Use TailWindCSS with DaisyUi instead of Bulma for styles

Add navbar and footer
Improve design of the List
Add MIT LICENCE
This commit is contained in:
Lucàs
2022-08-16 19:16:02 +02:00
parent 3c1e040c15
commit ba11981039
21 changed files with 879 additions and 242 deletions
+5 -25
View File
@@ -1,29 +1,9 @@
<div class="container">
<h1 class="title has-text-centered mt-5">{{ title }}</h1>
<div class="w-screen h-screen justify-between flex flex-col">
<app-navbar></app-navbar>
<div class="card">
<div class="card-content">
<table class="table is-striped is-narrow is-fullwidth">
<tr *ngFor="let todoItem of todoList">
<td>
<input class="checkbox is-primary" type="checkbox" (change)="saveList()"
[checked]="todoItem.completed" name="task-{{ todoItem.id }}"
id="task-{{ todoItem.id }}">
</td>
<td>
<label for="task-{{ todoItem.id }}">{{ todoItem.task }}</label>
</td>
<td>
<input class="button is-danger is-primary is-pulled-right" type="button"
value="remove" (click)="removeItem(todoItem.id)">
</td>
</tr>
</table>
<input class="input is-primary" type="text" [(ngModel)]="todoInput"
(keydown.enter)="addItem()">
</div>
<div class="container mx-auto">
<app-todolist class="mx-2"></app-todolist>
</div>
<app-footer></app-footer>
</div>
+2 -51
View File
@@ -1,57 +1,8 @@
import {Component, OnInit} from '@angular/core';
import TodoItem from '../models/TodoItem';
const LOCAL_STORAGE_KEY: string = "todoList";
import {Component} from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{
public title = 'Todo List App';
public todoInput!: string;
public todoList!: TodoItem[];
ngOnInit() {
this.todoInput = "";
this.todoList = this.getSavedList();
}
private getSavedList(): TodoItem[] {
console.info("Load TodoList");
const loadedValues: string|null = localStorage.getItem(LOCAL_STORAGE_KEY);
if (loadedValues) return JSON.parse(loadedValues) as TodoItem[];
return [];
}
public saveList() {
console.info("Save todoList");
localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(this.todoList))
}
public addItem(): void {
if (!this.todoInput) return;
const newItem: TodoItem = new TodoItem(this.getNextIndex(), this.todoInput);
this.todoList.push(newItem);
this.todoInput = "";
this.saveList();
}
public removeItem(index: number): void {
this.todoList = this.todoList.filter(item => {
return item.id !== index;
});
this.saveList();
}
private getNextIndex() {
if (this.todoList.length === 0) return 1;
return Math.max(...this.todoList.map(item => item.id)) + 1
}
}
export class AppComponent {}
+7 -1
View File
@@ -3,10 +3,16 @@ import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import {FormsModule} from '@angular/forms';
import { NavbarComponent } from './navbar/navbar.component';
import { FooterComponent } from './footer/footer.component';
import { TodolistComponent } from './todolist/todolist.component';
@NgModule({
declarations: [
AppComponent
AppComponent,
NavbarComponent,
FooterComponent,
TodolistComponent
],
imports: [
BrowserModule,
View File
+9
View File
@@ -0,0 +1,9 @@
<footer class="footer footer-center p-4 bg-base-300 text-base-content">
<div>
<p>MIT Licence © 2022 -
<a href="https://github.com/LucasVbr/todo-list" class="link link-hover"
target="_blank">See code on GitHub
</a>
</p>
</div>
</footer>
+23
View File
@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { FooterComponent } from './footer.component';
describe('FooterComponent', () => {
let component: FooterComponent;
let fixture: ComponentFixture<FooterComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ FooterComponent ]
})
.compileComponents();
fixture = TestBed.createComponent(FooterComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
+15
View File
@@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-footer',
templateUrl: './footer.component.html',
styleUrls: ['./footer.component.css']
})
export class FooterComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}
View File
+3
View File
@@ -0,0 +1,3 @@
<div class="navbar bg-base-100">
<a class="btn btn-ghost normal-case text-xl">Todo List App</a>
</div>
+23
View File
@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { NavbarComponent } from './navbar.component';
describe('NavbarComponent', () => {
let component: NavbarComponent;
let fixture: ComponentFixture<NavbarComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ NavbarComponent ]
})
.compileComponents();
fixture = TestBed.createComponent(NavbarComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
+15
View File
@@ -0,0 +1,15 @@
import {Component, OnInit} from '@angular/core';
@Component({
selector: 'app-navbar',
templateUrl: './navbar.component.html',
styleUrls: ['./navbar.component.css']
})
export class NavbarComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}
+50
View File
@@ -0,0 +1,50 @@
<div class="card m-auto w-96 bg-base-100 shadow-xl">
<div class="card-body">
<!-- Input-->
<div class="form-control">
<div class="input-group justify-center">
<input type="text" placeholder="Type here your task..."
class="input input-bordered w-full"
[(ngModel)]="todoInput" (keydown.enter)="addItem()"/>
<button class="btn btn-square" (click)="addItem()">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none"
viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round"
d="M12 4v16m8-8H4"/>
</svg>
</button>
</div>
</div>
<!-- List-->
<div class="form-control" *ngFor="let todoItem of todoList">
<label class="label cursor-pointer" for="task-{{ todoItem.id }}">
<input type="checkbox" checked="checked"
class="checkbox checkbox-primary"
id="task-{{ todoItem.id }}" name="task-{{ todoItem.id }}"
[(ngModel)]="todoItem.completed" (change)="saveList()"/>
<span class="label-text">{{ todoItem.task }}</span>
<button class="btn btn-error btn-square btn-outline"
(click)="removeItem(todoItem.id)">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none"
viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round"
stroke-width="2"
d="M6 18L18 6M6 6l12 12"/>
</svg>
</button>
</label>
</div>
<div class="card-actions justify-between">
You have {{ todoList.length }} pending task(s)
<button class="btn btn-error" (click)="clearList()">Clear All</button>
</div>
</div>
</div>
@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { TodolistComponent } from './todolist.component';
describe('TodolistComponent', () => {
let component: TodolistComponent;
let fixture: ComponentFixture<TodolistComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ TodolistComponent ]
})
.compileComponents();
fixture = TestBed.createComponent(TodolistComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
+58
View File
@@ -0,0 +1,58 @@
import { Component, OnInit } from '@angular/core';
import TodoItem from '../../models/TodoItem';
const LOCAL_STORAGE_KEY: string = "todoList";
@Component({
selector: 'app-todolist',
templateUrl: './todolist.component.html',
styleUrls: ['./todolist.component.css']
})
export class TodolistComponent implements OnInit {
public todoInput!: string;
public todoList!: TodoItem[];
ngOnInit() {
this.todoInput = "";
this.todoList = this.getSavedList();
}
public addItem(): void {
if (!this.todoInput) return;
const newItem: TodoItem = new TodoItem(this.getNextIndex(), this.todoInput);
this.todoList.push(newItem);
this.todoInput = "";
this.saveList();
}
public removeItem(index: number): void {
this.todoList = this.todoList.filter(item => {
return item.id !== index;
});
this.saveList();
}
public clearList(): void {
this.todoList = [];
this.saveList();
}
public saveList() {
console.info("Save todoList");
localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(this.todoList))
}
private getSavedList(): TodoItem[] {
console.info("Load TodoList");
const loadedValues: string|null = localStorage.getItem(LOCAL_STORAGE_KEY);
if (loadedValues) return JSON.parse(loadedValues) as TodoItem[];
return [];
}
private getNextIndex() {
if (this.todoList.length === 0) return 1;
return Math.max(...this.todoList.map(item => item.id)) + 1
}
}