From 4dbf1982ee0d786117aba300ae542921697b8cba Mon Sep 17 00:00:00 2001 From: Leon Ekelund Date: Tue, 13 Jan 2026 18:39:48 +0100 Subject: [PATCH 1/3] set up project basics --- index.html | 8 +++++++- package.json | 7 ++++++- src/App.jsx | 2 +- src/index.css | 10 ++++++++-- vite.config.js | 3 ++- 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/index.html b/index.html index f7ac4e42..73a32c0d 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,13 @@ - Todo + + + + Goyo Tasks
diff --git a/package.json b/package.json index caf62893..356299bd 100644 --- a/package.json +++ b/package.json @@ -10,18 +10,23 @@ "preview": "vite preview" }, "dependencies": { + "@tailwindcss/vite": "^4.1.18", "react": "^19.0.0", - "react-dom": "^19.0.0" + "react-dom": "^19.0.0", + "zustand": "^5.0.10" }, "devDependencies": { "@eslint/js": "^9.21.0", "@types/react": "^19.0.10", "@types/react-dom": "^19.0.4", "@vitejs/plugin-react": "^4.3.4", + "autoprefixer": "^10.4.23", "eslint": "^9.21.0", "eslint-plugin-react-hooks": "^5.1.0", "eslint-plugin-react-refresh": "^0.4.19", "globals": "^15.15.0", + "postcss": "^8.5.6", + "tailwindcss": "^4.1.18", "vite": "^6.2.0" } } diff --git a/src/App.jsx b/src/App.jsx index 54275400..53de88f3 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,5 +1,5 @@ export const App = () => { return ( -

React Boilerplate

+

GoyoTasks

) } diff --git a/src/index.css b/src/index.css index f7c0aef5..551933a0 100644 --- a/src/index.css +++ b/src/index.css @@ -1,3 +1,9 @@ -:root { - font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; +@import "tailwindcss"; + +@layer base { + html, body { + font-family: "DM Sans", system-ui, -apple-system, BlinkMacSystemFont, + "Segoe UI", sans-serif; + } } + diff --git a/vite.config.js b/vite.config.js index ba242447..d9e4dfd7 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,7 +1,8 @@ +import tailwindcss from '@tailwindcss/vite' import react from '@vitejs/plugin-react' import { defineConfig } from 'vite' // https://vitejs.dev/config/ export default defineConfig({ - plugins: [react()] + plugins: [tailwindcss(), react()] }) From 768b48d3ff3a28ed3563ea1a2e71247921f7887f Mon Sep 17 00:00:00 2001 From: Leon Ekelund Date: Sun, 18 Jan 2026 15:16:54 +0100 Subject: [PATCH 2/3] add logic and styling --- package.json | 1 + src/App.jsx | 23 ++++++++++++++--- src/assets/goyologo.svg | 3 +++ src/components/AddTodo.jsx | 35 +++++++++++++++++++++++++ src/components/EmptyState.jsx | 7 +++++ src/components/TaskCounter.jsx | 13 ++++++++++ src/components/TodoItem.jsx | 28 ++++++++++++++++++++ src/components/TodoList.jsx | 19 ++++++++++++++ src/components/store/useTodoStore.js | 38 ++++++++++++++++++++++++++++ src/index.css | 10 ++++++++ 10 files changed, 174 insertions(+), 3 deletions(-) create mode 100644 src/assets/goyologo.svg create mode 100644 src/components/AddTodo.jsx create mode 100644 src/components/EmptyState.jsx create mode 100644 src/components/TaskCounter.jsx create mode 100644 src/components/TodoItem.jsx create mode 100644 src/components/TodoList.jsx create mode 100644 src/components/store/useTodoStore.js diff --git a/package.json b/package.json index 356299bd..1bba4b60 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "@tailwindcss/vite": "^4.1.18", "react": "^19.0.0", "react-dom": "^19.0.0", + "react-icons": "^5.5.0", "zustand": "^5.0.10" }, "devDependencies": { diff --git a/src/App.jsx b/src/App.jsx index 53de88f3..30acc751 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,5 +1,22 @@ +import { AddTodo } from "./components/AddTodo"; +import { TaskCounter } from "./components/TaskCounter"; +import { TodoList } from "./components/TodoList"; + export const App = () => { return ( -

GoyoTasks

- ) -} +
+
+

+ Goyo Tasks 고요 +

+ +
+
+
+ + +
+
+
+ ); +}; diff --git a/src/assets/goyologo.svg b/src/assets/goyologo.svg new file mode 100644 index 00000000..96f400ee --- /dev/null +++ b/src/assets/goyologo.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/components/AddTodo.jsx b/src/components/AddTodo.jsx new file mode 100644 index 00000000..14aea840 --- /dev/null +++ b/src/components/AddTodo.jsx @@ -0,0 +1,35 @@ +import { useState } from "react"; +import useTodoStore from "./store/useTodoStore"; + +export const AddTodo = () => { + const [text, setText] = useState(""); + const addTask = useTodoStore((state) => state.addTask); + + const handleSubmit = (e) => { + e.preventDefault(); + addTask(text); + setText(""); + }; + + return ( +
+ setText(e.target.value)} + placeholder="Add a new task..." + className="flex-1 px-4 py-3 bg-white border border-border/50 rounded-lg text-text placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-primary/30 focus:border-primary shadow-sm transition-shadow" + /> + +
+ ); +}; diff --git a/src/components/EmptyState.jsx b/src/components/EmptyState.jsx new file mode 100644 index 00000000..2a9ece40 --- /dev/null +++ b/src/components/EmptyState.jsx @@ -0,0 +1,7 @@ +export const EmptyState = () => { + return ( +
+

No tasks yet. Add one above to get started.

+
+ ); +}; diff --git a/src/components/TaskCounter.jsx b/src/components/TaskCounter.jsx new file mode 100644 index 00000000..b1cff04a --- /dev/null +++ b/src/components/TaskCounter.jsx @@ -0,0 +1,13 @@ +import useTodoStore from "./store/useTodoStore"; + +export const TaskCounter = () => { + const tasks = useTodoStore((state) => state.tasks); + const completedCount = tasks.filter((task) => task.completed).length; + const totalCount = tasks.length; + + return ( +

+ {completedCount} of {totalCount} tasks completed +

+ ); +}; diff --git a/src/components/TodoItem.jsx b/src/components/TodoItem.jsx new file mode 100644 index 00000000..e0f418dc --- /dev/null +++ b/src/components/TodoItem.jsx @@ -0,0 +1,28 @@ +import { FiTrash2 } from "react-icons/fi"; +import useTodoStore from "./store/useTodoStore"; + +export const TodoItem = ({ task }) => { + const toggleTask = useTodoStore((state) => state.toggleTask); + const removeTask = useTodoStore((state) => state.removeTask); + + return ( +
  • + toggleTask(task.id)} + className="w-4 h-4 accent-primary" + /> + + {task.text} + + +
  • + ); +}; diff --git a/src/components/TodoList.jsx b/src/components/TodoList.jsx new file mode 100644 index 00000000..4faa9110 --- /dev/null +++ b/src/components/TodoList.jsx @@ -0,0 +1,19 @@ +import useTodoStore from "./store/useTodoStore"; +import { TodoItem } from "./TodoItem"; +import { EmptyState } from "./EmptyState"; + +export const TodoList = () => { + const tasks = useTodoStore((state) => state.tasks); + + if (tasks.length === 0) { + return ; + } + + return ( +
      + {tasks.map((task) => ( + + ))} +
    + ); +}; diff --git a/src/components/store/useTodoStore.js b/src/components/store/useTodoStore.js new file mode 100644 index 00000000..b038a95e --- /dev/null +++ b/src/components/store/useTodoStore.js @@ -0,0 +1,38 @@ +import { create } from "zustand"; + +const useTodoStore = create((set) => ({ + tasks: [], + + addTask: (text) => { + if (!text.trim()) return; + + set((state) => ({ + tasks: [ + { + id: Date.now(), + text, + completed: false, + }, + ...state.tasks, + ], + })); + }, + + toggleTask: (id) => { + set((state) => ({ + tasks: state.tasks.map((task) => + task.id === id + ? { ...task, completed: !task.completed } + : task + ), + })); + }, + + removeTask: (id) => { + set((state) => ({ + tasks: state.tasks.filter((task) => task.id !== id), + })); + }, +})); + +export default useTodoStore; diff --git a/src/index.css b/src/index.css index 551933a0..bc985a98 100644 --- a/src/index.css +++ b/src/index.css @@ -1,5 +1,15 @@ @import "tailwindcss"; +@theme { + --color-bg: #F8F7F4; + --color-surface: #F1F0EC; + --color-border: #DAD8D2; + --color-text: #1F2328; + --color-text-muted: #6B7075; + --color-primary: #4A5B6A; + --color-primarymuted: #E4E9ED; +} + @layer base { html, body { font-family: "DM Sans", system-ui, -apple-system, BlinkMacSystemFont, From 4c63f4abc08ada4a1454e4d510630213565af592 Mon Sep 17 00:00:00 2001 From: Leon Ekelund <102791497+LeonEkelund@users.noreply.github.com> Date: Sun, 18 Jan 2026 15:20:19 +0100 Subject: [PATCH 3/3] Update README with GoyoTasks description and demo link Added a brief description and live demo link for GoyoTasks. --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d1c68b57..9b152e82 100644 --- a/README.md +++ b/README.md @@ -1 +1,3 @@ -# Todo \ No newline at end of file +GoyoTasks is a clean, minimal, and easy-to-use web-based to-do app that helps you organize your tasks and boost productivity. + +Live Demo: https://goyotasks.netlify.app/