import { useEffect, useRef, useState } from 'react' import { Hand, ListOrdered } from 'lucide-react' import { useIsOrganizer } from '@/hooks/useIsOrganizer' import type { HandQueueEntry } from '@/hooks/useChat' interface HandQueueMenuProps { queue: HandQueueEntry[] onLower: (identity: string) => void } /** * Кнопка «Очередь» в тулбаре с поповером над ней — видна только организатору * (задача B1). Тот же самодостаточный паттерн, что и `StageViewMenu` («Вид»): * собственное состояние открытия, закрытие по клику вне/Escape, поповер * `.tb-menu` над кнопкой — а не боковая панель на весь экран (как чат): * очередь рук — короткий список, а не история переписки, разворачивать её * во весь экран незачем и на мобильном. * * Размер поповера подстраивается под число записей — `.hand-queue-list` * растёт вместе со списком и не даёт пустого места при 1–2 поднятых руках, * но не бесконечно: после ~10 строк список упирается в `max-height` и дальше * скроллится (см. room.css) — иначе организатор на энергичной встрече * получил бы поповер выше экрана. */ export function HandQueueMenu({ queue, onLower }: HandQueueMenuProps) { const isOrganizer = useIsOrganizer() const [open, setOpen] = useState(false) const wrapRef = useRef(null) useEffect(() => { if (!open) return function handlePointerDown(event: MouseEvent) { if (wrapRef.current && !wrapRef.current.contains(event.target as Node)) { setOpen(false) } } function handleKeydown(event: KeyboardEvent) { if (event.key === 'Escape') setOpen(false) } document.addEventListener('mousedown', handlePointerDown) document.addEventListener('keydown', handleKeydown) return () => { document.removeEventListener('mousedown', handlePointerDown) document.removeEventListener('keydown', handleKeydown) } }, [open]) if (!isOrganizer) return null return (
{open && (
{queue.length === 0 ? (

Пока никто не поднял руку

) : (
    {queue.map((entry, index) => (
  1. {index + 1}
  2. ))}
)}
)}
) }