From 5d47c0c611d3d2457dfb5d5460862f9dc62a1ecd Mon Sep 17 00:00:00 2001 From: smuddyx Date: Sun, 26 Apr 2020 16:38:06 +0200 Subject: [PATCH] welcome screen --- firestore.rules | 1 + src/app/app-routing.module.ts | 26 +++- src/app/modules/brand/brand.component.html | 4 + src/app/modules/brand/brand.component.less | 12 ++ src/app/modules/brand/brand.component.spec.ts | 25 ++++ src/app/modules/brand/brand.component.ts | 16 +++ src/app/modules/brand/brand.module.ts | 30 +++++ .../brand/new-user/new-user.component.html | 8 ++ .../brand/new-user/new-user.component.less | 118 ++++++++++++++++++ .../brand/new-user/new-user.component.spec.ts | 25 ++++ .../brand/new-user/new-user.component.ts | 17 +++ src/app/modules/user/info/info.component.html | 5 +- src/app/modules/user/info/info.component.less | 8 +- src/app/modules/user/info/info.component.ts | 3 + .../modules/user/login/login.component.html | 27 +++- .../modules/user/login/login.component.less | 44 +++++++ src/app/modules/user/user.module.ts | 2 + src/app/services/user/user.service.ts | 2 +- .../navigation/navigation.component.html | 4 +- .../navigation/navigation.component.less | 1 + .../components/button/button.component.html | 2 +- .../components/button/button.component.less | 2 +- .../components/logo/logo.component.html | 49 ++++++++ .../components/logo/logo.component.less | 5 + .../components/logo/logo.component.spec.ts | 25 ++++ .../components/logo/logo.component.ts | 16 +++ .../components/logo/logo.module.ts | 16 +++ .../widget-modules/guards/role.guard.spec.ts | 16 +++ src/app/widget-modules/guards/role.guard.ts | 45 +++++++ 29 files changed, 538 insertions(+), 16 deletions(-) create mode 100644 src/app/modules/brand/brand.component.html create mode 100644 src/app/modules/brand/brand.component.less create mode 100644 src/app/modules/brand/brand.component.spec.ts create mode 100644 src/app/modules/brand/brand.component.ts create mode 100644 src/app/modules/brand/brand.module.ts create mode 100644 src/app/modules/brand/new-user/new-user.component.html create mode 100644 src/app/modules/brand/new-user/new-user.component.less create mode 100644 src/app/modules/brand/new-user/new-user.component.spec.ts create mode 100644 src/app/modules/brand/new-user/new-user.component.ts create mode 100644 src/app/widget-modules/components/logo/logo.component.html create mode 100644 src/app/widget-modules/components/logo/logo.component.less create mode 100644 src/app/widget-modules/components/logo/logo.component.spec.ts create mode 100644 src/app/widget-modules/components/logo/logo.component.ts create mode 100644 src/app/widget-modules/components/logo/logo.module.ts create mode 100644 src/app/widget-modules/guards/role.guard.spec.ts create mode 100644 src/app/widget-modules/guards/role.guard.ts diff --git a/firestore.rules b/firestore.rules index 6aa41a2..17008f1 100644 --- a/firestore.rules +++ b/firestore.rules @@ -11,6 +11,7 @@ service cloud.firestore { return get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == 'admin' } + allow create: if request.resource.id == request.auth.uid; allow read: if isUser(resource) || isAdmin(); allow write: if isUser(resource) || isAdmin(); } diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index e29e3c6..62c1191 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -1,6 +1,7 @@ import {NgModule} from '@angular/core'; import {PreloadAllModules, RouterModule, Routes} from '@angular/router'; import {AngularFireAuthGuard, redirectUnauthorizedTo} from '@angular/fire/auth-guard'; +import {RoleGuard} from './widget-modules/guards/role.guard'; const routes: Routes = [ { @@ -11,24 +12,37 @@ const routes: Routes = [ { path: 'songs', loadChildren: () => import('./modules/songs/songs.module').then(m => m.SongsModule), - canActivate: [AngularFireAuthGuard], - data: {authGuardPipe: () => redirectUnauthorizedTo(['user', 'login'])} + canActivate: [AngularFireAuthGuard, RoleGuard], + data: { + authGuardPipe: () => redirectUnauthorizedTo(['user', 'login']), + requiredRoles: ['user'] + } }, { path: 'shows', loadChildren: () => import('./modules/shows/shows.module').then(m => m.ShowsModule), - canActivate: [AngularFireAuthGuard], - data: {authGuardPipe: () => redirectUnauthorizedTo(['user', 'login'])} + canActivate: [AngularFireAuthGuard, RoleGuard], + data: { + authGuardPipe: () => redirectUnauthorizedTo(['user', 'login']), + requiredRoles: ['leader'] + } }, { path: 'presentation', loadChildren: () => import('./modules/presentation/presentation.module').then(m => m.PresentationModule), - canActivate: [AngularFireAuthGuard], - data: {authGuardPipe: () => redirectUnauthorizedTo(['user', 'login'])} + canActivate: [AngularFireAuthGuard, RoleGuard], + data: { + authGuardPipe: () => redirectUnauthorizedTo(['user', 'login']), + requiredRoles: ['presenter'] + } }, { path: 'user', loadChildren: () => import('./modules/user/user.module').then(m => m.UserModule) + }, + { + path: 'brand', + loadChildren: () => import('./modules/brand/brand.module').then(m => m.BrandModule), } ]; diff --git a/src/app/modules/brand/brand.component.html b/src/app/modules/brand/brand.component.html new file mode 100644 index 0000000..882e5fa --- /dev/null +++ b/src/app/modules/brand/brand.component.html @@ -0,0 +1,4 @@ +
+ + +
diff --git a/src/app/modules/brand/brand.component.less b/src/app/modules/brand/brand.component.less new file mode 100644 index 0000000..a5f0b19 --- /dev/null +++ b/src/app/modules/brand/brand.component.less @@ -0,0 +1,12 @@ +.copyright { + color: #fff; + opacity: 0.7; + font-size: 20px; + transform: translate(173px, -40px); +} + +.brand { + @media screen and (max-width: 860px) { + transform: scale(0.5) translateY(-50%); + } +} diff --git a/src/app/modules/brand/brand.component.spec.ts b/src/app/modules/brand/brand.component.spec.ts new file mode 100644 index 0000000..85d363b --- /dev/null +++ b/src/app/modules/brand/brand.component.spec.ts @@ -0,0 +1,25 @@ +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; + +import {BrandComponent} from './brand.component'; + +describe('BrandComponent', () => { + let component: BrandComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [BrandComponent] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(BrandComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/modules/brand/brand.component.ts b/src/app/modules/brand/brand.component.ts new file mode 100644 index 0000000..c7f3e34 --- /dev/null +++ b/src/app/modules/brand/brand.component.ts @@ -0,0 +1,16 @@ +import {Component, OnInit} from '@angular/core'; + +@Component({ + selector: 'app-brand', + templateUrl: './brand.component.html', + styleUrls: ['./brand.component.less'] +}) +export class BrandComponent implements OnInit { + + constructor() { + } + + ngOnInit(): void { + } + +} diff --git a/src/app/modules/brand/brand.module.ts b/src/app/modules/brand/brand.module.ts new file mode 100644 index 0000000..4b9c96d --- /dev/null +++ b/src/app/modules/brand/brand.module.ts @@ -0,0 +1,30 @@ +import {NgModule} from '@angular/core'; +import {CommonModule} from '@angular/common'; +import {BrandComponent} from './brand.component'; +import {RouterModule, Routes} from '@angular/router'; +import {LogoModule} from '../../widget-modules/components/logo/logo.module'; +import {NewUserComponent} from './new-user/new-user.component'; + + +const routes: Routes = [ + { + path: '', + pathMatch: 'full', + component: BrandComponent + }, + { + path: 'new-user', + component: NewUserComponent + }, +]; + +@NgModule({ + declarations: [BrandComponent, NewUserComponent], + imports: [ + CommonModule, + RouterModule.forChild(routes), + LogoModule + ] +}) +export class BrandModule { +} diff --git a/src/app/modules/brand/new-user/new-user.component.html b/src/app/modules/brand/new-user/new-user.component.html new file mode 100644 index 0000000..1bd0913 --- /dev/null +++ b/src/app/modules/brand/new-user/new-user.component.html @@ -0,0 +1,8 @@ +
+ +
+
WILLKOMMEN
+
{{user.name}}
+
Es wurden noch keine Berechtigungen zugeteilt, bitte wende Dich an den Administrator!
+
+
diff --git a/src/app/modules/brand/new-user/new-user.component.less b/src/app/modules/brand/new-user/new-user.component.less new file mode 100644 index 0000000..1f04e60 --- /dev/null +++ b/src/app/modules/brand/new-user/new-user.component.less @@ -0,0 +1,118 @@ +@animation-duration: 20s; + +.frame { + width: 512px; + position: relative; +} + +.brand { + position: absolute; + left: 0; + animation: @animation-duration brand ease-in-out forwards; + opacity: 0; +} + +.text { + position: absolute; + left: 0; + transform: translateX(50%); + color: #fff; + margin-top: 60px; + + .welcome { + opacity: 0; + font-size: 80px; + animation: @animation-duration welcome ease-in-out forwards; + } + + .name { + opacity: 0; + font-size: 50px; + animation: @animation-duration name ease-in-out forwards; + } + + .roles { + opacity: 0; + font-size: 20px; + margin-top: 40px; + animation: @animation-duration roles ease-in-out forwards; + } +} + +@keyframes brand { + 10% { + opacity: 0; + transform: translateX(0); + } + 15% { + opacity: 1; + transform: translateX(0); + } + 20% { + opacity: 1; + transform: translateX(0); + } + 25% { + opacity: 1; + transform: translateX(-50%); + } + + 100% { + opacity: 1; + transform: translateX(-50%); + } +} + +@keyframes welcome { + 30% { + opacity: 0; + transform: scale(1.4); + filter: blur(50px); + } + 40% { + opacity: 1; + transform: translateX(0); + filter: blur(0px); + } + + 100% { + opacity: 1; + transform: translateX(0); + } +} + +@keyframes name { + 50% { + opacity: 0; + transform: scale(1.4); + filter: blur(50px); + } + 60% { + opacity: 1; + transform: translateX(0); + filter: blur(0px); + } + + 100% { + opacity: 1; + transform: scale(1); + } +} + +@keyframes roles { + 70% { + opacity: 0; + transform: scale(1.4); + filter: blur(50px); + } + 80% { + opacity: 1; + transform: translateX(0); + filter: blur(0px); + } + + 100% { + opacity: 1; + transform: scale(1); + } +} diff --git a/src/app/modules/brand/new-user/new-user.component.spec.ts b/src/app/modules/brand/new-user/new-user.component.spec.ts new file mode 100644 index 0000000..0179e33 --- /dev/null +++ b/src/app/modules/brand/new-user/new-user.component.spec.ts @@ -0,0 +1,25 @@ +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; + +import {NewUserComponent} from './new-user.component'; + +describe('NewUserComponent', () => { + let component: NewUserComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [NewUserComponent] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(NewUserComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/modules/brand/new-user/new-user.component.ts b/src/app/modules/brand/new-user/new-user.component.ts new file mode 100644 index 0000000..74af3df --- /dev/null +++ b/src/app/modules/brand/new-user/new-user.component.ts @@ -0,0 +1,17 @@ +import {Component} from '@angular/core'; +import {UserService} from '../../../services/user/user.service'; +import {Observable} from 'rxjs'; +import {User} from '../../../services/user/user'; + +@Component({ + selector: 'app-new-user', + templateUrl: './new-user.component.html', + styleUrls: ['./new-user.component.less'] +}) +export class NewUserComponent { + public user$: Observable + + constructor(private userService: UserService) { + this.user$ = userService.user$ + } +} diff --git a/src/app/modules/user/info/info.component.html b/src/app/modules/user/info/info.component.html index 3f72924..542fb91 100644 --- a/src/app/modules/user/info/info.component.html +++ b/src/app/modules/user/info/info.component.html @@ -1,5 +1,8 @@ -

{{user.role|role}}

+

+ Es wurden noch keine Berechtigungen zugeteilt, bitte wende Dich an den Administrator! + {{transdormUserRoles(user.role)}} +

bevorzugte Anzeige der Akkorde diff --git a/src/app/modules/user/info/info.component.less b/src/app/modules/user/info/info.component.less index 820cdcf..3c7372a 100644 --- a/src/app/modules/user/info/info.component.less +++ b/src/app/modules/user/info/info.component.less @@ -1,3 +1,7 @@ -.mat-form-field { - width: 100%; +.warn { + color: #621700; +} + +p { + margin-bottom: 20px; } diff --git a/src/app/modules/user/info/info.component.ts b/src/app/modules/user/info/info.component.ts index 7baddf9..6549f82 100644 --- a/src/app/modules/user/info/info.component.ts +++ b/src/app/modules/user/info/info.component.ts @@ -25,4 +25,7 @@ export class InfoComponent implements OnInit { await this.userService.update$(uid, {chordMode: value}); } + public getUserRoles = (roles: string): string[] => roles?.split(';') ?? []; + public transdormUserRoles = (roles: string): string => this.getUserRoles(roles).join(', '); + } diff --git a/src/app/modules/user/login/login.component.html b/src/app/modules/user/login/login.component.html index 1cd0d8d..9b0d6a8 100644 --- a/src/app/modules/user/login/login.component.html +++ b/src/app/modules/user/login/login.component.html @@ -1,4 +1,4 @@ - + + +
+ + +
diff --git a/src/app/modules/user/login/login.component.less b/src/app/modules/user/login/login.component.less index 54bc57f..7cadcff 100644 --- a/src/app/modules/user/login/login.component.less +++ b/src/app/modules/user/login/login.component.less @@ -6,3 +6,47 @@ p.error { margin: 8px 10px; color: darkred; } + +.login { + padding: 20px; + width: 400px; + margin: 100px 0; + background: #fffc; + border-radius: 8px; + font-size: 18px; + @media screen and (max-width: 860px) { + margin: 20px; + box-sizing: border-box; + width: 90vw; + } +} + +button { + font-size: 18px; +} + +.btn-login { + margin-bottom: 40px; +} + +.btn-password { + margin-bottom: 20px; + color: #888; +} + +.btn-user { + color: #888; +} + +.frame { + display: flex; + position: relative; + flex-wrap: wrap; +} + +app-logo { + transform: scale(0.84); + @media screen and (max-width: 860px) { + display: none; + } +} diff --git a/src/app/modules/user/user.module.ts b/src/app/modules/user/user.module.ts index 8deac12..f174f59 100644 --- a/src/app/modules/user/user.module.ts +++ b/src/app/modules/user/user.module.ts @@ -20,6 +20,7 @@ import {RoleModule} from '../../services/user/role.module'; import {UserComponent} from './info/users/user/user.component'; import {NewComponent} from './new/new.component'; import {ButtonModule} from '../../widget-modules/components/button/button.module'; +import {LogoModule} from '../../widget-modules/components/logo/logo.module'; @NgModule({ @@ -37,6 +38,7 @@ import {ButtonModule} from '../../widget-modules/components/button/button.module FormsModule, RoleModule, ButtonModule, + LogoModule, ] diff --git a/src/app/services/user/user.service.ts b/src/app/services/user/user.service.ts index 6229f98..2b3c556 100644 --- a/src/app/services/user/user.service.ts +++ b/src/app/services/user/user.service.ts @@ -58,7 +58,7 @@ export class UserService { await this.db.doc('users/' + userId).set({name, chordMode: 'onlyFirst'}); const dUser = await this.readUser(aUser.user.uid); this._user$.next(dUser); - await this.router.navigateByUrl('/user/info'); + await this.router.navigateByUrl('/brand/new-user'); } private readUser$ = (uid) => this.db.doc$('users/' + uid); diff --git a/src/app/widget-modules/components/application-frame/navigation/navigation.component.html b/src/app/widget-modules/components/application-frame/navigation/navigation.component.html index 26c177f..0af6155 100644 --- a/src/app/widget-modules/components/application-frame/navigation/navigation.component.html +++ b/src/app/widget-modules/components/application-frame/navigation/navigation.component.html @@ -1,12 +1,12 @@ diff --git a/src/app/widget-modules/components/application-frame/navigation/navigation.component.less b/src/app/widget-modules/components/application-frame/navigation/navigation.component.less index 5dcb00e..4560335 100644 --- a/src/app/widget-modules/components/application-frame/navigation/navigation.component.less +++ b/src/app/widget-modules/components/application-frame/navigation/navigation.component.less @@ -37,4 +37,5 @@ nav { .links { display: flex; + height: 50px; } diff --git a/src/app/widget-modules/components/button/button.component.html b/src/app/widget-modules/components/button/button.component.html index 2716682..eaad9ec 100644 --- a/src/app/widget-modules/components/button/button.component.html +++ b/src/app/widget-modules/components/button/button.component.html @@ -1,6 +1,6 @@ diff --git a/src/app/widget-modules/components/button/button.component.less b/src/app/widget-modules/components/button/button.component.less index 0c1d551..9c5745c 100644 --- a/src/app/widget-modules/components/button/button.component.less +++ b/src/app/widget-modules/components/button/button.component.less @@ -5,7 +5,7 @@ button { } } -.content { +.button-content { @media screen and (max-width: 860px) { display: none ; } diff --git a/src/app/widget-modules/components/logo/logo.component.html b/src/app/widget-modules/components/logo/logo.component.html new file mode 100644 index 0000000..7951efb --- /dev/null +++ b/src/app/widget-modules/components/logo/logo.component.html @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/app/widget-modules/components/logo/logo.component.less b/src/app/widget-modules/components/logo/logo.component.less new file mode 100644 index 0000000..549e1d8 --- /dev/null +++ b/src/app/widget-modules/components/logo/logo.component.less @@ -0,0 +1,5 @@ +svg { + width: 512px; + height: 512px; + margin: 40px; +} diff --git a/src/app/widget-modules/components/logo/logo.component.spec.ts b/src/app/widget-modules/components/logo/logo.component.spec.ts new file mode 100644 index 0000000..793de6c --- /dev/null +++ b/src/app/widget-modules/components/logo/logo.component.spec.ts @@ -0,0 +1,25 @@ +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; + +import {LogoComponent} from './logo.component'; + +describe('LogoComponent', () => { + let component: LogoComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [LogoComponent] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(LogoComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/widget-modules/components/logo/logo.component.ts b/src/app/widget-modules/components/logo/logo.component.ts new file mode 100644 index 0000000..3ba3256 --- /dev/null +++ b/src/app/widget-modules/components/logo/logo.component.ts @@ -0,0 +1,16 @@ +import {Component, OnInit} from '@angular/core'; + +@Component({ + selector: 'app-logo', + templateUrl: './logo.component.html', + styleUrls: ['./logo.component.less'] +}) +export class LogoComponent implements OnInit { + + constructor() { + } + + ngOnInit(): void { + } + +} diff --git a/src/app/widget-modules/components/logo/logo.module.ts b/src/app/widget-modules/components/logo/logo.module.ts new file mode 100644 index 0000000..dbfd8c0 --- /dev/null +++ b/src/app/widget-modules/components/logo/logo.module.ts @@ -0,0 +1,16 @@ +import {NgModule} from '@angular/core'; +import {CommonModule} from '@angular/common'; +import {LogoComponent} from './logo.component'; + + +@NgModule({ + declarations: [LogoComponent], + exports: [ + LogoComponent + ], + imports: [ + CommonModule + ] +}) +export class LogoModule { +} diff --git a/src/app/widget-modules/guards/role.guard.spec.ts b/src/app/widget-modules/guards/role.guard.spec.ts new file mode 100644 index 0000000..ccd33ba --- /dev/null +++ b/src/app/widget-modules/guards/role.guard.spec.ts @@ -0,0 +1,16 @@ +import {TestBed} from '@angular/core/testing'; + +import {RoleGuard} from './role.guard'; + +describe('RoleGuard', () => { + let guard: RoleGuard; + + beforeEach(() => { + TestBed.configureTestingModule({}); + guard = TestBed.inject(RoleGuard); + }); + + it('should be created', () => { + expect(guard).toBeTruthy(); + }); +}); diff --git a/src/app/widget-modules/guards/role.guard.ts b/src/app/widget-modules/guards/role.guard.ts new file mode 100644 index 0000000..dd78e81 --- /dev/null +++ b/src/app/widget-modules/guards/role.guard.ts @@ -0,0 +1,45 @@ +import {Injectable} from '@angular/core'; +import {ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, UrlTree} from '@angular/router'; +import {Observable} from 'rxjs'; +import {UserService} from '../../services/user/user.service'; +import {map} from 'rxjs/operators'; + +@Injectable({ + providedIn: 'root' +}) +export class RoleGuard implements CanActivate { + constructor(private userService: UserService, private router: Router) { + } + + canActivate( + next: ActivatedRouteSnapshot, + state: RouterStateSnapshot): Observable { + const requiredRoles = next.data.requiredRoles; + if (!requiredRoles) throw new Error('requiredRoles is not defined!'); + + return this.userService.user$.pipe( + map(user => { + const roles = user.role?.split(';') ?? []; + if (roles.indexOf('admin') !== -1) return true; + const allowed = roles.some(s => requiredRoles.indexOf(s) !== -1); + + return allowed || this.router.createUrlTree(this.defaultRoute(roles)); + }) + ) + } + + private defaultRoute(roles: string[]): string[] { + if (!roles || roles.length === 0) return ['brand', 'new-user']; + switch (roles[0]) { + case 'user': + return ['songs']; + case 'presenter': + return ['presentation']; + case 'leader': + return ['shows']; + } + + return ['brand', 'new-user']; + } + +}