'use client'; import { useState, type CSSProperties } from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faPlay } from '@fortawesome/free-solid-svg-icons'; import { DONATION_AMOUNT_MIN, DONATION_AMOUNT_MAX, DONATION_AMOUNT_STEP, DONATION_AMOUNT_DEFAULT, ALERT_NAME_MAX_LENGTH, PREVIEW_DEFAULT_NAME } from '@/constants/donation'; import { MOCK_CREW_RANKING } from '../constants'; import type { FormState } from '../types'; type Props = { form: FormState; }; type SimulatedDonation = { name: string; totalAmount: number; donationCount: number; }; const THEME_NAMES = ['basic', 'dark', 'minimal']; export default function CrewWidgetPreviewPanel({ form }: Props) { const [previewName, setPreviewName] = useState(PREVIEW_DEFAULT_NAME); const [previewAmount, setPreviewAmount] = useState(DONATION_AMOUNT_DEFAULT); const [simulatedDonations, setSimulatedDonations] = useState([]); // 시뮬레이션 데이터 있으면 contributionRate 자동 계산, 없으면 mock const visibleItems = simulatedDonations.length > 0 ? (() => { const sorted = simulatedDonations.slice().sort((a, b) => b.totalAmount - a.totalAmount); const total = sorted.reduce((sum, d) => sum + d.totalAmount, 0) || 1; return sorted.slice(0, form.maxDisplayCount).map((d, i) => ({ rank: i + 1, nickname: d.name, totalAmount: d.totalAmount, donationCount: d.donationCount, contributionRate: (d.totalAmount / total) * 100 })); })() : MOCK_CREW_RANKING.slice(0, form.maxDisplayCount); const themeName = THEME_NAMES[form.theme] ?? 'basic'; const getFontStyle = (rank: number): CSSProperties => { if (rank === 1) { return { '--row-font-family': form.rank1FontFamily || 'inherit', '--row-font-size': `${form.rank1FontSizePx}px`, '--row-font-color': form.rank1FontColor } as CSSProperties; } if (rank === 2) { return { '--row-font-family': form.rank2FontFamily || 'inherit', '--row-font-size': `${form.rank2FontSizePx}px`, '--row-font-color': form.rank2FontColor } as CSSProperties; } if (rank === 3) { return { '--row-font-family': form.rank3FontFamily || 'inherit', '--row-font-size': `${form.rank3FontSizePx}px`, '--row-font-color': form.rank3FontColor } as CSSProperties; } return { '--row-font-family': form.rowFontFamily || 'inherit', '--row-font-size': `${form.rowFontSizePx}px`, '--row-font-color': form.rowFontColor } as CSSProperties; }; const getBadgeClass = (rank: number) => { if (rank <= 3) { return `crew-widget-preview__badge--${rank}`; } return 'crew-widget-preview__badge--default'; }; const bodyStyle = { '--preview-bg': form.bgColor } as CSSProperties; const titleStyle = { '--preview-title-font': form.titleFontFamily || 'inherit', '--preview-title-size': `${form.titleFontSizePx}px`, '--preview-title-color': form.titleFontColor } as CSSProperties; const handlePreview = () => { const name = (previewName || PREVIEW_DEFAULT_NAME).trim(); const amount = previewAmount || DONATION_AMOUNT_DEFAULT; setSimulatedDonations(prev => { const existing = prev.find(d => d.name === name); if (existing) { return prev.map(d => d.name === name ? { ...d, totalAmount: d.totalAmount + amount, donationCount: d.donationCount + 1 } : d ); } return [...prev, { name, totalAmount: amount, donationCount: 1 }]; }); }; const handleReset = () => { setSimulatedDonations([]); }; const totalSimulatedAmount = simulatedDonations.reduce((sum, d) => sum + d.totalAmount, 0); return ( ); }