From 5b17058e9312cf778b2992a48d5bf9d405232316 Mon Sep 17 00:00:00 2001 From: ketarubot Date: Thu, 31 Jul 2025 16:00:46 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat=20::=20todo=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=EB=B0=8F=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.css | 39 +++++------------------------- src/App.jsx | 68 +++++++++++++++++++++++++++++++++++++++++++++++----- src/List.css | 23 ++++++++++++++++++ 3 files changed, 91 insertions(+), 39 deletions(-) create mode 100644 src/List.css diff --git a/src/App.css b/src/App.css index b9d355d..38f5c2f 100644 --- a/src/App.css +++ b/src/App.css @@ -5,38 +5,11 @@ text-align: center; } -.logo { - height: 6em; - padding: 1.5em; - will-change: filter; - transition: filter 300ms; -} -.logo:hover { - filter: drop-shadow(0 0 2em #646cffaa); -} -.logo.react:hover { - filter: drop-shadow(0 0 2em #61dafbaa); +ul { + padding: 0; } -@keyframes logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} - -@media (prefers-reduced-motion: no-preference) { - a:nth-of-type(2) .logo { - animation: logo-spin infinite 20s linear; - } -} - -.card { - padding: 2em; -} - -.read-the-docs { - color: #888; -} +input { + display: inline-block; + margin: 10px; +} \ No newline at end of file diff --git a/src/App.jsx b/src/App.jsx index 5d62758..1f0cf1d 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,15 +1,71 @@ -import { useState } from "react"; -import reactLogo from "./assets/react.svg"; -import viteLogo from "/vite.svg"; +import { useState, useRef, useEffect } from "react"; import "./App.css"; +import "./List.css"; -function App() { +function List({ id, detail, onDelete }) { + return ( +
  • + {detail} + +
  • + ); +} + +function DisplayTodosState({ todos }) { const [count, setCount] = useState(0); - const name = "류승찬"; + + return ( +

    + [ ToDo의 개수: {todos.length}개, 완료한 Todo: {count}개 ] +

    + ) +} + +function manageLocalStorage() { + +} + +function App() { + const [todos, setTodos] = useState([]); + const inputRef = useRef(null); + const addTodos = () => { + const add = inputRef.current.value; + if (add) { + setTodos(prev => [...prev, + { id: Date.now(), context: add } + ]); + inputRef.current.value = ''; + } + }; + + const deleteTodos = (deleteId) => { + setTodos(prev => prev.filter(todo => todo.id !== deleteId)); + }; + useEffect(() => { + inputRef.current.focus(); + }, []); return ( <> - 화이팅 +

    To-Do List

    + + + + ); } diff --git a/src/List.css b/src/List.css new file mode 100644 index 0000000..1a22e90 --- /dev/null +++ b/src/List.css @@ -0,0 +1,23 @@ +.todo { + list-style: none; + margin: 10px; + background-color: lightgray; + padding: 30px; + border-radius: 20px; + width: 250px; + position: relative; + height: 30px; + line-height: 30px; +} + +.remove { + position: absolute; + height: 30px; + right: 15px; + background-color: red; + color: white; + padding: 0px 10px; + text-align: center; + line-height: 28px; + top: 30px; +} \ No newline at end of file From 4a7820b3a2c8893408c487a15364da90eb234fd8 Mon Sep 17 00:00:00 2001 From: ketarubot Date: Thu, 31 Jul 2025 16:39:39 +0900 Subject: [PATCH 2/3] =?UTF-8?q?feat=20::=20todo=20=EC=99=84=EB=A3=8C=20?= =?UTF-8?q?=ED=91=9C=EC=8B=9C,=20todoState=20=ED=91=9C=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.jsx | 50 +++++++++------------------- src/components/DisplayTodosState.jsx | 22 ++++++++++++ src/components/List.jsx | 17 ++++++++++ src/main.jsx | 2 +- src/{ => style}/App.css | 0 src/style/DisplayTodosState.css | 10 ++++++ src/{ => style}/List.css | 21 ++++++++++-- src/{ => style}/index.css | 0 8 files changed, 84 insertions(+), 38 deletions(-) create mode 100644 src/components/DisplayTodosState.jsx create mode 100644 src/components/List.jsx rename src/{ => style}/App.css (100%) create mode 100644 src/style/DisplayTodosState.css rename src/{ => style}/List.css (55%) rename src/{ => style}/index.css (100%) diff --git a/src/App.jsx b/src/App.jsx index 1f0cf1d..4e9b0e3 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,52 +1,34 @@ import { useState, useRef, useEffect } from "react"; -import "./App.css"; -import "./List.css"; - -function List({ id, detail, onDelete }) { - return ( -
  • - {detail} - -
  • - ); -} - -function DisplayTodosState({ todos }) { - const [count, setCount] = useState(0); - - return ( -

    - [ ToDo의 개수: {todos.length}개, 완료한 Todo: {count}개 ] -

    - ) -} - -function manageLocalStorage() { - -} +import "./style/App.css"; +import List from "./components/List"; +import DisplayTodosState from "./components/DisplayTodosState"; function App() { const [todos, setTodos] = useState([]); const inputRef = useRef(null); + const addTodos = () => { const add = inputRef.current.value; if (add) { setTodos(prev => [...prev, - { id: Date.now(), context: add } + { id: Date.now(), context: add, complete: false } ]); inputRef.current.value = ''; } }; - const deleteTodos = (deleteId) => { setTodos(prev => prev.filter(todo => todo.id !== deleteId)); }; + const setComplete = (setId) => { + setTodos(prev => + prev.map(todo => + todo.id === setId + ? { ...todo, complete: !todo.complete } + : todo + ) + ); + }; - useEffect(() => { - inputRef.current.focus(); - }, []); return ( <>

    To-Do List

    @@ -59,8 +41,8 @@ function App() { {todos.map(todo => )} diff --git a/src/components/DisplayTodosState.jsx b/src/components/DisplayTodosState.jsx new file mode 100644 index 0000000..823cb83 --- /dev/null +++ b/src/components/DisplayTodosState.jsx @@ -0,0 +1,22 @@ +import '../style/DisplayTodosState.css'; +import { useState, useEffect } from 'react'; + +function DisplayTodosState({ todos }) { + const [count, setCount] = useState(0); + + useEffect(() => { + setCount(0); + for (const todo of todos) { + if (todo.complete === true) setCount(count+1); + } + }, [todos]); + + return ( +

    + [ ToDo의 개수: {todos.length}개, + 완료한 Todo: {count}개 ] +

    + ) +} + +export default DisplayTodosState; \ No newline at end of file diff --git a/src/components/List.jsx b/src/components/List.jsx new file mode 100644 index 0000000..9b22594 --- /dev/null +++ b/src/components/List.jsx @@ -0,0 +1,17 @@ +import "../style/List.css"; + +function List({ todo, changeState, onDelete }) { + return ( +
  • + {todo.context} + + +
  • + ); +} + +export default List; \ No newline at end of file diff --git a/src/main.jsx b/src/main.jsx index b9a1a6d..b0944bb 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -1,6 +1,6 @@ import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' -import './index.css' +import './style/index.css' import App from './App.jsx' createRoot(document.getElementById('root')).render( diff --git a/src/App.css b/src/style/App.css similarity index 100% rename from src/App.css rename to src/style/App.css diff --git a/src/style/DisplayTodosState.css b/src/style/DisplayTodosState.css new file mode 100644 index 0000000..f29ccb5 --- /dev/null +++ b/src/style/DisplayTodosState.css @@ -0,0 +1,10 @@ +strong { + color: green; + font-weight: 600; +} + +p { + background-color: rgb(227, 242, 248); + padding: 5px; + border-radius: 15px; +} \ No newline at end of file diff --git a/src/List.css b/src/style/List.css similarity index 55% rename from src/List.css rename to src/style/List.css index 1a22e90..3a00f25 100644 --- a/src/List.css +++ b/src/style/List.css @@ -2,7 +2,7 @@ list-style: none; margin: 10px; background-color: lightgray; - padding: 30px; + padding: 20px; border-radius: 20px; width: 250px; position: relative; @@ -13,11 +13,26 @@ .remove { position: absolute; height: 30px; - right: 15px; + right: 10px; background-color: red; color: white; padding: 0px 10px; text-align: center; line-height: 28px; - top: 30px; + top: 35px; +} + +.complete { + position: absolute; + height: 30px; + right: 10px; + background-color: yellowgreen; + padding: 0px 10px; + text-align: center; + line-height: 28px; + top: 5px; +} + +.end { + background-color: gray !important; } \ No newline at end of file diff --git a/src/index.css b/src/style/index.css similarity index 100% rename from src/index.css rename to src/style/index.css From c0c537e9774c53adda5cbdb316f52e8b330a00d9 Mon Sep 17 00:00:00 2001 From: ketarubot Date: Thu, 31 Jul 2025 18:27:51 +0900 Subject: [PATCH 3/3] =?UTF-8?q?refactor=20::=20=ED=9A=A8=EC=9C=A8=EC=84=B1?= =?UTF-8?q?=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/DisplayTodosState.jsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/components/DisplayTodosState.jsx b/src/components/DisplayTodosState.jsx index 823cb83..19d6f92 100644 --- a/src/components/DisplayTodosState.jsx +++ b/src/components/DisplayTodosState.jsx @@ -4,11 +4,10 @@ import { useState, useEffect } from 'react'; function DisplayTodosState({ todos }) { const [count, setCount] = useState(0); + // 수정 코드(한번만 계산) useEffect(() => { - setCount(0); - for (const todo of todos) { - if (todo.complete === true) setCount(count+1); - } + const completedCount = todos.filter(todo => todo.complete).length; + setCount(completedCount); }, [todos]); return (