From cbf30c6bb4e74b6f4abfc2c54a57723445058cc6 Mon Sep 17 00:00:00 2001 From: zephyrdark Date: Tue, 3 Feb 2026 07:12:44 +0900 Subject: [PATCH] feat: add portfolio list page --- frontend/src/app/portfolio/page.tsx | 126 ++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 frontend/src/app/portfolio/page.tsx diff --git a/frontend/src/app/portfolio/page.tsx b/frontend/src/app/portfolio/page.tsx new file mode 100644 index 0000000..bcad07c --- /dev/null +++ b/frontend/src/app/portfolio/page.tsx @@ -0,0 +1,126 @@ +'use client'; + +import { useEffect, useState } from 'react'; +import { useRouter } from 'next/navigation'; +import Link from 'next/link'; +import Sidebar from '@/components/layout/Sidebar'; +import Header from '@/components/layout/Header'; +import { api } from '@/lib/api'; + +interface Portfolio { + id: number; + name: string; + portfolio_type: string; + created_at: string; + updated_at: string; +} + +interface User { + id: number; + username: string; + email: string; +} + +export default function PortfolioListPage() { + const router = useRouter(); + const [user, setUser] = useState(null); + const [loading, setLoading] = useState(true); + const [portfolios, setPortfolios] = useState([]); + const [error, setError] = useState(null); + + useEffect(() => { + const init = async () => { + try { + const userData = await api.getCurrentUser() as User; + setUser(userData); + await fetchPortfolios(); + } catch { + router.push('/login'); + } finally { + setLoading(false); + } + }; + init(); + }, [router]); + + const fetchPortfolios = async () => { + try { + setError(null); + const data = await api.get('/api/portfolios'); + setPortfolios(data); + } catch (err) { + const message = err instanceof Error ? err.message : 'Failed to fetch portfolios'; + setError(message); + } + }; + + const getTypeLabel = (type: string) => { + return type === 'pension' ? '퇴직연금' : '일반'; + }; + + if (loading) { + return ( +
+
Loading...
+
+ ); + } + + return ( +
+ +
+
+
+
+

포트폴리오

+ + 새 포트폴리오 + +
+ + {error && ( +
+ {error} +
+ )} + +
+ {portfolios.map((portfolio) => ( + +
+

+ {portfolio.name} +

+ + {getTypeLabel(portfolio.portfolio_type)} + +
+

+ 생성일: {new Date(portfolio.created_at).toLocaleDateString('ko-KR')} +

+ + ))} + + {portfolios.length === 0 && !error && ( +
+ 아직 포트폴리오가 없습니다. 새 포트폴리오를 생성해보세요. +
+ )} +
+
+
+
+ ); +}