import { useState, useRef, useCallback } from 'react'; import { createPortal } from 'react-dom'; import { useParams, Link, useNavigate } from 'react-router-dom'; import { useAuth } from '@/hooks/useAuth'; import { useUserCats } from '@/hooks/useCats'; import { useQuery } from '@tanstack/react-query'; import { getUser, uploadAvatar, setAvatarPreset } from '@/api/endpoints'; import CatModal from '@/components/CatModal'; import UserAvatar from '@/components/UserAvatar'; import { Button } from '@/components/ui/button'; import { Skeleton } from '@/components/ui/skeleton'; import { ArrowLeft, Plus, LogOut, Shield, Heart, Image, Trophy, Camera, X, Grid3x3 } from 'lucide-react'; import { PRESETS } from '@/lib/avatars'; import { useToast } from '@/components/Toast'; export default function ProfilePage() { const { id: paramId } = useParams<{ id?: string }>(); const navigate = useNavigate(); const { user: me, logout, updateUser } = useAuth(); const [modalCatId, setModalCatId] = useState(null); const [showAvatarPicker, setShowAvatarPicker] = useState(false); const { toast } = useToast(); const profileUserId = paramId ? parseInt(paramId) : me?.id; const isMe = !paramId || (me && profileUserId === me.id); const { data: userData } = useQuery({ queryKey: ['user', profileUserId], queryFn: () => getUser(profileUserId!).then(r => r.data.user), enabled: !isMe && !!profileUserId, }); const { data, isLoading } = useUserCats(profileUserId ?? 0); const profileUser = isMe ? me : userData; const fileInputRef = useRef(null); const onFileChange = useCallback(async (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (!file || !isMe) return; const fd = new FormData(); fd.append('avatar', file); try { const res = await uploadAvatar(fd); updateUser(res.data.user); toast('Аватар обновлён'); } catch { toast('Ошибка', 'error'); } e.target.value = ''; }, [isMe, updateUser, toast]); const handlePreset = async (emoji: string) => { if (!isMe) return; try { const res = await setAvatarPreset(emoji); updateUser(res.data.user); setShowAvatarPicker(false); toast('Аватар обновлён'); } catch { toast('Ошибка', 'error'); } }; if (isLoading) { return (
{Array.from({ length: 9 }).map((_, i) => ( ))}
); } if (!profileUser && !isMe) { return (

Пользователь не найден

); } const cats = data?.cats ?? []; const totalLikes = cats.reduce((sum, c) => sum + c.likes_count, 0); return (
{!isMe && (
)} {/* Шапка профиля */}
{/* Аватар */}
{isMe && ( )}
{/* Инфо */}

@{profileUser?.username}

{isMe && me?.is_admin && ( )} {isMe && ( )}
{/* Статистика */}
} />
} />
{isMe && ( )}
{/* Разделитель с иконкой сетки */}
Публикации
{/* Сетка фото */} {cats.length === 0 ? (

Пока нет публикаций

{isMe ? 'Поделитесь первым фото' : 'У пользователя пока нет котов'}

{isMe && ( )}
) : (
{cats.map((cat, i) => ( ))}
)} {modalCatId && setModalCatId(null)} />} {/* Пикер аватара */} {showAvatarPicker && createPortal(
setShowAvatarPicker(false)} >
e.stopPropagation()} >

Выбрать аватар

{PRESETS.map(emoji => ( ))}
, document.body )}
); } function Stat({ value, label, icon, }: { value: number; label: string; icon?: React.ReactNode; }) { return (
{icon} {value} {label}
); }