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
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 Lucàs Vabre
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+1 -1
View File
@@ -23,7 +23,7 @@
"src/assets"
],
"styles": [
"node_modules/bulma/bulma.sass",
"node_modules/daisyui/dist/full.css",
"src/styles.css"
],
"scripts": []
+607 -162
View File
File diff suppressed because it is too large Load Diff
+4 -1
View File
@@ -18,7 +18,7 @@
"@angular/platform-browser": "^14.1.0",
"@angular/platform-browser-dynamic": "^14.1.0",
"@angular/router": "^14.1.0",
"bulma": "^0.9.4",
"daisyui": "^2.24.0",
"rxjs": "~7.5.0",
"tslib": "^2.3.0",
"zone.js": "~0.11.4"
@@ -28,12 +28,15 @@
"@angular/cli": "~14.1.2",
"@angular/compiler-cli": "^14.1.0",
"@types/jasmine": "~4.0.0",
"autoprefixer": "^10.4.8",
"jasmine-core": "~4.2.0",
"karma": "~6.4.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage": "~2.2.0",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.0.0",
"postcss": "^8.4.16",
"tailwindcss": "^3.1.8",
"typescript": "~4.7.2"
}
}
+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
}
}
+3 -1
View File
@@ -1 +1,3 @@
/* You can add global styles to this file, and also import other style files */
@tailwind base;
@tailwind components;
@tailwind utilities;
+10
View File
@@ -0,0 +1,10 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./src/**/*{html, ts}"
],
theme: {
extend: {},
},
plugins: [],
}