Merge branch 'dev'

This commit is contained in:
Lucàs
2023-06-17 13:27:18 +02:00
10 changed files with 47 additions and 19 deletions
+9
View File
@@ -8,6 +8,7 @@
"name": "todo-list", "name": "todo-list",
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"@heroicons/react": "^2.0.18",
"@reduxjs/toolkit": "^1.9.5", "@reduxjs/toolkit": "^1.9.5",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
@@ -462,6 +463,14 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
} }
}, },
"node_modules/@heroicons/react": {
"version": "2.0.18",
"resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.0.18.tgz",
"integrity": "sha512-7TyMjRrZZMBPa+/5Y8lN0iyvUU/01PeMGX2+RE7cQWpEUIcb4QotzUObFkJDejj/HUH4qjP/eQ0gzzKs2f+6Yw==",
"peerDependencies": {
"react": ">= 16"
}
},
"node_modules/@humanwhocodes/config-array": { "node_modules/@humanwhocodes/config-array": {
"version": "0.11.10", "version": "0.11.10",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz",
+2
View File
@@ -5,11 +5,13 @@
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"dev-host": "vite --host",
"build": "tsc && vite build", "build": "tsc && vite build",
"lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"@heroicons/react": "^2.0.18",
"@reduxjs/toolkit": "^1.9.5", "@reduxjs/toolkit": "^1.9.5",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
+1 -1
View File
@@ -5,7 +5,7 @@ import TodoCard from './components/todo/TodoCard.tsx';
export default function App() { export default function App() {
return ( return (
<div className={"w-screen min-h-screen bg-blue-50"}> <div className={"w-screen min-h-screen bg-base-300"}>
<Navbar/> <Navbar/>
<main className={"w-full min-h-screen flex justify-center items-center"}> <main className={"w-full min-h-screen flex justify-center items-center"}>
+2 -2
View File
@@ -1,8 +1,8 @@
export default function Footer() { export default function Footer() {
return ( return (
<footer className={"Footer footer w-screen fixed bottom-0 p-4"}> <footer className={"Footer footer w-screen absolute bottom-0 p-4"}>
<p className={"inline-block w-full text-center"}> <p className={"inline-block w-full text-center"}>
MIT Licence © 2023 <a className={"link"} href={"https://github.com/LucasVbr/todo-list"} target={"_blank"}>See code on GitHub</a> MIT Licence © 2023 <a className={"link link-hover"} href={"https://github.com/LucasVbr/todo-list"} target={"_blank"}>See code on GitHub</a>
</p> </p>
</footer> </footer>
) )
+9 -3
View File
@@ -1,7 +1,13 @@
import clsx from 'clsx';
export default function Navbar() { export default function Navbar() {
return ( return (
<div className={"Navbar navbar fixed top-0"}> <div className={clsx('Navbar',
<button className={"btn btn-ghost normal-case text-xl"}>Todo List App</button> 'navbar absolute top-0',
'flex justify-between')}>
<button className={'btn btn-ghost normal-case text-xl'}>
Todo List App
</button>
</div> </div>
) );
} }
+7 -7
View File
@@ -1,6 +1,7 @@
import {FormEvent, useState} from 'react'; import {FormEvent, useState} from 'react';
import {useDispatch} from 'react-redux'; import {useDispatch} from 'react-redux';
import {addTodo} from '../../features/todo/todoSlice.ts'; import {addTodo} from '../../features/todo/todoSlice.ts';
import {PlusIcon} from '@heroicons/react/24/outline';
export default function TodoAddItemForm() { export default function TodoAddItemForm() {
const [name, setName] = useState(''); const [name, setName] = useState('');
@@ -17,13 +18,12 @@ export default function TodoAddItemForm() {
<form onSubmit={handleSubmit} className={'TodoAddItemForm'}> <form onSubmit={handleSubmit} className={'TodoAddItemForm'}>
<div className={'form-control'}> <div className={'form-control'}>
<div className={'input-group'}> <div className={'input-group'}>
<input type={'text'} value={name} placeholder={'Type here your task...'} <input type={'text'} value={name}
className={'input input-bordered w-full'} placeholder={'Type here your task...'}
onChange={evt => setName(evt.target.value)} className={'input border-primary w-full'}
/> onChange={evt => setName(evt.target.value)}/>
<button type={'submit'} className={'btn btn-square'}> <button type={'submit'} className={'btn btn-square btn-primary'}>
<img className={'h-6 w-6'} src={'/icons/plus.svg'} <PlusIcon className={"h-6 w-6"}/>
alt="Plus icon"/>
</button> </button>
</div> </div>
</div> </div>
+3 -1
View File
@@ -3,12 +3,14 @@ import TodoAddItemForm from './TodoAddItemForm.tsx';
import TodoCardFooter from './TodoCardFooter.tsx'; import TodoCardFooter from './TodoCardFooter.tsx';
import {useSelector} from 'react-redux'; import {useSelector} from 'react-redux';
import {RootState} from '../../store.ts'; import {RootState} from '../../store.ts';
import clsx from 'clsx';
export default function TodoCard() { export default function TodoCard() {
const todos = useSelector((state: RootState) => state.todo); const todos = useSelector((state: RootState) => state.todo);
return ( return (
<div className={'TodoCard card bg-base-100 shadow-xl p-5 gap-7 transition ease-in-out delay-150'}> <div className={clsx('TodoCard',
'card max-w-6xl p-5 shadow-xl gap-7 bg-base-100')}>
<TodoAddItemForm/> <TodoAddItemForm/>
{todos.length > 0 && ( {todos.length > 0 && (
<> <>
+5 -1
View File
@@ -6,7 +6,11 @@ import TodoState from '../../models/TodoState.ts';
export default function TodoCardFooter() { export default function TodoCardFooter() {
const dispatch = useDispatch(); const dispatch = useDispatch();
const selectedTodosCount: number = useSelector((state: RootState) => state.todo.filter((todo: TodoState) => !todo.checked).length); const selectedTodosCount: number = useSelector(
(state: RootState) => state.todo.filter(
(todo: TodoState) => !todo.checked
).length
);
const handleDelete = () => dispatch(deleteSelectedTodos()); const handleDelete = () => dispatch(deleteSelectedTodos());
+7 -3
View File
@@ -13,9 +13,13 @@ export default function TodoItem({todo}: Props) {
const handleCheck = () => dispatch(checkTodo(todo.id)); const handleCheck = () => dispatch(checkTodo(todo.id));
return ( return (
<label className={clsx('TodoItem', 'shadow rounded-lg p-4 w-full flex items-center justify-between cursor-pointer')}> <label className={clsx('TodoItem',
{todo.name} 'w-full p-4 rounded-lg cursor-pointer',
<input type={"checkbox"} onChange={handleCheck} checked={todo.checked} className={"checkbox checkbox-primary"}/> 'border-[1px] border-base-300 shadow',
'flex items-center justify-between gap-5')}>
<span className={"break-all"}>{todo.name}</span>
<input type={'checkbox'} onChange={handleCheck} checked={todo.checked}
className={'checkbox checkbox-primary'}/>
</label> </label>
); );
} }
+2 -1
View File
@@ -1,5 +1,6 @@
import TodoItem from './TodoItem.tsx'; import TodoItem from './TodoItem.tsx';
import type TodoState from '../../models/TodoState.ts'; import type TodoState from '../../models/TodoState.ts';
import clsx from 'clsx';
type Props = { type Props = {
todos: TodoState[] todos: TodoState[]
@@ -7,7 +8,7 @@ type Props = {
export default function TodoItemList({todos}: Props) { export default function TodoItemList({todos}: Props) {
return ( return (
<div className={'TodoItemList w-full flex flex-col gap-2'}> <div className={clsx('TodoItemList', 'w-full flex flex-col gap-2')}>
{todos.map((todo: TodoState, index) => <TodoItem todo={todo} key={index}/>)} {todos.map((todo: TodoState, index) => <TodoItem todo={todo} key={index}/>)}
</div> </div>
); );