Functions.jsx 컴포넌트 분할: 1,583→460줄 (3훅+8컴포넌트+유틸)
- lottoUtils.jsx: 공통 유틸·상수 추출 (Ball, NumberRow, 통계 헬퍼 등) - hooks/useLottoData.js: 핵심 데이터 로드 (최신회차, 통계, 시뮬레이션, 리포트) - hooks/usePurchases.js: 구매 기록 CRUD - hooks/useManualRecommend.js: 수동 추천 + 히스토리 - components/: MetricBlock, FrequencyChart, PerformanceBanner, ConfidenceRing, CombinedRecommendPanel, ReportPanel, PersonalAnalysisPanel, PurchasePanel 분리 - getReport import 누락 버그 수정 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
59
src/pages/lotto/components/MetricBlock.jsx
Normal file
59
src/pages/lotto/components/MetricBlock.jsx
Normal file
@@ -0,0 +1,59 @@
|
||||
import React from 'react';
|
||||
import { toBucketEntries } from '../lottoUtils';
|
||||
|
||||
const MetricBlock = ({ title, metrics }) => {
|
||||
if (!metrics) return null;
|
||||
const buckets = toBucketEntries(metrics);
|
||||
const maxBucket = buckets.length ? Math.max(...buckets.map(([, v]) => Number(v) || 0), 1) : 1;
|
||||
const odd = Number(metrics.odd) || 0;
|
||||
const even = Number(metrics.even) || 0;
|
||||
const totalOE = odd + even || 1;
|
||||
const oddPct = (odd / totalOE) * 100;
|
||||
|
||||
return (
|
||||
<div className="lotto-metrics">
|
||||
<div className="lotto-metrics__head">
|
||||
<p className="lotto-metrics__title">{title}</p>
|
||||
<span className="lotto-metrics__sum">총 출현 횟수 {metrics.sum ?? '-'}</span>
|
||||
</div>
|
||||
<div className="lotto-metric-cards">
|
||||
<div className="lotto-metric-card">
|
||||
<p className="lotto-metric-card__label">최소 출현</p>
|
||||
<p className="lotto-metric-card__value">{metrics.min ?? '-'}</p>
|
||||
</div>
|
||||
<div className="lotto-metric-card">
|
||||
<p className="lotto-metric-card__label">최대 출현</p>
|
||||
<p className="lotto-metric-card__value">{metrics.max ?? '-'}</p>
|
||||
</div>
|
||||
<div className="lotto-metric-card">
|
||||
<p className="lotto-metric-card__label">출현 편차</p>
|
||||
<p className="lotto-metric-card__value">{metrics.range ?? '-'}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="lotto-odd-even">
|
||||
<div className="lotto-odd-even__labels">
|
||||
<span>홀 {odd}</span><span>짝 {even}</span>
|
||||
</div>
|
||||
<div className="lotto-odd-even__bar" aria-hidden>
|
||||
<span className="lotto-odd-even__odd" style={{ width: `${oddPct}%` }} />
|
||||
<span className="lotto-odd-even__even" style={{ width: `${100 - oddPct}%` }} />
|
||||
</div>
|
||||
</div>
|
||||
{buckets.length ? (
|
||||
<div className="lotto-buckets">
|
||||
{buckets.map(([label, value]) => (
|
||||
<div key={label} className="lotto-bucket">
|
||||
<span className="lotto-bucket__label">{label}</span>
|
||||
<div className="lotto-bucket__bar" aria-hidden>
|
||||
<span style={{ width: `${((Number(value) || 0) / maxBucket) * 100}%` }} />
|
||||
</div>
|
||||
<span className="lotto-bucket__value">{value}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default MetricBlock;
|
||||
Reference in New Issue
Block a user