Select Git revision
MyCombinationPage.jsx
MyCombinationPage.jsx 5.46 KiB
import React, { useEffect, useState } from "react";
import getMyPCs from "@/api/my/getMyPCs";
import getPartById from "@/api/parts/getPartById";
import { useNavigate } from "react-router-dom";
import './MyCombinationPage.css';
import PartItem from "@/components/PartItem";
import updatePCName from "@/api/my/updatePCName";
const CertifiedCombination = () => {
const [pcs, setPcs] = useState([]);
const [selectedPc, setSelectedPc] = useState(null);
const [partsData, setPartsData] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);
const [editingPcId, setEditingPcId] = useState(null);
const [editingName, setEditingName] = useState("");
const navigate = useNavigate();
const [isPartsLoading, setIsPartsLoading] = useState(false);
useEffect(() => {
const fetchPCs = async () => {
try {
const pcsData = await getMyPCs();
setPcs(pcsData);
if (pcsData.length > 0) {
setSelectedPc(pcsData[0]);
}
} catch (error) {
console.error("내 PC 목록 불러오기 중 오류 발생:", error);
}
};
fetchPCs();
}, []);
useEffect(() => {
const fetchParts = async () => {
if (selectedPc && !selectedPc.parts.some(part => part.partType === "오류")) {
setIsPartsLoading(true);
const parts = await Promise.all(
selectedPc.parts.map(async (partId) => {
try {
return await getPartById(partId);
} catch (error) {
console.error(`부품 ID ${partId} 불러오기 중 오류 발생:`, error);
return {
partType: "오류",
name: "오류가 발생했습니다.",
description: `${partId} 부품을 찾을 수 없습니다.`,
imageUrl: "",
};
}
})
);
setPartsData(parts.filter((part) => part !== null));
setIsPartsLoading(false);
}
};
fetchParts();
}, [selectedPc]);
const handlePcClick = (pcId) => {
const selected = pcs.find((pc) => pc.id === pcId);
setSelectedPc(selected);
};
const handleAddPcClick = () => {
navigate('/partscertification');
};
const handleEditClick = (pc) => {
setError(null);
setEditingPcId(pc.id);
setEditingName(pc.name);
};
const handleCancel = () => {
setEditingPcId(null);
setError(null);
};
const handleNameSubmit = async (pcId) => {
if (!editingName.trim()) {
setError("PC 이름을 입력해주세요");
return;
}
setIsLoading(true);
setError(null);
try {
await updatePCName(pcId, editingName);
setPcs(pcs.map(pc =>
pc.id === pcId ? { ...pc, name: editingName } : pc
));
setEditingPcId(null);
} catch (error) {
setError("PC 이름 변경 중 오류가 발생했습니다");
console.error("PC 이름 변경 중 오류 발생:", error);
} finally {
setIsLoading(false);
}
};
const handleNameChange = (e) => {
setEditingName(e.target.value);
};
return (
<div className="layout">
<aside className="sidebar">
<h3>내 PC 목록</h3>
<ul>
{pcs.map((pc) => (
<li
key={pc.id}
className={`pc-item ${selectedPc && selectedPc.id === pc.id ? 'active' : ''}`}
>
{editingPcId === pc.id ? (
<div className="edit-name-container">
<input
type="text"
value={editingName}
onChange={handleNameChange}
onClick={(e) => e.stopPropagation()}
placeholder="PC 이름 입력"
/>
<div className="edit-buttons">
<button
onClick={(e) => {
e.stopPropagation();
handleNameSubmit(pc.id);
}}
disabled={isLoading}
>
{isLoading ? '저장 중...' : '저장'}
</button>
<button
onClick={(e) => {
e.stopPropagation();
handleCancel();
}}
className="cancel-button"
disabled={isLoading}
>
취소
</button>
</div>
{error && <div className="error-message">{error}</div>}
</div>
) : (
<div className="pc-item-content" onClick={() => handlePcClick(pc.id)}>
<span>{pc.name}</span>
<button
className="edit-button"
onClick={(e) => {
e.stopPropagation();
handleEditClick(pc);
}}
>
수정
</button>
</div>
)}
</li>
))}
</ul>
<button className="add-pc-btn" onClick={handleAddPcClick}>
<span>+</span>
<span>새 PC 등록하기</span>
</button>
</aside>
<main className={`part-list ${isPartsLoading ? 'loading' : ''}`}>
{partsData.map((part, index) => (
<PartItem key={index} part={part} />
))}
</main>
</div>
);
};
export default CertifiedCombination;