Skip to content

Commit

Permalink
'solution'
Browse files Browse the repository at this point in the history
  • Loading branch information
fochoa3pg committed Feb 21, 2025
1 parent 05df4af commit 8711925
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 26 deletions.
33 changes: 22 additions & 11 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 15 additions & 1 deletion src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,21 @@ const routes: Routes = [
{
path: '',
component: HomeComponent,
pathMatch: 'full'
pathMatch: 'full',
},
{
path:'pending',
component: HomeComponent,
data: {
completed: false
}
},
{
path:'completed',
component: HomeComponent,
data: {
completed: true
}
}
];

Expand Down
6 changes: 5 additions & 1 deletion src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HomeComponent } from './pages/home/home.component';
import { ReactiveFormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';

@NgModule({
declarations: [
Expand All @@ -12,7 +14,9 @@ import { HomeComponent } from './pages/home/home.component';
],
imports: [
BrowserModule,
AppRoutingModule
ReactiveFormsModule,
AppRoutingModule,
CommonModule
],
providers: [],
bootstrap: [AppComponent]
Expand Down
6 changes: 6 additions & 0 deletions src/app/models/todo-task.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export class TodoTask {
public id!: number;
public title!: string;
public completed!: boolean;
public edit!: boolean;
}
32 changes: 21 additions & 11 deletions src/app/pages/home/home.component.html
Original file line number Diff line number Diff line change
@@ -1,21 +1,31 @@
<section class="todoapp">
<header class="header">
<div class="container">
<div class="container" [formGroup]="form">
<h1>My Day</h1>
<p>All my tasks in one place</p>
<input
class="new-todo"
placeholder="Type new todo"
autofocus
formControlName="title"
type="text"
(keydown.enter)="addTask()"
/>
</div>
</header>
<div class="container todoapp-wrapper">
<!-- This section should be hidden by default and shown when there are todos -->
<section class="main">
<section class="main" *ngIf="canSeeActions()">
<ul class="todo-list">
<li class="completed">
<li [ngClass]="getMode(task)" *ngFor="let task of tasks">
<div class="view">
<input class="toggle" type="checkbox" [checked]="task.completed" (click)="onCheck($event, task)"/>
<label (dblclick)="editTask(task)">{{task.title}}</label>
<button class="destroy"></button>
</div>
<input #editField class="edit" [value]="task.title" (keydown.escape)="cancel(task)" (keydown.enter)="saveEdit(task, $event)"/>
</li>
<!-- <li class="completed">
<div class="view">
<input class="toggle" type="checkbox" checked />
<label>Learn JavaScript</label>
Expand All @@ -38,27 +48,27 @@ <h1>My Day</h1>
<button class="destroy"></button>
</div>
<input class="edit" value="Make dishes" />
</li>
</li> -->
</ul>
</section>
<!-- This footer should be hidden by default and shown when there are todos -->
<footer class="footer">
<footer class="footer" *ngIf="canSeeActions()">
<!-- This should be `0 items left` by default -->
<span class="todo-count"><strong>0</strong> item left</span>
<span class="todo-count"><strong>{{getPendingItems()}}</strong> item<ng-container *ngIf="getPendingItems() === 0 || getPendingItems() > 1">s</ng-container> left</span>
<!-- Remove this if you don't implement routing -->
<ul class="filters">
<ul class="filters" >
<li>
<a routerLink="/" class="selected">All</a>
<a routerLink="/" routerLinkActive="selected" [routerLinkActiveOptions]="{exact: true}">All</a>
</li>
<li>
<a routerLink="/pending">Pending</a>
<a routerLink="/pending" routerLinkActive="selected" [routerLinkActiveOptions]="{exact: true}">Pending</a>
</li>
<li>
<a routerLink="/completed">Completed</a>
<a routerLink="/completed" routerLinkActive="selected" [routerLinkActiveOptions]="{exact: true}">Completed</a>
</li>
</ul>
<!-- Hidden if no completed items are left ↓ -->
<button class="clear-completed">Clear completed</button>
<button class="clear-completed" (click)="clearCompleted()" *ngIf="canSeeCompletedAction()">Clear completed</button>
</footer>
</div>
</section>
108 changes: 106 additions & 2 deletions src/app/pages/home/home.component.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,118 @@
import { Component, OnInit } from '@angular/core';
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { ActivatedRoute, Route } from '@angular/router';

import { TodoTask } from 'src/app/models/todo-task.model';

@Component({
selector: 'app-home',
templateUrl: './home.component.html',
})
export class HomeComponent implements OnInit {

constructor() { }
public tasks: TodoTask[] = [];
public originalTasks: TodoTask[] = [];
public form!: FormGroup;
public filter: boolean | undefined;

@ViewChild("editField") editField!: ElementRef;

constructor(private route: ActivatedRoute) { }

ngOnInit(): void {

this.form = new FormGroup({
title: new FormControl()
});

const storedData = localStorage.getItem('mydayapp-angular');
this.tasks = !!storedData ? JSON.parse(storedData) : [];
this.originalTasks = [...this.tasks];
this.applyFilter();
}

public addTask(): void {
const task = this.form.controls['title'].value;
if (task && task.trim() !== "") {
this.tasks.push({ id: Math.floor(Math.random() * 100), title: task, completed: false, edit: false });
this.save();
this.form.controls['title'].patchValue(null);
}
}

public onCheck(event: Event, task: TodoTask): void {
const checked = (event.target as HTMLInputElement).checked;
task.completed = checked;
this.save();
}

public editTask(task: TodoTask): void {
task.edit = !task.edit;
this.editField.nativeElement.focus();
}

public cancel(task: TodoTask): void {
task.edit = false;
this.editField.nativeElement.value = task.title.trim();
}

public saveEdit(task: TodoTask, event: Event): void {
task.title = (event.target as HTMLInputElement).value.trim();
task.edit = false;
this.save();
}

public getPendingItems(): number {
return this.tasks.filter(x => !x.completed).length;
}

public canSeeCompletedAction(): boolean {
return this.tasks.some(x => x.completed);
}

public clearCompleted(): void {
this.tasks = this.tasks.filter(x => !x.completed);
this.originalTasks = this.originalTasks.filter(x => !x.completed);
this.save();
}

public canSeeActions(): boolean {
if (this.filter !== undefined) {
return true;
}
return this.tasks.length > 0;
}

public getMode(task: TodoTask): string {

if (task.completed)
return 'completed';
else if (task.edit)
return 'editing'
else
return '';
}

private save(): void {

this.tasks.forEach(o => {
let element = this.originalTasks.find(x => x.id === o.id);
if (element) {
element.completed = o.completed;
element.title = o.title;
} else {
this.originalTasks.push(o);
}
});
localStorage.setItem('mydayapp-angular', JSON.stringify(this.originalTasks));
this.applyFilter();
}

private applyFilter(): void {
this.filter = this.route.snapshot.data['completed'];
if (this.filter !== undefined) {
this.tasks = this.originalTasks.filter(x => x.completed === this.route.snapshot.data['completed']);
}
}

}
1 change: 1 addition & 0 deletions src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ body {
.todo-list li .destroy:hover,
.todo-list li .destroy:focus {
color: #c18585;
cursor: pointer;
}

.todo-list li .destroy:after {
Expand Down

0 comments on commit 8711925

Please sign in to comment.