From 63f613e829edb764ca1601886fa62fcb5f023860 Mon Sep 17 00:00:00 2001 From: BradyMitch Date: Mon, 9 Mar 2026 15:53:47 -0700 Subject: [PATCH 1/2] added archive modal --- .../ConfirmArchiveLocationModal.tsx | 103 ++++++++++++++++++ .../ConfirmArchiveLocationModal/index.ts | 1 + 2 files changed, 104 insertions(+) create mode 100644 src/components/settings/locations/ConfirmArchiveLocationModal/ConfirmArchiveLocationModal.tsx create mode 100644 src/components/settings/locations/ConfirmArchiveLocationModal/index.ts diff --git a/src/components/settings/locations/ConfirmArchiveLocationModal/ConfirmArchiveLocationModal.tsx b/src/components/settings/locations/ConfirmArchiveLocationModal/ConfirmArchiveLocationModal.tsx new file mode 100644 index 0000000..5ddd63e --- /dev/null +++ b/src/components/settings/locations/ConfirmArchiveLocationModal/ConfirmArchiveLocationModal.tsx @@ -0,0 +1,103 @@ +"use client" + +import { useEffect, useState } from "react" +import { + CloseButton, + DialogActions, + DialogBody, + DialogHeader, + DialogTitle, + Modal, +} from "@/components/common/dialog" +import type { LocationWithRelations } from "@/lib/prisma/location/types" + +type ConfirmArchiveLocationModalProps = { + open: boolean + onClose: () => void + location: LocationWithRelations | null + updateLocation: ( + location: Partial, + prevLocation: Partial + ) => Promise + revalidateTable: () => Promise +} + +export const ConfirmArchiveLocationModal = ({ + open, + onClose, + location, + updateLocation, + revalidateTable, +}: ConfirmArchiveLocationModalProps) => { + const [formData, setFormData] = useState(null) + const [previousLocation, setPreviousLocation] = useState(null) + const [archiveConfirmation, setArchiveConfirmation] = useState("") + + const isArchived = location?.deletedAt !== null + + useEffect(() => { + if (open && location) { + setFormData(location) + setPreviousLocation(location) + } + }, [open, location]) + + if (!location || !formData || !previousLocation) return null + + const handleSave = async () => { + if (formData) { + await updateLocation( + { ...formData, deletedAt: isArchived ? null : new Date() }, + previousLocation + ) + await revalidateTable() + setArchiveConfirmation("") + onClose() + } + } + + return ( + + } className="bg-background-danger"> + + {isArchived ? "Unarchive" : "Archive"} Location + + + + +
+
+ + setArchiveConfirmation(e.target.value)} + autoComplete="off" + className="mt-2 block w-full rounded-md border border-border-dark px-2 py-1 text-xs text-typography-primary" + /> +
+
+
+ + + + + +
+ ) +} diff --git a/src/components/settings/locations/ConfirmArchiveLocationModal/index.ts b/src/components/settings/locations/ConfirmArchiveLocationModal/index.ts new file mode 100644 index 0000000..8934b31 --- /dev/null +++ b/src/components/settings/locations/ConfirmArchiveLocationModal/index.ts @@ -0,0 +1 @@ +export * from "./ConfirmArchiveLocationModal" From 964b474f2ef5e641b1b71adefc2cffaf81769f76 Mon Sep 17 00:00:00 2001 From: BradyMitch Date: Mon, 9 Mar 2026 16:08:43 -0700 Subject: [PATCH 2/2] archive button --- .../EditLocationModal.test.tsx | 90 +++++++++++++++++++ .../EditLocationModal/EditLocationModal.tsx | 10 +++ .../locations/LocationTable/LocationTable.tsx | 14 +++ 3 files changed, 114 insertions(+) diff --git a/src/components/settings/locations/EditLocationModal/EditLocationModal.test.tsx b/src/components/settings/locations/EditLocationModal/EditLocationModal.test.tsx index 7f89159..27d94c1 100644 --- a/src/components/settings/locations/EditLocationModal/EditLocationModal.test.tsx +++ b/src/components/settings/locations/EditLocationModal/EditLocationModal.test.tsx @@ -77,6 +77,7 @@ describe("EditLocationModal", () => { const updateLocation = vi.fn().mockResolvedValue(location) const revalidateTable = vi.fn().mockResolvedValue(undefined) const doesLocationCodeExist = vi.fn().mockResolvedValue(false) + const openConfirmArchiveLocationModal = vi.fn() render( { updateLocation={updateLocation} doesLocationCodeExist={doesLocationCodeExist} revalidateTable={revalidateTable} + openConfirmArchiveLocationModal={openConfirmArchiveLocationModal} /> ) @@ -101,6 +103,7 @@ describe("EditLocationModal", () => { const updateLocation = vi.fn().mockResolvedValue(location) const revalidateTable = vi.fn().mockResolvedValue(undefined) const doesLocationCodeExist = vi.fn().mockResolvedValue(false) + const openConfirmArchiveLocationModal = vi.fn() render( { updateLocation={updateLocation} doesLocationCodeExist={doesLocationCodeExist} revalidateTable={revalidateTable} + openConfirmArchiveLocationModal={openConfirmArchiveLocationModal} /> ) @@ -127,6 +131,7 @@ describe("EditLocationModal", () => { const updateLocation = vi.fn().mockResolvedValue(location) const revalidateTable = vi.fn().mockResolvedValue(undefined) const doesLocationCodeExist = vi.fn().mockResolvedValue(false) + const openConfirmArchiveLocationModal = vi.fn() const { queryByText } = render( { updateLocation={updateLocation} doesLocationCodeExist={doesLocationCodeExist} revalidateTable={revalidateTable} + openConfirmArchiveLocationModal={openConfirmArchiveLocationModal} /> ) @@ -156,6 +162,7 @@ describe("EditLocationModal", () => { const updateLocation = vi.fn().mockResolvedValue(archivedLocation) const revalidateTable = vi.fn().mockResolvedValue(undefined) const doesLocationCodeExist = vi.fn().mockResolvedValue(false) + const openConfirmArchiveLocationModal = vi.fn() render( { updateLocation={updateLocation} doesLocationCodeExist={doesLocationCodeExist} revalidateTable={revalidateTable} + openConfirmArchiveLocationModal={openConfirmArchiveLocationModal} /> ) @@ -175,4 +183,86 @@ describe("EditLocationModal", () => { expect(screen.getByText("This location is archived and cannot be edited.")).toBeTruthy() ) }) + + it("shows Archive button with text 'Archive' for active location", async () => { + const onClose = vi.fn() + const updateLocation = vi.fn().mockResolvedValue(location) + const revalidateTable = vi.fn().mockResolvedValue(undefined) + const doesLocationCodeExist = vi.fn().mockResolvedValue(false) + const openConfirmArchiveLocationModal = vi.fn() + + render( + + ) + + await waitFor(() => expect(screen.getByText("Archive")).toBeTruthy()) + }) + + it("calls openConfirmArchiveLocationModal when Archive button is clicked", async () => { + const onClose = vi.fn() + const updateLocation = vi.fn().mockResolvedValue(location) + const revalidateTable = vi.fn().mockResolvedValue(undefined) + const doesLocationCodeExist = vi.fn().mockResolvedValue(false) + const openConfirmArchiveLocationModal = vi.fn() + + render( + + ) + + await waitFor(() => expect(screen.getByText("Archive")).toBeTruthy()) + fireEvent.click(screen.getByText("Archive")) + expect(openConfirmArchiveLocationModal).toHaveBeenCalled() + }) + + it("shows Unarchive button for archived location", async () => { + const archivedLocation = { + ...location, + deletedAt: new Date(), + } as LocationWithRelations + + const onClose = vi.fn() + const updateLocation = vi.fn().mockResolvedValue(archivedLocation) + const revalidateTable = vi.fn().mockResolvedValue(undefined) + const doesLocationCodeExist = vi.fn().mockResolvedValue(false) + const openConfirmArchiveLocationModal = vi.fn() + + render( + + ) + + await waitFor(() => expect(screen.getByText("Unarchive")).toBeTruthy()) + }) }) diff --git a/src/components/settings/locations/EditLocationModal/EditLocationModal.tsx b/src/components/settings/locations/EditLocationModal/EditLocationModal.tsx index 206c46c..7bcd713 100644 --- a/src/components/settings/locations/EditLocationModal/EditLocationModal.tsx +++ b/src/components/settings/locations/EditLocationModal/EditLocationModal.tsx @@ -28,6 +28,7 @@ type EditLocationModalProps = { ) => Promise doesLocationCodeExist: (code: string) => Promise revalidateTable: () => Promise + openConfirmArchiveLocationModal: () => void } export const EditLocationModal = ({ @@ -40,6 +41,7 @@ export const EditLocationModal = ({ updateLocation, doesLocationCodeExist, revalidateTable, + openConfirmArchiveLocationModal, }: EditLocationModalProps) => { const [isSaving, setIsSaving] = useState(false) const [formData, setFormData] = useState | null>(null) @@ -128,6 +130,11 @@ export const EditLocationModal = ({ } } + const handleOpenArchive = () => { + openConfirmArchiveLocationModal() + onClose() + } + return ( }> @@ -162,6 +169,9 @@ export const EditLocationModal = ({ +