import { useState, useMemo, useEffect } from "react"; import { Link, useSearchParams } from "react-router-dom"; import PageHeader from "@/components/common/PageHeader"; import SearchInput from "@/components/common/SearchInput"; import FilterDropdown from "@/components/common/FilterDropdown"; import FilterResetButton from "@/components/common/FilterResetButton"; import Pagination from "@/components/common/Pagination"; import EmptyState from "@/components/common/EmptyState"; import CopyButton from "@/components/common/CopyButton"; import MessageSlidePanel from "../components/MessageSlidePanel"; import { formatDate } from "@/utils/format"; import { MOCK_MESSAGES, SERVICE_FILTER_OPTIONS } from "../types"; const PAGE_SIZE = 10; export default function MessageListPage() { const [searchParams, setSearchParams] = useSearchParams(); // 필터 입력 상태 const [search, setSearch] = useState(""); const [serviceFilter, setServiceFilter] = useState("전체 서비스"); const [currentPage, setCurrentPage] = useState(1); const [loading, setLoading] = useState(false); // 실제 적용될 필터 (조회 버튼 클릭 시 반영) const [appliedSearch, setAppliedSearch] = useState(""); const [appliedService, setAppliedService] = useState("전체 서비스"); // URL 쿼리 파라미터로 messageId가 넘어온 경우 자동 검색 useEffect(() => { const messageId = searchParams.get("messageId"); if (messageId) { setSearch(messageId); setAppliedSearch(messageId); setSearchParams({}, { replace: true }); } }, []); // eslint-disable-line react-hooks/exhaustive-deps // 슬라이드 패널 상태 const [panelOpen, setPanelOpen] = useState(false); const [selectedMessageId, setSelectedMessageId] = useState( null ); // 조회 버튼 const handleQuery = () => { setLoading(true); setTimeout(() => { setAppliedSearch(search); setAppliedService(serviceFilter); setCurrentPage(1); setLoading(false); }, 400); }; // 필터 초기화 const handleReset = () => { setSearch(""); setServiceFilter("전체 서비스"); setAppliedSearch(""); setAppliedService("전체 서비스"); setCurrentPage(1); }; // 필터링된 데이터 const filtered = useMemo(() => { return MOCK_MESSAGES.filter((msg) => { // 검색 (메시지 ID / 제목) if (appliedSearch) { const q = appliedSearch.toLowerCase(); if ( !msg.messageId.toLowerCase().includes(q) && !msg.title.toLowerCase().includes(q) ) return false; } // 서비스 필터 if ( appliedService !== "전체 서비스" && msg.serviceName !== appliedService ) { return false; } return true; }); }, [appliedSearch, appliedService]); // 페이지네이션 const totalItems = filtered.length; const totalPages = Math.max(1, Math.ceil(totalItems / PAGE_SIZE)); const paged = filtered.slice( (currentPage - 1) * PAGE_SIZE, currentPage * PAGE_SIZE ); // 행 클릭 → 슬라이드 패널 const handleRowClick = (messageId: string) => { setSelectedMessageId(messageId); setPanelOpen(true); }; return (
add 새 메시지 } /> {/* 필터바 */}
{/* 테이블 */} {loading ? ( /* 로딩 스켈레톤 */
{Array.from({ length: 5 }).map((_, i) => ( ))}
메시지 ID 메시지 제목 서비스 작성일
) : paged.length > 0 ? (
{paged.map((msg, idx) => ( handleRowClick(msg.messageId)} > {/* 메시지 ID */} {/* 메시지 제목 */} {/* 서비스 */} {/* 작성일 */} ))}
메시지 ID 메시지 제목 서비스 작성일
e.stopPropagation()} > {msg.messageId}
{msg.title} {msg.serviceName} {formatDate(msg.createdAt)}
{/* 페이지네이션 */}
) : ( )} {/* 슬라이드 패널 */} setPanelOpen(false)} messageId={selectedMessageId} />
); }