This commit is contained in:
1 parent
8efd032cc6
commit
df38dccbf1
735 files changed
+128321
-120870
No files matched your search
@@ -4,12 +4,12 @@ import { useEffect, useState } from "react";
|
||||
import { updateRoomItem } from "@/actions/rooms";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from "@/components/ui/dialog";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
@@ -17,163 +17,169 @@ import { Textarea } from "@/components/ui/textarea";
|
||||
import { useServerAction } from "@/hooks/use-server-action";
|
||||
|
||||
interface EditItem {
|
||||
id: number;
|
||||
name: string;
|
||||
type: string;
|
||||
x: number;
|
||||
y: number;
|
||||
z: number;
|
||||
rot: number;
|
||||
wallPos: string;
|
||||
extraData: string;
|
||||
id: number;
|
||||
name: string;
|
||||
type: string;
|
||||
x: number;
|
||||
y: number;
|
||||
z: number;
|
||||
rot: number;
|
||||
wallPos: string;
|
||||
extraData: string;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
roomId: number;
|
||||
item: EditItem | null;
|
||||
open: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
roomId: number;
|
||||
item: EditItem | null;
|
||||
open: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
}
|
||||
|
||||
export function EditItemDialog({ roomId, item, open, onOpenChange }: Props) {
|
||||
const { run, isPending } = useServerAction();
|
||||
const [x, setX] = useState("0");
|
||||
const [y, setY] = useState("0");
|
||||
const [z, setZ] = useState("0");
|
||||
const [rot, setRot] = useState("0");
|
||||
const [wallPos, setWallPos] = useState("");
|
||||
const [extraData, setExtraData] = useState("");
|
||||
const { run, isPending } = useServerAction();
|
||||
const [x, setX] = useState("0");
|
||||
const [y, setY] = useState("0");
|
||||
const [z, setZ] = useState("0");
|
||||
const [rot, setRot] = useState("0");
|
||||
const [wallPos, setWallPos] = useState("");
|
||||
const [extraData, setExtraData] = useState("");
|
||||
|
||||
const isWall = item?.type === "i";
|
||||
const isWall = item?.type === "i";
|
||||
|
||||
useEffect(() => {
|
||||
if (item) {
|
||||
setX(String(item.x));
|
||||
setY(String(item.y));
|
||||
setZ(String(item.z));
|
||||
setRot(String(item.rot));
|
||||
setWallPos(item.wallPos);
|
||||
setExtraData(item.extraData);
|
||||
}
|
||||
}, [item]);
|
||||
useEffect(() => {
|
||||
if (item) {
|
||||
setX(String(item.x));
|
||||
setY(String(item.y));
|
||||
setZ(String(item.z));
|
||||
setRot(String(item.rot));
|
||||
setWallPos(item.wallPos);
|
||||
setExtraData(item.extraData);
|
||||
}
|
||||
}, [item]);
|
||||
|
||||
function handleSave() {
|
||||
if (!item) return;
|
||||
const payload = isWall
|
||||
? { roomId, itemId: item.id, wallPos, extraData }
|
||||
: {
|
||||
roomId,
|
||||
itemId: item.id,
|
||||
x: Number(x),
|
||||
y: Number(y),
|
||||
z: Number(z),
|
||||
rot: Number(rot),
|
||||
extraData,
|
||||
};
|
||||
run(() => updateRoomItem(payload), {
|
||||
successMessage: "Item updated and room reloaded",
|
||||
onSuccess: () => onOpenChange(false),
|
||||
});
|
||||
}
|
||||
function handleSave() {
|
||||
if (!item) return;
|
||||
const payload = isWall
|
||||
? { roomId, itemId: item.id, wallPos, extraData }
|
||||
: {
|
||||
roomId,
|
||||
itemId: item.id,
|
||||
x: Number(x),
|
||||
y: Number(y),
|
||||
z: Number(z),
|
||||
rot: Number(rot),
|
||||
extraData,
|
||||
};
|
||||
run(() => updateRoomItem(payload), {
|
||||
successMessage: "Item updated and room reloaded",
|
||||
onSuccess: () => onOpenChange(false),
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="sm:max-w-[480px]">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Edit furniture</DialogTitle>
|
||||
<DialogDescription>{item ? `${item.name} (#${item.id})` : ""}</DialogDescription>
|
||||
</DialogHeader>
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="sm:max-w-[480px]">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Edit furniture</DialogTitle>
|
||||
<DialogDescription>
|
||||
{item ? `${item.name} (#${item.id})` : ""}
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="space-y-4">
|
||||
{isWall ? (
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="wallPos">Wall position</Label>
|
||||
<Input
|
||||
id="wallPos"
|
||||
value={wallPos}
|
||||
onChange={(e) => setWallPos(e.target.value)}
|
||||
placeholder=":w=0,0 l=0,0 r"
|
||||
className="font-mono"
|
||||
/>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Format: <code>:w=X,Y l=X,Y r</code>
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<div className="grid grid-cols-3 gap-3">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="x">X</Label>
|
||||
<Input
|
||||
id="x"
|
||||
type="number"
|
||||
value={x}
|
||||
onChange={(e) => setX(e.target.value)}
|
||||
className="font-mono"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="y">Y</Label>
|
||||
<Input
|
||||
id="y"
|
||||
type="number"
|
||||
value={y}
|
||||
onChange={(e) => setY(e.target.value)}
|
||||
className="font-mono"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="z">Z</Label>
|
||||
<Input
|
||||
id="z"
|
||||
type="number"
|
||||
step="0.01"
|
||||
value={z}
|
||||
onChange={(e) => setZ(e.target.value)}
|
||||
className="font-mono"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="rot">Rotation (0-7)</Label>
|
||||
<Input
|
||||
id="rot"
|
||||
type="number"
|
||||
min={0}
|
||||
max={7}
|
||||
value={rot}
|
||||
onChange={(e) => setRot(e.target.value)}
|
||||
className="font-mono w-24"
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
<div className="space-y-4">
|
||||
{isWall ? (
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="wallPos">Wall position</Label>
|
||||
<Input
|
||||
id="wallPos"
|
||||
value={wallPos}
|
||||
onChange={(e) => setWallPos(e.target.value)}
|
||||
placeholder=":w=0,0 l=0,0 r"
|
||||
className="font-mono"
|
||||
/>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Format: <code>:w=X,Y l=X,Y r</code>
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<div className="grid grid-cols-3 gap-3">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="x">X</Label>
|
||||
<Input
|
||||
id="x"
|
||||
type="number"
|
||||
value={x}
|
||||
onChange={(e) => setX(e.target.value)}
|
||||
className="font-mono"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="y">Y</Label>
|
||||
<Input
|
||||
id="y"
|
||||
type="number"
|
||||
value={y}
|
||||
onChange={(e) => setY(e.target.value)}
|
||||
className="font-mono"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="z">Z</Label>
|
||||
<Input
|
||||
id="z"
|
||||
type="number"
|
||||
step="0.01"
|
||||
value={z}
|
||||
onChange={(e) => setZ(e.target.value)}
|
||||
className="font-mono"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="rot">Rotation (0-7)</Label>
|
||||
<Input
|
||||
id="rot"
|
||||
type="number"
|
||||
min={0}
|
||||
max={7}
|
||||
value={rot}
|
||||
onChange={(e) => setRot(e.target.value)}
|
||||
className="font-mono w-24"
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="extraData">Extra data</Label>
|
||||
<Textarea
|
||||
id="extraData"
|
||||
value={extraData}
|
||||
onChange={(e) => setExtraData(e.target.value)}
|
||||
rows={3}
|
||||
className="font-mono text-xs"
|
||||
placeholder="(empty)"
|
||||
/>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Item state/data (e.g. dice value, sticky note text, color)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="extraData">Extra data</Label>
|
||||
<Textarea
|
||||
id="extraData"
|
||||
value={extraData}
|
||||
onChange={(e) => setExtraData(e.target.value)}
|
||||
rows={3}
|
||||
className="font-mono text-xs"
|
||||
placeholder="(empty)"
|
||||
/>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Item state/data (e.g. dice value, sticky note text, color)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<DialogFooter>
|
||||
<Button variant="outline" onClick={() => onOpenChange(false)} disabled={isPending}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button onClick={handleSave} disabled={isPending}>
|
||||
{isPending ? "Saving..." : "Save"}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
<DialogFooter>
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => onOpenChange(false)}
|
||||
disabled={isPending}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button onClick={handleSave} disabled={isPending}>
|
||||
{isPending ? "Saving..." : "Save"}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user