Skip to content

Commit

Permalink
Project submission modal (#451)
Browse files Browse the repository at this point in the history
  • Loading branch information
aidantrabs authored Feb 6, 2025
2 parents 9e3d681 + 24530ae commit 5d8bf96
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 8 deletions.
101 changes: 101 additions & 0 deletions frontend/src/components/ConfirmationModal/ConfirmationModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import React from 'react';
import { Dialog, Transition } from '@headlessui/react';
import { Fragment } from 'react';
import { IoMdClose } from 'react-icons/io';

export interface ConfirmationModalProps {
isOpen: boolean;
onClose: () => void;
title?: string;
children: React.ReactNode;
primaryAction: () => void;
primaryActionText?: string;
secondaryActionText?: string;
primaryButtonClassName?: string;
secondaryButtonClassName?: string;
showCloseButton?: boolean;
}

export const ConfirmationModal: React.FC<ConfirmationModalProps> = ({
isOpen,
onClose,
title,
children,
primaryAction,
primaryActionText = 'Confirm',
secondaryActionText = 'Cancel',
primaryButtonClassName = '',
secondaryButtonClassName = '',
showCloseButton = true,
}) => {
return (
<Transition appear show={isOpen} as={Fragment}>
<Dialog as="div" className="relative z-50" onClose={onClose}>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-black/25" aria-hidden="true" />
</Transition.Child>

<div className="fixed inset-0 overflow-y-auto">
<div className="flex min-h-full items-center justify-center p-4">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 scale-95"
enterTo="opacity-100 scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
<Dialog.Panel className="relative w-full max-w-md transform overflow-hidden rounded-lg bg-white p-6 text-left shadow-xl transition-all">
{showCloseButton && (
<button
onClick={onClose}
className="absolute right-4 top-4 rounded-lg p-2 text-gray-400 hover:bg-gray-100 hover:text-gray-500"
>
<IoMdClose className="h-5 w-5" />
</button>
)}

{title && (
<Dialog.Title className="text-2xl font-bold text-gray-900">
{title}
</Dialog.Title>
)}

<div className="mt-4 text-base text-gray-600">
{children}
</div>

<div className="mt-8 flex justify-end gap-3">
<button
type="button"
className={`rounded-lg border border-gray-300 bg-white px-4 py-2 text-gray-900 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 ${secondaryButtonClassName}`}
onClick={onClose}
>
{secondaryActionText}
</button>

<button
type="button"
className={`rounded-lg bg-gray-500 px-4 py-2 text-white hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 ${primaryButtonClassName}`}
onClick={primaryAction}
>
{primaryActionText}
</button>
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</Dialog>
</Transition>
);
};
2 changes: 2 additions & 0 deletions frontend/src/components/ConfirmationModal/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { ConfirmationModal } from './ConfirmationModal';
export type { ConfirmationModalProps } from './ConfirmationModal';
47 changes: 39 additions & 8 deletions frontend/src/pages/user/_auth/project/$projectId.form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { SectionedLayout } from '@/templates';
import { cva } from 'class-variance-authority';
import { sanitizeHtmlId } from '@/utils/html';
import { QuestionInputs } from '@/components/QuestionInputs/QuestionInputs';
import { ConfirmationModal } from '@/components/ConfirmationModal';
import { useQuery } from '@tanstack/react-query';
import { scrollToTop } from '@/utils';
import { useDebounceFn } from '@/hooks';
Expand Down Expand Up @@ -75,6 +76,7 @@ function ProjectFormPage() {
const [currentStep, setCurrentStep] = useState<number>(0);
const dirtyInputRef = useRef<Map<string, ProjectDraft>>(new Map());
const notification = useNotification();
const [showSubmitModal, setShowSubmitModal] = useState(false);

const autosave = useDebounceFn(
async () => {
Expand Down Expand Up @@ -492,20 +494,33 @@ function ProjectFormPage() {
});

if (valid) {
try {
if (!accessToken || !currentProjectId) return;
await submitProject(accessToken, currentProjectId);
// replace to not let them go back, it causes the creation of a new project
navigate({ to: '/user/dashboard', replace: true });
} catch (e) {
console.error(e);
}
// try {
// if (!accessToken || !currentProjectId) return;
// await submitProject(accessToken, currentProjectId);
// // replace to not let them go back, it causes the creation of a new project
// navigate({ to: '/user/dashboard', replace: true });
// } catch (e) {
// console.error(e);
// }
setShowSubmitModal(true);
} else {
// update the group questions so that it refreshes the ui
setGroupedQuestions((prev) => [...prev]);
}
};

const handleSubmitConfirm = async () => {
try {
if (!accessToken || !currentProjectId) return;
await submitProject(accessToken, currentProjectId);

// replace to not let them go back, it causes the creation of a new project
navigate({ to: '/user/dashboard', replace: true });
} catch (e) {
console.error(e);
}
}

// TODO: make a better loading screen
if (groupedQuestions.length < 1 || loadingQuestions) return null;

Expand Down Expand Up @@ -650,6 +665,22 @@ function ProjectFormPage() {
</form>
</div>
</SectionedLayout>

<ConfirmationModal
isOpen={showSubmitModal}
onClose={() => setShowSubmitModal(false)}
primaryAction={handleSubmitConfirm}
title="Submit Application?"
primaryActionText="Yes, submit it"
>
<div className="space-y-4">
<p>Have you double-checked everything in this project?</p>
<p>
Once submitted, you won't be able to make changes until the application
is either approved or sent back for review.
</p>
</div>
</ConfirmationModal>
</div>
);
}

0 comments on commit 5d8bf96

Please sign in to comment.