fix and update
This commit is contained in:
130
apps/frontend/components/family/family-sidebar-panel.tsx
Normal file
130
apps/frontend/components/family/family-sidebar-panel.tsx
Normal file
@@ -0,0 +1,130 @@
|
||||
'use client';
|
||||
|
||||
import Link from 'next/link';
|
||||
import { useState } from 'react';
|
||||
import { Loader2, Search, UsersRound } from 'lucide-react';
|
||||
import { AvatarWithPresence } from '@/components/family/avatar-with-presence';
|
||||
import { FamilyGroupSelector } from '@/components/family/family-group-selector';
|
||||
import { FamilyInviteDialog } from '@/components/family/family-invite-dialog';
|
||||
import { useFamilyOverlay } from '@/components/family/family-overlay-provider';
|
||||
import { useAuth } from '@/components/id/auth-provider';
|
||||
import { useSelectedFamily } from '@/hooks/use-primary-family';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
export function FamilySidebarPanel() {
|
||||
const { user, token } = useAuth();
|
||||
const {
|
||||
group,
|
||||
groupSummaries,
|
||||
loading,
|
||||
hasFamily,
|
||||
selectedGroupId,
|
||||
setSelectedGroupId,
|
||||
presenceByUserId,
|
||||
refresh
|
||||
} = useSelectedFamily(Boolean(user && token));
|
||||
const { openChatWithMember } = useFamilyOverlay();
|
||||
const [inviteOpen, setInviteOpen] = useState(false);
|
||||
|
||||
if (!user || !token) return null;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="mt-5 border-t border-[#eceef4] pt-4">
|
||||
<div className="mb-2 flex items-center justify-between gap-1">
|
||||
<div className="min-w-0">
|
||||
<p className="truncate text-[11px] font-semibold uppercase tracking-wide text-[#667085]">Семья</p>
|
||||
{hasFamily ? (
|
||||
<FamilyGroupSelector
|
||||
groups={groupSummaries}
|
||||
selectedGroupId={selectedGroupId}
|
||||
onSelect={setSelectedGroupId}
|
||||
href={`/family/${group!.id}`}
|
||||
nameClassName="text-xs font-medium text-[#1f2430]"
|
||||
/>
|
||||
) : (
|
||||
<Link href="/family" className="text-xs font-medium text-[#3390ec] hover:underline">
|
||||
Создать семью
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
{hasFamily ? (
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-7 w-7 shrink-0 rounded-lg"
|
||||
aria-label="Найти и пригласить"
|
||||
onClick={() => setInviteOpen(true)}
|
||||
>
|
||||
<Search className="h-3.5 w-3.5" />
|
||||
</Button>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
{loading ? (
|
||||
<div className="flex items-center gap-2 py-2 text-[11px] text-[#667085]">
|
||||
<Loader2 className="h-3.5 w-3.5 animate-spin" />
|
||||
Загрузка...
|
||||
</div>
|
||||
) : hasFamily ? (
|
||||
<div className="max-h-[220px] space-y-1 overflow-y-auto pr-1">
|
||||
{(group?.members ?? []).map((member) => {
|
||||
const presence = presenceByUserId.get(member.userId);
|
||||
const isSelf = member.userId === user.id;
|
||||
return (
|
||||
<button
|
||||
key={member.id}
|
||||
type="button"
|
||||
className={cn(
|
||||
'flex w-full items-center gap-2 rounded-xl px-2 py-1.5 text-left transition hover:bg-[#f4f5f8]',
|
||||
isSelf && 'bg-[#fafbfd]'
|
||||
)}
|
||||
onClick={() => openChatWithMember(member.userId, member.displayName)}
|
||||
title={isSelf ? 'Вы' : `Написать ${member.displayName}`}
|
||||
>
|
||||
<AvatarWithPresence
|
||||
userId={member.userId}
|
||||
displayName={member.displayName}
|
||||
hasAvatar={member.hasAvatar}
|
||||
token={token}
|
||||
isVerified={member.isVerified}
|
||||
verificationIcon={member.verificationIcon}
|
||||
online={isSelf ? undefined : presence?.online}
|
||||
className="h-8 w-8"
|
||||
/>
|
||||
<div className="min-w-0 flex-1">
|
||||
<p className="truncate text-[12px] font-medium leading-tight">
|
||||
{member.displayName}
|
||||
{isSelf ? ' (Вы)' : ''}
|
||||
</p>
|
||||
{!isSelf ? (
|
||||
<p className={cn('truncate text-[10px]', presence?.online ? 'text-emerald-600' : 'text-[#a8adbc]')}>
|
||||
{presence?.online ? 'В сети' : 'Не в сети'}
|
||||
</p>
|
||||
) : null}
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
) : (
|
||||
<div className="rounded-xl bg-[#f4f5f8] px-2 py-3 text-[11px] text-[#667085]">
|
||||
<UsersRound className="mb-1 h-4 w-4" />
|
||||
Приглашайте близких и общайтесь в чатах
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{hasFamily ? (
|
||||
<FamilyInviteDialog
|
||||
groupId={group!.id}
|
||||
open={inviteOpen}
|
||||
onOpenChange={setInviteOpen}
|
||||
onInvited={() => void refresh()}
|
||||
/>
|
||||
) : null}
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user