Skip to content

Commit

Permalink
Merge pull request #123 from uatisdeproblem/108-migrate-speakers-page
Browse files Browse the repository at this point in the history
feat: Added speakers frontend #78 #108
  • Loading branch information
rbento1096 committed Mar 12, 2024
2 parents 642219a + d34727a commit b4d07cc
Show file tree
Hide file tree
Showing 14 changed files with 234 additions and 6 deletions.
2 changes: 1 addition & 1 deletion back-end/src/handlers/sessions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ class Sessions extends ResourceController {

const filtertedSessions = sessions.filter(
x =>
(!this.queryParams.speaker || x.speakers.filter(x => x).includes(this.queryParams.speaker)) &&
(!this.queryParams.speaker || x.speakers.some(speaker => speaker.speakerId === this.queryParams.speaker)) &&
(!this.queryParams.room || x.room.roomId === this.queryParams.room)
);

Expand Down
4 changes: 4 additions & 0 deletions front-end/src/app/tabs/menu/menu.page.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,9 @@
<ion-icon name="business" slot="start"></ion-icon>
<ion-label>{{ 'MENU.ORGANIZATIONS' | translate }}</ion-label>
</ion-item>
<ion-item button color="white" (click)="app.goToInTabs(['speakers'])">
<ion-icon name="mic" slot="start"></ion-icon>
<ion-label>{{ 'MENU.SPEAKERS' | translate }}</ion-label>
</ion-item>
</ion-list>
</ion-content>
36 changes: 36 additions & 0 deletions front-end/src/app/tabs/speakers/speaker.page.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<ion-header>
<ion-toolbar>
<ion-title>{{ 'SPEAKERS.DETAILS' | translate }}</ion-title>
</ion-toolbar>
</ion-header>

<ion-content>
<ion-grid class="contentGrid">
<ion-row class="ion-justify-content-center">
<ion-col size="12" size-md="6">
<app-speaker-card [speaker]="speaker"></app-speaker-card>
</ion-col>
<ion-col size="12" size-md="6">
<ion-list>
<ion-list-header>
<ion-label class="ion-text-center">
<h2>{{ 'SPEAKERS.SESSIONS' | translate }}</h2>
</ion-label>
</ion-list-header>
<ion-searchbar #searchbar color="light" (ionInput)="filterSessions($event.target.value)"></ion-searchbar>
<ion-col *ngIf="!sessions">
<app-session-card [preview]="true"></app-session-card>
</ion-col>
<ion-col *ngIf="sessions && sessions.length === 0">
<ion-item lines="none" color="white">
<ion-label class="ion-text-center">{{ 'COMMON.NO_ELEMENT_FOUND' | translate }}</ion-label>
</ion-item>
</ion-col>
<ion-col *ngFor="let session of sessions">
<app-session-card [session]="session" [preview]="true" (click)="app.goToInTabs(['sessions', session.sessionId])"></app-session-card>
</ion-col>
</ion-list>
</ion-col>
</ion-row>
</ion-grid>
</ion-content>
Empty file.
51 changes: 51 additions & 0 deletions front-end/src/app/tabs/speakers/speaker.page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

import { IDEALoadingService, IDEAMessageService } from '@idea-ionic/common';

import { AppService } from 'src/app/app.service';
import { SpeakersService } from './speakers.service';
import { SessionsService } from '../sessions/sessions.service';

import { Speaker } from '@models/speaker.model';
import { Session } from '@models/session.model';

@Component({
selector: 'app-speaker',
templateUrl: './speaker.page.html',
styleUrls: ['./speaker.page.scss']
})
export class SpeakerPage implements OnInit {
speaker: Speaker;
sessions: Session[];

constructor(
private route: ActivatedRoute,
private loading: IDEALoadingService,
private message: IDEAMessageService,
private _speakers: SpeakersService,
private _sessions: SessionsService,
public app: AppService
) {}

async ngOnInit() {
await this.loadData();
}

async loadData() {
try {
await this.loading.show();
const speakerId = this.route.snapshot.paramMap.get('speakerId');
this.speaker = await this._speakers.getById(speakerId);
this.sessions = await this._sessions.getList({ speaker: this.speaker.speakerId, force: true });
} catch (err) {
this.message.error('COMMON.NOT_FOUND');
} finally {
await this.loading.hide();
}
}

async filterSessions(search: string = ''): Promise<void> {
this.sessions = await this._sessions.getList({ search, speaker: this.speaker.speakerId });
}
}
14 changes: 11 additions & 3 deletions front-end/src/app/tabs/speakers/speakerCard.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,24 @@ import { Speaker } from '@models/speaker.model';
<ion-card *ngIf="preview" [color]="preview ? 'white' : ''">
<ion-card-header>
<ion-card-title>{{ speaker.name }}</ion-card-title>
<ion-card-subtitle>{{ speaker.description }}</ion-card-subtitle>
<ion-card-subtitle>{{ speaker.organization.name }}</ion-card-subtitle>
</ion-card-header>
</ion-card>
<ion-card *ngIf="!preview" color="white">
<ion-card-header>
<ion-card-subtitle style="font-weight: 300;" class="ion-text-right">
<ion-card-subtitle class="ion-text-right">
<ion-img [src]="app.getImageURLByURI(speaker.imageURI)"></ion-img>
</ion-card-subtitle>
<ion-card-title>{{ speaker.name }}</ion-card-title>
<ion-card-subtitle>{{ speaker.organization }}</ion-card-subtitle>
<ion-card-subtitle>
<ion-button fill="clear" color="dark" (click)="app.goToInTabs(['organizations', speaker.organization.organizationId])">
{{ speaker.organization.name }}
</ion-button>
</ion-card-subtitle>
<ion-card-subtitle>
<a [href]="'mailto:' + speaker.contactEmail">{{ speaker.contactEmail }}</a>
</ion-card-subtitle>
</ion-card-header>
<ion-card-content>
<div class="divDescription" *ngIf="speaker.description">
Expand Down
16 changes: 16 additions & 0 deletions front-end/src/app/tabs/speakers/speakers-routing.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { SpeakersPage } from './speakers.page';
import { SpeakerPage } from './speaker.page';

const routes: Routes = [
{ path: '', component: SpeakersPage },
{ path: ':speakerId', component: SpeakerPage }
];

@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class SpeakersRoutingModule {}
25 changes: 25 additions & 0 deletions front-end/src/app/tabs/speakers/speakers.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { IonicModule } from '@ionic/angular';
import { FormsModule } from '@angular/forms';
import { IDEATranslationsModule } from '@idea-ionic/common';

import { SpeakersRoutingModule } from './speakers-routing.module';
import { SpeakerPage } from './speaker.page';
import { SpeakersPage } from './speakers.page';
import { SpeakerCardStandaloneComponent } from './speakerCard.component';
import { SessionCardStandaloneComponent } from '../sessions/sessionCard.component';

@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
IDEATranslationsModule,
SpeakersRoutingModule,
SpeakerCardStandaloneComponent,
SessionCardStandaloneComponent
],
declarations: [SpeakersPage, SpeakerPage]
})
export class SpeakersModule {}
27 changes: 27 additions & 0 deletions front-end/src/app/tabs/speakers/speakers.page.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<ion-header>
<ion-toolbar *ngIf="app.isInMobileMode()" color="ideaToolbar">
<ion-title class="ion-text-center">
{{ 'SPEAKERS.LIST' | translate }}
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list lines="inset" style="padding: 0; max-width: 500px; margin: 0 auto;">
<ion-searchbar #searchbar color="light" (ionInput)="filterSpeakers($event.target.value)"></ion-searchbar>
<ion-item color="white" class="noElements" *ngIf="speakers && !speakers.length">
<ion-label>{{ 'COMMON.NO_ELEMENT_FOUND' | translate }}</ion-label>
</ion-item>
<ion-item color="white" *ngIf="!speakers">
<ion-label><ion-skeleton-text animated></ion-skeleton-text></ion-label>
</ion-item>
<ion-item
color="white"
*ngFor="let speaker of speakers"
button
detail
(click)="selectSpeaker(speaker)"
>
<ion-label class="ion-text-wrap">{{ speaker.name }}</ion-label>
</ion-item>
</ion-list>
</ion-content>
Empty file.
49 changes: 49 additions & 0 deletions front-end/src/app/tabs/speakers/speakers.page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Component, OnInit, ViewChild } from '@angular/core';
import { IonContent } from '@ionic/angular';

import { Speaker } from '@models/speaker.model';
import { SpeakersService } from './speakers.service';
import { AppService } from 'src/app/app.service';
import { IDEALoadingService, IDEAMessageService } from '@idea-ionic/common';

@Component({
selector: 'app-speakers',
templateUrl: './speakers.page.html',
styleUrls: ['./speakers.page.scss']
})
export class SpeakersPage implements OnInit {
@ViewChild(IonContent) content: IonContent;

speakers: Speaker[];
filteredSpeakers: Speaker[];

constructor(
private loading: IDEALoadingService,
private message: IDEAMessageService,
private _speakers: SpeakersService,
public app: AppService
) {}

ngOnInit() {
this.loadData();
}

async loadData() {
try {
await this.loading.show();
this.speakers = await this._speakers.getList({});
} catch (error) {
this.message.error('COMMON.OPERATION_FAILED');
} finally {
this.loading.hide();
}
}

async filterSpeakers(search = ''): Promise<void> {
this.speakers = await this._speakers.getList({ search });
}

selectSpeaker(speaker: Speaker) {
this.app.goToInTabs(['speakers', speaker.speakerId]);
}
}
4 changes: 3 additions & 1 deletion front-end/src/app/tabs/speakers/speakers.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ export class SpeakersService {
constructor(private api: IDEAApiService) {}

private async loadList(organization?: string): Promise<void> {
this.speakers = (await this.api.getResource(['speakers'], { params: { organization } })).map(s => new Speaker(s));
const params: any = {};
if (organization) params.organization = organization;
this.speakers = (await this.api.getResource(['speakers'], { params: params })).map(s => new Speaker(s));
}

/**
Expand Down
4 changes: 4 additions & 0 deletions front-end/src/app/tabs/tabs.routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ const routes: Routes = [
{
path: 'organizations',
loadChildren: (): Promise<any> => import('./organizations/organizations.module').then(m => m.OrganizationsModule)
},
{
path: 'speakers',
loadChildren: (): Promise<any> => import('./speakers/speakers.module').then(m => m.SpeakersModule)
}
]
}
Expand Down
8 changes: 7 additions & 1 deletion front-end/src/assets/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@
"HOME": "Home",
"AGENDA": "Agenda",
"VENUES": "Venues",
"ORGANIZATIONS": "Organizations"
"ORGANIZATIONS": "Organizations",
"SPEAKERS": "Speakers"
},
"USER": {
"ESN_ACCOUNTS": "ESN Accounts",
Expand Down Expand Up @@ -353,5 +354,10 @@
"LIST": "Organizations list",
"DETAILS": "Organization details",
"SPEAKERS": "Speakers from this organization"
},
"SPEAKERS": {
"LIST": "Speakers list",
"DETAILS": "Speaker details",
"SESSIONS": "Sessions given by this speaker"
}
}

0 comments on commit b4d07cc

Please sign in to comment.