This commit is contained in:
Андрей Дувакин 2024-10-05 14:11:29 +05:00
parent 3a750eda6d
commit 68f4836935
4 changed files with 348 additions and 1 deletions

View File

@ -8,6 +8,7 @@ import FederalDistricts from "./pages/FederalDistricts.jsx";
import Roles from "./pages/Roles.jsx"; import Roles from "./pages/Roles.jsx";
import Statuses from "./pages/Statuses.jsx"; import Statuses from "./pages/Statuses.jsx";
import Trucks from "./pages/Trucks.jsx"; import Trucks from "./pages/Trucks.jsx";
import Users from "./pages/Users.jsx";
const RoutesComponent = () => ( const RoutesComponent = () => (
<Routes> <Routes>
@ -19,7 +20,8 @@ const RoutesComponent = () => (
<Route path="/federal_districts" element={<FederalDistricts />} /> <Route path="/federal_districts" element={<FederalDistricts />} />
<Route path="/roles" element={<Roles />} /> <Route path="/roles" element={<Roles />} />
<Route path="/statuses" element={<Statuses />} />{" "} <Route path="/statuses" element={<Statuses />} />{" "}
<Route path="/trucks" element={<Trucks />} /> <Route path="/trucks" element={<Trucks />} />{" "}
<Route path="/users" element={<Users />} />
</Route> </Route>
</Routes> </Routes>
); );

View File

@ -399,3 +399,62 @@ export const deleteTruck = async (id) => {
throw error; throw error;
} }
}; };
export const getUsers = async () => {
try {
const response = await axios.get(`${API_URL}/users`, {
headers: {
Authorization: `Bearer ${getAuthToken()}`,
Accept: "application/json",
},
});
return response.data;
} catch (error) {
console.log("Ошибка при загрузке пользователей:", error);
throw error;
}
};
export const createUser = async (userData) => {
try {
const response = await axios.post(`${API_URL}/users`, userData, {
headers: {
Authorization: `Bearer ${getAuthToken()}`,
"Content-Type": "application/json",
},
});
return response.data;
} catch (error) {
console.log("Ошибка при создании пользователя:", error);
throw error;
}
};
export const updateUser = async (id, userData) => {
try {
const response = await axios.put(`${API_URL}/users/${id}`, userData, {
headers: {
Authorization: `Bearer ${getAuthToken()}`,
"Content-Type": "application/json",
},
});
return response.data;
} catch (error) {
console.log("Ошибка при обновлении пользователя:", error);
throw error;
}
};
export const deleteUser = async (id) => {
try {
await axios.delete(`${API_URL}/users/${id}`, {
headers: {
Authorization: `Bearer ${getAuthToken()}`,
Accept: "application/json",
},
});
} catch (error) {
console.log("Ошибка при удалении пользователя:", error);
throw error;
}
};

View File

@ -55,6 +55,11 @@ const Header = () => {
Грузовики Грузовики
</Link> </Link>
</li> </li>
<li className="nav-item">
<Link className="nav-link" to="/users">
Пользователи
</Link>
</li>
</ul> </ul>
<div className="d-flex align-items-center ml-auto"> <div className="d-flex align-items-center ml-auto">
{isAuthenticated ? ( {isAuthenticated ? (

281
src/pages/Users.jsx Normal file
View File

@ -0,0 +1,281 @@
import React, { useState, useEffect } from "react";
import SelectionDialog from "../components/SelectionDialog.jsx";
import { useNavigate } from "react-router-dom";
import { getAuthToken } from "../api.jsx";
import {
getUsers,
createUser,
updateUser,
deleteUser,
getRoles,
} from "../api.jsx";
const Users = () => {
const [users, setUsers] = useState([]);
const [roles, setRoles] = useState([]);
const [newUser, setNewUser] = useState({
first_name: "",
last_name: "",
login: "",
password: "",
role_id: "",
});
const [editingUserId, setEditingUserId] = useState(null);
const [error, setError] = useState(null);
const [showRoleDialog, setShowRoleDialog] = useState(false);
const navigate = useNavigate();
useEffect(() => {
fetchUsers();
fetchRoles();
}, []);
const fetchUsers = async () => {
try {
const data = await getUsers();
console.log(data);
setUsers(data);
} catch (error) {
console.error("Ошибка при загрузке пользователей:", error);
}
};
const fetchRoles = async () => {
try {
const data = await getRoles();
setRoles(data);
} catch (error) {
console.error("Ошибка при загрузке ролей:", error);
}
};
const handleInputChange = (e) => {
const { name, value } = e.target;
setNewUser({ ...newUser, [name]: value });
};
const handleSubmit = async (e) => {
e.preventDefault();
if (
!newUser.first_name ||
!newUser.last_name ||
!newUser.login ||
!newUser.password ||
!newUser.role_id
) {
setError("Пожалуйста, заполните все поля.");
return;
}
try {
if (editingUserId) {
await updateUser(editingUserId, newUser);
} else {
await createUser(newUser);
}
fetchUsers();
resetForm();
} catch (error) {
console.error(
"Ошибка при добавлении или обновлении пользователя:",
error
);
}
};
const handleEdit = (user) => {
setNewUser({
first_name: user.first_name,
last_name: user.last_name,
login: user.login,
password: user.password,
role_id: user.role_id,
role_name: user.role_name,
});
setEditingUserId(user.id);
};
const handleDelete = async (userId) => {
try {
await deleteUser(userId);
fetchUsers();
} catch (error) {
console.error("Ошибка при удалении пользователя:", error);
}
};
const resetForm = () => {
setNewUser({
first_name: "",
last_name: "",
login: "",
password: "",
role_id: "",
});
setEditingUserId(null);
};
const handleDialogSelectRole = (selectedItem) => {
setNewUser({
...newUser,
role_id: selectedItem.id,
role_name: selectedItem.name,
});
setShowRoleDialog(false);
};
if (getAuthToken() === null) {
navigate("/login");
}
return (
<div className="container mt-4">
<h3>Пользователи</h3>
<form onSubmit={handleSubmit}>
<div className="form-group">
<label htmlFor="firstName">Имя</label>
<input
type="text"
className="form-control"
id="firstName"
name="first_name"
placeholder="Введите имя"
value={newUser.first_name}
onChange={handleInputChange}
/>
</div>
<div className="form-group">
<label htmlFor="lastName">Фамилия</label>
<input
type="text"
className="form-control"
id="lastName"
name="last_name"
placeholder="Введите фамилию"
value={newUser.last_name}
onChange={handleInputChange}
/>
</div>
<div className="form-group">
<label htmlFor="login">Логин</label>
<input
type="text"
className="form-control"
id="login"
name="login"
placeholder="Введите логин"
value={newUser.login}
onChange={handleInputChange}
/>
</div>
<div className="form-group">
<label htmlFor="password">Пароль</label>
<input
type="password"
className="form-control"
id="password"
name="password"
placeholder="Введите пароль"
value={newUser.password}
onChange={handleInputChange}
/>
</div>
<div className="input-group mb-3">
<input
type="text"
className="form-control"
id="roleId"
name="roleId"
placeholder="Выберите роль"
value={newUser.role_name ? newUser.role_name : ""}
readOnly
onClick={() => setShowRoleDialog(true)}
/>
<div className="input-group-append">
<button
type="button"
className="btn btn-outline-secondary"
onClick={() => setShowRoleDialog(true)}
>
Выбрать
</button>
</div>
</div>
<div className="btn-group">
<button type="submit" className="btn btn-primary">
{editingUserId ? "Обновить" : "Создать"}
</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>
</tr>
</thead>
<tbody>
{users.map((user) => (
<tr key={user.id}>
<td>{user.first_name}</td>
<td>{user.last_name}</td>
<td>{user.login}</td>
<td>{user.role_name}</td>
<td>
<div className="btn-group">
<button
className="btn btn-warning"
onClick={() => handleEdit(user)}
>
Изменить
</button>
<button
className="btn btn-danger"
onClick={() => handleDelete(user.id)}
>
Удалить
</button>
</div>
</td>
</tr>
))}
</tbody>
</table>
<SelectionDialog
show={showRoleDialog}
handleClose={() => setShowRoleDialog(false)}
items={roles}
columns={[
{ key: "id", label: "ID" },
{ key: "name", label: "Название" },
]}
onSelect={handleDialogSelectRole}
/>
</div>
);
};
export default Users;