From 51788f2194b9b56269ceb4dd480b5d95e7823b51 Mon Sep 17 00:00:00 2001 From: Roland Schneider Date: Fri, 27 Sep 2019 23:03:03 +0200 Subject: [PATCH] add month calendar --- customer/app/package-lock.json | 5 + customer/app/package.json | 1 + customer/app/src/app/_helpers/fake-backend.ts | 91 +++++++++++++++---- customer/app/src/app/_helpers/index.ts | 3 +- customer/app/src/app/app-routing.module.ts | 2 + customer/app/src/app/app.module.ts | 10 ++ .../fit-weekday-selector.component.html | 11 +++ .../fit-weekday-selector.component.scss | 0 .../fit-weekday-selector.component.spec.ts | 25 +++++ .../fit-weekday-selector.component.ts | 29 ++++++ .../month-calendar-day.component.html | 15 +++ .../month-calendar-day.component.scss | 20 ++++ .../month-calendar-day.component.spec.ts | 25 +++++ .../month-calendar-day.component.ts | 54 +++++++++++ .../month-calendar-event.component.html | 9 ++ .../month-calendar-event.component.scss | 0 .../month-calendar-event.component.spec.ts | 25 +++++ .../month-calendar-event.component.ts | 44 +++++++++ .../month-calendar.component.html | 15 +++ .../month-calendar.component.scss | 22 +++++ .../month-calendar.component.spec.ts | 25 +++++ .../month-calendar.component.ts | 91 +++++++++++++++++++ .../event-details.component.html | 36 ++++++++ .../event-details.component.scss | 0 .../event-details.component.spec.ts | 25 +++++ .../event-details/event-details.component.ts | 53 +++++++++++ .../src/app/pages/home/home.component.html | 10 +- .../app/src/app/pages/home/home.component.ts | 17 +++- customer/app/src/app/services/endpoints.ts | 5 + .../app/src/app/services/event.service.ts | 17 +++- .../app/services/navigation.service.spec.ts | 12 +++ .../src/app/services/navigation.service.ts | 24 +++++ customer/app/src/styles.scss | 2 +- 33 files changed, 698 insertions(+), 25 deletions(-) create mode 100644 customer/app/src/app/components/fit-weekday-selector/fit-weekday-selector.component.html create mode 100644 customer/app/src/app/components/fit-weekday-selector/fit-weekday-selector.component.scss create mode 100644 customer/app/src/app/components/fit-weekday-selector/fit-weekday-selector.component.spec.ts create mode 100644 customer/app/src/app/components/fit-weekday-selector/fit-weekday-selector.component.ts create mode 100644 customer/app/src/app/components/month-calendar-day/month-calendar-day.component.html create mode 100644 customer/app/src/app/components/month-calendar-day/month-calendar-day.component.scss create mode 100644 customer/app/src/app/components/month-calendar-day/month-calendar-day.component.spec.ts create mode 100644 customer/app/src/app/components/month-calendar-day/month-calendar-day.component.ts create mode 100644 customer/app/src/app/components/month-calendar-event/month-calendar-event.component.html create mode 100644 customer/app/src/app/components/month-calendar-event/month-calendar-event.component.scss create mode 100644 customer/app/src/app/components/month-calendar-event/month-calendar-event.component.spec.ts create mode 100644 customer/app/src/app/components/month-calendar-event/month-calendar-event.component.ts create mode 100644 customer/app/src/app/components/month-calendar/month-calendar.component.html create mode 100644 customer/app/src/app/components/month-calendar/month-calendar.component.scss create mode 100644 customer/app/src/app/components/month-calendar/month-calendar.component.spec.ts create mode 100644 customer/app/src/app/components/month-calendar/month-calendar.component.ts create mode 100644 customer/app/src/app/pages/event-details/event-details.component.html create mode 100644 customer/app/src/app/pages/event-details/event-details.component.scss create mode 100644 customer/app/src/app/pages/event-details/event-details.component.spec.ts create mode 100644 customer/app/src/app/pages/event-details/event-details.component.ts create mode 100644 customer/app/src/app/services/navigation.service.spec.ts create mode 100644 customer/app/src/app/services/navigation.service.ts diff --git a/customer/app/package-lock.json b/customer/app/package-lock.json index 4cc2cb9..73f3284 100644 --- a/customer/app/package-lock.json +++ b/customer/app/package-lock.json @@ -5937,6 +5937,11 @@ } } }, + "moment": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" + }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", diff --git a/customer/app/package.json b/customer/app/package.json index f830b27..88d345d 100644 --- a/customer/app/package.json +++ b/customer/app/package.json @@ -23,6 +23,7 @@ "@fortawesome/fontawesome-svg-core": "^1.2.19", "@fortawesome/free-solid-svg-icons": "^5.9.0", "bootstrap": "^4.3.1", + "moment": "^2.24.0", "ngx-bootstrap": "^5.0.0", "rxjs": "~6.4.0", "tslib": "^1.9.0", diff --git a/customer/app/src/app/_helpers/fake-backend.ts b/customer/app/src/app/_helpers/fake-backend.ts index 00d1b45..cc8954c 100644 --- a/customer/app/src/app/_helpers/fake-backend.ts +++ b/customer/app/src/app/_helpers/fake-backend.ts @@ -1,23 +1,22 @@ import {Injectable} from "@angular/core"; import { - HttpRequest, - HttpResponse, - HttpHandler, + HTTP_INTERCEPTORS, HttpEvent, + HttpHandler, HttpInterceptor, - HTTP_INTERCEPTORS + HttpRequest, + HttpResponse } from '@angular/common/http'; import {Observable, of, throwError} from 'rxjs'; -import {delay, mergeMap, materialize, dematerialize} from 'rxjs/operators'; -import {Event, EventType, Trainer} from "../services/event.service"; -import {identifierModuleUrl} from "@angular/compiler"; +import {delay, dematerialize, materialize, mergeMap} from 'rxjs/operators'; +import {DayToDisplay, Event, EventType, Trainer} from "../services/event.service"; +import * as moment from "moment"; -; /* FAKE BACKEND -This will serve as a standalone backend with delayed response so that it can imitate a real backend - using +This will serve as a standalone backend with delayed response so that it can imitate a real backend - using DELAYED OBSERVABLE 1. It will check the user credentails that come from "Authentication Service" during login @@ -66,8 +65,7 @@ export class FakeBackendInterceptor implements HttpInterceptor { name: "weight lift Trainer" }; - let events: Event[] = [ - ]; + let events: Event[] = []; let id = 1000; for (let dayIndex = 0; dayIndex < 28; dayIndex++) { @@ -75,7 +73,7 @@ export class FakeBackendInterceptor implements HttpInterceptor { for (let itemIndex = 0; itemIndex < 3; itemIndex++) { id = id + 1; - let reservedAt = id % 2 ? this.createEventDate(0,1) : null; + let reservedAt = id % 2 ? this.createEventDate(0, 1) : null; events.push( { id: id, @@ -85,7 +83,7 @@ export class FakeBackendInterceptor implements HttpInterceptor { trainer: [trainer1, trainer2][id % 2], eventType: eventTypes[id % eventTypes.length], reservedAt: reservedAt, - reservationCount: id% 11, + reservationCount: id % 11, seatCount: 10, } ) @@ -113,7 +111,7 @@ export class FakeBackendInterceptor implements HttpInterceptor { firstName: testUser.firstName, lastName: testUser.lastName, token: '0000-fake-jwt-token-0000' - } + }; return of(new HttpResponse({status: 200, body})) } else { @@ -161,6 +159,60 @@ export class FakeBackendInterceptor implements HttpInterceptor { }); } } + if (request.url.endsWith('/events/available') && request.method === 'GET') { + + const data = { + days: [], + events: [] + }; + moment.locale("hu"); + let _moment = moment(); + const today = _moment.startOf('day'); + + const startOfWeek = _moment.clone().startOf("week").startOf('day'); + + const nextDays :DayToDisplay[] = []; + for (let i = 0; i < 21; i++) { + let active = false; + let nextDay = startOfWeek.clone().add(i, 'd').startOf("day"); + if (nextDay.isAfter(today) || nextDay.isSameOrAfter(today)) { + active = true; + } + nextDays.push( + { + date: nextDay.toDate().getTime(), + active: active + } as DayToDisplay + ); + } + data.days = nextDays; + + nextDays.forEach(value => { + value.events = []; + const startOfDay = value.date + const endOfDay = moment(startOfDay).add(1,'d').toDate().getTime(); + events.forEach( event => { + if ( event.start >= value.date && event.start < endOfDay){ + value.events.push(event); + } + } ) + }); + + // + // const until = nextDays[nextDays.length - 1].toDate().getTime(); + // const availableEvents = events.filter(value => { + // return value.start < until; + // }); + // + // nextDays.forEach(value => { + // data.days.push(value.toDate().getTime()); + // }); + + // data.events = availableEvents; + + return of(new HttpResponse({status: 200, body: data})); + + } if (request.url.indexOf('/events') >= 0 && request.method === 'GET') { @@ -186,8 +238,8 @@ export class FakeBackendInterceptor implements HttpInterceptor { const length = GET_EVENT.length; pos = pos + length; let idEvent = request.url.substr(pos); - let event = events.find(value => value.id == +idEvent ); - return of(new HttpResponse({status: 200, body: event }) ); + let event = events.find(value => value.id == +idEvent); + return of(new HttpResponse({status: 200, body: event})); } else { // invalid JWT token found in request header return throwError({ @@ -201,9 +253,9 @@ export class FakeBackendInterceptor implements HttpInterceptor { if (request.headers.get('Authorization') === 'Bearer 0000-fake-jwt-token-0000') { if (request.url.indexOf('event/register&id_event=') && request.method === 'POST') { - return of(new HttpResponse({status: 200, body: {} }) ); - }else if (request.url.indexOf('event/cancel&id_event=') && request.method === 'POST') { - return of(new HttpResponse({status: 200, body: {} }) ); + return of(new HttpResponse({status: 200, body: {}})); + } else if (request.url.indexOf('event/cancel&id_event=') && request.method === 'POST') { + return of(new HttpResponse({status: 200, body: {}})); } } else { // invalid JWT token found in request header @@ -232,7 +284,6 @@ export class FakeBackendInterceptor implements HttpInterceptor { } } - // creating a PROVIDER export let fakeBackendProvider = { // use fake backend in place of Http service for backend-less development diff --git a/customer/app/src/app/_helpers/index.ts b/customer/app/src/app/_helpers/index.ts index b4668ef..67c3570 100644 --- a/customer/app/src/app/_helpers/index.ts +++ b/customer/app/src/app/_helpers/index.ts @@ -1,3 +1,4 @@ export * from './error.interceptor'; export * from './fake-backend'; -export * from './jwt.interceptor'; \ No newline at end of file +export * from './jwt.interceptor'; +export {DayToDisplay} from "../services/event.service"; diff --git a/customer/app/src/app/app-routing.module.ts b/customer/app/src/app/app-routing.module.ts index e193ea1..bb8e847 100644 --- a/customer/app/src/app/app-routing.module.ts +++ b/customer/app/src/app/app-routing.module.ts @@ -5,6 +5,7 @@ import {LoginComponent} from "./pages/login/login.component"; import {ProfileComponent} from "./pages/profile/profile.component"; import {AuthGuard} from "./_guards"; import {EventsComponent} from "./pages/events/events.component"; +import {EventDetailsComponent} from "./pages/event-details/event-details.component"; const routes: Routes = [ { path: 'home', component: HomeComponent }, @@ -13,6 +14,7 @@ const routes: Routes = [ { path: 'logout', redirectTo: '/login' , pathMatch: 'full'}, { path: 'profile', component: ProfileComponent, canActivate: [AuthGuard] }, { path: 'events', component: EventsComponent, canActivate: [AuthGuard] }, + { path: 'event-details/:idEvent', component: EventDetailsComponent, canActivate: [AuthGuard] , pathMatch: 'full' }, ]; @NgModule({ diff --git a/customer/app/src/app/app.module.ts b/customer/app/src/app/app.module.ts index 8390480..5430b2f 100644 --- a/customer/app/src/app/app.module.ts +++ b/customer/app/src/app/app.module.ts @@ -23,6 +23,11 @@ import {FontAwesomeModule} from "@fortawesome/angular-fontawesome"; import { library } from '@fortawesome/fontawesome-svg-core'; import { faUserPlus , faUserMinus } from '@fortawesome/free-solid-svg-icons'; +import { FitWeekdaySelectorComponent } from './components/fit-weekday-selector/fit-weekday-selector.component'; +import { MonthCalendarComponent } from './components/month-calendar/month-calendar.component'; +import { MonthCalendarDayComponent } from './components/month-calendar-day/month-calendar-day.component'; +import { MonthCalendarEventComponent } from './components/month-calendar-event/month-calendar-event.component'; +import { EventDetailsComponent } from './pages/event-details/event-details.component'; @@ -40,6 +45,11 @@ registerLocaleData(localeHu, 'hu'); ProfileComponent, EventsComponent, FitEventTypesComponent, + FitWeekdaySelectorComponent, + MonthCalendarComponent, + MonthCalendarDayComponent, + MonthCalendarEventComponent, + EventDetailsComponent, ], imports: [ BrowserModule, diff --git a/customer/app/src/app/components/fit-weekday-selector/fit-weekday-selector.component.html b/customer/app/src/app/components/fit-weekday-selector/fit-weekday-selector.component.html new file mode 100644 index 0000000..c2ebcb8 --- /dev/null +++ b/customer/app/src/app/components/fit-weekday-selector/fit-weekday-selector.component.html @@ -0,0 +1,11 @@ +

fit-weekday-selector works!

+
+
+

+ {{ formatDayName( nextDay ) }} +

+

+ {{ formatDate( nextDay ) }} +

+
+
diff --git a/customer/app/src/app/components/fit-weekday-selector/fit-weekday-selector.component.scss b/customer/app/src/app/components/fit-weekday-selector/fit-weekday-selector.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/customer/app/src/app/components/fit-weekday-selector/fit-weekday-selector.component.spec.ts b/customer/app/src/app/components/fit-weekday-selector/fit-weekday-selector.component.spec.ts new file mode 100644 index 0000000..3abde5a --- /dev/null +++ b/customer/app/src/app/components/fit-weekday-selector/fit-weekday-selector.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { FitWeekdaySelectorComponent } from './fit-weekday-selector.component'; + +describe('FitWeekdaySelectorComponent', () => { + let component: FitWeekdaySelectorComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ FitWeekdaySelectorComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(FitWeekdaySelectorComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/customer/app/src/app/components/fit-weekday-selector/fit-weekday-selector.component.ts b/customer/app/src/app/components/fit-weekday-selector/fit-weekday-selector.component.ts new file mode 100644 index 0000000..1c8d1e8 --- /dev/null +++ b/customer/app/src/app/components/fit-weekday-selector/fit-weekday-selector.component.ts @@ -0,0 +1,29 @@ +import {Component, Input, OnInit} from '@angular/core'; +import * as moment from 'moment'; + +@Component({ + selector: 'app-fit-weekday-selector', + templateUrl: './fit-weekday-selector.component.html', + styleUrls: ['./fit-weekday-selector.component.scss'] +}) +export class FitWeekdaySelectorComponent implements OnInit { + + @Input() + days: number[] = []; + + constructor() { } + + ngOnInit() { + moment.locale("hu"); + } + + formatDayName(dateNum){ + return moment(dateNum).format("dddd"); + } + + + formatDate(dateNum){ + return moment(dateNum).format("YYYY-MM-DD"); + } + +} diff --git a/customer/app/src/app/components/month-calendar-day/month-calendar-day.component.html b/customer/app/src/app/components/month-calendar-day/month-calendar-day.component.html new file mode 100644 index 0000000..1e1eb59 --- /dev/null +++ b/customer/app/src/app/components/month-calendar-day/month-calendar-day.component.html @@ -0,0 +1,15 @@ +
+ {{getDateOfDay()}} + {{getDayOfWeekName()}} + +
+

No events

+ + + + + diff --git a/customer/app/src/app/components/month-calendar-day/month-calendar-day.component.scss b/customer/app/src/app/components/month-calendar-day/month-calendar-day.component.scss new file mode 100644 index 0000000..efc100a --- /dev/null +++ b/customer/app/src/app/components/month-calendar-day/month-calendar-day.component.scss @@ -0,0 +1,20 @@ +@media (max-width:575px) { + .display-4 { + font-size: 1.5rem; + } + .day h5 { + background-color: #f8f9fa; + padding: 3px 5px 5px; + margin: -8px -8px 8px -8px; + } + .date { + padding-left: 16px; + } +} + +@media (min-width: 576px) { + .day { + min-height: 14.2857vw; + } +} + diff --git a/customer/app/src/app/components/month-calendar-day/month-calendar-day.component.spec.ts b/customer/app/src/app/components/month-calendar-day/month-calendar-day.component.spec.ts new file mode 100644 index 0000000..bf21c32 --- /dev/null +++ b/customer/app/src/app/components/month-calendar-day/month-calendar-day.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { MonthCalendarDayComponent } from './month-calendar-day.component'; + +describe('MonthCalendarDayComponent', () => { + let component: MonthCalendarDayComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ MonthCalendarDayComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(MonthCalendarDayComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/customer/app/src/app/components/month-calendar-day/month-calendar-day.component.ts b/customer/app/src/app/components/month-calendar-day/month-calendar-day.component.ts new file mode 100644 index 0000000..d6a5ca5 --- /dev/null +++ b/customer/app/src/app/components/month-calendar-day/month-calendar-day.component.ts @@ -0,0 +1,54 @@ +import {Component, EventEmitter, HostBinding, Input, OnInit, Output} from '@angular/core'; +import {dateToMoment, Day, MonthCalendarEvent} from "../month-calendar/month-calendar.component"; +import {DayToDisplay} from "../../_helpers"; + +@Component({ + selector: '[app-month-calendar-day]', + templateUrl: './month-calendar-day.component.html', + styleUrls: ['./month-calendar-day.component.scss'] +}) +export class MonthCalendarDayComponent implements OnInit { + + @Input() + day: DayToDisplay; + + @Output() + onEvent: EventEmitter = new EventEmitter(); + + oMoment: any; + + constructor() { } + + ngOnInit() { + if ( this.day ){ + + console.info(this.day); + this.oMoment = dateToMoment(this.day.date); + } + } + + getDayOfWeekName(){ + return this.oMoment.format('dddd'); + } + + getDateOfDay(){ + return this.oMoment.format('DD'); + } + + hasEvents(){ + return this.day.active && this.day.events && this.day.events.length; + } + + @HostBinding('class') get styleClass(){ + let styleClass = "day col-sm p-2 border border-left-0 border-top-0 text-truncate"; + if ( !this.day.active ){ + styleClass += " d-none d-sm-inline-block bg-light text-muted"; + } + return styleClass; + } + + handleEvent($event){ + this.onEvent.emit($event); + } + +} diff --git a/customer/app/src/app/components/month-calendar-event/month-calendar-event.component.html b/customer/app/src/app/components/month-calendar-event/month-calendar-event.component.html new file mode 100644 index 0000000..f6ae3be --- /dev/null +++ b/customer/app/src/app/components/month-calendar-event/month-calendar-event.component.html @@ -0,0 +1,9 @@ + + {{formatTime()}}:{{event.eventType.name}} + +
+ {{formatTrainer()}} +
+
diff --git a/customer/app/src/app/components/month-calendar-event/month-calendar-event.component.scss b/customer/app/src/app/components/month-calendar-event/month-calendar-event.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/customer/app/src/app/components/month-calendar-event/month-calendar-event.component.spec.ts b/customer/app/src/app/components/month-calendar-event/month-calendar-event.component.spec.ts new file mode 100644 index 0000000..571c483 --- /dev/null +++ b/customer/app/src/app/components/month-calendar-event/month-calendar-event.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { MonthCalendarEventComponent } from './month-calendar-event.component'; + +describe('MonthCalendarEventComponent', () => { + let component: MonthCalendarEventComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ MonthCalendarEventComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(MonthCalendarEventComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/customer/app/src/app/components/month-calendar-event/month-calendar-event.component.ts b/customer/app/src/app/components/month-calendar-event/month-calendar-event.component.ts new file mode 100644 index 0000000..e679eb1 --- /dev/null +++ b/customer/app/src/app/components/month-calendar-event/month-calendar-event.component.ts @@ -0,0 +1,44 @@ +import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; +import {Event} from "../../services/event.service"; +import * as moment from "moment"; +import {MonthCalendarEvent} from "../month-calendar/month-calendar.component"; + +@Component({ + selector: 'app-month-calendar-event', + templateUrl: './month-calendar-event.component.html', + styleUrls: ['./month-calendar-event.component.scss'] +}) +export class MonthCalendarEventComponent implements OnInit { + + @Input() + event: Event; + + @Output() + onEvent = new EventEmitter(); + + constructor() { + } + + ngOnInit() { + } + + formatTime() { + return moment(this.event.start).format('HH:mm'); + } + + hasTrainer() { + return !!this.event.trainer; + } + + formatTrainer() { + const trainer = this.event.trainer; + return trainer.name; + } + + selectEvent() { + this.onEvent.emit({ + type: 'SELECT_EVENT', + event: this.event + }) + } +} diff --git a/customer/app/src/app/components/month-calendar/month-calendar.component.html b/customer/app/src/app/components/month-calendar/month-calendar.component.html new file mode 100644 index 0000000..9092f69 --- /dev/null +++ b/customer/app/src/app/components/month-calendar/month-calendar.component.html @@ -0,0 +1,15 @@ +
+
+

Naptár

+
+
{{dayOfWeek.name}}
+
+
+
+ +
+
+
+
+
+ diff --git a/customer/app/src/app/components/month-calendar/month-calendar.component.scss b/customer/app/src/app/components/month-calendar/month-calendar.component.scss new file mode 100644 index 0000000..b3d75dc --- /dev/null +++ b/customer/app/src/app/components/month-calendar/month-calendar.component.scss @@ -0,0 +1,22 @@ +@media (max-width:575px) { + .display-4 { + font-size: 1.5rem; + } + .day h5 { + background-color: #f8f9fa; + padding: 3px 5px 5px; + margin: -8px -8px 8px -8px; + } + .date { + padding-left: 4px; + } +} + +@media (min-width: 576px) { + .day { + min-height: 14.2857vw; + } +} +.name-of-day-of-week{ + text-transform: capitalize; +} diff --git a/customer/app/src/app/components/month-calendar/month-calendar.component.spec.ts b/customer/app/src/app/components/month-calendar/month-calendar.component.spec.ts new file mode 100644 index 0000000..7146a07 --- /dev/null +++ b/customer/app/src/app/components/month-calendar/month-calendar.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { MonthCalendarComponent } from './month-calendar.component'; + +describe('MonthCalendarComponent', () => { + let component: MonthCalendarComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ MonthCalendarComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(MonthCalendarComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/customer/app/src/app/components/month-calendar/month-calendar.component.ts b/customer/app/src/app/components/month-calendar/month-calendar.component.ts new file mode 100644 index 0000000..c795fa9 --- /dev/null +++ b/customer/app/src/app/components/month-calendar/month-calendar.component.ts @@ -0,0 +1,91 @@ +import {Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges} from '@angular/core'; +import {Event, EventsAvailableResponse} from "../../services/event.service"; +import * as moment from "moment"; + +@Component({ + selector: 'app-month-calendar', + templateUrl: './month-calendar.component.html', + styleUrls: ['./month-calendar.component.scss'] +}) +export class MonthCalendarComponent implements OnInit, OnChanges { + + minDate: number; + maxDate: number; + daysOfWeek: DayOfWeek[]; + days: Day[]; + + @Input() + eventsAvailableResponse: EventsAvailableResponse; + + @Output() + onEvent: EventEmitter = new EventEmitter(); + + constructor( ) { } + + ngOnInit() { + moment.locale('hu'); + // + this.fillDaysOfWeek(); + // + // let firstDay = moment().startOf('week'); + // + // this.days = []; + // if ( this.eventsAvailableResponse ){ + // + // for ( let i = 0; i < this.eventsAvailableResponse.days.length; i++){ + // this.days.push({ + // date: this.eventsAvailableResponse.days[i], + // events: [], + // active: true + // }) + // } + // } + + } + + + + fillDaysOfWeek(){ + this.daysOfWeek = []; + let startOfWeek = moment().startOf("week"); + + for ( let i = 0; i < 7 ; i++ ){ + let momWeekDay = startOfWeek.clone().add(i,'d'); + const dayOfWeek = { + name: momWeekDay.format("dddd"), + }; + this.daysOfWeek.push(dayOfWeek); + } + } + + ngOnChanges(changes: SimpleChanges): void { + console.info(changes); + if ( changes.hasOwnProperty('eventsAvailableResponse')){ + + } + } + + handleEvent($event){ + this.onEvent.emit($event); + } + +} + +export interface Day { + date: number; + events: Event[]; + active: boolean; +} + +export interface DayOfWeek { + name: string; +} + +export function dateToMoment(date: number) { + return moment(date); +} + +export interface MonthCalendarEvent { + type: string; // type of the month calendar event + event: Event; // the fitness event +} diff --git a/customer/app/src/app/pages/event-details/event-details.component.html b/customer/app/src/app/pages/event-details/event-details.component.html new file mode 100644 index 0000000..d13b325 --- /dev/null +++ b/customer/app/src/app/pages/event-details/event-details.component.html @@ -0,0 +1,36 @@ +
+
+
Edzés típusa
+
{{event.eventType.name}}
+
+
+
Edző
+
{{event.trainer.name}}
+
+
+
Edzés kezdési időpontja
+
{{event.start | date:'yyyy.MM.dd HH:mm'}}
+
+
+
Edzés vége
+
{{event.end | date:'yyyy.MM.dd HH:mm'}}
+
+
+
Férőhelyek száma
+
{{event.seatCount }}
+
+ + + + +
+
+ Foglalás + Lemondás + Már nincs szabad hely +
+
+ Vissza +
+
+
diff --git a/customer/app/src/app/pages/event-details/event-details.component.scss b/customer/app/src/app/pages/event-details/event-details.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/customer/app/src/app/pages/event-details/event-details.component.spec.ts b/customer/app/src/app/pages/event-details/event-details.component.spec.ts new file mode 100644 index 0000000..aec5750 --- /dev/null +++ b/customer/app/src/app/pages/event-details/event-details.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { EventDetailsComponent } from './event-details.component'; + +describe('EventDetailsComponent', () => { + let component: EventDetailsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ EventDetailsComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(EventDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/customer/app/src/app/pages/event-details/event-details.component.ts b/customer/app/src/app/pages/event-details/event-details.component.ts new file mode 100644 index 0000000..a481e1f --- /dev/null +++ b/customer/app/src/app/pages/event-details/event-details.component.ts @@ -0,0 +1,53 @@ +import { Component, OnInit } from '@angular/core'; +import {Event, EventService} from "../../services/event.service"; +import {ActivatedRoute, RouterState} from "@angular/router"; +import {NavigationService} from "../../services/navigation.service"; + +@Component({ + selector: 'app-event-details', + templateUrl: './event-details.component.html', + styleUrls: ['./event-details.component.scss'] +}) +export class EventDetailsComponent implements OnInit { + + event: Event; + + constructor( + private eventService: EventService, + private route: ActivatedRoute, + private navigationService: NavigationService + ) { } + + ngOnInit() { + let idEvent = +this.route.snapshot.paramMap.get('idEvent'); + this.eventService.findEvent(idEvent).subscribe( + value => this.event = value + ); + + } + + mayRegister(event: Event) { + return event.reservedAt == null && event.reservationCount < event.seatCount; + } + + mayCancel(event: Event) { + return event.reservedAt; + } + + noFreeSeat(event: Event) { + return event.reservedAt == null && event.reservationCount >= event.seatCount; + } + + + goBack(event: Event) { + this.navigationService.navigateToHome(); + } + + register(event: Event) { + + } + + cancel(event: Event) { + } +} + diff --git a/customer/app/src/app/pages/home/home.component.html b/customer/app/src/app/pages/home/home.component.html index 5f2c53f..284e31a 100644 --- a/customer/app/src/app/pages/home/home.component.html +++ b/customer/app/src/app/pages/home/home.component.html @@ -1 +1,9 @@ -

home works!

+
+ + + + +
+ diff --git a/customer/app/src/app/pages/home/home.component.ts b/customer/app/src/app/pages/home/home.component.ts index f56c8c1..138f15a 100644 --- a/customer/app/src/app/pages/home/home.component.ts +++ b/customer/app/src/app/pages/home/home.component.ts @@ -1,4 +1,8 @@ import { Component, OnInit } from '@angular/core'; +import {EventsAvailableResponse, EventService} from "../../services/event.service"; +import {Observable} from "rxjs"; +import {MonthCalendarEvent} from "../../components/month-calendar/month-calendar.component"; +import {NavigationService} from "../../services/navigation.service"; @Component({ selector: 'app-home', @@ -7,9 +11,20 @@ import { Component, OnInit } from '@angular/core'; }) export class HomeComponent implements OnInit { - constructor() { } + availableEvents: Observable; + + constructor(private eventService: EventService, + private navigationService: NavigationService) { } + ngOnInit() { + this.availableEvents = this.eventService.findEventsAvailable(); + } + handleEvent($event: MonthCalendarEvent) { + console.info($event); + this.navigationService.navigateToEventDetails($event.event.id); + + } } diff --git a/customer/app/src/app/services/endpoints.ts b/customer/app/src/app/services/endpoints.ts index 99ae14a..1caefe1 100644 --- a/customer/app/src/app/services/endpoints.ts +++ b/customer/app/src/app/services/endpoints.ts @@ -29,4 +29,9 @@ export class Endpoints { return `${this.baseUrl}/event-type`; } + + public static GET_EVENTS_AVAILABLE(){ + return `${this.baseUrl}/events/available`; + } + } diff --git a/customer/app/src/app/services/event.service.ts b/customer/app/src/app/services/event.service.ts index 6222ede..e793606 100644 --- a/customer/app/src/app/services/event.service.ts +++ b/customer/app/src/app/services/event.service.ts @@ -1,7 +1,8 @@ -import { Injectable } from '@angular/core'; +import {Injectable} from '@angular/core'; import {HttpClient} from "@angular/common/http"; import {Endpoints} from "./endpoints"; import {Observable} from "rxjs"; +import {DayToDisplay} from "../_helpers"; @Injectable({ providedIn: 'root' @@ -31,6 +32,10 @@ export class EventService { return this.http.post(Endpoints.POST_EVENT_CANCEL( idEvent ),{}) as Observable; } + findEventsAvailable(): Observable{ + return this.http.get(Endpoints.GET_EVENTS_AVAILABLE()) as Observable; + } + } export interface Trainer { @@ -55,4 +60,14 @@ export interface EventType { name: string; } +export interface DayToDisplay { + date: number; + active: true; + events: Event[]; +} + +export interface EventsAvailableResponse { + days: DayToDisplay[]; + events: Event[]; +} diff --git a/customer/app/src/app/services/navigation.service.spec.ts b/customer/app/src/app/services/navigation.service.spec.ts new file mode 100644 index 0000000..037de59 --- /dev/null +++ b/customer/app/src/app/services/navigation.service.spec.ts @@ -0,0 +1,12 @@ +import { TestBed } from '@angular/core/testing'; + +import { NavigationService } from './navigation.service'; + +describe('NavigationService', () => { + beforeEach(() => TestBed.configureTestingModule({})); + + it('should be created', () => { + const service: NavigationService = TestBed.get(NavigationService); + expect(service).toBeTruthy(); + }); +}); diff --git a/customer/app/src/app/services/navigation.service.ts b/customer/app/src/app/services/navigation.service.ts new file mode 100644 index 0000000..68c309a --- /dev/null +++ b/customer/app/src/app/services/navigation.service.ts @@ -0,0 +1,24 @@ +import { Injectable } from '@angular/core'; +import {NavigationExtras, Router} from "@angular/router"; + +@Injectable({ + providedIn: 'root' +}) +export class NavigationService { + + constructor(private navigation: Router) { } + + public navigate(commands: any[], extras?: NavigationExtras){ + this.navigation.navigate( commands,extras ); + } + + public navigateToEventDetails(idEvent: number){ + this.navigate(['/event-details/'+idEvent ]) + } + + public navigateToHome(){ + this.navigate(['/home' ]) + } + + +} diff --git a/customer/app/src/styles.scss b/customer/app/src/styles.scss index 698e011..cd2bc02 100644 --- a/customer/app/src/styles.scss +++ b/customer/app/src/styles.scss @@ -36,7 +36,7 @@ body{ background: #e5ce48; border: 1px solid #e5ce48; color: #000; } -.btn.btn-primary:hover { +.btn.btn-primary:hover,.btn.btn-primary:active, .btn-primary:not(:disabled):not(.disabled):active { border: 1px solid #e5ce48; background: transparent; color: #e5ce48; }