From b5a8e8aaac21eb8816c2adb433e297931d4ba6b9 Mon Sep 17 00:00:00 2001 From: mmeau Date: Wed, 3 Jan 2024 10:05:48 +0100 Subject: [PATCH] Feature: add todo widget --- docs/widgets/services/todo.md | 13 +++++ mkdocs.yml | 1 + src/widgets/components.js | 1 + src/widgets/todo/component.jsx | 96 ++++++++++++++++++++++++++++++++++ src/widgets/todo/widget.js | 10 ++++ src/widgets/widgets.js | 2 + 6 files changed, 123 insertions(+) create mode 100644 docs/widgets/services/todo.md create mode 100644 src/widgets/todo/component.jsx create mode 100644 src/widgets/todo/widget.js diff --git a/docs/widgets/services/todo.md b/docs/widgets/services/todo.md new file mode 100644 index 00000000..0781344d --- /dev/null +++ b/docs/widgets/services/todo.md @@ -0,0 +1,13 @@ +--- +title: Todo +description: Todo Widget Configuration +--- + +The Todo widget provides a simple to-do list functionality. +It allows users to add, remove, and mark tasks as completed. +The component utilizes local storage to persist the to-do list data even when the user refreshes the page. + +```yaml +widget: + type: todo +``` diff --git a/mkdocs.yml b/mkdocs.yml index 77f55dde..dfaaaf66 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -122,6 +122,7 @@ nav: - widgets/services/syncthing-relay-server.md - widgets/services/tailscale.md - widgets/services/tdarr.md + - widgets/services/todo.md - widgets/services/traefik.md - widgets/services/transmission.md - widgets/services/truenas.md diff --git a/src/widgets/components.js b/src/widgets/components.js index 4209b69a..bf7aecd8 100644 --- a/src/widgets/components.js +++ b/src/widgets/components.js @@ -96,6 +96,7 @@ const components = { tautulli: dynamic(() => import("./tautulli/component")), tdarr: dynamic(() => import("./tdarr/component")), traefik: dynamic(() => import("./traefik/component")), + todo: dynamic(() => import("./todo/component")), transmission: dynamic(() => import("./transmission/component")), tubearchivist: dynamic(() => import("./tubearchivist/component")), truenas: dynamic(() => import("./truenas/component")), diff --git a/src/widgets/todo/component.jsx b/src/widgets/todo/component.jsx new file mode 100644 index 00000000..b121ddba --- /dev/null +++ b/src/widgets/todo/component.jsx @@ -0,0 +1,96 @@ +("use client"); + +import { MdOutlineDelete } from "react-icons/md"; +import { useEffect, useState } from "react"; +import classNames from "classnames"; + +import Container from "components/services/widget/container"; + +export default function Component({ service }) { + const [todos, setTodos] = useState([]); + const [inputValue, setInputValue] = useState(""); + + function handleChange(e) { + setInputValue(e.target.value); + } + + useEffect(() => { + const localStorageTodos = localStorage.getItem("todos"); + + const parsedTodos = localStorageTodos !== null ? JSON.parse(localStorageTodos) : []; + + setTodos(parsedTodos); + }, []); + + useEffect(() => { + if (todos.length === 0) return; + localStorage.setItem("todos", JSON.stringify(todos)); + }, [todos]); + + function handleSubmit(e) { + e.preventDefault(); + + if (inputValue.trim() === "") { + return; + } + + setTodos([...todos, inputValue]); + setInputValue(""); + } + + const handleDelete = (index) => { + const newTodos = [...todos]; + newTodos.splice(index, 1); + setTodos(newTodos); + + if (newTodos.length === 0) { + localStorage.removeItem("todos"); + } else { + localStorage.setItem("todos", JSON.stringify(newTodos)); + } + }; + + return ( + +
+ {todos.map((todo, index) => ( +
+ + + +
+ ))} +
+ + +
+
+
+ ); +} diff --git a/src/widgets/todo/widget.js b/src/widgets/todo/widget.js new file mode 100644 index 00000000..0de25333 --- /dev/null +++ b/src/widgets/todo/widget.js @@ -0,0 +1,10 @@ +const widget = { + mappings: { + "todo/latest": { + endpoint: "todo/latest", + validate: ["data"], + }, + }, +}; + +export default widget; diff --git a/src/widgets/widgets.js b/src/widgets/widgets.js index 904bd701..6a5b64ab 100644 --- a/src/widgets/widgets.js +++ b/src/widgets/widgets.js @@ -88,6 +88,7 @@ import strelaysrv from "./strelaysrv/widget"; import tailscale from "./tailscale/widget"; import tautulli from "./tautulli/widget"; import tdarr from "./tdarr/widget"; +import todo from "./todo/widget"; import traefik from "./traefik/widget"; import transmission from "./transmission/widget"; import tubearchivist from "./tubearchivist/widget"; @@ -193,6 +194,7 @@ const widgets = { tailscale, tautulli, tdarr, + todo, traefik, transmission, tubearchivist,