모의투자 관리 기능 추가

This commit is contained in:
Macbook
2026-05-31 03:47:07 +09:00
parent 9d7dddfa57
commit 16d0e2c226
78 changed files with 4688 additions and 972 deletions
@@ -0,0 +1,84 @@
import React, { useCallback } from 'react';
import type { PaperAllocationDto } from '../../utils/backendApi';
import { patchPaperAllocation } from '../../utils/backendApi';
import { fmtKrw } from '../TradeOrderPanel';
function coinCode(symbol: string): string {
return symbol.replace(/^KRW-/, '');
}
interface Props {
allocations: PaperAllocationDto[];
selectedMarket?: string;
onSelectMarket?: (market: string) => void;
onChanged?: () => void;
}
const PaperAllocationTable: React.FC<Props> = ({
allocations,
selectedMarket,
onSelectMarket,
onChanged,
}) => {
const toggleActive = useCallback(async (row: PaperAllocationDto) => {
await patchPaperAllocation(row.symbol, { isActive: !row.isActive });
onChanged?.();
}, [onChanged]);
if (!allocations.length) {
return <p className="ptd-muted"> . .</p>;
}
return (
<div className="ptd-alloc-table-wrap">
<table className="ptd-table ptd-alloc-table">
<thead>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
{allocations.map(row => {
const ret = row.symbolReturnPct ?? 0;
const selected = row.symbol === selectedMarket;
return (
<tr
key={row.symbol}
className={selected ? 'ptd-alloc-row--selected' : ''}
onClick={() => onSelectMarket?.(row.symbol)}
role="button"
tabIndex={0}
onKeyDown={e => { if (e.key === 'Enter') onSelectMarket?.(row.symbol); }}
>
<td>{row.koreanName || coinCode(row.symbol)}</td>
<td>{(row.weightPct ?? 0).toFixed(1)}%</td>
<td>{fmtKrw(row.maxInvestKrw)}</td>
<td>{fmtKrw(row.investedKrw ?? 0)}</td>
<td>{fmtKrw(row.evalAmount ?? 0)}</td>
<td className={ret >= 0 ? 'up' : 'down'}>{ret >= 0 ? '+' : ''}{ret.toFixed(2)}%</td>
<td onClick={e => e.stopPropagation()}>
<button
type="button"
className={`ptd-alloc-toggle${row.isActive !== false ? ' ptd-alloc-toggle--on' : ''}`}
onClick={() => void toggleActive(row)}
title={row.isActive !== false ? '신규 매수 허용' : '신규 매수 차단'}
>
{row.isActive !== false ? 'ON' : 'OFF'}
</button>
</td>
</tr>
);
})}
</tbody>
</table>
</div>
);
};
export default PaperAllocationTable;