-
-
+const AccountPage = () => {
+ const { data: auth } = useAuthStatus();
+ const userName = auth?.user?.name || "크레임";
+ const userEmail = auth?.user?.email || "crame25@gmail.com";
+ const [notificationsEnabled, setNotificationsEnabled] = useState(true);
+
+ return (
+
+
+
+
+ {/* Profile info card */}
+
+
+
내 정보
+
+
+
+
+
+
- 이름
+ - {userName}
+
+
+
- 생년월일
+ - 0000.00.00
+
+
+
- 아이디
+ - crame25
+
+
+
- 이메일
+ - {userEmail}
+
+
+
- 전화번호
+ - 000-0000-0000
+
+
+
+
+
+ {/* Account settings */}
+
+ {/* 알림 설정 */}
+
+
+
알림 설정
+
거래 및 시장 알림을 받습니다
+
+
+
+ {/* 소셜 연동 */}
+
+
+
+

+
+
ID : {userEmail}
+
연결일자 : 2000.00.00
+
+
+
+
+
- );
+
+
+ );
};
-
-export default PortfolioPage;
\ No newline at end of file
+export default AccountPage;
\ No newline at end of file
diff --git a/src/pages/login/GoogleLoginPage.tsx b/src/pages/login/GoogleLoginPage.tsx
index 49b58d8..072eea9 100644
--- a/src/pages/login/GoogleLoginPage.tsx
+++ b/src/pages/login/GoogleLoginPage.tsx
@@ -13,7 +13,7 @@ const GoogleLoginPage = () => {
const location = useLocation();
const state = location.state as LocationState;
const errorMessage = state?.error;
-
+
const CLIENT_ID = import.meta.env.VITE_GOOGLE_CLIENT_ID;
const REDIRECT_URI = "http://localhost:5173/login/auth/google";
const SCOPE = "email profile openid";
@@ -24,9 +24,12 @@ const GoogleLoginPage = () => {
}
useEffect(() => {
- // 이미 로그인된 사용자는 홈 페이지로 리디렉션
- if (authData?.isAuthenticated) {
- navigate('/home');
+ const isLocalhost = typeof window !== 'undefined' && window.location.hostname === 'localhost';
+ const enableLocalAuto = (import.meta as any)?.env?.VITE_ENABLE_LOCAL_AUTOLOGIN !== 'false';
+
+ // 로컬 자동로그인 상태에서는 로그인 페이지에서 자동 리다이렉트하지 않음
+ if (authData?.isAuthenticated && !(isLocalhost && enableLocalAuto)) {
+ navigate('/');
}
}, [authData, navigate]);
@@ -50,6 +53,14 @@ const GoogleLoginPage = () => {
+ {window.location.hostname === 'localhost' && (
+
+ )}
)
}
diff --git a/src/pages/portfoliio/ApiKeyPage.tsx b/src/pages/portfoliio/ApiKeyPage.tsx
new file mode 100644
index 0000000..0e690ca
--- /dev/null
+++ b/src/pages/portfoliio/ApiKeyPage.tsx
@@ -0,0 +1,149 @@
+import React, { useMemo, useState } from "react";
+import PortfolioHeader from "@/pages/portfoliio/components/PortfolioHeader";
+
+type ApiKeyItem = {
+ id: string;
+ name: string;
+ publicKey: string;
+ secretKey: string;
+ createdAt: string;
+ manager: string;
+};
+
+const initialRows: ApiKeyItem[] = [
+ { id: "1", name: "Key1", publicKey: "Public Key1", secretKey: "Secret Key1", createdAt: "생성일1", manager: "관리1" },
+ { id: "2", name: "Key2", publicKey: "Public Key2", secretKey: "Secret Key2", createdAt: "생성일2", manager: "관리2" },
+ { id: "3", name: "Key3", publicKey: "Public Key3", secretKey: "Secret Key3", createdAt: "생성일3", manager: "관리3" },
+ { id: "4", name: "Key4", publicKey: "Public Key4", secretKey: "Secret Key4", createdAt: "생성일4", manager: "관리4" },
+];
+
+const ApiKeyPage = () => {
+ const [rows, setRows] = useState
(initialRows);
+ const [open, setOpen] = useState(false);
+ const [form, setForm] = useState({ name: "", publicKey: "", secretKey: "" });
+
+ const isValid = useMemo(() => form.name && form.publicKey && form.secretKey, [form]);
+
+ const onConfirm = () => {
+ if (!isValid) return;
+ const now = new Date();
+ const createdAt = `${now.getFullYear()}.${String(now.getMonth() + 1).padStart(2, "0")}.${String(now.getDate()).padStart(2, "0")}`;
+ setRows(prev => [
+ ...prev,
+ {
+ id: String(prev.length + 1),
+ name: form.name,
+ publicKey: form.publicKey,
+ secretKey: form.secretKey,
+ createdAt,
+ manager: `관리${prev.length + 1}`,
+ },
+ ]);
+ setForm({ name: "", publicKey: "", secretKey: "" });
+ setOpen(false);
+ };
+
+ const onDelete = (id: string) => {
+ const ok = window.confirm("해당 API Key를 삭제하시겠습니까?");
+ if (!ok) return;
+ setRows(prev => prev.filter(r => r.id !== id));
+ };
+
+ return (
+
+
+
+
+ {/* 안내 */}
+
+
API Key 설정 안내
+
거래소 API를 등록하시면 자동매매 기능을 이용하실 수 있습니다. API Key는 안전하게 암호화되어 저장됩니다.
+
+
+ {/* 표 */}
+
+
+
API Key 관리
+
+
+
+
+
+
+ | Public Key |
+ Secret Key |
+ 생성일 |
+ 관리 |
+
+
+
+ {rows.map((r) => (
+
+ | {r.publicKey} |
+ {r.secretKey} |
+ {r.createdAt} |
+
+
+ {r.manager}
+
+
+ |
+
+ ))}
+
+
+
+
+
+
+ {/* 모달 */}
+ {open && (
+
+
+
API key 입력
+
+
+
+
+
+
+
+ )}
+
+ );
+};
+
+export default ApiKeyPage;
diff --git a/src/pages/quant/QuantPage.tsx b/src/pages/quant/QuantPage.tsx
index ebec03c..7fff9a2 100644
--- a/src/pages/quant/QuantPage.tsx
+++ b/src/pages/quant/QuantPage.tsx
@@ -26,7 +26,7 @@ const QuantPage = () => {
system.id === "algorithm-trading"
? () => navigate("/quant/algo")
: system.id === "ai-trading"
- ? undefined
+ ? () => navigate("/ai-trade")
: undefined
}
/>
diff --git a/src/pages/quant/components/StrategyCard.tsx b/src/pages/quant/components/StrategyCard.tsx
index 3c5a5be..7880ce2 100644
--- a/src/pages/quant/components/StrategyCard.tsx
+++ b/src/pages/quant/components/StrategyCard.tsx
@@ -48,7 +48,7 @@ const StrategyCard = ({
{title}
{subtitle && {subtitle}}
-