diff --git a/frontend/src/components/calendar/ConferenceOccurrenceDialog.tsx b/frontend/src/components/calendar/ConferenceOccurrenceDialog.tsx index ff01426..6468c72 100644 --- a/frontend/src/components/calendar/ConferenceOccurrenceDialog.tsx +++ b/frontend/src/components/calendar/ConferenceOccurrenceDialog.tsx @@ -1,10 +1,15 @@ import { Link, useNavigate } from 'react-router-dom' -import { Calendar, Lock, Play, Repeat, X } from 'lucide-react' -import type { OccurrenceOut } from '@/api/conferences' +import { Calendar, Hash, Lock, Pencil, Play, Repeat, X } from 'lucide-react' +import type { ConferenceOut, OccurrenceOut } from '@/api/conferences' +import { occurrenceBadge, OCCURRENCE_BADGE_ICON } from '@/lib/occurrenceStatus' +import { useModalDismiss } from '@/hooks/useModalDismiss' interface ConferenceOccurrenceDialogProps { occurrence: OccurrenceOut + /** Присутствует только когда текущий пользователь — организатор этого вхождения (`is_owner`) — показывает кнопку «Редактировать». */ + ownedConference?: ConferenceOut onClose: () => void + onEdit?: (conference: ConferenceOut) => void } function formatRange(startsAt: string, endsAt: string): string { @@ -18,14 +23,19 @@ function formatRange(startsAt: string, endsAt: string): string { /** * Быстрый просмотр вхождения конференции по клику на чип в календаре — для - * конференций, которые пользователь не организует (не владелец — - * `is_owner`): свои конференции CalendarPage открывает сразу в форме - * редактирования (`ConferenceFormCard`). Здесь — минимум: когда, статус, вход - * и ссылка на управление; подробности состава участников/организатора — в - * ховер-карточке при наведении/фокусе на чип (`ConferenceHoverCard`). + * всех конференций, включая свои: редактирование теперь отдельное действие + * (карандашик на чипе или кнопка «Редактировать» здесь, у владельца), сам + * клик по чипу всегда открывает это окно. Показывает статус, время, номер и, + * для владельца, вход в редактирование; подробности состава + * участников/организатора — в ховер-карточке при наведении/фокусе на чип + * (`ConferenceHoverCard`). */ -export function ConferenceOccurrenceDialog({ occurrence, onClose }: ConferenceOccurrenceDialogProps) { +export function ConferenceOccurrenceDialog({ occurrence, ownedConference, onClose, onEdit }: ConferenceOccurrenceDialogProps) { const navigate = useNavigate() + useModalDismiss(onClose) + + const badge = occurrenceBadge(occurrence, new Date(occurrence.starts_at), new Date(occurrence.ends_at)) + const BadgeIcon = OCCURRENCE_BADGE_ICON[badge.kind] return (
- Управление и редактирование — в «Моих конференциях» -
+ {!ownedConference && ( ++ Управление и редактирование — в «Моих конференциях» +
+ )} ) diff --git a/frontend/src/lib/occurrenceStatus.ts b/frontend/src/lib/occurrenceStatus.ts new file mode 100644 index 0000000..f0455d4 --- /dev/null +++ b/frontend/src/lib/occurrenceStatus.ts @@ -0,0 +1,24 @@ +import { CheckCircle2, Clock, Play, Repeat } from 'lucide-react' +import type { OccurrenceOut } from '@/api/conferences' + +export type OccurrenceBadgeKind = 'scheduled' | 'pinned' | 'live' | 'ended' + +/** Общая логика статус-бейджа вхождения — используется чипом календаря и информационным окном (`ConferenceOccurrenceDialog`). */ +export function occurrenceBadge( + occ: OccurrenceOut, + start: Date | null, + end: Date | null, +): { kind: OccurrenceBadgeKind; label: string } { + const now = new Date() + if (start && end && now >= start && now <= end) return { kind: 'live', label: 'Идёт сейчас' } + if (end && now > end) return { kind: 'ended', label: 'Завершена' } + if (occ.is_pinned) return { kind: 'pinned', label: 'Закреплена' } + return { kind: 'scheduled', label: 'Запланирована' } +} + +export const OCCURRENCE_BADGE_ICON: Record