1
0
Fork 0

fix(ui): add router.refresh after storage mutations, pluralize labels

ManageStorageDialog now calls router.refresh() after deposit,
withdraw, and transfer so the grid view reflects changes.
Await fetchData() before refreshing.

Resource labels now use pluralize() for correct unit display
(e.g. "1 liter" vs "3 liters").
This commit is contained in:
Jason Fraley 2026-07-28 14:03:43 -04:00
parent a4844efe22
commit 01ac20f44f
2 changed files with 14 additions and 8 deletions

View file

@ -1,6 +1,7 @@
"use client"; "use client";
import { useState, useEffect, useTransition, useCallback } from "react"; import { useState, useEffect, useTransition, useCallback } from "react";
import { useRouter } from "next/navigation";
import { import {
Dialog, Dialog,
DialogContent, DialogContent,
@ -32,7 +33,7 @@ import {
Loader2Icon, Loader2Icon,
} from "lucide-react"; } from "lucide-react";
import { Progress } from "@/components/ui/progress"; import { Progress } from "@/components/ui/progress";
import { cn } from "@/lib/utils"; import { cn, pluralize } from "@/lib/utils";
interface ManageStorageDialogProps { interface ManageStorageDialogProps {
structureId: number; structureId: number;
@ -54,6 +55,7 @@ export function ManageStorageDialog({
const [allResources, setAllResources] = useState<Resource[]>([]); const [allResources, setAllResources] = useState<Resource[]>([]);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [isPending, startTransition] = useTransition(); const [isPending, startTransition] = useTransition();
const router = useRouter();
const [message, setMessage] = useState<{ type: "success" | "error"; text: string } | null>(null); const [message, setMessage] = useState<{ type: "success" | "error"; text: string } | null>(null);
// Form state // Form state
@ -258,7 +260,8 @@ export function ManageStorageDialog({
if (result.success) { if (result.success) {
setMessage({ type: "success", text: "Resource deposited successfully." }); setMessage({ type: "success", text: "Resource deposited successfully." });
setDepositAmount("1"); setDepositAmount("1");
fetchData(); await fetchData();
router.refresh();
} else { } else {
setMessage({ type: "error", text: result.error ?? "Unknown error." }); setMessage({ type: "error", text: result.error ?? "Unknown error." });
} }
@ -278,7 +281,8 @@ export function ManageStorageDialog({
if (result.success) { if (result.success) {
setMessage({ type: "success", text: "Resource withdrawn successfully." }); setMessage({ type: "success", text: "Resource withdrawn successfully." });
setWithdrawAmount("1"); setWithdrawAmount("1");
fetchData(); await fetchData();
router.refresh();
} else { } else {
setMessage({ type: "error", text: result.error ?? "Unknown error." }); setMessage({ type: "error", text: result.error ?? "Unknown error." });
} }
@ -299,7 +303,8 @@ export function ManageStorageDialog({
if (result.success) { if (result.success) {
setMessage({ type: "success", text: "Transfer completed successfully." }); setMessage({ type: "success", text: "Transfer completed successfully." });
setTransferAmount("1"); setTransferAmount("1");
fetchData(); await fetchData();
router.refresh();
} else { } else {
setMessage({ type: "error", text: result.error ?? "Unknown error." }); setMessage({ type: "error", text: result.error ?? "Unknown error." });
} }
@ -437,7 +442,7 @@ export function ManageStorageDialog({
if (!resource || typeof resource === "number") return null; if (!resource || typeof resource === "number") return null;
return ( return (
<SelectItem key={entry.id ?? resource.id} value={String(resource.id)}> <SelectItem key={entry.id ?? resource.id} value={String(resource.id)}>
{resource.name} ({entry.amount.toLocaleString()} {resource.unitOfMeasure}) {resource.name} ({entry.amount.toLocaleString()} {pluralize(entry.amount, resource.unitOfMeasure)})
</SelectItem> </SelectItem>
); );
})} })}
@ -510,7 +515,7 @@ export function ManageStorageDialog({
if (!resource || typeof resource === "number") return null; if (!resource || typeof resource === "number") return null;
return ( return (
<SelectItem key={entry.id ?? resource.id} value={String(resource.id)}> <SelectItem key={entry.id ?? resource.id} value={String(resource.id)}>
{resource.name} ({entry.amount.toLocaleString()} {resource.unitOfMeasure}) {resource.name} ({entry.amount.toLocaleString()} {pluralize(entry.amount, resource.unitOfMeasure)})
</SelectItem> </SelectItem>
); );
})} })}

View file

@ -1,5 +1,6 @@
import { Resource, GameStructure } from "@/payload-types"; import { Resource, GameStructure } from "@/payload-types";
import { convertLexicalToPlaintext } from "@payloadcms/richtext-lexical/plaintext"; import { convertLexicalToPlaintext } from "@payloadcms/richtext-lexical/plaintext";
import { pluralize } from "@/lib/utils";
import { import {
Item, Item,
ItemContent, ItemContent,
@ -92,7 +93,7 @@ export function ResourceList({ storedResources, maxCapacityMass }: ResourceListP
/> />
<span>{resource.name}</span> <span>{resource.name}</span>
<span className="text-xs font-normal text-muted-foreground"> <span className="text-xs font-normal text-muted-foreground">
{entry.amount.toLocaleString()} {resource.unitOfMeasure} {entry.amount.toLocaleString()} {pluralize(entry.amount, resource.unitOfMeasure)}
</span> </span>
</ItemTitle> </ItemTitle>
{description && ( {description && (
@ -103,7 +104,7 @@ export function ResourceList({ storedResources, maxCapacityMass }: ResourceListP
</ItemContent> </ItemContent>
<div className="text-right shrink-0"> <div className="text-right shrink-0">
<div className="text-sm font-medium"> <div className="text-sm font-medium">
{entry.amount.toLocaleString()} {resource.unitOfMeasure} {entry.amount.toLocaleString()} {pluralize(entry.amount, resource.unitOfMeasure)}
</div> </div>
<div className="text-xs text-muted-foreground"> <div className="text-xs text-muted-foreground">
{mass > 0 && `${mass.toLocaleString()} kg mass`} {mass > 0 && `${mass.toLocaleString()} kg mass`}