fix(ux): resolve tickets #59 #66 #67 — project feedback and demand summary

#66: Project detail "Open Demands" summary incorrectly counted COMPLETED
demands as open. Fix: add `status !== "COMPLETED"` to the activeDemands
filter in /projects/[id]/page.tsx.

#59/#67: Project creation and edit had two bugs:
1. Both invalidated `project.list` but the page queries `project.listWithCosts`
   — the list never refreshed after a save.
2. Success toasts were either absent (ProjectModal) or mounted inside the
   wizard component that unmounts before the toast finishes.
Fix: correct invalidation key to listWithCosts; add optional onSuccess prop
to both ProjectWizard and ProjectModal; ProjectsClient wires onSuccess to a
persistent SuccessToast rendered outside the modals.

Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
2026-04-03 16:05:29 +02:00
parent b7bb6d05af
commit 2da29c8191
4 changed files with 39 additions and 8 deletions
@@ -28,6 +28,7 @@ import { useRowOrder } from "~/hooks/useRowOrder.js";
import { SortableColumnHeader } from "~/components/ui/SortableColumnHeader.js";
import { DraggableTableRow } from "~/components/ui/DraggableTableRow.js";
import { ShoringBadge } from "~/components/projects/ShoringIndicator.js";
import { SuccessToast } from "~/components/ui/SuccessToast.js";
import { PROJECT_STATUS_BADGE as STATUS_COLORS, ORDER_TYPE_BADGE as ORDER_TYPE_COLORS } from "~/lib/status-styles.js";
@@ -182,6 +183,7 @@ export function ProjectsClient() {
const [modalOpen, setModalOpen] = useState(false);
const [wizardOpen, setWizardOpen] = useState(false);
const [editingProject, setEditingProject] = useState<Project | null>(null);
const [successToast, setSuccessToast] = useState<string | null>(null);
const [openStatusProjectId, setOpenStatusProjectId] = useState<string | null>(null);
const [batchStatusPicker, setBatchStatusPicker] = useState(false);
const [confirmBatchStatus, setConfirmBatchStatus] = useState<{ ids: string[]; status: string } | null>(null);
@@ -749,10 +751,34 @@ export function ProjectsClient() {
/>
{/* Modal */}
{modalOpen && <ProjectModal project={editingProject} onClose={closeModal} />}
{modalOpen && (
<ProjectModal
project={editingProject}
onClose={closeModal}
onSuccess={(name) =>
setSuccessToast(
editingProject
? `Project "${name}" updated successfully.`
: `Project "${name}" created successfully.`,
)
}
/>
)}
{/* Wizard */}
<ProjectWizard open={wizardOpen} onClose={() => setWizardOpen(false)} />
<ProjectWizard
open={wizardOpen}
onClose={() => setWizardOpen(false)}
onSuccess={(shortCode, name) =>
setSuccessToast(`Project "${shortCode}${name}" created successfully.`)
}
/>
<SuccessToast
show={successToast !== null}
message={successToast ?? ""}
onDone={() => setSuccessToast(null)}
/>
</div>
);
}