update confirm modal logic

This commit is contained in:
Nate Kelley 2025-03-20 15:58:48 -06:00
parent 1a8532cb54
commit 5193e17a1d
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
3 changed files with 72 additions and 23 deletions

View File

@ -55,3 +55,38 @@ export const Default: Story = {
); );
} }
}; };
export const Sequential: Story = {
render: () => {
const { openConfirmModal } = useBusterNotifications();
const handleSequentialModals = async () => {
await openConfirmModal({
title: 'First Modal',
content: 'This is the first modal in the sequence.',
onOk: fn(),
onCancel: fn()
});
await new Promise((resolve) => setTimeout(resolve, 100));
await openConfirmModal({
title: 'Second Modal',
content: 'Here comes the second modal!',
onOk: fn(),
onCancel: fn()
});
await new Promise((resolve) => setTimeout(resolve, 100));
await openConfirmModal({
title: 'Final Modal',
content: 'This is the last modal in our sequence.',
onOk: fn(),
onCancel: fn()
});
};
return <Button onClick={handleSequentialModals}>Open Sequential Modals</Button>;
}
};

View File

@ -1,5 +1,5 @@
import { ConfirmModalProps, ConfirmProps } from '@/components/ui/modal/ConfirmModal'; import { ConfirmModalProps, ConfirmProps } from '@/components/ui/modal/ConfirmModal';
import { useState, useRef } from 'react'; import { useState, useRef, useMemo } from 'react';
const defaultConfirmModalProps: ConfirmProps = { const defaultConfirmModalProps: ConfirmProps = {
title: '', title: '',
@ -8,19 +8,22 @@ const defaultConfirmModalProps: ConfirmProps = {
onCancel: async () => {} onCancel: async () => {}
}; };
interface QueuedModal extends ConfirmProps {
resolve: (value: void) => void;
reject: (reason?: any) => void;
onClose: () => void;
}
export const useOpenConfirmModal = () => { export const useOpenConfirmModal = () => {
const [open, setOpen] = useState(false); const [modalQueue, setModalQueue] = useState<QueuedModal[]>([]);
const confirmModalPropsRef = useRef<ConfirmProps>(defaultConfirmModalProps); const currentModal = modalQueue[0]; // Get the first modal in the queue
const resolveRef = useRef<((value: void) => void) | null>(null);
const rejectRef = useRef<((reason?: any) => void) | null>(null);
const openConfirmModal = (props: ConfirmProps): Promise<void> => { const openConfirmModal = (props: ConfirmProps): Promise<void> => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
resolveRef.current = resolve; const newModal: QueuedModal = {
rejectRef.current = reject;
confirmModalPropsRef.current = {
...props, ...props,
resolve,
reject,
onOk: async () => { onOk: async () => {
try { try {
await props.onOk(); await props.onOk();
@ -28,7 +31,8 @@ export const useOpenConfirmModal = () => {
} catch (error) { } catch (error) {
reject(error); reject(error);
} finally { } finally {
setOpen(false); // Remove the current modal from the queue
setModalQueue((prev) => prev.slice(1));
} }
}, },
onCancel: async () => { onCancel: async () => {
@ -38,24 +42,34 @@ export const useOpenConfirmModal = () => {
} catch (error) { } catch (error) {
reject(error); reject(error);
} finally { } finally {
setOpen(false); // Remove the current modal from the queue
setModalQueue((prev) => prev.slice(1));
} }
},
onClose: () => {
resolve();
setModalQueue((prev) => prev.slice(1));
} }
}; };
setOpen(true); setModalQueue((prev) => [...prev, newModal]);
}); });
}; };
const onCloseConfirmModal = () => { const confirmModalProps: ConfirmModalProps = useMemo(() => {
setOpen(false); return currentModal
}; ? {
...currentModal,
open: true
}
: {
...defaultConfirmModalProps,
open: false,
onClose: () => {}
};
}, [currentModal]);
const confirmModalProps: ConfirmModalProps = { return useMemo(() => {
...confirmModalPropsRef.current, return { openConfirmModal, confirmModalProps };
open, }, [openConfirmModal, confirmModalProps]);
onClose: onCloseConfirmModal
};
return { openConfirmModal, confirmModalProps };
}; };

View File

@ -1,7 +1,7 @@
'use client'; 'use client';
import { DashboardViewProps } from '../config'; import { DashboardViewProps } from '../config';
import React, { useState } from 'react'; import React from 'react';
import { useMemoizedFn } from '@/hooks'; import { useMemoizedFn } from '@/hooks';
import { DashboardEditTitles } from './DashboardEditTitle'; import { DashboardEditTitles } from './DashboardEditTitle';
import { DashboardContentController } from './DashboardContentController'; import { DashboardContentController } from './DashboardContentController';