diff --git a/angular.json b/angular.json
index 6dfe2c9..7621d68 100644
--- a/angular.json
+++ b/angular.json
@@ -60,7 +60,7 @@
{
"type": "initial",
"maximumWarning": "1mb",
- "maximumError": "2mb"
+ "maximumError": "2.5mb"
},
{
"type": "anyComponentStyle",
diff --git a/package-lock.json b/package-lock.json
index e7562e7..42f6819 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -25,6 +25,8 @@
"@ng-bootstrap/ng-bootstrap": "^16.0.0",
"@popperjs/core": "^2.11.8",
"bootstrap": "^5.3.2",
+ "moment": "^2.30.1",
+ "moment-timezone": "^0.5.45",
"rxjs": "~7.8.1",
"tslib": "^2.6.2",
"zone.js": "~0.14.4"
@@ -15318,6 +15320,25 @@
"safe-buffer": "~5.1.0"
}
},
+ "node_modules/moment": {
+ "version": "2.30.1",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
+ "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/moment-timezone": {
+ "version": "0.5.45",
+ "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.45.tgz",
+ "integrity": "sha512-HIWmqA86KcmCAhnMAN0wuDOARV/525R2+lOLotuGFzn4HO+FH+/645z2wx0Dt3iDv6/p61SIvKnDstISainhLQ==",
+ "dependencies": {
+ "moment": "^2.29.4"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/mrmime": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz",
@@ -32671,6 +32692,19 @@
}
}
},
+ "moment": {
+ "version": "2.30.1",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
+ "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how=="
+ },
+ "moment-timezone": {
+ "version": "0.5.45",
+ "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.45.tgz",
+ "integrity": "sha512-HIWmqA86KcmCAhnMAN0wuDOARV/525R2+lOLotuGFzn4HO+FH+/645z2wx0Dt3iDv6/p61SIvKnDstISainhLQ==",
+ "requires": {
+ "moment": "^2.29.4"
+ }
+ },
"mrmime": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz",
diff --git a/package.json b/package.json
index cf55b16..8e8c342 100644
--- a/package.json
+++ b/package.json
@@ -32,6 +32,8 @@
"@ng-bootstrap/ng-bootstrap": "^16.0.0",
"@popperjs/core": "^2.11.8",
"bootstrap": "^5.3.2",
+ "moment": "^2.30.1",
+ "moment-timezone": "^0.5.45",
"rxjs": "~7.8.1",
"tslib": "^2.6.2",
"zone.js": "~0.14.4"
diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index b9b4923..e0ea548 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -22,6 +22,10 @@ import {ShelterCertificateDeleteComponent} from "./shelter-certificate/shelter-c
import {ShelterCreateComponent} from "./shelter/shelter-create/shelter-create.component";
import {LocationListComponent} from "./location/location-list/location-list.component";
import {LocationCreateComponent} from "./location/location-create/location-create.component";
+import {ScheduleListComponent} from "./schedule/schedule-list/schedule-list.component";
+import {ScheduleCreateComponent} from "./schedule/schedule-create/schedule-create.component";
+import {ScheduleDetailComponent} from "./schedule/schedule-detail/schedule-detail.component";
+
const routes: Routes = [
{ path: 'users/create', component: UserRegisterComponent},
@@ -43,6 +47,9 @@ const routes: Routes = [
{ path: 'shelter-certificate/create', component: ShelterCertificateCreateComponent},
{ path: 'shelter-certificate/:id', component: ShelterCertificateDetailComponent},
{ path: 'shelter-certificate/:id/delete', component: ShelterCertificateDeleteComponent},
+ { path: 'schedules', component: ScheduleListComponent, canActivate: [LoggedInGuard]},
+ { path: 'schedules/create', component: ScheduleCreateComponent, canActivate: [LoggedInGuard]},
+ { path: 'schedules/:id', component: ScheduleDetailComponent, canActivate: [LoggedInGuard]},
{ path: 'about', component: AboutComponent},
{ path: '404', component: NotFoundComponent},
{ path: '', redirectTo: 'about', pathMatch: 'full'},
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 677b01d..7b7a91a 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -42,6 +42,12 @@ import {LocationService} from './location/location.service'
import {LocationListComponent} from './location/location-list/location-list.component';
import {LocationSearchComponent} from './location/location-search/location-search.component';
import {LocationCreateComponent} from "./location/location-create/location-create.component";
+import {ScheduleService} from './schedule/schedule.service'
+import {ScheduleListComponent} from './schedule/schedule-list/schedule-list.component';
+import {ScheduleSearchComponent} from './schedule/schedule-search/schedule-search.component';
+import {ScheduleCreateComponent} from "./schedule/schedule-create/schedule-create.component";
+import {ScheduleDetailComponent} from "./schedule/schedule-detail/schedule-detail.component";
+
@NgModule({
declarations: [
@@ -65,6 +71,10 @@ import {LocationCreateComponent} from "./location/location-create/location-creat
ShelterCertificateCreateComponent,
ShelterCertificateDetailComponent,
ShelterCertificateDeleteComponent,
+ ScheduleListComponent,
+ ScheduleSearchComponent,
+ ScheduleCreateComponent,
+ ScheduleDetailComponent,
ShelterListComponent,
ShelterCreateComponent,
ShelterDetailComponent,
@@ -89,7 +99,7 @@ import {LocationCreateComponent} from "./location/location-create/location-creat
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: HttpErrorInterceptor, multi: true },
- AuthenticationBasicService, LoggedInGuard, UserService, ShelterService, LocationService,
+ AuthenticationBasicService, LoggedInGuard, UserService, ScheduleService, ShelterService, LocationService,
provideAnimationsAsync()
],
bootstrap: [AppComponent]
diff --git a/src/app/navbar/navbar.component.html b/src/app/navbar/navbar.component.html
index dd11dc3..b8a93f8 100644
--- a/src/app/navbar/navbar.component.html
+++ b/src/app/navbar/navbar.component.html
@@ -28,6 +28,15 @@
[routerLink]="['/shelter-certificate/create']"> Create
+
+ Schedules
+
Shelters
diff --git a/src/app/schedule/schedule-create/schedule-create.component.html b/src/app/schedule/schedule-create/schedule-create.component.html
new file mode 100644
index 0000000..57db4d6
--- /dev/null
+++ b/src/app/schedule/schedule-create/schedule-create.component.html
@@ -0,0 +1,30 @@
+
diff --git a/src/app/schedule/schedule-create/schedule-create.component.ts b/src/app/schedule/schedule-create/schedule-create.component.ts
new file mode 100644
index 0000000..4fb38b1
--- /dev/null
+++ b/src/app/schedule/schedule-create/schedule-create.component.ts
@@ -0,0 +1,60 @@
+import {Component, OnInit} from '@angular/core';
+import {Router} from '@angular/router';
+import {AuthenticationBasicService} from 'src/app/login-basic/authentication-basic.service';
+import {Schedule} from '../schedule';
+import {ScheduleService} from '../schedule.service';
+import {PagedResourceCollection} from '@lagoshny/ngx-hateoas-client';
+import {HttpClient} from '@angular/common/http';
+import {environment} from "../../../environments/environment";
+import * as moment from 'moment';
+import 'moment-timezone';
+
+@Component({
+ selector: 'app-schedules-create',
+ templateUrl: './schedule-create.component.html',
+})
+export class ScheduleCreateComponent implements OnInit {
+
+ public schedule: Schedule = new Schedule();
+
+ public startTime: Date;
+ public endTime: Date;
+ public shelter: string;
+ public schedules: Schedule[] = [];
+ public pageSize = 5;
+ public page = 1;
+ public totalSchedules = 0;
+ public creationDate: Date
+ public authserv: AuthenticationBasicService;
+ public types: [];
+
+ constructor(private router: Router,
+ private authenticationService: AuthenticationBasicService,
+ private scheduleService: ScheduleService,
+
+ private http: HttpClient) { }
+
+ ngOnInit(): void {
+ this.creationDate = new Date();
+ this.http.get(`${environment.API}/profile/schedules`)
+ .subscribe(data => {
+ this.types = (data.alps.descriptor[0].descriptor[2].doc.value).split(',').sort();
+ });
+
+ this.scheduleService.getPage({ pageParams: { size: this.pageSize }, sort: { id: 'ASC' } }).subscribe(
+ (page: PagedResourceCollection) => {
+ this.schedules = page.resources;
+ this.totalSchedules = page.totalElements;
+ });
+ }
+
+ onSubmit(): void {
+
+ this.schedule.startTime = moment.tz(this.schedule.startTime.toString(), 'America/Los_Angeles')
+ this.schedule.endTime = moment.tz(this.schedule.endTime.toString(), 'America/Los_Angeles')
+ this.scheduleService.createResource({ body: this.schedule }).subscribe(
+ (schedule:Schedule) => this.router.navigate([schedule.uri]));
+ }
+
+
+}
diff --git a/src/app/schedule/schedule-detail/schedule-detail.component.html b/src/app/schedule/schedule-detail/schedule-detail.component.html
new file mode 100644
index 0000000..3f19cf8
--- /dev/null
+++ b/src/app/schedule/schedule-detail/schedule-detail.component.html
@@ -0,0 +1,26 @@
+
+
+
{{schedule.id}}
+
+
+
StartTime
+
{{schedule.startTime}}
+
+
+
EndTime
+
{{schedule.endTime}}
+
+
+
+
+
diff --git a/src/app/schedule/schedule-detail/schedule-detail.component.ts b/src/app/schedule/schedule-detail/schedule-detail.component.ts
new file mode 100644
index 0000000..27b444a
--- /dev/null
+++ b/src/app/schedule/schedule-detail/schedule-detail.component.ts
@@ -0,0 +1,26 @@
+import { Component, OnInit } from '@angular/core';
+import { ActivatedRoute } from '@angular/router';
+import { AuthenticationBasicService } from '../../login-basic/authentication-basic.service';
+import {ScheduleService} from "../schedule.service";
+import {Schedule} from "../schedule";
+
+@Component({
+ selector: 'app-schedule-detail',
+ templateUrl: './schedule-detail.component.html'
+})
+export class ScheduleDetailComponent implements OnInit {
+ public schedule: Schedule = new Schedule();
+
+ constructor(private route: ActivatedRoute,
+ private scheduleService: ScheduleService) {
+ }
+
+ ngOnInit(): void {
+ const id = this.route.snapshot.paramMap.get('id');
+ this.scheduleService.getResource(id).subscribe(
+ schedule => {
+ this.schedule = schedule;
+ });
+ }
+
+}
diff --git a/src/app/schedule/schedule-list/schedule-list.component.html b/src/app/schedule/schedule-list/schedule-list.component.html
new file mode 100644
index 0000000..f156f4e
--- /dev/null
+++ b/src/app/schedule/schedule-list/schedule-list.component.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
StartTime
+
{{schedule.startTime}}
+
EndTime
+
{{schedule.endTime}}
+
+
+
+
+
+
+
+
diff --git a/src/app/schedule/schedule-list/schedule-list.component.ts b/src/app/schedule/schedule-list/schedule-list.component.ts
new file mode 100644
index 0000000..b770e0d
--- /dev/null
+++ b/src/app/schedule/schedule-list/schedule-list.component.ts
@@ -0,0 +1,38 @@
+import { Router } from '@angular/router';
+import { Component, OnInit } from '@angular/core';
+import { ScheduleService } from '../schedule.service';
+import { PagedResourceCollection } from '@lagoshny/ngx-hateoas-client';
+import {Schedule} from "../schedule";
+
+@Component({
+ selector: 'app-schedule-list',
+ templateUrl: './schedule-list.component.html'
+})
+export class ScheduleListComponent implements OnInit {
+ public schedules: Schedule[] = [];
+ public pageSize = 5;
+ public page = 1;
+ public totalSchedules = 0;
+
+ constructor(
+ public router: Router,
+ private scheduleService: ScheduleService) {
+ }
+
+ ngOnInit(): void {
+ this.scheduleService.getPage({ pageParams: { size: this.pageSize }, sort: { id: 'ASC' } }).subscribe(
+ (page: PagedResourceCollection) => {
+ this.schedules = page.resources;
+ this.totalSchedules = page.totalElements;
+ });
+ }
+
+ changePage(): void {
+ this.scheduleService.getPage({ pageParams: { page: this.page - 1, size: this.pageSize }, sort: { id: 'ASC' } }).subscribe(
+ (page: PagedResourceCollection) => this.schedules = page.resources);
+ }
+
+ detail(schedule: Schedule): void {
+ this.router.navigate(['schedules', schedule.id]);
+ }
+}
diff --git a/src/app/schedule/schedule-search/schedule-search.component.html b/src/app/schedule/schedule-search/schedule-search.component.html
new file mode 100644
index 0000000..1bdb926
--- /dev/null
+++ b/src/app/schedule/schedule-search/schedule-search.component.html
@@ -0,0 +1,11 @@
+
+
+
+
+ {{r.email}}
+
diff --git a/src/app/schedule/schedule-search/schedule-search.component.ts b/src/app/schedule/schedule-search/schedule-search.component.ts
new file mode 100644
index 0000000..cda6450
--- /dev/null
+++ b/src/app/schedule/schedule-search/schedule-search.component.ts
@@ -0,0 +1,42 @@
+import { Component, EventEmitter, Output } from '@angular/core';
+import { ScheduleService } from '../schedule.service';
+import { Observable, of, OperatorFunction } from 'rxjs';
+import { catchError, debounceTime, distinctUntilChanged, map, switchMap, tap } from 'rxjs/operators';
+import { ResourceCollection } from '@lagoshny/ngx-hateoas-client';
+import {Schedule} from "../schedule";
+
+@Component({
+ selector: 'app-schedule-search',
+ templateUrl: './schedule-search.component.html'
+})
+
+export class ScheduleSearchComponent {
+ @Output() emitResults: EventEmitter = new EventEmitter();
+ searchFailed = false;
+ searching = false;
+
+ constructor(private scheduleService: ScheduleService) {
+ }
+
+ autocomplete: OperatorFunction = (text$: Observable) =>
+ text$.pipe(
+ debounceTime(500),
+ distinctUntilChanged(),
+ tap(() => this.searching = true),
+ switchMap(term => term.length < 3 ? of([]) :
+ this.scheduleService.findById(term).pipe(
+ map((collection: ResourceCollection) => collection.resources),
+ tap(() => this.searchFailed = false),
+ catchError(() => {
+ this.searchFailed = true;
+ return of([]);
+ })
+ )
+ ),
+ tap(() => this.searching = false )
+ )
+
+ select(item: any): void {
+ this.emitResults.emit(item as Schedule);
+ }
+}
diff --git a/src/app/schedule/schedule.service.ts b/src/app/schedule/schedule.service.ts
new file mode 100644
index 0000000..c296157
--- /dev/null
+++ b/src/app/schedule/schedule.service.ts
@@ -0,0 +1,28 @@
+import { Injectable } from "@angular/core";
+import { Observable } from "rxjs/internal/Observable";
+import { HateoasResourceOperation, ResourceCollection } from "@lagoshny/ngx-hateoas-client";
+import { Schedule } from "./schedule";
+
+@Injectable({providedIn: "root"})
+export class ScheduleService extends HateoasResourceOperation {
+
+ constructor() {
+ super(Schedule);
+ }
+
+ public findById(id: string): Observable> {
+ return this.searchCollection("findByCreatedBy", { params: { id: id } })
+ }
+
+ public findByStartTime(startTime: string): Observable> {
+ return this.searchCollection("findByStartTime", { params: { startTime: startTime } })
+ }
+
+ public findByEndTime(endTime: string): Observable> {
+ return this.searchCollection("findByEndTime", { params: { endTime: endTime } })
+ }
+
+ public findByShelter(shelter: string): Observable> {
+ return this.searchCollection("findByShelter", { params: { shelter: shelter } })
+ }
+}
diff --git a/src/app/schedule/schedule.ts b/src/app/schedule/schedule.ts
new file mode 100644
index 0000000..0425a66
--- /dev/null
+++ b/src/app/schedule/schedule.ts
@@ -0,0 +1,15 @@
+import {HateoasResource, Resource} from '@lagoshny/ngx-hateoas-client';
+
+@HateoasResource('schedules')
+export class Schedule extends Resource {
+ id: number;
+ startTime: moment.Moment;
+ endTime: moment.Moment;
+ //shelter: string;
+ uri: string;
+
+ constructor(values: object = {}) {
+ super();
+ Object.assign(this as any, values);
+ }
+}
diff --git a/src/app/user/user-list/user-list.component.ts b/src/app/user/user-list/user-list.component.ts
index f3e1355..a7ab76c 100644
--- a/src/app/user/user-list/user-list.component.ts
+++ b/src/app/user/user-list/user-list.component.ts
@@ -5,7 +5,7 @@ import { User } from '../../login-basic/user';
import { PagedResourceCollection } from '@lagoshny/ngx-hateoas-client';
@Component({
- selector: 'app-shelter-certificate-list',
+ selector: 'app-user-list',
templateUrl: './user-list.component.html'
})
export class UserListComponent implements OnInit {