welcome screen
This commit is contained in:
@@ -11,6 +11,7 @@ service cloud.firestore {
|
|||||||
return get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == 'admin'
|
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 read: if isUser(resource) || isAdmin();
|
||||||
allow write: if isUser(resource) || isAdmin();
|
allow write: if isUser(resource) || isAdmin();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import {NgModule} from '@angular/core';
|
import {NgModule} from '@angular/core';
|
||||||
import {PreloadAllModules, RouterModule, Routes} from '@angular/router';
|
import {PreloadAllModules, RouterModule, Routes} from '@angular/router';
|
||||||
import {AngularFireAuthGuard, redirectUnauthorizedTo} from '@angular/fire/auth-guard';
|
import {AngularFireAuthGuard, redirectUnauthorizedTo} from '@angular/fire/auth-guard';
|
||||||
|
import {RoleGuard} from './widget-modules/guards/role.guard';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
@@ -11,24 +12,37 @@ const routes: Routes = [
|
|||||||
{
|
{
|
||||||
path: 'songs',
|
path: 'songs',
|
||||||
loadChildren: () => import('./modules/songs/songs.module').then(m => m.SongsModule),
|
loadChildren: () => import('./modules/songs/songs.module').then(m => m.SongsModule),
|
||||||
canActivate: [AngularFireAuthGuard],
|
canActivate: [AngularFireAuthGuard, RoleGuard],
|
||||||
data: {authGuardPipe: () => redirectUnauthorizedTo(['user', 'login'])}
|
data: {
|
||||||
|
authGuardPipe: () => redirectUnauthorizedTo(['user', 'login']),
|
||||||
|
requiredRoles: ['user']
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'shows',
|
path: 'shows',
|
||||||
loadChildren: () => import('./modules/shows/shows.module').then(m => m.ShowsModule),
|
loadChildren: () => import('./modules/shows/shows.module').then(m => m.ShowsModule),
|
||||||
canActivate: [AngularFireAuthGuard],
|
canActivate: [AngularFireAuthGuard, RoleGuard],
|
||||||
data: {authGuardPipe: () => redirectUnauthorizedTo(['user', 'login'])}
|
data: {
|
||||||
|
authGuardPipe: () => redirectUnauthorizedTo(['user', 'login']),
|
||||||
|
requiredRoles: ['leader']
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'presentation',
|
path: 'presentation',
|
||||||
loadChildren: () => import('./modules/presentation/presentation.module').then(m => m.PresentationModule),
|
loadChildren: () => import('./modules/presentation/presentation.module').then(m => m.PresentationModule),
|
||||||
canActivate: [AngularFireAuthGuard],
|
canActivate: [AngularFireAuthGuard, RoleGuard],
|
||||||
data: {authGuardPipe: () => redirectUnauthorizedTo(['user', 'login'])}
|
data: {
|
||||||
|
authGuardPipe: () => redirectUnauthorizedTo(['user', 'login']),
|
||||||
|
requiredRoles: ['presenter']
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'user',
|
path: 'user',
|
||||||
loadChildren: () => import('./modules/user/user.module').then(m => m.UserModule)
|
loadChildren: () => import('./modules/user/user.module').then(m => m.UserModule)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'brand',
|
||||||
|
loadChildren: () => import('./modules/brand/brand.module').then(m => m.BrandModule),
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
4
src/app/modules/brand/brand.component.html
Normal file
4
src/app/modules/brand/brand.component.html
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<div class="brand">
|
||||||
|
<app-logo></app-logo>
|
||||||
|
<div class="copyright">© 2020 - Benjamin Ifland</div>
|
||||||
|
</div>
|
||||||
12
src/app/modules/brand/brand.component.less
Normal file
12
src/app/modules/brand/brand.component.less
Normal file
@@ -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%);
|
||||||
|
}
|
||||||
|
}
|
||||||
25
src/app/modules/brand/brand.component.spec.ts
Normal file
25
src/app/modules/brand/brand.component.spec.ts
Normal file
@@ -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<BrandComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [BrandComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(BrandComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
16
src/app/modules/brand/brand.component.ts
Normal file
16
src/app/modules/brand/brand.component.ts
Normal file
@@ -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 {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
30
src/app/modules/brand/brand.module.ts
Normal file
30
src/app/modules/brand/brand.module.ts
Normal file
@@ -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 {
|
||||||
|
}
|
||||||
8
src/app/modules/brand/new-user/new-user.component.html
Normal file
8
src/app/modules/brand/new-user/new-user.component.html
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<div class="frame">
|
||||||
|
<app-brand class="brand"></app-brand>
|
||||||
|
<div *ngIf="user$|async as user" class="text">
|
||||||
|
<div class="welcome">WILLKOMMEN</div>
|
||||||
|
<div class="name">{{user.name}}</div>
|
||||||
|
<div class="roles">Es wurden noch keine Berechtigungen zugeteilt, bitte wende Dich an den Administrator!</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
118
src/app/modules/brand/new-user/new-user.component.less
Normal file
118
src/app/modules/brand/new-user/new-user.component.less
Normal file
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
25
src/app/modules/brand/new-user/new-user.component.spec.ts
Normal file
25
src/app/modules/brand/new-user/new-user.component.spec.ts
Normal file
@@ -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<NewUserComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [NewUserComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(NewUserComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
17
src/app/modules/brand/new-user/new-user.component.ts
Normal file
17
src/app/modules/brand/new-user/new-user.component.ts
Normal file
@@ -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<User>
|
||||||
|
|
||||||
|
constructor(private userService: UserService) {
|
||||||
|
this.user$ = userService.user$
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
<app-card *ngIf="user$|async as user" heading="Hallo {{user.name}}">
|
<app-card *ngIf="user$|async as user" heading="Hallo {{user.name}}">
|
||||||
<p>{{user.role|role}}</p>
|
<p>
|
||||||
|
<span *ngIf="getUserRoles(user.role).length===0" class="warn">Es wurden noch keine Berechtigungen zugeteilt, bitte wende Dich an den Administrator!</span>
|
||||||
|
<span>{{transdormUserRoles(user.role)}}</span>
|
||||||
|
</p>
|
||||||
|
|
||||||
<mat-form-field appearance="outline">
|
<mat-form-field appearance="outline">
|
||||||
<mat-label>bevorzugte Anzeige der Akkorde</mat-label>
|
<mat-label>bevorzugte Anzeige der Akkorde</mat-label>
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
.mat-form-field {
|
.warn {
|
||||||
width: 100%;
|
color: #621700;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,4 +25,7 @@ export class InfoComponent implements OnInit {
|
|||||||
await this.userService.update$(uid, {chordMode: value});
|
await this.userService.update$(uid, {chordMode: value});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getUserRoles = (roles: string): string[] => roles?.split(';') ?? [];
|
||||||
|
public transdormUserRoles = (roles: string): string => this.getUserRoles(roles).join(', ');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<app-card>
|
<!--<app-card>
|
||||||
<div [formGroup]="form" class="form">
|
<div [formGroup]="form" class="form">
|
||||||
<mat-form-field appearance="outline">
|
<mat-form-field appearance="outline">
|
||||||
<mat-label>E-Mail Addresse</mat-label>
|
<mat-label>E-Mail Addresse</mat-label>
|
||||||
@@ -18,4 +18,27 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</app-card>
|
</app-card>-->
|
||||||
|
|
||||||
|
<div class="frame">
|
||||||
|
<app-logo></app-logo>
|
||||||
|
<div class="login">
|
||||||
|
<div [formGroup]="form" class="form">
|
||||||
|
<mat-form-field appearance="outline">
|
||||||
|
<mat-label>E-Mail Addresse</mat-label>
|
||||||
|
<input (keyup.enter)="onLogin()" formControlName="user" matInput>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field appearance="outline">
|
||||||
|
<mat-label>Passwort</mat-label>
|
||||||
|
<input (keyup.enter)="onLogin()" formControlName="pass" matInput type="password">
|
||||||
|
</mat-form-field>
|
||||||
|
<p *ngIf="errorMessage" class="error">{{errorMessage|authMessage}}</p>
|
||||||
|
<button (click)="onLogin()" class="btn-login" color="primary" mat-stroked-button>Anmelden</button>
|
||||||
|
<button class="btn-password" mat-stroked-button routerLink="/user/password">Passwort zurücksetzen</button>
|
||||||
|
<button class="btn-user" mat-stroked-button routerLink="/user/new">neuen Benutzer anlegen</button>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -6,3 +6,47 @@ p.error {
|
|||||||
margin: 8px 10px;
|
margin: 8px 10px;
|
||||||
color: darkred;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import {RoleModule} from '../../services/user/role.module';
|
|||||||
import {UserComponent} from './info/users/user/user.component';
|
import {UserComponent} from './info/users/user/user.component';
|
||||||
import {NewComponent} from './new/new.component';
|
import {NewComponent} from './new/new.component';
|
||||||
import {ButtonModule} from '../../widget-modules/components/button/button.module';
|
import {ButtonModule} from '../../widget-modules/components/button/button.module';
|
||||||
|
import {LogoModule} from '../../widget-modules/components/logo/logo.module';
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@@ -37,6 +38,7 @@ import {ButtonModule} from '../../widget-modules/components/button/button.module
|
|||||||
FormsModule,
|
FormsModule,
|
||||||
RoleModule,
|
RoleModule,
|
||||||
ButtonModule,
|
ButtonModule,
|
||||||
|
LogoModule,
|
||||||
|
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ export class UserService {
|
|||||||
await this.db.doc('users/' + userId).set({name, chordMode: 'onlyFirst'});
|
await this.db.doc('users/' + userId).set({name, chordMode: 'onlyFirst'});
|
||||||
const dUser = await this.readUser(aUser.user.uid);
|
const dUser = await this.readUser(aUser.user.uid);
|
||||||
this._user$.next(dUser);
|
this._user$.next(dUser);
|
||||||
await this.router.navigateByUrl('/user/info');
|
await this.router.navigateByUrl('/brand/new-user');
|
||||||
}
|
}
|
||||||
|
|
||||||
private readUser$ = (uid) => this.db.doc$<User>('users/' + uid);
|
private readUser$ = (uid) => this.db.doc$<User>('users/' + uid);
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
<nav [class.hidden]="(windowScroll$|async)>60" class="head">
|
<nav [class.hidden]="(windowScroll$|async)>60" class="head">
|
||||||
<div class="links">
|
<div class="links">
|
||||||
<app-brand></app-brand>
|
<app-brand routerLink="/brand"></app-brand>
|
||||||
<app-link *appRole="['user','presenter', 'leader']" [icon]="faSongs" link="/songs" text="Lieder"></app-link>
|
<app-link *appRole="['user','presenter', 'leader']" [icon]="faSongs" link="/songs" text="Lieder"></app-link>
|
||||||
<app-link *appRole="['leader']" [icon]="faShows" link="/shows" text="Veranstaltungen"></app-link>
|
<app-link *appRole="['leader']" [icon]="faShows" link="/shows" text="Veranstaltungen"></app-link>
|
||||||
<app-link *appRole="['presenter']" [icon]="faPresentation" link="/presentation" text="Präsentation"></app-link>
|
<app-link *appRole="['presenter']" [icon]="faPresentation" link="/presentation" text="Präsentation"></app-link>
|
||||||
<app-link [icon]="faUser" link="/user" text="Benutzer"></app-link>
|
<app-link [icon]="faUser" link="/user" text="Benutzer"></app-link>
|
||||||
</div>
|
</div>
|
||||||
<div class="actions">
|
<div *appRole="['user','presenter', 'leader']" class="actions">
|
||||||
<app-filter></app-filter>
|
<app-filter></app-filter>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|||||||
@@ -37,4 +37,5 @@ nav {
|
|||||||
|
|
||||||
.links {
|
.links {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
height: 50px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<button mat-button>
|
<button mat-button>
|
||||||
<span *ngIf="icon"><fa-icon [icon]="icon"></fa-icon><span class="content"> </span></span>
|
<span *ngIf="icon"><fa-icon [icon]="icon"></fa-icon><span class="content"> </span></span>
|
||||||
<span class="content">
|
<span class="button-content">
|
||||||
<ng-content></ng-content>
|
<ng-content></ng-content>
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ button {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.button-content {
|
||||||
@media screen and (max-width: 860px) {
|
@media screen and (max-width: 860px) {
|
||||||
display: none ;
|
display: none ;
|
||||||
}
|
}
|
||||||
|
|||||||
49
src/app/widget-modules/components/logo/logo.component.html
Normal file
49
src/app/widget-modules/components/logo/logo.component.html
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 24 KiB |
@@ -0,0 +1,5 @@
|
|||||||
|
svg {
|
||||||
|
width: 512px;
|
||||||
|
height: 512px;
|
||||||
|
margin: 40px;
|
||||||
|
}
|
||||||
@@ -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<LogoComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [LogoComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(LogoComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
16
src/app/widget-modules/components/logo/logo.component.ts
Normal file
16
src/app/widget-modules/components/logo/logo.component.ts
Normal file
@@ -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 {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
16
src/app/widget-modules/components/logo/logo.module.ts
Normal file
16
src/app/widget-modules/components/logo/logo.module.ts
Normal file
@@ -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 {
|
||||||
|
}
|
||||||
16
src/app/widget-modules/guards/role.guard.spec.ts
Normal file
16
src/app/widget-modules/guards/role.guard.spec.ts
Normal file
@@ -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();
|
||||||
|
});
|
||||||
|
});
|
||||||
45
src/app/widget-modules/guards/role.guard.ts
Normal file
45
src/app/widget-modules/guards/role.guard.ts
Normal file
@@ -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<boolean | UrlTree> {
|
||||||
|
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'];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user