1
0
Fork 0

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.
This commit is contained in:
Jason Fraley 2026-08-18 02:05:20 -04:00
parent 0fc61ebb47
commit 4906fc8008
4 changed files with 48 additions and 9 deletions

View file

@ -57,12 +57,23 @@ const modeMeta: Record<
interface BankTransactionDialogProps { interface BankTransactionDialogProps {
accountId: number; accountId: number;
otherAccounts: { id: number; name: string }[]; 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 router = useRouter();
const [mode, setMode] = useState<Mode>("deposit"); const [mode, setMode] = useState<Mode>(initialMode);
const [open, setOpen] = useState(false); const [internalOpen, setInternalOpen] = useState(false);
const open = externalOpen ?? internalOpen;
const setOpen = externalOnOpenChange ?? setInternalOpen;
const [amount, setAmount] = useState(""); const [amount, setAmount] = useState("");
const [toId, setToId] = useState(""); const [toId, setToId] = useState("");
const [memo, setMemo] = useState(""); const [memo, setMemo] = useState("");

View file

@ -27,13 +27,22 @@ import { createBankAccount } from "@/app/(frontend)/logistics/banking/actions";
interface CreateAccountDialogProps { interface CreateAccountDialogProps {
isManager: boolean; isManager: boolean;
factions: { id: number; name: string }[]; factions: { id: number; name: string }[];
open?: boolean;
onOpenChange?: (open: boolean) => void;
} }
type AccountType = "treasury" | "faction" | "personal"; 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 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 [name, setName] = useState("");
const [accountType, setAccountType] = useState<AccountType>("personal"); const [accountType, setAccountType] = useState<AccountType>("personal");
const [ownerFactionId, setOwnerFactionId] = useState(""); const [ownerFactionId, setOwnerFactionId] = useState("");

View file

@ -34,6 +34,11 @@ import {
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
interface CreateTicketDialogProps {
open?: boolean;
onOpenChange?: (open: boolean) => void;
}
function isTicketCategory(value: string): value is TicketCategory { function isTicketCategory(value: string): value is TicketCategory {
return TICKET_CATEGORIES.some((option) => option.value === value); 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); return TICKET_PRIORITIES.some((option) => option.value === value);
} }
export function CreateTicketDialog() { export function CreateTicketDialog({
open: externalOpen,
onOpenChange: externalOnOpenChange,
}: CreateTicketDialogProps = {}) {
const router = useRouter(); 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 [title, setTitle] = useState("");
const [category, setCategory] = useState<TicketCategory>("support_request"); const [category, setCategory] = useState<TicketCategory>("support_request");
const [priority, setPriority] = useState<TicketPriority>("medium"); const [priority, setPriority] = useState<TicketPriority>("medium");

View file

@ -31,6 +31,8 @@ import { createMarketListing } from "@/app/(frontend)/logistics/market/actions";
interface CreateListingDialogProps { interface CreateListingDialogProps {
locker: LockerStorage | null; locker: LockerStorage | null;
currencyLabel: string | null; currencyLabel: string | null;
open?: boolean;
onOpenChange?: (open: boolean) => void;
} }
interface SellableAsset { interface SellableAsset {
@ -42,9 +44,16 @@ interface SellableAsset {
basePrice: number | null; basePrice: number | null;
} }
export function CreateListingDialog({ locker, currencyLabel }: CreateListingDialogProps) { export function CreateListingDialog({
locker,
currencyLabel,
open: externalOpen,
onOpenChange: externalOnOpenChange,
}: CreateListingDialogProps) {
const router = useRouter(); 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 [assetId, setAssetId] = useState("");
const [quantity, setQuantity] = useState("1"); const [quantity, setQuantity] = useState("1");
const [price, setPrice] = useState(""); const [price, setPrice] = useState("");