전체적인 리팩토링
This commit is contained in:
@@ -1,14 +1,21 @@
|
||||
import { useState, useTransition } from "react";
|
||||
import { useEffect, useState, useTransition } from "react";
|
||||
import { useShallow } from "zustand/react/shallow";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import { useKisRuntimeStore } from "@/features/settings/store/use-kis-runtime-store";
|
||||
import {
|
||||
revokeKisCredentials,
|
||||
validateKisCredentials,
|
||||
} from "@/features/settings/apis/kis-auth.api";
|
||||
import {
|
||||
getRememberedKisValue,
|
||||
isKisRememberEnabled,
|
||||
setKisRememberEnabled,
|
||||
setRememberedKisValue,
|
||||
} from "@/features/settings/lib/kis-remember-storage";
|
||||
import {
|
||||
KeyRound,
|
||||
ShieldCheck,
|
||||
@@ -37,6 +44,7 @@ export function KisAuthForm() {
|
||||
kisAppKeyInput,
|
||||
kisAppSecretInput,
|
||||
verifiedAccountNo,
|
||||
hasHydrated,
|
||||
verifiedCredentials,
|
||||
isKisVerified,
|
||||
setKisTradingEnvInput,
|
||||
@@ -51,6 +59,7 @@ export function KisAuthForm() {
|
||||
kisAppKeyInput: state.kisAppKeyInput,
|
||||
kisAppSecretInput: state.kisAppSecretInput,
|
||||
verifiedAccountNo: state.verifiedAccountNo,
|
||||
hasHydrated: state._hasHydrated,
|
||||
verifiedCredentials: state.verifiedCredentials,
|
||||
isKisVerified: state.isKisVerified,
|
||||
setKisTradingEnvInput: state.setKisTradingEnvInput,
|
||||
@@ -66,6 +75,74 @@ export function KisAuthForm() {
|
||||
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
||||
const [isValidating, startValidateTransition] = useTransition();
|
||||
const [isRevoking, startRevokeTransition] = useTransition();
|
||||
// [State] 앱키 입력값을 브라우저 재접속 후 자동 복원할지 여부
|
||||
const [rememberAppKey, setRememberAppKey] = useState(() =>
|
||||
isKisRememberEnabled("appKey"),
|
||||
);
|
||||
// [State] 앱시크릿키 입력값을 브라우저 재접속 후 자동 복원할지 여부
|
||||
const [rememberAppSecret, setRememberAppSecret] = useState(() =>
|
||||
isKisRememberEnabled("appSecret"),
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!hasHydrated || kisAppKeyInput.trim()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// [Step 1] 세션 입력값이 비어 있을 때만 저장된 앱키를 복원합니다.
|
||||
const rememberedAppKey = getRememberedKisValue("appKey");
|
||||
if (rememberedAppKey) {
|
||||
setKisAppKeyInput(rememberedAppKey);
|
||||
}
|
||||
}, [hasHydrated, kisAppKeyInput, setKisAppKeyInput]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!hasHydrated || kisAppSecretInput.trim()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// [Step 1] 세션 입력값이 비어 있을 때만 저장된 앱시크릿키를 복원합니다.
|
||||
const rememberedAppSecret = getRememberedKisValue("appSecret");
|
||||
if (rememberedAppSecret) {
|
||||
setKisAppSecretInput(rememberedAppSecret);
|
||||
}
|
||||
}, [hasHydrated, kisAppSecretInput, setKisAppSecretInput]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!hasHydrated) {
|
||||
return;
|
||||
}
|
||||
|
||||
// [Step 2] 앱키 기억하기 체크 상태를 저장/해제합니다.
|
||||
setKisRememberEnabled("appKey", rememberAppKey);
|
||||
}, [hasHydrated, rememberAppKey]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!hasHydrated || !rememberAppKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
// [Step 2] 앱키 입력값이 바뀔 때 기억하기가 켜져 있으면 값을 갱신합니다.
|
||||
setRememberedKisValue("appKey", kisAppKeyInput);
|
||||
}, [hasHydrated, rememberAppKey, kisAppKeyInput]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!hasHydrated) {
|
||||
return;
|
||||
}
|
||||
|
||||
// [Step 2] 앱시크릿키 기억하기 체크 상태를 저장/해제합니다.
|
||||
setKisRememberEnabled("appSecret", rememberAppSecret);
|
||||
}, [hasHydrated, rememberAppSecret]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!hasHydrated || !rememberAppSecret) {
|
||||
return;
|
||||
}
|
||||
|
||||
// [Step 2] 앱시크릿키 입력값이 바뀔 때 기억하기가 켜져 있으면 값을 갱신합니다.
|
||||
setRememberedKisValue("appSecret", kisAppSecretInput);
|
||||
}, [hasHydrated, rememberAppSecret, kisAppSecretInput]);
|
||||
|
||||
function handleValidate() {
|
||||
startValidateTransition(async () => {
|
||||
@@ -243,22 +320,39 @@ export function KisAuthForm() {
|
||||
|
||||
{/* ========== APP KEY INPUTS ========== */}
|
||||
<div className="space-y-3">
|
||||
<CredentialInput
|
||||
id="kis-app-key"
|
||||
label="앱키"
|
||||
placeholder="한국투자증권 앱키 입력"
|
||||
value={kisAppKeyInput}
|
||||
onChange={setKisAppKeyInput}
|
||||
icon={KeySquare}
|
||||
/>
|
||||
<CredentialInput
|
||||
id="kis-app-secret"
|
||||
label="앱시크릿키"
|
||||
placeholder="한국투자증권 앱시크릿키 입력"
|
||||
value={kisAppSecretInput}
|
||||
onChange={setKisAppSecretInput}
|
||||
icon={Lock}
|
||||
/>
|
||||
<div className="space-y-2">
|
||||
<CredentialInput
|
||||
id="kis-app-key"
|
||||
label="앱키"
|
||||
placeholder="한국투자증권 앱키 입력"
|
||||
value={kisAppKeyInput}
|
||||
onChange={setKisAppKeyInput}
|
||||
icon={KeySquare}
|
||||
/>
|
||||
<RememberCheckbox
|
||||
id="remember-kis-app-key"
|
||||
checked={rememberAppKey}
|
||||
onChange={setRememberAppKey}
|
||||
label="앱키 기억하기"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<CredentialInput
|
||||
id="kis-app-secret"
|
||||
label="앱시크릿키"
|
||||
placeholder="한국투자증권 앱시크릿키 입력"
|
||||
value={kisAppSecretInput}
|
||||
onChange={setKisAppSecretInput}
|
||||
icon={Lock}
|
||||
/>
|
||||
<RememberCheckbox
|
||||
id="remember-kis-app-secret"
|
||||
checked={rememberAppSecret}
|
||||
onChange={setRememberAppSecret}
|
||||
label="앱시크릿키 기억하기"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</SettingsCard>
|
||||
@@ -306,3 +400,31 @@ function CredentialInput({
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function RememberCheckbox({
|
||||
id,
|
||||
checked,
|
||||
onChange,
|
||||
label,
|
||||
}: {
|
||||
id: string;
|
||||
checked: boolean;
|
||||
onChange: (checked: boolean) => void;
|
||||
label: string;
|
||||
}) {
|
||||
return (
|
||||
<div className="flex items-center gap-2 pl-1">
|
||||
<Checkbox
|
||||
id={id}
|
||||
checked={checked}
|
||||
onCheckedChange={(next) => onChange(next === true)}
|
||||
/>
|
||||
<Label
|
||||
htmlFor={id}
|
||||
className="cursor-pointer text-xs font-medium text-zinc-500 dark:text-zinc-300"
|
||||
>
|
||||
{label}
|
||||
</Label>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user