import { useState, useEffect } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { Search, Plus, Menu, MessageSquare, X, User as UserIcon, } from 'lucide-react'; import { useAuthStore } from '../stores/authStore'; import { useChatStore } from '../stores/chatStore'; import { useLang } from '../lib/i18n'; import { api } from '../lib/api'; import { getInitials, generateAvatarColor } from '../lib/utils'; import Avatar from './Avatar'; import { StoryGroup } from '../lib/types'; import ChatListItem from './ChatListItem'; import NewChatModal from './NewChatModal'; import UserProfile from './UserProfile'; import SideMenu from './SideMenu'; import StoryViewer, { CreateStoryModal } from './StoryViewer'; const API_URL = import.meta.env.VITE_API_URL || ''; export default function Sidebar() { const { user, logout } = useAuthStore(); const { chats, activeChat, searchQuery, setSearchQuery, clearStore } = useChatStore(); const { t } = useLang(); const [showNewChat, setShowNewChat] = useState(false); const [showProfile, setShowProfile] = useState(false); const [showSideMenu, setShowSideMenu] = useState(false); const [storyGroups, setStoryGroups] = useState([]); const [storyViewerIndex, setStoryViewerIndex] = useState(null); const [showCreateStory, setShowCreateStory] = useState(false); const loadStories = () => { api.getStories().then(setStoryGroups).catch(console.error); }; useEffect(() => { loadStories(); const interval = setInterval(loadStories, 30000); // refresh every 30s return () => clearInterval(interval); }, []); const filteredChats = chats.filter((chat) => { if (!searchQuery) return true; const q = searchQuery.toLowerCase(); if (chat.name?.toLowerCase().includes(q)) return true; return chat.members.some( (m) => m.user.id !== user?.id && (m.user.username.toLowerCase().includes(q) || m.user.displayName.toLowerCase().includes(q)) ); }).sort((a, b) => { // Favorites chat always on top if (a.type === 'favorites') return -1; if (b.type === 'favorites') return 1; return 0; }); const handleLogout = () => { clearStore(); logout(); }; return ( <>
{/* Шапка */}
Vortex

Vortex

{/* Поиск */}
setSearchQuery(e.target.value)} className="w-full pl-11 pr-10 py-3 rounded-2xl bg-surface-tertiary/80 text-[15px] font-medium text-white placeholder-zinc-500 border border-border/30 hover:border-border/60 focus:border-accent transition-all outline-none shadow-inner" /> {searchQuery && ( )}
{/* Story circles */} {(storyGroups.length > 0 || true) && (
{/* Add story circle */} {storyGroups.map((group, idx) => { const avatarUrl = group.user.avatar ? `${API_URL}${group.user.avatar}` : null; const isMine = group.user.id === user?.id; return ( ); })}
)} {/* Список чатов */}
{filteredChats.length === 0 ? (

{searchQuery ? t('nothingFound') : t('noChats')}

) : ( filteredChats.map((chat) => ( )) )}
{/* Модалки */} {showNewChat && setShowNewChat(false)} />} {showProfile && setShowProfile(false)} isSelf />} setShowSideMenu(false)} /> {storyViewerIndex !== null && storyGroups.length > 0 && ( { setStoryViewerIndex(null); loadStories(); }} onRefresh={loadStories} /> )} {showCreateStory && ( setShowCreateStory(false)} onCreated={loadStories} /> )} ); }