278 lines
7.7 KiB
JavaScript
278 lines
7.7 KiB
JavaScript
import React, { useState, useEffect } from "react";
|
||
import SelectionDialog from "../components/SelectionDialog.jsx";
|
||
import { useNavigate } from "react-router-dom";
|
||
import { getAuthToken } from "../api.jsx";
|
||
import {
|
||
getAccessories,
|
||
createAccessory,
|
||
updateAccessory,
|
||
deleteAccessory,
|
||
getCities,
|
||
} from "../api.jsx";
|
||
|
||
const Accessories = () => {
|
||
const [accessories, setAccessories] = useState([]);
|
||
const [cities, setCities] = useState([]);
|
||
const [newAccessory, setNewAccessory] = useState({
|
||
name: "",
|
||
volume: "",
|
||
weight: "",
|
||
period: "",
|
||
city_id: "",
|
||
});
|
||
const [editingAccessoryId, setEditingAccessoryId] = useState(null);
|
||
const [error, setError] = useState(null);
|
||
const [showCityDialog, setShowCityDialog] = useState(false);
|
||
const navigate = useNavigate();
|
||
|
||
useEffect(() => {
|
||
fetchAccessories();
|
||
fetchCities();
|
||
}, []);
|
||
|
||
const fetchAccessories = async () => {
|
||
try {
|
||
const data = await getAccessories();
|
||
console.log(data);
|
||
setAccessories(data);
|
||
} catch (error) {
|
||
console.error("Ошибка при загрузке аксессуаров:", error);
|
||
}
|
||
};
|
||
|
||
const fetchCities = async () => {
|
||
try {
|
||
const data = await getCities();
|
||
setCities(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 ||
|
||
!newAccessory.city_id
|
||
) {
|
||
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,
|
||
city_name: accessory.city_name,
|
||
});
|
||
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);
|
||
};
|
||
|
||
const handleDialogSelectCity = (selectedItem) => {
|
||
setNewAccessory({
|
||
...newAccessory,
|
||
city_id: selectedItem.id,
|
||
city_name: selectedItem.name,
|
||
});
|
||
setShowCityDialog(false);
|
||
};
|
||
|
||
if (getAuthToken() === null) {
|
||
navigate("/login");
|
||
}
|
||
|
||
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="input-group mb-3">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
id="cityId"
|
||
name="cityId"
|
||
placeholder="Выберите город"
|
||
value={newAccessory.city_name ? newAccessory.city_name : ""}
|
||
readOnly
|
||
onClick={() => setShowCityDialog(true)}
|
||
/>
|
||
<div className="input-group-append">
|
||
<button
|
||
type="button"
|
||
className="btn btn-outline-secondary"
|
||
onClick={() => setShowCityDialog(true)}
|
||
>
|
||
Выбрать
|
||
</button>
|
||
</div>
|
||
</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>Название</th>
|
||
<th>Объем</th>
|
||
<th>Вес</th>
|
||
<th>Период</th>
|
||
<th>Город</th>
|
||
<th>Действия</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{accessories.map((accessory) => (
|
||
<tr key={accessory.id}>
|
||
<td>{accessory.name}</td>
|
||
<td>{accessory.volume}</td>
|
||
<td>{accessory.weight}</td>
|
||
<td>{accessory.period}</td>
|
||
<td>{accessory.city_name}</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>
|
||
|
||
<SelectionDialog
|
||
show={showCityDialog}
|
||
handleClose={() => setShowCityDialog(false)}
|
||
items={cities}
|
||
columns={[
|
||
{ key: "id", label: "ID" },
|
||
{ key: "name", label: "Название" },
|
||
]}
|
||
onSelect={handleDialogSelectCity}
|
||
/>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default Accessories;
|