-
onOpen(cat.id)}
- >
-
-
+
+
onOpen(cat.id)}>
+
+
+
{cat.username.charAt(0).toUpperCase()}
- onOpen(cat.id)}>
+
- {cat.caption && (
-
-
- @{cat.username}
+
+
@{cat.username}
onOpen(cat.id)}>
-
diff --git a/client/src/components/CatModal.tsx b/client/src/components/CatModal.tsx
index dfdb12c..3fe1773 100644
--- a/client/src/components/CatModal.tsx
+++ b/client/src/components/CatModal.tsx
@@ -4,7 +4,7 @@ import { useLikeStatus, useLikeCat, useUnlikeCat } from '@/hooks/useLikes';
import { useAuth } from '@/hooks/useAuth';
import { useToast } from '@/components/Toast';
import { Avatar, AvatarFallback } from '@/components/ui/avatar';
-import { X, Heart, Trash2 } from 'lucide-react';
+import { X, Heart, Trash2, Trophy } from 'lucide-react';
interface CatModalProps {
catId: number;
@@ -39,14 +39,14 @@ export default function CatModal({ catId, onClose }: CatModalProps) {
const toggleLike = async () => {
if (isOwner || !user || !cat) return;
if (liked) {
- setLiked(false); setLikeCount((c) => c - 1);
+ setLiked(false); setLikeCount(c => c - 1);
try { await unlikeMutation.mutateAsync(); refetchLike(); }
- catch { setLiked(true); setLikeCount((c) => c + 1); }
+ catch { setLiked(true); setLikeCount(c => c + 1); }
} else {
- setLiked(true); setLikeCount((c) => c + 1);
+ setLiked(true); setLikeCount(c => c + 1);
toast('❤️');
try { await likeMutation.mutateAsync(); refetchLike(); }
- catch { setLiked(false); setLikeCount((c) => c - 1); }
+ catch { setLiked(false); setLikeCount(c => c - 1); }
}
};
@@ -58,9 +58,9 @@ export default function CatModal({ catId, onClose }: CatModalProps) {
if (isLoading || !cat) {
return (
- - @{cat.username} +
+ {cat.caption && (
+
- )}
+ )}
- + @{cat.username} {cat.caption}
-
-
-
-
-
- 🏆
- {cat.user_points}
-
-
-
+
+
@@ -72,15 +72,17 @@ export default function CatModal({ catId, onClose }: CatModalProps) {
});
return (
-
+
Загрузка...
+
e.stopPropagation()}
+ className="w-full sm:max-w-lg bg-white sm:rounded-2xl max-h-[92vh] flex flex-col overflow-hidden shadow-xl animate-slide-up sm:animate-scale-in"
+ onClick={e => e.stopPropagation()}
>
-
+
diff --git a/client/src/components/FeedSidebar.tsx b/client/src/components/FeedSidebar.tsx
index 8132b7a..d1a328b 100644
--- a/client/src/components/FeedSidebar.tsx
+++ b/client/src/components/FeedSidebar.tsx
@@ -2,14 +2,13 @@ import { useAuth } from '@/hooks/useAuth';
import { useCats } from '@/hooks/useCats';
import { Avatar, AvatarFallback } from '@/components/ui/avatar';
import { Link } from 'react-router-dom';
+import { Trophy, Crown, Medal } from 'lucide-react';
-function Medal({ rank }: { rank: number }) {
- const colors = ['bg-blue-100 text-blue-700', 'bg-stone-100 text-stone-500', 'bg-amber-100 text-amber-700'];
- return (
-
- {rank + 1}
-
- );
+function RankBadge({ rank }: { rank: number }) {
+ if (rank === 0) return ;
+ if (rank === 1) return ;
+ if (rank === 2) return ;
+ return {rank + 1};
}
export default function FeedSidebar() {
@@ -29,45 +28,49 @@ export default function FeedSidebar() {
.slice(0, 5);
return (
-
-
- {cat.username.charAt(0).toUpperCase()}
+
+
+ {cat.username.charAt(0).toUpperCase()}
+
-
@{cat.username}
@@ -89,20 +91,20 @@ export default function CatModal({ catId, onClose }: CatModalProps) {
{isOwner && (
-
+
)}
-
+
+
- {likeCount > 0 && {likeCount}}
+
+ {likeCount > 0 && {likeCount}}
-
- 🏆
- {cat.user_points}
- баллов
+
+
+ {cat.user_points}
+ баллов
{!imageLoaded && (
@@ -133,16 +135,16 @@ export default function CatModal({ catId, onClose }: CatModalProps) {
onClick={toggleLike}
disabled={isOwner || !user}
className={`flex items-center gap-1.5 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'
}`}
>
-
-
+
)}
-
- {cat.username.charAt(0).toUpperCase()}
+
+
+ {cat.username.charAt(0).toUpperCase()}
+
-
-
+ - @{cat.username} - {cat.caption || 'Без подписи'} -
-+ @{cat.username} + {cat.caption || 'Без подписи'} +
+
{user && (
-
-
-
+
+
+
{user.username.charAt(0).toUpperCase()}
-
)}
- {user.username}
-🏆 {user.points} баллов
+{user.username}
+
+
-
- 🏆 Лидеры
+
- 🏆 Лидеры
+
+
+ Лидеры
{topUsers.length === 0 ? (
- Пока нет пользователей
+ Пока никого нет
) : (
-
+
{topUsers.map(([id, u], i) => (
-
-
-
- {u.username.charAt(0).toUpperCase()}
+
+
+
+
+ {u.username.charAt(0).toUpperCase()}
+
- {u.username}
- {u.points}
+ {u.username}
+ {u.points}
))}
)}
- Catstagram · сообщество котоводов
+ Catstagram · сообщество котоводов
);
}
\ No newline at end of file
diff --git a/client/src/components/Navbar.tsx b/client/src/components/Navbar.tsx
index ca89250..851d5a5 100644
--- a/client/src/components/Navbar.tsx
+++ b/client/src/components/Navbar.tsx
@@ -1,7 +1,7 @@
import { Link, useLocation } from 'react-router-dom';
import { useAuth } from '@/hooks/useAuth';
import { Avatar, AvatarFallback } from '@/components/ui/avatar';
-import { Shield } from 'lucide-react';
+import { Home, PlusCircle, User, Shield } from 'lucide-react';
export default function Navbar() {
const { user } = useAuth();
@@ -10,25 +10,29 @@ export default function Navbar() {
if (!user) return null;
return (
-
+ Лидеры
{topUsers.length === 0 ? (
- Пока нет пользователей
+Пока никого нет
) : ( -
+
-
{topUsers.map(([id, u], i) => (
-
-
-
- {u.username.charAt(0).toUpperCase()}
+
+
+
+
+ {u.username.charAt(0).toUpperCase()}
+
- {u.username}
- {u.points}
+ {u.username}
+ {u.points}
))}
)}
Catstagram · сообщество котоводов
+Catstagram · сообщество котоводов