This commit is contained in:
ExostFlash 2025-11-26 15:33:26 +01:00
parent 17179b95f0
commit 587b979ff2
17 changed files with 208 additions and 58 deletions

View file

@ -1,9 +1,17 @@
import { Routes } from '@angular/router';
import { HomeComponent } from './component/home/home.component';
import { AboutComponent } from './component/about/about.component';
export const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'home', component: HomeComponent },
{ path: 'about', component: AboutComponent }
{
path: 'tasks',
loadChildren: () => import('./module/task/task.component').then(m => m.TASKS_ROUTES)
},
{
path: 'about',
loadChildren: () => import('./module/about/about.component').then(m => m.ABOUT_ROUTES)
}
];

View file

@ -2,6 +2,7 @@
<nav>
<a routerLink="/" [class.active]="isHomeActive()">Home</a>
|
<a routerLink="/tasks" routerLinkActive="active">Tasks</a>
<a routerLink="/about" routerLinkActive="active">About</a>
</nav>
</header>

View file

@ -1,19 +1 @@
<h1>Home works!</h1>
<h2>Task List</h2>
@if (tasks$ | async; as tasks) {
<ul>
@for (task of tasks; track task) {
<li>
{{ task.title }}
</li>
}
</ul>
} @else {
<p>Loading tasks...</p>
}
<p>Elapsed time: <span style="font-family:monospace;font-size:1.2em">{{ elapsedClock }}</span></p>
<!-- Add a task -->
<button (click)="addTask('New Task')">+ Add a task</button>
<p>Home works!</p>

View file

@ -1,45 +1,13 @@
import { Component, inject } from '@angular/core';
import { CommonModule, AsyncPipe } from '@angular/common';
import { TaskService } from '../../service/task.service';
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-home',
imports: [CommonModule, AsyncPipe],
standalone: true,
imports: [CommonModule],
templateUrl: './home.component.html',
styleUrl: './home.component.css'
})
export class HomeComponent {
protected count = 0;
private intervalId: any;
public elapsedClock: string = '';
private taskService = inject(TaskService);
tasks$ = this.taskService.tasks$;
ngOnInit() {
this.updateElapsedClock();
this.intervalId = setInterval(() => {
this.count++;
this.updateElapsedClock();
}, 500);
}
ngOnDestroy() {
if (this.intervalId) {
clearInterval(this.intervalId);
}
}
private updateElapsedClock() {
const totalSeconds = Math.floor(this.count / 2);
const h = String(Math.floor(totalSeconds / 3600)).padStart(2, '0');
const m = String(Math.floor((totalSeconds % 3600) / 60)).padStart(2, '0');
const s = String(totalSeconds % 60).padStart(2, '0');
this.elapsedClock = `${h}:${m}:${s}`;
}
addTask(title: string) {
this.taskService.addTask(title);
}
}

View file

@ -0,0 +1,18 @@
.trash-btn {
background: none;
border: none;
cursor: pointer;
color: #c00;
font-size: 1.1em;
padding: 0.1em 0.3em;
border-radius: 4px;
transition: background 0.2s, color 0.2s;
}
.trash-btn:hover {
background: #ffeaea;
color: #fff;
}
.trash-btn:hover svg {
color: #fff;
fill: #fff;
}

View file

@ -0,0 +1,25 @@
<h1>tasks-page works!</h1>
<h2>Task List</h2>
@if (tasks$ | async; as tasks) {
<ul>
@for (task of tasks; track task) {
<li>
<span>{{ task.title }}</span>
<button class="trash-btn" (click)="removeTask(task.id)" title="Delete task">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="20" height="20" style="display:inline-block;vertical-align:middle;fill:currentColor;"><path d="M268 416h24a12 12 0 0 0 12-12V188a12 12 0 0 0-12-12h-24a12 12 0 0 0-12 12v216a12 12 0 0 0 12 12zM432 80h-82.41l-34-56.7A48 48 0 0 0 274.41 0H173.59a48 48 0 0 0-41.16 23.3L98.41 80H16A16 16 0 0 0 0 96v16a16 16 0 0 0 16 16h16v336a48 48 0 0 0 48 48h288a48 48 0 0 0 48-48V128h16a16 16 0 0 0 16-16V96a16 16 0 0 0-16-16zM171.84 50.91A6 6 0 0 1 177 48h94a6 6 0 0 1 5.15 2.91L293.61 80H154.39zM368 464H80V128h288zm-212-48h24a12 12 0 0 0 12-12V188a12 12 0 0 0-12-12h-24a12 12 0 0 0-12 12v216a12 12 0 0 0 12 12z"/></svg>
</button>
</li>
}
</ul>
} @else {
<p>Loading tasks...</p>
}
<p>Elapsed time: <span style="font-family:monospace;font-size:1.2em">{{ elapsedClock }}</span></p>
<!-- Add a task -->
<form (submit)="onAddTaskSubmit($event)" style="margin-top:1em;display:flex;gap:0.5em;align-items:center;">
<input type="text" name="taskTitle" placeholder="Task name" required style="padding:0.3em 0.7em;border-radius:4px;border:1px solid #ccc;min-width:120px;" />
<button type="submit">+ Add a task</button>
</form>

View file

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { TasksPageComponent } from './tasks-page.component';
describe('TasksPageComponent', () => {
let component: TasksPageComponent;
let fixture: ComponentFixture<TasksPageComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [TasksPageComponent]
})
.compileComponents();
fixture = TestBed.createComponent(TasksPageComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -0,0 +1,58 @@
import { Component, inject } from '@angular/core';
import { CommonModule, AsyncPipe } from '@angular/common';
import { TaskService } from '../../service/task.service';
@Component({
selector: 'app-tasks-page',
imports: [CommonModule, AsyncPipe],
templateUrl: './tasks-page.component.html',
styleUrl: './tasks-page.component.css',
})
export class TasksPageComponent {
protected count = 0;
private intervalId: any;
public elapsedClock: string = '';
private taskService = inject(TaskService);
tasks$ = this.taskService.tasks$;
ngOnInit() {
this.updateElapsedClock();
this.intervalId = setInterval(() => {
this.count++;
this.updateElapsedClock();
}, 500);
}
ngOnDestroy() {
if (this.intervalId) {
clearInterval(this.intervalId);
}
}
private updateElapsedClock() {
const totalSeconds = Math.floor(this.count / 2);
const h = String(Math.floor(totalSeconds / 3600)).padStart(2, '0');
const m = String(Math.floor((totalSeconds % 3600) / 60)).padStart(2, '0');
const s = String(totalSeconds % 60).padStart(2, '0');
this.elapsedClock = `${h}:${m}:${s}`;
}
removeTask(id: number) {
this.taskService.removeTask(id);
}
onAddTaskSubmit(event: SubmitEvent) {
event.preventDefault();
const form = event.target as HTMLFormElement;
const input = form.elements.namedItem('taskTitle') as HTMLInputElement | null;
if (input && input.value.trim()) {
this.addTask(input.value.trim());
form.reset();
}
}
addTask(title: string) {
this.taskService.addTask(title);
}
}

View file

View file

@ -0,0 +1 @@
<p>about works!</p>

View file

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AboutComponent } from './about.component';
describe('AboutComponent', () => {
let component: AboutComponent;
let fixture: ComponentFixture<AboutComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [AboutComponent]
})
.compileComponents();
fixture = TestBed.createComponent(AboutComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -0,0 +1,7 @@
import { Routes } from '@angular/router';
import { AboutComponent } from '../../component/about/about.component';
export const ABOUT_ROUTES: Routes = [
{ path: '', component: AboutComponent },
];

View file

View file

@ -0,0 +1 @@
<p>task works!</p>

View file

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { TaskComponent } from './task.component';
describe('TaskComponent', () => {
let component: TaskComponent;
let fixture: ComponentFixture<TaskComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [TaskComponent]
})
.compileComponents();
fixture = TestBed.createComponent(TaskComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -0,0 +1,7 @@
import { Routes } from '@angular/router';
import { TasksPageComponent } from '../../component/tasks-page/tasks-page.component';
export const TASKS_ROUTES: Routes = [
{ path: '', component: TasksPageComponent },
];

View file

@ -25,4 +25,9 @@ export class TaskService {
this.tasks.push(newTask);
this.tasksSubject.next([...this.tasks]);
}
removeTask(id: number) {
this.tasks = this.tasks.filter(task => task.id !== id);
this.tasksSubject.next([...this.tasks]);
}
}