배치 정보 조절 에러 해결

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(() => {
if (placement) {
setEditData({
position_x: placement.position_x,
position_y: placement.position_y,
position_z: placement.position_z,
size_x: placement.size_x,
size_y: placement.size_y,
size_z: placement.size_z,
@ -107,52 +104,6 @@ export default function MaterialEditPanel({ placement, onClose, onUpdate, onRemo
<div className="space-y-3">
<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 크기 */}
<div>
<Label className="text-xs"></Label>
@ -167,7 +118,7 @@ export default function MaterialEditPanel({ placement, onClose, onUpdate, onRemo
value={editData.size_x ?? placement.size_x}
onChange={(e) => setEditData({ ...editData, size_x: parseFloat(e.target.value) || 1 })}
min="1"
step="0.5"
step="1"
className="h-8 text-xs"
/>
</div>
@ -181,7 +132,7 @@ export default function MaterialEditPanel({ placement, onClose, onUpdate, onRemo
value={editData.size_y ?? placement.size_y}
onChange={(e) => setEditData({ ...editData, size_y: parseFloat(e.target.value) || 1 })}
min="1"
step="0.5"
step="1"
className="h-8 text-xs"
/>
</div>
@ -195,7 +146,7 @@ export default function MaterialEditPanel({ placement, onClose, onUpdate, onRemo
value={editData.size_z ?? placement.size_z}
onChange={(e) => setEditData({ ...editData, size_z: parseFloat(e.target.value) || 1 })}
min="1"
step="0.5"
step="1"
className="h-8 text-xs"
/>
</div>

View File

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