'use client'; import { FoxBadge, type FoxBadgeColor } from '@fox/core/components/fox-badge'; import { FoxIconButton } from '@fox/core/components/fox-icon-button'; import { FoxStatusIndicator } from '@fox/core/components/fox-status-indicator'; import type { FoxListColumn } from '@fox/core/components/fox-list-container'; import type { CommonCode } from '@/lib/domain/common-code'; import { FoxPaperclipIcon } from '@fox/core/icons'; import { formatPhoneNumber } from '@/lib/domain/phone-number'; import { EMPTY_FIELD_PLACEHOLDER, formatAnswerStatusLabel, formatBoardCategoryLabel, formatFaqTypeLabel, formatInquiryTypeLabel, formatOptionalValue, formatVisibilityLabel, type BoardPost, type BoardType, } from '@/lib/domain/board-post'; import { BoardRowActions } from './board-row-actions'; import { InquiryRowActions } from '../inquiries/_components/inquiry-row-actions'; function numberColumn(page: number, pageSize: number): FoxListColumn { return { key: 'no', header: '번호', width: 80, render: (_row, index) => (page - 1) * pageSize + index + 1, }; } function visibilityColumn(): FoxListColumn { return { key: 'isVisible', header: '사용여부', width: 120, render: (row) => ( ), }; } function actionsColumn( boardType: BoardType, faqTypes: readonly CommonCode[] = [] ): FoxListColumn { return { key: 'actions', header: '관리', width: 120, render: (row) => ( event.stopPropagation()}> ), }; } function noticeColumns(page: number, pageSize: number): FoxListColumn[] { return [ numberColumn(page, pageSize), { key: 'category', header: '구분', width: 120, render: (row) => ( {formatBoardCategoryLabel(row.categoryCode)} ), }, { key: 'title', header: '제목', width: 320, emphasis: true }, { key: 'attachment', header: '첨부', width: 100, render: (row) => row.attachmentId ? ( } label={`${row.title} 첨부파일`} /> ) : null, }, { key: 'authorName', header: '작성자', width: 160, render: (row) => formatOptionalValue(row.authorName), }, visibilityColumn(), { key: 'createdAt', header: '작성일', width: 140, render: (row) => formatOptionalValue(row.createdAt), }, actionsColumn('notice'), ]; } function faqColumns( page: number, pageSize: number, faqTypes: readonly CommonCode[] ): FoxListColumn[] { const typeOptions = faqTypes.map((code) => ({ value: code.code, label: code.label, })); return [ numberColumn(page, pageSize), { key: 'category', header: '구분', width: 120, render: (row) => ( {formatBoardCategoryLabel(row.categoryCode)} ), }, { key: 'type', header: '유형', width: 120, render: (row) => formatFaqTypeLabel(row.typeCode, typeOptions), }, { key: 'title', header: '제목', width: 320, emphasis: true }, { key: 'authorName', header: '작성자', width: 160, render: (row) => formatOptionalValue(row.authorName), }, { key: 'createdAt', header: '등록일', width: 140, render: (row) => formatOptionalValue(row.createdAt), }, visibilityColumn(), actionsColumn('faq', faqTypes), ]; } // TODO: BBS_ANS_CD의 실제 코드값이 확인되면 코드값 기준 표로 바꾼다(관리자 권한 배지와 같은 방식). // 이슈: 코드값을 모르고 코드명도 코드관리 화면에서 바뀔 수 있어 코드명으로 색을 고른다. // 앞에서부터 먼저 걸리는 것을 쓴다 — 「미처리」가 「처리」보다 앞에 있어야 한다. const ANSWER_STATUS_BADGE_COLORS: readonly (readonly [string, FoxBadgeColor])[] = [ ['미답변', 'warning'], ['미처리', 'warning'], ['완료', 'success'], ['반려', 'danger'], ['보류', 'danger'], ['취소', 'danger'], ['처리', 'information'], ['진행', 'information'], ['접수', 'information'], ['대기', 'warning'], ]; function answerStatusBadgeColor(label: string): FoxBadgeColor { const matched = ANSWER_STATUS_BADGE_COLORS.find(([keyword]) => label.includes(keyword) ); return matched?.[1] ?? 'neutral'; } function inquiryColumns( page: number, pageSize: number, answerStatuses: readonly CommonCode[] ): FoxListColumn[] { const statusOptions = answerStatuses.map((code) => ({ value: code.code, label: code.label, })); return [ numberColumn(page, pageSize), { key: 'type', header: '질문유형', width: 120, render: (row) => formatInquiryTypeLabel(row.typeCode), }, { key: 'title', header: '질문제목', width: 280, emphasis: true }, { key: 'authorName', header: '질문자명', width: 140, render: (row) => formatOptionalValue(row.authorName), }, { key: 'authorPhoneNumber', header: '전화번호', width: 160, render: (row) => formatOptionalValue(formatPhoneNumber(row.authorPhoneNumber)), }, { key: 'createdAt', header: '질문일', width: 140, render: (row) => formatOptionalValue(row.createdAt), }, { key: 'answerStatus', header: '상태', width: 120, render: (row) => { if (!row.answerStatusCode) { return EMPTY_FIELD_PLACEHOLDER; } const label = formatAnswerStatusLabel(row.answerStatusCode, statusOptions); return ( {label} ); }, }, { key: 'answeredAt', header: '답변일', width: 140, render: (row) => formatOptionalValue(row.answeredAt), }, { key: 'actions', header: '관리', width: 160, render: (row) => ( ), }, ]; } export function boardPostColumns( boardType: BoardType, page: number, pageSize: number, answerStatuses: readonly CommonCode[] = [], faqTypes: readonly CommonCode[] = [] ): FoxListColumn[] { if (boardType === 'notice') return noticeColumns(page, pageSize); if (boardType === 'faq') return faqColumns(page, pageSize, faqTypes); return inquiryColumns(page, pageSize, answerStatuses); }