main #6
					 25 changed files with 385 additions and 98 deletions
				
			
		
							
								
								
									
										32
									
								
								.gitea/workflows/release.yml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								.gitea/workflows/release.yml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,32 @@
 | 
				
			||||||
 | 
					name: Release
 | 
				
			||||||
 | 
					on:
 | 
				
			||||||
 | 
					  push:
 | 
				
			||||||
 | 
					    branches:
 | 
				
			||||||
 | 
					      - prod
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					env:
 | 
				
			||||||
 | 
					  GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					permissions:
 | 
				
			||||||
 | 
					  contents: read # for checkout
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					concurrency:
 | 
				
			||||||
 | 
					  group: ${{ github.ref }}  # Ensure each branch has its own group
 | 
				
			||||||
 | 
					  cancel-in-progress: false # Prevent new runs from canceling in-progress runs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					jobs:
 | 
				
			||||||
 | 
					  release:
 | 
				
			||||||
 | 
					    name: Release
 | 
				
			||||||
 | 
					    runs-on: ubuntu-latest
 | 
				
			||||||
 | 
					    permissions:
 | 
				
			||||||
 | 
					      contents: write # to be able to publish a GitHub release
 | 
				
			||||||
 | 
					      issues: write # to be able to comment on released issues
 | 
				
			||||||
 | 
					      pull-requests: write # to be able to comment on released pull requests
 | 
				
			||||||
 | 
					      id-token: write # to enable use of OIDC for npm provenance
 | 
				
			||||||
 | 
					    steps:
 | 
				
			||||||
 | 
					      - name: Create Release
 | 
				
			||||||
 | 
					        uses: https://git.kjan.de/actions/semantic-release@main
 | 
				
			||||||
 | 
					        with:
 | 
				
			||||||
 | 
					          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
 | 
				
			||||||
 | 
					          GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,7 +27,8 @@
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
            "styles": [
 | 
					            "styles": [
 | 
				
			||||||
              "src/styles.css"
 | 
					              "@angular/material/prebuilt-themes/azure-blue.css",
 | 
				
			||||||
 | 
					              "src/styles.scss"
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
            "scripts": []
 | 
					            "scripts": []
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
| 
						 | 
					@ -97,6 +98,7 @@
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
            "styles": [
 | 
					            "styles": [
 | 
				
			||||||
 | 
					              "@angular/material/prebuilt-themes/azure-blue.css",
 | 
				
			||||||
              "src/styles.css"
 | 
					              "src/styles.css"
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
            "scripts": []
 | 
					            "scripts": []
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										41
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										41
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							| 
						 | 
					@ -9,10 +9,12 @@
 | 
				
			||||||
      "version": "0.0.0",
 | 
					      "version": "0.0.0",
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "@angular/animations": "^19.0.0",
 | 
					        "@angular/animations": "^19.0.0",
 | 
				
			||||||
 | 
					        "@angular/cdk": "^19.1.0",
 | 
				
			||||||
        "@angular/common": "^19.0.0",
 | 
					        "@angular/common": "^19.0.0",
 | 
				
			||||||
        "@angular/compiler": "^19.0.0",
 | 
					        "@angular/compiler": "^19.0.0",
 | 
				
			||||||
        "@angular/core": "^19.0.0",
 | 
					        "@angular/core": "^19.0.0",
 | 
				
			||||||
        "@angular/forms": "^19.0.0",
 | 
					        "@angular/forms": "^19.0.0",
 | 
				
			||||||
 | 
					        "@angular/material": "^19.1.0",
 | 
				
			||||||
        "@angular/platform-browser": "^19.0.0",
 | 
					        "@angular/platform-browser": "^19.0.0",
 | 
				
			||||||
        "@angular/platform-browser-dynamic": "^19.0.0",
 | 
					        "@angular/platform-browser-dynamic": "^19.0.0",
 | 
				
			||||||
        "@angular/router": "^19.0.0",
 | 
					        "@angular/router": "^19.0.0",
 | 
				
			||||||
| 
						 | 
					@ -390,6 +392,23 @@
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/@angular/cdk": {
 | 
				
			||||||
 | 
					      "version": "19.1.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-19.1.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-h7VSaMA/vFHb7u1bwoHKl3L3mZLIcXNZw6v7Nei9ITfEo1PfSKbrYhleeqpNikzE+LxNDKJrbZtpAckSYHblmA==",
 | 
				
			||||||
 | 
					      "license": "MIT",
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "tslib": "^2.3.0"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "optionalDependencies": {
 | 
				
			||||||
 | 
					        "parse5": "^7.1.2"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "peerDependencies": {
 | 
				
			||||||
 | 
					        "@angular/common": "^19.0.0 || ^20.0.0",
 | 
				
			||||||
 | 
					        "@angular/core": "^19.0.0 || ^20.0.0",
 | 
				
			||||||
 | 
					        "rxjs": "^6.5.3 || ^7.4.0"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/@angular/cli": {
 | 
					    "node_modules/@angular/cli": {
 | 
				
			||||||
      "version": "19.1.2",
 | 
					      "version": "19.1.2",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-19.1.2.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-19.1.2.tgz",
 | 
				
			||||||
| 
						 | 
					@ -517,6 +536,24 @@
 | 
				
			||||||
        "rxjs": "^6.5.3 || ^7.4.0"
 | 
					        "rxjs": "^6.5.3 || ^7.4.0"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/@angular/material": {
 | 
				
			||||||
 | 
					      "version": "19.1.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/@angular/material/-/material-19.1.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-LTQBWtuRGjNpA7ceQu9PyiUUq0KLfBP8LvL04hLFbEsZ0fIPQ/OO/Otn67/7TMtnHRFnPeezYPHcAHBhiNlR4A==",
 | 
				
			||||||
 | 
					      "license": "MIT",
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "tslib": "^2.3.0"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "peerDependencies": {
 | 
				
			||||||
 | 
					        "@angular/animations": "^19.0.0 || ^20.0.0",
 | 
				
			||||||
 | 
					        "@angular/cdk": "19.1.0",
 | 
				
			||||||
 | 
					        "@angular/common": "^19.0.0 || ^20.0.0",
 | 
				
			||||||
 | 
					        "@angular/core": "^19.0.0 || ^20.0.0",
 | 
				
			||||||
 | 
					        "@angular/forms": "^19.0.0 || ^20.0.0",
 | 
				
			||||||
 | 
					        "@angular/platform-browser": "^19.0.0 || ^20.0.0",
 | 
				
			||||||
 | 
					        "rxjs": "^6.5.3 || ^7.4.0"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/@angular/platform-browser": {
 | 
					    "node_modules/@angular/platform-browser": {
 | 
				
			||||||
      "version": "19.1.1",
 | 
					      "version": "19.1.1",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-19.1.1.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-19.1.1.tgz",
 | 
				
			||||||
| 
						 | 
					@ -6663,7 +6700,7 @@
 | 
				
			||||||
      "version": "4.5.0",
 | 
					      "version": "4.5.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
 | 
				
			||||||
      "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
 | 
					      "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
 | 
				
			||||||
      "dev": true,
 | 
					      "devOptional": true,
 | 
				
			||||||
      "engines": {
 | 
					      "engines": {
 | 
				
			||||||
        "node": ">=0.12"
 | 
					        "node": ">=0.12"
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
| 
						 | 
					@ -10387,7 +10424,7 @@
 | 
				
			||||||
      "version": "7.2.1",
 | 
					      "version": "7.2.1",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz",
 | 
				
			||||||
      "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==",
 | 
					      "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==",
 | 
				
			||||||
      "dev": true,
 | 
					      "devOptional": true,
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "entities": "^4.5.0"
 | 
					        "entities": "^4.5.0"
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,10 +11,12 @@
 | 
				
			||||||
  "private": true,
 | 
					  "private": true,
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "@angular/animations": "^19.0.0",
 | 
					    "@angular/animations": "^19.0.0",
 | 
				
			||||||
 | 
					    "@angular/cdk": "^19.1.0",
 | 
				
			||||||
    "@angular/common": "^19.0.0",
 | 
					    "@angular/common": "^19.0.0",
 | 
				
			||||||
    "@angular/compiler": "^19.0.0",
 | 
					    "@angular/compiler": "^19.0.0",
 | 
				
			||||||
    "@angular/core": "^19.0.0",
 | 
					    "@angular/core": "^19.0.0",
 | 
				
			||||||
    "@angular/forms": "^19.0.0",
 | 
					    "@angular/forms": "^19.0.0",
 | 
				
			||||||
 | 
					    "@angular/material": "^19.1.0",
 | 
				
			||||||
    "@angular/platform-browser": "^19.0.0",
 | 
					    "@angular/platform-browser": "^19.0.0",
 | 
				
			||||||
    "@angular/platform-browser-dynamic": "^19.0.0",
 | 
					    "@angular/platform-browser-dynamic": "^19.0.0",
 | 
				
			||||||
    "@angular/router": "^19.0.0",
 | 
					    "@angular/router": "^19.0.0",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,8 @@ import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
 | 
				
			||||||
import { provideRouter } from '@angular/router';
 | 
					import { provideRouter } from '@angular/router';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { routes } from './app.routes';
 | 
					import { routes } from './app.routes';
 | 
				
			||||||
 | 
					import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const appConfig: ApplicationConfig = {
 | 
					export const appConfig: ApplicationConfig = {
 | 
				
			||||||
  providers: [provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes)]
 | 
					  providers: [provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes), provideAnimationsAsync()]
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,6 +2,8 @@ import { Routes } from '@angular/router';
 | 
				
			||||||
import { LoginComponent } from './login/login.component';
 | 
					import { LoginComponent } from './login/login.component';
 | 
				
			||||||
import { DashboardComponent } from './dashboard/dashboard.component';
 | 
					import { DashboardComponent } from './dashboard/dashboard.component';
 | 
				
			||||||
import { AuthGuard } from './service/auth.service';
 | 
					import { AuthGuard } from './service/auth.service';
 | 
				
			||||||
 | 
					import { CreateLinkComponent } from './create-link/create-link.component';
 | 
				
			||||||
 | 
					import { ViewLinkComponent } from './view-link/view-link.component';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const routes: Routes = [
 | 
					export const routes: Routes = [
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
| 
						 | 
					@ -13,6 +15,15 @@ export const routes: Routes = [
 | 
				
			||||||
    component: DashboardComponent,
 | 
					    component: DashboardComponent,
 | 
				
			||||||
    canActivate: [AuthGuard],
 | 
					    canActivate: [AuthGuard],
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    path: 'create-link',
 | 
				
			||||||
 | 
					    component: CreateLinkComponent,
 | 
				
			||||||
 | 
					    canActivate: [AuthGuard],
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    path: ':link',
 | 
				
			||||||
 | 
					    component: ViewLinkComponent,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    path: "**",
 | 
					    path: "**",
 | 
				
			||||||
    redirectTo: "",
 | 
					    redirectTo: "",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										0
									
								
								src/app/create-link/create-link.component.css
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								src/app/create-link/create-link.component.css
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										19
									
								
								src/app/create-link/create-link.component.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/app/create-link/create-link.component.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,19 @@
 | 
				
			||||||
 | 
					<div class="mx-auto container">
 | 
				
			||||||
 | 
					  <app-navbar></app-navbar>
 | 
				
			||||||
 | 
					  <button mat-flat-button class="mt-3" color="warn" (click)="back()">Back</button>
 | 
				
			||||||
 | 
					  <mat-card class="mt-3 p-3" appearance="outlined">
 | 
				
			||||||
 | 
					    <form class="flex flex-col" [formGroup]="createLinkForm">
 | 
				
			||||||
 | 
					      <mat-form-field appearance="outline">
 | 
				
			||||||
 | 
					        <mat-error>{{errorMessages['name']}}</mat-error>
 | 
				
			||||||
 | 
					        <mat-label>Name</mat-label>
 | 
				
			||||||
 | 
					        <input formControlName="name" matInput placeholder="My Awesome link">
 | 
				
			||||||
 | 
					      </mat-form-field>
 | 
				
			||||||
 | 
					      <mat-form-field appearance="outline">
 | 
				
			||||||
 | 
					        <mat-error>{{errorMessages['link']}}</mat-error>
 | 
				
			||||||
 | 
					        <mat-label>Link</mat-label>
 | 
				
			||||||
 | 
					        <input formControlName="link" matInput type="url" placeholder="https://kjan.de">
 | 
				
			||||||
 | 
					      </mat-form-field>
 | 
				
			||||||
 | 
					      <button mat-flat-button type="submit" (click)="submit()">Create</button>
 | 
				
			||||||
 | 
					    </form>
 | 
				
			||||||
 | 
					  </mat-card>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
							
								
								
									
										23
									
								
								src/app/create-link/create-link.component.spec.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/app/create-link/create-link.component.spec.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,23 @@
 | 
				
			||||||
 | 
					import { ComponentFixture, TestBed } from '@angular/core/testing';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { CreateLinkComponent } from './create-link.component';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					describe('CreateLinkComponent', () => {
 | 
				
			||||||
 | 
					  let component: CreateLinkComponent;
 | 
				
			||||||
 | 
					  let fixture: ComponentFixture<CreateLinkComponent>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  beforeEach(async () => {
 | 
				
			||||||
 | 
					    await TestBed.configureTestingModule({
 | 
				
			||||||
 | 
					      imports: [CreateLinkComponent]
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    .compileComponents();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fixture = TestBed.createComponent(CreateLinkComponent);
 | 
				
			||||||
 | 
					    component = fixture.componentInstance;
 | 
				
			||||||
 | 
					    fixture.detectChanges();
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('should create', () => {
 | 
				
			||||||
 | 
					    expect(component).toBeTruthy();
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
							
								
								
									
										74
									
								
								src/app/create-link/create-link.component.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								src/app/create-link/create-link.component.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,74 @@
 | 
				
			||||||
 | 
					import { Component } from '@angular/core';
 | 
				
			||||||
 | 
					import { NavbarComponent } from '../navbar/navbar.component';
 | 
				
			||||||
 | 
					import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
 | 
				
			||||||
 | 
					import { LinkService } from '../service/link.service';
 | 
				
			||||||
 | 
					import { Router } from '@angular/router';
 | 
				
			||||||
 | 
					import { MatCardModule } from '@angular/material/card';
 | 
				
			||||||
 | 
					import { MatInputModule, MatLabel } from '@angular/material/input';
 | 
				
			||||||
 | 
					import { MatFormFieldModule } from '@angular/material/form-field';
 | 
				
			||||||
 | 
					import { MatButtonModule } from '@angular/material/button';
 | 
				
			||||||
 | 
					import { debounceTime } from 'rxjs';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Component({
 | 
				
			||||||
 | 
					  selector: 'app-create-link',
 | 
				
			||||||
 | 
					  imports: [NavbarComponent, ReactiveFormsModule, MatCardModule, MatFormFieldModule, MatInputModule, MatButtonModule],
 | 
				
			||||||
 | 
					  templateUrl: './create-link.component.html',
 | 
				
			||||||
 | 
					  styleUrl: './create-link.component.css'
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					export class CreateLinkComponent {
 | 
				
			||||||
 | 
					  public createLinkForm!: FormGroup;
 | 
				
			||||||
 | 
					  public requestFailed: boolean = false;
 | 
				
			||||||
 | 
					  public errorMessages: Record<string, string> = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  constructor(private linkService: LinkService, private router: Router) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private validationErrorMessages: Record<string, string> = {
 | 
				
			||||||
 | 
					    required: "This field is required",
 | 
				
			||||||
 | 
					    pattern: "This must be a valid url",
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  updateErrorMessages(): void {
 | 
				
			||||||
 | 
					    this.errorMessages = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Object.keys(this.createLinkForm.controls).forEach(field => {
 | 
				
			||||||
 | 
					      const control = this.createLinkForm.get(field);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (control && control.errors) {
 | 
				
			||||||
 | 
					        this.errorMessages[field] = Object.keys(control.errors)
 | 
				
			||||||
 | 
					          .map(errorKey => this.validationErrorMessages[errorKey] || `Unknown error: ${errorKey}`)
 | 
				
			||||||
 | 
					          .join(' ');
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  back() {
 | 
				
			||||||
 | 
					    this.router.navigate(['dashboard']);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ngOnInit(): void {
 | 
				
			||||||
 | 
					    this.createLinkForm = new FormGroup({
 | 
				
			||||||
 | 
					      name: new FormControl('', Validators.required),
 | 
				
			||||||
 | 
					      link: new FormControl('', [Validators.required, Validators.pattern(/((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)/)]),
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    this.createLinkForm.valueChanges.subscribe(() => {
 | 
				
			||||||
 | 
					      this.updateErrorMessages();
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  submit() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!this.createLinkForm.valid) {
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.requestFailed = false;
 | 
				
			||||||
 | 
					    this.linkService.createLink({
 | 
				
			||||||
 | 
					      name: this.createLinkForm.get('name')?.value,
 | 
				
			||||||
 | 
					      link: this.createLinkForm.get('link')?.value,
 | 
				
			||||||
 | 
					    }).catch(() => this.requestFailed = true).finally(() => {
 | 
				
			||||||
 | 
					      if (!this.requestFailed) {
 | 
				
			||||||
 | 
					        this.router.navigate(['dashboard']);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,27 +1,56 @@
 | 
				
			||||||
<div class="mx-auto container">
 | 
					<div class="mx-auto container">
 | 
				
			||||||
  <app-navbar></app-navbar>
 | 
					  <app-navbar></app-navbar>
 | 
				
			||||||
  <div class="overflow-x-auto">
 | 
					  <div class="overflow-x-auto">
 | 
				
			||||||
    <table class="table">
 | 
					    <button mat-flat-button color="secondary" class="my-3" (click)="createLink()">Create new Link</button>
 | 
				
			||||||
      <!-- head -->
 | 
					
 | 
				
			||||||
      <thead>
 | 
					    <mat-card appearance="outlined">
 | 
				
			||||||
        <tr>
 | 
					      <mat-card-content>
 | 
				
			||||||
          <th></th>
 | 
					        <table mat-table [dataSource]="links" class="mat-elevation-z8">
 | 
				
			||||||
          <th>Name</th>
 | 
					
 | 
				
			||||||
          <th>Url</th>
 | 
					          <!--- Note that these columns can be defined in any order.
 | 
				
			||||||
          <th>Short Url</th>
 | 
					        The actual rendered columns are set as a property on the row definition" -->
 | 
				
			||||||
        </tr>
 | 
					
 | 
				
			||||||
      </thead>
 | 
					          <!-- Position Column -->
 | 
				
			||||||
      <tbody>
 | 
					          <ng-container matColumnDef="id">
 | 
				
			||||||
        <!-- row 1 -->
 | 
					            <th mat-header-cell *matHeaderCellDef> ID </th>
 | 
				
			||||||
        @for (link of links; track link) {
 | 
					            <td mat-cell *matCellDef="let element">
 | 
				
			||||||
        <tr class="bg-base-200">
 | 
					              <a href="{{element.id}}">
 | 
				
			||||||
          <th>{{link.id}}</th>
 | 
					                {{element.id}}
 | 
				
			||||||
          <td>{{link.name}}</td>
 | 
					              </a>
 | 
				
			||||||
          <td><a href="{{link.link}}">{{link.link}}</a></td>
 | 
					            </td>
 | 
				
			||||||
          <td>ndy</td>
 | 
					          </ng-container>
 | 
				
			||||||
        </tr>
 | 
					
 | 
				
			||||||
        }
 | 
					          <!-- Name Column -->
 | 
				
			||||||
      </tbody>
 | 
					          <ng-container matColumnDef="name">
 | 
				
			||||||
    </table>
 | 
					            <th mat-header-cell *matHeaderCellDef> Name </th>
 | 
				
			||||||
 | 
					            <td mat-cell *matCellDef="let element"> {{element.name}} </td>
 | 
				
			||||||
 | 
					          </ng-container>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          <!-- Weight Column -->
 | 
				
			||||||
 | 
					          <ng-container matColumnDef="link">
 | 
				
			||||||
 | 
					            <th mat-header-cell *matHeaderCellDef> Link </th>
 | 
				
			||||||
 | 
					            <td mat-cell *matCellDef="let element"> {{element.link}} </td>
 | 
				
			||||||
 | 
					          </ng-container>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          <!-- Symbol Column -->
 | 
				
			||||||
 | 
					          <ng-container matColumnDef="shortLink">
 | 
				
			||||||
 | 
					            <th mat-header-cell *matHeaderCellDef> Short link </th>
 | 
				
			||||||
 | 
					            <td mat-cell *matCellDef="let element">
 | 
				
			||||||
 | 
					              <button mat-flat-button class="my-3" (click)="copyLink(element.id)">Copy short link</button>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					          </ng-container>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          <ng-container matColumnDef="actions">
 | 
				
			||||||
 | 
					            <th mat-header-cell *matHeaderCellDef> Actions </th>
 | 
				
			||||||
 | 
					            <td mat-cell *matCellDef="let element">
 | 
				
			||||||
 | 
					              <button mat-flat-button color="warn" (click)="deleteLink(element.id)">Delete</button>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					          </ng-container>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
 | 
				
			||||||
 | 
					          <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
 | 
				
			||||||
 | 
					        </table>
 | 
				
			||||||
 | 
					      </mat-card-content>
 | 
				
			||||||
 | 
					    </mat-card>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,21 +2,46 @@ import { Component } from '@angular/core';
 | 
				
			||||||
import { LinkService } from '../service/link.service';
 | 
					import { LinkService } from '../service/link.service';
 | 
				
			||||||
import { RecordModel } from 'pocketbase';
 | 
					import { RecordModel } from 'pocketbase';
 | 
				
			||||||
import { NavbarComponent } from '../navbar/navbar.component';
 | 
					import { NavbarComponent } from '../navbar/navbar.component';
 | 
				
			||||||
 | 
					import { Router, RouterLink } from '@angular/router';
 | 
				
			||||||
 | 
					import { MatRow, MatTableModule } from '@angular/material/table';
 | 
				
			||||||
 | 
					import { MatCardModule } from '@angular/material/card';
 | 
				
			||||||
 | 
					import { Link } from '../models/link';
 | 
				
			||||||
 | 
					import { MatButtonModule } from '@angular/material/button';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Component({
 | 
					@Component({
 | 
				
			||||||
  selector: 'app-dashboard',
 | 
					  selector: 'app-dashboard',
 | 
				
			||||||
  imports: [NavbarComponent],
 | 
					  imports: [NavbarComponent, MatTableModule, MatCardModule, MatButtonModule],
 | 
				
			||||||
  templateUrl: './dashboard.component.html',
 | 
					  templateUrl: './dashboard.component.html',
 | 
				
			||||||
  styleUrl: './dashboard.component.css'
 | 
					  styleUrl: './dashboard.component.css'
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
export class DashboardComponent {
 | 
					export class DashboardComponent {
 | 
				
			||||||
  public links: any[] = [];
 | 
					  public links: Link[] = [];
 | 
				
			||||||
 | 
					  displayedColumns: string[] = ['id', 'name', 'link', 'shortLink', 'actions'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(private linkService: LinkService) { };
 | 
					  constructor(private linkService: LinkService, private router: Router) { };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  copyLink(id: string) {
 | 
				
			||||||
 | 
					    navigator.clipboard.writeText(this.getShortLink(id));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  getShortLink(id: string): string {
 | 
				
			||||||
 | 
					    return window.location.hostname + '/' + id;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ngOnInit(): void {
 | 
					  ngOnInit(): void {
 | 
				
			||||||
    this.linkService.getLinks().then(links => {
 | 
					    this.linkService.getLinks().then(links => {
 | 
				
			||||||
      this.links = links;
 | 
					      this.links = links;
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  createLink() {
 | 
				
			||||||
 | 
					    this.router.navigate(['create-link']);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  deleteLink(id: string) {
 | 
				
			||||||
 | 
					    this.linkService.deleteLink(id); // TODO Check if something went wrong
 | 
				
			||||||
 | 
					    this.links = this.links.filter(link => {
 | 
				
			||||||
 | 
					      return link.id != id;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										6
									
								
								src/app/models/link.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/app/models/link.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,6 @@
 | 
				
			||||||
 | 
					export interface Link {
 | 
				
			||||||
 | 
					  id: string;
 | 
				
			||||||
 | 
					  link: string;
 | 
				
			||||||
 | 
					  name: string;
 | 
				
			||||||
 | 
					  owner: string;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,52 +0,0 @@
 | 
				
			||||||
<div class="navbar bg-base-100 rounded-2xl shadow-xl my-3 z-100">
 | 
					 | 
				
			||||||
  <div class="navbar-start">
 | 
					 | 
				
			||||||
    <div class="dropdown">
 | 
					 | 
				
			||||||
      <div tabindex="0" role="button" class="btn btn-ghost lg:hidden">
 | 
					 | 
				
			||||||
        <svg
 | 
					 | 
				
			||||||
          xmlns="http://www.w3.org/2000/svg"
 | 
					 | 
				
			||||||
          class="h-5 w-5"
 | 
					 | 
				
			||||||
          fill="none"
 | 
					 | 
				
			||||||
          viewBox="0 0 24 24"
 | 
					 | 
				
			||||||
          stroke="currentColor">
 | 
					 | 
				
			||||||
          <path
 | 
					 | 
				
			||||||
            stroke-linecap="round"
 | 
					 | 
				
			||||||
            stroke-linejoin="round"
 | 
					 | 
				
			||||||
            stroke-width="2"
 | 
					 | 
				
			||||||
            d="M4 6h16M4 12h8m-8 6h16" />
 | 
					 | 
				
			||||||
        </svg>
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
      <ul
 | 
					 | 
				
			||||||
        tabindex="0"
 | 
					 | 
				
			||||||
        class="menu menu-sm dropdown-content bg-base-100 rounded-box z-[10000] mt-3 w-52 p-2 shadow">
 | 
					 | 
				
			||||||
        <li><a>Dashboard</a></li>
 | 
					 | 
				
			||||||
        <li>
 | 
					 | 
				
			||||||
          <a>Parent</a>
 | 
					 | 
				
			||||||
          <ul class="p-2">
 | 
					 | 
				
			||||||
            <li><a>Submenu 1</a></li>
 | 
					 | 
				
			||||||
            <li><a>Submenu 2</a></li>
 | 
					 | 
				
			||||||
          </ul>
 | 
					 | 
				
			||||||
        </li>
 | 
					 | 
				
			||||||
        <li><a>Item 3</a></li>
 | 
					 | 
				
			||||||
      </ul>
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
    <a class="btn btn-ghost text-xl">jklink</a>
 | 
					 | 
				
			||||||
  </div>
 | 
					 | 
				
			||||||
  <div class="navbar-center hidden lg:flex">
 | 
					 | 
				
			||||||
    <ul class="menu menu-horizontal px-1">
 | 
					 | 
				
			||||||
      <li><a>Item 1</a></li>
 | 
					 | 
				
			||||||
      <li>
 | 
					 | 
				
			||||||
        <details>
 | 
					 | 
				
			||||||
          <summary>Parent</summary>
 | 
					 | 
				
			||||||
          <ul class="p-2">
 | 
					 | 
				
			||||||
            <li><a>Submenu 1</a></li>
 | 
					 | 
				
			||||||
            <li><a>Submenu 2</a></li>
 | 
					 | 
				
			||||||
          </ul>
 | 
					 | 
				
			||||||
        </details>
 | 
					 | 
				
			||||||
      </li>
 | 
					 | 
				
			||||||
      <li><a>Item 3</a></li>
 | 
					 | 
				
			||||||
    </ul>
 | 
					 | 
				
			||||||
  </div>
 | 
					 | 
				
			||||||
  <div class="navbar-end">
 | 
					 | 
				
			||||||
    <a class="btn">Button</a>
 | 
					 | 
				
			||||||
  </div>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,7 @@
 | 
				
			||||||
import { Injectable } from "@angular/core";
 | 
					import { Injectable } from "@angular/core";
 | 
				
			||||||
import { environment } from "../../environments/environment";
 | 
					import { environment } from "../../environments/environment";
 | 
				
			||||||
import PocketBase, { RecordModel } from 'pocketbase';
 | 
					import PocketBase, { RecordModel } from 'pocketbase';
 | 
				
			||||||
 | 
					import { Link } from "../models/link";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Injectable({
 | 
					@Injectable({
 | 
				
			||||||
| 
						 | 
					@ -9,7 +10,23 @@ import PocketBase, { RecordModel } from 'pocketbase';
 | 
				
			||||||
export class LinkService {
 | 
					export class LinkService {
 | 
				
			||||||
  private pb = new PocketBase(environment.POCKETBASE);
 | 
					  private pb = new PocketBase(environment.POCKETBASE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getLinks(): Promise<RecordModel[]> {
 | 
					  getLinks(): Promise<Link[]> {
 | 
				
			||||||
    return this.pb.collection('links').getFullList();
 | 
					    return this.pb.collection<Link>('links').getFullList<Link>();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  getLink(id: string): Promise<Link> {
 | 
				
			||||||
 | 
					    return this.pb.collection('links').getOne<Link>(id);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  deleteLink(id: string) {
 | 
				
			||||||
 | 
					    this.pb.collection('links').delete(id);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  createLink(link: any): Promise<RecordModel> {
 | 
				
			||||||
 | 
					    return this.pb.collection('links').create({
 | 
				
			||||||
 | 
					      'name': link.name,
 | 
				
			||||||
 | 
					      'link': link.link,
 | 
				
			||||||
 | 
					      'owner': this.pb.authStore.record?.id,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										0
									
								
								src/app/view-link/view-link.component.css
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								src/app/view-link/view-link.component.css
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										3
									
								
								src/app/view-link/view-link.component.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/app/view-link/view-link.component.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,3 @@
 | 
				
			||||||
 | 
					<p>Your are being redirected.</p>
 | 
				
			||||||
 | 
					<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-5944102294748899"
 | 
				
			||||||
 | 
					  crossorigin="anonymous"></script>
 | 
				
			||||||
							
								
								
									
										23
									
								
								src/app/view-link/view-link.component.spec.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/app/view-link/view-link.component.spec.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,23 @@
 | 
				
			||||||
 | 
					import { ComponentFixture, TestBed } from '@angular/core/testing';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { ViewLinkComponent } from './view-link.component';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					describe('ViewLinkComponent', () => {
 | 
				
			||||||
 | 
					  let component: ViewLinkComponent;
 | 
				
			||||||
 | 
					  let fixture: ComponentFixture<ViewLinkComponent>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  beforeEach(async () => {
 | 
				
			||||||
 | 
					    await TestBed.configureTestingModule({
 | 
				
			||||||
 | 
					      imports: [ViewLinkComponent]
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    .compileComponents();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fixture = TestBed.createComponent(ViewLinkComponent);
 | 
				
			||||||
 | 
					    component = fixture.componentInstance;
 | 
				
			||||||
 | 
					    fixture.detectChanges();
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('should create', () => {
 | 
				
			||||||
 | 
					    expect(component).toBeTruthy();
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
							
								
								
									
										19
									
								
								src/app/view-link/view-link.component.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/app/view-link/view-link.component.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,19 @@
 | 
				
			||||||
 | 
					import { Component } from '@angular/core';
 | 
				
			||||||
 | 
					import { LinkService } from '../service/link.service';
 | 
				
			||||||
 | 
					import { ActivatedRoute, Router } from '@angular/router';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Component({
 | 
				
			||||||
 | 
					  selector: 'app-view-link',
 | 
				
			||||||
 | 
					  imports: [],
 | 
				
			||||||
 | 
					  templateUrl: './view-link.component.html',
 | 
				
			||||||
 | 
					  styleUrl: './view-link.component.css'
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					export class ViewLinkComponent {
 | 
				
			||||||
 | 
					  constructor(private linkService: LinkService, private route: ActivatedRoute, private router: Router) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ngOnInit(): void {
 | 
				
			||||||
 | 
					    this.linkService.getLink(this.route.snapshot.params['link']).then(link => {
 | 
				
			||||||
 | 
					      window.location.href = link.link;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,3 +1,3 @@
 | 
				
			||||||
export const environment = {
 | 
					export const environment = {
 | 
				
			||||||
  POCKETBASE: 'http://pocketbase-yocs0oko0o8cws44kw8gk8g8.192.168.178.105.sslip.io/'
 | 
					  POCKETBASE: 'https://jklink-pocketbase-test.intern.kjan.de'
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,3 +1,3 @@
 | 
				
			||||||
export const environment = {
 | 
					export const environment = {
 | 
				
			||||||
  POCKETBASE: 'http://pocketbase-yocs0oko0o8cws44kw8gk8g8.192.168.178.105.sslip.io/'
 | 
					  POCKETBASE: 'https://jklink-pocketbase-test.intern.kjan.de'
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,8 +6,10 @@
 | 
				
			||||||
  <base href="/">
 | 
					  <base href="/">
 | 
				
			||||||
  <meta name="viewport" content="width=device-width, initial-scale=1">
 | 
					  <meta name="viewport" content="width=device-width, initial-scale=1">
 | 
				
			||||||
  <link rel="icon" type="image/x-icon" href="favicon.ico">
 | 
					  <link rel="icon" type="image/x-icon" href="favicon.ico">
 | 
				
			||||||
 | 
					  <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
 | 
				
			||||||
 | 
					  <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
 | 
				
			||||||
</head>
 | 
					</head>
 | 
				
			||||||
<body class="h-full base-100" >
 | 
					<body class="h-full base-100 mat-typography" >
 | 
				
			||||||
  <app-root></app-root>
 | 
					  <app-root></app-root>
 | 
				
			||||||
</body>
 | 
					</body>
 | 
				
			||||||
</html>
 | 
					</html>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,3 +0,0 @@
 | 
				
			||||||
@tailwind base;
 | 
					 | 
				
			||||||
@tailwind components;
 | 
					 | 
				
			||||||
@tailwind utilities;
 | 
					 | 
				
			||||||
							
								
								
									
										22
									
								
								src/styles.scss
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/styles.scss
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,22 @@
 | 
				
			||||||
 | 
					@use '@angular/material' as mat;
 | 
				
			||||||
 | 
					@tailwind base;
 | 
				
			||||||
 | 
					@tailwind components;
 | 
				
			||||||
 | 
					@tailwind utilities;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$theme: mat.define-theme();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					html {
 | 
				
			||||||
 | 
					  @include mat.all-component-themes($theme);
 | 
				
			||||||
 | 
					  // This line allows you to use color="..." for your toolbar.
 | 
				
			||||||
 | 
					  @include mat.color-variants-backwards-compatibility($theme);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					html,
 | 
				
			||||||
 | 
					body {
 | 
				
			||||||
 | 
					  height: 100%;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					body {
 | 
				
			||||||
 | 
					  margin: 0;
 | 
				
			||||||
 | 
					  font-family: Roboto, "Helvetica Neue", sans-serif;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -6,14 +6,9 @@ module.exports = {
 | 
				
			||||||
  theme: {
 | 
					  theme: {
 | 
				
			||||||
    extend: {},
 | 
					    extend: {},
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  daisyui: {
 | 
					  corePlugins: {
 | 
				
			||||||
    styled: true,
 | 
					    preflight: false,
 | 
				
			||||||
    themes: true,
 | 
					 | 
				
			||||||
    base: true,
 | 
					 | 
				
			||||||
    utils: true,
 | 
					 | 
				
			||||||
    logs: true,
 | 
					 | 
				
			||||||
    rtl: false
 | 
					 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  plugins: [require("@tailwindcss/typography"), require("daisyui")],
 | 
					  plugins: [],
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue