"use client" import type React from "react" import { useState } from "react" import { Loader2 } from "lucide-react" import { GlassModal, fieldClass, labelClass } from "./glass-modal" import * as api from "@/lib/api" import { ApiError } from "@/lib/api" import type { CalendarEvent, EventType, EventVisibility, Room } from "@/lib/types" import { parseDateTime, toBackendDateTime, toDateParam, toInputTime } from "@/lib/date-utils" interface CreateEventDialogProps { rooms: Room[] defaultRoomId: number | null defaultDate: Date /** When set, the dialog edits this event instead of creating a new one. */ editingEvent?: CalendarEvent onClose: () => void onCreated: () => void } const TYPE_OPTIONS: { value: EventType; label: string }[] = [ { value: "proposal", label: "Proposal (members vote to confirm)" }, { value: "busy", label: "Busy — room sees it as busy, no details" }, { value: "private", label: "Private — hidden from the room" }, ] const VISIBILITY_OPTIONS: { value: EventVisibility; label: string }[] = [ { value: "room", label: "Room — visible to all members" }, { value: "busy_only", label: "Busy only — hide details" }, { value: "private", label: "Private — only me" }, ] const optionClass = "bg-slate-800 text-white" export function CreateEventDialog({ rooms, defaultRoomId, defaultDate, editingEvent, onClose, onCreated, }: CreateEventDialogProps) { const isEditing = !!editingEvent const initialRoom = editingEvent?.room_id ?? defaultRoomId ?? rooms[0]?.id ?? 0 // Start time defaults to "now", rounded up to the next quarter hour. const now = new Date() const defaultStartTime = new Date(now) defaultStartTime.setMinutes(Math.ceil(now.getMinutes() / 15) * 15, 0, 0) const defaultEndTime = new Date(defaultStartTime) defaultEndTime.setHours(defaultEndTime.getHours() + 1) const editStart = editingEvent ? parseDateTime(editingEvent.start_time) : null const editEnd = editingEvent ? parseDateTime(editingEvent.end_time) : null const [roomId, setRoomId] = useState(initialRoom) const [title, setTitle] = useState(editingEvent?.title ?? "") const [description, setDescription] = useState(editingEvent?.description ?? "") const [type, setType] = useState(editingEvent?.type ?? "proposal") const [visibility, setVisibility] = useState(editingEvent?.visibility ?? "room") const [date, setDate] = useState(toDateParam(editStart ?? defaultDate)) const [multiDay, setMultiDay] = useState( editStart && editEnd ? toDateParam(editStart) !== toDateParam(editEnd) : false, ) const [endDate, setEndDate] = useState(toDateParam(editEnd ?? editStart ?? defaultDate)) const [startTime, setStartTime] = useState(toInputTime(editStart ?? defaultStartTime)) const [endTime, setEndTime] = useState(toInputTime(editEnd ?? defaultEndTime)) const [minPeople, setMinPeople] = useState(editingEvent?.min_people ?? 1) const [error, setError] = useState(null) const [submitting, setSubmitting] = useState(false) // Busy/private events are always visible to the room as just "busy" (no // details) or not visible at all — that's implied by the type, so the // visibility choice only makes sense for proposals. const handleTypeChange = (value: EventType) => { setType(value) if (value === "busy") setVisibility("busy_only") else if (value === "private") setVisibility("private") else setVisibility("room") } const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() setError(null) if (!roomId) { setError("Please select a room.") return } const startDate = new Date(`${date}T${startTime}`) const endDate2 = new Date(`${multiDay ? endDate : date}T${endTime}`) if (endDate2 <= startDate) { setError("End time must be after the start time.") return } const payload = { room_id: roomId, type, title: title.trim(), description: description.trim(), start_time: toBackendDateTime(startDate), end_time: toBackendDateTime(endDate2), visibility: type === "proposal" ? visibility : type === "busy" ? "busy_only" : "private", min_people: type === "proposal" ? minPeople : 0, } as const setSubmitting(true) try { if (isEditing && editingEvent) { await api.updateEvent(editingEvent.id, payload) } else { await api.createEvent({ ...payload, status: type === "proposal" ? "proposed" : "confirmed" }) } onCreated() onClose() } catch (err) { setError( err instanceof ApiError ? err.message : isEditing ? "Could not save the changes." : "Could not create the event.", ) } finally { setSubmitting(false) } } const dialogTitle = isEditing ? "Edit event" : "Create event" if (rooms.length === 0) { return (

You need to be in a room before creating an event. Create or join a room first.

) } return (
setTitle(e.target.value)} className={fieldClass} placeholder="e.g. Team dinner" />