File name
Commit message
Commit date
08-14
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 type { Metadata } from 'next';
import Link from 'next/link';
import { Alert } from '@/components/ui/alert';
import { Pagination } from '@/components/ui/pagination';
import { verifySession } from '@/lib/auth/dal';
import { fetchAdminMembers } from '@/lib/data/repositories/admin-member-repository';
import {
buildAdminMemberHref,
parseAdminMemberQuery,
} from '@/lib/domain/admin-member-query';
import { AdminMemberListToolbar } from './_components/admin-member-list-toolbar';
import { AdminMemberSearchBar } from './_components/admin-member-search-bar';
import { AdminMemberTable } from './_components/admin-member-table';
export const metadata: Metadata = {
title: '관리자 회원',
};
interface PageProps {
searchParams: Promise<Record<string, string | string[] | undefined>>;
}
/**
* 관리자 회원 목록(시안 ADM_ADM_101).
*
* 학생 회원 목록과 달리 전체 건수가 **확정값**이라 페이지 수를 그대로 계산한다 — Repository가
* 백엔드 페이징을 쓰지 않고 전체를 받아 직접 세기 때문이다(그 이유는 Repository 주석 참조).
*
* `verifySession()`의 반환값을 목록까지 내려보내는 이유는 본인 계정의 삭제 버튼을 막기 위해서다
* (시안 ⑤). 실제 차단은 Server Action이 다시 확인한다.
*/
export default async function Page({ searchParams }: PageProps) {
const admin = await verifySession();
const query = parseAdminMemberQuery(await searchParams);
const { items, totalCount } = await fetchAdminMembers(query);
const totalPages = Math.max(1, Math.ceil(totalCount / query.pageSize));
// 요청 페이지가 범위를 벗어나면(예: 삭제로 마지막 페이지가 사라짐) 마지막 페이지로 맞춘다 —
// 표의 순번 계산도 이 값을 기준으로 해야 헤더의 "현재페이지"와 어긋나지 않는다.
const currentPage = Math.min(query.page, totalPages);
return (
<section className="flex flex-1 flex-col gap-6 p-8">
<h1 className="text-headline-sm text-foreground">관리자 회원 목록</h1>
<AdminMemberSearchBar query={query} />
<AdminMemberListToolbar query={query} />
<p className="text-body-md text-foreground-muted">
총 {totalCount}명 | 현재페이지 {currentPage}/{totalPages}
</p>
{items.length === 0 ? (
<Alert
title="검색 결과가 없습니다."
actions={
<Link
href={buildAdminMemberHref(query, { keyword: '', page: 1 })}
className="bg-foreground px-4 py-2 text-background"
>
확인
</Link>
}
>
다른 검색어로 다시 시도해 주세요.
</Alert>
) : (
<>
<AdminMemberTable
items={items}
page={currentPage}
pageSize={query.pageSize}
totalCount={totalCount}
currentAdminId={admin.id}
/>
<Pagination
currentPage={currentPage}
totalPages={totalPages}
buildHref={(page: number) => buildAdminMemberHref(query, { page })}
/>
</>
)}
</section>
);
}