File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeaderCell,
TableRow,
} from '@/components/ui/table';
import {
formatAdminRoleLabel,
formatOptionalValue,
type AdminMember,
} from '@/lib/domain/admin-member';
import { AdminMemberRowActions } from './admin-member-row-actions';
interface AdminMemberTableProps {
items: AdminMember[];
page: number;
pageSize: number;
totalCount: number;
/** 현재 로그인한 관리자의 id — 본인 행의 삭제 버튼을 막는 데 쓴다. */
currentAdminId: string;
}
const COLUMN_HEADERS = [
'번호',
'이름',
'아이디',
'휴대전화번호',
'이메일',
'역할',
'생성일',
'관리',
];
/**
* 관리자 회원 목록 테이블(시안 ADM_ADM_101 ④). 개인정보 마스킹은 시안에 "마스킹 처리 없음"으로
* 명시돼 있어 원본 값을 그대로 노출한다.
*
* **"번호"는 저장된 값이 아니라 전체 건수에서 거꾸로 세는 표시 순번이다** — 시안이 6·5·4처럼
* 내림차순으로 표기하고, 목록의 기본 정렬이 생성일 최신순이라 "가장 최근에 만들어진 계정이 가장
* 큰 번호"가 된다. 이 계산은 정확한 전체 건수를 전제하는데, Repository가 전체를 받아 세기 때문에
* 그 전제가 성립한다(백엔드 `totalCount`는 신뢰할 수 없다 — Repository 주석 참조).
*
* 백엔드가 아직 주지 않는 항목(휴대전화번호·이메일·생성일)은 열을 그대로 유지한 채 `-`로 표시한다
* — 백엔드가 필드를 추가하면 Repository 매핑만 늘리면 이 파일은 그대로 값이 채워진다.
*
* "관리" 열은 행별 수정/삭제 트리거(AdminMemberRowActions)에 위임한다 — 상호작용이 필요한 것은
* 그 셀뿐이라 이 테이블 자체는 Server Component로 유지하고 최말단만 클라이언트 경계로 뗀다.
*/
export function AdminMemberTable({
items,
page,
pageSize,
totalCount,
currentAdminId,
}: AdminMemberTableProps) {
const offset = (page - 1) * pageSize;
return (
<Table>
<TableHead>
<TableRow>
{COLUMN_HEADERS.map((header) => (
<TableHeaderCell key={header}>{header}</TableHeaderCell>
))}
</TableRow>
</TableHead>
<TableBody>
{items.map((member, index) => (
<TableRow key={member.id}>
<TableCell>{totalCount - offset - index}</TableCell>
<TableCell>{member.name}</TableCell>
<TableCell>{member.loginId}</TableCell>
<TableCell>{formatOptionalValue(member.phoneNumber)}</TableCell>
<TableCell>{formatOptionalValue(member.email)}</TableCell>
<TableCell>{formatAdminRoleLabel(member.roleCode)}</TableCell>
<TableCell>{formatOptionalValue(member.createdAt)}</TableCell>
<TableCell>
<AdminMemberRowActions
member={member}
isSelf={member.id === currentAdminId}
/>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
);
}