From 4906fc8008675dbb8836a357ecc5992f46d0acca Mon Sep 17 00:00:00 2001 From: Z8MB1E Date: Tue, 18 Aug 2026 02:05:20 -0400 Subject: [PATCH] refactor(ui): make dialogs controlled via open/onOpenChange props Support external open state management so parent components and the command palette can trigger these dialogs programmatically. --- .../frontend/banking/BankTransactionDialog.tsx | 17 ++++++++++++++--- .../frontend/banking/CreateAccountDialog.tsx | 13 +++++++++++-- .../frontend/helpdesk/CreateTicketDialog.tsx | 14 ++++++++++++-- .../frontend/market/CreateListingDialog.tsx | 13 +++++++++++-- 4 files changed, 48 insertions(+), 9 deletions(-) diff --git a/src/components/frontend/banking/BankTransactionDialog.tsx b/src/components/frontend/banking/BankTransactionDialog.tsx index 776f305..354d6d2 100644 --- a/src/components/frontend/banking/BankTransactionDialog.tsx +++ b/src/components/frontend/banking/BankTransactionDialog.tsx @@ -57,12 +57,23 @@ const modeMeta: Record< interface BankTransactionDialogProps { accountId: number; otherAccounts: { id: number; name: string }[]; + open?: boolean; + onOpenChange?: (open: boolean) => void; + initialMode?: Mode; } -export function BankTransactionDialog({ accountId, otherAccounts }: BankTransactionDialogProps) { +export function BankTransactionDialog({ + accountId, + otherAccounts, + open: externalOpen, + onOpenChange: externalOnOpenChange, + initialMode = "deposit", +}: BankTransactionDialogProps) { const router = useRouter(); - const [mode, setMode] = useState("deposit"); - const [open, setOpen] = useState(false); + const [mode, setMode] = useState(initialMode); + const [internalOpen, setInternalOpen] = useState(false); + const open = externalOpen ?? internalOpen; + const setOpen = externalOnOpenChange ?? setInternalOpen; const [amount, setAmount] = useState(""); const [toId, setToId] = useState(""); const [memo, setMemo] = useState(""); diff --git a/src/components/frontend/banking/CreateAccountDialog.tsx b/src/components/frontend/banking/CreateAccountDialog.tsx index 70a2269..bef6939 100644 --- a/src/components/frontend/banking/CreateAccountDialog.tsx +++ b/src/components/frontend/banking/CreateAccountDialog.tsx @@ -27,13 +27,22 @@ import { createBankAccount } from "@/app/(frontend)/logistics/banking/actions"; interface CreateAccountDialogProps { isManager: boolean; factions: { id: number; name: string }[]; + open?: boolean; + onOpenChange?: (open: boolean) => void; } type AccountType = "treasury" | "faction" | "personal"; -export function CreateAccountDialog({ isManager, factions }: CreateAccountDialogProps) { +export function CreateAccountDialog({ + isManager, + factions, + open: externalOpen, + onOpenChange: externalOnOpenChange, +}: CreateAccountDialogProps) { const router = useRouter(); - const [open, setOpen] = useState(false); + const [internalOpen, setInternalOpen] = useState(false); + const open = externalOpen ?? internalOpen; + const setOpen = externalOnOpenChange ?? setInternalOpen; const [name, setName] = useState(""); const [accountType, setAccountType] = useState("personal"); const [ownerFactionId, setOwnerFactionId] = useState(""); diff --git a/src/components/frontend/helpdesk/CreateTicketDialog.tsx b/src/components/frontend/helpdesk/CreateTicketDialog.tsx index 9cf26af..0261a37 100644 --- a/src/components/frontend/helpdesk/CreateTicketDialog.tsx +++ b/src/components/frontend/helpdesk/CreateTicketDialog.tsx @@ -34,6 +34,11 @@ import { import { cn } from "@/lib/utils"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; +interface CreateTicketDialogProps { + open?: boolean; + onOpenChange?: (open: boolean) => void; +} + function isTicketCategory(value: string): value is TicketCategory { return TICKET_CATEGORIES.some((option) => option.value === value); } @@ -42,9 +47,14 @@ function isTicketPriority(value: string): value is TicketPriority { return TICKET_PRIORITIES.some((option) => option.value === value); } -export function CreateTicketDialog() { +export function CreateTicketDialog({ + open: externalOpen, + onOpenChange: externalOnOpenChange, +}: CreateTicketDialogProps = {}) { const router = useRouter(); - const [open, setOpen] = useState(false); + const [internalOpen, setInternalOpen] = useState(false); + const open = externalOpen ?? internalOpen; + const setOpen = externalOnOpenChange ?? setInternalOpen; const [title, setTitle] = useState(""); const [category, setCategory] = useState("support_request"); const [priority, setPriority] = useState("medium"); diff --git a/src/components/frontend/market/CreateListingDialog.tsx b/src/components/frontend/market/CreateListingDialog.tsx index 661c340..3d8b095 100644 --- a/src/components/frontend/market/CreateListingDialog.tsx +++ b/src/components/frontend/market/CreateListingDialog.tsx @@ -31,6 +31,8 @@ import { createMarketListing } from "@/app/(frontend)/logistics/market/actions"; interface CreateListingDialogProps { locker: LockerStorage | null; currencyLabel: string | null; + open?: boolean; + onOpenChange?: (open: boolean) => void; } interface SellableAsset { @@ -42,9 +44,16 @@ interface SellableAsset { basePrice: number | null; } -export function CreateListingDialog({ locker, currencyLabel }: CreateListingDialogProps) { +export function CreateListingDialog({ + locker, + currencyLabel, + open: externalOpen, + onOpenChange: externalOnOpenChange, +}: CreateListingDialogProps) { const router = useRouter(); - const [open, setOpen] = useState(false); + const [internalOpen, setInternalOpen] = useState(false); + const open = externalOpen ?? internalOpen; + const setOpen = externalOnOpenChange ?? setInternalOpen; const [assetId, setAssetId] = useState(""); const [quantity, setQuantity] = useState("1"); const [price, setPrice] = useState("");