oriyo_next/src/widgets/transactions-table.tsx

238 lines
7.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use client';
import { format, subMonths } from 'date-fns';
import { ru } from 'date-fns/locale';
import { CalendarIcon } from 'lucide-react';
import { useState } from 'react';
import { useTextController } from '@/shared/language/hooks/use-text-controller';
import { Button } from '@/shared/shadcn-ui/button';
import { Calendar } from '@/shared/shadcn-ui/calendar';
import { Label } from '@/shared/shadcn-ui/label';
import {
Popover,
PopoverContent,
PopoverTrigger,
} from '@/shared/shadcn-ui/popover';
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '@/shared/shadcn-ui/table';
// Sample customer data
const customerData = {
firstName: 'Алишер',
lastName: 'Рахмонов',
passportNumber: 'A12345678',
bonusPoints: 1250,
cardNumber: '5678-9012-3456-7890',
expiryDate: '12/2025',
registrationDate: '15.06.2020',
};
// Sample transaction data
const generateTransactions = () => {
const stations = [
'АЗС Душанбе-Центр',
'АЗС Душанбе-Запад',
'АЗС Душанбе-Восток',
'АЗС Худжанд',
'АЗС Куляб',
];
const products = [
{ name: 'ДТ', price: 8.5 },
{ name: 'АИ-92', price: 9.2 },
{ name: 'АИ-95', price: 10.5 },
{ name: 'Z-100 Power', price: 11.8 },
{ name: 'Пропан', price: 6.3 },
];
const transactions = [];
// Generate 50 random transactions over the last 6 months
for (let i = 0; i < 50; i++) {
const date = subMonths(new Date(), Math.random() * 6);
const station = stations[Math.floor(Math.random() * stations.length)];
const product = products[Math.floor(Math.random() * products.length)];
const quantity = Math.floor(Math.random() * 40) + 10; // 10-50 liters
const cost = product.price;
const total = quantity * cost;
transactions.push({
id: i + 1,
date,
station,
product: product.name,
quantity,
cost,
total,
});
}
// Sort by date (newest first)
return transactions.sort((a, b) => b.date.getTime() - a.date.getTime());
};
const transactions = generateTransactions();
export const TransactionsTable = () => {
const [startDate, setStartDate] = useState<Date | undefined>(
subMonths(new Date(), 1),
);
const [endDate, setEndDate] = useState<Date | undefined>(new Date());
const [filteredTransactions, setFilteredTransactions] =
useState(transactions);
// Filter transactions by date range
const filterTransactions = () => {
if (!startDate || !endDate) return;
const filtered = transactions.filter((transaction) => {
const transactionDate = new Date(transaction.date);
return transactionDate >= startDate && transactionDate <= endDate;
});
setFilteredTransactions(filtered);
};
const { t } = useTextController();
return (
<div className='space-y-6'>
<div className='flex flex-col items-start justify-between gap-4 md:flex-row md:items-center'>
<h2 className='text-2xl font-bold'>
{t('corporate.transactions.title')}
</h2>
<div className='flex w-full flex-col gap-4 md:w-auto md:flex-row'>
<div className='grid sm:grid-cols-2 gap-2'>
<div className='flex items-center gap-2'>
<Label htmlFor='start-date'>
{t('corporate.transactions.dateFrom')}
</Label>
<Popover>
<PopoverTrigger asChild>
<Button
variant='outline'
className='w-full justify-start text-left font-normal'
>
<CalendarIcon className='mr-2 h-4 w-4' />
{startDate
? format(startDate, 'PP', { locale: ru })
: 'Выберите дату'}
</Button>
</PopoverTrigger>
<PopoverContent className='w-auto p-0'>
<Calendar
mode='single'
selected={startDate}
onSelect={setStartDate}
initialFocus
/>
</PopoverContent>
</Popover>
</div>
<div className='flex items-center gap-2'>
<Label htmlFor='end-date'>
{t('corporate.transactions.dateTo')}
</Label>
<Popover>
<PopoverTrigger asChild>
<Button
variant='outline'
className='w-full justify-start text-left font-normal'
>
<CalendarIcon className='mr-2 h-4 w-4' />
{endDate
? format(endDate, 'PP', { locale: ru })
: t('corporate.transactions.selectDate')}
</Button>
</PopoverTrigger>
<PopoverContent className='w-auto p-0'>
<Calendar
mode='single'
selected={endDate}
onSelect={setEndDate}
initialFocus
/>
</PopoverContent>
</Popover>
</div>
</div>
<Button
className='mt-auto bg-red-600 hover:bg-red-700'
onClick={filterTransactions}
>
{t('corporate.transactions.applyButton')}
</Button>
</div>
</div>
<div className='rounded-md border'>
<Table>
<TableHeader>
<TableRow>
<TableHead>
{t('corporate.transactions.tableHeaders.date')}
</TableHead>
<TableHead>
{t('corporate.transactions.tableHeaders.station')}
</TableHead>
<TableHead>
{t('corporate.transactions.tableHeaders.product')}
</TableHead>
<TableHead className='text-right'>
{t('corporate.transactions.tableHeaders.quantity')}
</TableHead>
<TableHead className='text-right'>
{t('corporate.transactions.tableHeaders.price')}
</TableHead>
<TableHead className='text-right'>
{t('corporate.transactions.tableHeaders.total')}
</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{filteredTransactions.length > 0 ? (
filteredTransactions.map((transaction) => (
<TableRow key={transaction.id}>
<TableCell>
{format(transaction.date, 'dd.MM.yyyy')}
</TableCell>
<TableCell>{transaction.station}</TableCell>
<TableCell>{transaction.product}</TableCell>
<TableCell className='text-right'>
{transaction.quantity}
</TableCell>
<TableCell className='text-right'>
{transaction.cost.toFixed(2)} {t('corporate.currency')}
</TableCell>
<TableCell className='text-right font-medium'>
{transaction.total.toFixed(2)} {t('corporate.currency')}
</TableCell>
</TableRow>
))
) : (
<TableRow>
<TableCell
colSpan={6}
className='py-6 text-center text-gray-500'
>
{t('corporate.transactions.noTransactions')}
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</div>
</div>
);
};