Files
han-app/VM1_app/figma/src/app/pages/Profile.tsx
T

286 lines
12 KiB
TypeScript

import { User, FileText, Calendar, MapPin, Phone, Mail, ChevronRight, ArrowLeft, Download, CheckCircle, Clock } from 'lucide-react';
import { useNavigate } from 'react-router';
import * as Accordion from '@radix-ui/react-accordion';
import { ChevronDown } from 'lucide-react';
interface ProfileSection {
icon: React.ReactNode;
title: string;
value?: string;
action?: string;
}
interface Document {
id: string;
title: string;
date: string;
status: 'ready' | 'processing';
}
interface Service {
id: string;
title: string;
status: 'active' | 'completed' | 'pending';
date: string;
}
const profileSections: ProfileSection[] = [
{
icon: <User className="w-5 h-5" />,
title: 'Имя',
value: 'Азамат Искандаров',
},
{
icon: <Phone className="w-5 h-5" />,
title: 'Телефон',
value: '+7 (999) 123-45-67',
},
{
icon: <Mail className="w-5 h-5" />,
title: 'Email',
value: 'azamat@example.com',
},
];
const documentSections: ProfileSection[] = [
{
icon: <FileText className="w-5 h-5" />,
title: 'Мой патент',
value: 'Действует до 15.07.2026',
action: 'Подробнее',
},
{
icon: <Calendar className="w-5 h-5" />,
title: 'РВП',
value: 'В процессе оформления',
action: 'Проверить статус',
},
{
icon: <MapPin className="w-5 h-5" />,
title: 'Регистрация',
value: 'Москва, ул. Ленина, д. 1',
action: 'Изменить',
},
];
const readyDocuments: Document[] = [
{
id: '1',
title: 'Справка о несудимости',
date: '15.05.2026',
status: 'ready',
},
{
id: '2',
title: 'Перевод паспорта',
date: '10.05.2026',
status: 'ready',
},
{
id: '3',
title: 'Выписка из банка',
date: 'В обработке',
status: 'processing',
},
];
const services: Service[] = [
{
id: '1',
title: 'Консультация юриста',
status: 'completed',
date: '20.05.2026',
},
{
id: '2',
title: 'Помощь в продлении патента',
status: 'active',
date: 'До 30.05.2026',
},
{
id: '3',
title: 'Перевод документов',
status: 'pending',
date: 'Ожидает оплаты',
},
];
export function Profile() {
const navigate = useNavigate();
return (
<div className="flex-1 overflow-y-auto">
<div className="px-4 py-4">
{/* Кнопка назад и аватар */}
<div className="flex items-center gap-3 mb-4">
<button
onClick={() => navigate('/')}
className="flex items-center justify-center w-9 h-9 rounded-full hover:bg-muted transition-colors"
aria-label="Назад"
>
<ArrowLeft className="w-5 h-5" />
</button>
<h1 className="text-xl font-medium">Профиль</h1>
</div>
<div className="flex flex-col items-center py-4 mb-4">
<div className="flex items-center justify-center w-20 h-20 rounded-full bg-primary text-primary-foreground mb-3">
<User className="w-10 h-10" />
</div>
<h2 className="text-lg font-medium">Азамат Искандаров</h2>
<p className="text-sm text-muted-foreground">Мигрант</p>
</div>
{/* Аккордеон с разделами */}
<Accordion.Root type="multiple" defaultValue={['personal']} className="space-y-3">
{/* Личная информация */}
<Accordion.Item value="personal" className="bg-card border border-border rounded-lg overflow-hidden">
<Accordion.Header>
<Accordion.Trigger className="w-full px-4 py-3 flex items-center justify-between hover:bg-accent/50 transition-colors group">
<span className="text-sm font-medium">Личная информация</span>
<ChevronDown className="w-5 h-5 text-muted-foreground transition-transform group-data-[state=open]:rotate-180" />
</Accordion.Trigger>
</Accordion.Header>
<Accordion.Content className="overflow-hidden data-[state=open]:animate-slideDown data-[state=closed]:animate-slideUp">
<div className="border-t border-border divide-y divide-border">
{profileSections.map((section, index) => (
<div key={index} className="p-3 flex items-center gap-3">
<div className="flex items-center justify-center w-9 h-9 rounded-full bg-muted text-muted-foreground flex-shrink-0">
{section.icon}
</div>
<div className="flex-1 min-w-0">
<p className="text-xs text-muted-foreground">{section.title}</p>
<p className="text-sm font-medium">{section.value}</p>
</div>
</div>
))}
</div>
</Accordion.Content>
</Accordion.Item>
{/* Мои документы */}
<Accordion.Item value="documents" className="bg-card border border-border rounded-lg overflow-hidden">
<Accordion.Header>
<Accordion.Trigger className="w-full px-4 py-3 flex items-center justify-between hover:bg-accent/50 transition-colors group">
<span className="text-sm font-medium">Мои документы</span>
<ChevronDown className="w-5 h-5 text-muted-foreground transition-transform group-data-[state=open]:rotate-180" />
</Accordion.Trigger>
</Accordion.Header>
<Accordion.Content className="overflow-hidden data-[state=open]:animate-slideDown data-[state=closed]:animate-slideUp">
<div className="border-t border-border divide-y divide-border">
{documentSections.map((section, index) => (
<button
key={index}
className="w-full p-3 flex items-center gap-3 hover:bg-accent/50 transition-colors text-left"
>
<div className="flex items-center justify-center w-9 h-9 rounded-full bg-primary/10 text-primary flex-shrink-0">
{section.icon}
</div>
<div className="flex-1 min-w-0">
<p className="text-sm font-medium mb-0.5">{section.title}</p>
<p className="text-xs text-muted-foreground">{section.value}</p>
</div>
{section.action && (
<ChevronRight className="w-5 h-5 text-muted-foreground flex-shrink-0" />
)}
</button>
))}
</div>
</Accordion.Content>
</Accordion.Item>
{/* Готовые документы */}
<Accordion.Item value="ready-docs" className="bg-card border border-border rounded-lg overflow-hidden">
<Accordion.Header>
<Accordion.Trigger className="w-full px-4 py-3 flex items-center justify-between hover:bg-accent/50 transition-colors group">
<span className="text-sm font-medium">Готовые документы</span>
<ChevronDown className="w-5 h-5 text-muted-foreground transition-transform group-data-[state=open]:rotate-180" />
</Accordion.Trigger>
</Accordion.Header>
<Accordion.Content className="overflow-hidden data-[state=open]:animate-slideDown data-[state=closed]:animate-slideUp">
<div className="border-t border-border divide-y divide-border">
{readyDocuments.map((doc) => (
<div key={doc.id} className="p-3 flex items-center gap-3">
<div className={`flex items-center justify-center w-9 h-9 rounded-full flex-shrink-0 ${
doc.status === 'ready' ? 'bg-green-500/10 text-green-600' : 'bg-yellow-500/10 text-yellow-600'
}`}>
{doc.status === 'ready' ? <CheckCircle className="w-5 h-5" /> : <Clock className="w-5 h-5" />}
</div>
<div className="flex-1 min-w-0">
<p className="text-sm font-medium mb-0.5">{doc.title}</p>
<p className="text-xs text-muted-foreground">{doc.date}</p>
</div>
{doc.status === 'ready' && (
<button className="flex items-center justify-center w-9 h-9 rounded-full hover:bg-muted transition-colors">
<Download className="w-4 h-4 text-primary" />
</button>
)}
</div>
))}
</div>
</Accordion.Content>
</Accordion.Item>
{/* Мои услуги */}
<Accordion.Item value="services" className="bg-card border border-border rounded-lg overflow-hidden">
<Accordion.Header>
<Accordion.Trigger className="w-full px-4 py-3 flex items-center justify-between hover:bg-accent/50 transition-colors group">
<span className="text-sm font-medium">Мои услуги</span>
<ChevronDown className="w-5 h-5 text-muted-foreground transition-transform group-data-[state=open]:rotate-180" />
</Accordion.Trigger>
</Accordion.Header>
<Accordion.Content className="overflow-hidden data-[state=open]:animate-slideDown data-[state=closed]:animate-slideUp">
<div className="border-t border-border divide-y divide-border">
{services.map((service) => (
<div key={service.id} className="p-3 flex items-center gap-3">
<div className={`w-2 h-2 rounded-full flex-shrink-0 ${
service.status === 'completed' ? 'bg-green-500' :
service.status === 'active' ? 'bg-blue-500' : 'bg-yellow-500'
}`} />
<div className="flex-1 min-w-0">
<p className="text-sm font-medium mb-0.5">{service.title}</p>
<p className="text-xs text-muted-foreground">{service.date}</p>
</div>
<span className={`text-xs font-medium px-2 py-1 rounded-full ${
service.status === 'completed' ? 'bg-green-500/10 text-green-600' :
service.status === 'active' ? 'bg-blue-500/10 text-blue-600' : 'bg-yellow-500/10 text-yellow-600'
}`}>
{service.status === 'completed' ? 'Завершено' :
service.status === 'active' ? 'Активно' : 'Ожидает'}
</span>
</div>
))}
</div>
</Accordion.Content>
</Accordion.Item>
</Accordion.Root>
{/* Настройки */}
<div className="space-y-2 mt-6">
<button
onClick={() => navigate('/calendar')}
className="w-full bg-card border border-border rounded-lg p-4 flex items-center justify-between hover:bg-accent/50 transition-colors"
>
<span className="text-sm font-medium">Календарь обязательств</span>
<ChevronRight className="w-5 h-5 text-muted-foreground" />
</button>
<button className="w-full bg-card border border-border rounded-lg p-4 flex items-center justify-between hover:bg-accent/50 transition-colors">
<span className="text-sm font-medium">Настройки уведомлений</span>
<ChevronRight className="w-5 h-5 text-muted-foreground" />
</button>
<button className="w-full bg-card border border-border rounded-lg p-4 flex items-center justify-between hover:bg-accent/50 transition-colors">
<span className="text-sm font-medium">Язык</span>
<div className="flex items-center gap-2">
<span className="text-sm text-muted-foreground">Русский</span>
<ChevronRight className="w-5 h-5 text-muted-foreground" />
</div>
</button>
<button className="w-full bg-destructive/10 border border-destructive/20 text-destructive rounded-lg p-4 flex items-center justify-center hover:bg-destructive/20 transition-colors">
<span className="text-sm font-medium">Выйти из аккаунта</span>
</button>
</div>
</div>
</div>
);
}