Первоначальная версия VidConf
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
import { Link, useNavigate } from 'react-router-dom'
|
||||
import { Calendar, Lock, Play, Repeat, X } from 'lucide-react'
|
||||
import type { OccurrenceOut } from '@/api/conferences'
|
||||
|
||||
interface ConferenceOccurrenceDialogProps {
|
||||
occurrence: OccurrenceOut
|
||||
onClose: () => void
|
||||
}
|
||||
|
||||
function formatRange(startsAt: string, endsAt: string): string {
|
||||
const start = new Date(startsAt)
|
||||
const end = new Date(endsAt)
|
||||
const dateLabel = start.toLocaleDateString('ru-RU', { day: 'numeric', month: 'long', year: 'numeric' })
|
||||
const startTime = start.toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' })
|
||||
const endTime = end.toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' })
|
||||
return `${dateLabel}, ${startTime}–${endTime}`
|
||||
}
|
||||
|
||||
/**
|
||||
* Быстрый просмотр вхождения конференции по клику на чип в календаре — для
|
||||
* конференций, которые пользователь не организует (не владелец —
|
||||
* `is_owner`): свои конференции CalendarPage открывает сразу в форме
|
||||
* редактирования (`ConferenceFormCard`). Здесь — минимум: когда, статус, вход
|
||||
* и ссылка на управление; подробности состава участников/организатора — в
|
||||
* ховер-карточке при наведении/фокусе на чип (`ConferenceHoverCard`).
|
||||
*/
|
||||
export function ConferenceOccurrenceDialog({ occurrence, onClose }: ConferenceOccurrenceDialogProps) {
|
||||
const navigate = useNavigate()
|
||||
|
||||
return (
|
||||
<div className="modal-overlay" role="dialog" aria-modal="true" aria-labelledby="occurrence-dialog-title" onClick={onClose}>
|
||||
<div className="modal-panel" onClick={(e) => e.stopPropagation()}>
|
||||
<div className="modal-head">
|
||||
<h2 id="occurrence-dialog-title">
|
||||
{occurrence.is_closed && <Lock className="title-lock" aria-hidden="true" />}
|
||||
{occurrence.title ?? 'Конференция без названия'}
|
||||
</h2>
|
||||
<button type="button" className="modal-close" aria-label="Закрыть" onClick={onClose}>
|
||||
<X className="lucide" style={{ width: 16, height: 16 }} aria-hidden="true" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="detail-row">
|
||||
<Calendar style={{ width: 18, height: 18 }} aria-hidden="true" />
|
||||
<span className="label">Когда</span>
|
||||
<span>{formatRange(occurrence.starts_at, occurrence.ends_at)}</span>
|
||||
</div>
|
||||
<div className="detail-row">
|
||||
<Repeat style={{ width: 18, height: 18 }} aria-hidden="true" />
|
||||
<span className="label">Номер</span>
|
||||
<span>{occurrence.number}</span>
|
||||
</div>
|
||||
{occurrence.is_pinned && (
|
||||
<div className="detail-row">
|
||||
<Repeat style={{ width: 18, height: 18 }} aria-hidden="true" />
|
||||
<span className="label">Статус</span>
|
||||
<span>Закреплённая конференция — повторяется по расписанию</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="modal-actions">
|
||||
<button type="button" className="btn btn-primary" onClick={() => navigate(`/j/${occurrence.slug}`)}>
|
||||
<Play style={{ width: 16, height: 16 }} aria-hidden="true" />
|
||||
Войти
|
||||
</button>
|
||||
</div>
|
||||
<p className="field-hint" style={{ textAlign: 'center', marginTop: 'var(--space-3)' }}>
|
||||
Управление и редактирование — в <Link to="/my-conferences">«Моих конференциях»</Link>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user