From 2c2011659aa164d544b22dd3eaefa11eaa2cbd78 Mon Sep 17 00:00:00 2001 From: gahusb Date: Thu, 23 Apr 2026 14:46:51 +0900 Subject: [PATCH] =?UTF-8?q?feat(home):=20=EB=AA=A8=EB=B0=94=EC=9D=BC=20?= =?UTF-8?q?=EB=B0=98=EC=9D=91=ED=98=95=20=E2=80=94=20=EC=8A=A4=EC=99=80?= =?UTF-8?q?=EC=9D=B4=ED=94=84=20TODO=20+=20=ED=92=80=EB=8B=A4=EC=9A=B4=20?= =?UTF-8?q?=EB=A6=AC=ED=94=84=EB=A0=88=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- src/pages/home/Home.css | 22 +++++++-- src/pages/home/Home.jsx | 103 +++++++++++++++++++++++++++++++++++----- 2 files changed, 107 insertions(+), 18 deletions(-) diff --git a/src/pages/home/Home.css b/src/pages/home/Home.css index 40e1c5c..8880d32 100644 --- a/src/pages/home/Home.css +++ b/src/pages/home/Home.css @@ -803,15 +803,27 @@ .home-profile__name { font-size: 16px; } + + .home-hero__stats { + grid-template-columns: 1fr; + } + + .home-grid { + grid-template-columns: 1fr 1fr; + gap: 10px; + } + + .home-card { + min-height: 80px; + } + + .home-posts { + grid-template-columns: 1fr; + } } @media (max-width: 480px) { .home-grid { grid-template-columns: 1fr 1fr; } - - .home-hero__stats { - grid-template-columns: 1fr; - gap: 10px; - } } diff --git a/src/pages/home/Home.jsx b/src/pages/home/Home.jsx index 565e1b5..21f9bdf 100644 --- a/src/pages/home/Home.jsx +++ b/src/pages/home/Home.jsx @@ -1,10 +1,13 @@ -import React, { useEffect, useRef, useState } from 'react'; +import React, { useCallback, useEffect, useRef, useState } from 'react'; import { Link } from 'react-router-dom'; import { navLinks } from '../../routes.jsx'; import { getBlogPosts } from '../../data/blog'; import { getTodos } from '../../api'; import { getCurrentTheme } from '../../data/heroConfig'; import myPhoto from '../../assets/myPhoto.jpg'; +import { useIsMobile } from '../../hooks/useIsMobile'; +import SwipeableView from '../../components/SwipeableView'; +import PullToRefresh from '../../components/PullToRefresh'; import './Home.css'; const TODO_COLUMNS = [ @@ -17,22 +20,24 @@ const Home = () => { const posts = getBlogPosts().slice(0, 3); const highlights = navLinks.filter((link) => link.id !== 'home'); const theme = getCurrentTheme(); + const isMobile = useIsMobile(); const [todosByStatus, setTodosByStatus] = useState({ todo: [], in_progress: [], done: [] }); - useEffect(() => { - getTodos() - .then((data) => { - if (!Array.isArray(data)) return; - setTodosByStatus({ - todo: data.filter((t) => t.status === 'todo'), - in_progress: data.filter((t) => t.status === 'in_progress'), - done: data.filter((t) => t.status === 'done'), - }); - }) - .catch(() => { /* 조용히 실패 */ }); + const loadTodos = useCallback(async () => { + const data = await getTodos(); + if (!Array.isArray(data)) return; + setTodosByStatus({ + todo: data.filter((t) => t.status === 'todo'), + in_progress: data.filter((t) => t.status === 'in_progress'), + done: data.filter((t) => t.status === 'done'), + }); }, []); + useEffect(() => { + loadTodos().catch(() => { /* 조용히 실패 */ }); + }, [loadTodos]); + const totalTasks = todosByStatus.todo.length + todosByStatus.in_progress.length + todosByStatus.done.length; const doneTasks = todosByStatus.done.length; const inProgress = todosByStatus.in_progress.length; @@ -132,7 +137,79 @@ const Home = () => {

TODO

계획 · 진행 중 · 완료 태스크를 한눈에 확인합니다.

- + + {isMobile ? ( + + {(todosByStatus.todo || []).length === 0 ? ( +

태스크가 없습니다.

+ ) : (todosByStatus.todo || []).map((todo) => ( +
+

{todo.title}

+ {todo.description &&

{todo.description}

} +

+ {todo.updated_at + ? new Date(todo.updated_at).toLocaleDateString('ko-KR', { month: 'short', day: 'numeric' }) + : ''} +

+
+ ))} + + ), + }, + { + key: 'in_progress', + label: '진행중', + content: ( +
+ {(todosByStatus.in_progress || []).length === 0 ? ( +

태스크가 없습니다.

+ ) : (todosByStatus.in_progress || []).map((todo) => ( +
+

{todo.title}

+ {todo.description &&

{todo.description}

} +

+ {todo.updated_at + ? new Date(todo.updated_at).toLocaleDateString('ko-KR', { month: 'short', day: 'numeric' }) + : ''} +

+
+ ))} +
+ ), + }, + { + key: 'done', + label: '완료', + content: ( +
+ {(todosByStatus.done || []).length === 0 ? ( +

태스크가 없습니다.

+ ) : (todosByStatus.done || []).map((todo) => ( +
+

{todo.title}

+ {todo.description &&

{todo.description}

} +

+ {todo.updated_at + ? new Date(todo.updated_at).toLocaleDateString('ko-KR', { month: 'short', day: 'numeric' }) + : ''} +

+
+ ))} +
+ ), + }, + ]} + /> + ) : ( + + )} +