._.
This commit is contained in:
parent
028d13f4a2
commit
bd71225a23
@ -1,6 +1,7 @@
|
||||
import { Routes, Route, Navigate } from "react-router-dom";
|
||||
import Login from "./pages/Login";
|
||||
import Home from "./pages/Home.jsx";
|
||||
import Accessories from "./pages/Accessories.jsx";
|
||||
import PrivateRoute from "./components/PrivateRoute";
|
||||
|
||||
const RoutesComponent = () => (
|
||||
@ -8,6 +9,7 @@ const RoutesComponent = () => (
|
||||
<Route path="/login" element={<Login />} />
|
||||
<Route element={<PrivateRoute />}>
|
||||
<Route path="/" element={<Home />} />
|
||||
<Route path="/accessories" element={<Accessories />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
);
|
||||
|
||||
63
src/api.jsx
63
src/api.jsx
@ -32,3 +32,66 @@ export const loginUser = async (loginData) => {
|
||||
throw error.response ? error.response.data : error;
|
||||
}
|
||||
};
|
||||
|
||||
export const getAccessories = async () => {
|
||||
try {
|
||||
const response = await axios.get(`${API_URL}/accessories`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${getAuthToken()}`,
|
||||
Accept: "application/json",
|
||||
},
|
||||
});
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
console.log("Ошибка при получении аксессуаров:", error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const createAccessory = async (accessoryData) => {
|
||||
try {
|
||||
const response = await axios.post(`${API_URL}/accessories`, accessoryData, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${getAuthToken()}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
console.log("Ошибка при создании аксессуара:", error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const updateAccessory = async (id, accessoryData) => {
|
||||
try {
|
||||
const response = await axios.put(
|
||||
`${API_URL}/accessories/${id}`,
|
||||
accessoryData,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${getAuthToken()}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
}
|
||||
);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
console.log("Ошибка при обновлении аксессуара:", error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const deleteAccessory = async (id) => {
|
||||
try {
|
||||
await axios.delete(`${API_URL}/accessories/${id}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${getAuthToken()}`,
|
||||
Accept: "application/json",
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
console.log("Ошибка при удалении аксессуара:", error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
@ -25,6 +25,11 @@ const Header = () => {
|
||||
Заказы
|
||||
</Link>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<Link className="nav-link" to="/accessories">
|
||||
Компоненты
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
<div className="d-flex align-items-center ml-auto">
|
||||
{isAuthenticated ? (
|
||||
|
||||
210
src/pages/Accessories.jsx
Normal file
210
src/pages/Accessories.jsx
Normal file
@ -0,0 +1,210 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import {
|
||||
getAccessories,
|
||||
createAccessory,
|
||||
updateAccessory,
|
||||
deleteAccessory,
|
||||
} from "../api.jsx";
|
||||
|
||||
const Accessories = () => {
|
||||
const [accessories, setAccessories] = useState([]);
|
||||
const [newAccessory, setNewAccessory] = useState({
|
||||
name: "",
|
||||
volume: "",
|
||||
weight: "",
|
||||
period: "",
|
||||
city_id: "",
|
||||
});
|
||||
const [editingAccessoryId, setEditingAccessoryId] = useState(null);
|
||||
const [error, setError] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
fetchAccessories();
|
||||
}, []);
|
||||
|
||||
const fetchAccessories = async () => {
|
||||
try {
|
||||
const data = await getAccessories();
|
||||
setAccessories(data);
|
||||
} catch (error) {
|
||||
console.error("Ошибка при загрузке аксессуаров:", error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleInputChange = (e) => {
|
||||
const { name, value } = e.target;
|
||||
setNewAccessory({ ...newAccessory, [name]: value });
|
||||
};
|
||||
|
||||
const handleSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
if (
|
||||
!newAccessory.name ||
|
||||
!newAccessory.volume ||
|
||||
!newAccessory.weight ||
|
||||
!newAccessory.period
|
||||
) {
|
||||
setError("Пожалуйста, заполните все поля.");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (editingAccessoryId) {
|
||||
await updateAccessory(editingAccessoryId, newAccessory);
|
||||
} else {
|
||||
await createAccessory(newAccessory);
|
||||
}
|
||||
fetchAccessories();
|
||||
resetForm();
|
||||
} catch (error) {
|
||||
console.error("Ошибка при добавлении или обновлении аксессуара:", error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleEdit = (accessory) => {
|
||||
setNewAccessory({
|
||||
name: accessory.name,
|
||||
volume: accessory.volume,
|
||||
weight: accessory.weight,
|
||||
period: accessory.period,
|
||||
city_id: accessory.city_id,
|
||||
});
|
||||
setEditingAccessoryId(accessory.id);
|
||||
};
|
||||
|
||||
const handleDelete = async (accessoryId) => {
|
||||
try {
|
||||
await deleteAccessory(accessoryId);
|
||||
fetchAccessories();
|
||||
} catch (error) {
|
||||
console.error("Ошибка при удалении аксессуара:", error);
|
||||
}
|
||||
};
|
||||
|
||||
const resetForm = () => {
|
||||
setNewAccessory({
|
||||
name: "",
|
||||
volume: "",
|
||||
weight: "",
|
||||
period: "",
|
||||
city_id: "",
|
||||
});
|
||||
setEditingAccessoryId(null);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="container mt-4">
|
||||
<h3>Аксессуары</h3>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<div className="form-group">
|
||||
<label htmlFor="accessoryName">Название аксессуара</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
id="accessoryName"
|
||||
name="name"
|
||||
placeholder="Введите название аксессуара"
|
||||
value={newAccessory.name}
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label htmlFor="accessoryVolume">Объем</label>
|
||||
<input
|
||||
type="number"
|
||||
className="form-control"
|
||||
id="accessoryVolume"
|
||||
name="volume"
|
||||
placeholder="Введите объем"
|
||||
value={newAccessory.volume}
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label htmlFor="accessoryWeight">Вес</label>
|
||||
<input
|
||||
type="number"
|
||||
className="form-control"
|
||||
id="accessoryWeight"
|
||||
name="weight"
|
||||
placeholder="Введите вес"
|
||||
value={newAccessory.weight}
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label htmlFor="accessoryPeriod">Период</label>
|
||||
<input
|
||||
type="number"
|
||||
className="form-control"
|
||||
id="accessoryPeriod"
|
||||
name="period"
|
||||
placeholder="Введите период"
|
||||
value={newAccessory.period}
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="btn-group">
|
||||
<button type="submit" className="btn btn-primary">
|
||||
{editingAccessoryId ? "Обновить" : "Создать"}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-secondary"
|
||||
onClick={resetForm}
|
||||
>
|
||||
Отменить
|
||||
</button>
|
||||
</div>
|
||||
{error && (
|
||||
<div className="alert alert-danger mt-3" role="alert">
|
||||
{error}
|
||||
</div>
|
||||
)}
|
||||
</form>
|
||||
<h3 className="mt-5">Список аксессуаров</h3>
|
||||
<table className="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Название</th>
|
||||
<th>Объем</th>
|
||||
<th>Вес</th>
|
||||
<th>Период</th>
|
||||
<th>Действия</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{accessories.map((accessory) => (
|
||||
<tr key={accessory.id}>
|
||||
<td>{accessory.id}</td>
|
||||
<td>{accessory.name}</td>
|
||||
<td>{accessory.volume}</td>
|
||||
<td>{accessory.weight}</td>
|
||||
<td>{accessory.period}</td>
|
||||
<td>
|
||||
<div className="btn-group">
|
||||
<button
|
||||
className="btn btn-warning"
|
||||
onClick={() => handleEdit(accessory)}
|
||||
>
|
||||
Изменить
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-danger"
|
||||
onClick={() => handleDelete(accessory.id)}
|
||||
>
|
||||
Удалить
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Accessories;
|
||||
Loading…
x
Reference in New Issue
Block a user