feat: add Angular Material and refactor UI components
This commit is contained in:
parent
00a7688ef9
commit
6317c97d96
15 changed files with 194 additions and 131 deletions
|
@ -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",
|
||||||
|
@ -41,4 +43,4 @@
|
||||||
"tailwindcss": "^3.4.17",
|
"tailwindcss": "^3.4.17",
|
||||||
"typescript": "~5.6.2"
|
"typescript": "~5.6.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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()]
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,29 +1,19 @@
|
||||||
<div class="h-full mx-auto container">
|
<div class="mx-auto container">
|
||||||
<app-navbar></app-navbar>
|
<app-navbar></app-navbar>
|
||||||
<div class="h-full overflow-x-auto pt-10">
|
<button mat-flat-button class="mt-3" color="warn" (click)="back()">Back</button>
|
||||||
|
<mat-card class="mt-3 p-3" appearance="outlined">
|
||||||
<div class="mx-auto card bg-base-100 w-96 shadow-xl">
|
<form class="flex flex-col" [formGroup]="createLinkForm">
|
||||||
<div class="card-body">
|
<mat-form-field appearance="outline">
|
||||||
<h2 class="card-title">Create link</h2>
|
<mat-error>{{errorMessages['name']}}</mat-error>
|
||||||
@if (requestFailed) {
|
<mat-label>Name</mat-label>
|
||||||
<div role="alert" class="alert alert-error">
|
<input formControlName="name" matInput placeholder="My Awesome link">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 shrink-0 stroke-current" fill="none"
|
</mat-form-field>
|
||||||
viewBox="0 0 24 24">
|
<mat-form-field appearance="outline">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
<mat-error>{{errorMessages['link']}}</mat-error>
|
||||||
d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
<mat-label>Link</mat-label>
|
||||||
</svg>
|
<input formControlName="link" matInput type="url" placeholder="https://kjan.de">
|
||||||
<span>Something went wrong</span>
|
</mat-form-field>
|
||||||
</div>
|
<button mat-flat-button type="submit" (click)="submit()">Create</button>
|
||||||
}
|
</form>
|
||||||
<form [formGroup]="createLinkForm">
|
</mat-card>
|
||||||
<input formControlName="name" type="text" placeholder="Name"
|
|
||||||
class="mb-3 input input-bordered w-full max-w-xs" />
|
|
||||||
<input formControlName="link" type="url" placeholder="Link" class="input input-bordered w-full max-w-xs" />
|
|
||||||
</form>
|
|
||||||
<div class="card-actions justify-end">
|
|
||||||
<button class="btn btn-primary" (click)="submit()">Create</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,29 +1,66 @@
|
||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { NavbarComponent } from '../navbar/navbar.component';
|
import { NavbarComponent } from '../navbar/navbar.component';
|
||||||
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
|
import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||||
import { LinkService } from '../service/link.service';
|
import { LinkService } from '../service/link.service';
|
||||||
import { Router } from '@angular/router';
|
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({
|
@Component({
|
||||||
selector: 'app-create-link',
|
selector: 'app-create-link',
|
||||||
imports: [NavbarComponent, ReactiveFormsModule],
|
imports: [NavbarComponent, ReactiveFormsModule, MatCardModule, MatFormFieldModule, MatInputModule, MatButtonModule],
|
||||||
templateUrl: './create-link.component.html',
|
templateUrl: './create-link.component.html',
|
||||||
styleUrl: './create-link.component.css'
|
styleUrl: './create-link.component.css'
|
||||||
})
|
})
|
||||||
export class CreateLinkComponent {
|
export class CreateLinkComponent {
|
||||||
public createLinkForm!: FormGroup;
|
public createLinkForm!: FormGroup;
|
||||||
public requestFailed: boolean = false;
|
public requestFailed: boolean = false;
|
||||||
|
public errorMessages: Record<string, string> = {};
|
||||||
|
|
||||||
constructor(private linkService: LinkService, private router: Router) { }
|
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 {
|
ngOnInit(): void {
|
||||||
this.createLinkForm = new FormGroup({
|
this.createLinkForm = new FormGroup({
|
||||||
name: new FormControl(''),
|
name: new FormControl('', Validators.required),
|
||||||
link: new FormControl(''),
|
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() {
|
submit() {
|
||||||
|
|
||||||
|
if (!this.createLinkForm.valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.requestFailed = false;
|
this.requestFailed = false;
|
||||||
this.linkService.createLink({
|
this.linkService.createLink({
|
||||||
name: this.createLinkForm.get('name')?.value,
|
name: this.createLinkForm.get('name')?.value,
|
||||||
|
|
|
@ -1,32 +1,50 @@
|
||||||
<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">
|
||||||
<button class="btn btn-primary" (click)="createLink()">Create new Link</button>
|
<button mat-flat-button color="secondary" class="my-3" (click)="createLink()">Create new Link</button>
|
||||||
<table class="table">
|
|
||||||
<!-- head -->
|
<mat-card appearance="outlined">
|
||||||
<thead>
|
<mat-card-content>
|
||||||
<tr>
|
<table mat-table [dataSource]="links" class="mat-elevation-z8">
|
||||||
<th></th>
|
|
||||||
<th>Name</th>
|
<!--- Note that these columns can be defined in any order.
|
||||||
<th>Url</th>
|
The actual rendered columns are set as a property on the row definition" -->
|
||||||
<th>Short Url</th>
|
|
||||||
<th>Actions</th>
|
<!-- Position Column -->
|
||||||
</tr>
|
<ng-container matColumnDef="id">
|
||||||
</thead>
|
<th mat-header-cell *matHeaderCellDef> ID </th>
|
||||||
<tbody>
|
<td mat-cell *matCellDef="let element"> {{element.id}} </td>
|
||||||
<!-- row 1 -->
|
</ng-container>
|
||||||
@for (link of links; track link) {
|
|
||||||
<tr class="bg-base-200">
|
<!-- Name Column -->
|
||||||
<th>{{link.id}}</th>
|
<ng-container matColumnDef="name">
|
||||||
<td>{{link.name}}</td>
|
<th mat-header-cell *matHeaderCellDef> Name </th>
|
||||||
<td><a href="{{link.link}}">{{link.link}}</a></td>
|
<td mat-cell *matCellDef="let element"> {{element.name}} </td>
|
||||||
<td>ndy</td>
|
</ng-container>
|
||||||
<td>
|
|
||||||
<button class="btn btn-error" (click)="deleteLink(link.id)">Delete</button>
|
<!-- Weight Column -->
|
||||||
</td>
|
<ng-container matColumnDef="link">
|
||||||
</tr>
|
<th mat-header-cell *matHeaderCellDef> Link </th>
|
||||||
}
|
<td mat-cell *matCellDef="let element"> {{element.link}} </td>
|
||||||
</tbody>
|
</ng-container>
|
||||||
</table>
|
|
||||||
|
<!-- Symbol Column -->
|
||||||
|
<ng-container matColumnDef="symbol">
|
||||||
|
<th mat-header-cell *matHeaderCellDef> Short Url </th>
|
||||||
|
<td mat-cell *matCellDef="let element"> ndy </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>
|
||||||
|
|
|
@ -3,15 +3,20 @@ 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 { 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', 'symbol', 'actions'];
|
||||||
|
|
||||||
constructor(private linkService: LinkService, private router: Router) { };
|
constructor(private linkService: LinkService, private router: Router) { };
|
||||||
|
|
||||||
|
|
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,8 +10,8 @@ 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>();
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteLink(id: string) {
|
deleteLink(id: string) {
|
||||||
|
|
|
@ -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
Reference in a new issue