feat(event-dialog): redesign with glass-strong styling, icon-decorated inputs, and Cancel button

- Apply glass-strong to DialogContent
- Add LucideMapPin and CalendarIcon/Clock icons to input fields
- Replace native checkbox with Checkbox + Label component
- Unify allDay date inputs into single relative-positioned blocks
- Add Cancel button to DialogFooter
- Rename Save to Create for new events
This commit is contained in:
2026-04-08 00:56:49 -04:00
parent e000d41474
commit a26787a026

View File

@@ -1,5 +1,9 @@
"use client";
import { CalendarIcon, Clock, LucideMapPin } from "lucide-react";
import { RecurrencePicker } from "@/components/recurrence-picker";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import {
Dialog,
DialogContent,
@@ -9,6 +13,7 @@ import {
DialogTitle,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
interface EventDialogProps {
open: boolean;
@@ -64,35 +69,47 @@ export const EventDialog = ({
return (
<Dialog open={open} onOpenChange={handleOpenChange}>
<DialogContent>
<DialogContent className="glass-strong max-w-md">
<DialogHeader>
<DialogTitle>{editingId ? "Edit Event" : "Add Event"}</DialogTitle>
<DialogTitle className="text-base">
{editingId ? "Edit Event" : "New Event"}
</DialogTitle>
<DialogDescription className="sr-only">
Fill in the event details below. Title and start date are required.
</DialogDescription>
</DialogHeader>
<div className="space-y-3">
<Input
id="event-title"
name="title"
placeholder="Title"
placeholder="Event title"
value={title}
onChange={(e) => setTitle(e.target.value)}
className="font-medium"
/>
<textarea
id="event-description"
name="description"
className="border rounded p-2 w-full"
placeholder="Description"
className="flex field-sizing-content min-h-[60px] max-h-40 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm placeholder:text-muted-foreground/50 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring resize-none"
placeholder="Add a description..."
value={description}
onChange={(e) => setDescription(e.target.value)}
/>
<div className="grid grid-cols-2 gap-3">
<div className="relative">
<LucideMapPin className="absolute left-3 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground/50" />
<Input
id="event-location"
name="location"
placeholder="Location"
value={location}
onChange={(e) => setLocation(e.target.value)}
className="pl-8"
/>
</div>
<Input
id="event-url"
name="url"
@@ -100,47 +117,74 @@ export const EventDialog = ({
value={url}
onChange={(e) => setUrl(e.target.value)}
/>
<RecurrencePicker value={recurrenceRule} onChange={setRecurrenceRule} />
</div>
<label className="flex items-center gap-2 mt-2" htmlFor="event-all-day">
<input
id="event-all-day"
name="allDay"
type="checkbox"
checked={allDay}
onChange={(e) => setAllDay(e.target.checked)}
<RecurrencePicker
value={recurrenceRule}
onChange={setRecurrenceRule}
/>
All day event
</label>
<div className="flex items-center gap-2 py-1">
<Checkbox
id="event-all-day"
checked={allDay}
onCheckedChange={(checked) => setAllDay(checked === true)}
/>
<Label
htmlFor="event-all-day"
className="text-sm font-normal cursor-pointer"
>
All day
</Label>
</div>
<div className="space-y-2">
<div className="relative">
<CalendarIcon className="absolute left-3 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground/50 pointer-events-none" />
{!allDay ? (
<>
<Input
type="datetime-local"
value={start}
onChange={(e) => setStart(e.target.value)}
className="pl-8"
placeholder="Start"
/>
<Input
type="datetime-local"
value={end}
onChange={(e) => setEnd(e.target.value)}
/>
</>
) : (
<>
<Input
type="date"
value={start ? start.split("T")[0] : ""}
onChange={(e) => setStart(e.target.value)}
className="pl-8"
/>
)}
</div>
<div className="relative">
<Clock className="absolute left-3 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground/50 pointer-events-none" />
{!allDay ? (
<Input
type="datetime-local"
value={end}
onChange={(e) => setEnd(e.target.value)}
className="pl-8"
placeholder="End"
/>
) : (
<Input
type="date"
value={end ? end.split("T")[0] : ""}
onChange={(e) => setEnd(e.target.value)}
className="pl-8"
/>
</>
)}
<DialogFooter>
<Button onClick={onSave}>{editingId ? "Update" : "Save"}</Button>
</div>
</div>
</div>
<DialogFooter className="gap-2 sm:gap-0">
<Button variant="ghost" onClick={() => handleOpenChange(false)}>
Cancel
</Button>
<Button onClick={onSave}>{editingId ? "Update" : "Create"}</Button>
</DialogFooter>
</DialogContent>
</Dialog>