oriyo_next/src/widgets/transactions-table.tsx
2025-04-27 01:43:05 +05:00

217 lines
6.9 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 { 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);
};
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'>История операций</h2>
<div className='flex w-full flex-col gap-4 md:w-auto md:flex-row'>
<div className='grid grid-cols-2 gap-2'>
<div className='flex items-center gap-2'>
<Label htmlFor='start-date'>От</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'>До</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 })
: 'Выберите дату'}
</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}
>
Применить
</Button>
</div>
</div>
<div className='rounded-md border'>
<Table>
<TableHeader>
<TableRow>
<TableHead>Дата</TableHead>
<TableHead>Станция</TableHead>
<TableHead>Продукт</TableHead>
<TableHead className='text-right'>Кол-во (л)</TableHead>
<TableHead className='text-right'>Стоимость</TableHead>
<TableHead className='text-right'>Сумма</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)} сомони
</TableCell>
<TableCell className='text-right font-medium'>
{transaction.total.toFixed(2)} сомони
</TableCell>
</TableRow>
))
) : (
<TableRow>
<TableCell
colSpan={6}
className='py-6 text-center text-gray-500'
>
Нет операций за выбранный период
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</div>
</div>
);
};