'use client' import { BarChart3 } from "lucide-react" import { useEffect, useState } from "react" import apiClient from "@/lib/api-client" interface TraitData { trait: string regional: number myFarm: number } interface GenomeTraitsTableProps { farmNo?: number | null } export function GenomeTraitsTable({ farmNo }: GenomeTraitsTableProps) { const [traitData, setTraitData] = useState([]) const [loading, setLoading] = useState(true) useEffect(() => { const fetchTraitData = async () => { if (!farmNo) { setLoading(false) return } try { const traits = [ { name: '12개월령체중', key: '12개월령체중' }, { name: '도체중', key: '도체중' }, { name: '근내지방도', key: '근내지방도' }, { name: '등심단면적', key: '등심단면적' }, { name: '등지방두께', key: '등지방두께' }, ] const results: TraitData[] = [] for (const trait of traits) { try { const farmResponse = await apiClient.post('/cow/ranking', { filterOptions: { farmNo: farmNo }, rankingOptions: { criteriaType: 'GENOME', traitConditions: [{ traitNm: trait.key, weight: 1.0 }] } }) const globalResponse = await apiClient.post('/cow/ranking/global', { rankingOptions: { criteriaType: 'GENOME', traitConditions: [{ traitNm: trait.key, weight: 1.0 }] } }) const farmResult = farmResponse.data || farmResponse const globalResult = globalResponse.data || globalResponse const farmScores = farmResult.items?.map((item: any) => item.sortValue) || [] const farmAvg = farmScores.length > 0 ? farmScores.reduce((sum: number, score: number) => sum + score, 0) / farmScores.length : 0 const globalScores = globalResult.items?.map((item: any) => item.sortValue) || [] const regionalAvg = globalScores.length > 0 ? globalScores.reduce((sum: number, score: number) => sum + score, 0) / globalScores.length : 0 results.push({ trait: trait.name, myFarm: parseFloat(farmAvg.toFixed(2)), regional: parseFloat(regionalAvg.toFixed(2)) }) } catch (error) { console.error(`[형질 테이블] ${trait.name} 데이터 로드 실패:`, error) } } setTraitData(results) } catch (error) { console.error('[형질 테이블] 전체 데이터 로드 실패:', error) setTraitData([]) } finally { setLoading(false) } } fetchTraitData() }, [farmNo]) const getTraitShortName = (name: string) => { const shortNames: Record = { '12개월령체중': '12개월령체중', '등심단면적': '등심단면적', '등지방두께': '등지방두께', '근내지방도': '근내지방도', '도체중': '도체중' } return shortNames[name] || name } if (loading) { return (
) } return (
{/* 헤더 */}

형질별 점수

보은군과 비교한 수치에요

5개 형질
{/* 콘텐츠 */}
{traitData.length === 0 ? (
데이터가 없습니다.
) : (
{traitData.map((item, idx) => { const diff = item.myFarm - item.regional const isPositive = diff >= 0 // σ를 0~100 스케일로 변환 (-3σ~+3σ → 0~100) const toPercent = (sigma: number) => Math.min(100, Math.max(0, ((sigma + 3) / 6) * 100)) return (
{/* 형질명 + 차이 */}
{getTraitShortName(item.trait)} = 0.3 ? 'bg-emerald-50 text-emerald-700 border border-emerald-200 shadow-sm' : diff <= -0.3 ? 'bg-amber-50 text-amber-700 border border-amber-200 shadow-sm' : 'bg-slate-50 text-slate-700 border border-slate-200' }`}> {diff > 0 ? '+' : ''}{diff.toFixed(1)}σ
{/* 비교 바 */}
{/* 보은군 바 */}
{/* 내농장 바 */}
{/* 라벨 */}
내농장 {item.myFarm > 0 ? '+' : ''}{item.myFarm}σ
보은군 {item.regional > 0 ? '+' : ''}{item.regional}σ
) })}
)}
) }