Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Added room front-end #78 #107 #118

Merged
merged 1 commit into from
Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions front-end/src/app/tabs/rooms/room.page.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<ion-header>
<ion-toolbar>
<ion-title>{{ 'ROOMS.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-room-card [room]="room"></app-room-card>
</ion-col>
<ion-col size="12" size-md="6">
<ion-list>
<ion-list-header>
<ion-label class="ion-text-center">
<h2>{{ 'ROOMS.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/rooms/room.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 { RoomsService } from './rooms.service';
import { SessionsService } from '../sessions/sessions.service';

import { Room } from '@models/room.model';
import { Session } from '@models/session.model';

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

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

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

async loadData() {
try {
await this.loading.show();
const roomId = this.route.snapshot.paramMap.get('roomId');
this.room = await this._rooms.getById(roomId);
this.sessions = await this._sessions.getList({ room: this.room.roomId, 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, room: this.room.roomId });
}
}
15 changes: 15 additions & 0 deletions front-end/src/app/tabs/rooms/rooms-routing.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { RoomPage } from './room.page';

const routes: Routes = [
{ path: ':roomId', component: RoomPage },
{ path: '', redirectTo: '/', pathMatch: 'full' }
];

@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class RoomsRoutingModule {}
24 changes: 24 additions & 0 deletions front-end/src/app/tabs/rooms/rooms.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
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 { RoomsRoutingModule } from './rooms-routing.module';
import { RoomPage } from './room.page';
import { RoomCardStandaloneComponent } from './roomCard.component';
import { SessionCardStandaloneComponent } from '../sessions/sessionCard.component';

@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
IDEATranslationsModule,
RoomsRoutingModule,
RoomCardStandaloneComponent,
SessionCardStandaloneComponent
],
declarations: [RoomPage]
})
export class RoomsModule {}
71 changes: 71 additions & 0 deletions front-end/src/app/tabs/sessions/sessionCard.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { Component, Input } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';

import { IDEATranslationsModule } from '@idea-ionic/common';

import { AppService } from 'src/app/app.service';

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

@Component({
standalone: true,
imports: [CommonModule, FormsModule, IonicModule, IDEATranslationsModule],
selector: 'app-session-card',
template: `
<ng-container *ngIf="session; else skeletonTemplate">
<ion-card *ngIf="preview" [color]="preview ? 'white' : ''">
<ion-card-header>
<ion-card-title>{{ session.name }}</ion-card-title>
<ion-card-subtitle>{{ session.description }}</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-button fill="clear" (click)="app.goToInTabs(['sessions', session.sessionId])">
<ion-icon name="location-outline"></ion-icon>
<ion-label>
{{ session.room.venue.name }}
</ion-label>
</ion-button>
</ion-card-subtitle>
<ion-card-title>{{ session.name }}</ion-card-title>
<ion-card-subtitle>{{ session.description }}</ion-card-subtitle>
</ion-card-header>
<ion-card-content>
<div class="divDescription" *ngIf="session.description">
<ion-textarea readonly [rows]="4" [(ngModel)]="session.description"></ion-textarea>
</div>
</ion-card-content>
</ion-card>
</ng-container>

<ng-template #skeletonTemplate>
<ion-card color="white">
<ion-skeleton-text animated style="height: 200px;"></ion-skeleton-text>
<ion-card-header>
<ion-card-title>
<ion-skeleton-text animated style="width: 60%;"></ion-skeleton-text>
</ion-card-title>
<ion-card-subtitle>
<ion-skeleton-text animated style="width: 50%;"></ion-skeleton-text>
</ion-card-subtitle>
</ion-card-header>
<ion-card-content>
<ion-skeleton-text animated style="width: 80%;"></ion-skeleton-text>
<ion-skeleton-text animated style="width: 70%;"></ion-skeleton-text>
<ion-skeleton-text animated style="width: 60%;"></ion-skeleton-text>
</ion-card-content>
</ion-card>
</ng-template>
`
})
export class SessionCardStandaloneComponent {
@Input() session: Session;
@Input() preview: boolean;

constructor(public app: AppService) {}
}
13 changes: 10 additions & 3 deletions front-end/src/app/tabs/sessions/sessions.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,29 @@ export class SessionsService {

constructor(private api: IDEAApiService) {}

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

/**
* Get (and optionally filter) the list of sessions.
* Note: it can be paginated.
* Note: it's a slice of the array.
* Note: if speaker id is passed, it will filter sessions for that speaker.
* Note: if room id is passed, it will filter sessions for that room.
*/
async getList(options: {
force?: boolean;
withPagination?: boolean;
startPaginationAfterId?: string;
search?: string;
speaker?: string;
room?: string;
}): Promise<Session[]> {
if (!this.sessions || options.force) await this.loadList();
if (!this.sessions || options.force) await this.loadList(options.speaker, options.room);
if (!this.sessions) return null;

options.search = options.search ? String(options.search).toLowerCase() : '';
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 @@ -20,6 +20,10 @@ const routes: Routes = [
{
path: 'venues',
loadChildren: (): Promise<any> => import('./venues/venues.module').then(m => m.VenuesModule)
},
{
path: 'rooms',
loadChildren: (): Promise<any> => import('./rooms/rooms.module').then(m => m.RoomsModule)
}
]
}
Expand Down
4 changes: 4 additions & 0 deletions front-end/src/assets/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -333,5 +333,9 @@
"MAP": "Map",
"DETAILS": "Venue's details",
"ROOMS": "Venue's rooms"
},
"ROOMS": {
"DETAILS": "Room details",
"SESSIONS": "Sessions hosted in this room"
}
}