8개 커스텀 훅으로 state/handler 로직 추출: - usePortfolio: 포트폴리오 CRUD, 예수금, 브로커 그룹 - useSellHistory: 매도 내역 CRUD, 드로어/폼 상태 - useAiCoach: AI 코치 분석 + 캐시 - useAssetHistory: 자산 추이 차트 데이터 - useMarketContext: VIX/F&G/국채/WTI 시장 데이터 - useAiBalance: AI 모의투자 잔고, 수동 주문 - useReportData: 리포트 정렬, 차트, 집중도 분석 - useAdvisor: 어드바이저 프롬프트 빌더 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
67 lines
2.5 KiB
JavaScript
67 lines
2.5 KiB
JavaScript
import { useState, useCallback } from 'react';
|
|
import { getAssetHistory, saveAssetSnapshot } from '../../../api';
|
|
|
|
export default function useAssetHistory() {
|
|
const [assetHistory, setAssetHistory] = useState(null);
|
|
const [assetHistoryLoading, setAssetHistoryLoading] = useState(false);
|
|
const [assetHistoryDays, setAssetHistoryDays] = useState(30);
|
|
const [snapshotSaving, setSnapshotSaving] = useState(false);
|
|
|
|
const loadAssetHistory = useCallback(async (days) => {
|
|
setAssetHistoryLoading(true);
|
|
try {
|
|
const data = await getAssetHistory(days);
|
|
const raw = data?.snapshots ?? data?.history ?? (Array.isArray(data) ? data : []);
|
|
const byDate = {};
|
|
for (const item of raw) byDate[item.date] = item.total_assets ?? 0;
|
|
|
|
const toLocalDate = (d) => {
|
|
const y = d.getFullYear();
|
|
const m = String(d.getMonth() + 1).padStart(2, '0');
|
|
const day = String(d.getDate()).padStart(2, '0');
|
|
return `${y}-${m}-${day}`;
|
|
};
|
|
|
|
let filled;
|
|
if (days > 0) {
|
|
const today = new Date();
|
|
filled = Array.from({ length: days }, (_, i) => {
|
|
const d = new Date(today);
|
|
d.setDate(today.getDate() - (days - 1 - i));
|
|
const dateStr = toLocalDate(d);
|
|
const val = byDate[dateStr];
|
|
return val > 0 ? { date: dateStr, total_assets: val } : null;
|
|
}).filter(Boolean);
|
|
} else {
|
|
filled = Object.entries(byDate)
|
|
.filter(([, v]) => v > 0)
|
|
.map(([date, total_assets]) => ({ date, total_assets }))
|
|
.sort((a, b) => a.date.localeCompare(b.date));
|
|
}
|
|
setAssetHistory(filled);
|
|
} catch {
|
|
setAssetHistory([]);
|
|
} finally {
|
|
setAssetHistoryLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
const handleSaveSnapshot = async (totalAssets, days) => {
|
|
setSnapshotSaving(true);
|
|
try {
|
|
await saveAssetSnapshot(totalAssets != null ? Number(totalAssets) : undefined);
|
|
await loadAssetHistory(days);
|
|
} catch (err) {
|
|
alert('스냅샷 저장 실패: ' + (err?.message ?? String(err)));
|
|
} finally {
|
|
setSnapshotSaving(false);
|
|
}
|
|
};
|
|
|
|
return {
|
|
assetHistory, assetHistoryLoading,
|
|
assetHistoryDays, setAssetHistoryDays,
|
|
snapshotSaving, loadAssetHistory, handleSaveSnapshot,
|
|
};
|
|
}
|