Рабочий чат

This commit is contained in:
Халимов Рустам
2026-04-01 23:18:55 +03:00
parent 249c344df8
commit 4ae7dd60ce
42 changed files with 1016 additions and 184 deletions
@@ -1,3 +1,4 @@
import { createPortal } from 'react-dom';
import { useState } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { X, Search } from 'lucide-react';
@@ -32,14 +33,14 @@ export default function ForwardModal({ onClose, onForward }: ForwardModalProps)
return 0;
});
return (
<div className="fixed inset-0 z-50 flex items-center justify-center p-4">
return createPortal(
<div className="fixed inset-0 z-[99999] flex items-center justify-center p-4">
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
onClick={onClose}
className="absolute inset-0 bg-black/50 backdrop-blur-sm"
className="absolute inset-0 bg-black/60 backdrop-blur-md"
/>
<motion.div
initial={{ opacity: 0, scale: 0.95, y: 20 }}
@@ -48,31 +49,31 @@ export default function ForwardModal({ onClose, onForward }: ForwardModalProps)
role="dialog"
aria-modal="true"
aria-label={t('forward')}
className="relative w-full max-w-md bg-surface-secondary/90 glass-strong rounded-3xl overflow-hidden shadow-2xl border border-border"
className="relative w-full max-w-md bg-[#1a1a1a] rounded-[2rem] overflow-hidden shadow-[0_20px_50px_rgba(0,0,0,0.5)] border border-white/10"
>
<div className="p-4 flex items-center justify-between border-b border-white/5">
<h2 className="text-lg font-semibold text-white">{t('forwardMessage')}</h2>
<div className="p-5 flex items-center justify-between border-b border-white/5">
<h2 className="text-xl font-bold font-headline text-white">{t('forwardMessage')}</h2>
<button
onClick={onClose}
className="w-8 h-8 flex items-center justify-center rounded-full hover:bg-white/10 transition-colors"
className="w-10 h-10 flex items-center justify-center rounded-xl hover:bg-white/10 transition-colors"
>
<X size={20} className="text-zinc-400" />
</button>
</div>
<div className="p-4">
<div className="relative mb-4">
<Search className="absolute left-3 top-1/2 -translate-y-1/2 text-zinc-500" size={18} />
<div className="p-5">
<div className="relative mb-5">
<Search className="absolute left-4 top-1/2 -translate-y-1/2 text-zinc-500" size={18} />
<input
type="text"
placeholder={t('searchChats') || 'Поиск чатов'}
value={search}
onChange={(e) => setSearch(e.target.value)}
className="w-full bg-black/20 border border-white/10 rounded-xl py-2.5 pl-10 pr-4 text-white placeholder-zinc-500 focus:outline-none focus:border-knot-500 transition-colors"
className="w-full bg-black/40 border border-white/10 rounded-2xl py-3 pl-12 pr-4 text-white placeholder-zinc-500 focus:outline-none focus:ring-2 focus:ring-primary/20 transition-all"
/>
</div>
<div className="max-h-80 overflow-y-auto space-y-1 pr-2 custom-scrollbar">
<div className="max-h-96 overflow-y-auto space-y-1.5 pr-2 custom-scrollbar">
{filteredChats.map((chat) => {
const otherMember = chat.members.find((m) => m.userId !== user?.id);
const chatName =
@@ -88,19 +89,33 @@ export default function ForwardModal({ onClose, onForward }: ForwardModalProps)
<button
key={chat.id}
onClick={() => onForward(chat.id)}
className="w-full flex items-center gap-3 p-2 rounded-xl hover:bg-white/5 transition-colors text-left"
className="w-full flex items-center gap-4 p-3 rounded-2xl hover:bg-white/5 transition-all text-left group"
>
<Avatar src={chatAvatar} name={chatName} size="md" />
<span className="text-white font-medium flex-1 truncate">{chatName}</span>
<div className="relative group-hover:scale-105 transition-transform duration-300">
{chat.type === 'favorites' ? (
<div className="w-12 h-12 rounded-full bg-gradient-to-br from-primary to-primary-container flex items-center justify-center shadow-lg shadow-primary/10 border-2 border-outline-variant/10">
<span className="material-symbols-outlined text-on-primary-container text-[24px]">bookmark</span>
</div>
) : (
<Avatar src={chatAvatar} name={chatName} size="lg" />
)}
</div>
<div className="flex-1 min-w-0">
<div className="text-white font-bold truncate group-hover:text-primary transition-colors">{chatName}</div>
<div className="text-[11px] text-zinc-500 font-bold uppercase tracking-widest mt-0.5">
{chat.type === 'favorites' ? t('favoritesDescription') : chat.type === 'personal' ? t('chat') : `${chat.members.length} ${t('members')}`}
</div>
</div>
</button>
);
})}
{filteredChats.length === 0 && (
<p className="text-center text-zinc-500 py-4 text-sm">{t('nothingFound')}</p>
<p className="text-center text-zinc-500 py-8 text-sm">{t('nothingFound')}</p>
)}
</div>
</div>
</motion.div>
</div>
</div>,
document.body
);
}