Merge pull request 'main' (#6) from main into prod
All checks were successful
Release / Release (push) Successful in 2m6s
All checks were successful
Release / Release (push) Successful in 2m6s
Reviewed-on: #6
This commit is contained in:
commit
5b8efc8921
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": [
|
||||
"src/styles.css"
|
||||
"@angular/material/prebuilt-themes/azure-blue.css",
|
||||
"src/styles.scss"
|
||||
],
|
||||
"scripts": []
|
||||
},
|
||||
|
@ -97,6 +98,7 @@
|
|||
}
|
||||
],
|
||||
"styles": [
|
||||
"@angular/material/prebuilt-themes/azure-blue.css",
|
||||
"src/styles.css"
|
||||
],
|
||||
"scripts": []
|
||||
|
|
41
package-lock.json
generated
41
package-lock.json
generated
|
@ -9,10 +9,12 @@
|
|||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@angular/animations": "^19.0.0",
|
||||
"@angular/cdk": "^19.1.0",
|
||||
"@angular/common": "^19.0.0",
|
||||
"@angular/compiler": "^19.0.0",
|
||||
"@angular/core": "^19.0.0",
|
||||
"@angular/forms": "^19.0.0",
|
||||
"@angular/material": "^19.1.0",
|
||||
"@angular/platform-browser": "^19.0.0",
|
||||
"@angular/platform-browser-dynamic": "^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": {
|
||||
"version": "19.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@angular/cli/-/cli-19.1.2.tgz",
|
||||
|
@ -517,6 +536,24 @@
|
|||
"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": {
|
||||
"version": "19.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-19.1.1.tgz",
|
||||
|
@ -6663,7 +6700,7 @@
|
|||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
||||
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"engines": {
|
||||
"node": ">=0.12"
|
||||
},
|
||||
|
@ -10387,7 +10424,7 @@
|
|||
"version": "7.2.1",
|
||||
"resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz",
|
||||
"integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"dependencies": {
|
||||
"entities": "^4.5.0"
|
||||
},
|
||||
|
|
|
@ -11,10 +11,12 @@
|
|||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "^19.0.0",
|
||||
"@angular/cdk": "^19.1.0",
|
||||
"@angular/common": "^19.0.0",
|
||||
"@angular/compiler": "^19.0.0",
|
||||
"@angular/core": "^19.0.0",
|
||||
"@angular/forms": "^19.0.0",
|
||||
"@angular/material": "^19.1.0",
|
||||
"@angular/platform-browser": "^19.0.0",
|
||||
"@angular/platform-browser-dynamic": "^19.0.0",
|
||||
"@angular/router": "^19.0.0",
|
||||
|
|
|
@ -2,7 +2,8 @@ import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
|
|||
import { provideRouter } from '@angular/router';
|
||||
|
||||
import { routes } from './app.routes';
|
||||
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
|
||||
|
||||
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 { DashboardComponent } from './dashboard/dashboard.component';
|
||||
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 = [
|
||||
{
|
||||
|
@ -13,6 +15,15 @@ export const routes: Routes = [
|
|||
component: DashboardComponent,
|
||||
canActivate: [AuthGuard],
|
||||
},
|
||||
{
|
||||
path: 'create-link',
|
||||
component: CreateLinkComponent,
|
||||
canActivate: [AuthGuard],
|
||||
},
|
||||
{
|
||||
path: ':link',
|
||||
component: ViewLinkComponent,
|
||||
},
|
||||
{
|
||||
path: "**",
|
||||
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">
|
||||
<app-navbar></app-navbar>
|
||||
<div class="overflow-x-auto">
|
||||
<table class="table">
|
||||
<!-- head -->
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Name</th>
|
||||
<th>Url</th>
|
||||
<th>Short Url</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- row 1 -->
|
||||
@for (link of links; track link) {
|
||||
<tr class="bg-base-200">
|
||||
<th>{{link.id}}</th>
|
||||
<td>{{link.name}}</td>
|
||||
<td><a href="{{link.link}}">{{link.link}}</a></td>
|
||||
<td>ndy</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
<button mat-flat-button color="secondary" class="my-3" (click)="createLink()">Create new Link</button>
|
||||
|
||||
<mat-card appearance="outlined">
|
||||
<mat-card-content>
|
||||
<table mat-table [dataSource]="links" class="mat-elevation-z8">
|
||||
|
||||
<!--- Note that these columns can be defined in any order.
|
||||
The actual rendered columns are set as a property on the row definition" -->
|
||||
|
||||
<!-- Position Column -->
|
||||
<ng-container matColumnDef="id">
|
||||
<th mat-header-cell *matHeaderCellDef> ID </th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<a href="{{element.id}}">
|
||||
{{element.id}}
|
||||
</a>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Name Column -->
|
||||
<ng-container matColumnDef="name">
|
||||
<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>
|
||||
|
|
|
@ -2,21 +2,46 @@ import { Component } from '@angular/core';
|
|||
import { LinkService } from '../service/link.service';
|
||||
import { RecordModel } from 'pocketbase';
|
||||
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({
|
||||
selector: 'app-dashboard',
|
||||
imports: [NavbarComponent],
|
||||
imports: [NavbarComponent, MatTableModule, MatCardModule, MatButtonModule],
|
||||
templateUrl: './dashboard.component.html',
|
||||
styleUrl: './dashboard.component.css'
|
||||
})
|
||||
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 {
|
||||
this.linkService.getLinks().then(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 { environment } from "../../environments/environment";
|
||||
import PocketBase, { RecordModel } from 'pocketbase';
|
||||
import { Link } from "../models/link";
|
||||
|
||||
|
||||
@Injectable({
|
||||
|
@ -9,7 +10,23 @@ import PocketBase, { RecordModel } from 'pocketbase';
|
|||
export class LinkService {
|
||||
private pb = new PocketBase(environment.POCKETBASE);
|
||||
|
||||
getLinks(): Promise<RecordModel[]> {
|
||||
return this.pb.collection('links').getFullList();
|
||||
getLinks(): Promise<Link[]> {
|
||||
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 = {
|
||||
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 = {
|
||||
POCKETBASE: 'http://pocketbase-yocs0oko0o8cws44kw8gk8g8.192.168.178.105.sslip.io/'
|
||||
POCKETBASE: 'https://jklink-pocketbase-test.intern.kjan.de'
|
||||
};
|
||||
|
|
|
@ -6,8 +6,10 @@
|
|||
<base href="/">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<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>
|
||||
<body class="h-full base-100" >
|
||||
<body class="h-full base-100 mat-typography" >
|
||||
<app-root></app-root>
|
||||
</body>
|
||||
</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: {
|
||||
extend: {},
|
||||
},
|
||||
daisyui: {
|
||||
styled: true,
|
||||
themes: true,
|
||||
base: true,
|
||||
utils: true,
|
||||
logs: true,
|
||||
rtl: false
|
||||
corePlugins: {
|
||||
preflight: false,
|
||||
},
|
||||
plugins: [require("@tailwindcss/typography"), require("daisyui")],
|
||||
plugins: [],
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue