'use client'; import { useState } from 'react'; import { useParams, useRouter } from 'next/navigation'; import { Box, Container, TextField, Select, MenuItem, FormControl, InputLabel, Card, CardContent, Typography, Button, InputAdornment, Pagination, Chip, Dialog, DialogTitle, DialogContent, DialogActions, Grid, } from '@mui/material'; import { Search, FilterList, Casino, Download, People, TrendingUp, Person, AccessTime, } from '@mui/icons-material'; // 디자인 시스템 색상 const colors = { pink: '#F472B6', purple: '#C084FC', purpleLight: '#E9D5FF', blue: '#60A5FA', mint: '#34D399', orange: '#FB923C', yellow: '#FBBF24', gray: { 900: '#1A1A1A', 700: '#4A4A4A', 500: '#9E9E9E', 300: '#D9D9D9', 100: '#F5F5F5', }, }; // Mock 데이터 const mockParticipants = [ { id: '0001', name: '김**', phone: '010-****-1234', channel: 'SNS (Instagram)', channelType: 'sns', date: '2025-11-02 14:23', status: 'waiting' as const, }, { id: '0002', name: '이**', phone: '010-****-5678', channel: '우리동네TV', channelType: 'uriTV', date: '2025-11-02 15:45', status: 'waiting' as const, }, { id: '0003', name: '박**', phone: '010-****-9012', channel: '링고비즈', channelType: 'ringoBiz', date: '2025-11-02 16:12', status: 'waiting' as const, }, { id: '0004', name: '최**', phone: '010-****-3456', channel: 'SNS (Naver)', channelType: 'sns', date: '2025-11-02 17:30', status: 'winner' as const, }, { id: '0005', name: '정**', phone: '010-****-7890', channel: '우리동네TV', channelType: 'uriTV', date: '2025-11-02 18:15', status: 'loser' as const, }, ]; type ChannelType = 'all' | 'uriTV' | 'ringoBiz' | 'sns'; type StatusType = 'all' | 'waiting' | 'winner' | 'loser'; export default function ParticipantsPage() { const params = useParams(); const router = useRouter(); const eventId = params.eventId as string; const [searchTerm, setSearchTerm] = useState(''); const [channelFilter, setChannelFilter] = useState('all'); const [statusFilter, setStatusFilter] = useState('all'); const [currentPage, setCurrentPage] = useState(1); const [selectedParticipant, setSelectedParticipant] = useState(null); const [detailDialogOpen, setDetailDialogOpen] = useState(false); const itemsPerPage = 20; // 필터링 const filteredParticipants = mockParticipants.filter((participant) => { const matchesSearch = participant.name.includes(searchTerm) || participant.phone.includes(searchTerm); const matchesChannel = channelFilter === 'all' || participant.channelType === channelFilter; const matchesStatus = statusFilter === 'all' || participant.status === statusFilter; return matchesSearch && matchesChannel && matchesStatus; }); // 페이지네이션 const totalPages = Math.ceil(filteredParticipants.length / itemsPerPage); const startIndex = (currentPage - 1) * itemsPerPage; const endIndex = Math.min(startIndex + itemsPerPage, filteredParticipants.length); const pageParticipants = filteredParticipants.slice(startIndex, endIndex); const getStatusColor = (status: string) => { switch (status) { case 'waiting': return 'default'; case 'winner': return 'success'; case 'loser': return 'error'; default: return 'default'; } }; const getStatusText = (status: string) => { switch (status) { case 'waiting': return '당첨 대기'; case 'winner': return '당첨'; case 'loser': return '미당첨'; default: return status; } }; const handleParticipantClick = (participant: typeof mockParticipants[0]) => { setSelectedParticipant(participant); setDetailDialogOpen(true); }; const handleDrawClick = () => { router.push(`/events/${eventId}/draw`); }; const handleDownloadClick = () => { alert('엑셀 다운로드 기능은 추후 구현됩니다'); }; // 통계 계산 const stats = { total: mockParticipants.length, waiting: mockParticipants.filter((p) => p.status === 'waiting').length, winner: mockParticipants.filter((p) => p.status === 'winner').length, channelDistribution: { uriTV: mockParticipants.filter((p) => p.channelType === 'uriTV').length, ringoBiz: mockParticipants.filter((p) => p.channelType === 'ringoBiz').length, sns: mockParticipants.filter((p) => p.channelType === 'sns').length, }, }; return ( {/* Page Header */} 👥 참여자 목록 이벤트에 참여한 사용자들의 정보를 확인하고 관리하세요 {/* Statistics Cards */} 전체 참여자 {stats.total}명 대기중 {stats.waiting}명 당첨자 {stats.winner}명 당첨률 {stats.total > 0 ? Math.round((stats.winner / stats.total) * 100) : 0}% {/* Search Section */} setSearchTerm(e.target.value)} InputProps={{ startAdornment: ( ), }} sx={{ '& .MuiOutlinedInput-root': { borderRadius: 3, bgcolor: 'white', }, }} /> {/* Filters */} 참여 경로 상태 {/* Total Count & Drawing Button */} {filteredParticipants.length}명 참여 {/* Participant List */} {pageParticipants.length === 0 ? ( 검색 결과가 없습니다 다른 검색어나 필터를 사용해보세요 ) : ( {pageParticipants.map((participant) => ( handleParticipantClick(participant)} > {/* Header */} #{participant.id} {participant.name} {participant.phone} {/* Info */} 참여 경로 참여 일시 {participant.date} ))} )} {/* Pagination */} {totalPages > 1 && ( setCurrentPage(page)} color="primary" size="large" sx={{ '& .MuiPaginationItem-root': { fontSize: '1rem', fontWeight: 600, }, }} /> )} {/* Participant Detail Dialog */} setDetailDialogOpen(false)} maxWidth="sm" fullWidth PaperProps={{ sx: { borderRadius: 4, }, }} > 참여자 상세 정보 {selectedParticipant && ( {selectedParticipant.name} #{selectedParticipant.id} 전화번호 {selectedParticipant.phone} 참여 경로 {selectedParticipant.channel} 참여 일시 {selectedParticipant.date} 당첨 여부 )} ); }