diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 6aefef0..27f1b97 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -8,7 +8,8 @@ "watch": "ng build --watch --configuration development", "test": "ng test", "generate": "oazapfts --optimistic --useEnumType ./src/app/generated-api/swagger.json ./src/app/generated-api/api.ts", - "dev": "pnpm -w run dev" + "dev": "pnpm -w run dev", + "deploy": "ng build --aot --configuration production" }, "prettier": { "printWidth": 100, @@ -59,4 +60,4 @@ "oazapfts": "^6.3.1", "typescript": "~5.9.3" } -} \ No newline at end of file +} diff --git a/packages/frontend/src/app/app.html b/packages/frontend/src/app/app.html index 8f41600..f118f67 100644 --- a/packages/frontend/src/app/app.html +++ b/packages/frontend/src/app/app.html @@ -1,14 +1,16 @@ @if(this.auth.loggedIn()){
- - -
} - +
+ +
diff --git a/packages/frontend/src/app/app.routes.ts b/packages/frontend/src/app/app.routes.ts index 99b2c44..4669c48 100644 --- a/packages/frontend/src/app/app.routes.ts +++ b/packages/frontend/src/app/app.routes.ts @@ -11,7 +11,6 @@ import { AuthGuardData, createAuthGuard } from 'keycloak-angular'; import { Login } from './components/login/login'; import { MissingPage } from './components/missing-page/missing-page'; import { Claim } from './generated-api/api'; -import { keycloakConfig } from './util/keycloak-config'; export const roles = { UserAdmin: 'useradmin', @@ -71,9 +70,5 @@ export const routes: Routes = [ ), canActivate: [requireRoles([Claim.Memberadmin])], }, - { - path: 'profile', - redirectTo: `${keycloakConfig.url}/realms/${keycloakConfig.realm}/account`, - }, { path: '**', component: MissingPage }, ]; diff --git a/packages/frontend/src/app/app.scss b/packages/frontend/src/app/app.scss index 2e49617..92fbefb 100644 --- a/packages/frontend/src/app/app.scss +++ b/packages/frontend/src/app/app.scss @@ -1,10 +1,10 @@ -@media print { - .no-print { - display: none; - visibility: hidden; - } - - :not(.no-print) { - visibility: visible; - } +:host { + display: flex; + flex-direction: column; + height: 100%; + overflow: hidden; +} + +.outlet { + overflow: auto; } diff --git a/packages/frontend/src/app/app.ts b/packages/frontend/src/app/app.ts index 2b7727e..2dd53a3 100644 --- a/packages/frontend/src/app/app.ts +++ b/packages/frontend/src/app/app.ts @@ -1,15 +1,29 @@ -import { Component, inject, signal } from '@angular/core'; +import { Component, effect, inject, signal } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { RouterModule, RouterOutlet } from '@angular/router'; import { Authentication } from './services/authentication'; +import { keycloakConfig } from './util/keycloak-config'; @Component({ - selector: 'app-root', - imports: [RouterOutlet, MatButtonModule, RouterModule], - templateUrl: './app.html', - styleUrl: './app.scss', + selector: 'app-root', + imports: [RouterOutlet, MatButtonModule, RouterModule], + templateUrl: './app.html', + styleUrl: './app.scss', }) export class App { - protected readonly title = signal('frontend'); - protected readonly auth = inject(Authentication); + protected readonly title = signal('frontend'); + protected readonly auth = inject(Authentication); + + protected gotoProfile() { + window.location.href = `${keycloakConfig.url}/realms/${keycloakConfig.realm}/account`; + } + + constructor() { + effect(() => { + const loggedIn = this.auth.loggedIn(); + if (!loggedIn) { + this.auth.login(); + } + }); + } } diff --git a/packages/frontend/src/app/components/home/home.html b/packages/frontend/src/app/components/home/home.html index c985447..09e6688 100644 --- a/packages/frontend/src/app/components/home/home.html +++ b/packages/frontend/src/app/components/home/home.html @@ -1,14 +1,26 @@

Startseite

- + + + + + + + + + + + + + + diff --git a/packages/frontend/src/app/components/home/home.ts b/packages/frontend/src/app/components/home/home.ts index d4f6fc9..9e482b0 100644 --- a/packages/frontend/src/app/components/home/home.ts +++ b/packages/frontend/src/app/components/home/home.ts @@ -1,13 +1,21 @@ import { Component } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; +import { MatListModule } from '@angular/material/list'; import { RouterModule } from '@angular/router'; +import { ClaimGuardDirective } from '../../directives/claim-guard.directive'; +import { Claim } from '../../generated-api/api'; @Component({ - selector: 'app-home', - imports: [RouterModule, MatButtonModule], - templateUrl: './home.html', - styleUrl: './home.scss', + selector: 'app-home', + imports: [ + RouterModule, + MatButtonModule, + MatListModule, + ClaimGuardDirective, + ], + templateUrl: './home.html', + styleUrl: './home.scss', }) export class Home { - + protected Claim = Claim; } diff --git a/packages/frontend/src/app/components/view-members/view-members.html b/packages/frontend/src/app/components/view-members/view-members.html index d596632..087765a 100644 --- a/packages/frontend/src/app/components/view-members/view-members.html +++ b/packages/frontend/src/app/components/view-members/view-members.html @@ -1,142 +1,180 @@ -

Mitglieder & Sportlerübersicht

- -
-
- - +
+

Mitglieder & Sportlerübersicht

+
+
+ +
+
+ + + + +
+ + Aktiv + Inaktiv + Alle + + + + [matDatepicker]="picker" + [formControl]="statusDateControl" + placeholder="Aktiv bis" /> + DD.MM.YYYY + + -
- - Aktiv - Inaktiv - Alle - - - - - DD.MM.YYYY - - - -
- Nur mit Passnummer
+ Nur mit Passnummer
+
+ + + + + + - -
Bearb. + +
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - } - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + } + + - - - - + + + + - - -
Bearb. - - Entf. - - Vorname - - Nachname - - Geschlecht{{ element.geschlecht }}Passnummer - {{ element.passnummer | nobreakHyphen }} - Geburtsdatum - {{ element.geburtsdatum | datePipe }} - Geburtsort{{ element.geburtsort }} - Vereinsmitgliedschaft - - @if(element.verein){ - - }@else { + + Nr.{{i+1}}Vorname + + Nachname + + + Geschlecht + {{ element.geschlecht }} + Passnummer + + {{ element.passnummer | nobreakHyphen }} + + Geburtsdatum + + {{ element.geburtsdatum | datePipe }} + + Geburtsort + {{ element.geburtsort }} + Vereinsmitgliedschaft + + @if(element.verein){ + + }@else { - - Kontakt{{ element.kontakt }} - Kündigung zum - - {{ (element.kuendigungzum | datePipe) ?? "-" }} - Kontakt{{ element.kontakt }}
+ + + Kündigung zum + + + {{ (element.kuendigungzum | datePipe) ?? "-" }} + + + + + Entf. + + + + + + + + Zeige {{dataSource.filteredData.length}} von + {{dataSource.data.length}} Mitgliedern + @if(dataSource.filteredData.length !== dataSource.data.length) + {(gefiltert) } + + + + + + + +
diff --git a/packages/frontend/src/app/components/view-members/view-members.scss b/packages/frontend/src/app/components/view-members/view-members.scss index 38b8b06..eb4e0f6 100644 --- a/packages/frontend/src/app/components/view-members/view-members.scss +++ b/packages/frontend/src/app/components/view-members/view-members.scss @@ -1,16 +1,33 @@ -mat-radio-group { +@use "@angular/material" as mat; + +:host { display: flex; - flex-direction: column; + flex-flow: column; + height: 100%; + // overflow: auto; } -.filter-header { +.filter-container { display: flex; flex-direction: row; - justify-content: space-evenly; + justify-content: start; + gap: 5vw; + flex-wrap: wrap; +} + +.table-container { + overflow: auto; + border: 1px solid var(--mat-sys-outline); + min-height: 400px; } mat-form-field { - height: 100%; + display: inline-block; +} + +mat-radio-group { + display: flex; + flex-direction: column; } .status-filters { @@ -19,3 +36,16 @@ mat-form-field { justify-content: center; gap: 1rem; } + +td { + border: 1px solid var(--mat-sys-outline-variant); + border-collapse: collapse; +} + +.table-row:nth-child(even) { + background-color: var(--mat-sys-surface-variant); +} + +.table-row:nth-child(odd) { + background-color: var(--mat-sys-surface); +} diff --git a/packages/frontend/src/app/components/view-members/view-members.ts b/packages/frontend/src/app/components/view-members/view-members.ts index ff7ece4..bd71bf7 100644 --- a/packages/frontend/src/app/components/view-members/view-members.ts +++ b/packages/frontend/src/app/components/view-members/view-members.ts @@ -1,4 +1,5 @@ import { AfterViewInit, Component, viewChild } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { FormControl, ReactiveFormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; import { MatCheckbox } from '@angular/material/checkbox'; @@ -62,7 +63,7 @@ export class ViewMembers implements AfterViewInit { protected readonly displayedColumns: string[] = [ 'edit', - 'delete', + 'index', 'vorname', 'nachname', 'geschlecht', @@ -72,6 +73,7 @@ export class ViewMembers implements AfterViewInit { 'verein', 'kontakt', 'kuendigungzum', + 'delete', ]; protected deleteMember(memberId: any) { @@ -157,6 +159,7 @@ export class ViewMembers implements AfterViewInit { return originalFilterPredicate( { ...data, + id: null, geburtsdatum: this.datePipe.transform( data.geburtsdatum ?? undefined, ), @@ -189,7 +192,22 @@ export class ViewMembers implements AfterViewInit { const date = combined[2]; const onlyWithID = combined[3]; this.dataSource.filter = `${filter?.replaceAll(';', '') ?? ''};${status};${date?.toISOString()};${onlyWithID}`; - console.log('filter', this.dataSource.filter); + }); + + this.statusControl.valueChanges + .pipe(takeUntilDestroyed()) + .subscribe(value => { + if ( + value === MemberStatusFilter.ALL && + this.statusDateControl.enabled + ) { + return this.statusDateControl.disable(); + } else if ( + value !== MemberStatusFilter.ALL && + this.statusDateControl.disabled + ) { + return this.statusDateControl.enable(); + } }); this.updateData(); @@ -202,8 +220,6 @@ export class ViewMembers implements AfterViewInit { private async updateData(): Promise { const members = await api.getMembers(); - console.log('Members loaded'); - console.dir(members); this.dataSource.data = members; } } diff --git a/packages/frontend/src/app/directives/claim-guard.directive.ts b/packages/frontend/src/app/directives/claim-guard.directive.ts new file mode 100644 index 0000000..db009a1 --- /dev/null +++ b/packages/frontend/src/app/directives/claim-guard.directive.ts @@ -0,0 +1,27 @@ +import { Directive, effect, ElementRef, inject, input } from '@angular/core'; +import { Claim } from '../generated-api/api'; +import { Authentication } from '../services/authentication'; + +@Directive({ + selector: '[claimGuard]', +}) +export class ClaimGuardDirective { + private readonly element = inject(ElementRef); + private readonly auth = inject(Authentication); + + public readonly claimGuard = input.required(); + private readonly originalDisplay = this.element.nativeElement.style.display; + + constructor() { + effect(() => { + const claims = this.auth.claims(); + const requiredClaim = this.claimGuard(); + + if (!claims || !claims[requiredClaim]) { + this.element.nativeElement.style.display = 'none'; + } else { + this.element.nativeElement.style.display = this.originalDisplay; + } + }); + } +} diff --git a/packages/frontend/src/styles.colors.scss b/packages/frontend/src/styles.colors.scss deleted file mode 100644 index 8500bd1..0000000 --- a/packages/frontend/src/styles.colors.scss +++ /dev/null @@ -1,205 +0,0 @@ -// This file was generated by running 'ng generate @angular/material:theme-color'. -// Proceed with caution if making changes to this file. - -@use 'sass:map'; -@use '@angular/material' as mat; - -// Note: Color palettes are generated from primary: #0047a0, secondary: #cc9c00, tertiary: #cd2e3a, error: #E63241 -$_palettes: ( - primary: ( - 0: #000000, - 10: #001a43, - 20: #002d6c, - 25: #003881, - 30: #004397, - 35: #134fa8, - 40: #275bb5, - 50: #4575cf, - 60: #618feb, - 70: #83aaff, - 80: #afc6ff, - 90: #d8e2ff, - 95: #edf0ff, - 98: #faf9ff, - 99: #fefbff, - 100: #ffffff, - ), - secondary: ( - 0: #000000, - 10: #251a00, - 20: #3f2e00, - 25: #4c3800, - 30: #5a4300, - 35: #694f00, - 40: #775a00, - 50: #967200, - 60: #b58a00, - 70: #d5a411, - 80: #f3bf33, - 90: #ffdf99, - 95: #ffefd2, - 98: #fff8f2, - 99: #fffbff, - 100: #ffffff, - ), - tertiary: ( - 0: #000000, - 10: #410007, - 20: #680010, - 25: #7d0016, - 30: #92001b, - 35: #a60a23, - 40: #b81d2d, - 50: #db3943, - 60: #ff535a, - 70: #ff8887, - 80: #ffb3b0, - 90: #ffdad8, - 95: #ffedeb, - 98: #fff8f7, - 99: #fffbff, - 100: #ffffff, - ), - neutral: ( - 0: #000000, - 10: #191b21, - 20: #2e3036, - 25: #393b42, - 30: #45464d, - 35: #515259, - 40: #5d5e65, - 50: #75777e, - 60: #8f9098, - 70: #aaabb2, - 80: #c5c6ce, - 90: #e2e2ea, - 95: #f0f0f8, - 98: #faf9ff, - 99: #fefbff, - 100: #ffffff, - 4: #0c0e14, - 6: #111319, - 12: #1d1f25, - 17: #282a30, - 22: #33353b, - 24: #37393f, - 87: #d9d9e1, - 92: #e7e7f0, - 94: #ededf5, - 96: #f3f3fb, - ), - neutral-variant: ( - 0: #000000, - 10: #171b25, - 20: #2c303b, - 25: #373b46, - 30: #434752, - 35: #4e525e, - 40: #5a5e6a, - 50: #737783, - 60: #8d909d, - 70: #a7abb8, - 80: #c3c6d4, - 90: #dfe2f0, - 95: #edf0ff, - 98: #faf9ff, - 99: #fefbff, - 100: #ffffff, - ), - error: ( - 0: #000000, - 10: #410007, - 20: #680011, - 25: #7d0016, - 30: #92001c, - 35: #a90021, - 40: #bd0b29, - 50: #e12e3e, - 60: #ff535a, - 70: #ff8887, - 80: #ffb3b1, - 90: #ffdad8, - 95: #ffedeb, - 98: #fff8f7, - 99: #fffbff, - 100: #ffffff, - ), -); - -$_rest: ( - secondary: map.get($_palettes, secondary), - neutral: map.get($_palettes, neutral), - neutral-variant: map.get($_palettes, neutral-variant), - error: map.get($_palettes, error), -); - -$primary-palette: map.merge(map.get($_palettes, primary), $_rest); -$tertiary-palette: map.merge(map.get($_palettes, tertiary), $_rest); - -@function _high-contrast-value($light, $dark, $theme-type) { - @if ($theme-type == light) { - @return $light; - } - @if ($theme-type == dark) { - @return $dark; - } - @if ($theme-type == color-scheme) { - @return light-dark(#{$light}, #{$dark}); - } - - @error 'Unknown theme-type #{$theme-type}. Expected light, dark, or color-scheme'; -} - -@mixin high-contrast-overrides($theme-type) { - @include mat.theme-overrides(( - primary: _high-contrast-value(#002963, #ecefff, $theme-type), - on-primary: _high-contrast-value(#ffffff, #000000, $theme-type), - primary-container: _high-contrast-value(#00459c, #a9c2ff, $theme-type), - on-primary-container: _high-contrast-value(#ffffff, #000a23, $theme-type), - inverse-primary: _high-contrast-value(#afc6ff, #00449a, $theme-type), - primary-fixed: _high-contrast-value(#00459c, #d8e2ff, $theme-type), - primary-fixed-dim: _high-contrast-value(#003070, #afc6ff, $theme-type), - on-primary-fixed: _high-contrast-value(#ffffff, #000000, $theme-type), - on-primary-fixed-variant: _high-contrast-value(#ffffff, #00102f, $theme-type), - secondary: _high-contrast-value(#392a00, #ffeecf, $theme-type), - on-secondary: _high-contrast-value(#ffffff, #000000, $theme-type), - secondary-container: _high-contrast-value(#5d4600, #efbb2f, $theme-type), - on-secondary-container: _high-contrast-value(#ffffff, #110a00, $theme-type), - secondary-fixed: _high-contrast-value(#5d4600, #ffdf99, $theme-type), - secondary-fixed-dim: _high-contrast-value(#413000, #f3bf33, $theme-type), - on-secondary-fixed: _high-contrast-value(#ffffff, #000000, $theme-type), - on-secondary-fixed-variant: _high-contrast-value(#ffffff, #181000, $theme-type), - tertiary: _high-contrast-value(#60000e, #ffecea, $theme-type), - on-tertiary: _high-contrast-value(#ffffff, #000000, $theme-type), - tertiary-container: _high-contrast-value(#97001c, #ffadab, $theme-type), - on-tertiary-container: _high-contrast-value(#ffffff, #220002, $theme-type), - tertiary-fixed: _high-contrast-value(#97001c, #ffdad8, $theme-type), - tertiary-fixed-dim: _high-contrast-value(#6c0011, #ffb3b0, $theme-type), - on-tertiary-fixed: _high-contrast-value(#ffffff, #000000, $theme-type), - on-tertiary-fixed-variant: _high-contrast-value(#ffffff, #2d0003, $theme-type), - background: _high-contrast-value(#faf9ff, #111319, $theme-type), - on-background: _high-contrast-value(#191b21, #e2e2ea, $theme-type), - surface: _high-contrast-value(#faf9ff, #111319, $theme-type), - surface-dim: _high-contrast-value(#b8b8c0, #111319, $theme-type), - surface-bright: _high-contrast-value(#faf9ff, #4e5056, $theme-type), - surface-container-low: _high-contrast-value(#f0f0f8, #1d1f25, $theme-type), - surface-container-lowest: _high-contrast-value(#ffffff, #000000, $theme-type), - surface-container: _high-contrast-value(#e2e2ea, #2e3036, $theme-type), - surface-container-high: _high-contrast-value(#d3d4dc, #393b42, $theme-type), - surface-container-highest: _high-contrast-value(#c5c6ce, #45464d, $theme-type), - on-surface: _high-contrast-value(#000000, #ffffff, $theme-type), - shadow: _high-contrast-value(#000000, #000000, $theme-type), - scrim: _high-contrast-value(#000000, #000000, $theme-type), - surface-tint: _high-contrast-value(#275bb5, #afc6ff, $theme-type), - inverse-surface: _high-contrast-value(#2e3036, #e2e2ea, $theme-type), - inverse-on-surface: _high-contrast-value(#ffffff, #000000, $theme-type), - outline: _high-contrast-value(#282c37, #edeffe, $theme-type), - outline-variant: _high-contrast-value(#454954, #bfc2d0, $theme-type), - error: _high-contrast-value(#60000e, #ffecea, $theme-type), - on-error: _high-contrast-value(#ffffff, #000000, $theme-type), - error-container: _high-contrast-value(#97001d, #ffadab, $theme-type), - on-error-container: _high-contrast-value(#ffffff, #220002, $theme-type), - surface-variant: _high-contrast-value(#dfe2f0, #434752, $theme-type), - on-surface-variant: _high-contrast-value(#000000, #ffffff, $theme-type), - )) - } diff --git a/packages/frontend/src/styles.scss b/packages/frontend/src/styles.scss index 6c49839..0427794 100644 --- a/packages/frontend/src/styles.scss +++ b/packages/frontend/src/styles.scss @@ -1,47 +1,109 @@ - // Include theming for Angular Material with `mat.theme()`. // This Sass mixin will define CSS variables that are used for styling Angular Material // components according to the Material 3 design spec. // Learn more about theming and how to use it for your application's // custom components at https://material.angular.dev/guide/theming -@use '@angular/material' as mat; -@use './styles.colors.scss' as my-theme; + +@use "@angular/material" as mat; +@use "./theme-colors.scss" as theme-colors; @include mat.core(); -@include mat.core-theme(my-theme.$primary-palette); -@include mat.button-theme(my-theme.$primary-palette); - html { - @include mat.theme(( - color: ( - primary: my-theme.$primary-palette, - tertiary: my-theme.$tertiary-palette, - ), - typography: Roboto, - density: 0, - )); - @include mat.core-theme(my-theme.$primary-palette); - @include mat.button-theme(my-theme.$primary-palette); + // Default the application to a light color theme. This can be changed to + // `dark` to enable the dark color theme, or to `light dark` to defer to the + // user's system settings. + color-scheme: light; + + @include mat.theme( + ( + color: ( + theme-type: light, + primary: theme-colors.$primary-palette, + tertiary: theme-colors.$tertiary-palette, + ), + typography: ( + plain-family: Roboto, + brand-family: Roboto, + ), + density: ( + scale: 0, + ), + ) + ); + + // Define css classes like .mat-text-on-surface + // @include mat.system-classes(); + + .primary-btn { + @include mat.button-overrides( + ( + filled-container-color: var(--mat-sys-primary), + filled-label-text-color: var(--mat-sys-on-primary), + outlined-label-text-color: var(--mat-sys-primary), + outlined-outline-color: var(--mat-sys-primary), + protected-container-color: var(--mat-sys-primary), + protected-label-text-color: var(--mat-sys-on-primary), + text-label-text-color: var(--mat-sys-primary), + tonal-label-text-color: var(--mat-sys-primary), + ) + ); + } + .secondary-btn { + @include mat.button-overrides( + ( + filled-container-color: var(--mat-sys-secondary), + filled-label-text-color: var(--mat-sys-on-secondary), + outlined-label-text-color: var(--mat-sys-secondary), + outlined-outline-color: var(--mat-sys-secondary), + protected-container-color: var(--mat-sys-secondary), + protected-label-text-color: var(--mat-sys-on-secondary), + text-label-text-color: var(--mat-sys-secondary), + tonal-label-text-color: var(--mat-sys-secondary), + ) + ); + } + .tertiary-btn { + @include mat.button-overrides( + ( + filled-container-color: var(--mat-sys-tertiary), + filled-label-text-color: var(--mat-sys-on-tertiary), + outlined-label-text-color: var(--mat-sys-tertiary), + outlined-outline-color: var(--mat-sys-tertiary), + protected-container-color: var(--mat-sys-tertiary), + protected-label-text-color: var(--mat-sys-on-tertiary), + text-label-text-color: var(--mat-sys-tertiary), + tonal-label-text-color: var(--mat-sys-tertiary), + ) + ); + } } body { - // Default the application to a light color theme. This can be changed to - // `dark` to enable the dark color theme, or to `light dark` to defer to the - // user's system settings. - color-scheme: light; + // Set a default background, font and text colors for the application using + // Angular Material's system-level CSS variables. Learn more about these + // variables at https://material.angular.dev/guide/system-variables + background-color: var(--mat-sys-surface); + color: var(--mat-sys-on-surface); + // font: var(--mat-sys-body-medium); - // Set a default background, font and text colors for the application using - // Angular Material's system-level CSS variables. Learn more about these - // variables at https://material.angular.dev/guide/system-variables - background-color: var(--mat-sys-surface); - color: var(--mat-sys-on-surface); - font: var(--mat-sys-body-medium); - - // Reset the user agent margin. - margin: 0; + // Reset the user agent margin. + margin: 0; } /* You can add global styles to this file, and also import other style files */ -html, body { height: 100%; } -body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; } +html, +body { + height: 100%; +} + +@media print { + .no-print { + display: none; + visibility: hidden; + } + + :not(.no-print) { + visibility: visible; + } +} diff --git a/packages/frontend/src/theme-colors.scss b/packages/frontend/src/theme-colors.scss new file mode 100644 index 0000000..10d1b86 --- /dev/null +++ b/packages/frontend/src/theme-colors.scss @@ -0,0 +1,137 @@ +// This file was generated by running 'ng generate @angular/material:theme-color'. +// Proceed with caution if making changes to this file. + +@use 'sass:map'; +@use '@angular/material' as mat; + +// Note: Color palettes are generated from primary: #0047a0, secondary: #cd2e3a, tertiary: #673b6d +$_palettes: ( + primary: ( + 0: #000000, + 10: #001a43, + 20: #002d6c, + 25: #003881, + 30: #004397, + 35: #134fa8, + 40: #275bb5, + 50: #4575cf, + 60: #618feb, + 70: #83aaff, + 80: #afc6ff, + 90: #d8e2ff, + 95: #edf0ff, + 98: #faf9ff, + 99: #fefbff, + 100: #ffffff, + ), + secondary: ( + 0: #000000, + 10: #410007, + 20: #680010, + 25: #7d0016, + 30: #92001b, + 35: #a60a23, + 40: #b81d2d, + 50: #db3943, + 60: #ff535a, + 70: #ff8887, + 80: #ffb3b0, + 90: #ffdad8, + 95: #ffedeb, + 98: #fff8f7, + 99: #fffbff, + 100: #ffffff, + ), + tertiary: ( + 0: #000000, + 10: #310839, + 20: #491f50, + 25: #552b5c, + 30: #623668, + 35: #6f4274, + 40: #7c4e81, + 50: #96669b, + 60: #b27fb6, + 70: #ce99d2, + 80: #ecb4ef, + 90: #ffd5ff, + 95: #ffebfc, + 98: #fff7fa, + 99: #fffbff, + 100: #ffffff, + ), + neutral: ( + 0: #000000, + 10: #191b21, + 20: #2e3036, + 25: #393b42, + 30: #45464d, + 35: #515259, + 40: #5d5e65, + 50: #75777e, + 60: #8f9098, + 70: #aaabb2, + 80: #c5c6ce, + 90: #e2e2ea, + 95: #f0f0f8, + 98: #faf9ff, + 99: #fefbff, + 100: #ffffff, + 4: #0c0e14, + 6: #111319, + 12: #1d1f25, + 17: #282a30, + 22: #33353b, + 24: #37393f, + 87: #d9d9e1, + 92: #e7e7f0, + 94: #ededf5, + 96: #f3f3fb, + ), + neutral-variant: ( + 0: #000000, + 10: #171b25, + 20: #2c303b, + 25: #373b46, + 30: #434752, + 35: #4e525e, + 40: #5a5e6a, + 50: #737783, + 60: #8d909d, + 70: #a7abb8, + 80: #c3c6d4, + 90: #dfe2f0, + 95: #edf0ff, + 98: #faf9ff, + 99: #fefbff, + 100: #ffffff, + ), + error: ( + 0: #000000, + 10: #410002, + 20: #690005, + 25: #7e0007, + 30: #93000a, + 35: #a80710, + 40: #ba1a1a, + 50: #de3730, + 60: #ff5449, + 70: #ff897d, + 80: #ffb4ab, + 90: #ffdad6, + 95: #ffedea, + 98: #fff8f7, + 99: #fffbff, + 100: #ffffff, + ), +); + +$_rest: ( + secondary: map.get($_palettes, secondary), + neutral: map.get($_palettes, neutral), + neutral-variant: map.get($_palettes, neutral-variant), + error: map.get($_palettes, error), +); + +$primary-palette: map.merge(map.get($_palettes, primary), $_rest); +$tertiary-palette: map.merge(map.get($_palettes, tertiary), $_rest); \ No newline at end of file