배치 정보 조절 에러 해결

This commit is contained in:
dohyeons 2025-10-17 17:43:58 +09:00
parent 6603ff81fe
commit 8b28107147
2 changed files with 50 additions and 124 deletions

View File

@ -49,9 +49,6 @@ export default function MaterialEditPanel({ placement, onClose, onUpdate, onRemo
useEffect(() => { useEffect(() => {
if (placement) { if (placement) {
setEditData({ setEditData({
position_x: placement.position_x,
position_y: placement.position_y,
position_z: placement.position_z,
size_x: placement.size_x, size_x: placement.size_x,
size_y: placement.size_y, size_y: placement.size_y,
size_z: placement.size_z, size_z: placement.size_z,
@ -107,52 +104,6 @@ export default function MaterialEditPanel({ placement, onClose, onUpdate, onRemo
<div className="space-y-3"> <div className="space-y-3">
<div className="text-xs font-medium text-gray-500"> ( )</div> <div className="text-xs font-medium text-gray-500"> ( )</div>
{/* 3D 위치 */}
<div>
<Label className="text-xs"></Label>
<div className="grid grid-cols-3 gap-2">
<div>
<Label htmlFor="edit-posX" className="text-xs text-gray-600">
X
</Label>
<Input
id="edit-posX"
type="number"
value={editData.position_x ?? placement.position_x}
onChange={(e) => setEditData({ ...editData, position_x: parseFloat(e.target.value) || 0 })}
step="0.5"
className="h-8 text-xs"
/>
</div>
<div>
<Label htmlFor="edit-posY" className="text-xs text-gray-600">
Y
</Label>
<Input
id="edit-posY"
type="number"
value={editData.position_y ?? placement.position_y}
onChange={(e) => setEditData({ ...editData, position_y: parseFloat(e.target.value) || 0 })}
step="0.5"
className="h-8 text-xs"
/>
</div>
<div>
<Label htmlFor="edit-posZ" className="text-xs text-gray-600">
Z
</Label>
<Input
id="edit-posZ"
type="number"
value={editData.position_z ?? placement.position_z}
onChange={(e) => setEditData({ ...editData, position_z: parseFloat(e.target.value) || 0 })}
step="0.5"
className="h-8 text-xs"
/>
</div>
</div>
</div>
{/* 3D 크기 */} {/* 3D 크기 */}
<div> <div>
<Label className="text-xs"></Label> <Label className="text-xs"></Label>
@ -167,7 +118,7 @@ export default function MaterialEditPanel({ placement, onClose, onUpdate, onRemo
value={editData.size_x ?? placement.size_x} value={editData.size_x ?? placement.size_x}
onChange={(e) => setEditData({ ...editData, size_x: parseFloat(e.target.value) || 1 })} onChange={(e) => setEditData({ ...editData, size_x: parseFloat(e.target.value) || 1 })}
min="1" min="1"
step="0.5" step="1"
className="h-8 text-xs" className="h-8 text-xs"
/> />
</div> </div>
@ -181,7 +132,7 @@ export default function MaterialEditPanel({ placement, onClose, onUpdate, onRemo
value={editData.size_y ?? placement.size_y} value={editData.size_y ?? placement.size_y}
onChange={(e) => setEditData({ ...editData, size_y: parseFloat(e.target.value) || 1 })} onChange={(e) => setEditData({ ...editData, size_y: parseFloat(e.target.value) || 1 })}
min="1" min="1"
step="0.5" step="1"
className="h-8 text-xs" className="h-8 text-xs"
/> />
</div> </div>
@ -195,7 +146,7 @@ export default function MaterialEditPanel({ placement, onClose, onUpdate, onRemo
value={editData.size_z ?? placement.size_z} value={editData.size_z ?? placement.size_z}
onChange={(e) => setEditData({ ...editData, size_z: parseFloat(e.target.value) || 1 })} onChange={(e) => setEditData({ ...editData, size_z: parseFloat(e.target.value) || 1 })}
min="1" min="1"
step="0.5" step="1"
className="h-8 text-xs" className="h-8 text-xs"
/> />
</div> </div>

View File

@ -62,10 +62,15 @@ export default function YardEditor({ layout, onBack }: YardEditorProps) {
const [placements, setPlacements] = useState<YardPlacement[]>([]); const [placements, setPlacements] = useState<YardPlacement[]>([]);
const [materials, setMaterials] = useState<TempMaterial[]>([]); const [materials, setMaterials] = useState<TempMaterial[]>([]);
const [selectedPlacement, setSelectedPlacement] = useState<YardPlacement | null>(null); const [selectedPlacement, setSelectedPlacement] = useState<YardPlacement | null>(null);
const [selectedMaterial, setSelectedMaterial] = useState<TempMaterial | null>(null);
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
const [isSaving, setIsSaving] = useState(false); const [isSaving, setIsSaving] = useState(false);
const [searchTerm, setSearchTerm] = useState(""); const [searchTerm, setSearchTerm] = useState("");
const [editValues, setEditValues] = useState({
size_x: 5,
size_y: 5,
size_z: 5,
color: "#3b82f6",
});
// 배치 목록 & 자재 목록 로드 // 배치 목록 & 자재 목록 로드
useEffect(() => { useEffect(() => {
@ -78,10 +83,10 @@ export default function YardEditor({ layout, onBack }: YardEditorProps) {
]); ]);
if (placementsRes.success) { if (placementsRes.success) {
setPlacements(placementsRes.data); setPlacements(placementsRes.data as YardPlacement[]);
} }
if (materialsRes.success) { if (materialsRes.success) {
setMaterials(materialsRes.data); setMaterials(materialsRes.data as TempMaterial[]);
} }
} catch (error) { } catch (error) {
console.error("데이터 로드 실패:", error); console.error("데이터 로드 실패:", error);
@ -93,6 +98,18 @@ export default function YardEditor({ layout, onBack }: YardEditorProps) {
loadData(); loadData();
}, [layout.id]); }, [layout.id]);
// selectedPlacement 변경 시 editValues 업데이트
useEffect(() => {
if (selectedPlacement) {
setEditValues({
size_x: selectedPlacement.size_x,
size_y: selectedPlacement.size_y,
size_z: selectedPlacement.size_z,
color: selectedPlacement.color,
});
}
}, [selectedPlacement]);
// 자재 클릭 → 배치 추가 // 자재 클릭 → 배치 추가
const handleMaterialClick = async (material: TempMaterial) => { const handleMaterialClick = async (material: TempMaterial) => {
// 이미 배치되었는지 확인 // 이미 배치되었는지 확인
@ -102,8 +119,6 @@ export default function YardEditor({ layout, onBack }: YardEditorProps) {
return; return;
} }
setSelectedMaterial(material);
// 기본 위치에 배치 // 기본 위치에 배치
const placementData = { const placementData = {
external_material_id: `TEMP-${material.id}`, external_material_id: `TEMP-${material.id}`,
@ -123,11 +138,10 @@ export default function YardEditor({ layout, onBack }: YardEditorProps) {
try { try {
const response = await yardLayoutApi.addMaterialPlacement(layout.id, placementData); const response = await yardLayoutApi.addMaterialPlacement(layout.id, placementData);
if (response.success) { if (response.success) {
setPlacements((prev) => [...prev, response.data]); setPlacements((prev) => [...prev, response.data as YardPlacement]);
setSelectedPlacement(response.data); setSelectedPlacement(response.data as YardPlacement);
setSelectedMaterial(null);
} }
} catch (error: any) { } catch (error) {
console.error("자재 배치 실패:", error); console.error("자재 배치 실패:", error);
alert("자재 배치에 실패했습니다."); alert("자재 배치에 실패했습니다.");
} }
@ -262,7 +276,7 @@ export default function YardEditor({ layout, onBack }: YardEditorProps) {
<Yard3DCanvas <Yard3DCanvas
placements={placements} placements={placements}
selectedPlacementId={selectedPlacement?.id || null} selectedPlacementId={selectedPlacement?.id || null}
onPlacementClick={setSelectedPlacement} onPlacementClick={(placement) => setSelectedPlacement(placement as YardPlacement)}
onPlacementDrag={handlePlacementDrag} onPlacementDrag={handlePlacementDrag}
/> />
)} )}
@ -304,60 +318,18 @@ export default function YardEditor({ layout, onBack }: YardEditorProps) {
<div className="space-y-3 border-t pt-4"> <div className="space-y-3 border-t pt-4">
<Label className="text-sm font-semibold"> </Label> <Label className="text-sm font-semibold"> </Label>
<div className="grid grid-cols-3 gap-2">
<div>
<Label className="text-xs">X</Label>
<Input
type="number"
step="0.5"
value={selectedPlacement.position_x}
onChange={(e) =>
handlePlacementUpdate(selectedPlacement.id, {
position_x: parseFloat(e.target.value),
})
}
/>
</div>
<div>
<Label className="text-xs">Y</Label>
<Input
type="number"
step="0.5"
value={selectedPlacement.position_y}
onChange={(e) =>
handlePlacementUpdate(selectedPlacement.id, {
position_y: parseFloat(e.target.value),
})
}
/>
</div>
<div>
<Label className="text-xs">Z</Label>
<Input
type="number"
step="0.5"
value={selectedPlacement.position_z}
onChange={(e) =>
handlePlacementUpdate(selectedPlacement.id, {
position_z: parseFloat(e.target.value),
})
}
/>
</div>
</div>
<div className="grid grid-cols-3 gap-2"> <div className="grid grid-cols-3 gap-2">
<div> <div>
<Label className="text-xs"></Label> <Label className="text-xs"></Label>
<Input <Input
type="number" type="number"
step="1" step="1"
value={selectedPlacement.size_x} value={editValues.size_x}
onChange={(e) => onChange={(e) => {
handlePlacementUpdate(selectedPlacement.id, { const newValue = parseFloat(e.target.value) || 1;
size_x: parseFloat(e.target.value), setEditValues((prev) => ({ ...prev, size_x: newValue }));
}) handlePlacementUpdate(selectedPlacement.id, { size_x: newValue });
} }}
/> />
</div> </div>
<div> <div>
@ -365,12 +337,12 @@ export default function YardEditor({ layout, onBack }: YardEditorProps) {
<Input <Input
type="number" type="number"
step="1" step="1"
value={selectedPlacement.size_y} value={editValues.size_y}
onChange={(e) => onChange={(e) => {
handlePlacementUpdate(selectedPlacement.id, { const newValue = parseFloat(e.target.value) || 1;
size_y: parseFloat(e.target.value), setEditValues((prev) => ({ ...prev, size_y: newValue }));
}) handlePlacementUpdate(selectedPlacement.id, { size_y: newValue });
} }}
/> />
</div> </div>
<div> <div>
@ -378,12 +350,12 @@ export default function YardEditor({ layout, onBack }: YardEditorProps) {
<Input <Input
type="number" type="number"
step="1" step="1"
value={selectedPlacement.size_z} value={editValues.size_z}
onChange={(e) => onChange={(e) => {
handlePlacementUpdate(selectedPlacement.id, { const newValue = parseFloat(e.target.value) || 1;
size_z: parseFloat(e.target.value), setEditValues((prev) => ({ ...prev, size_z: newValue }));
}) handlePlacementUpdate(selectedPlacement.id, { size_z: newValue });
} }}
/> />
</div> </div>
</div> </div>
@ -392,8 +364,11 @@ export default function YardEditor({ layout, onBack }: YardEditorProps) {
<Label className="text-xs"></Label> <Label className="text-xs"></Label>
<Input <Input
type="color" type="color"
value={selectedPlacement.color} value={editValues.color}
onChange={(e) => handlePlacementUpdate(selectedPlacement.id, { color: e.target.value })} onChange={(e) => {
setEditValues((prev) => ({ ...prev, color: e.target.value }));
handlePlacementUpdate(selectedPlacement.id, { color: e.target.value });
}}
/> />
</div> </div>
</div> </div>