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 type { StudentMember } from '@/lib/domain/student-member';
import { StudentRowActions } from './student-row-actions';
interface StudentTableProps {
items: StudentMember[];
page: number;
pageSize: number;
}
const COLUMN_HEADERS = [
'번호',
'회원코드',
'이름',
'아이디',
'휴대전화번호',
'이메일',
'역할',
'학교',
'학년/반/번호',
'보호자이름',
'보호자연락처',
'가입일',
'관리',
];
/**
* 학생 회원 목록 테이블 — 조회 전용(등록/수정/삭제 없음). "번호"는 저장된 값이 아니라
* 현재 페이지 기준 표시 순번(= (page-1)*pageSize + 행 인덱스 + 1)이다. 개인정보 마스킹은
* 기획 시안에서 명시적으로 해제 지시가 있어 원본 값을 그대로 노출한다.
*
* "관리" 열은 행별 조회 팝업 트리거(StudentRowActions)에 위임한다 — 상호작용이 필요한 것은
* 그 셀뿐이라 이 테이블 자체는 Server Component로 유지하고 최말단만 클라이언트 경계로 뗀다
* (§2.4 "'use client'는 최말단에만").
*/
export function StudentTable({ items, page, pageSize }: StudentTableProps) {
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>{(page - 1) * pageSize + index + 1}</TableCell>
<TableCell>{member.memberCode}</TableCell>
<TableCell>{member.name}</TableCell>
<TableCell>{member.loginId}</TableCell>
<TableCell>{member.phoneNumber}</TableCell>
<TableCell>{member.email}</TableCell>
<TableCell>{member.role}</TableCell>
<TableCell>{member.schoolName}</TableCell>
<TableCell>{`${member.grade}학년 ${member.classNumber}반 ${member.studentNumber}번`}</TableCell>
<TableCell>{member.guardianName}</TableCell>
<TableCell>{member.guardianPhoneNumber}</TableCell>
<TableCell>{member.joinedAt}</TableCell>
<TableCell>
<StudentRowActions member={member} />
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
);
}