import { useState } from 'react'; import { Alert, Checkbox, Form, Input, Modal, Typography, message } from 'antd'; import { ProCard } from '@ant-design/pro-components'; import { useQuery, useQueryClient } from '@tanstack/react-query'; import type { ColDef } from '@ag-grid-community/core'; import PageContainer from '@/components/common/PageContainer'; import SearchForm from '@/components/common/SearchForm'; import DataGrid from '@/components/common/DataGrid'; import PermissionButton from '@/components/common/PermissionButton'; import CodeBadge from '@/components/common/CodeBadge'; import AttachmentUpload from '@/components/biz/AttachmentUpload'; import { complaintApi, ComplaintRow, ComplaintSaveReq, ComplaintSearchParam } from '@/api/complaint'; import { GRAY, RADIUS, SHADOW, COLOR_ERROR_BG, COLOR_ERROR_BORDER } from '@/theme/tokens'; const { Text } = Typography; const fmt = (v: unknown) => (v as number)?.toLocaleString() ?? '-'; const COLUMNS: ColDef[] = [ { field: 'contractNo', headerName: '계약번호', width: 150, pinned: 'left' }, { field: 'agentName', headerName: '설계사', width: 120 }, { field: 'complaintType', headerName: '민원유형', width: 120 }, { field: 'content', headerName: '민원내용', flex: 1 }, { field: 'receivedDate', headerName: '접수일', width: 120 }, { field: 'status', headerName: '상태', width: 100, cellRenderer: (p: { value: string }) => , }, { field: 'chargebackTriggered', headerName: '환수', width: 80, cellRenderer: (p: { value: boolean }) => p.value ? 환수 : -, }, { field: 'chargebackAmount', headerName: '환수금액', width: 120, type: 'numericColumn', valueFormatter: (p) => fmt(p.value) }, { field: 'closedAt', headerName: '처리일', width: 120 }, ]; export default function Complaints() { const qc = useQueryClient(); const [params, setParams] = useState({ pageSize: 100 }); const [createOpen, setCreateOpen] = useState(false); const [closeTarget, setCloseTarget] = useState(null); const [processNote, setProcessNote] = useState(''); const [createdId, setCreatedId] = useState(null); const [form] = Form.useForm(); const { data, isLoading, isError } = useQuery({ queryKey: ['complaints', params], queryFn: () => complaintApi.list(params), retry: false, }); const rows = data?.list ?? []; const chargebackCount = rows.filter((r) => r.chargebackTriggered).length; const handleCreate = async () => { const values = await form.validateFields() as ComplaintSaveReq; try { const created = await complaintApi.create(values); message.success('민원 등록 완료'); qc.invalidateQueries({ queryKey: ['complaints'] }); setCreatedId(created.complaintId); setCreateOpen(false); form.resetFields(); } catch { /* handled */ } }; const handleClose = async () => { if (!closeTarget) return; try { await complaintApi.close(closeTarget, processNote); message.success('처리완료'); qc.invalidateQueries({ queryKey: ['complaints'] }); setCloseTarget(null); setProcessNote(''); } catch { /* handled */ } }; return ( setCreateOpen(true)}> + 민원 등록 } > {isError && ( )} {chargebackCount > 0 && (
환수 민원 {chargebackCount}건 — 정산 시 자동 반영
)} setParams({ ...v as ComplaintSearchParam, pageSize: 100 })} onReset={() => setParams({ pageSize: 100 })} /> rows={rows} columns={[ ...COLUMNS, { headerName: '액션', width: 120, pinned: 'right', cellRenderer: (p: { data: ComplaintRow }) => ( { setCloseTarget(p.data.complaintId); setProcessNote(''); }} > 처리완료 ), }, ]} loading={isLoading} height={600} rowKey="complaintId" getRowStyle={(params) => { if (params.data?.chargebackTriggered) { return { background: '#FEF0F1' }; } return undefined; }} /> {/* 등록 모달 */} setCreateOpen(false)} okText="등록" cancelText="취소" width={560}>
환수 트리거 (13M 이내 민원)
{/* 처리완료 모달 */} setCloseTarget(null)} okText="처리완료" cancelText="취소" >
setProcessNote(e.target.value)} placeholder="처리 내용을 입력하세요" />
{/* 첨부파일 (마지막 등록 건) */} {createdId && ( )}
); }