update navigation + profile
This commit is contained in:
parent
53ac145165
commit
1c0be5e1ea
@ -1,69 +1,74 @@
|
||||
import {NgModule} from '@angular/core';
|
||||
import {Routes, RouterModule} from '@angular/router';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
|
||||
import {AuthGuard, AuthUpdateGuard, AuthenticatedGuard, AnonymousGuard} from './auth/auth.guard';
|
||||
import {ImprintComponent, PrivacyPolicyComponent, TermsOfServiceComponent} from './pages/general/general.component';
|
||||
import {FormLoginComponent} from './pages/form-login/form-login.component';
|
||||
import {FormLogin2FAComponent} from './pages/form-login-2fa/form-login-2fa.component';
|
||||
import {PasswordComponent} from './pages/password/password.component';
|
||||
import {PasswordResetComponent} from './pages/password-reset/password-reset.component';
|
||||
import {AccountComponent} from './pages/account/account.component';
|
||||
import {RegisterComponent} from './pages/register/register.component';
|
||||
import {TokensComponent} from './pages/tokens/tokens.component';
|
||||
import {ServicesComponent} from './pages/services/services.component';
|
||||
import {InfoComponent} from './pages/account/info/info.component';
|
||||
import {ProfileComponent} from './pages/account/profile/profile.component';
|
||||
import {VoucherComponent} from './pages/account/voucher/voucher.component';
|
||||
import {SecurityComponent} from './pages/account/security/security.component';
|
||||
import {UnavailableComponent} from './pages/unavailable/unavailable.component';
|
||||
import {NotfoundComponent} from './pages/notfound/notfound.component';
|
||||
import {UserComponent} from './pages/user/user.component'
|
||||
import {JitsiComponent} from './pages/jitsi/jitsi.component'
|
||||
import {ParteyTimeslotsComponent} from './pages/partey/timeslots/timeslots.compontent'
|
||||
import {AliasesComponent} from './pages/account/aliases/aliases.component';
|
||||
import {DomainsComponent} from './pages/account/domains/domains.component';
|
||||
import {InvitesComponent} from './pages/invites/invites.component';
|
||||
import {UrlShortenerComponent, UrlShortenerPasswordComponent} from './pages/urlshortener/urlshortener.component';
|
||||
import {MinetestAccountsComponent} from './pages/minetest/accounts/accounts.component';
|
||||
import { AuthGuard, AuthUpdateGuard, AuthenticatedGuard, AnonymousGuard } from './auth/auth.guard';
|
||||
import { MainComponent } from './ui/main/main.component';
|
||||
import { FormLoginComponent } from './pages/form-login/form-login.component';
|
||||
import { FormLogin2FAComponent } from './pages/form-login-2fa/form-login-2fa.component';
|
||||
import { PasswordComponent } from './pages/password/password.component';
|
||||
import { PasswordResetComponent } from './pages/password-reset/password-reset.component';
|
||||
import { AccountComponent } from './pages/account/account.component';
|
||||
import { RegisterComponent } from './pages/register/register.component';
|
||||
import { TokensComponent } from './pages/tokens/tokens.component';
|
||||
import { ServicesComponent } from './pages/services/services.component';
|
||||
import { InfoComponent } from './pages/account/info/info.component';
|
||||
import { ProfileComponent } from './pages/account/profile/profile.component';
|
||||
import { VoucherComponent } from './pages/account/voucher/voucher.component';
|
||||
import { SecurityComponent } from './pages/account/security/security.component';
|
||||
import { UnavailableComponent } from './pages/unavailable/unavailable.component';
|
||||
import { NotfoundComponent } from './pages/notfound/notfound.component';
|
||||
import { UserComponent } from './pages/user/user.component'
|
||||
import { JitsiComponent } from './pages/jitsi/jitsi.component'
|
||||
import { ParteyComponent } from './pages/partey/partey.component'
|
||||
import { ParteyTimeslotsComponent } from './pages/partey/timeslots/timeslots.compontent'
|
||||
import { AliasesComponent } from './pages/account/aliases/aliases.component';
|
||||
import { DomainsComponent } from './pages/account/domains/domains.component';
|
||||
import { InvitesComponent } from './pages/invites/invites.component';
|
||||
import { UrlShortenerComponent, UrlShortenerPasswordComponent } from './pages/urlshortener/urlshortener.component';
|
||||
import { MinetestAccountsComponent } from './pages/minetest/accounts/accounts.component';
|
||||
import { DividertestComponent } from './pages/dividertest/dividertest.component'
|
||||
|
||||
const routes: Routes = [
|
||||
{path: '', redirectTo: "/services", pathMatch: 'full'},
|
||||
{path: 'imprint', component: ImprintComponent, canActivate: [AuthUpdateGuard]},
|
||||
{path: 'privacy-policy', component: PrivacyPolicyComponent, canActivate: [AuthUpdateGuard]},
|
||||
{path: 'terms-of-service', component: TermsOfServiceComponent, canActivate: [AuthUpdateGuard]},
|
||||
{path: 'login', component: FormLoginComponent, canActivate: [AnonymousGuard]},
|
||||
{path: 'login/2fa', component: FormLogin2FAComponent, canActivate: [AnonymousGuard]},
|
||||
{path: 'service-login', component: FormLoginComponent, canActivate: [AnonymousGuard]},
|
||||
{path: 'service-login/2fa', component: FormLogin2FAComponent, canActivate: [AnonymousGuard]},
|
||||
{path: 'password', component: PasswordComponent, canActivate: [AnonymousGuard]},
|
||||
{path: 'password-reset', component: PasswordResetComponent, canActivate: [AnonymousGuard]},
|
||||
{path: 'services', component: ServicesComponent, canActivate: [AuthenticatedGuard]},
|
||||
{ path: 'profile/:username', component: UserComponent, canActivate: [ AuthUpdateGuard ] },
|
||||
{
|
||||
path: 'account', component: AccountComponent, canActivate: [AuthenticatedGuard], children: [
|
||||
|
||||
{path: 'info', component: InfoComponent, canActivate: [AuthenticatedGuard]},
|
||||
{path: 'profile', component: ProfileComponent, canActivate: [AuthenticatedGuard]},
|
||||
{path: 'security', component: SecurityComponent, canActivate: [AuthenticatedGuard]},
|
||||
{path: 'voucher', component: VoucherComponent, canActivate: [AuthenticatedGuard]},
|
||||
{path: 'aliases', component: AliasesComponent, canActivate: [AuthenticatedGuard]},
|
||||
{path: 'domains', component: DomainsComponent, canActivate: [AuthenticatedGuard]}
|
||||
path: '', component: MainComponent, children: [
|
||||
{ path: '', redirectTo: "/services", pathMatch: 'full' },
|
||||
{ path: 'login', component: FormLoginComponent, canActivate: [ AnonymousGuard ] },
|
||||
{ path: 'login/2fa', component: FormLogin2FAComponent, canActivate: [ AnonymousGuard ] },
|
||||
{ path: 'service-login', component: FormLoginComponent, canActivate: [ AnonymousGuard ] },
|
||||
{ path: 'service-login/2fa', component: FormLogin2FAComponent, canActivate: [ AnonymousGuard ] },
|
||||
{ path: 'password', component: PasswordComponent, canActivate: [ AnonymousGuard ] },
|
||||
{ path: 'password-reset', component: PasswordResetComponent, canActivate: [ AnonymousGuard ] },
|
||||
{ path: 'services', component: ServicesComponent, canActivate: [ AuthenticatedGuard ] },
|
||||
{
|
||||
path: 'account', component: AccountComponent, canActivate: [ AuthenticatedGuard ], children: [
|
||||
{ path: '', redirectTo: "/account/info", pathMatch: 'full' },
|
||||
{ path: 'info', component: InfoComponent, canActivate: [ AuthenticatedGuard ] },
|
||||
{ path: 'profile', component: ProfileComponent, canActivate: [ AuthenticatedGuard ] },
|
||||
{ path: 'security', component: SecurityComponent, canActivate: [ AuthenticatedGuard ] },
|
||||
{ path: 'voucher', component: VoucherComponent, canActivate: [ AuthenticatedGuard ] },
|
||||
{ path: 'aliases', component: AliasesComponent, canActivate: [ AuthenticatedGuard ] },
|
||||
{ path: 'domains', component: DomainsComponent, canActivate: [ AuthenticatedGuard ] }
|
||||
]
|
||||
},
|
||||
{path: 'register', component: RegisterComponent, canActivate: [AnonymousGuard]},
|
||||
{path: 'tokens', component: TokensComponent, canActivate: [AuthGuard]},
|
||||
{path: 'jitsi', component: JitsiComponent, canActivate: [AuthenticatedGuard]},
|
||||
{path: 'partey/timeslots', component: ParteyTimeslotsComponent, canActivate: [AuthenticatedGuard]},
|
||||
{path: 'minetest/accounts', component: MinetestAccountsComponent, canActivate: [AuthenticatedGuard]},
|
||||
{path: 'urlshortener', component: UrlShortenerComponent, canActivate: [AuthenticatedGuard]},
|
||||
{path: 'urlshortener/:code', component: UrlShortenerPasswordComponent, canActivate: [AuthUpdateGuard]},
|
||||
{path: 'invites/:quota', component: InvitesComponent, canActivate: [AuthenticatedGuard]},
|
||||
{path: 'unavailable', component: UnavailableComponent},
|
||||
{path: 'p/:username', component: UserComponent, canActivate: [AuthUpdateGuard]},
|
||||
{path: '**', component: NotfoundComponent, pathMatch: 'full', canActivate: [AuthUpdateGuard]},
|
||||
{ path: 'register', component: RegisterComponent, canActivate: [ AnonymousGuard ] },
|
||||
{ path: 'tokens', component: TokensComponent, canActivate: [ AuthGuard ] },
|
||||
{ path: 'jitsi', component: JitsiComponent, canActivate: [ AuthenticatedGuard ] },
|
||||
{ path: 'partey', component: ParteyComponent, canActivate: [ AuthenticatedGuard ] },
|
||||
{ path: 'partey/timeslots', component: ParteyTimeslotsComponent, canActivate: [ AuthenticatedGuard ] },
|
||||
{ path: 'minetest/accounts', component: MinetestAccountsComponent, canActivate: [ AuthenticatedGuard ] },
|
||||
{ path: 'dividertest', component: DividertestComponent },
|
||||
{ path: 'urlshortener', component: UrlShortenerComponent, canActivate: [ AuthenticatedGuard ] },
|
||||
{ path: 'urlshortener/:code', component: UrlShortenerPasswordComponent, canActivate: [ AuthUpdateGuard ] },
|
||||
{ path: 'invites/:quota', component: InvitesComponent, canActivate: [ AuthenticatedGuard ] },
|
||||
{ path: 'unavailable', component: UnavailableComponent },
|
||||
{ path: 'p/:username', component: UserComponent, canActivate: [ AuthUpdateGuard ] },
|
||||
{ path: '**', component: NotfoundComponent, pathMatch: 'full', canActivate: [ AuthUpdateGuard ] }, ]
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forRoot(routes, {onSameUrlNavigation: 'reload', relativeLinkResolution: 'legacy'})],
|
||||
exports: [RouterModule]
|
||||
imports: [ RouterModule.forRoot(routes, { onSameUrlNavigation: 'reload', relativeLinkResolution: 'legacy' }) ],
|
||||
exports: [ RouterModule ]
|
||||
})
|
||||
export class AppRoutingModule {}
|
||||
export class AppRoutingModule { }
|
||||
|
@ -1,86 +1,3 @@
|
||||
<mat-toolbar color="primary">
|
||||
<a href="javascript:" mat-icon-button>
|
||||
<mat-icon (click)="sidenav.toggle()">menu</mat-icon>
|
||||
</a>
|
||||
<mat-icon svgIcon="logo"></mat-icon>
|
||||
<span>
|
||||
we.bstly
|
||||
</span>
|
||||
<span class="spacer"></span>
|
||||
<ng-container>
|
||||
|
||||
<button mat-button [matMenuTriggerFor]="menu">
|
||||
<mat-icon>settings</mat-icon>
|
||||
<mat-icon>arrow_drop_down</mat-icon>
|
||||
</button>
|
||||
<mat-menu #menu="matMenu">
|
||||
<a *ngIf="!auth || auth && !auth.authenticated" routerLink="/login" routerLinkActive="active" mat-menu-item>
|
||||
<mat-icon>login</mat-icon> {{'login' | i18n}}
|
||||
</a>
|
||||
<mat-divider *ngIf="!auth || auth && !auth.authenticated"></mat-divider>
|
||||
<a *ngFor="let locale of locales" mat-menu-item (click)="setLocale(locale)">{{'locale.' + locale + '.long' |
|
||||
i18n}} <mat-icon inline=true *ngIf="locale == currentLocale">done</mat-icon></a>
|
||||
<a mat-menu-item>
|
||||
<mat-slide-toggle (change)="darkThemeChange($event)" [checked]="darkTheme == 'true'">
|
||||
{{'profileField.name.darkTheme' | i18n}}
|
||||
</mat-slide-toggle>
|
||||
</a>
|
||||
<mat-divider *ngIf="auth && auth.authenticated"></mat-divider>
|
||||
<a *ngIf="auth && auth.authenticated" (click)="logout()" mat-menu-item>
|
||||
<mat-icon>exit_to_app</mat-icon> {{'logout' | i18n}}
|
||||
</a>
|
||||
</mat-menu>
|
||||
</ng-container>
|
||||
</mat-toolbar>
|
||||
|
||||
<mat-sidenav-container>
|
||||
<mat-sidenav #sidenav [mode]="isBiggerScreen() ? 'side' : 'over'" [(opened)]="opened"
|
||||
(click)="!isBiggerScreen() && opened=false">
|
||||
<mat-nav-list>
|
||||
<a *ngIf="!auth || auth && !auth.authenticated" routerLink="/login" routerLinkActive="active" mat-list-item>
|
||||
<mat-icon>login</mat-icon> {{'login' | i18n}}
|
||||
</a>
|
||||
<a *ngIf="auth && auth.authenticated" routerLink="/account/info" routerLinkActive="active" mat-list-item>
|
||||
<mat-icon>account_circle</mat-icon> {{'account' | i18n}}
|
||||
</a>
|
||||
<a *ngIf="auth && auth.authenticated" routerLink="/services" routerLinkActive="active" mat-list-item>
|
||||
<mat-icon>widgets</mat-icon> {{'services' | i18n}}
|
||||
</a>
|
||||
<a routerLink="/tokens" mat-list-item>
|
||||
<mat-icon>card_giftcard</mat-icon> {{'tokens.redeem' | i18n}}
|
||||
</a>
|
||||
<a (click)="openExternal('https://wiki.bstly.de/services/webstly','_blank')" mat-list-item>
|
||||
<mat-icon>help</mat-icon> {{'help' | i18n}}<mat-icon style="font-size: 1em;">open_in_new
|
||||
</mat-icon>
|
||||
</a>
|
||||
<a (click)="openExternal('https://membership.bstly.de','_blank')" mat-list-item>
|
||||
<mat-icon>shopping_cart</mat-icon> {{'tokens.get' | i18n}}<mat-icon style="font-size: 1em;">open_in_new
|
||||
</mat-icon>
|
||||
</a>
|
||||
<a *ngIf="auth && auth.authenticated" (click)="logout()" mat-list-item>
|
||||
<mat-icon>exit_to_app</mat-icon> {{'logout' | i18n}}
|
||||
</a>
|
||||
</mat-nav-list>
|
||||
|
||||
<span class="spacer"></span>
|
||||
|
||||
<mat-nav-list>
|
||||
<a (click)="openExternal('https://www.bstly.de/imprint/')" mat-list-item style="font-size: 0.7em;">
|
||||
{{'imprint' | i18n}}
|
||||
</a>
|
||||
<a (click)="openExternal('https://www.bstly.de/privacy-policy/#we.bstly')" mat-list-item style="font-size: 0.7em;">
|
||||
{{'privacy-policy' | i18n}}
|
||||
</a>
|
||||
<a (click)="openExternal('https://www.bstly.de')" mat-list-item style="font-size: 0.7em;">
|
||||
Bastelei e. V.
|
||||
</a>
|
||||
</mat-nav-list>
|
||||
</mat-sidenav>
|
||||
|
||||
<!-- Main content -->
|
||||
<mat-sidenav-content>
|
||||
<div class="container">
|
||||
<mat-drawer-container>
|
||||
<router-outlet></router-outlet>
|
||||
</div>
|
||||
</mat-sidenav-content>
|
||||
</mat-sidenav-container>
|
||||
</mat-drawer-container>
|
@ -13,7 +13,7 @@ import { DatePipe } from '@angular/common';
|
||||
import { AutofocusDirective } from './material/autofocus';
|
||||
|
||||
import { I18nPipe } from './utils/i18n.pipe';
|
||||
import { ImprintComponent, PrivacyPolicyComponent, TermsOfServiceComponent } from './pages/general/general.component';
|
||||
import { MainComponent } from './ui/main/main.component';
|
||||
import { AccountComponent } from './pages/account/account.component';
|
||||
import { ServicesComponent } from './pages/services/services.component';
|
||||
import { AppComponent } from './app.component';
|
||||
@ -44,8 +44,11 @@ import { HtmlComponent } from './utils/html/html.component';
|
||||
import { ConfirmDialog } from './ui/confirm/confirm.component'
|
||||
import { UserComponent } from './pages/user/user.component'
|
||||
import { JitsiComponent, JitsiEditDialog, JitsiShareDialog } from './pages/jitsi/jitsi.component'
|
||||
import { ParteyComponent } from './pages/partey/partey.component'
|
||||
import { ParteyTimeslotsComponent, ParteyTimeslotDialog } from './pages/partey/timeslots/timeslots.compontent'
|
||||
import { UrlShortenerComponent, UrlShortenerPasswordComponent, UrlShortenerShareDialog, UrlShortenerEditDialog } from './pages/urlshortener/urlshortener.component'
|
||||
import { DividerComponent } from './ui/divider/divider.component'
|
||||
import { DividertestComponent } from './pages/dividertest/dividertest.component'
|
||||
|
||||
|
||||
import { I18nService } from './services/i18n.service';
|
||||
@ -71,8 +74,8 @@ export class XhrInterceptor implements HttpInterceptor {
|
||||
declarations: [
|
||||
AutofocusDirective,
|
||||
I18nPipe,
|
||||
MainComponent,
|
||||
AppComponent,
|
||||
ImprintComponent, PrivacyPolicyComponent, TermsOfServiceComponent,
|
||||
AccountComponent,
|
||||
LoginComponent,
|
||||
FormLoginComponent,
|
||||
@ -103,9 +106,10 @@ export class XhrInterceptor implements HttpInterceptor {
|
||||
ConfirmDialog,
|
||||
UserComponent,
|
||||
JitsiComponent, JitsiEditDialog, JitsiShareDialog,
|
||||
ParteyTimeslotsComponent, ParteyTimeslotDialog,
|
||||
ParteyComponent, ParteyTimeslotsComponent, ParteyTimeslotDialog,
|
||||
MinetestAccountsComponent,
|
||||
UrlShortenerComponent, UrlShortenerShareDialog, UrlShortenerEditDialog, UrlShortenerPasswordComponent
|
||||
UrlShortenerComponent, UrlShortenerShareDialog, UrlShortenerEditDialog, UrlShortenerPasswordComponent,
|
||||
DividerComponent, DividertestComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
|
1
src/app/pages/dividertest/dividertest.component.html
Normal file
1
src/app/pages/dividertest/dividertest.component.html
Normal file
@ -0,0 +1 @@
|
||||
<app-divider [dividerModel]="dividerModel"></app-divider>
|
28
src/app/pages/dividertest/dividertest.component.ts
Normal file
28
src/app/pages/dividertest/dividertest.component.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-dividertest',
|
||||
templateUrl: './dividertest.component.html',
|
||||
styleUrls: [ './dividertest.component.scss' ]
|
||||
})
|
||||
export class DividertestComponent implements OnInit {
|
||||
|
||||
dividerModel = {
|
||||
free: 0,
|
||||
items: [ { name: "mail", value: 5 }, { name: "nextcloud", value: 15 } ],
|
||||
unit: 'M',
|
||||
units: [
|
||||
{ name: "G", value: 1, steps: 0.5 },
|
||||
{ name: "M", value: 1024, steps: 1 },
|
||||
{ name: "K", value: 1024 * 1024, steps: 10 },
|
||||
{ name: "B", value: 1024 * 1024 * 1024, steps: 100 }
|
||||
]
|
||||
};
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-imprint',
|
||||
templateUrl: './general.imprint.html'
|
||||
})
|
||||
export class ImprintComponent implements OnInit {
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-privacy-policy',
|
||||
templateUrl: './general.privacy-policy.html'
|
||||
})
|
||||
export class PrivacyPolicyComponent implements OnInit {
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-terms-of-service',
|
||||
templateUrl: './general.terms-of-service.html'
|
||||
})
|
||||
export class TermsOfServiceComponent implements OnInit {
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
@ -1 +0,0 @@
|
||||
<app-html [template]="'imprint'"></app-html>
|
@ -1 +0,0 @@
|
||||
<app-html [template]="'privacy-policy'"></app-html>
|
@ -1 +0,0 @@
|
||||
<app-html [template]="'terms-of-service'"></app-html>
|
10
src/app/pages/partey/partey.component.html
Normal file
10
src/app/pages/partey/partey.component.html
Normal file
@ -0,0 +1,10 @@
|
||||
<h3>{{'partey.tags' | i18n}}</h3>
|
||||
|
||||
<p *ngIf="!tags || tags.length == 0">{{'partey.tags.none' | i18n}}</p>
|
||||
|
||||
<mat-chip-list>
|
||||
<mat-chip *ngFor="let tag of tags">{{tag.tag}}</mat-chip>
|
||||
</mat-chip-list>
|
||||
|
||||
|
||||
<app-partey-timeslots></app-partey-timeslots>
|
0
src/app/pages/partey/partey.component.scss
Normal file
0
src/app/pages/partey/partey.component.scss
Normal file
24
src/app/pages/partey/partey.component.ts
Normal file
24
src/app/pages/partey/partey.component.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { ParteyTagsService } from '../../services/partey.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-partey',
|
||||
templateUrl: './partey.component.html',
|
||||
styleUrls: [ './partey.component.scss' ]
|
||||
})
|
||||
export class ParteyComponent implements OnInit {
|
||||
|
||||
|
||||
tags;
|
||||
|
||||
constructor(private parteyTagsService: ParteyTagsService) {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.parteyTagsService.get().subscribe((data: any[]) => {
|
||||
this.tags = data;
|
||||
})
|
||||
}
|
||||
|
||||
}
|
@ -8,7 +8,7 @@ import { FormControl } from '@angular/forms';
|
||||
import { debounceTime } from 'rxjs/operators';
|
||||
import { PageEvent } from '@angular/material/paginator';
|
||||
|
||||
import { ParteyTimeslotsService } from '../../../services/partey.timeslots.service';
|
||||
import { ParteyTimeslotsService } from '../../../services/partey.service';
|
||||
import { ConfirmDialog } from '../../../ui/confirm/confirm.component';
|
||||
import { I18nService } from './../../../services/i18n.service';
|
||||
import { AuthService } from './../../../services/auth.service';
|
||||
|
@ -2,7 +2,11 @@
|
||||
<mat-progress-bar *ngIf="!success && !error" mode="indeterminate"></mat-progress-bar>
|
||||
|
||||
<div *ngIf="success">
|
||||
<h3>{{model.username}} <small *ngIf="isMe">{{'user.isMe' | i18n}}</small></h3>
|
||||
<h3>{{model.username}}
|
||||
<button *ngIf="isMe" mat-icon-button color="accent">
|
||||
<mat-icon>star</mat-icon>
|
||||
</button>
|
||||
</h3>
|
||||
<app-profilefields [username]="model.username"></app-profilefields>
|
||||
<div *ngIf="model.aliases && model.aliases.length > 0">
|
||||
<h4>{{'user.aliases' | i18n}}</h4>
|
||||
|
@ -27,14 +27,15 @@ export class UserComponent implements OnInit {
|
||||
this.profileService.getForUser(this.username).subscribe((data: any) => {
|
||||
this.success = true;
|
||||
this.model = data;
|
||||
|
||||
this.authService.auth.subscribe((auth: any) => {
|
||||
this.isMe = auth && auth.principal && auth.principal.username == this.model.username;
|
||||
});
|
||||
}, error => {
|
||||
this.error = error;
|
||||
})
|
||||
|
||||
this.authService.auth.subscribe((auth: any) => {
|
||||
this.isMe = auth && auth.principal && auth.principal.username == this.username;
|
||||
console.log(this.isMe, auth);
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -67,3 +67,19 @@ export class ParteyTimeslotsService {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class ParteyTagsService {
|
||||
|
||||
constructor(private http: HttpClient) {
|
||||
}
|
||||
|
||||
get() {
|
||||
return this.http.get(environment.apiUrl + "/partey/tags");
|
||||
}
|
||||
|
||||
}
|
13
src/app/ui/divider/divider.component.html
Normal file
13
src/app/ui/divider/divider.component.html
Normal file
@ -0,0 +1,13 @@
|
||||
<p>free: {{toCurrentUnit(dividerModel.free)}}{{unit.name}}</p>
|
||||
|
||||
|
||||
<mat-select [(ngModel)]="unit">
|
||||
<mat-option *ngFor="let item of dividerModel.units" [value]="item">{{item.name}}</mat-option>
|
||||
</mat-select>
|
||||
|
||||
<div *ngFor="let item of dividerModel.items">
|
||||
<label>{{item.name}}: {{toCurrentUnit(item.value)}}{{unit.name}}</label>
|
||||
<mat-slider [max]="toCurrentUnit(dividerModel.free + item.value)" min=0 [step]="unit.steps" [value]="toCurrentUnit(item.value)" thumbLabel
|
||||
tickInterval="5" (change)="updateValue($event, item)">
|
||||
</mat-slider>
|
||||
</div>
|
3
src/app/ui/divider/divider.component.scss
Normal file
3
src/app/ui/divider/divider.component.scss
Normal file
@ -0,0 +1,3 @@
|
||||
mat-slider {
|
||||
display: block;
|
||||
}
|
36
src/app/ui/divider/divider.component.ts
Normal file
36
src/app/ui/divider/divider.component.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { I18nService } from '../../services/i18n.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-divider',
|
||||
templateUrl: './divider.component.html',
|
||||
styleUrls: [ './divider.component.scss' ]
|
||||
})
|
||||
export class DividerComponent implements OnInit {
|
||||
|
||||
|
||||
@Input() dividerModel;
|
||||
unit;
|
||||
|
||||
constructor(private i18n: I18nService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.unit = this.dividerModel.units.find(unit => unit.name == this.dividerModel.unit);
|
||||
}
|
||||
|
||||
toCurrentUnit(value) {
|
||||
return this.unit.value * value;
|
||||
}
|
||||
|
||||
fromCurrentUnit(value) {
|
||||
return value / this.unit.value;
|
||||
}
|
||||
|
||||
updateValue($event, item) {
|
||||
const value = this.fromCurrentUnit($event.value);
|
||||
const diff = item.value - value;
|
||||
item.value = value;
|
||||
this.dividerModel.free += diff;
|
||||
}
|
||||
|
||||
}
|
86
src/app/ui/main/main.component.html
Normal file
86
src/app/ui/main/main.component.html
Normal file
@ -0,0 +1,86 @@
|
||||
<mat-toolbar color="primary">
|
||||
<a href="javascript:" mat-icon-button>
|
||||
<mat-icon (click)="sidenav.toggle()">menu</mat-icon>
|
||||
</a>
|
||||
<mat-icon svgIcon="logo"></mat-icon>
|
||||
<span>
|
||||
we.bstly
|
||||
</span>
|
||||
<span class="spacer"></span>
|
||||
<ng-container>
|
||||
|
||||
<button mat-button [matMenuTriggerFor]="menu">
|
||||
<mat-icon>settings</mat-icon>
|
||||
<mat-icon>arrow_drop_down</mat-icon>
|
||||
</button>
|
||||
<mat-menu #menu="matMenu">
|
||||
<a *ngIf="!auth || auth && !auth.authenticated" routerLink="/login" routerLinkActive="active" mat-menu-item>
|
||||
<mat-icon>login</mat-icon> {{'login' | i18n}}
|
||||
</a>
|
||||
<mat-divider *ngIf="!auth || auth && !auth.authenticated"></mat-divider>
|
||||
<a *ngFor="let locale of locales" mat-menu-item (click)="setLocale(locale)">{{'locale.' + locale + '.long' |
|
||||
i18n}} <mat-icon inline=true *ngIf="locale == currentLocale">done</mat-icon></a>
|
||||
<a mat-menu-item>
|
||||
<mat-slide-toggle (change)="darkThemeChange($event)" [checked]="darkTheme == 'true'">
|
||||
{{'profileField.name.darkTheme' | i18n}}
|
||||
</mat-slide-toggle>
|
||||
</a>
|
||||
<mat-divider *ngIf="auth && auth.authenticated"></mat-divider>
|
||||
<a *ngIf="auth && auth.authenticated" (click)="logout()" mat-menu-item>
|
||||
<mat-icon>exit_to_app</mat-icon> {{'logout' | i18n}}
|
||||
</a>
|
||||
</mat-menu>
|
||||
</ng-container>
|
||||
</mat-toolbar>
|
||||
|
||||
<mat-sidenav-container>
|
||||
<mat-sidenav #sidenav [mode]="isBiggerScreen() ? 'side' : 'over'" [(opened)]="opened"
|
||||
(click)="!isBiggerScreen() && opened=false">
|
||||
<mat-nav-list>
|
||||
<a *ngIf="!auth || auth && !auth.authenticated" routerLink="/login" routerLinkActive="active" mat-list-item>
|
||||
<mat-icon>login</mat-icon> {{'login' | i18n}}
|
||||
</a>
|
||||
<a *ngIf="auth && auth.authenticated" routerLink="/account/info" routerLinkActive="active" mat-list-item>
|
||||
<mat-icon>account_circle</mat-icon> {{'account' | i18n}}
|
||||
</a>
|
||||
<a *ngIf="auth && auth.authenticated" routerLink="/services" routerLinkActive="active" mat-list-item>
|
||||
<mat-icon>widgets</mat-icon> {{'services' | i18n}}
|
||||
</a>
|
||||
<a routerLink="/tokens" mat-list-item>
|
||||
<mat-icon>card_giftcard</mat-icon> {{'tokens.redeem' | i18n}}
|
||||
</a>
|
||||
<a (click)="openExternal('https://wiki.bstly.de/services/webstly','_blank')" mat-list-item>
|
||||
<mat-icon>help</mat-icon> {{'help' | i18n}}<mat-icon style="font-size: 1em;">open_in_new
|
||||
</mat-icon>
|
||||
</a>
|
||||
<a (click)="openExternal('https://membership.bstly.de','_blank')" mat-list-item>
|
||||
<mat-icon>shopping_cart</mat-icon> {{'tokens.get' | i18n}}<mat-icon style="font-size: 1em;">open_in_new
|
||||
</mat-icon>
|
||||
</a>
|
||||
<a *ngIf="auth && auth.authenticated" (click)="logout()" mat-list-item>
|
||||
<mat-icon>exit_to_app</mat-icon> {{'logout' | i18n}}
|
||||
</a>
|
||||
</mat-nav-list>
|
||||
|
||||
<span class="spacer"></span>
|
||||
|
||||
<mat-nav-list>
|
||||
<a (click)="openExternal('https://www.bstly.de/imprint/')" mat-list-item style="font-size: 0.7em;">
|
||||
{{'imprint' | i18n}}
|
||||
</a>
|
||||
<a (click)="openExternal('https://www.bstly.de/privacy-policy/#we.bstly')" mat-list-item style="font-size: 0.7em;">
|
||||
{{'privacy-policy' | i18n}}
|
||||
</a>
|
||||
<a (click)="openExternal('https://www.bstly.de')" mat-list-item style="font-size: 0.7em;">
|
||||
Bastelei e. V.
|
||||
</a>
|
||||
</mat-nav-list>
|
||||
</mat-sidenav>
|
||||
|
||||
<!-- Main content -->
|
||||
<mat-sidenav-content>
|
||||
<div class="container">
|
||||
<router-outlet></router-outlet>
|
||||
</div>
|
||||
</mat-sidenav-content>
|
||||
</mat-sidenav-container>
|
0
src/app/ui/main/main.component.scss
Normal file
0
src/app/ui/main/main.component.scss
Normal file
144
src/app/ui/main/main.component.ts
Normal file
144
src/app/ui/main/main.component.ts
Normal file
@ -0,0 +1,144 @@
|
||||
import {Component, HostListener} from '@angular/core';
|
||||
|
||||
import {AuthService} from '../../services/auth.service';
|
||||
import {I18nService} from '../../services/i18n.service';
|
||||
import {ProfileService} from '../../services/profile.service';
|
||||
import {Router} from '@angular/router';
|
||||
import {DomSanitizer} from '@angular/platform-browser';
|
||||
import {MatIconRegistry} from '@angular/material/icon';
|
||||
import {DateAdapter} from '@angular/material/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-main',
|
||||
templateUrl: './main.component.html',
|
||||
styleUrls: ['./main.component.scss']
|
||||
})
|
||||
|
||||
export class MainComponent {
|
||||
opened = true;
|
||||
darkTheme = "false";
|
||||
title = 'we.bstly';
|
||||
currentLocale: String;
|
||||
datetimeformat: String;
|
||||
locales;
|
||||
auth;
|
||||
|
||||
constructor(
|
||||
private i18n: I18nService,
|
||||
private authService: AuthService,
|
||||
private profileService: ProfileService,
|
||||
private router: Router,
|
||||
private iconRegistry: MatIconRegistry,
|
||||
private sanitizer: DomSanitizer,
|
||||
private _adapter: DateAdapter<any>) {
|
||||
iconRegistry.addSvgIcon('logo', sanitizer.bypassSecurityTrustResourceUrl('assets/icons/logo.svg'));
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.datetimeformat = this.i18n.get('format.datetime', []);
|
||||
this.currentLocale = this.i18n.getLocale();
|
||||
this.locales = this.i18n.getLocales();
|
||||
this.authService.auth.subscribe(data => {
|
||||
this.auth = data;
|
||||
})
|
||||
|
||||
this._adapter.setLocale(this.currentLocale);
|
||||
|
||||
const width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
|
||||
if(width < 768) {
|
||||
this.opened = false;
|
||||
} else {
|
||||
this.opened = true;
|
||||
}
|
||||
|
||||
if(localStorage.getItem("bstly.darkTheme") == "true") {
|
||||
this.darkTheme = "true";
|
||||
window.document.body.classList.add("dark-theme");
|
||||
}
|
||||
}
|
||||
|
||||
setLocale(locale) {
|
||||
localStorage.setItem("bstly.locale", locale);
|
||||
|
||||
if(this.auth && this.auth.authenticated) {
|
||||
this.profileService.getField("locale").subscribe((profileField: any) => {
|
||||
|
||||
if(profileField == null) {
|
||||
profileField = {
|
||||
"name": "locale",
|
||||
"type": "TEXT",
|
||||
"visibility": "PRIVATE"
|
||||
}
|
||||
}
|
||||
|
||||
profileField.value = locale;
|
||||
this.profileService.createOrUpdate(profileField).subscribe((response) => {
|
||||
window.location.reload();
|
||||
})
|
||||
})
|
||||
} else {
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
|
||||
darkThemeChange($event) {
|
||||
if($event.checked) {
|
||||
this.darkTheme = "true";
|
||||
} else {
|
||||
this.darkTheme = "false";
|
||||
}
|
||||
|
||||
localStorage.setItem("bstly.darkTheme", this.darkTheme);
|
||||
|
||||
if(this.auth && this.auth.authenticated) {
|
||||
this.profileService.getField("darkTheme").subscribe((profileField: any) => {
|
||||
|
||||
if(profileField == null) {
|
||||
profileField = {
|
||||
"name": "darkTheme",
|
||||
"type": "BOOL",
|
||||
"visibility": "PRIVATE"
|
||||
}
|
||||
}
|
||||
|
||||
profileField.value = this.darkTheme;
|
||||
this.profileService.createOrUpdate(profileField).subscribe((response) => {
|
||||
window.location.reload();
|
||||
})
|
||||
})
|
||||
} else {
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
logout() {
|
||||
this.authService.logout().subscribe(data => {
|
||||
this.router.navigate([""]).then(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
isBiggerScreen() {
|
||||
const width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
|
||||
if(width < 768) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
openExternal(url, target = '_self') {
|
||||
window.open(url, target);
|
||||
}
|
||||
|
||||
@HostListener('window:resize', ['$event'])
|
||||
onResize(event) {
|
||||
if(event.target.innerWidth < 768) {
|
||||
this.opened = false;
|
||||
} else {
|
||||
this.opened = true;
|
||||
}
|
||||
}
|
||||
}
|
@ -4,7 +4,8 @@
|
||||
|
||||
export const environment = {
|
||||
production: false,
|
||||
apiUrl : 'http://localhost:9000'
|
||||
// apiUrl : 'http://localhost:9000',
|
||||
apiUrl : 'https://api.bstly.lh8.de',
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -83,13 +83,26 @@ body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !important;
|
||||
}
|
||||
|
||||
app-root {
|
||||
app-root, app-main {
|
||||
height: 100%;
|
||||
max-height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
app-root {
|
||||
padding: 15px;
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
app-main {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
mat-card {
|
||||
max-width: 400px;
|
||||
margin: 2em auto;
|
||||
@ -280,6 +293,11 @@ table {
|
||||
|
||||
|
||||
.dark-theme {
|
||||
|
||||
app-root {
|
||||
background-color: #303030;
|
||||
}
|
||||
|
||||
table {
|
||||
|
||||
background: #424242;
|
||||
|
Loading…
Reference in New Issue
Block a user