Files
HKSingleParty/03_source/frontend/src/sections/invoice/invoice-details.tsx

222 lines
6.5 KiB
TypeScript

import type { IInvoiceItem } from 'src/types/invoice';
import { useState, useCallback } from 'react';
import Box from '@mui/material/Box';
import Card from '@mui/material/Card';
import Table from '@mui/material/Table';
import Stack from '@mui/material/Stack';
import Divider from '@mui/material/Divider';
import TableRow from '@mui/material/TableRow';
import TableHead from '@mui/material/TableHead';
import TableBody from '@mui/material/TableBody';
import TableCell from '@mui/material/TableCell';
import Typography from '@mui/material/Typography';
import { fDate } from 'src/utils/format-time';
import { fCurrency } from 'src/utils/format-number';
import { INVOICE_STATUS_OPTIONS } from 'src/_mock';
import { Label } from 'src/components/label';
import { Scrollbar } from 'src/components/scrollbar';
import { InvoiceToolbar } from './invoice-toolbar';
import { InvoiceTotalSummary } from './invoice-total-summary';
import { useTranslation } from 'react-i18next';
import { changeStatus } from 'src/actions/invoice';
import { toast } from 'src/components/snackbar';
// ----------------------------------------------------------------------
type Props = {
invoice: IInvoiceItem;
};
export function InvoiceDetails({ invoice }: Props) {
const { t } = useTranslation();
const [currentStatus, setCurrentStatus] = useState(invoice?.status);
const handleChangeStatus = useCallback(
(event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
// setCurrentStatus(event.target.value);
try {
changeStatus(invoice.id, event.target.value);
setCurrentStatus(event.target.value);
toast.success('status changed!');
} catch (error) {
console.error(error);
toast.warning('error during changing status');
}
},
[]
);
const renderFooter = () => (
<Box
sx={{
py: 3,
gap: 2,
display: 'flex',
flexWrap: 'wrap',
alignItems: 'center',
}}
>
<div>
<Typography variant="subtitle2" sx={{ mb: 0.5 }}>
NOTES
</Typography>
<Typography variant="body2">
We appreciate your business. Should you need us to add VAT or extra notes let us know!
</Typography>
</div>
<Box sx={{ flexGrow: { md: 1 }, textAlign: { md: 'right' } }}>
<Typography variant="subtitle2" sx={{ mb: 0.5 }}>
Have a question?
</Typography>
<Typography variant="body2">support@minimals.cc</Typography>
</Box>
</Box>
);
const renderList = () => (
<Scrollbar sx={{ mt: 5 }}>
<Table sx={{ minWidth: 960 }}>
<TableHead>
<TableRow>
<TableCell width={40}>#</TableCell>
<TableCell sx={{ typography: 'subtitle2' }}>Description</TableCell>
<TableCell>Qty</TableCell>
<TableCell align="right">Unit price</TableCell>
<TableCell align="right">Total</TableCell>
</TableRow>
</TableHead>
<TableBody>
{invoice?.items.map((row, index) => (
<TableRow key={index}>
<TableCell>{index + 1}</TableCell>
<TableCell>
<Box sx={{ maxWidth: 560 }}>
<Typography variant="subtitle2">{row.title}</Typography>
<Typography variant="body2" sx={{ color: 'text.secondary' }} noWrap>
{row.description}
</Typography>
</Box>
</TableCell>
<TableCell>{row.quantity}</TableCell>
<TableCell align="right">{fCurrency(row.price)}</TableCell>
<TableCell align="right">{fCurrency(row.price * row.quantity)}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Scrollbar>
);
return (
<>
<InvoiceToolbar
invoice={invoice}
currentStatus={currentStatus || ''}
onChangeStatus={handleChangeStatus}
statusOptions={INVOICE_STATUS_OPTIONS}
/>
<Card sx={{ pt: 5, px: 5 }}>
<Box
sx={{
rowGap: 5,
display: 'grid',
alignItems: 'center',
gridTemplateColumns: { xs: 'repeat(1, 1fr)', sm: 'repeat(2, 1fr)' },
}}
>
<Box
component="img"
alt="Invoice logo"
src="/logo/logo-single.svg"
sx={{ width: 48, height: 48 }}
/>
<Stack spacing={1} sx={{ alignItems: { xs: 'flex-start', md: 'flex-end' } }}>
<Label
variant="soft"
color={
(currentStatus === 'paid' && 'success') ||
(currentStatus === 'pending' && 'warning') ||
(currentStatus === 'overdue' && 'error') ||
'default'
}
>
{currentStatus}
</Label>
<Typography variant="h6">{invoice?.invoiceNumber}</Typography>
</Stack>
<Stack sx={{ typography: 'body2' }}>
<Typography variant="subtitle2" sx={{ mb: 1 }}>
Invoice from
</Typography>
{invoice?.invoiceFrom.name}
<br />
{invoice?.invoiceFrom.fullAddress}
<br />
Phone: {invoice?.invoiceFrom.phoneNumber}
<br />
</Stack>
<Stack sx={{ typography: 'body2' }}>
<Typography variant="subtitle2" sx={{ mb: 1 }}>
Invoice to
</Typography>
{invoice?.invoiceTo.name}
<br />
{invoice?.invoiceTo.fullAddress}
<br />
Phone: {invoice?.invoiceTo.phoneNumber}
<br />
</Stack>
<Stack sx={{ typography: 'body2' }}>
<Typography variant="subtitle2" sx={{ mb: 1 }}>
Date create
</Typography>
{fDate(invoice?.createDate)}
</Stack>
<Stack sx={{ typography: 'body2' }}>
<Typography variant="subtitle2" sx={{ mb: 1 }}>
Due date
</Typography>
{fDate(invoice?.dueDate)}
</Stack>
</Box>
{renderList()}
<Divider sx={{ borderStyle: 'dashed' }} />
<InvoiceTotalSummary
taxes={invoice?.taxes}
subtotal={invoice?.subtotal}
discount={invoice?.discount}
shipping={invoice?.shipping}
totalAmount={invoice?.totalAmount}
/>
<Divider sx={{ mt: 5, borderStyle: 'dashed' }} />
{renderFooter()}
</Card>
</>
);
}