UI: complete redesign — warm atelier style, Manrope font, burnt orange accent, shadow-based cards
This commit is contained in:
@@ -7,7 +7,7 @@ import { useToast } from '@/components/Toast';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Avatar, AvatarFallback } from '@/components/ui/avatar';
|
||||
import { Skeleton } from '@/components/ui/skeleton';
|
||||
import { ArrowLeft, Heart, Trash2 } from 'lucide-react';
|
||||
import { ArrowLeft, Heart, Trash2, Trophy, Image } from 'lucide-react';
|
||||
|
||||
export default function CatPage() {
|
||||
const { id } = useParams<{ id: string }>();
|
||||
@@ -52,13 +52,12 @@ export default function CatPage() {
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="mx-auto max-w-[580px] px-4 py-8">
|
||||
<div className="mx-auto max-w-[520px] px-5 py-8">
|
||||
<Skeleton className="mb-4 h-4 w-20 rounded-lg" />
|
||||
<Skeleton className="aspect-[4/3] w-full rounded-xl" />
|
||||
<Skeleton className="aspect-[4/3] w-full rounded-2xl" />
|
||||
<div className="mt-5 space-y-3">
|
||||
<Skeleton className="h-4 w-32 rounded-lg" />
|
||||
<Skeleton className="h-3 w-48 rounded-lg" />
|
||||
<Skeleton className="h-3 w-24 rounded-lg" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -66,12 +65,12 @@ export default function CatPage() {
|
||||
|
||||
if (isError || !cat) {
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center py-24 animate-rise">
|
||||
<div className="mb-4 flex h-14 w-14 items-center justify-center rounded-xl bg-[var(--secondary)]">
|
||||
<span className="text-xl">🔍</span>
|
||||
<div className="flex flex-col items-center justify-center py-24 animate-fade-up">
|
||||
<div className="mb-4 h-14 w-14 rounded-2xl flex items-center justify-center bg-[var(--border-light)]">
|
||||
<Image className="h-7 w-7 text-[var(--fg-tertiary)]" strokeWidth={1.5} />
|
||||
</div>
|
||||
<p className="text-base font-semibold mb-1">Кот не найден</p>
|
||||
<Button variant="outline" onClick={() => navigate('/feed')} className="rounded-lg text-xs mt-2">В ленту</Button>
|
||||
<Button variant="outline" onClick={() => navigate('/feed')} className="rounded-xl text-xs mt-2 h-9 px-4">В ленту</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -81,17 +80,17 @@ export default function CatPage() {
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="mx-auto max-w-[580px] px-4 py-6 animate-rise">
|
||||
<div className="mx-auto max-w-[520px] px-5 py-6 animate-fade-up">
|
||||
<button onClick={() => navigate(-1)}
|
||||
className="mb-5 flex items-center gap-1.5 text-xs text-[var(--fg-secondary)] hover:text-[var(--fg)] transition-colors">
|
||||
<ArrowLeft className="h-4 w-4 stroke-[1.5]" /> Назад
|
||||
className="mb-5 flex items-center gap-1.5 text-xs text-[var(--fg-tertiary)] hover:text-[var(--fg)] transition-colors">
|
||||
<ArrowLeft className="h-4 w-4" strokeWidth={1.5} /> Назад
|
||||
</button>
|
||||
|
||||
<div className="card border overflow-hidden">
|
||||
<div className="bg-[var(--secondary)] relative">
|
||||
<div className="card overflow-hidden">
|
||||
<div className="bg-[var(--bg)] relative">
|
||||
{!imageLoaded && (
|
||||
<div className="absolute inset-0 flex items-center justify-center">
|
||||
<div className="h-8 w-8 rounded-full border-2 border-[var(--fg-tertiary)]/30 border-t-[var(--primary)] animate-spin" />
|
||||
<div className="h-6 w-6 rounded-full border-2 border-[var(--border)] border-t-[var(--accent)] animate-spin" />
|
||||
</div>
|
||||
)}
|
||||
<img src={cat.image_url} alt={cat.caption || 'Фото кота'}
|
||||
@@ -102,46 +101,48 @@ export default function CatPage() {
|
||||
<div className="p-5 space-y-4">
|
||||
<div className="flex items-start justify-between">
|
||||
<Link to={`/profile/${cat.user_id}`} className="flex items-center gap-3 group">
|
||||
<Avatar className="h-10 w-10 border">
|
||||
<AvatarFallback className="text-sm avatar">{cat.username.charAt(0).toUpperCase()}</AvatarFallback>
|
||||
<Avatar className="h-10 w-10">
|
||||
<AvatarFallback className="text-sm avatar-colored bg-[var(--accent)]">
|
||||
{cat.username.charAt(0).toUpperCase()}
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
<div>
|
||||
<span className="text-sm font-semibold group-hover:text-[var(--primary)] transition-colors">@{cat.username}</span>
|
||||
<span className="text-sm font-semibold group-hover:text-[var(--accent)] transition-colors">@{cat.username}</span>
|
||||
<p className="text-[11px] text-[var(--fg-tertiary)]">{dateStr}</p>
|
||||
</div>
|
||||
</Link>
|
||||
{isOwner && (
|
||||
<button onClick={handleDelete} className="btn-icon h-9 w-9 text-[var(--fg-secondary)] hover:text-[var(--danger)] hover:bg-[var(--danger-light)]">
|
||||
<button onClick={handleDelete} className="btn-ghost h-9 w-9 text-[var(--fg-tertiary)] hover:text-red-500 hover:bg-red-50">
|
||||
<Trash2 className="h-4 w-4" strokeWidth={1.5} />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{cat.caption && (
|
||||
<p className="text-sm leading-[1.45]">
|
||||
<span className="font-semibold mr-1.5">@{cat.username}</span>
|
||||
<p className="text-sm leading-[1.5]">
|
||||
<span className="font-semibold mr-1">@{cat.username}</span>
|
||||
{cat.caption}
|
||||
</p>
|
||||
)}
|
||||
|
||||
<div className="border-t" />
|
||||
<div className="divider" />
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<button onClick={toggleLike} disabled={isOwner || !user}
|
||||
className={`flex items-center gap-2 text-sm font-medium transition-all ${
|
||||
isOwner ? 'text-[var(--fg-tertiary)] cursor-not-allowed' : liked ? 'text-[var(--danger)]' : 'text-[var(--fg-secondary)] hover:text-[var(--fg)]'
|
||||
isOwner ? 'text-[var(--fg-tertiary)] cursor-not-allowed' : liked ? 'text-red-500' : 'text-[var(--fg-secondary)] hover:text-red-400'
|
||||
}`}>
|
||||
<Heart className={`h-5 w-5 transition-all ${liked ? 'fill-[var(--danger)] stroke-[var(--danger)] animate-pop' : 'stroke-[1.5]'}`} />
|
||||
{cat.likes_count > 0 && <span className="tabular-nums">{cat.likes_count}</span>}
|
||||
<Heart className={`h-5 w-5 transition-all ${liked ? 'fill-red-500 stroke-red-500 animate-pop' : 'stroke-[1.5]'}`} />
|
||||
{cat.likes_count > 0 && <span className="stat-value">{cat.likes_count}</span>}
|
||||
</button>
|
||||
<span className="flex items-center gap-1.5 text-xs text-[var(--fg-secondary)]">
|
||||
<span>🏆</span>
|
||||
<span className="font-semibold">{cat.user_points}</span>
|
||||
<span className="flex items-center gap-1.5 text-xs text-[var(--fg-tertiary)]">
|
||||
<Trophy className="h-3.5 w-3.5" strokeWidth={1.5} />
|
||||
<span className="font-semibold text-[var(--fg-secondary)]">{cat.user_points}</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<Button variant="outline" size="sm" onClick={() => navigate('/feed')} className="rounded-lg text-xs h-8">
|
||||
<ArrowLeft className="h-3.5 w-3.5 mr-1" strokeWidth={1.5} /> В ленту
|
||||
<Button variant="outline" size="sm" onClick={() => navigate('/feed')} className="rounded-xl text-xs h-8 px-4 gap-1">
|
||||
<ArrowLeft className="h-3.5 w-3.5" strokeWidth={1.5} /> В ленту
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user