frontend phase 11
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
'use client';
|
||||
import { FunctionComponent } from 'react';
|
||||
import { useLocale, useTranslations } from 'next-intl';
|
||||
import { Paper, Stack, Typography } from '@mui/material';
|
||||
import StatusChip from '../StatusChip';
|
||||
import { formatIrrToToman, formatShamsiDate } from '@/utils';
|
||||
import { installmentStatusKind, type BnplInstallmentRow, type BnplInstallmentStatus } from '@/services/bnpl/types';
|
||||
|
||||
export interface InstallmentScheduleRowProps {
|
||||
row: BnplInstallmentRow;
|
||||
/** Render the provider-reported status chip (D5 Wallet). The D4 schedule preview omits it. */
|
||||
showStatus?: boolean;
|
||||
}
|
||||
|
||||
/** i18n key for each provider-reported installment status (labels are keys off the code, never derived). */
|
||||
const STATUS_LABEL_KEY: Record<BnplInstallmentStatus, string> = {
|
||||
paid: 'status_paid',
|
||||
due_soon: 'status_due_soon',
|
||||
upcoming: 'status_upcoming',
|
||||
overdue: 'status_overdue',
|
||||
};
|
||||
|
||||
/**
|
||||
* One repayment row — the down-payment (due «امروز») or an installment (Shamsi due date), with the
|
||||
* **served** amount (Toman via the money util). Reused by the D4 schedule table and the D5 Wallet due list;
|
||||
* `showStatus` adds the provider-reported status chip (D5). No money is computed here — display only.
|
||||
* @component InstallmentScheduleRow
|
||||
*/
|
||||
const InstallmentScheduleRow: FunctionComponent<InstallmentScheduleRowProps> = ({ row, showStatus = false }) => {
|
||||
const t = useTranslations('bnpl');
|
||||
const locale = useLocale();
|
||||
|
||||
const label =
|
||||
row.kind === 'down_payment' ? t('down_payment') : t('installment_n', { n: row.sequence });
|
||||
const dueLabel = row.kind === 'down_payment' ? t('today') : formatShamsiDate(`${row.dueDate}T00:00:00`, locale);
|
||||
|
||||
return (
|
||||
<Paper
|
||||
elevation={0}
|
||||
data-row-kind={row.kind}
|
||||
sx={{ p: 1.5, borderRadius: 2, border: '1px solid', borderColor: 'divider' }}
|
||||
>
|
||||
<Stack direction="row" sx={{ justifyContent: 'space-between', alignItems: 'center', gap: 1.5 }}>
|
||||
<Stack sx={{ gap: 0.25 }}>
|
||||
<Typography variant="body2" sx={{ fontWeight: 700 }}>
|
||||
{label}
|
||||
</Typography>
|
||||
<Typography variant="caption" sx={{ color: 'text.secondary' }}>
|
||||
{dueLabel}
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Stack sx={{ alignItems: 'flex-end', gap: 0.5 }}>
|
||||
<Typography
|
||||
variant="body2"
|
||||
sx={{ fontWeight: 700, color: row.kind === 'down_payment' ? 'var(--bal-secondary)' : undefined }}
|
||||
>
|
||||
{formatIrrToToman(row.amountIrr, locale)}
|
||||
</Typography>
|
||||
{showStatus && row.status ? (
|
||||
<StatusChip status={installmentStatusKind(row.status)} label={t(STATUS_LABEL_KEY[row.status])} />
|
||||
) : null}
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Paper>
|
||||
);
|
||||
};
|
||||
|
||||
export default InstallmentScheduleRow;
|
||||
Reference in New Issue
Block a user