import { useState, useTransition } from "react"; import { useShallow } from "zustand/react/shallow"; import { cn } from "@/lib/utils"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { useKisRuntimeStore } from "@/features/dashboard/store/use-kis-runtime-store"; import { revokeKisCredentials, validateKisCredentials, } from "@/features/dashboard/apis/kis-auth.api"; /** * @description KIS 인증 입력 폼 * @see features/dashboard/store/use-kis-runtime-store.ts 인증 입력값/검증 상태를 저장합니다. */ export function KisAuthForm() { const { kisTradingEnvInput, kisAppKeyInput, kisAppSecretInput, verifiedCredentials, isKisVerified, setKisTradingEnvInput, setKisAppKeyInput, setKisAppSecretInput, setVerifiedKisSession, invalidateKisVerification, clearKisRuntimeSession, } = useKisRuntimeStore( useShallow((state) => ({ kisTradingEnvInput: state.kisTradingEnvInput, kisAppKeyInput: state.kisAppKeyInput, kisAppSecretInput: state.kisAppSecretInput, verifiedCredentials: state.verifiedCredentials, isKisVerified: state.isKisVerified, setKisTradingEnvInput: state.setKisTradingEnvInput, setKisAppKeyInput: state.setKisAppKeyInput, setKisAppSecretInput: state.setKisAppSecretInput, setVerifiedKisSession: state.setVerifiedKisSession, invalidateKisVerification: state.invalidateKisVerification, clearKisRuntimeSession: state.clearKisRuntimeSession, })), ); const [statusMessage, setStatusMessage] = useState(null); const [errorMessage, setErrorMessage] = useState(null); const [isValidating, startValidateTransition] = useTransition(); const [isRevoking, startRevokeTransition] = useTransition(); function handleValidate() { startValidateTransition(async () => { try { setErrorMessage(null); setStatusMessage(null); const appKey = kisAppKeyInput.trim(); const appSecret = kisAppSecretInput.trim(); if (!appKey || !appSecret) { throw new Error("App Key와 App Secret을 모두 입력해 주세요."); } // 주문 기능에서 계좌번호가 필요할 수 있어 구조는 유지하되, 인증 단계에서는 입력받지 않습니다. const credentials = { appKey, appSecret, tradingEnv: kisTradingEnvInput, accountNo: verifiedCredentials?.accountNo ?? "", }; const result = await validateKisCredentials(credentials); setVerifiedKisSession(credentials, result.tradingEnv); setStatusMessage( `${result.message} (${result.tradingEnv === "real" ? "실전" : "모의"})`, ); } catch (err) { invalidateKisVerification(); setErrorMessage( err instanceof Error ? err.message : "API 키 검증 중 오류가 발생했습니다.", ); } }); } function handleRevoke() { if (!verifiedCredentials) return; startRevokeTransition(async () => { try { setErrorMessage(null); setStatusMessage(null); const result = await revokeKisCredentials(verifiedCredentials); clearKisRuntimeSession(result.tradingEnv); setStatusMessage( `${result.message} (${result.tradingEnv === "real" ? "실전" : "모의"})`, ); } catch (err) { setErrorMessage( err instanceof Error ? err.message : "연결 해제 중 오류가 발생했습니다.", ); } }); } return ( KIS API 키 연결 대시보드 사용 전, 개인 API 키를 입력하고 검증해 주세요. 검증에 성공해야 시세 조회가 동작합니다. {/* ========== CREDENTIAL INPUTS ========== */}
setKisAppKeyInput(e.target.value)} placeholder="App Key 입력" autoComplete="off" />
setKisAppSecretInput(e.target.value)} placeholder="App Secret 입력" autoComplete="off" />
{/* ========== ACTIONS ========== */}
{isKisVerified ? ( 연결됨 ({verifiedCredentials?.tradingEnv === "real" ? "실전" : "모의"}) ) : ( 미연결 )}
{errorMessage && (
{errorMessage}
)} {statusMessage && (
{statusMessage}
)}
); }