import React, { createContext, useCallback, useContext, useMemo, useState } from "react"; import { Button, Dialog, DialogActions, DialogContent, DialogTitle, TextField, Typography } from "@mui/material"; type PromptOptions = { title?: string; message: string; defaultValue?: string; confirmLabel?: string; cancelLabel?: string; }; type PromptContextValue = { prompt: (options: PromptOptions) => Promise; }; type PromptState = PromptOptions & { open: boolean; resolver?: (value: string | null) => void; }; const PromptContext = createContext(null); export function PromptProvider({ children }: { children: React.ReactNode }) { const [state, setState] = useState({ open: false, title: "Enter value", message: "", defaultValue: "", confirmLabel: "Save", cancelLabel: "Cancel", }); const [value, setValue] = useState(""); const closeWith = useCallback((next: string | null) => { setState((prev) => { prev.resolver?.(next); return { ...prev, open: false, resolver: undefined }; }); }, []); const prompt = useCallback((options: PromptOptions) => { return new Promise((resolve) => { setValue(options.defaultValue ?? ""); setState({ open: true, title: options.title ?? "Enter value", message: options.message, defaultValue: options.defaultValue ?? "", confirmLabel: options.confirmLabel ?? "Save", cancelLabel: options.cancelLabel ?? "Cancel", resolver: resolve, }); }); }, []); const contextValue = useMemo(() => ({ prompt }), [prompt]); return ( {children} closeWith(null)} fullWidth maxWidth="xs"> {state.title} {state.message} setValue(e.target.value)} inputProps={{ maxLength: 180 }} helperText={`${value.length}/180`} /> ); } export function usePrompt() { const ctx = useContext(PromptContext); if (!ctx) throw new Error("usePrompt must be used within PromptProvider"); return ctx; }