diff --git a/frontend/src/app/staff/furnitureItems/page.tsx b/frontend/src/app/staff/furnitureItems/page.tsx
index bd99a29..d9c51b4 100644
--- a/frontend/src/app/staff/furnitureItems/page.tsx
+++ b/frontend/src/app/staff/furnitureItems/page.tsx
@@ -45,7 +45,6 @@ export default function furnitureItemTemplate() {
const handleBeginEditing = (category: string) => {
setEditingCategory(category);
- console.log(category);
};
const handleFinishEditing = () => {
diff --git a/frontend/src/app/vsr/page.tsx b/frontend/src/app/vsr/page.tsx
index fc41e66..e1034a3 100644
--- a/frontend/src/app/vsr/page.tsx
+++ b/frontend/src/app/vsr/page.tsx
@@ -35,6 +35,7 @@ import { ICreateVSRFormInput, IVSRFormInput } from "@/components/VSRForm/VSRForm
import { vsrInputFieldValidators } from "@/components/VSRForm/VSRFormValidators";
import { ListDetail, SingleDetail } from "@/components/VSRIndividual";
import styles from "@/app/vsr/page.module.css";
+import { useDirtyForm } from "@/hooks/useDirtyForm";
enum VSRFormError {
CANNOT_RETRIEVE_FURNITURE_NO_INTERNET,
@@ -56,11 +57,13 @@ const VeteranServiceRequest: React.FC = () => {
register,
handleSubmit,
control,
- formState: { errors, isValid },
+ formState: { errors, isValid, dirtyFields },
watch,
reset,
} = formProps;
+ useDirtyForm({ isDirty: Object.keys(dirtyFields).length > 0 });
+
/**
* Internal state for fields that are complicated and cannot be controlled with a
* named form field alone (e.g. there is a multiple choice and a text field for "Other")
diff --git a/frontend/src/components/FurnitureRequest/EditTemplate/index.tsx b/frontend/src/components/FurnitureRequest/EditTemplate/index.tsx
index a15c500..4dd6158 100644
--- a/frontend/src/components/FurnitureRequest/EditTemplate/index.tsx
+++ b/frontend/src/components/FurnitureRequest/EditTemplate/index.tsx
@@ -17,6 +17,7 @@ import { ConfirmDeleteModal } from "@/components/shared/ConfirmDeleteModal";
import { Button } from "@/components/shared/Button";
import { NotificationBanner } from "@/components/shared/NotificationBanner";
import { ConfirmDiscardEditsModal } from "@/components/shared/ConfirmDiscardEditsModal";
+import { useDirtyForm } from "@/hooks/useDirtyForm";
enum FurnitureItemAction {
NONE,
@@ -178,6 +179,13 @@ export const EditTemplate = ({
const canSelectAnotherItem = isEditing && !isAddingNewItem && !editingItemId;
+ const hasUnsavedChanges =
+ (isAddingNewItem && (itemName !== "" || allowMultiple)) ||
+ (editingItemId !== null &&
+ (itemName !== getFurnitureItemById(editingItemId)?.name ||
+ allowMultiple !== getFurnitureItemById(editingItemId)?.allowMultiple));
+ useDirtyForm({ isDirty: hasUnsavedChanges });
+
return (
<>
@@ -264,12 +272,7 @@ export const EditTemplate = ({
variant="error"
outlined
onClick={() => {
- if (
- (isAddingNewItem && (itemName || allowMultiple)) ||
- (editingItemId &&
- (itemName !== getFurnitureItemById(editingItemId)?.name ||
- allowMultiple !== getFurnitureItemById(editingItemId)?.allowMultiple))
- ) {
+ if (hasUnsavedChanges) {
setDiscardEditsConfirmationModalOpen(true);
} else {
onFinishEditing();
diff --git a/frontend/src/components/VSRIndividual/VSRIndividualPage/index.tsx b/frontend/src/components/VSRIndividual/VSRIndividualPage/index.tsx
index c9db9a5..ef16252 100644
--- a/frontend/src/components/VSRIndividual/VSRIndividualPage/index.tsx
+++ b/frontend/src/components/VSRIndividual/VSRIndividualPage/index.tsx
@@ -34,6 +34,7 @@ import { useMediaQuery } from "@mui/material";
import styles from "@/components/VSRIndividual/VSRIndividualPage/styles.module.css";
import { ConfirmDiscardEditsModal } from "@/components/shared/ConfirmDiscardEditsModal";
import { ADMIN_ROLE } from "@/constants/roles";
+import { useDirtyForm } from "@/hooks/useDirtyForm";
enum VSRIndividualError {
CANNOT_RETRIEVE_FURNITURE_NO_INTERNET,
@@ -60,7 +61,14 @@ export const VSRIndividualPage = () => {
const [isEditing, setIsEditing] = useState(false);
const formProps = useForm();
- const { handleSubmit } = formProps;
+ const {
+ handleSubmit,
+ formState: { dirtyFields },
+ reset,
+ } = formProps;
+
+ const isDirty = Object.keys(dirtyFields).length > 0;
+ useDirtyForm({ isDirty });
const [updateStatusSuccessNotificationOpen, setUpdateStatusSuccessNotificationOpen] =
useState(false);
@@ -148,6 +156,7 @@ export const VSRIndividualPage = () => {
// Handle success/error
if (response.success) {
+ reset();
setIsEditing(false);
setVSR(response.data);
setEditSuccessNotificationOpen(true);
@@ -277,6 +286,12 @@ export const VSRIndividualPage = () => {
setLoadingDownload(false);
};
+ const discardChanges = () => {
+ reset();
+ fetchVSR();
+ setIsEditing(false);
+ };
+
/**
* Conditionally renders the "Approve" button on the page, if the VSR's status is "Received"
*/
@@ -312,7 +327,13 @@ export const VSRIndividualPage = () => {
iconAlt="Close"
text="Discard Changes"
hideTextOnMobile
- onClick={() => setDiscardEditsConfirmationModalOpen(true)}
+ onClick={() => {
+ if (isDirty) {
+ setDiscardEditsConfirmationModalOpen(true);
+ } else {
+ discardChanges();
+ }
+ }}
/>