diff --git a/package.json b/package.json index 05dfa36..948d16c 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "@angular/router": "~9.1.7", "bootstrap": "^4.5.3", "ng-particles": "^2.1.11", + "ngx-image-gallery": "^2.0.5", "rxjs": "~6.5.4", "tslib": "^1.10.0", "zone.js": "~0.10.2" diff --git a/src/apis/index.php b/src/apis/index.php index 8adaa9a..830ff2e 100644 --- a/src/apis/index.php +++ b/src/apis/index.php @@ -71,6 +71,8 @@ switch($_GET['query']) { } } else if($_GET['type'] == 'works') { $item->type = $re['type']; + $item->videos = $re['videos']; + $item->gallery = $re['gallery']; $item->exhibitions = array(); $qx = mysqli_query($conn,"SELECT id,title FROM `exhibitions` WHERE id IN (".$re['exhibitions'].")"); while($re = mysqli_fetch_array($qx)) { diff --git a/src/app/app.module.ts b/src/app/app.module.ts index cb94103..ec33f1b 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -2,6 +2,7 @@ import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { HttpClientModule } from '@angular/common/http'; import { NgParticlesModule } from "ng-particles"; +import { NgxImageGalleryModule } from 'ngx-image-gallery'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; @@ -24,6 +25,7 @@ import { DetailComponent } from './detail/detail.component'; BrowserModule, AppRoutingModule, NgParticlesModule, + NgxImageGalleryModule, HttpClientModule ], providers: [], diff --git a/src/app/detail/detail.component.html b/src/app/detail/detail.component.html index f5aa256..15c2be3 100644 --- a/src/app/detail/detail.component.html +++ b/src/app/detail/detail.component.html @@ -3,7 +3,45 @@

{{details.title}}

+ + + + +
+ from + on + {{details.date_from | date}} + to {{details.date_to | date}} +
+
+ +
+
+ {{video.title}} +
+ {{video.code}} + +
+
+
+ + Tags: {{details.tags}} Exhibitions: @@ -19,3 +57,14 @@
+ + + diff --git a/src/app/detail/detail.component.scss b/src/app/detail/detail.component.scss index aeeb2d8..5e764b1 100644 --- a/src/app/detail/detail.component.scss +++ b/src/app/detail/detail.component.scss @@ -13,7 +13,7 @@ border-radius: 10px; .title { - margin-top: 0; + margin: 0; font-size: $font-34; font-weight: bold; text-transform: uppercase; @@ -22,7 +22,78 @@ .text { font-size: $font-18; text-align: justify; - padding-bottom: 40px; + padding: 40px 0; + } + + .date-container { + display: inline-flex; + position: absolute; + top: 40px; + right: 40px; + + .date { + display: inline-flex; + margin: auto; + font-size: $font-20; + } + + .date-indication { + margin: 2px 5px auto 5px; + font-size: $font-12; + } + } + + .gallery { + padding-top: 40px; + + .gallery-title { + font-size: $font-18; + font-weight: bold; + padding-bottom: 5px; + } + + .gallery-container { + position: relative; + //padding-bottom: 56.25%; + height: 180px; + + .image{ + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + object-fit: cover; + cursor: pointer; + transition: transform .4s; + + &:hover { + transform: scale(1.2) rotate(1deg); + z-index: 10; + } + } + } + } + + .videos { + .video-title { + font-size: $font-18; + font-weight: bold; + padding-bottom: 5px; + } + + .youtube { + position: relative; + padding-bottom: 56.25%; + + .iframe{ + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + } + } } .tags, diff --git a/src/app/detail/detail.component.ts b/src/app/detail/detail.component.ts index 9b5cf81..8a0eb7f 100644 --- a/src/app/detail/detail.component.ts +++ b/src/app/detail/detail.component.ts @@ -1,6 +1,8 @@ -import { Component, OnInit } from '@angular/core' +import { Component, OnInit, ViewChild } from '@angular/core' import { Router, NavigationEnd, NavigationStart, ActivatedRoute } from '@angular/router' +import { DomSanitizer } from '@angular/platform-browser' import { Location } from '@angular/common' +import { NgxImageGalleryComponent, GALLERY_IMAGE, GALLERY_CONF } from "ngx-image-gallery" import { ApisService } from '../services/apis.service' @Component({ @@ -10,18 +12,33 @@ import { ApisService } from '../services/apis.service' }) export class DetailComponent implements OnInit { + @ViewChild(NgxImageGalleryComponent) ngxImageGallery: NgxImageGalleryComponent + public details: any = {} + public section: string = '' + public id: number = 0 private history: string[] = [] + public conf: GALLERY_CONF = { + imageOffset: '0px', + showDeleteControl: false, + showImageTitle: false, + } + + public galleryImages: GALLERY_IMAGE[] = [] + constructor( private apisService: ApisService, private router: Router, private location: Location, - private activeRoute: ActivatedRoute + private activeRoute: ActivatedRoute, + private sanitizer: DomSanitizer ) { } ngOnInit(): void { - this.showDetails(this.router.url.split('/')[2], this.router.url.split('/')[3]) + this.section = this.router.url.split('/')[2] + this.id = parseInt(this.router.url.split('/')[3]) + this.showDetails(this.section, this.id) } showDetails(section, id): void { @@ -29,7 +46,25 @@ export class DetailComponent implements OnInit { if(this.history[this.history.length - 1] != `/detail/${section}/${id}`) { this.history.push(`/detail/${section}/${id}`) } - this.details = response.item + + const detail = response.item + detail.videos = detail.videos ? JSON.parse(detail.videos) : [] + detail.videos.forEach((e) => { + e.code = e.url.split('/').pop() + e.embed = this.sanitizer.bypassSecurityTrustResourceUrl(`https://www.youtube.com/embed/${e.code}`) + }) + detail.gallery = detail.gallery ? JSON.parse(detail.gallery) : [] + + detail.gallery.forEach((e) => { + this.galleryImages.push({ + url: e.url, + altText: e.title, + title: e.title, + thumbnailUrl: e.url + }) + }) + this.details = detail + },(error) => { console.error('getPortfolio ERROR', error) }).catch((e) => { @@ -41,10 +76,78 @@ export class DetailComponent implements OnInit { this.history.pop() if(this.history.length > 0) { const last = this.history[this.history.length - 1] - this.showDetails(last.split('/')[2], last.split('/')[3]) + this.section = last.split('/')[2] + this.id = parseInt(last.split('/')[3]) + this.showDetails(this.section, this.id) this.location.back() } else { this.location.back() } } + + + + + + + + + + + + + + + + openGallery(index: number = 0) { + this.ngxImageGallery.open(index); + } + + // close gallery + closeGallery() { + this.ngxImageGallery.close(); + } + + // set new active(visible) image in gallery + newImage(index: number = 0) { + this.ngxImageGallery.setActiveImage(index); + } + + // next image in gallery + nextImage(index: number = 0) { + this.ngxImageGallery.next(); + } + + // prev image in gallery + prevImage(index: number = 0) { + this.ngxImageGallery.prev(); + } + + /**************************************************/ + + // EVENTS + // callback on gallery opened + galleryOpened(index) { + console.info('Gallery opened at index ', index); + } + + // callback on gallery closed + galleryClosed() { + console.info('Gallery closed.'); + } + + // callback on gallery image clicked + galleryImageClicked(index) { + console.info('Gallery image clicked with index ', index); + } + + // callback on gallery image changed + galleryImageChanged(index) { + console.info('Gallery image changed to index ', index); + } + + // callback on user clicked delete button + deleteImage(index) { + console.info('Delete image at index ', index); + } } diff --git a/src/app/portfolio/portfolio.component.html b/src/app/portfolio/portfolio.component.html index 3f9d61a..094f09d 100644 --- a/src/app/portfolio/portfolio.component.html +++ b/src/app/portfolio/portfolio.component.html @@ -6,7 +6,19 @@
{{item.title}} - {{item.type}} + {{item.type}} + +
+
+ from + on + {{item.date_from | date}} +
+
+ to {{item.date_to | date}} +
+
+ {{item.tags}}
diff --git a/src/app/portfolio/portfolio.component.scss b/src/app/portfolio/portfolio.component.scss index a0965c4..d799a61 100644 --- a/src/app/portfolio/portfolio.component.scss +++ b/src/app/portfolio/portfolio.component.scss @@ -61,18 +61,37 @@ font-weight: bold; padding-top: 10px; } + + .date-container { + display: inline-flex; + flex-wrap: wrap; + + .date-row { + display: block; + width: 100%; + + .date { + display: inline-flex; + margin: auto; + font-size: $font-20; + } + + .date-indication { + margin: 2px 5px auto 5px; + font-size: $font-12; + } + + &:nth-of-type(2) { + margin-top: -12px; + } + } + } + } @each $angle in 0,1,2,3,4,5,6 { &.skew-#{$angle} { transform: skew(#{$angle - 3}deg, #{$angle - 3}deg); - /*animation: zoom#{$angle} #{$angle + 3}s ease-in infinite forwards; - @keyframes zoom#{$angle} { - 0% { transform: scale(1) skew(#{$angle - 3}deg, #{$angle - 3}deg); } - 50% { transform: scale(1.1) skew(#{$angle - 3}deg, #{$angle - 3}deg); } - 75% { transform: scale(.9) skew(#{$angle - 3}deg, #{$angle - 3}deg); } - 100% { transform: scale(1) skew(#{$angle - 3}deg, #{$angle - 3}deg); } - }*/ } } diff --git a/src/app/portfolio/portfolio.component.ts b/src/app/portfolio/portfolio.component.ts index 6bf8d0f..1902028 100644 --- a/src/app/portfolio/portfolio.component.ts +++ b/src/app/portfolio/portfolio.component.ts @@ -10,6 +10,7 @@ import { ApisService } from '../services/apis.service' export class PortfolioComponent implements OnInit { public portfolioItems: any = [] + public section: string = '' constructor( private apisService: ApisService, @@ -17,7 +18,9 @@ export class PortfolioComponent implements OnInit { { } ngOnInit(): void { - this.apisService.getPortfolio(this.router.url.split('/')[1]).toPromise().then((response) => { + this.section = this.router.url.split('/')[1] + + this.apisService.getPortfolio(this.section).toPromise().then((response) => { this.portfolioItems = response.items },(error) => { console.error('getPortfolio ERROR', error) @@ -27,7 +30,7 @@ export class PortfolioComponent implements OnInit { } showDetails(id): void { - const section = this.router.url.split('/')[1] == 'exhibitions' ? 'exhibitions' : 'works' + const section = this.section == 'exhibitions' ? 'exhibitions' : 'works' this.router.navigate([`/detail/${section}/${id}`]) } diff --git a/src/assets/scss/global.scss b/src/assets/scss/global.scss index 97bdc40..c575f20 100644 --- a/src/assets/scss/global.scss +++ b/src/assets/scss/global.scss @@ -14,6 +14,20 @@ body { } } +a, +li, +button { + outline: none !important; + &:active, + &:focus { + outline: none !important; + } +} + +.w-100 { + width: 100%; +} + .particles { position: fixed;