diff --git a/angular.json b/angular.json
index c0d44b9..c39ce7d 100644
--- a/angular.json
+++ b/angular.json
@@ -37,7 +37,8 @@
}
],
"styles": [
- "src/styles.scss"
+ "src/styles.scss",
+ "node_modules/swiper/swiper-bundle.css"
]
},
"configurations": {
diff --git a/package-lock.json b/package-lock.json
index d0b051d..e8e69be 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -23,6 +23,7 @@
"@tsparticles/angular": "~3.0.0",
"@tsparticles/engine": "~3.9.1",
"rxjs": "^7.8.0",
+ "swiper": "~12.0.3",
"tslib": "^2.3.0",
"tsparticles": "~3.9.1"
},
@@ -11987,6 +11988,25 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/swiper": {
+ "version": "12.0.3",
+ "resolved": "https://registry.npmjs.org/swiper/-/swiper-12.0.3.tgz",
+ "integrity": "sha512-BHd6U1VPEIksrXlyXjMmRWO0onmdNPaTAFduzqR3pgjvi7KfmUCAm/0cj49u2D7B0zNjMw02TSeXfinC1hDCXg==",
+ "funding": [
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/swiperjs"
+ },
+ {
+ "type": "open_collective",
+ "url": "http://opencollective.com/swiper"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4.7.0"
+ }
+ },
"node_modules/tapable": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz",
diff --git a/package.json b/package.json
index c816163..e466861 100644
--- a/package.json
+++ b/package.json
@@ -25,6 +25,7 @@
"@tsparticles/angular": "~3.0.0",
"@tsparticles/engine": "~3.9.1",
"rxjs": "^7.8.0",
+ "swiper": "~12.0.3",
"tslib": "^2.3.0",
"tsparticles": "~3.9.1"
},
diff --git a/src/app/constants/AssetsConstants.ts b/src/app/constants/AssetsConstants.ts
index adaebc7..7d84ed8 100644
--- a/src/app/constants/AssetsConstants.ts
+++ b/src/app/constants/AssetsConstants.ts
@@ -12,7 +12,7 @@
static readonly COLORDIGITAL_LOGO = '/assets/logos/dmixcloud_logo.jpg';
static readonly TERAPORT_LOGO = '/assets/logos/teraport_gmbh_logo.jpg';
- static readonly CV: 'assets/cv/andreas-dahm-cv.pdf';
+ static readonly DIPLOMA= 'assets/projects/diploma/Dahm2010-Diplomarbeit.pdf';
//project images
static readonly EL_MUCHO_1 = '/assets/projects/el-mucho/1.jpg';
diff --git a/src/app/layout/imageDialog/image.component.ts b/src/app/layout/imageDialog/image.component.ts
new file mode 100644
index 0000000..53e51d9
--- /dev/null
+++ b/src/app/layout/imageDialog/image.component.ts
@@ -0,0 +1,69 @@
+import { Component, Inject } from '@angular/core';
+import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
+import { MatButtonModule } from '@angular/material/button';
+import { MatIconModule } from '@angular/material/icon';
+
+@Component({
+ standalone: true,
+ imports: [MatDialogModule, MatButtonModule, MatIconModule],
+ template: `
+
+
+
{{ data.title }}
+
+
+
+
+
![]()
+
+
+ `,
+ styles: [`
+ .dialog {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ }
+
+ .topbar {
+ flex: 0 0 auto;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 1rem;
+
+ padding: 14px 16px;
+ }
+
+ .title {
+ font-weight: 600;
+ line-height: 1.2;
+ max-width: calc(100% - 56px);
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+
+ .stage {
+ flex: 1 1 auto;
+ padding: 0 16px 16px;
+ min-height: 0;
+ display: grid;
+ place-items: center;
+ }
+
+ .full {
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+ border-radius: 12px;
+ }
+ `],
+})
+export class ImageDialogComponent {
+ constructor(@Inject(MAT_DIALOG_DATA) public data: { title: string; src: string }) {
+ console.log(data.title);
+ }
+}
diff --git a/src/app/pages/about/about.component.scss b/src/app/pages/about/about.component.scss
index a563749..3957ca7 100644
--- a/src/app/pages/about/about.component.scss
+++ b/src/app/pages/about/about.component.scss
@@ -169,27 +169,6 @@
opacity: .85;
}
-.link-row {
- grid-row: 2;
- grid-column: 2;
- margin-top: .1rem;
- opacity: .85;
- vertical-align: center;
-}
-
-.link-with-icon {
- display: inline-flex;
- align-items: center;
- gap: .35rem;
- line-height: 1;
-}
-
-.link-with-icon mat-icon {
- font-size: 18px;
- height: 18px;
- width: 18px;
-}
-
.highlights {
margin-top: .4rem;
margin-left: .75rem;
diff --git a/src/app/pages/about/about.component.ts b/src/app/pages/about/about.component.ts
index 58b0b6f..08185d2 100644
--- a/src/app/pages/about/about.component.ts
+++ b/src/app/pages/about/about.component.ts
@@ -29,7 +29,6 @@ import {SharedFunctions} from '../../shared/SharedFunctions';
styleUrl: './about.component.scss'
})
export class AboutComponent {
- cvHref = AssetsConstants.CV;
xpKeys = [
{
@@ -143,13 +142,6 @@ export class AboutComponent {
'ABOUT.TOOLS.GRAFANA',
];
- openMail(event: Event) {
- event.preventDefault();
- const user = 'andreas.dahm';
- const domain = 'gmail.com';
- globalThis.location.href = `mailto:${user}@${domain}`;
- }
-
protected readonly UrlConstants = UrlConstants;
protected readonly AssetsConstants = AssetsConstants;
protected readonly SharedFunctions = SharedFunctions;
diff --git a/src/app/pages/projects/projects.component.html b/src/app/pages/projects/projects.component.html
index b97aaeb..ed1bacd 100644
--- a/src/app/pages/projects/projects.component.html
+++ b/src/app/pages/projects/projects.component.html
@@ -9,13 +9,54 @@
{{ project.introduction | translate }}
+
+ @if (project.link)
+ {
+
+ }
+
+ @if(project.assets)
+ {
+
+ }
+
@if (project.images.length > 0)
{
-
+
@for (img of project.images; track img) {
-
+
+
+
}
-
+
}
}
diff --git a/src/app/pages/projects/projects.component.scss b/src/app/pages/projects/projects.component.scss
index 325d60d..5f2be76 100644
--- a/src/app/pages/projects/projects.component.scss
+++ b/src/app/pages/projects/projects.component.scss
@@ -7,15 +7,34 @@
margin-left: 8px;
}
-.gallery {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(384px, 1fr));
- gap: 12px;
-}
-
-.gallery-img {
+.slide-img {
width: 100%;
height: auto;
+ max-height: 512px !important;
+ object-fit: cover;
+ border-radius: 12px;
display: block;
- border-radius: 16px;
+ cursor: pointer;
+}
+
+.my-swiper::part(button-prev),
+.my-swiper::part(button-next) {
+ width: 35px;
+ height: 35px;
+ padding: 5px;
+ border-radius: 999px;
+ background: rgba(0,0,0,.5);
+
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.my-swiper::part(button-prev):hover,
+.my-swiper::part(button-next):hover {
+ background: rgba(0,0,0,.75);
+}
+
+.my-swiper::part(pagination) {
+ bottom: 12px;
}
diff --git a/src/app/pages/projects/projects.component.ts b/src/app/pages/projects/projects.component.ts
index a5ae98c..a591fdc 100644
--- a/src/app/pages/projects/projects.component.ts
+++ b/src/app/pages/projects/projects.component.ts
@@ -1,9 +1,12 @@
-import {Component, inject, signal} from '@angular/core';
+import {Component, inject, signal, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import {MatAccordion, MatExpansionPanel, MatExpansionPanelDescription, MatExpansionPanelHeader, MatExpansionPanelTitle} from '@angular/material/expansion';
import {MatIcon} from '@angular/material/icon';
-import {TranslatePipe} from '@ngx-translate/core';
+import {TranslatePipe, TranslateService} from '@ngx-translate/core';
import {ActivatedRoute} from '@angular/router';
import {AssetsConstants} from '../../constants/AssetsConstants';
+import {MatDialog} from '@angular/material/dialog';
+import {ImageDialogComponent} from '../../layout/imageDialog/image.component';
+
export interface Projects {
identifier: string;
@@ -12,7 +15,7 @@ export interface Projects {
introduction: string,
images: string[],
icon: string,
- assets: string[],
+ assets: string,
link: string,
bulletPoints: string[],
}
@@ -26,14 +29,18 @@ export interface Projects {
MatExpansionPanelTitle,
MatExpansionPanelDescription,
MatIcon,
- TranslatePipe,
+ TranslatePipe
],
templateUrl: './projects.component.html',
styleUrl: './projects.component.scss',
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class ProjectsComponent {
private readonly route = inject(ActivatedRoute);
+ private readonly dialog = inject(MatDialog);
+ private readonly translateService = inject(TranslateService);
+
selectedKey = signal(null);
allProjects: Projects[] = [
@@ -44,7 +51,7 @@ export class ProjectsComponent {
introduction: 'PROJECTS.PLAYGROUND.INTRODUCTION',
images: [],
icon: 'web',
- assets: [],
+ assets: '',
link: 'https://andreas-dahm.eu',
bulletPoints: []
},
@@ -55,7 +62,7 @@ export class ProjectsComponent {
introduction: 'PROJECTS.EL_MUCHO.INTRODUCTION',
images: [AssetsConstants.EL_MUCHO_1, AssetsConstants.EL_MUCHO_2, AssetsConstants.EL_MUCHO_3, AssetsConstants.EL_MUCHO_4],
icon: 'sports_esports',
- assets: [],
+ assets: '',
link: 'https://store.steampowered.com/app/1532640/El_Mucho/',
bulletPoints: []
},
@@ -66,7 +73,7 @@ export class ProjectsComponent {
introduction: 'PROJECTS.GAME_JAMS.INTRODUCTION',
images: [AssetsConstants.GAME_JAMS_1, AssetsConstants.GAME_JAMS_2, AssetsConstants.GAME_JAMS_3],
icon: 'videogame_asset',
- assets: [],
+ assets: '',
link: 'https://itch.io/c/6628860/lobos-collection',
bulletPoints: []
},
@@ -77,7 +84,7 @@ export class ProjectsComponent {
introduction: 'PROJECTS.DIPLOMA.INTRODUCTION',
images: [AssetsConstants.DIPLOMA_1, AssetsConstants.DIPLOMA_2, AssetsConstants.DIPLOMA_3, AssetsConstants.DIPLOMA_4, AssetsConstants.DIPLOMA_5, AssetsConstants.DIPLOMA_6],
icon: 'history_edu',
- assets: [],
+ assets: AssetsConstants.DIPLOMA,
link: 'https://www.th-bingen.de',
bulletPoints: []
}
@@ -92,4 +99,18 @@ export class ProjectsComponent {
isExpanded(projectKey: string): boolean {
return this.selectedKey() === projectKey;
}
+
+ openImage(title: string, src: string) {
+ const translatedTitle = this.translateService.instant(title);
+ this.dialog.open(ImageDialogComponent, {
+ data: { title: translatedTitle, src },
+ width: '96vw',
+ height: '96vh',
+ maxWidth: '96vw',
+ maxHeight: '96vh',
+ panelClass: 'image-dialog-panel',
+ autoFocus: false,
+ restoreFocus: true,
+ });
+ }
}
diff --git a/src/assets/i18n/de.json b/src/assets/i18n/de.json
index fd23a87..35ef058 100644
--- a/src/assets/i18n/de.json
+++ b/src/assets/i18n/de.json
@@ -227,6 +227,7 @@
}
},
"PROJECTS": {
+ "DOWNLOAD": "Herunterladen",
"PLAYGROUND": {
"TITLE": "Playground Website",
"SHORT_DESCRIPTION": "Hier geht es um diese Webseite.",
diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json
index e3659db..ba1757a 100644
--- a/src/assets/i18n/en.json
+++ b/src/assets/i18n/en.json
@@ -227,6 +227,7 @@
}
},
"PROJECTS": {
+ "DOWNLOAD": "Download",
"PLAYGROUND": {
"TITLE": "Playground Website",
"SHORT_DESCRIPTION": "This is about this website.",
diff --git a/src/main.ts b/src/main.ts
index b0ef0a7..f28c38d 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -2,6 +2,9 @@ import { bootstrapApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config';
import packageJson from '../package.json';
import {AppComponent} from './app/layout/app/app.component';
+import { register } from 'swiper/element/bundle';
+register();
+
if (packageJson.version) {
console.log(`🌟 Frontend version: ${packageJson.version}`);
diff --git a/src/styles.scss b/src/styles.scss
index 494e1e8..dc63ed5 100644
--- a/src/styles.scss
+++ b/src/styles.scss
@@ -174,3 +174,40 @@ a {
.mat-expansion-panel-body {
padding-top: 0;
}
+
+.image-dialog-panel .mat-mdc-dialog-surface {
+ border-radius: 16px;
+ overflow: hidden;
+}
+
+.image-dialog-panel .mat-mdc-dialog-content {
+ padding: 0 !important;
+ margin: 0 !important;
+ overflow: hidden !important;
+ max-height: none !important;
+}
+
+.image-dialog-panel .mat-mdc-dialog-container {
+ padding: 0;
+}
+
+.link-row {
+ grid-row: 2;
+ grid-column: 2;
+ margin-top: .1rem;
+ opacity: .85;
+ vertical-align: center;
+}
+
+.link-with-icon {
+ display: inline-flex;
+ align-items: center;
+ gap: .35rem;
+ line-height: 1;
+}
+
+.link-with-icon mat-icon {
+ font-size: 18px;
+ height: 18px;
+ width: 18px;
+}