Loazing
This commit is contained in:
parent
17179b95f0
commit
587b979ff2
17 changed files with 208 additions and 58 deletions
|
|
@ -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)
|
||||
}
|
||||
];
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
18
src/app/component/tasks-page/tasks-page.component.css
Normal file
18
src/app/component/tasks-page/tasks-page.component.css
Normal 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;
|
||||
}
|
||||
25
src/app/component/tasks-page/tasks-page.component.html
Normal file
25
src/app/component/tasks-page/tasks-page.component.html
Normal 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>
|
||||
23
src/app/component/tasks-page/tasks-page.component.spec.ts
Normal file
23
src/app/component/tasks-page/tasks-page.component.spec.ts
Normal 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();
|
||||
});
|
||||
});
|
||||
58
src/app/component/tasks-page/tasks-page.component.ts
Normal file
58
src/app/component/tasks-page/tasks-page.component.ts
Normal 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);
|
||||
}
|
||||
}
|
||||
0
src/app/module/about/about.component.css
Normal file
0
src/app/module/about/about.component.css
Normal file
1
src/app/module/about/about.component.html
Normal file
1
src/app/module/about/about.component.html
Normal file
|
|
@ -0,0 +1 @@
|
|||
<p>about works!</p>
|
||||
23
src/app/module/about/about.component.spec.ts
Normal file
23
src/app/module/about/about.component.spec.ts
Normal 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();
|
||||
});
|
||||
});
|
||||
7
src/app/module/about/about.component.ts
Normal file
7
src/app/module/about/about.component.ts
Normal 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 },
|
||||
];
|
||||
0
src/app/module/task/task.component.css
Normal file
0
src/app/module/task/task.component.css
Normal file
1
src/app/module/task/task.component.html
Normal file
1
src/app/module/task/task.component.html
Normal file
|
|
@ -0,0 +1 @@
|
|||
<p>task works!</p>
|
||||
23
src/app/module/task/task.component.spec.ts
Normal file
23
src/app/module/task/task.component.spec.ts
Normal 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();
|
||||
});
|
||||
});
|
||||
7
src/app/module/task/task.component.ts
Normal file
7
src/app/module/task/task.component.ts
Normal 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 },
|
||||
];
|
||||
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue