From 73a5c7fae9ffbe9ada721148c8c454a643aceebe Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Sun, 20 Feb 2022 16:11:50 +0100 Subject: chore!: restructure repo I separated public files from the config/dev files. It improves repo readability. I also moved dotenv helper to public/inc directory and extract the Matomo tracker in the same directory. --- .../apps/todos/src/views/TodoList/TodoList.js | 84 ++++++++++++++++++++++ .../apps/todos/src/views/TodoList/TodoList.scss | 63 ++++++++++++++++ .../todos/src/views/TodoList/TodoListFilters.js | 47 ++++++++++++ .../apps/todos/src/views/TodoList/TodoListItem.js | 55 ++++++++++++++ 4 files changed, 249 insertions(+) create mode 100644 public/projects/react-small-apps/apps/todos/src/views/TodoList/TodoList.js create mode 100644 public/projects/react-small-apps/apps/todos/src/views/TodoList/TodoList.scss create mode 100644 public/projects/react-small-apps/apps/todos/src/views/TodoList/TodoListFilters.js create mode 100644 public/projects/react-small-apps/apps/todos/src/views/TodoList/TodoListItem.js (limited to 'public/projects/react-small-apps/apps/todos/src/views/TodoList') diff --git a/public/projects/react-small-apps/apps/todos/src/views/TodoList/TodoList.js b/public/projects/react-small-apps/apps/todos/src/views/TodoList/TodoList.js new file mode 100644 index 0000000..c671459 --- /dev/null +++ b/public/projects/react-small-apps/apps/todos/src/views/TodoList/TodoList.js @@ -0,0 +1,84 @@ +import { useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Button } from "../../components/forms"; +import TodoForm from "../TodoForm/TodoForm"; +import TodoListItem from "./TodoListItem"; +import "./TodoList.scss"; +import { deleteAllTodos } from "../../store/todos/todos.slice"; +import { LocalStorage } from "../../services/LocalStorage.service"; +import TodoListFilters from "./TodoListFilters"; + +function TodoList() { + const [todosList, setTodosList] = useState([]); + const [currentView, setCurrentView] = useState("all"); + const dispatch = useDispatch(); + const [isToggled, setIsToggled] = useState(false); + const currentUser = useSelector((state) => state.auth.currentUser); + const allTodos = useSelector((state) => state.todos); + + useEffect(() => { + const userTodos = allTodos.filter((todo) => todo.userId === currentUser.id); + + setTodosList(() => { + let list; + + switch (currentView) { + case "completed": + list = userTodos.filter((todo) => todo.done); + break; + case "ongoing": + list = userTodos.filter((todo) => !todo.done); + break; + default: + list = userTodos; + break; + } + + return list; + }); + }, [currentView, allTodos, currentUser.id]); + + useEffect(() => { + LocalStorage.set("todoList", allTodos); + }); + + const userTodosList = todosList.map((todo) => ( + + )); + + return ( +
+

Welcome back {currentUser.username}!

+
+ + +
+ {isToggled ? ( + + ) : ( + "" + )} + + {userTodosList.length > 0 ? ( +
    {userTodosList}
+ ) : ( + "" + )} +
+ ); +} + +export default TodoList; diff --git a/public/projects/react-small-apps/apps/todos/src/views/TodoList/TodoList.scss b/public/projects/react-small-apps/apps/todos/src/views/TodoList/TodoList.scss new file mode 100644 index 0000000..024fe3e --- /dev/null +++ b/public/projects/react-small-apps/apps/todos/src/views/TodoList/TodoList.scss @@ -0,0 +1,63 @@ +@use "../../sass/abstracts/placeholders"; +@use "../../sass/abstracts/variables" as var; + +.todos-actions { + display: flex; + gap: 1rem; +} + +.todos-filters { + display: flex; + flex-flow: row wrap; + align-items: center; + gap: clamp(0.2rem, 1vw, 0.5rem); + margin-top: 1rem +} + +.todos-list { + @extend %list-reset; + border: 1px solid #000; + margin-top: 1.5rem; + + &__item { + display: flex; + flex-flow: row wrap; + align-items: center; + gap: 1rem; + padding: 1rem; + + &:not(:first-child) { + border-top: 1px solid #000; + } + + .form__label { + margin: 0; + letter-spacing: 0; + text-transform: none; + } + + .todo__title { + background-image: linear-gradient( + to top, + transparent calc(50% - 3px), + var.$done-color calc(50% - 3px), + var.$done-color 50%, + transparent 50% + ); + background-size: 0 100%; + background-repeat: no-repeat; + margin-right: auto; + transition: background-size 0.3s ease-in-out 0s; + } + + &--done { + .todo__title { + background-size: 100% 100%; + } + } + + .btn { + padding: 0.4rem 0.7rem; + } + } +} diff --git a/public/projects/react-small-apps/apps/todos/src/views/TodoList/TodoListFilters.js b/public/projects/react-small-apps/apps/todos/src/views/TodoList/TodoListFilters.js new file mode 100644 index 0000000..338492a --- /dev/null +++ b/public/projects/react-small-apps/apps/todos/src/views/TodoList/TodoListFilters.js @@ -0,0 +1,47 @@ +import { Button } from "../../components/forms"; + +function TodoListFilters({ currentView, setCurrentView }) { + let allModifiers = ["filters"]; + let ongoingModifiers = ["filters"]; + let completedModifiers = ["filters"]; + + switch (currentView) { + case "all": + allModifiers.push("current"); + break; + case "ongoing": + ongoingModifiers.push("current"); + break; + case "completed": + completedModifiers.push("current"); + break; + default: + break; + } + + return ( +
+ Show: + + + +
+ ); +} + +export default TodoListFilters; diff --git a/public/projects/react-small-apps/apps/todos/src/views/TodoList/TodoListItem.js b/public/projects/react-small-apps/apps/todos/src/views/TodoList/TodoListItem.js new file mode 100644 index 0000000..f76c1a1 --- /dev/null +++ b/public/projects/react-small-apps/apps/todos/src/views/TodoList/TodoListItem.js @@ -0,0 +1,55 @@ +import { useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; +import { Link } from "react-router-dom"; +import { Button, Input } from "../../components/forms"; +import { deleteTodo, toggleTodo } from "../../store/todos/todos.slice"; +import { slugify } from "../../utilities/helpers"; + +function TodoListItem({ todo }) { + const { id, createdAt, title, done } = todo; + const [isChecked, setIsChecked] = useState(false); + const dispatch = useDispatch(); + + useEffect(() => { + if (done) setIsChecked(true); + }, [done]); + + const handleTodoDone = (checkboxState) => { + setIsChecked(checkboxState); + dispatch(toggleTodo(id)); + }; + + const todoSlug = slugify(title); + + const classNames = `todos-list__item ${ + isChecked ? "todos-list__item--done" : "" + }`; + + return ( +
  • + + {new Date(createdAt).toLocaleDateString()} + + + + {title} + + + + +
  • + ); +} + +export default TodoListItem; -- cgit v1.2.3