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

View File

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