Skip to content

Commit

Permalink
Merge pull request #2 from UdL-EPS-SoftArch/shelter-page
Browse files Browse the repository at this point in the history
Shelter page
  • Loading branch information
rogargon authored May 16, 2024
2 parents e81bde6 + f33c132 commit e638e64
Show file tree
Hide file tree
Showing 13 changed files with 479 additions and 7 deletions.
2 changes: 2 additions & 0 deletions src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { UserRegisterComponent } from './user/user-register/user-register.compon
import { UserEditComponent } from './user/user-edit/user-edit.component';
import { UserDeleteComponent } from './user/user-delete/user-delete.component';
import { ShelterListComponent } from './shelter/shelter-list/shelter-list.component'
import {ShelterCreateComponent} from "./shelter/shelter-create/shelter-create.component";

const routes: Routes = [
{ path: 'users/create', component: UserRegisterComponent},
Expand All @@ -20,6 +21,7 @@ const routes: Routes = [
{ path: '404', component: NotFoundComponent},
{ path: '', redirectTo: 'about', pathMatch: 'full'},
{ path: 'shelters', component: ShelterListComponent},
{ path: 'shelters/create', component: ShelterCreateComponent},
];

@NgModule({
Expand Down
11 changes: 9 additions & 2 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ import {AuthenticationBasicService} from './login-basic/authentication-basic.ser
import {LoggedInGuard} from './login-basic/loggedin.guard';
import {UserService} from './user/user.service';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
import {ShelterService} from "./shelter/shelter.service";
import {ShelterListComponent} from "./shelter/shelter-list/shelter-list.component";
import {ShelterCreateComponent} from "./shelter/shelter-create/shelter-create.component";
import {ShelterDetailComponent} from "./shelter/shelter-detail/shelter-detail.component";

@NgModule({
declarations: [
Expand All @@ -37,6 +41,9 @@ import { provideAnimationsAsync } from '@angular/platform-browser/animations/asy
UserEditComponent,
UserDeleteComponent,
UserSearchComponent,
ShelterListComponent,
ShelterCreateComponent,
ShelterDetailComponent
],
imports: [
BrowserModule,
Expand All @@ -50,12 +57,12 @@ import { provideAnimationsAsync } from '@angular/platform-browser/animations/asy
LoginBasicModule,
ErrorHandlerModule,
NgbModule,
ReactiveFormsModule,
ReactiveFormsModule
],
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: HttpErrorInterceptor, multi: true },
AuthenticationBasicService, LoggedInGuard, UserService, provideAnimationsAsync()
AuthenticationBasicService, LoggedInGuard, UserService, ShelterService, provideAnimationsAsync()
],
bootstrap: [AppComponent]
})
Expand Down
10 changes: 10 additions & 0 deletions src/app/navbar/navbar.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@
[routerLink]="['/users']"><span class="fas fa-user-circle"></span> List</a>
</div>
</li>
<li class="nav-item" *ngIf="isRole('user')" ngbDropdown>
<a class="nav-link dropdown-toggle" id="shelterDropdown" role="button"
aria-haspopup="true" aria-expanded="false" ngbDropdownToggle>Shelters</a>
<div class="dropdown-menu" aria-labelledby="playDropdown" ngbDropdownMenu>
<a class="dropdown-item" [routerLinkActive]="'active'" [routerLinkActiveOptions]="{ exact: true }"
[routerLink]="['/shelters']"><span class="fas fa-user-circle"></span> List</a>
<a class="dropdown-item" [routerLinkActive]="'active'" [routerLinkActiveOptions]="{ exact: true }"
[routerLink]="['/shelters/create']"><span class="fas fa-user-circle"></span> Create</a>
</div>
</li>
</ul>
<ul class="navbar-nav ms-auto me-3" app-login-navbar></ul>
</div>
Expand Down
97 changes: 97 additions & 0 deletions src/app/shelter/shelter-create/shelter-create.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<form
id="shelter-form"
(ngSubmit)="onSubmit()"
#form="ngForm"
[formGroup]="shelterForm"
>
<fieldset>
<div class="form-group mb-3">
<label class="control-label" for="name">Name*</label>
<input
id="name"
name="name"
formControlName="name"
type="text"
class="form-control"
[(ngModel)]="shelter.name"
/>
<div class="form-error" *ngIf="name.errors?.['required']">
Name is required.
</div>
<div
class="form-error"
*ngIf="name.errors?.['invalidName'] && !name.errors?.['required']"
>
Invalid name.
</div>
</div>

<div class="form-group mb-3">
<label class="control-label" for="email">Email</label>
<div class="email-input">
<input
id="email"
name="email"
formControlName="email"
type="text"
class="form-control"
[(ngModel)]="shelter.email"
/>
</div>
<div class="form-error" *ngIf="email.errors?.['invalidName']">
Invalid email.
</div>
</div>

<div class="form-group mb-3">
<label class="control-label" for="mobile">Mobile</label>
<div class="mobile-input">
<input
id="mobile"
name="mobile"
formControlName="mobile"
type="text"
class="form-control"
[(ngModel)]="shelter.mobile"
/>
</div>
<div class="form-error" *ngIf="mobile.errors?.['invalidName']">
Invalid mobile.
</div>
</div>

<!-- &lt;!&ndash; Added common names section &ndash;&gt;-->

<!-- <div *ngIf="commonNamesList.length > 0" class="added-cards-section mb-3">-->
<!-- <div-->
<!-- *ngFor="let commonName of commonNamesList; let i = index"-->
<!-- class="card"-->
<!-- >-->
<!-- <div class="card-wrapper">-->
<!-- <p>{{ commonName }}</p>-->
<!-- <div class="remove-card-btn" (click)="removeCommonName(i)">X</div>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->

<!-- Save and back buttons -->
<div class="form-group fa-pull-right mt-3">
<button
id="listBtn"
type="button"
[routerLink]="['..']"
class="btn btn-outline-primary pull-right"
>
Back
</button>
<button
id="submit"
type="submit"
[disabled]="!form.form.valid"
class="btn btn-success ms-3"
>
Submit
</button>
</div>
</fieldset>
</form>
129 changes: 129 additions & 0 deletions src/app/shelter/shelter-create/shelter-create.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import {Component, OnInit} from '@angular/core';
import {Router} from "@angular/router";
import {ShelterService} from "../shelter.service";
import {Shelter} from "../shelter";
import {AbstractControl, FormControl, FormGroup, ValidationErrors, ValidatorFn, Validators} from "@angular/forms";
import {ModalDismissReasons, NgbModal} from "@ng-bootstrap/ng-bootstrap";
import {PagedResourceCollection} from "@lagoshny/ngx-hateoas-client";
import {formatDate} from "@angular/common";

@Component({
selector: 'app-shelter-create',
templateUrl: './shelter-create.component.html',
})
export class ShelterCreateComponent implements OnInit{

closeResult = '';
public isModalSaved: boolean = false;
public shelters: Shelter[] = [];
public shelter: Shelter;
public commonNameInput: string = '';
public commonEmailsList: any = [];
public shelterForm: FormGroup;

constructor(
private router: Router,
private shelterService: ShelterService,
private modalService: NgbModal
) {}

ngOnInit(): void {
this.shelter = new Shelter();
this.shelterForm = new FormGroup({
name: new FormControl(this.shelter.name, [
Validators.required,
]),
email: new FormControl(this.shelter.email, [
Validators.required,
this.emailValidator(),
]),
mobile: new FormControl(this.shelter.mobile, [
Validators.required,
this.mobileValidator(),
]),
});
this.loadShelterList();
}

loadShelterList() {
this.shelterService
.getPage({
sort: { name: 'ASC' },
})
.subscribe((shelters: PagedResourceCollection<Shelter>) => {
this.shelters = shelters.resources.sort((a, b) =>
a.name.localeCompare(b.name)
);
});
}

open(content) {
this.modalService
.open(content, { ariaLabelledBy: 'modal-basic-title' })
.result.then(
(result) => {
this.closeResult = `Closed with: ${result}`;
},
(reason) => {
this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
}
);
}

private getDismissReason(reason: any): string {
if (reason === ModalDismissReasons.ESC) {
return 'by pressing ESC';
} else if (reason === ModalDismissReasons.BACKDROP_CLICK) {
return 'by clicking on a backdrop';
} else {
return `with: ${reason}`;
}
}

saveAndClose(modal: any) {
this.isModalSaved = true;
modal.close('Save click');
}

emailValidator(): ValidatorFn {
const nameRe: RegExp = /^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$/;
return (control: AbstractControl): ValidationErrors | null => {
const invalid = !nameRe.test(control.value);
return invalid ? { invalidName: { value: control.value } } : null;
};
}

mobileValidator(): ValidatorFn {
const nameRe: RegExp = /^$|[0-9]{11}/;
return (control: AbstractControl): ValidationErrors | null => {
const invalid = !nameRe.test(control.value);
return invalid ? { invalidName: { value: control.value } } : null;
};

}

get name() {
return this.shelterForm.get('name');
}

get email() {
return this.shelterForm.get('email');
}

get mobile() {
return this.shelterForm.get('mobile');
}

onSubmit(): void {
this.shelter.createdAt = new Date();
this.shelter.updatedAt = new Date();
this.shelterService
.createResource({ body: this.shelter })
.subscribe((shelter: Shelter) => {
console.log(shelter);
const uri = (shelter as any).uri;
this.router.navigate([uri]).then();
});
}

}
25 changes: 25 additions & 0 deletions src/app/shelter/shelter-delete/shelter-delete.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<div class="panel panel-warning">
<div class="panel-heading">
<div class="panel-title">Please, confirm deletion:</div>
</div>
<div class="panel-body">
<div class="text-center">
<button
id="deleteBtn"
type="button"
(click)="delete()"
class="btn btn-outline-danger m-1"
>
Delete
</button>
<button
id="listBtn"
type="button"
[routerLink]="['..']"
class="btn btn-outline-primary m-1"
>
Cancel
</button>
</div>
</div>
</div>
37 changes: 37 additions & 0 deletions src/app/shelter/shelter-delete/shelter-delete.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import {Component, OnInit} from '@angular/core';
import {ActivatedRoute, Router} from "@angular/router";
import {Shelter} from "../shelter";
import {ShelterService} from "../shelter.service";

@Component({
selector: 'app-shelter-delete',
templateUrl: './shelter-delete.component.html',
})
export class ShelterDeleteComponent implements OnInit {
idShelter: string;
shelter: Shelter;
constructor(
private router: Router,
private shelterService: ShelterService,
private route: ActivatedRoute
) {}
ngOnInit(): void {
this.idShelter = this.route.snapshot.paramMap.get('id');
}
delete() {
this.shelterService.getResource(this.idShelter).subscribe((shelter: Shelter) => {
this.shelter = shelter;
this.shelterService
.patchResource(this.shelter)
.subscribe((patchedShelter: Shelter) => {
this.shelterService.deleteResourceById(patchedShelter.id).subscribe({
next: (e) => {
this.router.navigateByUrl('/shelters');
},
error: (err) => {
},
});
});
});
}
}
Loading

0 comments on commit e638e64

Please sign in to comment.