diff --git a/backend/server.js b/backend/server.js index ff25579..f6ebf2e 100644 --- a/backend/server.js +++ b/backend/server.js @@ -104,6 +104,27 @@ app.delete('/api/departments/:id', authenticateToken, async (req, res) => { } }); +app.put('/api/departments/:id', authenticateToken, async (req, res) => { + const { id } = req.params; + const { name } = req.body; + if (!name || name.trim() === '') { + return res.status(400).json({ error: 'Department name is required' }); + } + + try { + const result = await db.run('UPDATE departments SET name = ? WHERE id = ?', [name.trim(), id]); + if (result.changes === 0) { + return res.status(404).json({ error: 'Department not found' }); + } + res.json({ id: parseInt(id, 10), name: name.trim() }); + } catch (error) { + if (error.message.includes('UNIQUE')) { + return res.status(400).json({ error: 'Department with this name already exists' }); + } + res.status(500).json({ error: error.message }); + } +}); + // 3. Companies Endpoints (New dictionary CRUD) app.get('/api/companies', async (req, res) => { try { @@ -142,6 +163,27 @@ app.delete('/api/companies/:id', authenticateToken, async (req, res) => { } }); +app.put('/api/companies/:id', authenticateToken, async (req, res) => { + const { id } = req.params; + const { name } = req.body; + if (!name || name.trim() === '') { + return res.status(400).json({ error: 'Company name is required' }); + } + + try { + const result = await db.run('UPDATE companies SET name = ? WHERE id = ?', [name.trim(), id]); + if (result.changes === 0) { + return res.status(404).json({ error: 'Company not found' }); + } + res.json({ id: parseInt(id, 10), name: name.trim() }); + } catch (error) { + if (error.message.includes('UNIQUE')) { + return res.status(400).json({ error: 'Company with this name already exists' }); + } + res.status(500).json({ error: error.message }); + } +}); + // 4. Employees Endpoints (Search & List) app.get('/api/employees', async (req, res) => { const { search, departmentId } = req.query; diff --git a/frontend/src/components/AdminPanel.jsx b/frontend/src/components/AdminPanel.jsx index 0656f58..5227f02 100644 --- a/frontend/src/components/AdminPanel.jsx +++ b/frontend/src/components/AdminPanel.jsx @@ -36,6 +36,68 @@ const AdminPanel = ({ token, employees, departments, companies, onRefreshData }) setTimeout(() => setAlert({ type: '', message: '' }), 5000); }; + // Department Edit States + const [editingDeptId, setEditingDeptId] = useState(null); + const [editingDeptName, setEditingDeptName] = useState(''); + + // Company Edit States + const [editingCompanyId, setEditingCompanyId] = useState(null); + const [editingCompanyName, setEditingCompanyName] = useState(''); + + const handleEditCompanySubmit = async (id) => { + if (!editingCompanyName.trim()) return; + + try { + const res = await fetch(`/api/companies/${id}`, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${token}` + }, + body: JSON.stringify({ name: editingCompanyName.trim() }) + }); + const data = await res.json(); + + if (res.ok) { + setEditingCompanyId(null); + setEditingCompanyName(''); + onRefreshData(); + showAlert('success', 'Название компании успешно обновлено!'); + } else { + showAlert('error', data.error || 'Ошибка при обновлении названия компании'); + } + } catch (err) { + showAlert('error', 'Ошибка сети при обновлении компании'); + } + }; + + const handleEditDeptSubmit = async (id) => { + if (!editingDeptName.trim()) return; + + try { + const res = await fetch(`/api/departments/${id}`, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${token}` + }, + body: JSON.stringify({ name: editingDeptName.trim() }) + }); + const data = await res.json(); + + if (res.ok) { + setEditingDeptId(null); + setEditingDeptName(''); + onRefreshData(); + showAlert('success', 'Название подразделения успешно обновлено!'); + } else { + showAlert('error', data.error || 'Ошибка при обновлении подразделения'); + } + } catch (err) { + showAlert('error', 'Ошибка сети при обновлении подразделения'); + } + }; + // ---------------------------------------------------- // Department Actions // ---------------------------------------------------- @@ -421,16 +483,63 @@ const AdminPanel = ({ token, employees, departments, companies, onRefreshData }) ) : ( companies.map((comp) => (