ConfirmContext.tsx 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. import React, { createContext, useContext, useState, ReactNode } from 'react';
  2. import ConfirmDialog from '../components/ConfirmDialog';
  3. interface ConfirmOptions {
  4. title?: string;
  5. message: string;
  6. confirmLabel?: string;
  7. cancelLabel?: string;
  8. }
  9. interface ConfirmContextType {
  10. confirm: (options: ConfirmOptions | string) => Promise<boolean>;
  11. }
  12. const ConfirmContext = createContext<ConfirmContextType | undefined>(undefined);
  13. export const useConfirm = () => {
  14. const context = useContext(ConfirmContext);
  15. if (!context) {
  16. throw new Error('useConfirm must be used within a ConfirmProvider');
  17. }
  18. return context;
  19. };
  20. interface ConfirmProviderProps {
  21. children: ReactNode;
  22. }
  23. export const ConfirmProvider: React.FC<ConfirmProviderProps> = ({ children }) => {
  24. const [options, setOptions] = useState<ConfirmOptions | null>(null);
  25. const [resolveRef, setResolveRef] = useState<((value: boolean) => void) | null>(null);
  26. const confirm = (opts: ConfirmOptions | string): Promise<boolean> => {
  27. return new Promise((resolve) => {
  28. if (typeof opts === 'string') {
  29. setOptions({ message: opts });
  30. } else {
  31. setOptions(opts);
  32. }
  33. setResolveRef(() => resolve);
  34. });
  35. };
  36. const handleConfirm = () => {
  37. if (resolveRef) resolveRef(true);
  38. setOptions(null);
  39. setResolveRef(null);
  40. };
  41. const handleCancel = () => {
  42. if (resolveRef) resolveRef(false);
  43. setOptions(null);
  44. setResolveRef(null);
  45. };
  46. return (
  47. <ConfirmContext.Provider value={{ confirm }}>
  48. {children}
  49. {options && (
  50. <ConfirmDialog
  51. isOpen={!!options}
  52. title={options.title}
  53. message={options.message}
  54. confirmLabel={options.confirmLabel}
  55. cancelLabel={options.cancelLabel}
  56. onConfirm={handleConfirm}
  57. onCancel={handleCancel}
  58. />
  59. )}
  60. </ConfirmContext.Provider>
  61. );
  62. };