This commit is contained in:
2026-06-26 15:28:32 +03:00
parent 6822dfe655
commit 846844a1f0
3 changed files with 103 additions and 5 deletions
+7 -1
View File
@@ -48,7 +48,7 @@ export const createOrder = (data) => axios.post(`${API_URL}/orders/`, data);
export const getUserOrders = () => axios.get(`${API_URL}/orders`);
export const getOrder = (id) => axios.get(`${API_URL}/orders/${id}`);
export const updateProfile = (data) => axios.patch(`${API_URL}/profile`);
export const updateProfile = (data) => axios.patch(`${API_URL}/profile`, data);
export const getUserInfo = () => axios.get(`${API_URL}/profile`);
export const uploadItemAvatar = (id, file) => {
@@ -58,3 +58,9 @@ export const uploadItemAvatar = (id, file) => {
headers: { "Content-Type": "multipart/form-data" },
});
};
export const getAllOrders = () => axios.get(`${API_URL}/admin/orders`);
export const updateOrderStatus = (id, data) =>
axios.patch(`${API_URL}/admin/orders/${id}`, data);
export const registerAdmin = (data) =>
axios.post(`${API_URL}/admin/register`, data);
+94
View File
@@ -0,0 +1,94 @@
import { useState, useEffect } from "react";
import { getAllOrders, updateOrderStatus } from "../api/index";
const STATUSES = [
{ value: "new", label: "Новый" },
{ value: "packed", label: "Собран" },
{ value: "delivered", label: "Доставлен" },
{ value: "cancel", label: "Отменён" },
];
export default function AdminOrders() {
const [orders, setOrders] = useState([]);
const [loading, setLoading] = useState(true);
const loadOrders = () => {
getAllOrders()
.then((res) => setOrders(res.data))
.catch(() => { })
.finally(() => setLoading(false));
};
useEffect(() => {
loadOrders();
}, []);
const handleStatusChange = async (id, newStatus) => {
try {
await updateOrderStatus(id, { status: newStatus });
setOrders((prev) =>
prev.map((o) => (o.id === id ? { ...o, status: newStatus } : o)),
);
} catch {
alert("Не удалось изменить статус");
}
};
if (loading) return <p className="text-white/60">Загрузка...</p>;
return (
<div className="flex flex-col gap-4">
{orders.length === 0 ? (
<p className="text-white/60">Заказов нет</p>
) : (
orders.map((order) => (
<div
key={order.id}
className="bg-white/5 rounded-lg p-4 border border-white/10"
>
{/* шапка: номер + селект статуса */}
<div className="flex justify-between items-center mb-3">
<span className="font-medium text-white">Заказ #{order.id}</span>
<select
value={order.status}
onChange={(e) => handleStatusChange(order.id, e.target.value)}
className="bg-slate-700 text-white text-sm rounded px-3 py-1 border border-white/10"
>
{STATUSES.map((s) => (
<option key={s.value} value={s.value}>
{s.label}
</option>
))}
</select>
</div>
{/* товары заказа */}
<div className="flex flex-col gap-2 mb-3 text-sm text-white/70">
{order.items?.map((oi) => (
<div key={oi.id} className="flex items-center gap-3">
<img
src={`/static/items/${oi.item?.avatar_url}`}
alt=""
className="w-20 h-20 object-cover rounded shrink-0"
/>
<span className="grow">{oi.item?.name}</span>
<span className="whitespace-nowrap">
{oi.quantity} {oi.item?.unit} × {oi.price}
</span>
</div>
))}
</div>
{/* подвал: адрес + итог */}
<div className="flex justify-between pt-2 border-t border-white/10 text-sm">
<span className="text-white/50">{order.delivery_address}</span>
<span className="font-medium text-white">
Итого: {order.total_price}
</span>
</div>
</div>
))
)}
</div>
);
}
+2 -4
View File
@@ -1,7 +1,7 @@
import { useState } from "react";
import PageLayout from "../components/PageLayout";
import AdminItems from "../components/AdminItems";
// import AdminOrders from "../components/AdminOrders"; // добавим позже
import AdminOrders from "../components/AdminOrders"; // добавим позже
// import AdminStaff from "../components/AdminStaff"; // добавим позже
export default function AdminPage() {
@@ -38,9 +38,7 @@ export default function AdminPage() {
{/* Содержимое активной вкладки */}
{tab === "items" && <AdminItems />}
{tab === "orders" && (
<p className="text-white/50">Раздел заказов в разработке</p>
)}
{tab === "orders" && <AdminOrders />}
{tab === "staff" && (
<p className="text-white/50">Раздел сотрудников в разработке</p>
)}