diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..5dabb89 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "sarif-viewer.connectToGithubCodeScanning": "off" +} \ No newline at end of file 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..338af47 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -13,6 +13,11 @@ 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'; +import { SessionListComponent } from './components/session-list/session-list.component'; @@ -25,6 +30,11 @@ import { GalleryComponent } from './gallery/gallery.component'; HeadermenuComponent, PageComponent, ButtonComponent, + TestPageComponent, + SpeakersComponent, + SpinnerComponent, + SpeakerDetailsComponent, + SessionListComponent, ], imports: [ BrowserModule, diff --git a/src/app/components/menus/headermenu/headermenu.component.html b/src/app/components/menus/headermenu/headermenu.component.html index 4a330cf..cdf972e 100644 --- a/src/app/components/menus/headermenu/headermenu.component.html +++ b/src/app/components/menus/headermenu/headermenu.component.html @@ -1,18 +1,18 @@ -
+
-
+
-
+
-
\ 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/session-list/session-list.component.html b/src/app/components/session-list/session-list.component.html new file mode 100644 index 0000000..8230a12 --- /dev/null +++ b/src/app/components/session-list/session-list.component.html @@ -0,0 +1,66 @@ +
+
+
+
+

Sessionplan Dev Day 2023

+
+ + + + + + + + + + + + + + + + + +
Zeit + {{ talk.slot.room }} +
{{ group[0].slot.start | date:'HH:mm' }} - {{ group[0].slot.end | date:'HH:mm' }} + +

+ {{ getSessionForRoom(group, talk.slot.room)?.title }} +

+ + {{speaker.name}} + +
+ + + + + + +
+ +
+ + + + + +
{{ group[0].slot.start | date:'HH:mm' }} - {{ group[0].slot.end | + date:'HH:mm' }} +

+ {{getSessionForRoom(group, talk.slot.room)?.slot.room}} +

+

+ {{getSessionForRoom(group, talk.slot.room)?.title}} +

+ + {{speaker.name}} + +
+ +
+
+
+
+
\ No newline at end of file diff --git a/src/app/components/session-list/session-list.component.scss b/src/app/components/session-list/session-list.component.scss new file mode 100644 index 0000000..fc8eac5 --- /dev/null +++ b/src/app/components/session-list/session-list.component.scss @@ -0,0 +1,98 @@ +:host { + .content-area { + padding-top: 1.5rem; + padding-bottom: 1.5rem; + } + + .content-area h1 { + color: #171034; + margin-bottom: 1rem; + } + + table { + border-collapse: collapse; + margin: 0; + padding: 0; + width: 100%; + table-layout: fixed; + font-size: 20px; + line-height: 23px; + margin-bottom: 3rem; + gap: 10px; + } + + table thead th:first-child { + width: 15%; + } + + .session_table thead th span { + position: relative; + width: 98%; + margin-left: 13px; + display: block; + &::after { + content: ""; + position: absolute; + left: 0; + border-radius: 100px; + background: #35a4a3; + top: auto; + bottom: -9px; + width: 100%; + height: 6px; + } + } + +.td_time { + color: #6c757d; + font-size: 24px; + line-height: 31px; + font-weight: 500; + } + + table th, + table td { + padding: 0.75rem; + vertical-align: top; + border-bottom: 1px solid #dee2e6; + } + + a.speaker-link, + a.title { + color: #35a4a3; + text-decoration: none; + background-color: transparent; + cursor: pointer; + } + + .test { + display: flex; + flex-direction: column; + } + + .session_table_small { + width: 100%; + } + + .session_table_small .row .td_topic::before { + content: ''; + display: block; + width: 5px; + height: 90%; + background-color: #35a4a3; + position: absolute; + left: 0; + top: 0; + border-radius: 100px; + } + + .session_table_small .row .td_topic { + position: relative; + padding-left: 10px; + } + + a:hover { + color:var(--highlight-dark); + text-decoration: underline; +} +} diff --git a/src/app/components/session-list/session-list.component.spec.ts b/src/app/components/session-list/session-list.component.spec.ts new file mode 100644 index 0000000..b1e5ff9 --- /dev/null +++ b/src/app/components/session-list/session-list.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SessionListComponent } from './session-list.component'; + +describe('SessionListComponent', () => { + let component: SessionListComponent; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [SessionListComponent] + }); + fixture = TestBed.createComponent(SessionListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/session-list/session-list.component.ts b/src/app/components/session-list/session-list.component.ts new file mode 100644 index 0000000..0f249cd --- /dev/null +++ b/src/app/components/session-list/session-list.component.ts @@ -0,0 +1,35 @@ +// session-list.component.ts +import { Component, OnInit } from "@angular/core"; +import { Observable } from "rxjs"; +import { SessionResults } from "src/app/interfaces/session.interface"; +import { fakePretalxTalks } from "src/app/mocks/APITalks"; +import { SessionService } from "src/app/services/session.service"; + +@Component({ + selector: "dd-session-list", + templateUrl: "./session-list.component.html", + styleUrls: ["./session-list.component.scss"] +}) + +export class SessionListComponent implements OnInit { + + talks$: Observable; + groupedSessions: SessionResults[][] = []; + + constructor(private sessionService: SessionService) { } + + ngOnInit(): void { + this.talks$ = this.sessionService.getAllSessions(); + this.groupedSessions = this.sessionService.getGroupedSessions(); + } + + getSessionForRoom(group: SessionResults[], room: string): SessionResults { + const foundSession = group.find(session => session.slot.room === room); + if (foundSession) { + return foundSession; + } else { + return null; + } + } + +} \ 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..33c91da --- /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 '../../interfaces/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..69f9a5c --- /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 var(--highlight-bright); + 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/interfaces/session.interface.ts b/src/app/interfaces/session.interface.ts new file mode 100644 index 0000000..eae3f87 --- /dev/null +++ b/src/app/interfaces/session.interface.ts @@ -0,0 +1,60 @@ +export interface SessionSpeaker { + name: string; + code: string; + biography: string; +} + +export interface Slot { + start: string; + end: string; + room: string; + room_id: number; +} + +interface Question { + id: number; + question: { + en: string; + }; + required: boolean; + target: string; + options: string; +} + +interface Answer { + id: number; + question: Question; + answer: string; + answer_file: any; + submission: string; + person: any; + options: any[]; +} + +export interface Session { + count: number; + next: string | null; + previous: string | null; + results: SessionResults[]; +} + +export interface SessionResults { + code: string; + speakers: SessionSpeaker[]; + title: string; + submission_type: string; + submission_type_id: number; + state: string; + abstract: string; + description: string; + duration: number; + do_not_record: boolean; + is_featured: boolean; + content_locale: string; + slot: Slot; + answers: Answer[]; + notes: string; + internal_notes: string; + tags: string[]; + tag_ids: number[]; +} \ No newline at end of file diff --git a/src/app/interfaces/speaker.interface.ts b/src/app/interfaces/speaker.interface.ts new file mode 100644 index 0000000..4ac9f40 --- /dev/null +++ b/src/app/interfaces/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/mocks/APISpeakers.ts b/src/app/mocks/APISpeakers.ts new file mode 100644 index 0000000..13362c3 --- /dev/null +++ b/src/app/mocks/APISpeakers.ts @@ -0,0 +1,86 @@ +import { APISpeakers } from "../interfaces/speaker.interface"; + +export const fakePretalxSpeaker: APISpeakers = { + count: 1, + next: null, + previous: null, + results: [ + { + code: "ABCDE", + name: "Ali G", + 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: "WEWEWE", + name: "WALL-E 🤖", + 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: "Barbie Puppe", + biography: "Die Puppe wurde von Ruth Handler, einer der Gründerinnen von Mattel, inspiriert, die ihre Tochter Barbara beobachtete, wie sie mit Puppen Rollenspiele durchführte. Diese Beobachtung führte zur Schaffung der Barbie-Puppe, die nach ihrer Tochter benannt wurde.", + 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: "BDF123", + name: "Ken Puppe", + 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/mocks/APITalks.ts b/src/app/mocks/APITalks.ts new file mode 100644 index 0000000..933c196 --- /dev/null +++ b/src/app/mocks/APITalks.ts @@ -0,0 +1,132 @@ +import { Session } from "../interfaces/session.interface"; + +export const fakePretalxTalks: Session = { + count: 5, + next: null, + previous: null, + results: [ + { + code: "Test 1", + speakers: [{ name: "Barbie", code: "BDF456", biography: "" },{ name: "Ken", code: "BDF123", biography: "" }], + title: "Agile techniques in Our Toybox", + submission_type: "talk", + submission_type_id: 12, + state: "confirmed", + abstract: "A good talk.", + description: "I will expand upon the properties of the talk, primarily its high quality.", + duration: 30, + do_not_record: true, + is_featured: false, + content_locale: "en", + slot: { + start: "2017-12-27T10:00:00Z", + end: "2017-12-27T10:30:00Z", + room: "NY", + room_id: 12, + }, + answers: [ + { + id: 1, + question: { + id: 1, + question: { en: "How much do you like green, on a scale from 1-10?" }, + required: false, + target: "submission", + options: "", + }, + answer: "11", + answer_file: null, + submission: "ABCDE", + person: null, + options: [], + }, + ], + notes: "Please make sure you give me red M&Ms", + internal_notes: "Absolutely no M&Ms, but cool proposal otherwise!", + tags: ["science"], + tag_ids: [5], + }, + { + code: "ABCDE", + speakers: [{ name: "Ali G", code: "ABCDE", biography: "" }], + title: "Bla, bla, bla, die Kunst der Beredsamkeit.", + submission_type: "talk", + submission_type_id: 12, + state: "confirmed", + abstract: "A good talk.", + description: "I will expand upon the properties of the talk, primarily its high quality.", + duration: 30, + do_not_record: true, + is_featured: false, + content_locale: "en", + slot: { + start: "2017-12-27T11:00:00Z", + end: "2017-12-27T11:30:00Z", + room: "Dresden", + room_id: 12, + }, + answers: [ + { + id: 1, + question: { + id: 1, + question: { en: "How much do you like green, on a scale from 1-10?" }, + required: false, + target: "submission", + options: "", + }, + answer: "11", + answer_file: null, + submission: "ABCDE", + person: null, + options: [], + }, + ], + notes: "Please make sure you give me red M&Ms", + internal_notes: "Absolutely no M&Ms, but cool proposal otherwise!", + tags: ["science"], + tag_ids: [5], + }, + { + code: "Test 2", + speakers: [{ name: "WALL-E 🤖", code: "WEWEWE", biography: "" }], + title: "Ethics of Artificial Intelligence", + submission_type: "talk", + submission_type_id: 12, + state: "confirmed", + abstract: "A good talk.", + description: "I will expand upon the properties of the talk, primarily its high quality.", + duration: 30, + do_not_record: true, + is_featured: false, + content_locale: "en", + slot: { + start: "2017-12-27T10:00:00Z", + end: "2017-12-27T10:30:00Z", + room: "Erde", + room_id: 12, + }, + answers: [ + { + id: 1, + question: { + id: 1, + question: { en: "How much do you like green, on a scale from 1-10?" }, + required: false, + target: "submission", + options: "", + }, + answer: "11", + answer_file: null, + submission: "ABCDE", + person: null, + options: [], + }, + ], + notes: "Please make sure you give me red M&Ms", + internal_notes: "Absolutely no M&Ms, but cool proposal otherwise!", + tags: ["science"], + tag_ids: [5], + }, + ], +}; \ No newline at end of file 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..566eebc --- /dev/null +++ b/src/app/pages/speaker-details/speaker-details.component.html @@ -0,0 +1,34 @@ +
+
+
+
+ +
+
+
+

{{ speaker.name }}

+

+ {{ speaker.biography }} +

Sessions: Dev Day 2023

+ +
+
+
+ +
+
+ +
+
\ No newline at end of file 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..1fafa76 --- /dev/null +++ b/src/app/pages/speaker-details/speaker-details.component.scss @@ -0,0 +1,27 @@ +:host { + .info { + padding-top: 40px; + padding-bottom: 40px; + text-align: left; + } + .col-highlight { + background: linear-gradient( + 14deg, + var(--fotos-backround-gardient-start) 0%, + var(--fotos-backround-gardient-end) 100% + ); + color: #ffffff; + } + .content-sidebar img { + max-width: 100%; + } + h3 { + padding-top: 1rem; + } + .session-link { + color: #35a4a3; + text-decoration: none; + background-color: transparent; + cursor: pointer; + } +} 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..8ce047a --- /dev/null +++ b/src/app/pages/speaker-details/speaker-details.component.ts @@ -0,0 +1,32 @@ +import { Component } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { SessionResults } from 'src/app/interfaces/session.interface'; +import { Speaker } from 'src/app/interfaces/speaker.interface'; +import { SessionService } from 'src/app/services/session.service'; +import { SpeakerService } from 'src/app/services/speaker.service'; + +@Component({ + selector: 'app-speaker-details', + templateUrl: './speaker-details.component.html', + styleUrls: ['./speaker-details.component.scss'] +}) +export class SpeakerDetailsComponent { + speaker: Speaker; + sessions: SessionResults[] = []; + + constructor(private route: ActivatedRoute, private speakerService: SpeakerService, private sessionService: SessionService) { } + + ngOnInit(): void { + this.route.paramMap.subscribe(params => { + const speakerCode = params.get('speakerCode'); + this.speakerService.getSpeakerDetails(speakerCode).subscribe(speaker => { + this.speaker = speaker; + }); + this.sessionService.getSessionsBySpeaker(speakerCode).subscribe(sessions => { + this.sessions = sessions; + console.log("finded:",this.sessions); + }); + }); + + } +} 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..a92d738 --- /dev/null +++ b/src/app/pages/test-page/test-page.component.html @@ -0,0 +1,5 @@ +
+

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/session.service.ts b/src/app/services/session.service.ts new file mode 100644 index 0000000..3e5e6dc --- /dev/null +++ b/src/app/services/session.service.ts @@ -0,0 +1,93 @@ +import { Injectable } from "@angular/core"; +import { HttpClient } from "@angular/common/http"; +import { Observable, of } from "rxjs"; +import { Session, SessionResults, SessionSpeaker, Slot } from "../interfaces/session.interface"; +import { fakePretalxTalks } from "../mocks/APITalks"; + + +@Injectable({ + providedIn: "root" +}) + +export class SessionService { + + private _url: string = "pretax"; + private mappedSession: SessionResults[] = []; + + constructor(private http: HttpClient) { + this.mappedSession = fakePretalxTalks.results.map(this.mapSession); + }; + + + private mapSession = (apiSession: any): SessionResults => { + return { + code: apiSession.code, + speakers: apiSession.speakers.map(this.mapSessionSpeaker), + title: apiSession.title, + submission_type: apiSession.submission_type, + submission_type_id: apiSession.submission_type_id, + state: apiSession.state, + abstract: apiSession.abstract, + description: apiSession.description, + duration: apiSession.duration, + do_not_record: apiSession.do_not_record, + is_featured: apiSession.is_featured, + content_locale: apiSession.content_locale, + slot: this.mapSlot(apiSession.slot), + answers: apiSession.answer, + notes: apiSession.notes, + internal_notes: apiSession.internal_notes, + tags: apiSession.tags, + tag_ids: apiSession.tags_ids + }; + + }; + + private mapSessionSpeaker = (apiSessionSpeaker: SessionSpeaker): SessionSpeaker => ({ + name: apiSessionSpeaker.name, + code: apiSessionSpeaker.code, + biography: apiSessionSpeaker.biography + }); + + private mapSlot = (apiSlot: Slot): Slot => ({ + start: apiSlot.start, + end: apiSlot.end, + room: apiSlot.room, + room_id: apiSlot.room_id + }); + + public getAllSessions = (): Observable => { + return of(this.mappedSession); + }; + + public getSession = (code: string): Observable => { + const session = this.mappedSession.find(s => s.code === code); + return of(session); + }; + + public getSessionsBySpeaker = (speakerCode: string): Observable => { + const sessions = this.mappedSession.filter(s => s.speakers.some(speaker => speaker.code === speakerCode)); + console.log("finded service:",sessions); + return of(sessions); + }; + + + public getGroupedSessions(): SessionResults[][] { + // bspl { "11:30": [{Session1},{Session2}...], ...} + const groupedSessions: any = {}; + this.mappedSession.forEach(session => { + // same start time for different sessions + const time = session.slot.start; + //If time hasn't been added yet --> push el. + if (groupedSessions[time]) { + groupedSessions[time].push(session); + } else { + groupedSessions[time] = [session]; + } + }); + // [[Sessions1,Session2], [Session3]] + return Object.values(groupedSessions); + } + +} + diff --git a/src/app/services/speaker.service.ts b/src/app/services/speaker.service.ts new file mode 100644 index 0000000..64867af --- /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 "../interfaces/speaker.interface"; +import {fakePretalxSpeaker } from "../mocks/APISpeakers"; + + +@Injectable({ + providedIn: "root" +}) +export class SpeakerService { + + private _url: string = "pretax"; + private mappedSpeakers: Speaker[] = []; + + constructor(private http: HttpClient) { + this.mappedSpeakers =fakePretalxSpeaker.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