✏️ 프로젝트 이름 인라인 편집 기능 추가
Some checks failed
SonarQube Analysis / SonarQube Scan (push) Has been cancelled

백엔드:
- dashboard.py에 PATCH /dashboard/projects/{id} 엔드포인트 추가
- 프로젝트 이름 업데이트 기능 구현
- 활동 로그 기록

프론트엔드:
- ProjectsPage에 인라인 편집 기능 추가
- 더블클릭으로 편집 모드 진입
- Enter 키로 저장, Escape로 취소
- 저장/취소 버튼 (✓/✕) 제공
- 간단하고 직관적인 UX
This commit is contained in:
Hyungi Ahn
2025-10-14 06:47:52 +09:00
parent 9325d36031
commit ca0336d627
2 changed files with 159 additions and 2 deletions

View File

@@ -4,6 +4,39 @@ const ProjectsPage = ({ user }) => {
const [projects, setProjects] = useState([]);
const [loading, setLoading] = useState(true);
const [showCreateForm, setShowCreateForm] = useState(false);
const [editingProject, setEditingProject] = useState(null);
const [editedName, setEditedName] = useState('');
// 프로젝트 이름 편집 시작
const startEditing = (project) => {
setEditingProject(project.id);
setEditedName(project.name);
};
// 프로젝트 이름 저장
const saveProjectName = async (projectId) => {
try {
// TODO: API 호출하여 프로젝트 이름 업데이트
// await api.patch(`/dashboard/projects/${projectId}?job_name=${encodeURIComponent(editedName)}`);
// 임시: 로컬 상태만 업데이트
setProjects(projects.map(p =>
p.id === projectId ? { ...p, name: editedName } : p
));
setEditingProject(null);
setEditedName('');
} catch (error) {
console.error('프로젝트 이름 수정 실패:', error);
alert('프로젝트 이름 수정에 실패했습니다.');
}
};
// 편집 취소
const cancelEditing = () => {
setEditingProject(null);
setEditedName('');
};
useEffect(() => {
// 실제로는 API에서 프로젝트 데이터를 가져올 예정
@@ -224,8 +257,62 @@ const ProjectsPage = ({ user }) => {
}}
onMouseEnter={(e) => e.currentTarget.style.background = '#f7fafc'}
onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}>
<td style={{ padding: '16px', fontWeight: '600', color: '#2d3748' }}>
{project.name}
<td
style={{ padding: '16px', fontWeight: '600', color: '#2d3748', cursor: 'pointer' }}
onDoubleClick={() => startEditing(project)}
title="더블클릭하여 이름 수정"
>
{editingProject === project.id ? (
<div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>
<input
type="text"
value={editedName}
onChange={(e) => setEditedName(e.target.value)}
onKeyPress={(e) => {
if (e.key === 'Enter') saveProjectName(project.id);
if (e.key === 'Escape') cancelEditing();
}}
autoFocus
style={{
flex: 1,
padding: '6px 10px',
border: '2px solid #3b82f6',
borderRadius: '4px',
fontSize: '14px'
}}
/>
<button
onClick={() => saveProjectName(project.id)}
style={{
padding: '6px 12px',
background: '#10b981',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer',
fontSize: '12px'
}}
>
</button>
<button
onClick={cancelEditing}
style={{
padding: '6px 12px',
background: '#ef4444',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer',
fontSize: '12px'
}}
>
</button>
</div>
) : (
<span>{project.name}</span>
)}
</td>
<td style={{ padding: '16px' }}>
<span style={{