Merge branch 'dev' into feat-auth

This commit is contained in:
BunyodL 2025-04-28 21:48:22 +05:00
commit a78467947d
47 changed files with 2943 additions and 1719 deletions

View File

@ -16,6 +16,7 @@
"@radix-ui/react-dropdown-menu": "^2.1.11",
"@radix-ui/react-label": "^2.1.4",
"@radix-ui/react-navigation-menu": "^1.2.10",
"@radix-ui/react-popover": "^1.1.11",
"@radix-ui/react-select": "^2.2.2",
"@radix-ui/react-slot": "^1.2.0",
"@radix-ui/react-tabs": "^1.1.8",
@ -24,18 +25,21 @@
"aos": "^2.3.4",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"date-fns": "^4.1.0",
"embla-carousel-autoplay": "^8.6.0",
"embla-carousel-react": "^8.6.0",
"lucide-react": "^0.501.0",
"next": "15.3.1",
"next-themes": "^0.4.6",
"react": "^19.0.0",
"react-day-picker": "8.10.1",
"react-dom": "^19.0.0",
"react-hook-form": "^7.56.1",
"react-redux": "^9.2.0",
"sonner": "^2.0.3",
"tailwind-merge": "^3.2.0",
"tailwindcss-animate": "^1.0.7",
"tailwindcss-animated": "^2.0.0",
"tw-animate-css": "^1.2.6",
"zod": "^3.24.3"
},

73
pnpm-lock.yaml generated
View File

@ -26,6 +26,9 @@ importers:
'@radix-ui/react-navigation-menu':
specifier: ^1.2.10
version: 1.2.10(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
'@radix-ui/react-popover':
specifier: ^1.1.11
version: 1.1.11(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
'@radix-ui/react-select':
specifier: ^2.2.2
version: 2.2.2(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
@ -50,6 +53,9 @@ importers:
clsx:
specifier: ^2.1.1
version: 2.1.1
date-fns:
specifier: ^4.1.0
version: 4.1.0
embla-carousel-autoplay:
specifier: ^8.6.0
version: 8.6.0(embla-carousel@8.6.0)
@ -68,6 +74,9 @@ importers:
react:
specifier: ^19.0.0
version: 19.1.0
react-day-picker:
specifier: 8.10.1
version: 8.10.1(date-fns@4.1.0)(react@19.1.0)
react-dom:
specifier: ^19.0.0
version: 19.1.0(react@19.1.0)
@ -86,6 +95,9 @@ importers:
tailwindcss-animate:
specifier: ^1.0.7
version: 1.0.7(tailwindcss@4.1.4)
tailwindcss-animated:
specifier: ^2.0.0
version: 2.0.0(tailwindcss@4.1.4)
tw-animate-css:
specifier: ^1.2.6
version: 1.2.6
@ -681,6 +693,19 @@ packages:
'@types/react-dom':
optional: true
'@radix-ui/react-popover@1.1.11':
resolution: {integrity: sha512-yFMfZkVA5G3GJnBgb2PxrrcLKm1ZLWXrbYVgdyTl//0TYEIHS9LJbnyz7WWcZ0qCq7hIlJZpRtxeSeIG5T5oJw==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
peerDependenciesMeta:
'@types/react':
optional: true
'@types/react-dom':
optional: true
'@radix-ui/react-popper@1.2.4':
resolution: {integrity: sha512-3p2Rgm/a1cK0r/UVkx5F/K9v/EplfjAeIFCGOPYPO4lZ0jtg4iSQXt/YGTSLWaf4x7NG6Z4+uKFcylcTZjeqDA==}
peerDependencies:
@ -1370,6 +1395,9 @@ packages:
resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==}
engines: {node: '>= 0.4'}
date-fns@4.1.0:
resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==}
debug@3.2.7:
resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
peerDependencies:
@ -2261,6 +2289,12 @@ packages:
queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
react-day-picker@8.10.1:
resolution: {integrity: sha512-TMx7fNbhLk15eqcMt+7Z7S2KF7mfTId/XJDjKE8f+IUcFn0l08/kI4FiYTL/0yuOLmEcbR4Fwe3GJf/NiiMnPA==}
peerDependencies:
date-fns: ^2.28.0 || ^3.0.0
react: ^16.8.0 || ^17.0.0 || ^18.0.0
react-dom@19.1.0:
resolution: {integrity: sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==}
peerDependencies:
@ -2507,6 +2541,11 @@ packages:
peerDependencies:
tailwindcss: '>=3.0.0 || insiders'
tailwindcss-animated@2.0.0:
resolution: {integrity: sha512-anNNGpxNgjydD8p1lcJjxxH+XbjW6KR8Xs29owTrbcf3tOJ6IRblpyFob43HBkfxFJJTAfFQqugoEG2b1EsR0A==}
peerDependencies:
tailwindcss: '>=3.1.0 || >=4.0.0'
tailwindcss@4.1.4:
resolution: {integrity: sha512-1ZIUqtPITFbv/DxRmDr5/agPqJwF69d24m9qmM1939TJehgY539CtzeZRjbLt5G6fSy/7YqqYsfvoTEw9xUI2A==}
@ -3121,6 +3160,29 @@ snapshots:
'@types/react': 19.1.2
'@types/react-dom': 19.1.2(@types/react@19.1.2)
'@radix-ui/react-popover@1.1.11(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)':
dependencies:
'@radix-ui/primitive': 1.1.2
'@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0)
'@radix-ui/react-context': 1.1.2(@types/react@19.1.2)(react@19.1.0)
'@radix-ui/react-dismissable-layer': 1.1.7(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
'@radix-ui/react-focus-guards': 1.1.2(@types/react@19.1.2)(react@19.1.0)
'@radix-ui/react-focus-scope': 1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
'@radix-ui/react-id': 1.1.1(@types/react@19.1.2)(react@19.1.0)
'@radix-ui/react-popper': 1.2.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
'@radix-ui/react-portal': 1.1.6(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
'@radix-ui/react-presence': 1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
'@radix-ui/react-primitive': 2.1.0(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
'@radix-ui/react-slot': 1.2.0(@types/react@19.1.2)(react@19.1.0)
'@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.2)(react@19.1.0)
aria-hidden: 1.2.4
react: 19.1.0
react-dom: 19.1.0(react@19.1.0)
react-remove-scroll: 2.6.3(@types/react@19.1.2)(react@19.1.0)
optionalDependencies:
'@types/react': 19.1.2
'@types/react-dom': 19.1.2(@types/react@19.1.2)
'@radix-ui/react-popper@1.2.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)':
dependencies:
'@floating-ui/react-dom': 2.1.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
@ -3814,6 +3876,8 @@ snapshots:
es-errors: 1.3.0
is-data-view: 1.0.2
date-fns@4.1.0: {}
debug@3.2.7:
dependencies:
ms: 2.1.3
@ -4782,6 +4846,11 @@ snapshots:
queue-microtask@1.2.3: {}
react-day-picker@8.10.1(date-fns@4.1.0)(react@19.1.0):
dependencies:
date-fns: 4.1.0
react: 19.1.0
react-dom@19.1.0(react@19.1.0):
dependencies:
react: 19.1.0
@ -5077,6 +5146,10 @@ snapshots:
dependencies:
tailwindcss: 4.1.4
tailwindcss-animated@2.0.0(tailwindcss@4.1.4):
dependencies:
tailwindcss: 4.1.4
tailwindcss@4.1.4: {}
tapable@2.2.1: {}

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

BIN
public/oriyo_bg.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

View File

@ -0,0 +1,308 @@
'use client';
import { format, subMonths } from 'date-fns';
import { ru } from 'date-fns/locale';
import { Building2, CalendarIcon, LogOut, Wallet } from 'lucide-react';
import { useState } from 'react';
import { Button } from '@/shared/shadcn-ui/button';
import { Calendar } from '@/shared/shadcn-ui/calendar';
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from '@/shared/shadcn-ui/card';
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';
// import { CardsList } from '@/widgets/cards-list';
// Sample company data
const companyData = {
companyName: 'ООО «ТаджикТранс»',
numberOfCards: 12,
fund: 25000,
overdraft: 5000,
totalFund: 30000,
registrationDate: '10.03.2019',
};
// 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 default function CorporateDashboard() {
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='flex min-h-screen flex-col'>
<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'>Корпоративный кабинет</h1>
<Button variant='outline' className='gap-2'>
<LogOut className='h-4 w-4' />
Выйти
</Button>
</div>
<div className='mb-10 grid gap-3 md:grid-cols-3 md:gap-6'>
{/* Company Card */}
<Card className='md:col-span-2'>
<CardHeader className='pb-2'>
<CardTitle className='flex items-center gap-2'>
<Building2 className='h-5 w-5 text-red-600' />
Информация о компании
</CardTitle>
</CardHeader>
<CardContent>
<div className='grid gap-6 md:grid-cols-2'>
<div>
<div className='mb-4 space-y-1'>
<p className='text-sm text-gray-500'>Название компании</p>
<p className='font-medium'>{companyData.companyName}</p>
</div>
<div className='mb-4 space-y-1'>
<p className='text-sm text-gray-500'>Количество карт</p>
<p className='font-medium'>{companyData.numberOfCards}</p>
</div>
<div className='space-y-1'>
<p className='text-sm text-gray-500'>Дата регистрации</p>
<p className='font-medium'>
{companyData.registrationDate}
</p>
</div>
</div>
<div>
<div className='mb-4 space-y-1'>
<p className='text-sm text-gray-500'>Фонд</p>
<p className='font-medium'>
{companyData.fund.toLocaleString()} сомони
</p>
</div>
<div className='mb-4 space-y-1'>
<p className='text-sm text-gray-500'>Овердрафт</p>
<p className='font-medium'>
{companyData.overdraft.toLocaleString()} сомони
</p>
</div>
</div>
</div>
</CardContent>
</Card>
{/* Fund Card */}
<Card className='bg-gradient-to-br from-red-600 to-red-800 text-white'>
<CardHeader>
<CardTitle className='flex items-center gap-2'>
<Wallet className='h-5 w-5' />
Общий фонд
</CardTitle>
<CardDescription className='text-white/80'>
Доступные средства
</CardDescription>
</CardHeader>
<CardContent>
<div className='text-center'>
<p className='mb-2 text-4xl font-bold'>
{companyData.totalFund.toLocaleString()}
</p>
<p className='text-white/80'>сомони</p>
</div>
</CardContent>
</Card>
</div>
{/* <CardsList totalCards={companyData.numberOfCards} /> */}
{/* Transactions */}
<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>
</div>
</main>
</div>
);
}

View File

@ -0,0 +1,110 @@
import { ArrowUpRight, Clock, CreditCard, LogOut, User } from 'lucide-react';
import { Button } from '@/shared/shadcn-ui/button';
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from '@/shared/shadcn-ui/card';
import { TransactionsTable } from '@/widgets/transactions-table';
// Sample customer data
const customerData = {
firstName: 'Алишер',
lastName: 'Рахмонов',
passportNumber: 'A12345678',
bonusPoints: 1250,
cardNumber: '5678-9012-3456-7890',
expiryDate: '12/2025',
registrationDate: '15.06.2020',
};
export default function CustomerDashboard() {
return (
<div className='flex min-h-screen flex-col'>
<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'>Личный кабинет</h1>
<Button variant='outline' className='gap-2'>
<LogOut className='h-4 w-4' />
Выйти
</Button>
</div>
<div className='mb-10 grid gap-3 md:grid-cols-3 md:gap-6'>
{/* Bonus Card */}
<Card className='bg-gradient-to-br from-red-600 to-red-800 text-white'>
<CardHeader>
<CardTitle className='flex items-center gap-2'>
<CreditCard className='h-5 w-5' />
Бонусная карта
</CardTitle>
<CardDescription className='text-white/80'>
Ваши накопленные бонусы
</CardDescription>
</CardHeader>
<CardContent>
<div className='text-center'>
<p className='mb-2 text-4xl font-bold'>
{customerData.bonusPoints}
</p>
<p className='text-white/80'>бонусных баллов</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>Действует до: 31.12.2023</span>
</div>
<ArrowUpRight className='h-5 w-5 text-white/60' />
</div>
</CardContent>
</Card>
{/* Customer Card */}
<Card 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' />
Информация о клиенте
</CardTitle>
</CardHeader>
<CardContent>
<div className='grid gap-6 md:grid-cols-2'>
<div>
<div className='mb-4 space-y-1'>
<p className='text-sm text-gray-500'>ФИО</p>
<p className='font-medium'>
{customerData.firstName} {customerData.lastName}
</p>
</div>
<div className='space-y-1'>
<p className='text-sm text-gray-500'>Дата регистрации</p>
<p className='font-medium'>
{customerData.registrationDate}
</p>
</div>
</div>
<div>
<div className='mb-4 space-y-1'>
<p className='text-sm text-gray-500'>Номер карты</p>
<p className='font-medium'>{customerData.cardNumber}</p>
</div>
<div className='mb-4 space-y-1'>
<p className='text-sm text-gray-500'>Срок действия</p>
<p className='font-medium'>{customerData.expiryDate}</p>
</div>
</div>
</div>
</CardContent>
</Card>
</div>
<TransactionsTable />
</div>
</main>
</div>
);
}

View File

@ -1,404 +1,5 @@
import {
Award,
Fuel,
History,
MapPin,
Star,
Target,
Users,
} from 'lucide-react';
import Image from 'next/image';
import AboutPage from "@/pages-templates/about";
import AnimatedCounter from '@/shared/components/animated-counter';
import { Button } from '@/shared/shadcn-ui/button';
import { Card, CardContent } from '@/shared/shadcn-ui/card';
import { CompanyTimeline } from '@/widgets/about-page/company-timeline';
import { StationGallery } from '@/widgets/about-page/station-gallery';
import { CtaSection } from '@/widgets/cta-section';
export const metadata = {
title: 'О нас | GasNetwork - Сеть заправок в Таджикистане',
description:
'Узнайте больше о нашей компании, истории и ценностях. Качественное топливо и отличный сервис.',
};
export default function AboutPage() {
return (
<div className='flex min-h-screen flex-col'>
<main className='flex-1'>
{/* Hero Section */}
<section className='relative'>
<div className='relative h-[400px] w-full overflow-hidden'>
<Image
src='/placeholder.svg?height=400&width=1920&text=Наша+История'
alt='О нашей компании'
width={1920}
height={400}
className='object-cover'
priority
/>
<div className='absolute inset-0 flex items-center bg-gradient-to-r from-black/70 to-black/30'>
<div className='container mx-auto'>
<div className='max-w-2xl space-y-4 text-white'>
<h1 className='text-4xl font-bold tracking-tight sm:text-5xl md:text-6xl'>
О нашей компании
</h1>
<p className='text-lg text-gray-200'>
Узнайте больше о нашей истории, ценностях и миссии. Мы
стремимся предоставлять лучший сервис и качественное топливо
для наших клиентов.
</p>
</div>
</div>
</div>
</div>
</section>
{/* Company Overview */}
<section className='py-16'>
<div className='container mx-auto'>
<div className='grid items-center gap-12 md:grid-cols-2'>
<div>
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
<Fuel className='h-6 w-6 text-red-600' />
</div>
<h2 className='mb-6 text-3xl font-bold tracking-tight sm:text-4xl'>
Лидер на рынке Таджикистана
</h2>
<p className='mb-6 text-gray-600'>
GasNetwork - ведущая сеть автозаправочных станций в
Таджикистане, предоставляющая высококачественное топливо и
превосходный сервис. Наша компания была основана в 2008 году и
с тех пор стала символом надежности и качества в
энергетическом секторе страны.
</p>
<p className='mb-6 text-gray-600'>
Мы гордимся тем, что предлагаем нашим клиентам только лучшее
топливо, соответствующее международным стандартам качества.
Наши заправочные станции оснащены современным оборудованием,
которое обеспечивает быстрое и безопасное обслуживание.
</p>
<p className='mb-6 text-gray-600'>
Наша миссия - сделать поездки наших клиентов комфортными и
безопасными, предоставляя качественное топливо и отличный
сервис по всей стране.
</p>
<div className='mb-6 grid grid-cols-2 gap-4'>
<div className='flex items-start'>
<div className='mt-1 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-red-600'>
<span className='text-xs text-white'></span>
</div>
<div className='ml-3'>
<h3 className='text-lg font-medium'>Качество</h3>
<p className='text-gray-600'>Топливо высшего стандарта</p>
</div>
</div>
<div className='flex items-start'>
<div className='mt-1 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-red-600'>
<span className='text-xs text-white'></span>
</div>
<div className='ml-3'>
<h3 className='text-lg font-medium'>Сервис</h3>
<p className='text-gray-600'>
Профессиональное обслуживание
</p>
</div>
</div>
<div className='flex items-start'>
<div className='mt-1 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-red-600'>
<span className='text-xs text-white'></span>
</div>
<div className='ml-3'>
<h3 className='text-lg font-medium'>Инновации</h3>
<p className='text-gray-600'>Современные технологии</p>
</div>
</div>
<div className='flex items-start'>
<div className='mt-1 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-red-600'>
<span className='text-xs text-white'></span>
</div>
<div className='ml-3'>
<h3 className='text-lg font-medium'>Доступность</h3>
<p className='text-gray-600'>Станции по всей стране</p>
</div>
</div>
</div>
</div>
<div className='relative h-[500px] overflow-hidden rounded-xl shadow-xl'>
<Image
src='/placeholder.svg?height=500&width=600&text=Главный+офис'
alt='Главный офис GasNetwork'
fill
className='object-cover'
/>
</div>
</div>
</div>
</section>
{/* Stats Section */}
<section className='bg-red-600 py-16 text-white'>
<div className='container mx-auto'>
<div className='mb-12 text-center'>
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
GasNetwork в цифрах
</h2>
<p className='mx-auto max-w-2xl text-white/80'>
Наши достижения и рост за годы работы на рынке Таджикистана
</p>
</div>
<div className='grid grid-cols-2 gap-8 text-center md:grid-cols-4'>
<div className='space-y-2'>
<h3 className='text-4xl font-bold'>
<AnimatedCounter end={25} suffix='+' />
</h3>
<p className='text-sm text-white/80'>Заправок по стране</p>
</div>
<div className='space-y-2'>
<h3 className='text-4xl font-bold'>
<AnimatedCounter end={15} />
</h3>
<p className='text-sm text-white/80'>Лет на рынке</p>
</div>
<div className='space-y-2'>
<h3 className='text-4xl font-bold'>
<AnimatedCounter end={150} suffix='+' />
</h3>
<p className='text-sm text-white/80'>Сотрудников</p>
</div>
<div className='space-y-2'>
<h3 className='text-4xl font-bold'>
<AnimatedCounter end={1000000} suffix='+' />
</h3>
<p className='text-sm text-white/80'>Клиентов в год</p>
</div>
</div>
</div>
</section>
{/* Our History */}
<section className='py-16'>
<div className='container mx-auto'>
<div className='mb-12 flex flex-col items-center justify-center text-center'>
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
<History className='h-6 w-6 text-red-600' />
</div>
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
Наша история
</h2>
<p className='max-w-2xl text-gray-600'>
История развития нашей компании от небольшой сети до лидера
рынка
</p>
</div>
<CompanyTimeline />
</div>
</section>
{/* Our Stations */}
<section className='bg-gray-50 py-16'>
<div className='container mx-auto'>
<div className='mb-12 flex flex-col items-center justify-center text-center'>
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
<MapPin className='h-6 w-6 text-red-600' />
</div>
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
Наши заправочные станции
</h2>
<p className='max-w-2xl text-gray-600'>
Современные заправочные станции, оснащенные по последнему слову
техники
</p>
</div>
<StationGallery />
<div className='mt-12 text-center'>
<p className='mx-auto mb-6 max-w-2xl text-gray-600'>
Наши заправочные станции расположены в стратегически важных
точках по всему Таджикистану, обеспечивая удобный доступ для
всех наших клиентов.
</p>
<Button className='bg-red-600 hover:bg-red-700'>
Найти ближайшую заправку <MapPin className='ml-2 h-4 w-4' />
</Button>
</div>
</div>
</section>
{/* Our Values */}
<section className='py-16'>
<div className='container mx-auto'>
<div className='mb-12 flex flex-col items-center justify-center text-center'>
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
<Target className='h-6 w-6 text-red-600' />
</div>
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
Наши ценности
</h2>
<p className='max-w-2xl text-gray-600'>
Принципы, которыми мы руководствуемся в нашей работе
</p>
</div>
<div className='grid gap-8 md:grid-cols-3'>
<Card className='overflow-hidden transition-all hover:shadow-lg'>
<CardContent className='p-6'>
<div className='mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-red-100'>
<Star className='h-6 w-6 text-red-600' />
</div>
<h3 className='mb-2 text-xl font-bold'>Качество</h3>
<p className='text-gray-600'>
Мы предлагаем только высококачественное топливо,
соответствующее международным стандартам. Регулярные
проверки и контроль качества гарантируют, что наши клиенты
получают лучшее.
</p>
</CardContent>
</Card>
<Card className='overflow-hidden transition-all hover:shadow-lg'>
<CardContent className='p-6'>
<div className='mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-red-100'>
<Users className='h-6 w-6 text-red-600' />
</div>
<h3 className='mb-2 text-xl font-bold'>
Клиентоориентированность
</h3>
<p className='text-gray-600'>
Наши клиенты - наш главный приоритет. Мы стремимся
предоставить лучший сервис, удобные условия и приятную
атмосферу на каждой нашей заправке.
</p>
</CardContent>
</Card>
<Card className='overflow-hidden transition-all hover:shadow-lg'>
<CardContent className='p-6'>
<div className='mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-red-100'>
<Award className='h-6 w-6 text-red-600' />
</div>
<h3 className='mb-2 text-xl font-bold'>Профессионализм</h3>
<p className='text-gray-600'>
Наши сотрудники - профессионалы своего дела. Мы постоянно
инвестируем в их обучение и развитие, чтобы обеспечить
высокий уровень обслуживания.
</p>
</CardContent>
</Card>
</div>
</div>
</section>
{/* Our Team */}
<section className='bg-gray-50 py-16'>
<div className='container mx-auto'>
<div className='mb-12 flex flex-col items-center justify-center text-center'>
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
<Users className='h-6 w-6 text-red-600' />
</div>
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
Наша команда
</h2>
<p className='max-w-2xl text-gray-600'>
Познакомьтесь с профессионалами, которые делают GasNetwork
лучшей сетью заправок в Таджикистане
</p>
</div>
<div className='grid grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-4'>
{[
{ name: 'Алишер Рахмонов', position: 'Генеральный директор' },
{ name: 'Фарида Каримова', position: 'Финансовый директор' },
{ name: 'Рустам Назаров', position: 'Технический директор' },
{ name: 'Зарина Шарипова', position: 'Директор по маркетингу' },
].map((person, index) => (
<div
key={index}
className='overflow-hidden rounded-lg bg-white shadow-md transition-transform hover:scale-105'
>
<div className='relative h-64 w-full'>
<Image
src={`/placeholder.svg?height=300&width=300&text=${person.name}`}
alt={person.name}
fill
className='object-cover'
/>
</div>
<div className='p-4 text-center'>
<h3 className='text-lg font-bold'>{person.name}</h3>
<p className='text-gray-600'>{person.position}</p>
</div>
</div>
))}
</div>
</div>
</section>
{/* Testimonials */}
<section className='py-16'>
<div className='container mx-auto'>
<div className='mb-12 flex flex-col items-center justify-center text-center'>
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
<Star className='h-6 w-6 text-red-600' />
</div>
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
Отзывы клиентов
</h2>
<p className='max-w-2xl text-gray-600'>
Что говорят о нас наши клиенты
</p>
</div>
<div className='grid gap-8 md:grid-cols-3'>
{[
{
name: 'Фархад К.',
text: 'Я всегда заправляюсь только на GasNetwork. Качество топлива на высоте, а обслуживание всегда приветливое и быстрое.',
rating: 5,
},
{
name: 'Нигина М.',
text: 'Очень удобно, что заправки расположены по всему городу. Всегда чисто, есть кафе и магазин. Рекомендую!',
rating: 5,
},
{
name: 'Джамшед Р.',
text: 'Пользуюсь картой лояльности GasNetwork уже 3 года. Накопил много бонусов и получил немало приятных подарков. Отличный сервис!',
rating: 4,
},
].map((testimonial, index) => (
<Card
key={index}
className='overflow-hidden transition-all hover:shadow-lg'
>
<CardContent className='p-6'>
<div className='mb-4 flex'>
{Array(5)
.fill(0)
.map((_, i) => (
<Star
key={i}
className={`h-5 w-5 ${i < testimonial.rating ? 'fill-yellow-400 text-yellow-400' : 'text-gray-300'}`}
/>
))}
</div>
<p className='mb-4 text-gray-600 italic'>
"{testimonial.text}"
</p>
<p className='font-semibold'>{testimonial.name}</p>
</CardContent>
</Card>
))}
</div>
</div>
</section>
<CtaSection />
</main>
</div>
);
export default function About(){
return <AboutPage/>
}

View File

@ -1,8 +1,6 @@
import {
ArrowRight,
Calendar,
CheckCircle,
Clock,
Heart,
Landmark,
MapPin,
@ -18,12 +16,6 @@ import {
CardHeader,
CardTitle,
} from '@/shared/shadcn-ui/card';
import {
Tabs,
TabsContent,
TabsList,
TabsTrigger,
} from '@/shared/shadcn-ui/tabs';
import { CtaSection } from '@/widgets/cta-section';
@ -39,7 +31,7 @@ export default function CharityPage() {
<main className='flex-1'>
{/* Hero Section */}
<section className='relative'>
<div className='relative h-[500px] w-full overflow-hidden'>
<div className='relative h-[400px] w-full overflow-hidden'>
<Image
src='/placeholder.svg?height=500&width=1920&text=Благотворительный+фонд+GasNetwork'
alt='Благотворительный фонд GasNetwork'
@ -52,7 +44,7 @@ export default function CharityPage() {
<div className='container mx-auto'>
<div className='max-w-2xl space-y-6 text-white'>
<div className='inline-flex items-center justify-center rounded-full bg-red-600/20 p-2'>
<Heart className='h-6 w-6 text-red-500' />
<Heart className='size-6 text-red-500' />
</div>
<h1 className='text-4xl font-bold tracking-tight sm:text-5xl md:text-6xl'>
Благотворительный фонд GasNetwork
@ -62,17 +54,6 @@ export default function CharityPage() {
Наш фонд поддерживает образование, здравоохранение и
экологические инициативы в Таджикистане.
</p>
<div className='flex flex-wrap gap-4'>
<Button className='bg-red-600 hover:bg-red-700'>
Поддержать проект
</Button>
<Button
variant='outline'
className='border-white text-white hover:bg-white/10'
>
Узнать больше
</Button>
</div>
</div>
</div>
</div>
@ -162,7 +143,7 @@ export default function CharityPage() {
результатов
</p>
</div>
<div className='grid grid-cols-2 gap-8 text-center md:grid-cols-4'>
<div className='grid grid-cols-1 gap-8 text-center md:grid-cols-3'>
<div className='space-y-2'>
<h3 className='text-4xl font-bold'>15+</h3>
<p className='text-white/80'>Реализованных проектов</p>
@ -175,301 +156,10 @@ export default function CharityPage() {
<h3 className='text-4xl font-bold'>5000+</h3>
<p className='text-white/80'>Людей получили помощь</p>
</div>
<div className='space-y-2'>
<h3 className='text-4xl font-bold'>20+</h3>
<p className='text-white/80'>Партнерских организаций</p>
</div>
</div>
</div>
</section>
{/* Our Projects */}
<section className='py-16'>
<div className='container mx-auto'>
<div className='mb-12 text-center'>
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
<Landmark className='h-6 w-6 text-red-600' />
</div>
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
Наши проекты
</h2>
<p className='mx-auto max-w-2xl text-gray-600'>
Мы поддерживаем различные инициативы, направленные на улучшение
жизни людей в Таджикистане
</p>
</div>
<Tabs defaultValue='education' className='w-full'>
<TabsList className='mb-8 grid w-full grid-cols-4'>
<TabsTrigger value='education'>Образование</TabsTrigger>
<TabsTrigger value='healthcare'>Здравоохранение</TabsTrigger>
<TabsTrigger value='environment'>Экология</TabsTrigger>
<TabsTrigger value='social'>Социальная помощь</TabsTrigger>
</TabsList>
<TabsContent value='education' className='space-y-8'>
<div className='grid gap-6 md:grid-cols-3'>
{[
{
title: 'Школьные библиотеки',
description:
'Мы оборудовали 10 школьных библиотек в сельских районах Таджикистана, предоставив более 5000 книг.',
image:
'/placeholder.svg?height=200&width=300&text=Школьные+библиотеки',
date: '2022-2023',
},
{
title: 'Стипендиальная программа',
description:
'Ежегодно мы предоставляем стипендии 20 талантливым студентам из малообеспеченных семей.',
image:
'/placeholder.svg?height=200&width=300&text=Стипендии',
date: '2021-настоящее время',
},
{
title: 'Компьютерные классы',
description:
'Мы оборудовали 5 компьютерных классов в школах Душанбе и других городов Таджикистана.',
image:
'/placeholder.svg?height=200&width=300&text=Компьютерные+классы',
date: '2022',
},
].map((project, index) => (
<Card key={index} className='overflow-hidden'>
<div className='relative h-48 w-full'>
<Image
src={project.image || '/placeholder.svg'}
alt={project.title}
fill
className='object-cover'
/>
</div>
<CardHeader>
<div className='flex items-center justify-between'>
<CardTitle>{project.title}</CardTitle>
<div className='flex items-center text-sm text-gray-500'>
<Clock className='mr-1 h-4 w-4' />
{project.date}
</div>
</div>
</CardHeader>
<CardContent>
<p className='text-gray-600'>{project.description}</p>
</CardContent>
<CardFooter>
<Button variant='outline' className='w-full'>
Подробнее
</Button>
</CardFooter>
</Card>
))}
</div>
<div className='text-center'>
<Button className='bg-red-600 hover:bg-red-700'>
Все образовательные проекты{' '}
<ArrowRight className='ml-2 h-4 w-4' />
</Button>
</div>
</TabsContent>
<TabsContent value='healthcare' className='space-y-8'>
<div className='grid gap-6 md:grid-cols-3'>
{[
{
title: 'Медицинское оборудование',
description:
'Мы закупили современное медицинское оборудование для 3 районных больниц в Таджикистане.',
image:
'/placeholder.svg?height=200&width=300&text=Медицинское+оборудование',
date: '2022',
},
{
title: 'Мобильная клиника',
description:
'Наша мобильная клиника предоставляет базовую медицинскую помощь в отдаленных районах страны.',
image:
'/placeholder.svg?height=200&width=300&text=Мобильная+клиника',
date: '2021-настоящее время',
},
{
title: 'Вакцинация детей',
description:
'Мы финансируем программу вакцинации детей в сельских районах Таджикистана.',
image:
'/placeholder.svg?height=200&width=300&text=Вакцинация',
date: '2023',
},
].map((project, index) => (
<Card key={index} className='overflow-hidden'>
<div className='relative h-48 w-full'>
<Image
src={project.image || '/placeholder.svg'}
alt={project.title}
fill
className='object-cover'
/>
</div>
<CardHeader>
<div className='flex items-center justify-between'>
<CardTitle>{project.title}</CardTitle>
<div className='flex items-center text-sm text-gray-500'>
<Clock className='mr-1 h-4 w-4' />
{project.date}
</div>
</div>
</CardHeader>
<CardContent>
<p className='text-gray-600'>{project.description}</p>
</CardContent>
<CardFooter>
<Button variant='outline' className='w-full'>
Подробнее
</Button>
</CardFooter>
</Card>
))}
</div>
<div className='text-center'>
<Button className='bg-red-600 hover:bg-red-700'>
Все проекты здравоохранения{' '}
<ArrowRight className='ml-2 h-4 w-4' />
</Button>
</div>
</TabsContent>
<TabsContent value='environment' className='space-y-8'>
<div className='grid gap-6 md:grid-cols-3'>
{[
{
title: 'Посадка деревьев',
description:
'Мы организовали посадку более 10,000 деревьев в различных регионах Таджикистана.',
image:
'/placeholder.svg?height=200&width=300&text=Посадка+деревьев',
date: '2021-настоящее время',
},
{
title: 'Чистые реки',
description:
'Проект по очистке рек и водоемов от мусора и загрязнений в сотрудничестве с местными сообществами.',
image:
'/placeholder.svg?height=200&width=300&text=Чистые+реки',
date: '2022-2023',
},
{
title: 'Экологическое образование',
description:
'Мы проводим образовательные программы по экологии для школьников и студентов.',
image:
'/placeholder.svg?height=200&width=300&text=Экологическое+образование',
date: '2023',
},
].map((project, index) => (
<Card key={index} className='overflow-hidden'>
<div className='relative h-48 w-full'>
<Image
src={project.image || '/placeholder.svg'}
alt={project.title}
fill
className='object-cover'
/>
</div>
<CardHeader>
<div className='flex items-center justify-between'>
<CardTitle>{project.title}</CardTitle>
<div className='flex items-center text-sm text-gray-500'>
<Clock className='mr-1 h-4 w-4' />
{project.date}
</div>
</div>
</CardHeader>
<CardContent>
<p className='text-gray-600'>{project.description}</p>
</CardContent>
<CardFooter>
<Button variant='outline' className='w-full'>
Подробнее
</Button>
</CardFooter>
</Card>
))}
</div>
<div className='text-center'>
<Button className='bg-red-600 hover:bg-red-700'>
Все экологические проекты{' '}
<ArrowRight className='ml-2 h-4 w-4' />
</Button>
</div>
</TabsContent>
<TabsContent value='social' className='space-y-8'>
<div className='grid gap-6 md:grid-cols-3'>
{[
{
title: 'Помощь детским домам',
description:
'Мы регулярно оказываем материальную помощь детским домам в Таджикистане.',
image:
'/placeholder.svg?height=200&width=300&text=Детские+дома',
date: '2020-настоящее время',
},
{
title: 'Поддержка пожилых людей',
description:
'Программа поддержки одиноких пожилых людей, включающая доставку продуктов и медикаментов.',
image:
'/placeholder.svg?height=200&width=300&text=Пожилые+люди',
date: '2021-настоящее время',
},
{
title: 'Инклюзивное образование',
description:
'Мы поддерживаем программы инклюзивного образования для детей с особыми потребностями.',
image:
'/placeholder.svg?height=200&width=300&text=Инклюзивное+образование',
date: '2022-2023',
},
].map((project, index) => (
<Card key={index} className='overflow-hidden'>
<div className='relative h-48 w-full'>
<Image
src={project.image || '/placeholder.svg'}
alt={project.title}
fill
className='object-cover'
/>
</div>
<CardHeader>
<div className='flex items-center justify-between'>
<CardTitle>{project.title}</CardTitle>
<div className='flex items-center text-sm text-gray-500'>
<Clock className='mr-1 h-4 w-4' />
{project.date}
</div>
</div>
</CardHeader>
<CardContent>
<p className='text-gray-600'>{project.description}</p>
</CardContent>
<CardFooter>
<Button variant='outline' className='w-full'>
Подробнее
</Button>
</CardFooter>
</Card>
))}
</div>
<div className='text-center'>
<Button className='bg-red-600 hover:bg-red-700'>
Все социальные проекты{' '}
<ArrowRight className='ml-2 h-4 w-4' />
</Button>
</div>
</TabsContent>
</Tabs>
</div>
</section>
{/* Upcoming Events */}
<section className='bg-gray-50 py-16'>
<div className='container mx-auto'>
@ -565,7 +255,7 @@ export default function CharityPage() {
</p>
</div>
<div className='grid gap-6 md:grid-cols-4'>
<div className='grid gap-3 md:grid-cols-2 md:gap-6 lg:grid-cols-4'>
{[
{
title: 'Сделать пожертвование',
@ -595,14 +285,13 @@ export default function CharityPage() {
<Card key={index} className='text-center'>
<CardHeader>
<div className='mb-4 flex justify-center'>{item.icon}</div>
<CardTitle>{item.title}</CardTitle>
<CardTitle className='break-words hyphens-auto'>
{item.title}
</CardTitle>
</CardHeader>
<CardContent>
<p className='text-gray-600'>{item.description}</p>
</CardContent>
<CardFooter className='flex justify-center'>
<Button variant='outline'>Подробнее</Button>
</CardFooter>
</Card>
))}
</div>

View File

@ -1,8 +1,5 @@
import { CertificatesPage } from "@/pages-templates/certificates"
import { CertificatesPage } from '@/pages-templates/clients/certificates';
export default function Certificates() {
return (
<CertificatesPage />
)
return <CertificatesPage />;
}

View File

@ -1,285 +1,5 @@
import { Check, Percent } from 'lucide-react';
import Image from 'next/image';
import { LoyaltyPage } from '@/pages-templates/clients/loyalty';
import { Card, CardContent } from '@/shared/shadcn-ui/card';
import { CtaSection } from '@/widgets/cta-section';
export const metadata = {
title: 'Программа лояльности | GasNetwork - Сеть заправок в Таджикистане',
description:
'Программа лояльности GasNetwork: накапливайте баллы и получайте скидки на топливо и услуги.',
};
export default function LoyaltyPage() {
return (
<div className='flex min-h-screen flex-col'>
<main className='flex-1'>
{/* Hero Section */}
<section className='relative'>
<div className='relative h-[400px] w-full overflow-hidden'>
<Image
src='/placeholder.svg?height=400&width=1920&text=Программа+лояльности'
alt='Программа лояльности'
width={1920}
height={400}
className='object-cover'
priority
/>
<div className='absolute inset-0 flex items-center bg-gradient-to-r from-black/70 to-black/30'>
<div className='container mx-auto'>
<div className='max-w-2xl space-y-4 text-white'>
<h1 className='text-4xl font-bold tracking-tight sm:text-5xl md:text-6xl'>
Программа лояльности
</h1>
<p className='text-lg text-gray-200'>
Накапливайте баллы и получайте скидки на топливо и услуги
нашей сети
</p>
</div>
</div>
</div>
</div>
</section>
{/* Program Overview */}
<section className='py-16'>
<div className='container mx-auto'>
<div className='grid items-center gap-12 md:grid-cols-2'>
<div>
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
<Percent className='h-6 w-6 text-red-600' />
</div>
<h2 className='mb-6 text-3xl font-bold tracking-tight sm:text-4xl'>
О программе лояльности
</h2>
<p className='mb-6 text-gray-600'>
Программа лояльности GasNetwork это возможность получать
баллы за каждую покупку топлива и услуг на наших заправочных
станциях. Накопленные баллы можно обменять на скидки, подарки
или дополнительные услуги.
</p>
<p className='mb-6 text-gray-600'>
Участие в программе абсолютно бесплатное. Вам нужно только
получить карту лояльности в любой нашей заправочной станции
или зарегистрироваться в мобильном приложении.
</p>
<div className='space-y-4'>
<div className='flex items-start'>
<div className='mt-1 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-red-600'>
<span className='text-xs text-white'></span>
</div>
<div className='ml-3'>
<h3 className='text-lg font-medium'>1 литр = 1 балл</h3>
<p className='text-gray-600'>
За каждый литр топлива вы получаете 1 балл
</p>
</div>
</div>
<div className='flex items-start'>
<div className='mt-1 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-red-600'>
<span className='text-xs text-white'></span>
</div>
<div className='ml-3'>
<h3 className='text-lg font-medium'>
Дополнительные баллы
</h3>
<p className='text-gray-600'>
За покупки в магазине и кафе на заправке
</p>
</div>
</div>
<div className='flex items-start'>
<div className='mt-1 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-red-600'>
<span className='text-xs text-white'></span>
</div>
<div className='ml-3'>
<h3 className='text-lg font-medium'>Специальные акции</h3>
<p className='text-gray-600'>
Удвоенные и утроенные баллы в праздничные дни
</p>
</div>
</div>
</div>
</div>
<div className='relative h-[400px] overflow-hidden rounded-xl shadow-xl'>
<Image
src='/placeholder.svg?height=400&width=600&text=Программа+лояльности'
alt='Программа лояльности'
fill
className='object-cover'
/>
</div>
</div>
</div>
</section>
{/* How It Works */}
<section className='bg-gray-50 py-16'>
<div className='container mx-auto'>
<div className='mb-12 text-center'>
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
Как это работает
</h2>
<p className='mx-auto max-w-2xl text-gray-600'>
Простые шаги для участия в программе лояльности GasNetwork
</p>
</div>
<div className='grid gap-8 md:grid-cols-4'>
<div className='text-center'>
<div className='mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-red-600 text-2xl font-bold text-white'>
1
</div>
<h3 className='mb-2 text-xl font-bold'>Получите карту</h3>
<p className='text-gray-600'>
Получите карту лояльности на любой заправке GasNetwork или
зарегистрируйтесь в мобильном приложении
</p>
</div>
<div className='text-center'>
<div className='mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-red-600 text-2xl font-bold text-white'>
2
</div>
<h3 className='mb-2 text-xl font-bold'>Заправляйтесь</h3>
<p className='text-gray-600'>
Используйте карту при каждой заправке и покупке в магазинах на
наших АЗС
</p>
</div>
<div className='text-center'>
<div className='mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-red-600 text-2xl font-bold text-white'>
3
</div>
<h3 className='mb-2 text-xl font-bold'>Накапливайте баллы</h3>
<p className='text-gray-600'>
Получайте баллы за каждую покупку и следите за их накоплением
в приложении
</p>
</div>
<div className='text-center'>
<div className='mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-red-600 text-2xl font-bold text-white'>
4
</div>
<h3 className='mb-2 text-xl font-bold'>Получайте выгоду</h3>
<p className='text-gray-600'>
Обменивайте накопленные баллы на скидки, подарки или
дополнительные услуги
</p>
</div>
</div>
</div>
</section>
{/* Loyalty Levels */}
<section className='py-16'>
<div className='container mx-auto'>
<div className='mb-12 text-center'>
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
Уровни лояльности
</h2>
<p className='mx-auto max-w-2xl text-gray-600'>
Чем больше вы заправляетесь, тем больше преимуществ получаете
</p>
</div>
<div className='grid gap-8 md:grid-cols-3'>
<Card className='overflow-hidden border-t-4 border-t-gray-400 transition-all hover:shadow-lg'>
<CardContent className='p-6'>
<h3 className='mb-4 text-center text-2xl font-bold'>
Стандарт
</h3>
<div className='mb-6 text-center'>
<span className='text-4xl font-bold'>1%</span>
<p className='text-sm text-gray-600'>возврат баллами</p>
</div>
<ul className='space-y-2'>
<li className='flex items-center'>
<Check className='mr-2 h-5 w-5 text-green-500' />
<span>1 балл за каждый литр топлива</span>
</li>
<li className='flex items-center'>
<Check className='mr-2 h-5 w-5 text-green-500' />
<span>Участие в акциях</span>
</li>
<li className='flex items-center'>
<Check className='mr-2 h-5 w-5 text-green-500' />
<span>Доступ к мобильному приложению</span>
</li>
</ul>
</CardContent>
</Card>
<Card className='overflow-hidden border-t-4 border-t-yellow-500 transition-all hover:shadow-lg'>
<CardContent className='p-6'>
<h3 className='mb-4 text-center text-2xl font-bold'>
Золотой
</h3>
<div className='mb-6 text-center'>
<span className='text-4xl font-bold'>2%</span>
<p className='text-sm text-gray-600'>возврат баллами</p>
</div>
<ul className='space-y-2'>
<li className='flex items-center'>
<Check className='mr-2 h-5 w-5 text-green-500' />
<span>2 балла за каждый литр топлива</span>
</li>
<li className='flex items-center'>
<Check className='mr-2 h-5 w-5 text-green-500' />
<span>Скидка 5% в кафе на заправках</span>
</li>
<li className='flex items-center'>
<Check className='mr-2 h-5 w-5 text-green-500' />
<span>Приоритетное обслуживание</span>
</li>
<li className='flex items-center'>
<Check className='mr-2 h-5 w-5 text-green-500' />
<span>Эксклюзивные акции</span>
</li>
</ul>
</CardContent>
</Card>
<Card className='overflow-hidden border-t-4 border-t-red-600 transition-all hover:shadow-lg'>
<CardContent className='p-6'>
<h3 className='mb-4 text-center text-2xl font-bold'>
Платиновый
</h3>
<div className='mb-6 text-center'>
<span className='text-4xl font-bold'>3%</span>
<p className='text-sm text-gray-600'>возврат баллами</p>
</div>
<ul className='space-y-2'>
<li className='flex items-center'>
<Check className='mr-2 h-5 w-5 text-green-500' />
<span>3 балла за каждый литр топлива</span>
</li>
<li className='flex items-center'>
<Check className='mr-2 h-5 w-5 text-green-500' />
<span>Скидка 10% в кафе на заправках</span>
</li>
<li className='flex items-center'>
<Check className='mr-2 h-5 w-5 text-green-500' />
<span>Бесплатная мойка раз в месяц</span>
</li>
<li className='flex items-center'>
<Check className='mr-2 h-5 w-5 text-green-500' />
<span>Персональный менеджер</span>
</li>
<li className='flex items-center'>
<Check className='mr-2 h-5 w-5 text-green-500' />
<span>VIP-обслуживание</span>
</li>
</ul>
</CardContent>
</Card>
</div>
</div>
</section>
<CtaSection />
</main>
</div>
);
export default function Loyalty() {
return <LoyaltyPage />;
}

View File

@ -1,254 +1,5 @@
import { ArrowRight, CreditCard, Gift, Percent, Wallet } from 'lucide-react';
import Image from 'next/image';
import Link from 'next/link';
import { ClientsPage } from "@/pages-templates/clients"
import { Button } from '@/shared/shadcn-ui/button';
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from '@/shared/shadcn-ui/card';
import { CtaSection } from '@/widgets/cta-section';
export const metadata = {
title: 'Клиентам | GasNetwork - Сеть заправок в Таджикистане',
description:
'Информация для клиентов: программа лояльности, топливные карты, сертификаты и способы оплаты.',
};
export default function ClientsPage() {
return (
<div className='flex min-h-screen flex-col'>
<main className='flex-1'>
{/* Hero Section */}
<section className='relative'>
<div className='relative h-[400px] w-full overflow-hidden'>
<Image
src='/placeholder.svg?height=400&width=1920&text=Для+наших+клиентов'
alt='Для наших клиентов'
width={1920}
height={400}
className='object-cover'
priority
/>
<div className='absolute inset-0 flex items-center bg-gradient-to-r from-black/70 to-black/30'>
<div className='container mx-auto'>
<div className='max-w-2xl space-y-4 text-white'>
<h1 className='text-4xl font-bold tracking-tight sm:text-5xl md:text-6xl'>
Для наших клиентов
</h1>
<p className='text-lg text-gray-200'>
Специальные предложения, программы лояльности и удобные
способы оплаты для наших клиентов
</p>
</div>
</div>
</div>
</div>
</section>
{/* Services Overview */}
<section className='py-16'>
<div className='container mx-auto'>
<div className='mb-12 text-center'>
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
Наши услуги для клиентов
</h2>
<p className='mx-auto max-w-2xl text-gray-600'>
Мы стремимся сделать обслуживание на наших заправках максимально
удобным и выгодным для вас
</p>
</div>
<div className='grid gap-6 md:grid-cols-2 lg:grid-cols-4'>
<Card className='overflow-hidden transition-all hover:shadow-lg'>
<CardHeader className='pb-3'>
<div className='mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-red-100'>
<Percent className='h-6 w-6 text-red-600' />
</div>
<CardTitle>Программа лояльности</CardTitle>
<CardDescription>
Накапливайте баллы и получайте скидки
</CardDescription>
</CardHeader>
<CardContent className='text-sm text-gray-600'>
<p>
Наша программа лояльности позволяет накапливать баллы за
каждую покупку и обменивать их на скидки и подарки.
</p>
</CardContent>
<CardFooter>
<Link href='/clients/loyalty'>
<Button variant='outline' className='w-full'>
Подробнее <ArrowRight className='ml-2 h-4 w-4' />
</Button>
</Link>
</CardFooter>
</Card>
<Card className='overflow-hidden transition-all hover:shadow-lg'>
<CardHeader className='pb-3'>
<div className='mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-red-100'>
<CreditCard className='h-6 w-6 text-red-600' />
</div>
<CardTitle>Топливная карта</CardTitle>
<CardDescription>
Удобный способ оплаты топлива
</CardDescription>
</CardHeader>
<CardContent className='text-sm text-gray-600'>
<p>
Топливные карты для физических и юридических лиц.
Контролируйте расходы и получайте дополнительные
преимущества.
</p>
</CardContent>
<CardFooter>
<Link href='/clients/fuel-card'>
<Button variant='outline' className='w-full'>
Подробнее <ArrowRight className='ml-2 h-4 w-4' />
</Button>
</Link>
</CardFooter>
</Card>
<Card className='overflow-hidden transition-all hover:shadow-lg'>
<CardHeader className='pb-3'>
<div className='mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-red-100'>
<Gift className='h-6 w-6 text-red-600' />
</div>
<CardTitle>Сертификаты</CardTitle>
<CardDescription>
Подарочные сертификаты на топливо и услуги
</CardDescription>
</CardHeader>
<CardContent className='text-sm text-gray-600'>
<p>
Подарите близким или партнерам сертификат на топливо или
услуги нашей сети. Идеальный подарок для автовладельцев.
</p>
</CardContent>
<CardFooter>
<Link href='/clients/certificates'>
<Button variant='outline' className='w-full'>
Подробнее <ArrowRight className='ml-2 h-4 w-4' />
</Button>
</Link>
</CardFooter>
</Card>
<Card className='overflow-hidden transition-all hover:shadow-lg'>
<CardHeader className='pb-3'>
<div className='mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-red-100'>
<Wallet className='h-6 w-6 text-red-600' />
</div>
<CardTitle>Способы оплаты</CardTitle>
<CardDescription>
Различные способы оплаты на наших заправках
</CardDescription>
</CardHeader>
<CardContent className='text-sm text-gray-600'>
<p>
Мы предлагаем различные способы оплаты: наличные, банковские
карты, мобильные платежи и топливные карты.
</p>
</CardContent>
<CardFooter>
<Link href='/clients/payment'>
<Button variant='outline' className='w-full'>
Подробнее <ArrowRight className='ml-2 h-4 w-4' />
</Button>
</Link>
</CardFooter>
</Card>
</div>
</div>
</section>
{/* Benefits Section */}
<section className='bg-gray-50 py-16'>
<div className='container mx-auto'>
<div className='grid items-center gap-12 md:grid-cols-2'>
<div className='order-2 md:order-1'>
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
<Percent className='h-6 w-6 text-red-600' />
</div>
<h2 className='mb-6 text-3xl font-bold tracking-tight sm:text-4xl'>
Преимущества для клиентов
</h2>
<p className='mb-6 text-gray-600'>
Став клиентом GasNetwork, вы получаете множество преимуществ,
которые делают заправку вашего автомобиля более выгодной и
удобной.
</p>
<div className='space-y-4'>
<div className='flex items-start'>
<div className='mt-1 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-red-600'>
<span className='text-xs text-white'></span>
</div>
<div className='ml-3'>
<h3 className='text-lg font-medium'>Экономия</h3>
<p className='text-gray-600'>
Скидки и бонусы для постоянных клиентов
</p>
</div>
</div>
<div className='flex items-start'>
<div className='mt-1 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-red-600'>
<span className='text-xs text-white'></span>
</div>
<div className='ml-3'>
<h3 className='text-lg font-medium'>Удобство</h3>
<p className='text-gray-600'>
Быстрая оплата и обслуживание
</p>
</div>
</div>
<div className='flex items-start'>
<div className='mt-1 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-red-600'>
<span className='text-xs text-white'></span>
</div>
<div className='ml-3'>
<h3 className='text-lg font-medium'>Качество</h3>
<p className='text-gray-600'>
Гарантированно высокое качество топлива
</p>
</div>
</div>
<div className='flex items-start'>
<div className='mt-1 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-red-600'>
<span className='text-xs text-white'></span>
</div>
<div className='ml-3'>
<h3 className='text-lg font-medium'>
Дополнительные услуги
</h3>
<p className='text-gray-600'>
Кафе, магазины и другие услуги на наших заправках
</p>
</div>
</div>
</div>
</div>
<div className='relative order-1 h-[400px] overflow-hidden rounded-xl shadow-xl md:order-2'>
<Image
src='/placeholder.svg?height=400&width=600&text=Преимущества+для+клиентов'
alt='Преимущества для клиентов'
fill
className='object-cover'
/>
</div>
</div>
</div>
</section>
<CtaSection />
</main>
</div>
);
export default function Clients() {
return <ClientsPage />;
}

View File

@ -1,5 +1,6 @@
@import 'tailwindcss';
@import "tw-animate-css";
@import 'tw-animate-css';
@import 'tailwindcss-animated';
@custom-variant dark (&:is(.dark *));
@ -49,7 +50,7 @@
--card-foreground: oklch(0.145 0 0);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.145 0 0);
--primary: oklch(0.577 0.245 27.325) ;
--primary: oklch(0.577 0.245 27.325);
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.97 0 0);
--secondary-foreground: oklch(0.205 0 0);

View File

@ -22,7 +22,12 @@ export default function RootLayout({
children: React.ReactNode;
}>) {
return (
<html lang='en' suppressHydrationWarning>
<html
lang='en'
suppressHydrationWarning
className='scroll-smooth'
style={{ scrollBehavior: 'smooth' }}
>
<body className={`${inter.className} antialiased`}>
<Providers>
<Header />

View File

@ -38,7 +38,7 @@ const tabs = [
export default function LoginPage() {
return (
<div className='flex min-h-screen flex-col'>
<div className='flex min-h-screen flex-col items-center justify-center'>
<main className='flex-1'>
<div className='container mx-auto max-w-6xl px-2 py-16'>
<div className='mb-12 flex flex-col items-center text-center'>

View File

@ -64,8 +64,8 @@ export const LoginForm = ({ type }: LoginFormProps) => {
};
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className='space-y-4'>
<Form {...form} >
<form onSubmit={form.handleSubmit(onSubmit)} className='space-y-4 mx-auto'>
<FormField
control={form.control}
name='phoneNumber'

View File

@ -1,10 +1,231 @@
'use client';
import { MapPin } from 'lucide-react';
import { useEffect, useRef } from 'react';
import {
Check,
ChevronLeft,
ChevronRight,
Filter,
List,
MapPin,
} from 'lucide-react';
import { useEffect, useRef, useState } from 'react';
import { useLanguage } from '@/shared/language';
import { Badge } from '@/shared/shadcn-ui/badge';
import { Button } from '@/shared/shadcn-ui/button';
import {
Tabs,
TabsContent,
TabsList,
TabsTrigger,
} from '@/shared/shadcn-ui/tabs';
// Sample data for gas stations
const stations = [
{
id: 1,
name: 'АЗС Душанбе-Центр',
address: 'ул. Рудаки 150, Душанбе',
city: 'Душанбе',
coordinates: { x: 0.2, y: 0.3 },
services: ['ДТ', 'АИ-92', 'АИ-95', 'Z-100 Power', 'Минимаркет', 'Туалет'],
},
{
id: 2,
name: 'АЗС Худжанд',
address: 'ул. Ленина 45, Худжанд',
city: 'Худжанд',
coordinates: { x: 0.5, y: 0.2 },
services: [
'ДТ',
'АИ-92',
'АИ-95',
'Пропан',
'Минимаркет',
'Автомойка',
'Туалет',
],
},
{
id: 3,
name: 'АЗС Куляб',
address: 'ул. Сомони 78, Куляб',
city: 'Куляб',
coordinates: { x: 0.7, y: 0.4 },
services: ['ДТ', 'АИ-92', 'Пропан', 'Туалет'],
},
{
id: 4,
name: 'АЗС Бохтар',
address: 'ул. Айни 23, Бохтар',
city: 'Бохтар',
coordinates: { x: 0.3, y: 0.6 },
services: [
'ДТ',
'АИ-92',
'АИ-95',
'Z-100 Power',
'Минимаркет',
'Зарядная станция',
'Туалет',
],
},
{
id: 5,
name: 'АЗС Хорог',
address: 'ул. Горная 12, Хорог',
city: 'Хорог',
coordinates: { x: 0.6, y: 0.7 },
services: ['ДТ', 'АИ-92', 'Автомойка', 'Туалет'],
},
{
id: 6,
name: 'АЗС Истаравшан',
address: 'ул. Исмоили Сомони 34, Истаравшан',
city: 'Истаравшан',
coordinates: { x: 0.8, y: 0.8 },
services: ['ДТ', 'АИ-92', 'АИ-95', 'Минимаркет', 'Туалет'],
},
{
id: 7,
name: 'АЗС Пенджикент',
address: 'ул. Рудаки 56, Пенджикент',
city: 'Пенджикент',
coordinates: { x: 0.1, y: 0.9 },
services: ['ДТ', 'АИ-92', 'АИ-95', 'Пропан', 'Минимаркет', 'Туалет'],
},
{
id: 8,
name: 'АЗС Душанбе-Запад',
address: 'ул. Джами 23, Душанбе',
city: 'Душанбе',
coordinates: { x: 0.25, y: 0.35 },
services: [
'ДТ',
'АИ-92',
'АИ-95',
'Z-100 Power',
'Пропан',
'Минимаркет',
'Автомойка',
'Туалет',
],
},
{
id: 9,
name: 'АЗС Душанбе-Восток',
address: 'ул. Айни 78, Душанбе',
city: 'Душанбе',
coordinates: { x: 0.15, y: 0.25 },
services: [
'ДТ',
'АИ-92',
'АИ-95',
'Зарядная станция',
'Минимаркет',
'Туалет',
],
},
{
id: 10,
name: 'АЗС Гиссар',
address: 'ул. Центральная 12, Гиссар',
city: 'Гиссар',
coordinates: { x: 0.4, y: 0.4 },
services: ['ДТ', 'АИ-92', 'Пропан', 'Туалет'],
},
{
id: 11,
name: 'АЗС Вахдат',
address: 'ул. Сомони 45, Вахдат',
city: 'Вахдат',
coordinates: { x: 0.55, y: 0.45 },
services: ['ДТ', 'АИ-92', 'АИ-95', 'Минимаркет', 'Туалет'],
},
{
id: 12,
name: 'АЗС Турсунзаде',
address: 'ул. Ленина 34, Турсунзаде',
city: 'Турсунзаде',
coordinates: { x: 0.65, y: 0.55 },
services: ['ДТ', 'АИ-92', 'АИ-95', 'Z-100 Power', 'Автомойка', 'Туалет'],
},
];
// All available filters
const allFilters = [
'ДТ',
'АИ-92',
'АИ-95',
'Z-100 Power',
'Пропан',
'Зарядная станция',
'Минимаркет',
'Автомойка',
'Туалет',
];
// Extract unique cities from stations
const allCities = [...new Set(stations.map((station) => station.city))].sort();
export default function GasStationMap() {
const { t } = useLanguage();
const mapRef = useRef<HTMLDivElement>(null);
const [activeFilters, setActiveFilters] = useState<string[]>([]);
const [activeCities, setActiveCities] = useState<string[]>([]);
const [filteredStations, setFilteredStations] = useState(stations);
const [selectedStation, setSelectedStation] = useState<number | null>(null);
const [isFilterOpen, setIsFilterOpen] = useState(false);
const [isStationListOpen, setIsStationListOpen] = useState(false);
const [activeFilterTab, setActiveFilterTab] = useState('cities');
// Toggle service filter
const toggleFilter = (filter: string) => {
if (activeFilters.includes(filter)) {
setActiveFilters(activeFilters.filter((f) => f !== filter));
} else {
setActiveFilters([...activeFilters, filter]);
}
};
// Toggle city filter
const toggleCity = (city: string) => {
if (activeCities.includes(city)) {
setActiveCities(activeCities.filter((c) => c !== city));
} else {
setActiveCities([...activeCities, city]);
}
};
// Select all cities
const selectAllCities = () => {
if (activeCities.length === allCities.length) {
setActiveCities([]);
} else {
setActiveCities([...allCities]);
}
};
// Filter stations based on active filters and cities
useEffect(() => {
let filtered = stations;
// Filter by services
if (activeFilters.length > 0) {
filtered = filtered.filter((station) =>
activeFilters.every((filter) => station.services.includes(filter)),
);
}
// Filter by cities
if (activeCities.length > 0) {
filtered = filtered.filter((station) =>
activeCities.includes(station.city),
);
}
setFilteredStations(filtered);
}, [activeFilters, activeCities]);
useEffect(() => {
// This is a placeholder for a real map implementation
@ -42,24 +263,15 @@ export default function GasStationMap() {
}
// Draw gas station markers
const stations = [
{ x: 0.2, y: 0.3 },
{ x: 0.5, y: 0.2 },
{ x: 0.7, y: 0.4 },
{ x: 0.3, y: 0.6 },
{ x: 0.6, y: 0.7 },
{ x: 0.8, y: 0.8 },
{ x: 0.1, y: 0.9 },
];
stations.forEach((station) => {
filteredStations.forEach((station) => {
const isSelected = selectedStation === station.id;
// Draw marker
ctx.fillStyle = '#ef4444';
ctx.fillStyle = isSelected ? '#3b82f6' : '#ef4444';
ctx.beginPath();
ctx.arc(
station.x * canvas.width,
station.y * canvas.height,
10,
station.coordinates.x * canvas.width,
station.coordinates.y * canvas.height,
isSelected ? 12 : 10,
0,
2 * Math.PI,
);
@ -70,9 +282,9 @@ export default function GasStationMap() {
ctx.lineWidth = 2;
ctx.beginPath();
ctx.arc(
station.x * canvas.width,
station.y * canvas.height,
10,
station.coordinates.x * canvas.width,
station.coordinates.y * canvas.height,
isSelected ? 12 : 10,
0,
2 * Math.PI,
);
@ -99,17 +311,257 @@ export default function GasStationMap() {
}
}
};
}, []);
}, [filteredStations, selectedStation]);
return (
<div className='relative h-full w-full'>
<div ref={mapRef} className='h-full w-full'></div>
<div className='absolute right-4 bottom-4 rounded-lg bg-white p-3 shadow-lg'>
{/* Filter panel - slides from left */}
<div
className={`absolute top-0 bottom-0 left-0 z-20 transform bg-white shadow-lg transition-transform duration-300 ${
isFilterOpen ? 'translate-x-0' : '-translate-x-full'
}`}
style={{ width: '300px' }}
>
<div className='flex items-center justify-between border-b border-gray-200 p-4'>
<div className='flex items-center gap-2'>
<Filter className='h-5 w-5 text-red-600' />
<span className='font-medium'>{t('map.filters')}</span>
</div>
<Button
variant='ghost'
size='sm'
onClick={() => setIsFilterOpen(false)}
>
<ChevronLeft className='h-5 w-5' />
</Button>
</div>
<div className='p-4'>
<Tabs
value={activeFilterTab}
onValueChange={setActiveFilterTab}
className='w-full'
>
<TabsList className='mb-4 grid w-full grid-cols-2'>
<TabsTrigger value='cities'>{t('map.cities')}</TabsTrigger>
<TabsTrigger value='services'>{t('map.services')}</TabsTrigger>
</TabsList>
<TabsContent value='cities' className='mt-0'>
<Button
variant='outline'
size='sm'
className='mb-3 flex w-full items-center justify-between'
onClick={selectAllCities}
>
<span>{t('map.allCities')}</span>
{activeCities.length === allCities.length && (
<Check className='h-4 w-4 text-green-600' />
)}
</Button>
<div className='flex max-h-[calc(100vh-250px)] flex-col gap-2 overflow-y-auto'>
{allCities.map((city) => (
<Button
key={city}
variant={
activeCities.includes(city) ? 'default' : 'outline'
}
size='sm'
className={`justify-between ${activeCities.includes(city) ? 'bg-red-600 hover:bg-red-700' : ''}`}
onClick={() => toggleCity(city)}
>
<span>{city}</span>
{activeCities.includes(city) && (
<Check className='ml-2 h-4 w-4' />
)}
</Button>
))}
</div>
{activeCities.length > 0 && (
<Button
variant='link'
className='mt-4 p-0 text-red-600'
onClick={() => setActiveCities([])}
>
{t('common.buttons.resetFilters')}
</Button>
)}
</TabsContent>
<TabsContent value='services' className='mt-0'>
<div className='flex flex-wrap gap-2'>
{allFilters.map((filter) => (
<Button
key={filter}
variant={
activeFilters.includes(filter) ? 'default' : 'outline'
}
size='sm'
className={
activeFilters.includes(filter)
? 'bg-red-600 hover:bg-red-700'
: ''
}
onClick={() => toggleFilter(filter)}
>
{filter}
</Button>
))}
</div>
{activeFilters.length > 0 && (
<Button
variant='link'
className='mt-4 p-0 text-red-600'
onClick={() => setActiveFilters([])}
>
{t('common.buttons.resetFilters')}
</Button>
)}
</TabsContent>
</Tabs>
</div>
</div>
{/* Station list panel - slides from right */}
<div
className={`absolute top-0 right-0 bottom-0 z-20 transform bg-white shadow-lg transition-transform duration-300 ${
isStationListOpen ? 'translate-x-0' : 'translate-x-full'
}`}
style={{ width: '350px' }}
>
<div className='flex items-center justify-between border-b border-gray-200 p-4'>
<Button
variant='ghost'
size='sm'
onClick={() => setIsStationListOpen(false)}
>
<ChevronRight className='h-5 w-5' />
</Button>
<div className='flex items-center gap-2'>
<span className='font-medium'>{t('map.stationsList')}</span>
<Badge>{filteredStations.length}</Badge>
</div>
</div>
<div
className='overflow-y-auto'
style={{ height: 'calc(100% - 60px)' }}
>
{filteredStations.length > 0 ? (
<div className='p-2'>
{filteredStations.map((station) => (
<div
key={station.id}
className={`mb-2 cursor-pointer rounded-lg border p-3 transition-colors ${
selectedStation === station.id
? 'border-blue-500 bg-blue-50'
: 'border-gray-200 hover:bg-gray-50'
}`}
onClick={() => setSelectedStation(station.id)}
>
<div className='flex items-start justify-between'>
<h4 className='font-medium'>{station.name}</h4>
<ChevronRight className='h-4 w-4 text-gray-400' />
</div>
<p className='mb-2 text-sm text-gray-500'>
{station.address}
</p>
<div className='flex flex-wrap gap-1'>
<Badge className='mb-1 border-blue-200 bg-blue-100 text-blue-800'>
{station.city}
</Badge>
{station.services.map((service) => (
<Badge
key={service}
variant='outline'
className={
activeFilters.includes(service)
? 'border-red-200 bg-red-100 text-red-800'
: ''
}
>
{service}
</Badge>
))}
</div>
</div>
))}
</div>
) : (
<div className='p-4 text-center text-gray-500'>
<p>{t('map.noStations')}</p>
<div className='mt-2 flex justify-center gap-2'>
{activeFilters.length > 0 && (
<Button
variant='link'
className='text-red-600'
onClick={() => setActiveFilters([])}
>
{t('common.buttons.resetFilters')}
</Button>
)}
{activeCities.length > 0 && (
<Button
variant='link'
className='text-red-600'
onClick={() => setActiveCities([])}
>
{t('map.allCities')}
</Button>
)}
</div>
</div>
)}
</div>
</div>
{/* Map */}
<div className='h-full w-full'>
<div ref={mapRef} className='h-full w-full'></div>
</div>
{/* Control buttons */}
<div className='absolute top-4 left-4 z-10'>
<Button
variant='default'
size='sm'
className='border border-gray-200 bg-white text-gray-800 shadow-md hover:bg-gray-100'
onClick={() => setIsFilterOpen(true)}
>
<Filter className='h-4 w-4 text-red-600 sm:mr-2' />
<span className='hidden sm:flex'>{t('map.filters')}</span>
{(activeFilters.length > 0 || activeCities.length > 0) && (
<Badge className='ml-2 bg-red-600' variant='default'>
{activeFilters.length + activeCities.length}
</Badge>
)}
</Button>
</div>
<div className='absolute top-4 right-4 z-10'>
<Button
variant='default'
size='sm'
className='border border-gray-200 bg-white text-gray-800 shadow-md hover:bg-gray-100'
onClick={() => setIsStationListOpen(true)}
>
<List className='h-4 w-4 text-red-600 sm:mr-2' />
<span className='hidden sm:flex'>{t('map.stationsList')}</span>
<Badge className='ml-2 bg-red-600' variant='default'>
{filteredStations.length}
</Badge>
</Button>
</div>
<div className='absolute bottom-4 left-4 rounded-lg bg-white p-3 shadow-lg'>
<div className='flex items-center gap-2 text-sm font-medium'>
<MapPin className='h-5 w-5 text-red-600' />
<span>Наши заправки</span>
<span>{t('map.ourStations')}</span>
</div>
<p className='mt-1 text-xs text-gray-500'>Всего станций: 25</p>
<p className='mt-1 text-xs text-gray-500'>
{t('map.totalStations')}: {stations.length}
</p>
</div>
</div>
);

View File

@ -0,0 +1,325 @@
'use client';
import {
Award,
Fuel,
History,
MapPin,
Star,
Target,
Users,
} from 'lucide-react';
import Image from 'next/image';
// import { useTranslation } from 'next-i18next';
import AnimatedCounter from '@/shared/components/animated-counter';
import { useLanguage } from '@/shared/language';
import { Button } from '@/shared/shadcn-ui/button';
import { Card, CardContent } from '@/shared/shadcn-ui/card';
import { CompanyTimeline } from '@/widgets/about-page/company-timeline';
import { StationGallery } from '@/widgets/about-page/station-gallery';
import { CtaSection } from '@/widgets/cta-section';
export const metadata = {
title: 'about.metadata.title',
description: 'about.metadata.description',
};
export default function AboutPage() {
const { t } = useLanguage();
return (
<div className='flex min-h-screen flex-col'>
<main className='flex-1'>
{/* Hero Section */}
<section className='relative'>
<div className='relative h-[400px] w-full overflow-hidden'>
<Image
src='/placeholder.svg?height=400&width=1920&text=Наша+История'
alt={t('about.hero.imageAlt')}
width={1920}
height={400}
className='object-cover'
priority
/>
<div className='absolute inset-0 flex items-center bg-gradient-to-r from-black/70 to-black/30'>
<div className='container mx-auto'>
<div className='max-w-2xl space-y-4 text-white'>
<h1 className='text-4xl font-bold tracking-tight sm:text-5xl md:text-6xl'>
{t('about.hero.title')}
</h1>
<p className='text-lg text-gray-200'>
{t('about.hero.subtitle')}
</p>
</div>
</div>
</div>
</div>
</section>
{/* Company Overview */}
<section className='py-16'>
<div className='container mx-auto'>
<div className='grid items-center gap-12 md:grid-cols-2'>
<div>
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
<Fuel className='h-6 w-6 text-red-600' />
</div>
<h2 className='mb-6 text-3xl font-bold tracking-tight sm:text-4xl'>
{t('about.overview.title')}
</h2>
<p className='mb-6 text-gray-600'>
{t('about.overview.description1')}
</p>
<p className='mb-6 text-gray-600'>
{t('about.overview.description2')}
</p>
<p className='mb-6 text-gray-600'>
{t('about.overview.description3')}
</p>
<div className='mb-6 grid grid-cols-2 gap-4'>
{[0, 1, 2, 3].map((index) => (
<div key={index} className='flex items-start'>
<div className='mt-1 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-red-600'>
<span className='text-xs text-white'></span>
</div>
<div className='ml-3'>
<h3 className='text-lg font-medium'>
{t(`about.overview.benefits.${index}.title`)}
</h3>
<p className='text-gray-600'>
{t(`about.overview.benefits.${index}.description`)}
</p>
</div>
</div>
))}
</div>
</div>
<div className='relative h-[500px] overflow-hidden rounded-xl shadow-xl'>
<Image
src='/placeholder.svg?height=500&width=600&text=Главный+офис'
alt={t('about.overview.imageAlt')}
fill
className='object-cover'
/>
</div>
</div>
</div>
</section>
{/* Stats Section */}
<section className='bg-red-600 py-16 text-white'>
<div className='container mx-auto'>
<div className='mb-12 text-center'>
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
{t('about.stats.title')}
</h2>
<p className='mx-auto max-w-2xl text-white/80'>
{t('about.stats.subtitle')}
</p>
</div>
<div className='grid grid-cols-2 gap-8 text-center md:grid-cols-4'>
{[0, 1, 2, 3].map((index) => (
<div key={index} className='space-y-2'>
<h3 className='text-4xl font-bold'>
<AnimatedCounter
end={Number(t(`about.stats.items.${index}.value`))}
suffix={
t(`about.stats.items.${index}.suffix`) ===
`about.stats.items.${index}.suffix`
? ''
: t(`about.stats.items.${index}.suffix`) || ''
}
/>
</h3>
<p className='text-sm text-white/80'>
{t(`about.stats.items.${index}.label`)}
</p>
</div>
))}
</div>
</div>
</section>
{/* Our History */}
<section className='py-16'>
<div className='container mx-auto'>
<div className='mb-12 flex flex-col items-center justify-center text-center'>
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
<History className='h-6 w-6 text-red-600' />
</div>
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
{t('about.history.title')}
</h2>
<p className='max-w-2xl text-gray-600'>
{t('about.history.subtitle')}
</p>
</div>
<CompanyTimeline />
</div>
</section>
{/* Our Stations */}
<section className='bg-gray-50 py-16'>
<div className='container mx-auto'>
<div className='mb-12 flex flex-col items-center justify-center text-center'>
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
<MapPin className='h-6 w-6 text-red-600' />
</div>
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
{t('about.stations.title')}
</h2>
<p className='max-w-2xl text-gray-600'>
{t('about.stations.subtitle')}
</p>
</div>
<StationGallery />
<div className='mt-12 text-center'>
<p className='mx-auto mb-6 max-w-2xl text-gray-600'>
{t('about.stations.description')}
</p>
<Button className='bg-red-600 hover:bg-red-700'>
{t('about.stations.buttonText')}{' '}
<MapPin className='ml-2 h-4 w-4' />
</Button>
</div>
</div>
</section>
{/* Our Values */}
<section className='py-16'>
<div className='container mx-auto'>
<div className='mb-12 flex flex-col items-center justify-center text-center'>
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
<Target className='h-6 w-6 text-red-600' />
</div>
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
{t('about.values.title')}
</h2>
<p className='max-w-2xl text-gray-600'>
{t('about.values.subtitle')}
</p>
</div>
<div className='grid gap-8 md:grid-cols-3'>
{[0, 1, 2].map((index) => (
<Card
key={index}
className='overflow-hidden transition-all hover:shadow-lg'
>
<CardContent className='p-6'>
<div className='mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-red-100'>
<Star className='h-6 w-6 text-red-600' />
</div>
<h3 className='mb-2 text-xl font-bold'>
{t(`about.values.items.${index}.title`)}
</h3>
<p className='text-gray-600'>
{t(`about.values.items.${index}.description`)}
</p>
</CardContent>
</Card>
))}
</div>
</div>
</section>
{/* Our Team */}
<section className='bg-gray-50 py-16'>
<div className='container mx-auto'>
<div className='mb-12 flex flex-col items-center justify-center text-center'>
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
<Users className='h-6 w-6 text-red-600' />
</div>
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
{t('about.team.title')}
</h2>
<p className='max-w-2xl text-gray-600'>
{t('about.team.subtitle')}
</p>
</div>
<div className='grid grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-4'>
{[0, 1, 2, 3].map((index) => (
<div
key={index}
className='overflow-hidden rounded-lg bg-white shadow-md transition-transform hover:scale-105'
>
<div className='relative h-64 w-full'>
<Image
src={`/placeholder.svg?height=300&width=300&text=${t(`about.team.members.${index}.name`)}`}
alt={t(`about.team.members.${index}.name`)}
fill
className='object-cover'
/>
</div>
<div className='p-4 text-center'>
<h3 className='text-lg font-bold'>
{t(`about.team.members.${index}.name`)}
</h3>
<p className='text-gray-600'>
{t(`about.team.members.${index}.position`)}
</p>
</div>
</div>
))}
</div>
</div>
</section>
{/* Testimonials */}
<section className='py-16'>
<div className='container mx-auto'>
<div className='mb-12 flex flex-col items-center justify-center text-center'>
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
<Star className='h-6 w-6 text-red-600' />
</div>
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
{t('about.testimonials.title')}
</h2>
<p className='max-w-2xl text-gray-600'>
{t('about.testimonials.subtitle')}
</p>
</div>
<div className='grid gap-8 md:grid-cols-3'>
{[0, 1, 2].map((index) => (
<Card
key={index}
className='overflow-hidden transition-all hover:shadow-lg'
>
<CardContent className='p-6'>
<div className='mb-4 flex'>
{Array(5)
.fill(0)
.map((_, i) => (
<Star
key={i}
className={`h-5 w-5 ${i < Number(t(`about.testimonials.items.${index}.rating`)) ? 'fill-yellow-400 text-yellow-400' : 'text-gray-300'}`}
/>
))}
</div>
<p className='mb-4 text-gray-600 italic'>
"{t(`about.testimonials.items.${index}.text`)}"
</p>
<p className='font-semibold'>
{t(`about.testimonials.items.${index}.name`)}
</p>
</CardContent>
</Card>
))}
</div>
</div>
</section>
<CtaSection />
</main>
</div>
);
}

View File

@ -1,122 +0,0 @@
"use client"
import Image from "next/image"
import { Card, CardContent } from "@/shared/shadcn-ui/card"
import { Button } from "@/shared/shadcn-ui/button"
import { Download, Eye } from "lucide-react"
import { useLanguage } from "@/shared/language"
export function CertificatesPage() {
const { t } = useLanguage()
// This data would typically come from an API or CMS
// We're keeping it as-is since it's dynamic content
const certificates = [
{
id: 1,
title: "ISO 9001:2015",
description: "Сертификат системы менеджмента качества",
image: "/placeholder.svg?height=400&width=300",
issueDate: "15.03.2022",
expiryDate: "15.03.2025",
},
{
id: 2,
title: "ISO 14001:2015",
description: "Сертификат экологического менеджмента",
image: "/placeholder.svg?height=400&width=300",
issueDate: "10.05.2022",
expiryDate: "10.05.2025",
},
{
id: 3,
title: "OHSAS 18001",
description: "Сертификат системы управления охраной труда",
image: "/placeholder.svg?height=400&width=300",
issueDate: "22.07.2022",
expiryDate: "22.07.2025",
},
{
id: 4,
title: "Сертификат качества топлива",
description: "Подтверждение соответствия топлива стандартам качества",
image: "/placeholder.svg?height=400&width=300",
issueDate: "05.01.2023",
expiryDate: "05.01.2024",
},
{
id: 5,
title: "Сертификат соответствия",
description: "Соответствие услуг национальным стандартам",
image: "/placeholder.svg?height=400&width=300",
issueDate: "18.09.2022",
expiryDate: "18.09.2025",
},
{
id: 6,
title: "Лицензия на хранение ГСМ",
description: "Разрешение на хранение горюче-смазочных материалов",
image: "/placeholder.svg?height=400&width=300",
issueDate: "30.11.2021",
expiryDate: "30.11.2026",
},
]
return (
<>
<main className="container mx-auto py-10">
<div className="mb-10 text-center">
<h1 className="mb-4 text-4xl font-bold">{t("certificates.title")}</h1>
<p className="mx-auto max-w-2xl text-lg text-gray-600">{t("certificates.description")}</p>
</div>
<div className="grid gap-8 md:grid-cols-2 lg:grid-cols-3">
{certificates.map((certificate) => (
<Card key={certificate.id} className="overflow-hidden transition-all duration-300 hover:shadow-lg">
<div className="relative h-[300px] w-full overflow-hidden bg-gray-100">
<Image
src={certificate.image || "/placeholder.svg"}
alt={certificate.title}
fill
className="object-contain p-4"
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
/>
</div>
<CardContent className="p-6">
<h3 className="mb-2 text-xl font-bold">{certificate.title}</h3>
<p className="mb-4 text-gray-600">{certificate.description}</p>
<div className="mb-4 text-sm text-gray-500">
<p>
{t("certificates.issueDate")}: {certificate.issueDate}
</p>
<p>
{t("certificates.expiryDate")}: {certificate.expiryDate}
</p>
</div>
<div className="flex gap-2">
<Button variant="outline" size="sm" className="flex items-center gap-1">
<Eye size={16} />
<span>{t("common.buttons.view")}</span>
</Button>
<Button variant="outline" size="sm" className="flex items-center gap-1">
<Download size={16} />
<span>{t("common.buttons.download")}</span>
</Button>
</div>
</CardContent>
</Card>
))}
</div>
<div className="mt-16 rounded-lg bg-gray-50 p-8">
<h2 className="mb-4 text-2xl font-bold">{t("certificates.requestInfo")}</h2>
<p className="mb-6 text-gray-600">{t("certificates.requestInfoText")}</p>
<div className="flex flex-wrap gap-4">
<Button className="bg-red-600 hover:bg-red-700">{t("common.buttons.contactUs")}</Button>
<Button variant="outline">{t("certificates.faq")}</Button>
</div>
</div>
</main>
</>
)
}

View File

@ -0,0 +1,127 @@
'use client';
import { Download, Eye } from 'lucide-react';
import Image from 'next/image';
import { useLanguage } from '@/shared/language';
import { Button } from '@/shared/shadcn-ui/button';
import { Card, CardContent } from '@/shared/shadcn-ui/card';
export function CertificatesPage() {
const { t } = useLanguage();
// This data would typically come from an API or CMS
// We're keeping it as-is since it's dynamic content
const certificates = [
{
id: 1,
title: 'ISO 9001:2015',
description: 'Сертификат системы менеджмента качества',
image: '/placeholder.svg?height=400&width=300',
issueDate: '15.03.2022',
expiryDate: '15.03.2025',
},
{
id: 2,
title: 'ISO 14001:2015',
description: 'Сертификат экологического менеджмента',
image: '/placeholder.svg?height=400&width=300',
issueDate: '10.05.2022',
expiryDate: '10.05.2025',
},
{
id: 3,
title: 'OHSAS 18001',
description: 'Сертификат системы управления охраной труда',
image: '/placeholder.svg?height=400&width=300',
issueDate: '22.07.2022',
expiryDate: '22.07.2025',
},
{
id: 4,
title: 'Сертификат качества топлива',
description: 'Подтверждение соответствия топлива стандартам качества',
image: '/placeholder.svg?height=400&width=300',
issueDate: '05.01.2023',
expiryDate: '05.01.2024',
},
{
id: 5,
title: 'Сертификат соответствия',
description: 'Соответствие услуг национальным стандартам',
image: '/placeholder.svg?height=400&width=300',
issueDate: '18.09.2022',
expiryDate: '18.09.2025',
},
{
id: 6,
title: 'Лицензия на хранение ГСМ',
description: 'Разрешение на хранение горюче-смазочных материалов',
image: '/placeholder.svg?height=400&width=300',
issueDate: '30.11.2021',
expiryDate: '30.11.2026',
},
];
return (
<>
<main className='container mx-auto py-10'>
<div className='mb-10 text-center'>
<h1 className='mb-4 text-4xl font-bold'>{t('certificates.title')}</h1>
<p className='mx-auto max-w-2xl text-lg text-gray-600'>
{t('certificates.description')}
</p>
</div>
<div className='grid gap-8 md:grid-cols-2 lg:grid-cols-3'>
{certificates.map((certificate) => (
<Card
key={certificate.id}
className='overflow-hidden transition-all duration-300 hover:shadow-lg'
>
<div className='relative h-[300px] w-full overflow-hidden bg-gray-100'>
<Image
src={certificate.image || '/placeholder.svg'}
alt={certificate.title}
fill
className='object-contain p-4'
sizes='(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw'
/>
</div>
<CardContent className='p-6'>
<h3 className='mb-2 text-xl font-bold'>{certificate.title}</h3>
<p className='mb-4 text-gray-600'>{certificate.description}</p>
<div className='mb-4 text-sm text-gray-500'>
<p>
{t('certificates.issueDate')}: {certificate.issueDate}
</p>
<p>
{t('certificates.expiryDate')}: {certificate.expiryDate}
</p>
</div>
<div className='flex gap-2'>
<Button
variant='outline'
size='sm'
className='flex items-center gap-1'
>
<Eye size={16} />
<span>{t('common.buttons.view')}</span>
</Button>
<Button
variant='outline'
size='sm'
className='flex items-center gap-1'
>
<Download size={16} />
<span>{t('common.buttons.download')}</span>
</Button>
</div>
</CardContent>
</Card>
))}
</div>
</main>
</>
);
}

View File

@ -0,0 +1,55 @@
"use client"
import Image from 'next/image';
import { BenefitsSection } from '@/widgets/clients/ui/benefits-section';
import { ServicesOverviewSection } from '@/widgets/clients/ui/services-overview-section';
import { CtaSection } from '@/widgets/cta-section';
import { useLanguage } from '@/shared/language';
export const metadata = {
title: 'Клиентам | GasNetwork - Сеть заправок в Таджикистане',
description:
'Информация для клиентов: программа лояльности, топливные карты, сертификаты и способы оплаты.',
};
export function ClientsPage() {
const { t } = useLanguage()
return (
<div className='flex min-h-screen flex-col'>
<main className='flex-1'>
{/* Hero Section */}
<section className='relative'>
<div className='relative h-[400px] w-full overflow-hidden'>
<Image
src='/placeholder.svg?height=400&width=1920&text=Для+наших+клиентов'
alt='Для наших клиентов'
width={1920}
height={400}
className='object-cover'
priority
/>
<div className='absolute inset-0 flex items-center bg-gradient-to-r from-black/70 to-black/30'>
<div className='container mx-auto'>
<div className='max-w-2xl space-y-4 text-white'>
<h1 className='text-4xl font-bold tracking-tight sm:text-5xl md:text-6xl'>
{t('clients.title')}
</h1>
<p className='text-lg text-gray-200'>
{t('clients.description')}
</p>
</div>
</div>
</div>
</div>
</section>
<ServicesOverviewSection />
<BenefitsSection />
<CtaSection />
</main>
</div>
);
}

View File

@ -0,0 +1,328 @@
'use client';
import { Check, Percent } from 'lucide-react';
import Image from 'next/image';
import { useLanguage } from '@/shared/language';
import { Card, CardContent } from '@/shared/shadcn-ui/card';
import { CtaSection } from '@/widgets/cta-section';
export const metadata = {
title: 'Программа лояльности | GasNetwork - Сеть заправок в Таджикистане',
description:
'Программа лояльности GasNetwork: накапливайте баллы и получайте скидки на топливо и услуги.',
};
export function LoyaltyPage() {
const { t } = useLanguage();
return (
<div className='flex min-h-screen flex-col'>
<main className='flex-1'>
{/* Hero Section */}
<section className='relative'>
<div className='relative h-[400px] w-full overflow-hidden'>
<Image
src='/placeholder.svg?height=400&width=1920&text=Программа+лояльности'
alt='Программа лояльности'
width={1920}
height={400}
className='object-cover'
priority
/>
<div className='absolute inset-0 flex items-center bg-gradient-to-r from-black/70 to-black/30'>
<div className='container mx-auto'>
<div className='max-w-2xl space-y-4 text-white'>
<h1 className='text-4xl font-bold tracking-tight sm:text-5xl md:text-6xl'>
{t('clients.loyalty.title')}
</h1>
<p className='text-lg text-gray-200'>
{t('clients.loyalty.description')}
</p>
</div>
</div>
</div>
</div>
</section>
{/* Program Overview */}
<section className='py-16'>
<div className='container mx-auto'>
<div className='grid items-center gap-12 md:grid-cols-2'>
<div>
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
<Percent className='h-6 w-6 text-red-600' />
</div>
<h2 className='mb-6 text-3xl font-bold tracking-tight sm:text-4xl'>
{t('clients.loyalty.programm.about')}
</h2>
<p className='mb-6 text-gray-600'>
{t('clients.loyalty.programm.about-description')}
</p>
<p className='mb-6 text-gray-600'>
{t('clients.loyalty.programm.about-description-2')}
</p>
<div className='space-y-4'>
<div className='flex items-start'>
<div className='mt-1 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-red-600'>
<span className='text-xs text-white'></span>
</div>
<div className='ml-3'>
<h3 className='text-lg font-medium'>
{t('clients.loyalty.programm.conditions-1')}
</h3>
<p className='text-gray-600'>
{t('clients.loyalty.programm.conditions.description-1')}
</p>
</div>
</div>
<div className='flex items-start'>
<div className='mt-1 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-red-600'>
<span className='text-xs text-white'></span>
</div>
<div className='ml-3'>
<h3 className='text-lg font-medium'>
{t('clients.loyalty.programm.conditions-2')}
</h3>
<p className='text-gray-600'>
{t('clients.loyalty.programm.conditions.description-2')}
</p>
</div>
</div>
<div className='flex items-start'>
<div className='mt-1 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-red-600'>
<span className='text-xs text-white'></span>
</div>
<div className='ml-3'>
<h3 className='text-lg font-medium'>
{t('clients.loyalty.programm.conditions-3')}
</h3>
<p className='text-gray-600'>
{t('clients.loyalty.programm.conditions.description-3')}
</p>
</div>
</div>
</div>
</div>
<div className='relative h-[400px] overflow-hidden rounded-xl shadow-xl'>
<Image
src='/placeholder.svg?height=400&width=600&text=Программа+лояльности'
alt='Программа лояльности'
fill
className='object-cover'
/>
</div>
</div>
</div>
</section>
{/* How It Works */}
<section className='bg-gray-50 py-16'>
<div className='container mx-auto'>
<div className='mb-12 text-center'>
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
{t('clients.loyalty.works.title')}
</h2>
<p className='mx-auto max-w-2xl text-gray-600'>
{t('clients.loyalty.works.description')}
</p>
</div>
<div className='grid gap-8 md:grid-cols-4'>
<div className='text-center'>
<div className='mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-red-600 text-2xl font-bold text-white'>
1
</div>
<h3 className='mb-2 text-xl font-bold'>
{t('clients.loyalty.works.stage-1')}
</h3>
<p className='text-gray-600'>
{t('clients.loyalty.works.stage.description-1')}
</p>
</div>
<div className='text-center'>
<div className='mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-red-600 text-2xl font-bold text-white'>
2
</div>
<h3 className='mb-2 text-xl font-bold'>
{t('clients.loyalty.works.stage-2')}
</h3>
<p className='text-gray-600'>
{t('clients.loyalty.works.stage.description-2')}
</p>
</div>
<div className='text-center'>
<div className='mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-red-600 text-2xl font-bold text-white'>
3
</div>
<h3 className='mb-2 text-xl font-bold'>
{t('clients.loyalty.works.stage-3')}
</h3>
<p className='text-gray-600'>
{t('clients.loyalty.works.stage.description-3')}
</p>
</div>
<div className='text-center'>
<div className='mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-red-600 text-2xl font-bold text-white'>
4
</div>
<h3 className='mb-2 text-xl font-bold'>
{t('clients.loyalty.works.stage-4')}
</h3>
<p className='text-gray-600'>
{t('clients.loyalty.works.stage.description-4')}
</p>
</div>
</div>
</div>
</section>
{/* Loyalty Levels */}
<section className='py-16'>
<div className='container mx-auto'>
<div className='mb-12 text-center'>
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
{t('clients.loyalty.works.levels.title')}
</h2>
<p className='mx-auto max-w-2xl text-gray-600'>
{t('clients.loyalty.works.levels.description')}
</p>
</div>
<div className='grid gap-8 md:grid-cols-3'>
<Card className='overflow-hidden border-t-4 border-t-gray-400 transition-all hover:shadow-lg'>
<CardContent className='p-6'>
<h3 className='mb-4 text-center text-2xl font-bold'>
{t('clients.loyalty.works.levels.card-1.title')}
</h3>
<div className='mb-6 text-center'>
<span className='text-4xl font-bold'>
{t('clients.loyalty.works.levels.card-1.percent')}
</span>
<p className='text-sm text-gray-600'>
{t('clients.loyalty.works.levels.card.mark')}
</p>
</div>
<ul className='space-y-2'>
<li className='flex items-center'>
<Check className='mr-2 h-5 w-5 text-green-500' />
<span>
{t('clients.loyalty.works.levels.card-1.bonus-1')}
</span>
</li>
<li className='flex items-center'>
<Check className='mr-2 h-5 w-5 text-green-500' />
<span>
{t('clients.loyalty.works.levels.card-1.bonus-2')}
</span>
</li>
<li className='flex items-center'>
<Check className='mr-2 h-5 w-5 text-green-500' />
<span>
{t('clients.loyalty.works.levels.card-1.bonus-3')}
</span>
</li>
</ul>
</CardContent>
</Card>
<Card className='overflow-hidden border-t-4 border-t-yellow-500 transition-all hover:shadow-lg'>
<CardContent className='p-6'>
<h3 className='mb-4 text-center text-2xl font-bold'>
{t('clients.loyalty.works.levels.card-2.title')}
</h3>
<div className='mb-6 text-center'>
<span className='text-4xl font-bold'>
{t('clients.loyalty.works.levels.card-2.percent')}
</span>
<p className='text-sm text-gray-600'>
{t('clients.loyalty.works.levels.card.mark')}
</p>
</div>
<ul className='space-y-2'>
<li className='flex items-center'>
<Check className='mr-2 h-5 w-5 text-green-500' />
<span>
{t('clients.loyalty.works.levels.card-1.bonus-1')}
</span>
</li>
<li className='flex items-center'>
<Check className='mr-2 h-5 w-5 text-green-500' />
<span>
{t('clients.loyalty.works.levels.card-2.bonus-2')}
</span>
</li>
<li className='flex items-center'>
<Check className='mr-2 h-5 w-5 text-green-500' />
<span>
{t('clients.loyalty.works.levels.card-3.bonus-3')}
</span>
</li>
<li className='flex items-center'>
<Check className='mr-2 h-5 w-5 text-green-500' />
<span>
{t('clients.loyalty.works.levels.card-4.bonus-4')}
</span>
</li>
</ul>
</CardContent>
</Card>
<Card className='overflow-hidden border-t-4 border-t-red-600 transition-all hover:shadow-lg'>
<CardContent className='p-6'>
<h3 className='mb-4 text-center text-2xl font-bold'>
{t('clients.loyalty.works.levels.card-3.title')}
</h3>
<div className='mb-6 text-center'>
<span className='text-4xl font-bold'>
{t('clients.loyalty.works.levels.card-3.percent')}
</span>
<p className='text-sm text-gray-600'>
{t('clients.loyalty.works.levels.card.mark')}
</p>
</div>
<ul className='space-y-2'>
<li className='flex items-center'>
<Check className='mr-2 h-5 w-5 text-green-500' />
<span>
{t('clients.loyalty.works.levels.card-3.bonus-1')}
</span>
</li>
<li className='flex items-center'>
<Check className='mr-2 h-5 w-5 text-green-500' />
<span>
{t('clients.loyalty.works.levels.card-3.bonus-2')}
</span>
</li>
<li className='flex items-center'>
<Check className='mr-2 h-5 w-5 text-green-500' />
<span>
{t('clients.loyalty.works.levels.card-3.bonus-3')}
</span>
</li>
<li className='flex items-center'>
<Check className='mr-2 h-5 w-5 text-green-500' />
<span>
{t('clients.loyalty.works.levels.card-3.bonus-4')}
</span>
</li>
<li className='flex items-center'>
<Check className='mr-2 h-5 w-5 text-green-500' />
<span>
{t('clients.loyalty.works.levels.card-3.bonus-5')}
</span>
</li>
</ul>
</CardContent>
</Card>
</div>
</div>
</section>
<CtaSection />
</main>
</div>
);
}

View File

@ -33,8 +33,8 @@ export default function AboutCounter() {
}, []);
return (
<div ref={sectionRef} className='my-8 grid grid-cols-3 gap-6 text-center'>
<div className='transform rounded-lg bg-white p-6 shadow-md transition-transform hover:scale-105'>
<div ref={sectionRef} className='my-8 grid grid-cols-1 gap-6 text-center'>
<div className='transform rounded-lg bg-white p-3 shadow-md transition-transform hover:scale-105 sm:p-6'>
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
<Users className='h-6 w-6 text-red-600' />
</div>
@ -43,7 +43,7 @@ export default function AboutCounter() {
</h3>
<p className='text-gray-600'>Сотрудников</p>
</div>
<div className='transform rounded-lg bg-white p-6 shadow-md transition-transform hover:scale-105'>
<div className='transform rounded-lg bg-white p-3 shadow-md transition-transform hover:scale-105 sm:p-6'>
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
<Users className='h-6 w-6 text-red-600' />
</div>
@ -52,7 +52,7 @@ export default function AboutCounter() {
</h3>
<p className='text-gray-600'>Литров топлива в месяц</p>
</div>
<div className='transform rounded-lg bg-white p-6 shadow-md transition-transform hover:scale-105'>
<div className='transform rounded-lg bg-white p-3 shadow-md transition-transform hover:scale-105 sm:p-6'>
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
<Users className='h-6 w-6 text-red-600' />
</div>

View File

@ -1,11 +1,13 @@
'use client';
import { ChevronLeft, ChevronRight } from 'lucide-react';
import { ChevronLeft, ChevronRight} from 'lucide-react';
import Image from 'next/image';
import { useEffect, useState } from 'react';
import { Button } from '@/shared/shadcn-ui/button';
import { Card, CardContent } from '@/shared/shadcn-ui/card';
import Link from 'next/link';
import { useLanguage } from '../language';
const promotions = [
{
@ -43,6 +45,8 @@ export default function PromotionSlider() {
const [currentIndex, setCurrentIndex] = useState(0);
const [visibleItems, setVisibleItems] = useState(3);
const { t } = useLanguage()
useEffect(() => {
const handleResize = () => {
if (window.innerWidth < 640) {
@ -106,13 +110,15 @@ export default function PromotionSlider() {
<span className='text-xs text-gray-500'>
Действует до: {promo.validUntil}
</span>
<Link href='#'>
<Button
variant='outline'
size='sm'
className='border-red-600 text-red-600 hover:bg-red-50'
>
Подробнее
</Button>
variant='outline'
size='sm'
className='border-red-600 text-red-600 hover:bg-red-50'
>
{t('common.buttons.readMore')}
</Button>
</Link>
</div>
</CardContent>
</Card>

View File

@ -1,6 +1,5 @@
{
"common.buttons.readMore": "Read More",
"common.buttons.viewAll": "View All",
"common.buttons.findStation": "Find Station",
"common.buttons.learnMore": "Learn More",
"common.buttons.download": "Download",
@ -13,7 +12,7 @@
"common.buttons.filter": "Filter",
"common.buttons.resetFilters": "Reset Filters",
"common.buttons.downloadApp": "Download App",
"common.buttons.getLoyaltyCard": "Get Loyalty Card",
"common.buttons.purchaseCardAtGasStations": "Purchase a card at gas stations",
"common.buttons.sendResume": "Send Resume",
"common.buttons.showAllStations": "Show All Stations",
"common.buttons.allPromotions": "All Promotions",
@ -30,8 +29,6 @@
"common.footer.contacts": "Contacts",
"common.footer.navigation": "Navigation",
"common.footer.subscribe": "Subscribe",
"common.footer.subscribeText": "Subscribe to our newsletter to receive news and special offers.",
"common.footer.yourEmail": "Your email",
"common.footer.rights": "All rights reserved.",
@ -83,8 +80,7 @@
"certificates.title": "Our Certificates",
"certificates.description": "GasNetwork adheres to high standards of quality and safety. Our certificates confirm the compliance of our products and services with international and national standards.",
"certificates.requestInfo": "Request Additional Information",
"certificates.requestInfoText": "If you need additional information about our certificates or would like to receive copies of documents, please contact our quality department.",
"certificates.issueDate": "Issue Date",
"certificates.expiryDate": "Valid Until",
"certificates.faq": "Frequently Asked Questions",

View File

@ -1,19 +1,22 @@
{
"common.contacts.address": "ул. Рудаки 137, Душанбе, Таджикистан",
"common.contacts.tel": "+992 (37) 223-45-67",
"common.contacts.email": "info@gasnetwork.tj",
"common.buttons.readMore": "Подробнее",
"common.buttons.viewAll": "Смотреть все",
"common.buttons.findStation": "Найти заправку",
"common.buttons.learnMore": "Узнать больше",
"common.buttons.download": "Скачать",
"common.buttons.view": "Просмотр",
"common.buttons.contactUs": "Связаться с нами",
"common.buttons.apply": "Оформить",
"common.buttons.apply": "Подать заявку",
"common.buttons.login": "Вход",
"common.buttons.logout": "Выйти",
"common.buttons.submit": "Отправить",
"common.buttons.filter": "Фильтры",
"common.buttons.resetFilters": "Сбросить фильтры",
"common.buttons.downloadApp": "Скачать приложение",
"common.buttons.getLoyaltyCard": "Получить карту лояльности",
"common.buttons.purchaseCardAtGasStations": "Приобретайте карту в сети АЗС",
"common.buttons.sendResume": "Отправить резюме",
"common.buttons.showAllStations": "Показать все заправки",
"common.buttons.allPromotions": "Все акции",
@ -30,14 +33,17 @@
"common.footer.contacts": "Контакты",
"common.footer.navigation": "Навигация",
"common.footer.subscribe": "Подписка",
"common.footer.subscribeText": "Подпишитесь на нашу рассылку, чтобы получать новости и специальные предложения.",
"common.footer.yourEmail": "Ваш email",
"common.footer.rights": "Все права защищены.",
"home.hero.title": "Сеть современных заправок в Таджикистане",
"home.hero.description": "Качественное топливо, удобное расположение и отличный сервис для наших клиентов",
"home.stats.stations": "Заправок по стране",
"home.stats.daily": "Клиентов ежедневно",
"home.stats.years": "Лет на рынке",
"home.stats.mode": "Работаем круглосуточно",
"home.about.title": "О нашей компании",
"home.about.description1": "Наша сеть заправок является одной из ведущих в Таджикистане. Мы предоставляем качественное топливо и высокий уровень обслуживания для наших клиентов уже более 15 лет.",
"home.about.description2": "Мы постоянно развиваемся, открывая новые станции и улучшая сервис на существующих. Наша цель - сделать заправку автомобиля максимально удобной и быстрой для каждого клиента.",
@ -48,6 +54,80 @@
"home.about.features.staff.title": "Профессиональный персонал",
"home.about.features.staff.description": "Наши сотрудники - профессионалы своего дела",
"about.hero.imageAlt": "О нашей компании",
"about.hero.title": "О нашей компании",
"about.hero.subtitle": "Узнайте больше о нашей истории, ценностях и миссии. Мы стремимся предоставлять лучший сервис и качественное топливо для наших клиентов.",
"about.overview.title": "Лидер на рынке Таджикистана",
"about.overview.description1": "GasNetwork - ведущая сеть автозаправочных станций в Таджикистане, предоставляющая высококачественное топливо и превосходный сервис. Наша компания была основана в 2008 году и с тех пор стала символом надежности и качества в энергетическом секторе страны.",
"about.overview.description2": "Мы гордимся тем, что предлагаем нашим клиентам только лучшее топливо, соответствующее международным стандартам качества. Наши заправочные станции оснащены современным оборудованием, которое обеспечивает быстрое и безопасное обслуживание.",
"about.overview.description3": "Наша миссия - сделать поездки наших клиентов комфортными и безопасными, предоставляя качественное топливо и отличный сервис по всей стране.",
"about.overview.imageAlt": "Главный офис GasNetwork",
"about.overview.benefits.0.title": "Качество",
"about.overview.benefits.0.description": "Топливо высшего стандарта",
"about.overview.benefits.1.title": "Сервис",
"about.overview.benefits.1.description": "Профессиональное обслуживание",
"about.overview.benefits.2.title": "Инновации",
"about.overview.benefits.2.description": "Современные технологии",
"about.overview.benefits.3.title": "Доступность",
"about.overview.benefits.3.description": "Станции по всей стране",
"about.stats.title": "GasNetwork в цифрах",
"about.stats.subtitle": "Наши достижения и рост за годы работы на рынке Таджикистана",
"about.stats.items.0.value": "25",
"about.stats.items.0.suffix": "+",
"about.stats.items.0.label": "Заправок по стране",
"about.stats.items.1.value": "15",
"about.stats.items.1.label": "Лет на рынке",
"about.stats.items.2.value": "150",
"about.stats.items.2.suffix": "+",
"about.stats.items.2.label": "Сотрудников",
"about.stats.items.3.value": "1000000",
"about.stats.items.3.suffix": "+",
"about.stats.items.3.label": "Клиентов в год",
"about.history.title": "Наша история",
"about.history.subtitle": "История развития нашей компании от небольшой сети до лидера рынка",
"about.stations.title": "Наши заправочные станции",
"about.stations.subtitle": "Современные заправочные станции, оснащенные по последнему слову техники",
"about.stations.description": "Наши заправочные станции расположены в стратегически важных точках по всему Таджикистану, обеспечивая удобный доступ для всех наших клиентов.",
"about.stations.buttonText": "Найти ближайшую заправку",
"about.values.title": "Наши ценности",
"about.values.subtitle": "Принципы, которыми мы руководствуемся в нашей работе",
"about.values.items.0.title": "Качество",
"about.values.items.0.description": "Мы предлагаем только высококачественное топливо, соответствующее международным стандартам. Регулярные проверки и контроль качества гарантируют, что наши клиенты получают лучшее.",
"about.values.items.1.title": "Клиентоориентированность",
"about.values.items.1.description": "Наши клиенты - наш главный приоритет. Мы стремимся предоставить лучший сервис, удобные условия и приятную атмосферу на каждой нашей заправке.",
"about.values.items.2.title": "Профессионализм",
"about.values.items.2.description": "Наши сотрудники - профессионалы своего дела. Мы постоянно инвестируем в их обучение и развитие, чтобы обеспечить высокий уровень обслуживания.",
"about.team.title": "Наша команда",
"about.team.subtitle": "Познакомьтесь с профессионалами, которые делают GasNetwork лучшей сетью заправок в Таджикистане",
"about.team.members.0.name": "Алишер Рахмонов",
"about.team.members.0.position": "Генеральный директор",
"about.team.members.1.name": "Фарида Каримова",
"about.team.members.1.position": "Финансовый директор",
"about.team.members.2.name": "Рустам Назаров",
"about.team.members.2.position": "Технический директор",
"about.team.members.3.name": "Зарина Шарипова",
"about.team.members.3.position": "Директор по маркетингу",
"about.testimonials.title": "Отзывы клиентов",
"about.testimonials.subtitle": "Что говорят о нас наши клиенты",
"about.testimonials.items.0.name": "Фархад К.",
"about.testimonials.items.0.text": "Я всегда заправляюсь только на GasNetwork. Качество топлива на высоте, а обслуживание всегда приветливое и быстрое.",
"about.testimonials.items.0.rating": "5",
"about.testimonials.items.1.name": "Нигина М.",
"about.testimonials.items.1.text": "Очень удобно, что заправки расположены по всему городу. Всегда чисто, есть кафе и магазин. Рекомендую!",
"about.testimonials.items.1.rating": "5",
"about.testimonials.items.2.name": "Джамшед Р.",
"about.testimonials.items.2.text": "Пользуюсь картой лояльности GasNetwork уже 3 года. Накопил много бонусов и получил немало приятных подарков. Отличный сервис!",
"about.testimonials.items.2.rating": "4",
"home.stations.title": "Наши заправки",
"home.stations.description": "Найдите ближайшую к вам заправку нашей сети. Мы расположены в удобных местах по всему Таджикистану.",
@ -81,10 +161,62 @@
"home.cta.title": "Присоединяйтесь к нам",
"home.cta.description": "Станьте частью нашей сети. Получайте специальные предложения, бонусы и скидки.",
"clients.title": "Для наших клиентов",
"clients.description": "Специальные предложения, программы лояльности и удобные способы оплаты для наших клиентов",
"clients.services": "Наши услуги для клиентов",
"clients.services.description": "Мы стремимся сделать обслуживание на наших заправках максимально удобным и выгодным для вас",
"clients.loyalty.title": "Программа лояльности",
"clients.loyalty.description": "Накапливайте баллы и получайте скидки на топливо и услуги нашей сети",
"clients.loyalty.programm.about": "О программе лояльности",
"clients.loyalty.programm.about-description": "Программа лояльности GasNetwork — это возможность получать баллы за каждую покупку топлива и услуг на наших заправочных станциях. Накопленные баллы можно обменять на скидки, подарки или дополнительные услуги.",
"clients.loyalty.programm.about-description-2": "Участие в программе абсолютно бесплатное. Вам нужно только получить карту лояльности в любой нашей заправочной станции или зарегистрироваться в мобильном приложении.",
"clients.loyalty.programm.conditions-1": "1 литр = 1 балл",
"clients.loyalty.programm.conditions.description-1": "За каждый литр топлива вы получаете 1 балл",
"clients.loyalty.programm.conditions-2": "Дополнительные баллы",
"clients.loyalty.programm.conditions.description-2": "За покупки в магазине и кафе на заправке",
"clients.loyalty.programm.conditions-3": "Специальные акции",
"clients.loyalty.programm.conditions.description-3": "Удвоенные и утроенные баллы в праздничные дни",
"clients.loyalty.works.title": "Как это работает",
"clients.loyalty.works.description": "Простые шаги для участия в программе лояльности GasNetwork",
"clients.loyalty.works.stage-1": "Получите карту",
"clients.loyalty.works.stage.description-1": "Получите карту лояльности на любой заправке GasNetwork или зарегистрируйтесь в мобильном приложении",
"clients.loyalty.works.stage-2": "Заправляйтесь",
"clients.loyalty.works.stage.description-2": "Используйте карту при каждой заправке и покупке в магазинах на наших АЗС",
"clients.loyalty.works.stage-3": "Накапливайте баллы",
"clients.loyalty.works.stage.description-3": "Получайте баллы за каждую покупку и следите за их накоплением в приложении",
"clients.loyalty.works.stage-4": "Получайте выгоду",
"clients.loyalty.works.stage.description-4": "Обменивайте накопленные баллы на скидки, подарки или дополнительные услуги",
"clients.loyalty.works.levels.title": "Уровни лояльности",
"clients.loyalty.works.levels.description": "Чем больше вы заправляетесь, тем больше преимуществ получаете",
"clients.loyalty.works.levels.card.mark": "возврат баллами",
"clients.loyalty.works.levels.card-1.title": "Стандарт",
"clients.loyalty.works.levels.card-1.percent": "1%",
"clients.loyalty.works.levels.card-1.bonus-1": "1 балл за каждый литр топлива",
"clients.loyalty.works.levels.card-1.bonus-2": "Участие в акциях",
"clients.loyalty.works.levels.card-1.bonus-3": "Доступ к мобильному приложению",
"clients.loyalty.works.levels.card-2.title": "Золотой",
"clients.loyalty.works.levels.card-2.percent": "2%",
"clients.loyalty.works.levels.card-2.bonus-1": "2 балла за каждый литр топлива",
"clients.loyalty.works.levels.card-2.bonus-2": "Скидка 5% в кафе на заправках",
"clients.loyalty.works.levels.card-2.bonus-3": "Приоритетное обслуживание",
"clients.loyalty.works.levels.card-2.bonus-4": "Эксклюзивные акции",
"clients.loyalty.works.levels.card-3.title": "Платиновый",
"clients.loyalty.works.levels.card-3.percent": "3%",
"clients.loyalty.works.levels.card-3.bonus-1": "3 балла за каждый литр топлива",
"clients.loyalty.works.levels.card-3.bonus-2": "Скидка 10% в кафе на заправках",
"clients.loyalty.works.levels.card-3.bonus-3": "Бесплатная мойка раз в месяц",
"clients.loyalty.works.levels.card-3.bonus-4": "Персональный менеджер",
"clients.loyalty.works.levels.card-3.bonus-5": "VIP-обслуживание",
"certificates.title": "Наши сертификаты",
"certificates.description": "GasNetwork придерживается высоких стандартов качества и безопасности. Наши сертификаты подтверждают соответствие нашей продукции и услуг международным и национальным стандартам.",
"certificates.requestInfo": "Запросить дополнительную информацию",
"certificates.requestInfoText": "Если вам требуется дополнительная информация о наших сертификатах или вы хотите получить копии документов, пожалуйста, свяжитесь с нашим отделом качества.",
"certificates.issueDate": "Дата выдачи",
"certificates.expiryDate": "Действителен до",
"certificates.faq": "Часто задаваемые вопросы",

View File

@ -0,0 +1,36 @@
import { cva, type VariantProps } from 'class-variance-authority';
import * as React from 'react';
import { cn } from '@/shared/lib/utils';
const badgeVariants = cva(
'focus:ring-ring inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:ring-2 focus:ring-offset-2 focus:outline-none',
{
variants: {
variant: {
default:
'bg-primary text-primary-foreground hover:bg-primary/80 border-transparent',
secondary:
'bg-secondary text-secondary-foreground hover:bg-secondary/80 border-transparent',
destructive:
'bg-destructive text-destructive-foreground hover:bg-destructive/80 border-transparent',
outline: 'text-foreground',
},
},
defaultVariants: {
variant: 'default',
},
},
);
export interface BadgeProps
extends React.HTMLAttributes<HTMLDivElement>,
VariantProps<typeof badgeVariants> {}
function Badge({ className, variant, ...props }: BadgeProps) {
return (
<div className={cn(badgeVariants({ variant }), className)} {...props} />
);
}
export { Badge, badgeVariants };

View File

@ -0,0 +1,70 @@
'use client';
import { ChevronLeft, ChevronRight } from 'lucide-react';
import * as React from 'react';
import { DayPicker } from 'react-day-picker';
import { cn } from '@/shared/lib/utils';
import { buttonVariants } from '@/shared/shadcn-ui/button';
export type CalendarProps = React.ComponentProps<typeof DayPicker>;
function Calendar({
className,
classNames,
showOutsideDays = true,
...props
}: CalendarProps) {
return (
<DayPicker
showOutsideDays={showOutsideDays}
className={cn('p-3', className)}
classNames={{
months: 'flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0',
month: 'space-y-4',
caption: 'flex justify-center pt-1 relative items-center',
caption_label: 'text-sm font-medium',
nav: 'space-x-1 flex items-center',
nav_button: cn(
buttonVariants({ variant: 'outline' }),
'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',
),
nav_button_previous: 'absolute left-1',
nav_button_next: 'absolute right-1',
table: 'w-full border-collapse space-y-1',
head_row: 'flex',
head_cell:
'text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]',
row: 'flex w-full mt-2',
cell: 'h-9 w-9 text-center text-sm p-0 relative [&:has([aria-selected].day-range-end)]:rounded-r-md [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20',
day: cn(
buttonVariants({ variant: 'ghost' }),
'h-9 w-9 p-0 font-normal aria-selected:opacity-100',
),
day_range_end: 'day-range-end',
day_selected:
'bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground',
day_today: 'bg-accent text-accent-foreground',
day_outside:
'day-outside text-muted-foreground aria-selected:bg-accent/50 aria-selected:text-muted-foreground',
day_disabled: 'text-muted-foreground opacity-50',
day_range_middle:
'aria-selected:bg-accent aria-selected:text-accent-foreground',
day_hidden: 'invisible',
...classNames,
}}
components={{
IconLeft: ({ className, ...props }) => (
<ChevronLeft className={cn('h-4 w-4', className)} {...props} />
),
IconRight: ({ className, ...props }) => (
<ChevronRight className={cn('h-4 w-4', className)} {...props} />
),
}}
{...props}
/>
);
}
Calendar.displayName = 'Calendar';
export { Calendar };

View File

@ -0,0 +1,30 @@
'use client';
import { cn } from '@/shared/lib/utils';
import * as PopoverPrimitive from '@radix-ui/react-popover';
import * as React from 'react';
const Popover = PopoverPrimitive.Root;
const PopoverTrigger = PopoverPrimitive.Trigger;
const PopoverContent = React.forwardRef<
React.ComponentRef<typeof PopoverPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
>(({ className, align = 'center', sideOffset = 4, ...props }, ref) => (
<PopoverPrimitive.Portal>
<PopoverPrimitive.Content
ref={ref}
align={align}
sideOffset={sideOffset}
className={cn(
'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-[--radix-popover-content-transform-origin] rounded-md border p-4 shadow-md outline-none',
className,
)}
{...props}
/>
</PopoverPrimitive.Portal>
));
PopoverContent.displayName = PopoverPrimitive.Content.displayName;
export { Popover, PopoverTrigger, PopoverContent };

View File

@ -0,0 +1,117 @@
import * as React from 'react';
import { cn } from '@/shared/lib/utils';
const Table = React.forwardRef<
HTMLTableElement,
React.HTMLAttributes<HTMLTableElement>
>(({ className, ...props }, ref) => (
<div className='relative w-full overflow-auto'>
<table
ref={ref}
className={cn('w-full caption-bottom text-sm', className)}
{...props}
/>
</div>
));
Table.displayName = 'Table';
const TableHeader = React.forwardRef<
HTMLTableSectionElement,
React.HTMLAttributes<HTMLTableSectionElement>
>(({ className, ...props }, ref) => (
<thead ref={ref} className={cn('[&_tr]:border-b', className)} {...props} />
));
TableHeader.displayName = 'TableHeader';
const TableBody = React.forwardRef<
HTMLTableSectionElement,
React.HTMLAttributes<HTMLTableSectionElement>
>(({ className, ...props }, ref) => (
<tbody
ref={ref}
className={cn('[&_tr:last-child]:border-0', className)}
{...props}
/>
));
TableBody.displayName = 'TableBody';
const TableFooter = React.forwardRef<
HTMLTableSectionElement,
React.HTMLAttributes<HTMLTableSectionElement>
>(({ className, ...props }, ref) => (
<tfoot
ref={ref}
className={cn(
'bg-muted/50 border-t font-medium [&>tr]:last:border-b-0',
className,
)}
{...props}
/>
));
TableFooter.displayName = 'TableFooter';
const TableRow = React.forwardRef<
HTMLTableRowElement,
React.HTMLAttributes<HTMLTableRowElement>
>(({ className, ...props }, ref) => (
<tr
ref={ref}
className={cn(
'hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors',
className,
)}
{...props}
/>
));
TableRow.displayName = 'TableRow';
const TableHead = React.forwardRef<
HTMLTableCellElement,
React.ThHTMLAttributes<HTMLTableCellElement>
>(({ className, ...props }, ref) => (
<th
ref={ref}
className={cn(
'text-muted-foreground h-12 px-4 text-left align-middle font-medium [&:has([role=checkbox])]:pr-0',
className,
)}
{...props}
/>
));
TableHead.displayName = 'TableHead';
const TableCell = React.forwardRef<
HTMLTableCellElement,
React.TdHTMLAttributes<HTMLTableCellElement>
>(({ className, ...props }, ref) => (
<td
ref={ref}
className={cn('p-4 align-middle [&:has([role=checkbox])]:pr-0', className)}
{...props}
/>
));
TableCell.displayName = 'TableCell';
const TableCaption = React.forwardRef<
HTMLTableCaptionElement,
React.HTMLAttributes<HTMLTableCaptionElement>
>(({ className, ...props }, ref) => (
<caption
ref={ref}
className={cn('text-muted-foreground mt-4 text-sm', className)}
{...props}
/>
));
TableCaption.displayName = 'TableCaption';
export {
Table,
TableHeader,
TableBody,
TableFooter,
TableHead,
TableRow,
TableCell,
TableCaption,
};

View File

@ -74,18 +74,22 @@ export function CompanyTimeline() {
data-aos='zoom-in-down'
>
<div className='mb-2 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
<Calendar className='h-5 w-5 text-red-600' />
<Calendar className='size-5 text-red-600' />
</div>
<h3 className='text-xl font-bold'>{event.year}</h3>
<h4 className='mb-2 text-lg font-semibold'>{event.title}</h4>
</div>
<div
className={`${index % 2 === 0 ? 'md:pl-10' : 'md:order-first md:pr-10 md:text-right'}`}
className={
index % 2 === 0
? 'md:pl-10'
: 'md:order-first md:pr-10 md:text-right'
}
>
<Card
className='overflow-hidden transition-all hover:shadow-md'
data-aos={index % 2 === 0 ? 'fade-left' : 'fade-right'}
data-aos={'fade-up'}
>
<CardContent className='p-4'>
<p className='text-gray-600'>{event.description}</p>
@ -94,8 +98,8 @@ export function CompanyTimeline() {
</div>
</div>
<div className='absolute top-5 left-1/2 -ml-3 hidden h-6 w-6 items-center justify-center rounded-full bg-red-600 md:flex'>
<div className='h-3 w-3 rounded-full bg-white'></div>
<div className='absolute top-5 left-1/2 -ml-3 hidden size-6 items-center justify-center rounded-full bg-red-600 md:flex'>
<div className='size-3 rounded-full bg-white'></div>
</div>
</div>
))}
@ -105,16 +109,18 @@ export function CompanyTimeline() {
<div className='mt-8 text-center'>
<Button
variant='outline'
onClick={() => setExpanded(!expanded)}
onClick={() => {
setExpanded(!expanded);
}}
className='inline-flex items-center'
>
{expanded ? (
<>
Свернуть <ChevronUp className='ml-2 h-4 w-4' />
Свернуть <ChevronUp className='ml-2 size-4' />
</>
) : (
<>
Показать больше <ChevronDown className='ml-2 h-4 w-4' />
Показать больше <ChevronDown className='ml-2 size-4' />
</>
)}
</Button>

View File

@ -10,7 +10,7 @@ export const AboutSection = () => {
const { t } = useLanguage();
return (
<section id='about' className='py-16'>
<section id='about' className='px-2 py-8 sm:py-16'>
<div className='container mx-auto'>
<div className='grid items-center gap-12 md:grid-cols-2'>
<div>
@ -24,47 +24,7 @@ export const AboutSection = () => {
<p className='mb-6 text-gray-600'>{t('home.about.description2')}</p>
<AboutCounter />
<div className='space-y-4'>
<div className='flex items-start'>
<div className='mt-1 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-red-600'>
<span className='text-xs text-white'></span>
</div>
<div className='ml-3'>
<h3 className='text-lg font-medium'>
{t('home.about.features.quality.title')}
</h3>
<p className='text-gray-600'>
{t('home.about.features.quality.description')}
</p>
</div>
</div>
<div className='flex items-start'>
<div className='mt-1 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-red-600'>
<span className='text-xs text-white'></span>
</div>
<div className='ml-3'>
<h3 className='text-lg font-medium'>
{t('home.about.features.equipment.title')}
</h3>
<p className='text-gray-600'>
{t('home.about.features.equipment.description')}
</p>
</div>
</div>
<div className='flex items-start'>
<div className='mt-1 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-red-600'>
<span className='text-xs text-white'></span>
</div>
<div className='ml-3'>
<h3 className='text-lg font-medium'>
{t('home.about.features.staff.title')}
</h3>
<p className='text-gray-600'>
{t('home.about.features.staff.description')}
</p>
</div>
</div>
</div>
<Features />
</div>
<div
className='relative h-[400px] overflow-hidden rounded-xl shadow-xl'
@ -82,3 +42,45 @@ export const AboutSection = () => {
</section>
);
};
interface Feature {
title: string;
description: string;
}
const features: Array<Feature> = [
{
title: 'home.about.features.quality.title',
description: 'home.about.features.quality.description',
},
{
title: 'home.about.features.equipment.title',
description: 'home.about.features.equipment.description',
},
{
title: 'home.about.features.staff.title',
description: 'home.about.features.staff.description',
},
];
const Features = () => {
const { t } = useLanguage();
return (
<div className='space-y-4'>
{features.map(({ title, description }) => {
return (
<div key={title} className='flex items-start'>
<div className='mt-1 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-red-600'>
<span className='text-xs text-white'></span>
</div>
<div className='ml-3'>
<h3 className='text-lg font-medium'>{t(title)}</h3>
<p className='text-gray-600'>{t(description)}</p>
</div>
</div>
);
})}
</div>
);
};

View File

@ -0,0 +1,76 @@
'use client';
import { BarChart, CreditCard, Download, FileText } from 'lucide-react';
import { Button } from '@/shared/shadcn-ui/button';
import { Card, CardContent } from '@/shared/shadcn-ui/card';
interface CardsListProps {
totalCards: number;
}
export const CardsList = ({ totalCards }: CardsListProps) => {
return (
<div className='mb-10'>
<div className='mb-4 flex items-center justify-between'>
<h2 className='text-2xl font-bold'>Топливные карты</h2>
<div className='flex gap-2'>
<Button variant='outline' className='gap-2'>
<Download className='h-4 w-4' />
Экспорт данных
</Button>
<Button variant='outline' className='gap-2'>
<FileText className='h-4 w-4' />
Отчеты
</Button>
<Button variant='outline' className='gap-2'>
<BarChart className='h-4 w-4' />
Аналитика
</Button>
</div>
</div>
<div className='grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4'>
{Array.from({ length: 4 }).map((_, index) => (
<Card key={index} className='overflow-hidden'>
<CardContent className='p-0'>
<div className='bg-gradient-to-r from-gray-800 to-gray-900 p-4 text-white'>
<div className='flex items-start justify-between'>
<div>
<p className='mb-1 text-xs text-gray-300'>
Карта #{index + 1}
</p>
<p className='font-medium'>**** **** **** {1000 + index}</p>
</div>
<CreditCard className='h-6 w-6 text-gray-300' />
</div>
</div>
<div className='p-4'>
<div className='mb-2 flex items-center justify-between'>
<p className='text-sm text-gray-500'>Лимит:</p>
<p className='font-medium'>
{(5000 * (index + 1)).toLocaleString()} сомони
</p>
</div>
<div className='flex items-center justify-between'>
<p className='text-sm text-gray-500'>Статус:</p>
<span className='inline-flex items-center rounded-full bg-green-100 px-2.5 py-0.5 text-xs font-medium text-green-800'>
Активна
</span>
</div>
</div>
</CardContent>
</Card>
))}
{/* Show more cards button */}
{totalCards > 4 && (
<Button
variant='outline'
className='h-full min-h-[120px] border-dashed'
>
Показать все карты ({totalCards})
</Button>
)}
</div>
</div>
);
};

View File

@ -2,6 +2,7 @@
import { ChevronRight, Heart } from 'lucide-react';
import Image from 'next/image';
import Link from 'next/link';
import { useLanguage } from '@/shared/language';
import { Button } from '@/shared/shadcn-ui/button';
@ -10,12 +11,12 @@ export const CharitySection = () => {
const { t } = useLanguage();
return (
<section id='charity' className='py-16'>
<section id='charity' className='px-2 py-8 sm:py-16'>
<div className='container mx-auto'>
<div className='grid items-center gap-12 md:grid-cols-2'>
<div
className='relative order-2 h-[400px] overflow-hidden rounded-xl shadow-xl md:order-1'
data-aos='zoom-out-up'
className='relative order-2 h-[400px] w-full overflow-hidden rounded-xl shadow-xl md:order-1'
data-aos='zoom-in'
>
<Image
src='/placeholder.svg?height=400&width=600'
@ -28,7 +29,7 @@ export const CharitySection = () => {
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
<Heart className='h-6 w-6 text-red-600' />
</div>
<h2 className='mb-6 text-3xl font-bold tracking-tight sm:text-4xl'>
<h2 className='mb-6 text-xl font-bold tracking-tight sm:text-4xl'>
{t('home.charity.title')}
</h2>
<p className='mb-6 text-gray-600'>
@ -53,9 +54,9 @@ export const CharitySection = () => {
<span>{t('home.charity.sports')}</span>
</li>
</ul>
<Button className='bg-red-600 hover:bg-red-700'>
{t('home.charity.learnMore')}
</Button>
<Link href={'/charity'}>
<Button>{t('home.charity.learnMore')}</Button>
</Link>
</div>
</div>
</div>

View File

@ -0,0 +1,74 @@
import { Percent } from 'lucide-react';
import Image from 'next/image';
interface Benefit {
title: string;
description: string;
}
const benefits: Array<Benefit> = [
{
title: 'Экономия',
description: 'Скидки и бонусы для постоянных клиентов',
},
{
title: 'Удобство',
description: 'Быстрая оплата и обслуживание',
},
{
title: 'Качество',
description: 'Гарантированно высокое качество топлива',
},
{
title: 'Дополнительные услуги',
description: 'Кафе, магазины и другие услуги на наших заправках',
},
];
export const BenefitsSection = () => {
return (
<section className='bg-gray-50 py-16'>
<div className='container mx-auto'>
<div className='grid items-center gap-12 md:grid-cols-2'>
<div className='order-2 md:order-1'>
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
<Percent className='h-6 w-6 text-red-600' />
</div>
<h2 className='mb-6 text-3xl font-bold tracking-tight sm:text-4xl'>
Преимущества для клиентов
</h2>
<p className='mb-6 text-gray-600'>
Став клиентом GasNetwork, вы получаете множество преимуществ,
которые делают заправку вашего автомобиля более выгодной и
удобной.
</p>
<div className='space-y-4'>
{benefits.map(({ title, description }) => {
return (
<div key={title} className='flex items-start'>
<div className='mt-1 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-red-600'>
<span className='text-xs text-white'></span>
</div>
<div className='ml-3'>
<h3 className='text-lg font-medium'>{title}</h3>
<p className='text-gray-600'>{description}</p>
</div>
</div>
);
})}
</div>
</div>
<div className='relative order-1 h-[400px] overflow-hidden rounded-xl shadow-xl md:order-2'>
<Image
src='/placeholder.svg?height=400&width=600&text=Преимущества+для+клиентов'
alt='Преимущества для клиентов'
fill
className='object-cover'
/>
</div>
</div>
</div>
</section>
);
};

View File

@ -0,0 +1,83 @@
import { CreditCard, type LucideProps, Percent, Wallet } from 'lucide-react';
import { type ForwardRefExoticComponent, type RefAttributes } from 'react';
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from '@/shared/shadcn-ui/card';
interface ServiceOverview {
title: string;
description: string;
contentText: string;
Icon: ForwardRefExoticComponent<
Omit<LucideProps, 'ref'> & RefAttributes<SVGSVGElement>
>;
}
const servicesOverview: Array<ServiceOverview> = [
{
title: 'Программа лояльности',
description: 'Накапливайте баллы и получайте скидки',
contentText:
'Наша программа лояльности позволяет накапливать баллы за каждую покупку и обменивать их на скидки и подарки.',
Icon: Percent,
},
{
title: 'Топливная карта',
description: 'Удобный способ оплаты топлива',
contentText:
'Топливные карты для физических и юридических лиц. Контролируйте расходы и получайте дополнительные преимущества.',
Icon: CreditCard,
},
{
title: 'Способы оплаты',
description: 'Различные способы оплаты на наших заправках',
contentText:
'Мы предлагаем различные способы оплаты: наличные, банковские карты, мобильные платежи и топливные карты.',
Icon: Wallet,
},
];
export const ServicesOverviewSection = () => {
return (
<section className='py-16'>
<div className='container mx-auto'>
<div className='mb-12 text-center'>
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
Наши услуги для клиентов
</h2>
<p className='mx-auto max-w-2xl text-gray-600'>
Мы стремимся сделать обслуживание на наших заправках максимально
удобным и выгодным для вас
</p>
</div>
<div className='grid gap-3 md:grid-cols-2 md:gap-6 lg:grid-cols-3'>
{servicesOverview.map(({ description, Icon, contentText, title }) => {
return (
<Card
key={title}
className='overflow-hidden transition-all hover:shadow-lg'
>
<CardHeader className='pb-3'>
<div className='mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-red-100'>
<Icon className='h-6 w-6 text-red-600' />
</div>
<CardTitle>{title}</CardTitle>
<CardDescription>{description}</CardDescription>
</CardHeader>
<CardContent className='text-sm text-gray-600'>
<p>{contentText}</p>
</CardContent>
</Card>
);
})}
</div>
</div>
</section>
);
};

View File

@ -1,5 +1,7 @@
'use client';
import Link from 'next/link';
import { useLanguage } from '@/shared/language';
import { Button } from '@/shared/shadcn-ui/button';
@ -7,7 +9,7 @@ export const CtaSection = () => {
const { t } = useLanguage();
return (
<section className='bg-red-600 py-16 text-white'>
<section className='bg-red-600 px-2 py-8 text-white sm:py-16'>
<div className='container mx-auto'>
<div className='flex flex-col items-center text-center'>
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
@ -15,10 +17,11 @@ export const CtaSection = () => {
</h2>
<p className='mb-8 max-w-2xl'>{t('home.cta.description')}</p>
<div className='flex flex-col gap-4 sm:flex-row'>
<Button variant='outline'>{t('common.buttons.downloadApp')}</Button>
<Button className='bg-white text-red-600 hover:bg-gray-100'>
{t('common.buttons.getLoyaltyCard')}
</Button>
<Link href='#'>
<Button variant='secondary'>
{t('common.buttons.purchaseCardAtGasStations')}
</Button>
</Link>
</div>
</div>
</div>

View File

@ -4,15 +4,14 @@ import { Fuel, Mail, MapPin, Phone } from 'lucide-react';
import Link from 'next/link';
import { useLanguage } from '@/shared/language';
import { Button } from '@/shared/shadcn-ui/button';
export const Footer = () => {
const { t } = useLanguage();
return (
<footer className='bg-gray-900 py-12 text-white px-4'>
<footer className='bg-gray-900 px-4 py-12 text-white'>
<div className='containe mx-autor'>
<div className='grid grid-cols-1 gap-8 md:grid-cols-4'>
<div className='grid grid-cols-1 gap-8 md:grid-cols-3'>
<div>
<div className='mb-4 flex items-center gap-2'>
<Fuel className='h-6 w-6 text-red-500' />
@ -67,15 +66,15 @@ export const Footer = () => {
<div className='space-y-3'>
<div className='flex items-start'>
<MapPin className='mt-0.5 mr-3 h-5 w-5 text-red-500' />
<p>ул. Рудаки 137, Душанбе, Таджикистан</p>
<p>{t('common.contacts.address')}</p>
</div>
<div className='flex items-start'>
<Phone className='mt-0.5 mr-3 h-5 w-5 text-red-500' />
<p>+992 (37) 223-45-67</p>
<p>{t('common.contacts.tel')}</p>
</div>
<div className='flex items-start'>
<Mail className='mt-0.5 mr-3 h-5 w-5 text-red-500' />
<p>info@gasnetwork.tj</p>
<p>{t('common.contacts.email')}</p>
</div>
</div>
</div>
@ -120,24 +119,6 @@ export const Footer = () => {
</li>
</ul>
</div>
<div>
<h3 className='mb-4 text-lg font-semibold'>
{t('common.footer.subscribe')}
</h3>
<p className='mb-4 text-gray-400'>
{t('common.footer.subscribeText')}
</p>
<form className='space-y-2'>
<input
type='email'
placeholder={t('common.footer.yourEmail')}
className='w-full rounded-md border border-gray-700 bg-gray-800 px-4 py-2 text-white'
/>
<Button className='w-full bg-red-600 hover:bg-red-700'>
{t('common.footer.subscribe')}
</Button>
</form>
</div>
</div>
<div className='mt-8 border-t border-gray-800 pt-8 text-center text-gray-400'>
<p>

View File

@ -11,8 +11,12 @@ import {
NavigationMenuTrigger,
navigationMenuTriggerStyle,
} from '@/shared/shadcn-ui/navigation-menu';
import { useLanguage } from '@/shared/language';
export function DesktopNav() {
const { t } = useLanguage();
return (
<NavigationMenu className='hidden lg:flex'>
<NavigationMenuList>
@ -22,72 +26,55 @@ export function DesktopNav() {
asChild
className={navigationMenuTriggerStyle()}
>
<span>Главная</span>
<span>{t('common.navigation.home')}</span>
</NavigationMenuLink>
</Link>
</NavigationMenuItem>
<NavigationMenuItem>
<Link href='/about' scroll>
<NavigationMenuLink
asChild
className={navigationMenuTriggerStyle()}
>
<span>О нас</span>
</NavigationMenuLink>
</Link>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuTrigger>Клиентам</NavigationMenuTrigger>
<NavigationMenuContent>
<ul className='grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px]'>
<li className='row-span-4'>
<NavigationMenuLink asChild>
<a
className='flex h-full w-full flex-col justify-end rounded-md bg-gradient-to-b from-red-500 to-red-700 p-6 no-underline outline-none select-none focus:shadow-md'
href='/clients'
>
<div className='mt-4 mb-2 text-lg font-medium text-white'>
Для наших клиентов
</div>
<p className='text-sm leading-tight text-white/90'>
Специальные предложения, программы лояльности и удобные
способы оплаты для наших клиентов
</p>
</a>
</NavigationMenuLink>
</li>
<ListItem href='/clients/loyalty' title='Программа лояльности'>
Накапливайте баллы и получайте скидки на топливо и услуги
</ListItem>
<ListItem href='/clients/fuel-card' title='Топливная карта'>
Удобный способ оплаты топлива для физических и юридических лиц
</ListItem>
<ListItem href='/clients/certificates' title='Сертификаты'>
Подарочные сертификаты на топливо и услуги нашей сети
</ListItem>
<ListItem href='/clients/payment' title='Способы оплаты'>
Различные способы оплаты на наших заправочных станциях
</ListItem>
</ul>
</NavigationMenuContent>
</NavigationMenuItem>
<NavigationMenuItem>
<Link href='/#stations' scroll>
<NavigationMenuLink
asChild
className={navigationMenuTriggerStyle()}
>
<span>Наши заправки</span>
<span>{t('common.navigation.stations')}</span>
</NavigationMenuLink>
</Link>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuTrigger>{t('common.navigation.clients')}</NavigationMenuTrigger>
<NavigationMenuContent>
<ul className='grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px]'>
<li className='row-span-4'>
<NavigationMenuLink asChild>
<Link
className='flex h-full w-full flex-col justify-end rounded-md bg-gradient-to-b from-red-500 to-red-700 p-6 no-underline outline-none select-none focus:shadow-md'
href='/clients'
>
<div className='mt-4 mb-2 text-lg font-medium text-white'>
{t('clients.title')}
</div>
<p className='text-sm leading-tight text-white/90'>
{t('clients.description')}
</p>
</Link>
</NavigationMenuLink>
</li>
<ListItem href='/clients/loyalty' title='Программа лояльности'>
Накапливайте баллы и получайте скидки на топливо и услуги
</ListItem>
<ListItem href='/clients/certificates' title='Сертификаты'>
Подарочные сертификаты на топливо и услуги нашей сети
</ListItem>
</ul>
</NavigationMenuContent>
</NavigationMenuItem>
<NavigationMenuItem>
<Link href='/#vacancies' scroll={true}>
<NavigationMenuLink
asChild
className={navigationMenuTriggerStyle()}
>
<span>Вакансии</span>
<span>{t('common.navigation.vacancies')}</span>
</NavigationMenuLink>
</Link>
</NavigationMenuItem>
@ -97,7 +84,17 @@ export function DesktopNav() {
asChild
className={navigationMenuTriggerStyle()}
>
<span>Акции</span>
<span>{t('common.navigation.promotions')}</span>
</NavigationMenuLink>
</Link>
</NavigationMenuItem>
<NavigationMenuItem>
<Link href='/about' scroll>
<NavigationMenuLink
asChild
className={navigationMenuTriggerStyle()}
>
<span>{t('common.navigation.about')}</span>
</NavigationMenuLink>
</Link>
</NavigationMenuItem>

View File

@ -5,7 +5,7 @@ import Link from 'next/link';
import { Logo } from '@/shared/assets/logo';
import { useLanguage } from '@/shared/language';
import { LanguageSwitcher } from '@/shared/language/ui/language-switcher';
// import { LanguageSwitcher } from '@/shared/language/ui/language-switcher';
import { Button } from '@/shared/shadcn-ui/button';
import { DesktopNav } from './desktop-nav';
@ -19,10 +19,10 @@ export function Header() {
<div className='container mx-auto flex h-16 items-center justify-between p-4'>
<Logo />
<DesktopNav />
<div className='flex items-center gap-6 lg:contents'>
<div className='flex items-center gap-3 sm:gap-6 lg:contents'>
<MobileNav />
<div className='flex items-center gap-6'>
<LanguageSwitcher />
<div className='flex items-center gap-3 sm:gap-6'>
{/* <LanguageSwitcher /> */}
<Link href={'/login'}>
<Button className='flex items-center gap-2'>
<UserCircle className='size-4' />

View File

@ -2,6 +2,7 @@
import { MapPin } from 'lucide-react';
import Image from 'next/image';
import Link from 'next/link';
import { useLanguage } from '@/shared/language';
import { Button } from '@/shared/shadcn-ui/button';
@ -11,32 +12,37 @@ export const HeroSection = () => {
return (
<section className='relative'>
<div className='relative h-[500px] w-full overflow-hidden'>
<div className='relative h-[300px] w-full overflow-hidden md:h-[500px] xl:h-[700px]'>
<Image
src='/placeholder.svg?height=500&width=1920'
src='/oriyo_bg.jpeg'
alt='Gas Station Network'
width={1920}
height={500}
fill
className='object-cover'
priority
/>
<div className='absolute inset-0 flex items-center bg-gradient-to-r from-black/70 to-black/30'>
<div className='absolute inset-0 flex items-center bg-gradient-to-r from-black/70 to-black/30 px-2'>
<div className='container mx-auto'>
<div className='max-w-lg space-y-4 text-white'>
<h1 className='text-4xl font-bold tracking-tight sm:text-5xl md:text-6xl'>
{t('home.hero.title')}
</h1>
<p className='text-lg text-gray-200'>
<div className='animate-fade animate-duration-[3000ms] animate-ease-in-out'>
<h1 className='text-2xl font-bold tracking-tight sm:text-4xl md:text-6xl'>
{t('home.hero.title')}
</h1>
</div>
<p className='text-gray-200 sm:text-lg'>
{t('home.hero.description')}
</p>
<div className='flex gap-4'>
<Button className='bg-red-600 hover:bg-red-700'>
{t('common.buttons.findStation')}{' '}
<MapPin className='ml-2 h-4 w-4' />
</Button>
<Button variant='outline'>
{t('common.buttons.learnMore')}
</Button>
<div className='flex flex-col gap-2 sm:flex-row sm:gap-4'>
<Link href='#'>
<Button className='bg-red-600 hover:bg-red-700'>
{t('common.buttons.findStation')}{' '}
<MapPin className='ml-2 h-4 w-4' />
</Button>
</Link>
<Link href='#'>
<Button variant='outline' className='animate-pulse'>
{t('common.buttons.learnMore')}
</Button>
</Link>
</div>
</div>
</div>

View File

@ -1,17 +1,16 @@
'use client';
import { ChevronRight, MapPin } from 'lucide-react';
import { MapPin } from 'lucide-react';
import { GasStationMap } from '@/features/map';
import { useLanguage } from '@/shared/language';
import { Button } from '@/shared/shadcn-ui/button';
export const MapSection = () => {
const { t } = useLanguage();
return (
<section id='stations' className='bg-gray-50 py-16'>
<section id='stations' className='bg-gray-50 px-2 py-8 sm:py-16'>
<div className='container mx-auto'>
<div className='mb-12 flex flex-col items-center justify-center text-center'>
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
@ -30,12 +29,6 @@ export const MapSection = () => {
>
<GasStationMap />
</div>
<div className='mt-8 flex justify-center'>
<Button className='bg-red-600 hover:bg-red-700'>
{t('common.buttons.viewAll')}{' '}
<ChevronRight className='ml-2 h-4 w-4' />
</Button>
</div>
</div>
</section>
);

View File

@ -2,6 +2,7 @@
import { Handshake } from 'lucide-react';
import Image from 'next/image';
import Link from 'next/link';
import { useLanguage } from '@/shared/language';
import { Button } from '@/shared/shadcn-ui/button';
@ -10,7 +11,7 @@ export const PartnersSection = () => {
const { t } = useLanguage();
return (
<section id='partners' className='bg-gray-50 py-16'>
<section id='partners' className='bg-gray-50 px-2 py-8 sm:py-16'>
<div className='container mx-auto'>
<div className='mb-12 flex flex-col items-center justify-center text-center'>
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
@ -24,11 +25,11 @@ export const PartnersSection = () => {
</p>
</div>
<div className='grid grid-cols-2 gap-8 md:grid-cols-4'>
<div className='grid grid-cols-2 gap-4 sm:gap-8 md:grid-cols-4'>
{[1, 2, 3, 4, 5, 6, 7, 8].map((partner) => (
<div
key={partner}
className='flex h-32 items-center justify-center rounded-lg bg-white p-6 shadow-md transition-transform hover:scale-105'
className='flex h-32 flex-col items-center justify-center gap-0.5 rounded-lg bg-white p-6 shadow-md transition-transform hover:scale-105'
data-aos='flip-left'
>
<Image
@ -38,6 +39,7 @@ export const PartnersSection = () => {
height={80}
className='max-h-16 w-auto'
/>
<h4 className='font-extralight'>Название</h4>
</div>
))}
</div>
@ -49,9 +51,11 @@ export const PartnersSection = () => {
<p className='mx-auto mb-6 max-w-2xl text-gray-600'>
{t('home.partners.becomePartnerText')}
</p>
<Button className='bg-red-600 hover:bg-red-700'>
{t('common.buttons.contactUs')}
</Button>
<Link href='#'>
<Button className='bg-red-600 hover:bg-red-700'>
{t('common.buttons.contactUs')}
</Button>
</Link>
</div>
</div>
</section>

View File

@ -1,16 +1,15 @@
'use client';
import { ArrowRight, Gift } from 'lucide-react';
import { Gift } from 'lucide-react';
import PromotionSlider from '@/shared/components/promotion-slider';
import { useLanguage } from '@/shared/language';
import { Button } from '@/shared/shadcn-ui/button';
export const PromotionsSection = () => {
const { t } = useLanguage();
return (
<section id='promotions' className='bg-gray-50 py-16'>
<section id='promotions' className='bg-gray-50 py-8 px-2 sm:py-16'>
<div className='container mx-auto'>
<div className='mb-12 flex flex-col items-center justify-center text-center'>
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
@ -24,12 +23,6 @@ export const PromotionsSection = () => {
</p>
</div>
<PromotionSlider />
<div className='mt-8 flex justify-center'>
<Button className='bg-red-600 hover:bg-red-700'>
{t('common.buttons.viewAll')}{' '}
<ArrowRight className='ml-2 h-4 w-4' />
</Button>
</div>
</div>
</section>
);

View File

@ -3,11 +3,14 @@
import { useEffect, useRef, useState } from 'react';
import AnimatedCounter from '../shared/components/animated-counter';
import { useLanguage } from '@/shared/language';
export function StatsSection() {
const [isVisible, setIsVisible] = useState(false);
const sectionRef = useRef<HTMLDivElement>(null);
const { t } = useLanguage()
useEffect(() => {
const observer = new IntersectionObserver(
(entries) => {
@ -32,32 +35,32 @@ export function StatsSection() {
}, []);
return (
<section ref={sectionRef} className='bg-red-600 py-12 text-white'>
<section ref={sectionRef} className='bg-red-600 py-6 sm:py-12 px-2 text-white'>
<div className='container mx-auto'>
<div className='grid grid-cols-2 gap-8 text-center md:grid-cols-4'>
<div className='grid grid-cols-2 gap-4 sm:gap-8 text-center md:grid-cols-4'>
<div className='space-y-2'>
<h3 className='text-3xl font-bold'>
{isVisible ? <AnimatedCounter end={25} suffix='+' /> : '0+'}
</h3>
<p className='text-sm text-white/80'>Заправок по стране</p>
<p className='text-sm text-white/80'>{t('home.stats.stations')}</p>
</div>
<div className='space-y-2'>
<h3 className='text-3xl font-bold'>
{isVisible ? <AnimatedCounter end={10000} suffix='+' /> : '0+'}
</h3>
<p className='text-sm text-white/80'>Клиентов ежедневно</p>
<p className='text-sm text-white/80'>{t('home.stats.daily')}</p>
</div>
<div className='space-y-2'>
<h3 className='text-3xl font-bold'>
{isVisible ? <AnimatedCounter end={15} /> : '0'}
</h3>
<p className='text-sm text-white/80'>Лет на рынке</p>
<p className='text-sm text-white/80'>{t('home.stats.years')}</p>
</div>
<div className='space-y-2'>
<h3 className='text-3xl font-bold'>
{isVisible ? <AnimatedCounter end={24} suffix='/7' /> : '0/7'}
</h3>
<p className='text-sm text-white/80'>Работаем круглосуточно</p>
<p className='text-sm text-white/80'>{t('home.stats.mode')}</p>
</div>
</div>
</div>

View File

@ -0,0 +1,216 @@
'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>
);
};

View File

@ -1,8 +1,10 @@
'use client';
import { ArrowRight, Briefcase } from 'lucide-react';
import { Briefcase } from 'lucide-react';
import { useLanguage } from '@/shared/language';
import { cn } from '@/shared/lib/utils';
import { Badge } from '@/shared/shadcn-ui/badge';
import { Button } from '@/shared/shadcn-ui/button';
import { Card, CardContent } from '@/shared/shadcn-ui/card';
import {
@ -16,7 +18,7 @@ export const VacanciesSection = () => {
const { t } = useLanguage();
return (
<section id='vacancies' className='py-16'>
<section id='vacancies' className='px-2 py-8 sm:py-16'>
<div className='container mx-auto'>
<div className='mb-12 flex flex-col items-center justify-center text-center'>
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
@ -32,9 +34,9 @@ export const VacanciesSection = () => {
<Tabs defaultValue='all' className='mx-auto w-full max-w-3xl'>
<TabsList className='mb-8 grid grid-cols-3'>
<TabsTrigger value='all'>Все вакансии</TabsTrigger>
<TabsTrigger value='office'>Офис</TabsTrigger>
<TabsTrigger value='stations'>Заправки</TabsTrigger>
<TabsTrigger value='all'>{t('home.vacancies.all')}</TabsTrigger>
<TabsTrigger value='office'>{t('home.vacancies.office')}</TabsTrigger>
<TabsTrigger value='stations'>{t('home.vacancies.stations')}</TabsTrigger>
</TabsList>
<TabsContent value='all' className='space-y-4'>
{[
@ -43,35 +45,12 @@ export const VacanciesSection = () => {
'Бухгалтер',
'Специалист по логистике',
].map((job, index) => (
<Card
<Vacancy
key={index}
className='overflow-hidden transition-all hover:shadow-md'
data-aos='zoom-in'
>
<CardContent className='p-0'>
<div className='p-6'>
<div className='flex items-start justify-between'>
<div>
<h3 className='mb-2 text-lg font-bold'>{job}</h3>
<p className='mb-4 text-sm text-gray-500'>
Душанбе, Таджикистан
</p>
<div className='mb-4 flex flex-wrap gap-2'>
<span className='inline-flex items-center rounded-full bg-gray-100 px-2.5 py-0.5 text-xs font-medium text-gray-800'>
Полный день
</span>
<span className='inline-flex items-center rounded-full bg-red-100 px-2.5 py-0.5 text-xs font-medium text-red-800'>
Опыт от 1 года
</span>
</div>
</div>
<Button variant='outline' size='sm'>
{t('common.buttons.readMore')}
</Button>
</div>
</div>
</CardContent>
</Card>
jobTitle={job}
location='Душанбе, Таджикистан'
tags={['Полный день', 'Опыт от 1 года']}
/>
))}
</TabsContent>
<TabsContent value='office' className='space-y-4'>
@ -80,79 +59,74 @@ export const VacanciesSection = () => {
'Бухгалтер',
'Специалист по логистике',
].map((job, index) => (
<Card
<Vacancy
key={index}
className='overflow-hidden transition-all hover:shadow-md'
>
<CardContent className='p-0'>
<div className='p-6'>
<div className='flex items-start justify-between'>
<div>
<h3 className='mb-2 text-lg font-bold'>{job}</h3>
<p className='mb-4 text-sm text-gray-500'>
Душанбе, Таджикистан
</p>
<div className='mb-4 flex flex-wrap gap-2'>
<span className='inline-flex items-center rounded-full bg-gray-100 px-2.5 py-0.5 text-xs font-medium text-gray-800'>
Полный день
</span>
<span className='inline-flex items-center rounded-full bg-red-100 px-2.5 py-0.5 text-xs font-medium text-red-800'>
Опыт от 1 года
</span>
</div>
</div>
<Button variant='outline' size='sm'>
{t('common.buttons.readMore')}
</Button>
</div>
</div>
</CardContent>
</Card>
jobTitle={job}
location='Душанбе, Таджикистан'
tags={['Полный день', 'Опыт от 1 года']}
/>
))}
</TabsContent>
<TabsContent value='stations' className='space-y-4'>
{['Оператор АЗС', 'Заправщик', 'Менеджер станции'].map(
(job, index) => (
<Card
<Vacancy
key={index}
className='overflow-hidden transition-all hover:shadow-md'
>
<CardContent className='p-0'>
<div className='p-6'>
<div className='flex items-start justify-between'>
<div>
<h3 className='mb-2 text-lg font-bold'>{job}</h3>
<p className='mb-4 text-sm text-gray-500'>
Душанбе, Таджикистан
</p>
<div className='mb-4 flex flex-wrap gap-2'>
<span className='inline-flex items-center rounded-full bg-gray-100 px-2.5 py-0.5 text-xs font-medium text-gray-800'>
Сменный график
</span>
<span className='inline-flex items-center rounded-full bg-red-100 px-2.5 py-0.5 text-xs font-medium text-red-800'>
Обучение
</span>
</div>
</div>
<Button variant='outline' size='sm'>
{t('common.buttons.readMore')}
</Button>
</div>
</div>
</CardContent>
</Card>
jobTitle={job}
location='Душанбе, Таджикистан'
tags={['Сменный график', 'Обучение']}
/>
),
)}
</TabsContent>
</Tabs>
<div className='mt-8 flex justify-center'>
<Button className='bg-red-600 hover:bg-red-700'>
{t('common.buttons.sendResume')}{' '}
<ArrowRight className='ml-2 h-4 w-4' />
</Button>
</div>
</div>
</section>
);
};
interface VacancyProps {
jobTitle: string;
location: string;
tags: Array<string>;
}
const Vacancy = ({ jobTitle, location, tags }: VacancyProps) => {
const { t } = useLanguage();
return (
<Card
className='overflow-hidden transition-all hover:shadow-md'
data-aos='zoom-in'
>
<CardContent className='p-0'>
<div className='p-6'>
<div className='flex flex-col items-start justify-between sm:flex-row'>
<div>
<h3 className='mb-2 text-lg font-bold'>{jobTitle}</h3>
<p className='mb-4 text-sm text-gray-500'>{location}</p>
<div className='mb-4 flex flex-wrap gap-2'>
{tags.map((tag, index) => {
return (
<Badge
key={index}
className={cn(
'inline-flex items-center rounded-full bg-gray-100 px-2.5 py-0.5 text-xs font-medium',
`${index % 2 === 0 ? 'bg-gray-100 text-gray-800' : 'bg-red-100 text-red-800'}`,
)}
>
{tag}
</Badge>
);
})}
</div>
</div>
<Button variant='outline' size='sm'>
{t('common.buttons.apply')}
</Button>
</div>
</div>
</CardContent>
</Card>
);
};

View File

@ -1,4 +1,5 @@
/** @type {import('tailwindcss').Config} */
import tailwindcssAnimated from 'tailwindcss-animated';
module.exports = {
darkMode: ['class'],
@ -102,5 +103,5 @@ module.exports = {
},
},
},
plugins: [require('tailwindcss-animate')],
plugins: [require('tailwindcss-animate'), tailwindcssAnimated],
};