From ba054b2a4e6ce0906f2f1061fc58ca91ad63b38f Mon Sep 17 00:00:00 2001 From: Stepan Berkunov Date: Thu, 26 Dec 2024 02:46:53 +0300 Subject: [PATCH] feat: finalize --- .../authentication.controller.ts | 6 +- .../authentication/authentication.service.ts | 4 ++ .../src/iam/authentication/dto/sign-up.dto.ts | 5 ++ .../admin-home-page.component.html | 15 +++++ .../admin-home-page.component.scss | 20 ++----- .../admin-home-page.component.ts | 45 ++++++++++++++- .../my-books-page.component.html | 1 - .../sign-in-page/sign-in-page.component.html | 6 +- .../sign-in-page/sign-in-page.component.scss | 7 +++ .../sign-in-page/sign-in-page.component.ts | 5 +- .../sign-up-page/sign-up-page.component.html | 57 +++++++++++++++++-- .../sign-up-page/sign-up-page.component.scss | 35 ++++++++++++ .../sign-up-page/sign-up-page.component.ts | 56 ++++++++++++------ .../app/features/iam/services/auth.service.ts | 8 +-- 14 files changed, 218 insertions(+), 52 deletions(-) diff --git a/backend/src/iam/authentication/authentication.controller.ts b/backend/src/iam/authentication/authentication.controller.ts index 3060a03..a2bc19a 100644 --- a/backend/src/iam/authentication/authentication.controller.ts +++ b/backend/src/iam/authentication/authentication.controller.ts @@ -22,8 +22,10 @@ export class AuthenticationController { constructor(private readonly authService: AuthenticationService) {} @Post('sign-up') - signUp(@Body() signUpDto: SignUpDto) { - return this.authService.signUp(signUpDto); + async signUp(@Body() signUpDto: SignUpDto) { + await this.authService.signUp(signUpDto); + + return {}; } // Cookies realization diff --git a/backend/src/iam/authentication/authentication.service.ts b/backend/src/iam/authentication/authentication.service.ts index 1310b26..2fcb8b9 100644 --- a/backend/src/iam/authentication/authentication.service.ts +++ b/backend/src/iam/authentication/authentication.service.ts @@ -35,6 +35,10 @@ export class AuthenticationService { user.email = signUpDto.email; user.password = await this.hashingService.hash(signUpDto.password); user.roles = [await this.rolesRepository.findOneBy({ name: 'user' })]; + user.name = signUpDto.name; + user.surname = signUpDto.surname; + user.patronymic = signUpDto.patronymic; + user.phone = signUpDto.phone; await this.usersRepository.save(user); } catch (err) { diff --git a/backend/src/iam/authentication/dto/sign-up.dto.ts b/backend/src/iam/authentication/dto/sign-up.dto.ts index 20af9c1..9c0f859 100644 --- a/backend/src/iam/authentication/dto/sign-up.dto.ts +++ b/backend/src/iam/authentication/dto/sign-up.dto.ts @@ -9,4 +9,9 @@ export class SignUpDto { @MinLength(10) password: string; + + name: string; + surname: string; + patronymic: string; + phone: string; } diff --git a/frontend/src/app/features/admin/pages/admin-home-page/admin-home-page.component.html b/frontend/src/app/features/admin/pages/admin-home-page/admin-home-page.component.html index adac2ed..910ce27 100644 --- a/frontend/src/app/features/admin/pages/admin-home-page/admin-home-page.component.html +++ b/frontend/src/app/features/admin/pages/admin-home-page/admin-home-page.component.html @@ -1,3 +1,18 @@

Дашборд

+ +
+ +

Всего бронирований: {{ (books$ | async)?.length }}

+
+ +

Всего пользователей: {{ (users$ | async)?.length }}

+
+ +

Всего номеров: {{ (rooms$ | async)?.length }}

+

Номера "Стандарт": {{ (roomsStandart$ | async)?.length }}

+

Номера "Комфорт": {{ (roomsComfort$ | async)?.length }}

+

Номер "Люкс": {{ (roomsLux$ | async)?.length }}

+
+
diff --git a/frontend/src/app/features/admin/pages/admin-home-page/admin-home-page.component.scss b/frontend/src/app/features/admin/pages/admin-home-page/admin-home-page.component.scss index 1b4423c..a3f92b6 100644 --- a/frontend/src/app/features/admin/pages/admin-home-page/admin-home-page.component.scss +++ b/frontend/src/app/features/admin/pages/admin-home-page/admin-home-page.component.scss @@ -1,16 +1,6 @@ -.dialog { - display: flex; - flex-direction: column; - gap: var(--spacing-04); - - &__form { - display: flex; - flex-direction: column; - gap: var(--spacing-03); - } - - &__actions { - display: flex; - gap: var(--spacing-03); - } +.dashboard { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(200px, 350px)); + justify-content: space-between; + gap: var(--spacing-06); } diff --git a/frontend/src/app/features/admin/pages/admin-home-page/admin-home-page.component.ts b/frontend/src/app/features/admin/pages/admin-home-page/admin-home-page.component.ts index 588dfdf..85ce1d5 100644 --- a/frontend/src/app/features/admin/pages/admin-home-page/admin-home-page.component.ts +++ b/frontend/src/app/features/admin/pages/admin-home-page/admin-home-page.component.ts @@ -1,14 +1,53 @@ -import {ChangeDetectionStrategy, Component, inject} from '@angular/core'; +import {ChangeDetectionStrategy, Component, inject, OnInit} from '@angular/core'; import {AdminService} from '../../services/admin.service'; +import {Card} from 'primeng/card'; +import {Booking} from '../../../booking/models/booking.model'; +import {User} from '../../../iam/models/user.model'; +import {Room} from '../../../booking/models/room.model'; +import {map, Observable} from 'rxjs'; +import {AsyncPipe} from '@angular/common'; @Component({ selector: 'app-admin-home-page', - imports: [], + imports: [ + Card, + AsyncPipe + ], templateUrl: './admin-home-page.component.html', styleUrl: './admin-home-page.component.scss', changeDetection: ChangeDetectionStrategy.OnPush }) -export class AdminHomePageComponent { +export class AdminHomePageComponent implements OnInit { private readonly adminService = inject(AdminService); + private destroy$ = new Observable(); + + books$ = new Observable(); + + users$ = new Observable(); + + rooms$ = new Observable(); + roomsStandart$ = new Observable(); + roomsComfort$ = new Observable(); + roomsLux$ = new Observable(); + + ngOnInit() { + this.books$ = this.adminService.getAllBookings(); + + this.users$ = this.adminService.getAllUsers(); + + this.rooms$ = this.adminService.getAllRooms(); + + this.roomsStandart$ = this.rooms$.pipe(map(rooms => { + return rooms.filter(room => room.roomType.id === 1); + })); + + this.roomsComfort$ = this.rooms$.pipe(map(rooms => { + return rooms.filter(room => room.roomType.id === 2); + })); + + this.roomsLux$ = this.rooms$.pipe(map(rooms => { + return rooms.filter(room => room.roomType.id === 3); + })); + } } diff --git a/frontend/src/app/features/booking/pages/my-books-page/my-books-page.component.html b/frontend/src/app/features/booking/pages/my-books-page/my-books-page.component.html index 1cd00cb..4bcd788 100644 --- a/frontend/src/app/features/booking/pages/my-books-page/my-books-page.component.html +++ b/frontend/src/app/features/booking/pages/my-books-page/my-books-page.component.html @@ -14,7 +14,6 @@

Бронирование #{{ booking.id }}

Комната

-

Действия:

} diff --git a/frontend/src/app/features/iam/pages/sign-in-page/sign-in-page.component.html b/frontend/src/app/features/iam/pages/sign-in-page/sign-in-page.component.html index 9ab2f87..cb69ab8 100644 --- a/frontend/src/app/features/iam/pages/sign-in-page/sign-in-page.component.html +++ b/frontend/src/app/features/iam/pages/sign-in-page/sign-in-page.component.html @@ -10,10 +10,14 @@

Авторизация

- + + + diff --git a/frontend/src/app/features/iam/pages/sign-in-page/sign-in-page.component.scss b/frontend/src/app/features/iam/pages/sign-in-page/sign-in-page.component.scss index aa13be1..97dfbc6 100644 --- a/frontend/src/app/features/iam/pages/sign-in-page/sign-in-page.component.scss +++ b/frontend/src/app/features/iam/pages/sign-in-page/sign-in-page.component.scss @@ -24,6 +24,13 @@ gap: var(--spacing-04); align-items: center; } + + .link { + a { + text-decoration: underline; + color: var(--primary-color) + } + } } } diff --git a/frontend/src/app/features/iam/pages/sign-in-page/sign-in-page.component.ts b/frontend/src/app/features/iam/pages/sign-in-page/sign-in-page.component.ts index d472866..a07a9d4 100644 --- a/frontend/src/app/features/iam/pages/sign-in-page/sign-in-page.component.ts +++ b/frontend/src/app/features/iam/pages/sign-in-page/sign-in-page.component.ts @@ -1,6 +1,6 @@ import {ChangeDetectionStrategy, Component, inject, OnDestroy, OnInit} from '@angular/core'; import {AuthService} from '../../services/auth.service'; -import {ActivatedRoute, Router} from '@angular/router'; +import {ActivatedRoute, Router, RouterLink} from '@angular/router'; import {FormControl, FormGroup, ReactiveFormsModule, Validators} from '@angular/forms'; import {Subject, switchMap, takeUntil} from 'rxjs'; import {Button} from 'primeng/button'; @@ -15,7 +15,8 @@ import {Password} from 'primeng/password'; Button, IftaLabel, InputText, - Password + Password, + RouterLink ], templateUrl: './sign-in-page.component.html', styleUrl: './sign-in-page.component.scss', diff --git a/frontend/src/app/features/iam/pages/sign-up-page/sign-up-page.component.html b/frontend/src/app/features/iam/pages/sign-up-page/sign-up-page.component.html index a90755e..dce2f9b 100644 --- a/frontend/src/app/features/iam/pages/sign-up-page/sign-up-page.component.html +++ b/frontend/src/app/features/iam/pages/sign-up-page/sign-up-page.component.html @@ -1,9 +1,54 @@ -
- +
+
+

Регистрация

- + + + - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
diff --git a/frontend/src/app/features/iam/pages/sign-up-page/sign-up-page.component.scss b/frontend/src/app/features/iam/pages/sign-up-page/sign-up-page.component.scss index e69de29..d790a4f 100644 --- a/frontend/src/app/features/iam/pages/sign-up-page/sign-up-page.component.scss +++ b/frontend/src/app/features/iam/pages/sign-up-page/sign-up-page.component.scss @@ -0,0 +1,35 @@ +.page-auth { + justify-content: center; + align-items: center; + + .auth-form { + background-color: var(--overlay-background); + border-radius: 8px; + padding: var(--spacing-06); + + display: flex; + flex-direction: column; + gap: var(--spacing-05); + + max-width: 500px; + + h1 { + font-size: 1.75rem; + text-align: center; + } + + form { + display: flex; + flex-direction: column; + gap: var(--spacing-04); + align-items: center; + } + + .link { + a { + text-decoration: underline; + color: var(--primary-color) + } + } + } +} diff --git a/frontend/src/app/features/iam/pages/sign-up-page/sign-up-page.component.ts b/frontend/src/app/features/iam/pages/sign-up-page/sign-up-page.component.ts index 9808413..95aee70 100644 --- a/frontend/src/app/features/iam/pages/sign-up-page/sign-up-page.component.ts +++ b/frontend/src/app/features/iam/pages/sign-up-page/sign-up-page.component.ts @@ -2,54 +2,78 @@ import {ChangeDetectionStrategy, Component, inject, OnDestroy, OnInit} from '@an import {AuthService} from '../../services/auth.service'; import {FormControl, FormGroup, ReactiveFormsModule, Validators} from "@angular/forms"; import {Subject, switchMap, takeUntil} from 'rxjs'; +import {Button} from 'primeng/button'; +import {IftaLabel} from 'primeng/iftalabel'; +import {InputText} from 'primeng/inputtext'; +import {Password} from 'primeng/password'; +import {Router, RouterLink} from '@angular/router'; +import {MessageService} from 'primeng/api'; @Component({ selector: 'app-sign-up-page', - imports: [ - ReactiveFormsModule - ], + imports: [ + ReactiveFormsModule, + Button, + IftaLabel, + InputText, + Password, + RouterLink + ], templateUrl: './sign-up-page.component.html', styleUrl: './sign-up-page.component.scss', changeDetection: ChangeDetectionStrategy.OnPush }) export class SignUpPageComponent implements OnInit, OnDestroy { + private readonly router = inject(Router); + private readonly messageService = inject(MessageService); private readonly authService = inject(AuthService); #destroy$ = new Subject() signUpForm!: FormGroup; - signUpProcess$ = new Subject<{ username: string, email: string, password: string }>(); + signUpProcess$ = new Subject(); ngOnInit() { this.signUpForm = new FormGroup({ username: new FormControl(null, Validators.required), email: new FormControl(null, {validators: [Validators.required, Validators.email]}), password: new FormControl(null, Validators.required), + surname: new FormControl(null, Validators.required), + name: new FormControl(null, Validators.required), + patronymic: new FormControl(null, Validators.required), + phone: new FormControl(null, Validators.required), }); this.signUpProcess$ .pipe( takeUntil(this.#destroy$), - switchMap(({email, username, password}) => { - return this.authService.signUp(username, email, password) + switchMap(() => { + return this.authService.signUp(this.signUpForm.value) }), ) .subscribe({ - next: () => { - console.log("Reg success") - }, - error: (err) => { - console.error("Auth error") + next: (v => { + this.messageService.add({ + severity: 'success', + summary: 'Успех', + detail: 'Аккаунт успешно зарегистрирован! Войдите с введенными данными', + life: 5000 + }); + this.router.navigateByUrl('/auth/log-in'); + }), + error: err => { + this.messageService.add({ + severity: 'error', + summary: 'Ошибка', + detail: 'Произошла ошибка! Обратитесь в поддержку', + life: 3000 + }); } }); } signUp() { - this.signUpProcess$.next({ - username: this.signUpForm.controls['username'].value, - email: this.signUpForm.controls['email'].value, - password: this.signUpForm.controls['password'].value - }); + this.signUpProcess$.next(); } ngOnDestroy() { diff --git a/frontend/src/app/features/iam/services/auth.service.ts b/frontend/src/app/features/iam/services/auth.service.ts index d4cdbff..5ce898c 100644 --- a/frontend/src/app/features/iam/services/auth.service.ts +++ b/frontend/src/app/features/iam/services/auth.service.ts @@ -44,14 +44,10 @@ export class AuthService { } // TODO протестировать регистрацию и диалог - signUp(username: string, email: string, password: string) { + signUp(userCred: Partial) { return this.http.post( this.configService.config.auth.url + '/authentication/sign-up', - { - username: username, - email: email, - password: password - }, + userCred, { withCredentials: true }