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
File name
Commit message
Commit date
'use client';
import { useEffect, useState, useTransition } from 'react';
import { FoxModal } from '@fox/core/components/fox-modal';
import { FoxPagination } from '@fox/core/components/fox-pagination';
import { FoxStatusIndicator } from '@fox/core/components/fox-status-indicator';
import { FoxTable } from '@fox/core/components/fox-table';
import { FoxTableCell } from '@fox/core/components/fox-table-cell';
import { FoxTableRow } from '@fox/core/components/fox-table-row';
import {
formatOptionalValue,
formatPoint,
formatPointDelta,
isPointEarned,
type PointAccount,
type PointHistoryEntry,
} from '@/lib/domain/point-account';
import { fetchPointHistoryAction } from '../_actions';
import styles from './point-detail-modal.module.scss';
interface PointDetailModalProps {
account: PointAccount;
onClose: () => void;
}
const MEMBER_COLUMNS = [
'회원번호',
'아이디',
'학생명',
'학교명',
'학년',
'반',
'번호',
'총 포인트',
'차감 포인트',
'사용 포인트',
'현재 포인트',
];
export function PointDetailModal({ account, onClose }: PointDetailModalProps) {
const [page, setPage] = useState(1);
const [entries, setEntries] = useState<PointHistoryEntry[]>([]);
const [totalPages, setTotalPages] = useState(1);
const [isLoading, startLoading] = useTransition();
useEffect(() => {
startLoading(async () => {
const result = await fetchPointHistoryAction(account.id, page);
setEntries(result.items);
setTotalPages(result.totalPages);
});
}, [account.id, page]);
const memberValues = [
account.memberNo,
account.loginId,
account.studentName,
account.schoolName,
account.grade,
account.classNo,
account.studentNo,
formatPoint(account.totalPoint),
formatPoint(account.deductedPoint),
formatPoint(account.usedPoint),
formatPoint(account.currentPoint),
];
return (
<FoxModal open size="lg" title="포인트 상세내역" onClose={onClose}>
<div className={styles.body}>
<FoxTable type="list" caption="회원정보">
<FoxTableRow head>
{MEMBER_COLUMNS.map((column) => (
<FoxTableCell key={column} head>
{column}
</FoxTableCell>
))}
</FoxTableRow>
<FoxTableRow>
{memberValues.map((value, index) => (
<FoxTableCell key={MEMBER_COLUMNS[index]} label={MEMBER_COLUMNS[index]}>
{formatOptionalValue(value)}
</FoxTableCell>
))}
</FoxTableRow>
</FoxTable>
<FoxTable type="list" caption="포인트 내역">
<FoxTableRow head>
<FoxTableCell head width={320}>
항목
</FoxTableCell>
<FoxTableCell head width={140}>
포인트
</FoxTableCell>
<FoxTableCell head width={160}>
구분(사이트)
</FoxTableCell>
<FoxTableCell head width={140}>
날짜
</FoxTableCell>
</FoxTableRow>
{entries.length === 0 ? (
<FoxTableRow>
<FoxTableCell colSpan={4} align="center">
{isLoading ? '불러오는 중…' : '포인트 내역이 없습니다.'}
</FoxTableCell>
</FoxTableRow>
) : (
entries.map((entry) => (
<FoxTableRow key={entry.id}>
<FoxTableCell label="항목">{entry.title}</FoxTableCell>
<FoxTableCell label="포인트">
{/* 기획 ② 취득은 파랑 +, 사용은 빨강 −. */}
<FoxStatusIndicator
type={isPointEarned(entry.point) ? 'information' : 'danger'}
label={formatPointDelta(entry.point)}
/>
</FoxTableCell>
<FoxTableCell label="구분(사이트)">{entry.siteName}</FoxTableCell>
<FoxTableCell label="날짜">{entry.date}</FoxTableCell>
</FoxTableRow>
))
)}
</FoxTable>
<div className={styles.pagination}>
<FoxPagination
currentPage={page}
totalPages={totalPages}
onPageChange={setPage}
label="포인트 내역 페이지"
/>
</div>
</div>
</FoxModal>
);
}