summaryrefslogtreecommitdiff
path: root/examples/server/webui/src/components/ModalProvider.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'examples/server/webui/src/components/ModalProvider.tsx')
-rw-r--r--examples/server/webui/src/components/ModalProvider.tsx151
1 files changed, 151 insertions, 0 deletions
diff --git a/examples/server/webui/src/components/ModalProvider.tsx b/examples/server/webui/src/components/ModalProvider.tsx
new file mode 100644
index 00000000..f2ebf8e0
--- /dev/null
+++ b/examples/server/webui/src/components/ModalProvider.tsx
@@ -0,0 +1,151 @@
+import React, { createContext, useState, useContext } from 'react';
+
+type ModalContextType = {
+ showConfirm: (message: string) => Promise<boolean>;
+ showPrompt: (
+ message: string,
+ defaultValue?: string
+ ) => Promise<string | undefined>;
+ showAlert: (message: string) => Promise<void>;
+};
+const ModalContext = createContext<ModalContextType>(null!);
+
+interface ModalState<T> {
+ isOpen: boolean;
+ message: string;
+ defaultValue?: string;
+ resolve: ((value: T) => void) | null;
+}
+
+export function ModalProvider({ children }: { children: React.ReactNode }) {
+ const [confirmState, setConfirmState] = useState<ModalState<boolean>>({
+ isOpen: false,
+ message: '',
+ resolve: null,
+ });
+ const [promptState, setPromptState] = useState<
+ ModalState<string | undefined>
+ >({ isOpen: false, message: '', resolve: null });
+ const [alertState, setAlertState] = useState<ModalState<void>>({
+ isOpen: false,
+ message: '',
+ resolve: null,
+ });
+ const inputRef = React.useRef<HTMLInputElement>(null);
+
+ const showConfirm = (message: string): Promise<boolean> => {
+ return new Promise((resolve) => {
+ setConfirmState({ isOpen: true, message, resolve });
+ });
+ };
+
+ const showPrompt = (
+ message: string,
+ defaultValue?: string
+ ): Promise<string | undefined> => {
+ return new Promise((resolve) => {
+ setPromptState({ isOpen: true, message, defaultValue, resolve });
+ });
+ };
+
+ const showAlert = (message: string): Promise<void> => {
+ return new Promise((resolve) => {
+ setAlertState({ isOpen: true, message, resolve });
+ });
+ };
+
+ const handleConfirm = (result: boolean) => {
+ confirmState.resolve?.(result);
+ setConfirmState({ isOpen: false, message: '', resolve: null });
+ };
+
+ const handlePrompt = (result?: string) => {
+ promptState.resolve?.(result);
+ setPromptState({ isOpen: false, message: '', resolve: null });
+ };
+
+ const handleAlertClose = () => {
+ alertState.resolve?.();
+ setAlertState({ isOpen: false, message: '', resolve: null });
+ };
+
+ return (
+ <ModalContext.Provider value={{ showConfirm, showPrompt, showAlert }}>
+ {children}
+
+ {/* Confirm Modal */}
+ {confirmState.isOpen && (
+ <dialog className="modal modal-open z-[1100]">
+ <div className="modal-box">
+ <h3 className="font-bold text-lg">{confirmState.message}</h3>
+ <div className="modal-action">
+ <button
+ className="btn btn-ghost"
+ onClick={() => handleConfirm(false)}
+ >
+ Cancel
+ </button>
+ <button
+ className="btn btn-error"
+ onClick={() => handleConfirm(true)}
+ >
+ Confirm
+ </button>
+ </div>
+ </div>
+ </dialog>
+ )}
+
+ {/* Prompt Modal */}
+ {promptState.isOpen && (
+ <dialog className="modal modal-open z-[1100]">
+ <div className="modal-box">
+ <h3 className="font-bold text-lg">{promptState.message}</h3>
+ <input
+ type="text"
+ className="input input-bordered w-full mt-2"
+ defaultValue={promptState.defaultValue}
+ ref={inputRef}
+ onKeyDown={(e) => {
+ if (e.key === 'Enter') {
+ handlePrompt((e.target as HTMLInputElement).value);
+ }
+ }}
+ />
+ <div className="modal-action">
+ <button className="btn btn-ghost" onClick={() => handlePrompt()}>
+ Cancel
+ </button>
+ <button
+ className="btn btn-primary"
+ onClick={() => handlePrompt(inputRef.current?.value)}
+ >
+ Submit
+ </button>
+ </div>
+ </div>
+ </dialog>
+ )}
+
+ {/* Alert Modal */}
+ {alertState.isOpen && (
+ <dialog className="modal modal-open z-[1100]">
+ <div className="modal-box">
+ <h3 className="font-bold text-lg">{alertState.message}</h3>
+ <div className="modal-action">
+ <button className="btn" onClick={handleAlertClose}>
+ OK
+ </button>
+ </div>
+ </div>
+ </dialog>
+ )}
+ </ModalContext.Provider>
+ );
+}
+
+export function useModals() {
+ const context = useContext(ModalContext);
+ if (!context) throw new Error('useModals must be used within ModalProvider');
+ return context;
+}