feat: initial JaniChat messenger — PWA, WebSocket, admin panel
This commit is contained in:
53
frontend/src/components/ChatListItem.tsx
Normal file
53
frontend/src/components/ChatListItem.tsx
Normal file
@@ -0,0 +1,53 @@
|
||||
import { formatDistanceToNow } from 'date-fns';
|
||||
import { ru } from 'date-fns/locale';
|
||||
import Avatar from './Avatar';
|
||||
import { Chat } from '../types';
|
||||
|
||||
interface Props {
|
||||
chat: Chat;
|
||||
active: boolean;
|
||||
online?: boolean;
|
||||
onClick: () => void;
|
||||
}
|
||||
|
||||
export default function ChatListItem({ chat, active, online, onClick }: Props) {
|
||||
const time = chat.lastMessageAt
|
||||
? formatDistanceToNow(new Date(chat.lastMessageAt), { addSuffix: false, locale: ru })
|
||||
: '';
|
||||
|
||||
const icon = chat.type === 'channel' ? '📢' : chat.type === 'group' ? '👥' : null;
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={onClick}
|
||||
className={`w-full flex items-center gap-3 px-3 py-2.5 rounded-xl text-left transition-colors ${
|
||||
active ? 'bg-blue-50' : 'hover:bg-gray-50'
|
||||
}`}
|
||||
>
|
||||
<Avatar
|
||||
name={chat.title}
|
||||
color={chat.avatarColor}
|
||||
online={chat.type === 'private' ? online : undefined}
|
||||
/>
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="font-medium text-gray-900 text-sm truncate">
|
||||
{icon && <span className="mr-1 text-xs">{icon}</span>}
|
||||
{chat.title}
|
||||
</span>
|
||||
{time && <span className="text-xs text-gray-400 flex-shrink-0 ml-1">{time}</span>}
|
||||
</div>
|
||||
<div className="flex items-center justify-between mt-0.5">
|
||||
<p className="text-xs text-gray-500 truncate">
|
||||
{chat.lastMessage || (chat.type === 'channel' ? 'Канал' : 'Нет сообщений')}
|
||||
</p>
|
||||
{chat.unreadCount > 0 && (
|
||||
<span className="bg-blue-500 text-white text-xs rounded-full min-w-[18px] h-[18px] flex items-center justify-center px-1 flex-shrink-0 ml-1">
|
||||
{chat.unreadCount > 99 ? '99+' : chat.unreadCount}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user