'use client'; import { useRouter } from 'next/navigation'; import { useState } from 'react'; import { FoxBadge, type FoxBadgeColor } from '@fox/core/components/fox-badge'; import { FoxButton } from '@fox/core/components/fox-button'; import { FoxButtonGroup } from '@fox/core/components/fox-button-group'; import { FoxListContainer, type FoxListColumn, } from '@fox/core/components/fox-list-container'; import { FoxSelectText } from '@fox/core/components/fox-select-text'; import { FoxArrowsDownUpIcon, FoxDownloadSimpleIcon, FoxPlusIcon, } from '@fox/core/icons'; import { formatAdminRoleLabel, formatOptionalValue, type AdminMember, } from '@/lib/domain/admin-member'; import { ADMIN_MEMBERS_EXCEL_PATH, ADMIN_MEMBER_PAGE_SIZE_OPTIONS, ADMIN_MEMBER_SEARCH_FIELD_OPTIONS, ADMIN_MEMBER_SORT_OPTIONS, buildAdminMemberHref, type AdminMemberPageSize, type AdminMemberQuery, type AdminMemberSearchField, type AdminMemberSortOption, } from '@/lib/domain/admin-member-query'; import { AdminMemberCreateModal } from './admin-member-create-modal'; import { AdminMemberRowActions } from './admin-member-row-actions'; interface AdminMemberListProps { items: AdminMember[]; query: AdminMemberQuery; currentPage: number; totalPages: number; totalCount: number; currentAdminId: string; } const FILL_COLUMN_WIDTH = 277; const BADGE_COLOR_BY_ROLE: Record = { ROLE_SYSTEM: 'accent', ROLE_ADMIN: 'primary', }; export function AdminMemberList({ items, query, currentPage, totalPages, totalCount, currentAdminId, }: AdminMemberListProps) { const router = useRouter(); const [isCreateOpen, setIsCreateOpen] = useState(false); function go(patch: Partial) { router.replace(buildAdminMemberHref(query, { ...patch, page: 1 })); } const offset = (currentPage - 1) * query.pageSize; const columns: FoxListColumn[] = [ { key: 'no', header: '번호', width: 80, render: (_row, index) => totalCount - offset - index, }, { key: 'name', header: '이름', width: FILL_COLUMN_WIDTH }, { key: 'loginId', header: '아이디', width: FILL_COLUMN_WIDTH }, { key: 'phoneNumber', header: '휴대전화번호', width: 200, render: (row) => formatOptionalValue(row.phoneNumber), }, { key: 'email', header: '이메일', width: FILL_COLUMN_WIDTH, render: (row) => formatOptionalValue(row.email), }, { key: 'role', header: '역할', width: 120, render: (row) => ( {formatAdminRoleLabel(row.roleCode)} ), }, { key: 'createdAt', header: '생성일', width: 160, render: (row) => formatOptionalValue(row.createdAt), }, { key: 'actions', header: '관리', width: 160, render: (row) => ( ), }, ]; return ( <> title="관리자 회원 목록" breadcrumb={[ { label: '홈', href: '/' }, { label: '관리자정보관리' }, { label: '관리자 회원' }, ]} caption="관리자 회원 목록" columns={columns} rows={items} rowKey={(row) => row.id} totalCount={totalCount} emptyMessage="검색 결과가 없습니다. 다른 검색어로 다시 시도해 주세요." sorts={ <> } options={ADMIN_MEMBER_SORT_OPTIONS.map((option) => ({ value: option.value, label: option.label, }))} value={query.sort} onValueChange={(value) => go({ sort: value as AdminMemberSortOption })} /> ({ value: String(size), label: `${size}개씩 보기`, }))} value={String(query.pageSize)} onValueChange={(value) => go({ pageSize: Number(value) as AdminMemberPageSize }) } /> } searchFields={ADMIN_MEMBER_SEARCH_FIELD_OPTIONS.map((option) => ({ value: option.value, label: option.label, }))} searchField={query.searchField} keyword={query.keyword} toolbarActions={
} label="엑셀 다운로드" /> } label="신규 등록" onAction={() => setIsCreateOpen(true)} />
} page={currentPage} totalPages={totalPages} buildHref={(patch) => buildAdminMemberHref(query, { page: Number(patch.page ?? 1) }) } onQueryChange={(patch) => { if (patch.keyword !== undefined || patch.searchField !== undefined) { go({ keyword: String(patch.keyword ?? ''), searchField: (patch.searchField ?? query.searchField) as AdminMemberSearchField, }); } }} /> {isCreateOpen && ( setIsCreateOpen(false)} /> )} ); }