218 lines
7.7 KiB
TypeScript
218 lines
7.7 KiB
TypeScript
'use client';
|
|
|
|
import { deleteCookie } from 'cookies-next';
|
|
import { format } from 'date-fns';
|
|
import { ArrowUpRight, Clock, CreditCard, LogOut, User } from 'lucide-react';
|
|
import { useEffect, useState } from 'react';
|
|
|
|
import {
|
|
useFetchBonusTransactionsQuery,
|
|
useFetchMyBonusInfoQuery,
|
|
} from '@/entities/bonus/api/bonus.api';
|
|
import { BonusTransactionRequest } from '@/entities/bonus/model/types/bonus-transactions.type';
|
|
|
|
import Loader from '@/shared/components/loader';
|
|
import { useTextController } from '@/shared/language/hooks/use-text-controller';
|
|
import { Button } from '@/shared/shadcn-ui/button';
|
|
import {
|
|
Card,
|
|
CardContent,
|
|
CardDescription,
|
|
CardHeader,
|
|
CardTitle,
|
|
} from '@/shared/shadcn-ui/card';
|
|
import { TableCell, TableHead, TableRow } from '@/shared/shadcn-ui/table';
|
|
|
|
import { TransactionsTable } from '@/widgets/transactions-table';
|
|
|
|
export function CustomerDashboard() {
|
|
const { t } = useTextController();
|
|
|
|
const [request, setTransactionFetchRequest] =
|
|
useState<BonusTransactionRequest>({
|
|
limit: 10,
|
|
page: 1,
|
|
});
|
|
|
|
const { data, isLoading } = useFetchMyBonusInfoQuery({});
|
|
|
|
const {
|
|
data: transactionsResponse,
|
|
refetch,
|
|
isFetching: isTransactionLoading,
|
|
} = useFetchBonusTransactionsQuery(request);
|
|
|
|
useEffect(() => {
|
|
refetch();
|
|
}, [request]);
|
|
|
|
return (
|
|
<div className='flex min-h-screen flex-col px-2.5'>
|
|
<main className='flex-1 py-10'>
|
|
<div className='container mx-auto max-w-6xl'>
|
|
<div className='mb-8 flex items-center justify-between'>
|
|
<h1 className='text-3xl font-bold'>{t('customer.pageTitle')}</h1>
|
|
<Button
|
|
variant='outline'
|
|
className='gap-2'
|
|
onClick={() => {
|
|
deleteCookie(`bonus__token`);
|
|
window.location.reload();
|
|
}}
|
|
>
|
|
<LogOut className='h-4 w-4' />
|
|
{t('customer.logoutButton')}
|
|
</Button>
|
|
</div>
|
|
|
|
<div className='mb-10 grid gap-3 md:grid-cols-3 md:gap-6'>
|
|
<Card
|
|
data-aos='zoom-in'
|
|
data-aos-mirror='true'
|
|
className='bg-gradient-to-br from-red-600 to-red-800 text-white'
|
|
>
|
|
{!data || isLoading ? (
|
|
<Loader />
|
|
) : (
|
|
<>
|
|
<CardHeader>
|
|
<CardTitle className='flex items-center gap-2'>
|
|
<CreditCard className='h-5 w-5' />
|
|
{t('customer.bonusCard.title')}
|
|
</CardTitle>
|
|
<CardDescription className='text-white/80'>
|
|
{t('customer.bonusCard.description')}
|
|
</CardDescription>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className='text-center'>
|
|
<p className='mb-2 text-4xl font-bold'>{data.bonuses}</p>
|
|
<p className='text-white/80'>
|
|
{t('customer.bonusCard.points')}
|
|
</p>
|
|
</div>
|
|
<div className='mt-6 flex items-center justify-between'>
|
|
<div className='flex items-center gap-1 text-sm text-white/80'>
|
|
<Clock className='h-4 w-4' />
|
|
<span>
|
|
{t('customer.bonusCard.validUntil')}{' '}
|
|
{new Date(data.end_date).toLocaleDateString('en-GB')}
|
|
</span>
|
|
</div>
|
|
<ArrowUpRight className='h-5 w-5 text-white/60' />
|
|
</div>
|
|
</CardContent>
|
|
</>
|
|
)}
|
|
</Card>
|
|
|
|
{/* Bonus Card */}
|
|
{/* Customer Card */}
|
|
<Card
|
|
data-aos='zoom-in'
|
|
data-aos-mirror='true'
|
|
className='md:col-span-2'
|
|
>
|
|
<CardHeader className='pb-2'>
|
|
<CardTitle className='flex items-center gap-2'>
|
|
<User className='h-5 w-5 text-red-600' />
|
|
{t('customer.infoCard.title')}
|
|
</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
{!data || isLoading ? (
|
|
<Loader />
|
|
) : (
|
|
<div className='grid gap-6 md:grid-cols-2'>
|
|
<div>
|
|
<div className='mb-4 space-y-1'>
|
|
<p className='text-sm text-gray-500'>
|
|
{t('customer.infoCard.regDateLabel')}
|
|
</p>
|
|
<p className='font-medium'>{data.fullname}</p>
|
|
</div>
|
|
<div className='space-y-1'>
|
|
<p className='text-sm text-gray-500'>
|
|
{t('customer.infoCard.regDateLabel')}
|
|
</p>
|
|
<p className='font-medium'>
|
|
{new Date(data.reg_date).toLocaleDateString('en-GB')}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<div className='mb-4 space-y-1'>
|
|
<p className='text-sm text-gray-500'>
|
|
{t('customer.infoCard.cardNumberLabel')}
|
|
</p>
|
|
<p className='font-medium'>{data.cardno}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
|
|
<TransactionsTable
|
|
isLoading={isTransactionLoading}
|
|
data={
|
|
transactionsResponse || {
|
|
limit: 10,
|
|
current_page: 1,
|
|
total_pages: 0,
|
|
total_records: 0,
|
|
transactions: [],
|
|
}
|
|
}
|
|
renderHeaders={() => (
|
|
<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>
|
|
)}
|
|
renderRow={(transaction) => (
|
|
<TableRow key={transaction.id}>
|
|
<TableCell>
|
|
{format(
|
|
new Date(transaction.date_create),
|
|
'dd.MM.yyyy HH:mm',
|
|
)}
|
|
</TableCell>
|
|
<TableCell>{transaction.station}</TableCell>
|
|
<TableCell>{transaction.product_name}</TableCell>
|
|
<TableCell className='text-right'>
|
|
{transaction.amount}
|
|
</TableCell>
|
|
<TableCell className='text-right'>
|
|
{transaction.price_real} {t('corporate.currency')}
|
|
</TableCell>
|
|
<TableCell className='text-right font-medium'>
|
|
{transaction.sum_real} {t('corporate.currency')}
|
|
</TableCell>
|
|
</TableRow>
|
|
)}
|
|
onChange={setTransactionFetchRequest}
|
|
/>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
);
|
|
}
|