diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index e7d59f4..745acc5 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -1,9 +1,13 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { PageComponent } from './pages/page/page.component'; +import { TestPageComponent } from './pages/test-page/test-page.component'; +import { SpeakerDetailsComponent } from './pages/speaker-details/speaker-details.component'; const routes: Routes = [ - { path: 'page/:id', component: PageComponent } + { path: 'page/:id', component: PageComponent }, + { path: 'test_page', component: TestPageComponent }, + { path: 'speaker-details/:speakerCode', component: SpeakerDetailsComponent } ]; @NgModule({ diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 251d80f..a55cd7b 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -13,6 +13,10 @@ import { ButtonComponent } from './components/button/button.component'; import { WorkshoplistComponent } from './workshoplist/workshoplist.component'; import { TimeplanComponent } from './timeplan/timeplan.component'; import { GalleryComponent } from './gallery/gallery.component'; +import { TestPageComponent } from './pages/test-page/test-page.component'; +import { SpeakersComponent } from './components/speakers/speakers.component'; +import { SpinnerComponent } from './components/spinner/spinner.component'; +import { SpeakerDetailsComponent } from './pages/speaker-details/speaker-details.component'; @@ -25,6 +29,10 @@ import { GalleryComponent } from './gallery/gallery.component'; HeadermenuComponent, PageComponent, ButtonComponent, + TestPageComponent, + SpeakersComponent, + SpinnerComponent, + SpeakerDetailsComponent, ], imports: [ BrowserModule, diff --git a/src/app/components/menus/headermenu/headermenu.component.html b/src/app/components/menus/headermenu/headermenu.component.html index 4a330cf..9e1a59a 100644 --- a/src/app/components/menus/headermenu/headermenu.component.html +++ b/src/app/components/menus/headermenu/headermenu.component.html @@ -1,4 +1,4 @@ -
+
\ No newline at end of file diff --git a/src/app/components/menus/headermenu/headermenu.component.scss b/src/app/components/menus/headermenu/headermenu.component.scss index d93f3d7..9f50cf6 100644 --- a/src/app/components/menus/headermenu/headermenu.component.scss +++ b/src/app/components/menus/headermenu/headermenu.component.scss @@ -8,6 +8,7 @@ position: sticky; display: block; top: 0; + z-index: 1000; .button-center { align-self: center; diff --git a/src/app/components/speakers/APISpeakers.ts b/src/app/components/speakers/APISpeakers.ts new file mode 100644 index 0000000..ad4f1d5 --- /dev/null +++ b/src/app/components/speakers/APISpeakers.ts @@ -0,0 +1,86 @@ +import { APISpeakers, Answer, Availability, Speaker } from './speaker.interface' + +export const fakePretalx: APISpeakers = { + count: 1, + next: null, + previous: null, + results: [ + { + code: "ABCDE", + name: "Max Mustermann", + biography: "Managing state and complex data in Angular", + submissions: ["DEFAB"], + avatar: "https://picsum.photos/200/300?random=3", + availabilities: [ + { + id: 1, + start: "2023-08-24T04:00:00Z", + end: "2023-08-25T04:00:00Z", + allDay: false + } + ], + answers: [ + { question: 'Favorite programming language?', answer: 'JavaScript' }, + { question: 'Experience in public speaking?', answer: 'Yes' } + ] + }, + { + code: "XYZ123", + name: "Alexander Pronin", + biography: "A good speaker", + submissions: ["DEFAB"], + avatar: "https://picsum.photos/200/300?random=1", + availabilities: [ + { + "id": 1, + "start": "2023-08-01T09:00:00Z", + "end": "2023-08-02T09:00:00Z", + "allDay": false + } + ], + answers: [ + { question: 'Favorite programming language?', answer: 'JavaScript' }, + { question: 'Experience in public speaking?', answer: 'Yes' } + ] + }, + { + code: "BDF456", + name: "Einfach Tobias", + biography: "Wird schon", + submissions: ["DEFAB"], + avatar: "https://picsum.photos/200/300?random=2", + availabilities: [ + { + "id": 1, + "start": "2023-08-01T09:00:00Z", + "end": "2023-08-02T09:00:00Z", + "allDay": false + } + ], + answers: [ + { question: 'Favorite programming language?', answer: 'JavaScript' }, + { question: 'Experience in public speaking?', answer: 'Yes' } + ] + }, + { + code: "BDF456", + name: "Versteckter Sprecher", + biography: "Jemand, der nicht angezeigt werden soll", + submissions: ["DEFAB"], + avatar: "https://picsum.photos/200/300?random=4", + availabilities: [ + { + "id": 1, + "start": "2023-08-01T09:00:00Z", + "end": "2023-08-02T09:00:00Z", + "allDay": false + } + ], + answers: [ + { question: 'Favorite programming language?', answer: 'JavaScript' }, + { question: 'Experience in public speaking?', answer: 'Yes' } + ] + }, + ] +} + diff --git a/src/app/components/speakers/speaker.interface.ts b/src/app/components/speakers/speaker.interface.ts new file mode 100644 index 0000000..4ac9f40 --- /dev/null +++ b/src/app/components/speakers/speaker.interface.ts @@ -0,0 +1,29 @@ +export interface APISpeakers { + count: number; + next: null | string; + previous: null | string; + results: Speaker[]; + } + +export interface Speaker { + code: string; + name: string; + biography: string; + submissions: string[]; + avatar: string; + email?: string; + availabilities: Availability[]; + answers?: Answer[]; + } + + export interface Availability { + id: number; + start: string; + end: string; + allDay: boolean; + } + + export interface Answer { + question: string; + answer: string; + } \ No newline at end of file diff --git a/src/app/components/speakers/speakers.component.html b/src/app/components/speakers/speakers.component.html new file mode 100644 index 0000000..16fbe8d --- /dev/null +++ b/src/app/components/speakers/speakers.component.html @@ -0,0 +1,30 @@ + +
+
+
+ +
+
+ +
+
+
{{ speaker.name }}
+
+
+ +
+
+
+
+ + Weniger + +
+
+
+
+ + + + \ No newline at end of file diff --git a/src/app/components/speakers/speakers.component.scss b/src/app/components/speakers/speakers.component.scss new file mode 100644 index 0000000..f7959af --- /dev/null +++ b/src/app/components/speakers/speakers.component.scss @@ -0,0 +1,82 @@ +:host { + .custom-card { + padding: 10px; + cursor: pointer; + + &:hover { + color: #14897d; + } + + .card-header { + text-align: center; + background: linear-gradient( + 14deg, + var(--fotos-backround-gardient-start) 0%, + var(--fotos-backround-gardient-end) 100% + ); + + .card-img { + max-width: 100%; + height: auto; + } + } + + .card-body { + text-align: center; + padding: 15px; + + .card-title { + font-size: 1.25rem; + margin: 0; + font-weight: bold; + } + } + .card-img { + filter: grayscale(100%); + transform: rotate(-4deg); + transition: all 0.3s ease; + + &:hover { + transform: rotate(0); + transition: transform 0.3s ease; + filter: grayscale(0%); + } + } + } + + .button-container { + display: flex; + justify-content: center; + align-items: center; + margin-top: 1rem; + + .toggle-content-button { + position: relative; + + &.more::before { + content: ""; + position: absolute; + width: 10px; + height: 10px; + transform: rotate(45deg) translateX(-4px); + border-right: 2px solid; + border-bottom: 2px solid; + top: 50%; + right: 1.25rem; + margin-top: -5px; + } + &.less::before { + content: ""; + position: absolute; + width: 10px; + height: 10px; + transform: rotate(225deg) translateX(-2px); + border-right: 2px solid; + border-bottom: 2px solid; + top: 50%; + right: 1.7rem; + margin-top: -4px; + } + } + } +} diff --git a/src/app/components/speakers/speakers.component.spec.ts b/src/app/components/speakers/speakers.component.spec.ts new file mode 100644 index 0000000..a3fe01b --- /dev/null +++ b/src/app/components/speakers/speakers.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SpeakersComponent } from './speakers.component'; + +describe('SpeakersComponent', () => { + let component: SpeakersComponent; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [SpeakersComponent] + }); + fixture = TestBed.createComponent(SpeakersComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/speakers/speakers.component.ts b/src/app/components/speakers/speakers.component.ts new file mode 100644 index 0000000..8fa82b6 --- /dev/null +++ b/src/app/components/speakers/speakers.component.ts @@ -0,0 +1,42 @@ + +import { Component, OnInit } from '@angular/core'; +import { SpeakerService } from '../../services/speaker.service'; +import { tap } from 'rxjs/operators'; +import { Speaker } from './speaker.interface'; +import { ButtonType } from '../button/button.component'; +import { Observable } from 'rxjs'; + + +@Component({ + selector: 'app-speakers', + templateUrl: './speakers.component.html', + styleUrls: ['./speakers.component.scss'] +}) + +export class SpeakersComponent implements OnInit { + showAll = false; + ButtonType = ButtonType; + + allSpeakers$: Observable; + + constructor(private speakerService: SpeakerService) { } + + ngOnInit(): void { + + //todo del setinterval + //this.allSpeakers$ = this.speakerService.getAllSpeakers() + setInterval(() => { + this.allSpeakers$ = this.speakerService.getAllSpeakers() + }, 1000); + } + + + toggleShowMore() { + this.showAll = !this.showAll; + } + + showSpeakerDetails(code: string): void { + console.log(code); + } + +} \ No newline at end of file diff --git a/src/app/components/spinner/spinner.component.html b/src/app/components/spinner/spinner.component.html new file mode 100644 index 0000000..6471006 --- /dev/null +++ b/src/app/components/spinner/spinner.component.html @@ -0,0 +1,3 @@ +
+
+
\ No newline at end of file diff --git a/src/app/components/spinner/spinner.component.scss b/src/app/components/spinner/spinner.component.scss new file mode 100644 index 0000000..43ad870 --- /dev/null +++ b/src/app/components/spinner/spinner.component.scss @@ -0,0 +1,29 @@ +:host { + .loading-container { + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + position: absolute; + top: 0; + width: 100%; + } + + .spinner { + border: 4px solid rgba(0, 0, 0, 0.1); + border-left: 4px solid #00b6a3; + border-radius: 50%; + width: 40px; + height: 40px; + animation: spin 1s linear infinite; + } + + @keyframes spin { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } + } +} diff --git a/src/app/components/spinner/spinner.component.spec.ts b/src/app/components/spinner/spinner.component.spec.ts new file mode 100644 index 0000000..2759278 --- /dev/null +++ b/src/app/components/spinner/spinner.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SpinnerComponent } from './spinner.component'; + +describe('SpinnerComponent', () => { + let component: SpinnerComponent; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [SpinnerComponent] + }); + fixture = TestBed.createComponent(SpinnerComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/spinner/spinner.component.ts b/src/app/components/spinner/spinner.component.ts new file mode 100644 index 0000000..beed2a2 --- /dev/null +++ b/src/app/components/spinner/spinner.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'dd-spinner', + templateUrl: './spinner.component.html', + styleUrls: ['./spinner.component.scss'] +}) +export class SpinnerComponent { + +} diff --git a/src/app/pages/speaker-details/speaker-details.component.html b/src/app/pages/speaker-details/speaker-details.component.html new file mode 100644 index 0000000..326ede4 --- /dev/null +++ b/src/app/pages/speaker-details/speaker-details.component.html @@ -0,0 +1 @@ +

speaker-details works!

diff --git a/src/app/pages/speaker-details/speaker-details.component.scss b/src/app/pages/speaker-details/speaker-details.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/pages/speaker-details/speaker-details.component.spec.ts b/src/app/pages/speaker-details/speaker-details.component.spec.ts new file mode 100644 index 0000000..9db1a8e --- /dev/null +++ b/src/app/pages/speaker-details/speaker-details.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SpeakerDetailsComponent } from './speaker-details.component'; + +describe('SpeakerDetailsComponent', () => { + let component: SpeakerDetailsComponent; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [SpeakerDetailsComponent] + }); + fixture = TestBed.createComponent(SpeakerDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/speaker-details/speaker-details.component.ts b/src/app/pages/speaker-details/speaker-details.component.ts new file mode 100644 index 0000000..7719357 --- /dev/null +++ b/src/app/pages/speaker-details/speaker-details.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-speaker-details', + templateUrl: './speaker-details.component.html', + styleUrls: ['./speaker-details.component.scss'] +}) +export class SpeakerDetailsComponent { + +} diff --git a/src/app/pages/test-page/test-page.component.html b/src/app/pages/test-page/test-page.component.html new file mode 100644 index 0000000..d80acbe --- /dev/null +++ b/src/app/pages/test-page/test-page.component.html @@ -0,0 +1,4 @@ +
+

test-page works!

+ +
\ No newline at end of file diff --git a/src/app/pages/test-page/test-page.component.scss b/src/app/pages/test-page/test-page.component.scss new file mode 100644 index 0000000..191cb62 --- /dev/null +++ b/src/app/pages/test-page/test-page.component.scss @@ -0,0 +1,7 @@ +.test-container { + align-items: center; + justify-content: center; + height: 200px; + width: 100%; + +} \ No newline at end of file diff --git a/src/app/pages/test-page/test-page.component.spec.ts b/src/app/pages/test-page/test-page.component.spec.ts new file mode 100644 index 0000000..8efa59d --- /dev/null +++ b/src/app/pages/test-page/test-page.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TestPageComponent } from './test-page.component'; + +describe('TestPageComponent', () => { + let component: TestPageComponent; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [TestPageComponent] + }); + fixture = TestBed.createComponent(TestPageComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/test-page/test-page.component.ts b/src/app/pages/test-page/test-page.component.ts new file mode 100644 index 0000000..7213113 --- /dev/null +++ b/src/app/pages/test-page/test-page.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-test-page', + templateUrl: './test-page.component.html', + styleUrls: ['./test-page.component.scss'] +}) +export class TestPageComponent { + +} diff --git a/src/app/services/speaker.service.ts b/src/app/services/speaker.service.ts new file mode 100644 index 0000000..c0d869c --- /dev/null +++ b/src/app/services/speaker.service.ts @@ -0,0 +1,62 @@ +import { Injectable } from "@angular/core"; +import { HttpClient } from "@angular/common/http"; +import { Observable, of } from "rxjs"; +import { Answer, Availability, Speaker } from "../components/speakers/speaker.interface"; +import { fakePretalx } from "../components/speakers/APISpeakers"; + + +@Injectable({ + providedIn: "root" +}) +export class SpeakerService { + + private _url: string = "pretax"; + private mappedSpeakers: Speaker[] = []; + + constructor(private http: HttpClient) { + this.mappedSpeakers = fakePretalx.results.map(this.mapSpeaker); + }; + + // Mapping function for Availability + private mapAvailability = (apiAvailability: any): Availability => ({ + id: apiAvailability.id, + start: apiAvailability.start, + end: apiAvailability.end, + allDay: apiAvailability.allDay + }); + + // Mapping function for Answer + private mapAnswer = (apiAnswer: any): Answer => ({ + question: apiAnswer.question, + answer: apiAnswer.answer + }); + + // Mapping function for Speaker + private mapSpeaker = (apiSpeaker: any): Speaker => { + return { + code: apiSpeaker.code, + name: apiSpeaker.name, + biography: apiSpeaker.biography, + submissions: apiSpeaker.submissions, + avatar: apiSpeaker.avatar, + email: apiSpeaker.email, + availabilities: apiSpeaker.availabilities.map(this.mapAvailability), + answers: apiSpeaker.answers.map(this.mapAnswer) + }; + + }; + + + public getAllSpeakers = (): Observable => { + // return this.http.get(this._url); + return of(this.mappedSpeakers); + }; + + public getSpeakerDetails = (code: string): Observable => { + // return this.http.get(this._url + "/" + id); + const speaker = this.mappedSpeakers.find(s => s.code === code); + return of(speaker); + }; + +} + diff --git a/src/app/style-components/button.scss b/src/app/style-components/button.scss index 2c95e66..c940c9c 100644 --- a/src/app/style-components/button.scss +++ b/src/app/style-components/button.scss @@ -27,4 +27,12 @@ font-size: 1.75rem; line-height: 2rem; } - } \ No newline at end of file + + &.outline { + background: transparent; + color: var(--button-border-color); + padding-right: 3rem; + border: 3px solid; + font-weight: bold; + } +} \ No newline at end of file diff --git a/src/variables.scss b/src/variables.scss index 29935ba..fd13819 100644 --- a/src/variables.scss +++ b/src/variables.scss @@ -24,4 +24,6 @@ --header-font-color: #ffffffff; --package-cost-gradient-start: #40d5c5; --package-cost-gradient-end: #00b6a3; + --fotos-backround-gardient-start: #00b6a3; + --fotos-backround-gardient-end: #14897d; } \ No newline at end of file