"use client";
import { useState } from "react";
import {
StickyNote,
Pin,
Bell,
Check,
Calendar as CalendarIcon,
X,
} from "lucide-react";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Calendar } from "@/components/ui/calendar";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import { cn } from "@/lib/utils";
type ColorLabel = {
id: string;
name: string;
class: string;
activeClass: string;
};
const colorLabels: ColorLabel[] = [
{ id: "none", name: "None", class: "bg-muted", activeClass: "ring-muted-foreground" },
{ id: "red", name: "Red", class: "bg-red-500", activeClass: "ring-red-500" },
{ id: "orange", name: "Orange", class: "bg-orange-500", activeClass: "ring-orange-500" },
{ id: "yellow", name: "Yellow", class: "bg-yellow-500", activeClass: "ring-yellow-500" },
{ id: "green", name: "Green", class: "bg-green-500", activeClass: "ring-green-500" },
{ id: "blue", name: "Blue", class: "bg-blue-500", activeClass: "ring-blue-500" },
{ id: "purple", name: "Purple", class: "bg-purple-500", activeClass: "ring-purple-500" },
];
export const title = "React Dialog Block Quick Note";
export default function DialogQuickNote() {
const [open, setOpen] = useState(false);
const [saved, setSaved] = useState(false);
const [title, setTitle] = useState("");
const [content, setContent] = useState("");
const [selectedColor, setSelectedColor] = useState("none");
const [isPinned, setIsPinned] = useState(false);
const [reminderDate, setReminderDate] = useState<Date | undefined>();
const [showCalendar, setShowCalendar] = useState(false);
const handleSave = () => {
console.log({ title, content, selectedColor, isPinned, reminderDate });
setSaved(true);
};
const handleClose = () => {
setOpen(false);
setTimeout(() => {
setSaved(false);
setTitle("");
setContent("");
setSelectedColor("none");
setIsPinned(false);
setReminderDate(undefined);
setShowCalendar(false);
}, 200);
};
const formatDate = (date: Date) => {
return date.toLocaleDateString("en-US", {
month: "short",
day: "numeric",
year: date.getFullYear() !== new Date().getFullYear() ? "numeric" : undefined,
});
};
const selectedColorData = colorLabels.find((c) => c.id === selectedColor);
return (
<Dialog open={open} onOpenChange={setOpen}>
<div className="flex min-h-[350px] items-center justify-center">
<DialogTrigger asChild>
<Button variant="outline">
<StickyNote className="mr-2 h-4 w-4" />
Quick Note
</Button>
</DialogTrigger>
</div>
<DialogContent className="sm:max-w-md">
{saved ? (
<>
<DialogHeader className="text-center">
<div className="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-primary/10 mb-4">
<Check className="h-6 w-6 text-primary" />
</div>
<DialogTitle>Note Saved</DialogTitle>
<DialogDescription>
{title ? `"${title}"` : "Your note"} has been saved
{isPinned && " and pinned"}
{reminderDate && ` with a reminder for ${formatDate(reminderDate)}`}.
</DialogDescription>
</DialogHeader>
<DialogFooter>
<Button onClick={handleClose} className="w-full">
Done
</Button>
</DialogFooter>
</>
) : (
<>
<DialogHeader>
<DialogTitle className="flex items-center gap-2">
<StickyNote className="h-5 w-5" />
Quick Note
</DialogTitle>
<DialogDescription>
Capture your thought quickly.
</DialogDescription>
</DialogHeader>
<div className="space-y-4 py-4">
<div className="space-y-2">
<Label htmlFor="note-title">Title (optional)</Label>
<Input
id="note-title"
placeholder="Note title..."
value={title}
onChange={(e) => setTitle(e.target.value)}
/>
</div>
<div className="space-y-2">
<Label htmlFor="note-content">Note</Label>
<Textarea
id="note-content"
placeholder="Write your note here..."
value={content}
onChange={(e) => setContent(e.target.value)}
className="min-h-[120px] resize-none"
/>
</div>
<div className="space-y-2">
<Label>Color Label</Label>
<div className="flex gap-2">
{colorLabels.map((color) => (
<button
key={color.id}
onClick={() => setSelectedColor(color.id)}
className={cn(
"h-6 w-6 rounded-full transition-all",
color.class,
selectedColor === color.id && `ring-2 ring-offset-2 ${color.activeClass}`
)}
title={color.name}
/>
))}
</div>
</div>
<div className="flex items-center gap-4">
<Popover open={showCalendar} onOpenChange={setShowCalendar}>
<PopoverTrigger asChild>
<Button
variant={reminderDate ? "secondary" : "outline"}
size="sm"
className="gap-2"
>
<Bell className="h-4 w-4" />
{reminderDate ? formatDate(reminderDate) : "Add Reminder"}
{reminderDate && (
<span
onClick={(e) => {
e.stopPropagation();
setReminderDate(undefined);
}}
className="ml-1 rounded-full hover:bg-muted-foreground/20 p-0.5"
>
<X className="h-3 w-3" />
</span>
)}
</Button>
</PopoverTrigger>
<PopoverContent className="w-auto p-0" align="start">
<Calendar
mode="single"
selected={reminderDate}
onSelect={(date) => {
setReminderDate(date);
setShowCalendar(false);
}}
disabled={(date) => date < new Date()}
initialFocus
/>
</PopoverContent>
</Popover>
<Button
variant={isPinned ? "secondary" : "outline"}
size="sm"
className="gap-2"
onClick={() => setIsPinned(!isPinned)}
>
<Pin className={cn("h-4 w-4", isPinned && "fill-current")} />
{isPinned ? "Pinned" : "Pin Note"}
</Button>
</div>
{(selectedColor !== "none" || isPinned || reminderDate) && (
<div className="flex flex-wrap gap-2 pt-2 border-t">
{selectedColor !== "none" && (
<Badge variant="secondary" className="gap-1.5">
<span className={cn("h-2 w-2 rounded-full", selectedColorData?.class)} />
{selectedColorData?.name}
</Badge>
)}
{isPinned && (
<Badge variant="secondary" className="gap-1">
<Pin className="h-3 w-3" />
Pinned
</Badge>
)}
{reminderDate && (
<Badge variant="secondary" className="gap-1">
<Bell className="h-3 w-3" />
{formatDate(reminderDate)}
</Badge>
)}
</div>
)}
</div>
<DialogFooter className="gap-2 sm:gap-0">
<Button variant="outline" onClick={handleClose}>
Cancel
</Button>
<Button onClick={handleSave} disabled={!content.trim()}>
Save Note
</Button>
</DialogFooter>
</>
)}
</DialogContent>
</Dialog>
);
}