Skip to content

Commit

Permalink
feat: add basic refuge detail skeleton
Browse files Browse the repository at this point in the history
  • Loading branch information
oriolagobat committed Nov 14, 2023
1 parent 4938e39 commit 97e3f23
Show file tree
Hide file tree
Showing 19 changed files with 421 additions and 11 deletions.
38 changes: 38 additions & 0 deletions app/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@
"tslib": "^2.3.0",
"zone.js": "~0.13.0",
"@capacitor/preferences": "^5.0.6",
"@types/uuid": "^9.0.5"
"@types/uuid": "^9.0.5",
"@capacitor/device": "^5.0.6",
"@ngx-translate/core": "^15.0.0",
"@ngx-translate/http-loader": "^8.0.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "^16.0.0",
Expand Down
19 changes: 18 additions & 1 deletion app/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,18 @@ import { IonicModule, IonicRouteStrategy } from '@ionic/angular';

import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
import {
HTTP_INTERCEPTORS,
HttpClient,
HttpClientModule,
} from '@angular/common/http';
import { AuthInterceptor } from './interceptors/auth.interceptor';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';

export function createTranslateLoader(http: HttpClient) {
return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}

@NgModule({
declarations: [AppComponent],
Expand All @@ -16,6 +26,13 @@ import { AuthInterceptor } from './interceptors/auth.interceptor';
IonicModule.forRoot(),
AppRoutingModule,
HttpClientModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: createTranslateLoader,
deps: [HttpClient],
},
}),
],
providers: [
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion app/src/app/pages/login/login.page.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
<ion-input
label="Username"
labelPlacement="stacked"
[clearInput]="true"
placeholder="John Doe"
fill="outline"
[(ngModel)]="credentials.username"
Expand All @@ -40,6 +39,7 @@
type="password"
errorText="Password is required"
required="Password is required"
(keyup.enter)="onLogin(loginForm)"
>
</ion-input>
<ion-note color="danger" *ngIf="hasError"> {{errorMessage}} </ion-note>
Expand Down
13 changes: 13 additions & 0 deletions app/src/app/pages/refuges/refuge-detail/refuge-detail.page.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<ion-header [translucent]="true">
<ion-toolbar>
<ion-title>refuge-detail</ion-title>
</ion-toolbar>
</ion-header>

<ion-content [fullscreen]="true">
<ion-header collapse="condense">
<ion-toolbar>
<ion-title size="large">refuge-detail</ion-title>
</ion-toolbar>
</ion-header>
</ion-content>
Empty file.
17 changes: 17 additions & 0 deletions app/src/app/pages/refuges/refuge-detail/refuge-detail.page.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { RefugeDetailPage } from './refuge-detail.page';

describe('RefugeDetailPage', () => {
let component: RefugeDetailPage;
let fixture: ComponentFixture<RefugeDetailPage>;

beforeEach(async(() => {
fixture = TestBed.createComponent(RefugeDetailPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));

it('should create', () => {
expect(component).toBeTruthy();
});
});
146 changes: 146 additions & 0 deletions app/src/app/pages/refuges/refuge-detail/refuge-detail.page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { RefugeService } from '../../../services/refuge/refuge.service';
import { AlertController, LoadingController } from '@ionic/angular';
import { TranslateService } from '@ngx-translate/core';
import {
GetRefugeFromIdErrors,
GetRefugeResponse,
} from '../../../../schemas/refuge/get-refuge-schema';
import { match } from 'ts-pattern';
import { Refuge } from '../../../../schemas/refuge/refuge';

@Component({
selector: 'app-refuge-detail',
templateUrl: './refuge-detail.page.html',
styleUrls: ['./refuge-detail.page.scss'],
})
export class RefugeDetailPage implements OnInit {
refuge?: Refuge;

constructor(
private router: Router,
private route: ActivatedRoute,
private refugeService: RefugeService,
private alertController: AlertController,
private loadingController: LoadingController,
private translateService: TranslateService,
) {
const refugeId = this.getRefugeIdFromUrl();
this.fetchRefuge(refugeId).then();
}

ngOnInit() {}

private async fetchRefuge(refugeId: string | null): Promise<void> {
if (refugeId != null) this.fetchRefugeFromId(refugeId);
else this.router.navigate(['login']).then();
}

private getRefugeIdFromUrl(): string | null {
return this.route.snapshot.paramMap.get('id');
}

private fetchRefugeFromId(refugeId: string) {
this.refugeService.getRefugeFrom(refugeId).subscribe({
next: (response: GetRefugeResponse) =>
this.handleGetRefugeResponse(response),
error: () => this.handleClientError().then(),
});
}

private handleGetRefugeResponse(response: GetRefugeResponse) {
match(response)
.with({ status: 'correct' }, (response) => (this.refuge = response.data))
.with({ status: 'error' }, (response) => {
this.handleGetError(response.error);
})
.exhaustive();
}

private handleGetError(error: GetRefugeFromIdErrors) {
match(error)
.with(GetRefugeFromIdErrors.NOT_FOUND, () => this.handleNotFoundRefuge())
.with(GetRefugeFromIdErrors.CLIENT_SEND_DATA_ERROR, () =>
this.handleBadUserData(),
)
.with(GetRefugeFromIdErrors.UNKNOWN_ERROR, () =>
this.handleUnknownError(),
)
.with(
GetRefugeFromIdErrors.SERVER_INCORRECT_DATA_FORMAT_ERROR,
GetRefugeFromIdErrors.PROGRAMMER_SEND_DATA_ERROR,
() => this.handleBadProgrammerData(),
)
.exhaustive();
}

private async handleClientError() {
const alert = await this.alertController.create({
header: this.translateService.instant('HOME.ERRORS.CLIENT_ERROR.HEADER'),
subHeader: this.translateService.instant(
'HOME.ERRORS.CLIENT_ERROR.SUBHEADER',
),
message: this.translateService.instant(
'HOME.ERRORS.CLIENT_ERROR.MESSAGE',
),
buttons: [
{
text: this.translateService.instant('HOME.ERRORS.CLIENT_ERROR.EXIT'),
handler: () => {
this.alertController.dismiss().then();
this.fetchRefuge(this.getRefugeIdFromUrl());
},
},
],
});
return await alert.present();
}

private handleNotFoundRefuge() {
this.finishLoadAnimAndExecute(() =>
this.router
.navigate(['not-found'], {
skipLocationChange: true,
})
.then(),
).then();
}

private handleBadProgrammerData() {
this.finishLoadAnimAndExecute(() =>
this.router
.navigate(['programming-error'], {
skipLocationChange: true,
})
.then(),
).then();
}

private handleBadUserData() {
this.finishLoadAnimAndExecute(() =>
this.router
.navigate(['not-found-page'], {
skipLocationChange: true,
})
.then(),
).then();
}

private handleUnknownError() {
this.finishLoadAnimAndExecute(() =>
this.router
.navigate(['internal-error-page'], {
skipLocationChange: true,
})
.then(),
).then();
}

private async finishLoadAnimAndExecute(
func: (() => void) | (() => Promise<void>),
) {
await this.loadingController.dismiss().then();
await func();
}
}
15 changes: 10 additions & 5 deletions app/src/app/pages/refuges/refuge-list/refuges-list.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
GetAllRefugesErrors,
} from '../../../../schemas/refuge/get-all-refuges-schema';
import { RefugeService } from '../../../services/refuge/refuge.service';
import { TranslateService } from '@ngx-translate/core';

@Component({
selector: 'app-refuges',
Expand All @@ -35,6 +36,7 @@ export class RefugesListPage implements OnInit {
private router: Router,
private refugeService: RefugeService,
private alertController: AlertController,
private translateService: TranslateService,
) {
this.errors = this.refugeService.getRefuges().pipe(
filter(
Expand Down Expand Up @@ -87,13 +89,16 @@ export class RefugesListPage implements OnInit {

private async handleClientError() {
const alert = await this.alertController.create({
header: 'Alert',
subHeader: 'The client is failing',
message:
'Is your internet connection working? Maybe is our fault and our server is down.',
header: this.translateService.instant('HOME.ERRORS.CLIENT_ERROR.HEADER'),
subHeader: this.translateService.instant(
'HOME.ERRORS.CLIENT_ERROR.SUBHEADER',
),
message: this.translateService.instant(
'HOME.ERRORS.CLIENT_ERROR.MESSAGE',
),
buttons: [
{
text: 'OK',
text: this.translateService.instant('HOME.ERRORS.CLIENT_ERROR.EXIT'),
handler: () => {
this.alertController.dismiss().then();
},
Expand Down
8 changes: 7 additions & 1 deletion app/src/app/pages/refuges/refuges-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,20 @@ import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { RefugesListPage } from './refuge-list/refuges-list.page';
import { supervisorGuard } from '../../guards/admin.guard';
import { supervisorGuard } from '../../guards/supervisor.guard';
import { RefugeDetailPage } from './refuge-detail/refuge-detail.page';

const routes: Routes = [
{
path: '',
component: RefugesListPage,
canActivate: [supervisorGuard],
},
{
path: ':id',
component: RefugeDetailPage,
canActivate: [supervisorGuard],
},
];

@NgModule({
Expand Down
3 changes: 2 additions & 1 deletion app/src/app/pages/refuges/refuges.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { IonicModule } from '@ionic/angular';
import { RefugesPageRoutingModule } from './refuges-routing.module';

import { RefugesListPage } from './refuge-list/refuges-list.page';
import { RefugeDetailPage } from './refuge-detail/refuge-detail.page';

@NgModule({
imports: [
Expand All @@ -16,6 +17,6 @@ import { RefugesListPage } from './refuge-list/refuges-list.page';
RefugesPageRoutingModule,
NgOptimizedImage,
],
declarations: [RefugesListPage],
declarations: [RefugesListPage, RefugeDetailPage],
})
export class RefugesPageModule {}
16 changes: 16 additions & 0 deletions app/src/app/services/language/device-language.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';

import { DeviceLanguageService } from './device-language.service';

describe('DeviceLanguageService', () => {
let service: DeviceLanguageService;

beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(DeviceLanguageService);
});

it('should be created', () => {
expect(service).toBeTruthy();
});
});
Loading

0 comments on commit 97e3f23

Please sign in to comment.