"use client" import { useEffect, useState } from "react" import { create } from "zustand" import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/shared/components/ui/dialog" import { Button } from "@/shared/components/ui/button" import { Input } from "@/shared/components/ui/input" import { Label } from "@/shared/components/ui/label" // ── Types ── export type PromptOptions = { title?: string description?: string label?: string placeholder?: string defaultValue?: string confirmLabel?: string cancelLabel?: string required?: boolean } type PromptStore = { open: boolean options: PromptOptions resolve: ((value: string | null) => void) | null _show: (options: PromptOptions) => Promise _close: (value: string | null) => void } // ── Store ── const usePromptStore = create((set, get) => ({ open: false, options: {}, resolve: null, _show: (options) => new Promise((resolve) => { set({ open: true, options, resolve }) }), _close: (value) => { const { resolve } = get() resolve?.(value) set({ open: false, resolve: null }) }, })) // ── Imperative API ── export function prompt(options: PromptOptions = {}): Promise { return usePromptStore.getState()._show(options) } // ── Dialog component (mount once in root layout) ── export function PromptDialog() { const { open, options, _close } = usePromptStore() const [value, setValue] = useState("") // Reset value whenever the dialog opens useEffect(() => { if (open) setValue(options.defaultValue ?? "") }, [open, options.defaultValue]) const submit = () => { if (options.required !== false && value.trim() === "") return _close(value.trim()) } return ( { if (!v) _close(null) }} > {options.title ?? "Enter a value"} {options.description && ( {options.description} )}
{options.label && } setValue(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter") { e.preventDefault() submit() } }} />
) }