import { useState, useEffect, useRef } from 'react'; import { useParams, useNavigate, Link } from 'react-router-dom'; import { useCat, useDeleteCat } from '@/hooks/useCats'; import { useLikeStatus, useLikeCat, useUnlikeCat } from '@/hooks/useLikes'; import { useComments, useAddComment, useDeleteComment } from '@/hooks/useComments'; import { useAuth } from '@/hooks/useAuth'; import { useToast } from '@/components/Toast'; import { Button } from '@/components/ui/button'; import { Skeleton } from '@/components/ui/skeleton'; import UserAvatar from '@/components/UserAvatar'; import { ArrowLeft, Heart, Trash2, Trophy, Image, Send, X } from 'lucide-react'; export default function CatPage() { const { id } = useParams<{ id: string }>(); const catId = parseInt(id!); const navigate = useNavigate(); const { user } = useAuth(); const { toast } = useToast(); const { data, isLoading, isError } = useCat(catId); const { data: likeData, refetch: refetchLike } = useLikeStatus(catId); const likeMutation = useLikeCat(catId); const unlikeMutation = useUnlikeCat(catId); const deleteMutation = useDeleteCat(); const { data: commentsData } = useComments(catId); const addCommentMutation = useAddComment(catId); const deleteCommentMutation = useDeleteComment(catId); const [liked, setLiked] = useState(false); const [imageLoaded, setImageLoaded] = useState(false); const [commentText, setCommentText] = useState(''); const commentsEndRef = useRef(null); const cat = data?.cat; const comments = commentsData?.comments ?? []; const isOwner = cat && user && cat.user_id === user.id; useEffect(() => { if (likeData?.liked !== undefined) setLiked(likeData.liked); }, [likeData?.liked]); const toggleLike = async () => { if (isOwner || !user || !cat) return; if (liked) { setLiked(false); try { await unlikeMutation.mutateAsync(); refetchLike(); } catch { setLiked(true); } } else { setLiked(true); toast('❤️'); try { await likeMutation.mutateAsync(); refetchLike(); } catch { setLiked(false); } } }; const handleDelete = async () => { if (!isOwner || !cat) return; try { await deleteMutation.mutateAsync(cat.id); toast('Удалено'); navigate('/feed'); } catch { toast('Ошибка удаления', 'error'); } }; const handleComment = async () => { const text = commentText.trim(); if (!text || !user) return; try { await addCommentMutation.mutateAsync(text); setCommentText(''); setTimeout(() => commentsEndRef.current?.scrollIntoView({ behavior: 'smooth' }), 100); } catch { toast('Ошибка', 'error'); } }; const handleDeleteComment = async (commentId: number) => { try { await deleteCommentMutation.mutateAsync(commentId); } catch { toast('Ошибка', 'error'); } }; if (isLoading) { return (
); } if (isError || !cat) { return (

Кот не найден

); } const dateStr = new Date(cat.created_at).toLocaleDateString('ru-RU', { year: 'numeric', month: 'long', day: 'numeric', hour: '2-digit', minute: '2-digit', }); return (
{!imageLoaded && (
)} {cat.caption setImageLoaded(true)} />
@{cat.username}

{dateStr}

{isOwner && ( )}
{cat.caption && (

@{cat.username} {cat.caption}

)}
{cat.user_points}
{comments.length > 0 && (

Комментарии · {comments.length}

{comments.map(c => (

@{c.username} {c.text}

{new Date(c.created_at).toLocaleDateString('ru-RU', { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' })}

{(user && (c.user_id === user.id || user.is_admin)) && ( )}
))}
)} {user && (
{ e.preventDefault(); handleComment(); }} className="flex items-center gap-2"> setCommentText(e.target.value)} placeholder="Написать комментарий..." maxLength={500} className="flex-1 h-9 px-3 text-sm rounded-xl border border-[var(--border)] bg-[var(--surface)] placeholder:text-[var(--fg-tertiary)] focus-ring" />
)}
); }