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 { RecurrencePicker } from "@/components/recurrence-picker";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { import {
Dialog, Dialog,
DialogContent, DialogContent,
@@ -9,6 +13,7 @@ import {
DialogTitle, DialogTitle,
} from "@/components/ui/dialog"; } from "@/components/ui/dialog";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
interface EventDialogProps { interface EventDialogProps {
open: boolean; open: boolean;
@@ -64,83 +69,122 @@ export const EventDialog = ({
return ( return (
<Dialog open={open} onOpenChange={handleOpenChange}> <Dialog open={open} onOpenChange={handleOpenChange}>
<DialogContent> <DialogContent className="glass-strong max-w-md">
<DialogHeader> <DialogHeader>
<DialogTitle>{editingId ? "Edit Event" : "Add Event"}</DialogTitle> <DialogTitle className="text-base">
{editingId ? "Edit Event" : "New Event"}
</DialogTitle>
<DialogDescription className="sr-only"> <DialogDescription className="sr-only">
Fill in the event details below. Title and start date are required. Fill in the event details below. Title and start date are required.
</DialogDescription> </DialogDescription>
</DialogHeader> </DialogHeader>
<Input
id="event-title"
name="title"
placeholder="Title"
value={title}
onChange={(e) => setTitle(e.target.value)}
/>
<textarea
id="event-description"
name="description"
className="border rounded p-2 w-full"
placeholder="Description"
value={description}
onChange={(e) => setDescription(e.target.value)}
/>
<Input
id="event-location"
name="location"
placeholder="Location"
value={location}
onChange={(e) => setLocation(e.target.value)}
/>
<Input
id="event-url"
name="url"
placeholder="URL"
value={url}
onChange={(e) => setUrl(e.target.value)}
/>
<RecurrencePicker value={recurrenceRule} onChange={setRecurrenceRule} />
<label className="flex items-center gap-2 mt-2" htmlFor="event-all-day"> <div className="space-y-3">
<input <Input
id="event-all-day" id="event-title"
name="allDay" name="title"
type="checkbox" placeholder="Event title"
checked={allDay} value={title}
onChange={(e) => setAllDay(e.target.checked)} onChange={(e) => setTitle(e.target.value)}
className="font-medium"
/> />
All day event
</label> <textarea
{!allDay ? ( id="event-description"
<> name="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 <Input
type="datetime-local" id="event-url"
value={start} name="url"
onChange={(e) => setStart(e.target.value)} placeholder="URL"
value={url}
onChange={(e) => setUrl(e.target.value)}
/> />
<Input </div>
type="datetime-local"
value={end} <RecurrencePicker
onChange={(e) => setEnd(e.target.value)} value={recurrenceRule}
onChange={setRecurrenceRule}
/>
<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"
<Input >
type="date" All day
value={start ? start.split("T")[0] : ""} </Label>
onChange={(e) => setStart(e.target.value)} </div>
/>
<Input <div className="space-y-2">
type="date" <div className="relative">
value={end ? end.split("T")[0] : ""} <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" />
onChange={(e) => setEnd(e.target.value)} {!allDay ? (
/> <Input
</> type="datetime-local"
)} value={start}
<DialogFooter> onChange={(e) => setStart(e.target.value)}
<Button onClick={onSave}>{editingId ? "Update" : "Save"}</Button> className="pl-8"
placeholder="Start"
/>
) : (
<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"
/>
)}
</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> </DialogFooter>
</DialogContent> </DialogContent>
</Dialog> </Dialog>