feat: add page profile with orders
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import PageLayout from "../components/PageLayout";
|
||||
import { getUserInfo, getUserOrders } from "../api";
|
||||
|
||||
export default function Profile() {
|
||||
const [user, setUser] = useState(null);
|
||||
const [orders, setOrders] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
Promise.all([getUserInfo(), getUserOrders()])
|
||||
.then(([userRes, ordersRes]) => {
|
||||
setUser(userRes.data);
|
||||
setOrders(ordersRes.data);
|
||||
})
|
||||
.catch(() => { })
|
||||
.finally(() => setLoading(false));
|
||||
}, []);
|
||||
|
||||
const handleLogout = () => {
|
||||
localStorage.removeItem("token");
|
||||
localStorage.removeItem("user");
|
||||
navigate("/");
|
||||
};
|
||||
|
||||
const statusLabels = {
|
||||
new: "Новый",
|
||||
packed: "Собирают",
|
||||
delivered: "Доставлен",
|
||||
cancel: "Отменен",
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<PageLayout>
|
||||
<p className="text-white p-6 md:p-16">Загрузка..</p>
|
||||
</PageLayout>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<PageLayout>
|
||||
<main className="px-6 md:px-16 grow w-full mb-10 text-white">
|
||||
<div className="flex items-center justify-between mb-8">
|
||||
<h1 className="text-2xl md:text-4xl font-medium uppercase">
|
||||
Личный кабинет
|
||||
</h1>
|
||||
<button
|
||||
onClick={handleLogout}
|
||||
className="text-white/60 hover:text-red-400 transition-colors text-sm uppercase"
|
||||
>
|
||||
Выйти
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<section className="mb-10 bg-white/5 rounded-lg p-6 border border-white/10">
|
||||
<h2 className="text-white/80 space-y-2">
|
||||
{user && (
|
||||
<div className="text-white/80 space-y-2">
|
||||
<p>
|
||||
Имя: {user.first_name || "не указано"}{" "}
|
||||
{user.last_name || "не указано"}
|
||||
</p>
|
||||
<p>Телефон: {user.phone || "не указано"}</p>
|
||||
<p>Логин: {user.username}</p>
|
||||
</div>
|
||||
)}
|
||||
</h2>
|
||||
</section>
|
||||
<section>
|
||||
<h2 className="text-xl font-medium mb-4">Мои заказы</h2>
|
||||
{orders.length === 0 ? (
|
||||
<p>У вас пока нет заказов</p>
|
||||
) : (
|
||||
<div className="flex flex-col gap-4">
|
||||
{orders.map((order) => (
|
||||
<div
|
||||
className="bg-white/5 rounded-lg p-4 border border-white/10"
|
||||
key={order.id}
|
||||
>
|
||||
<div className="flex justify-between mb-2">
|
||||
<span className="font-medium">Заказ #{order.id}</span>
|
||||
<span className="text-white/60 text-sm uppercase">
|
||||
{statusLabels[order.status]}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-1 mb-3">
|
||||
{order.items?.map((oi) => (
|
||||
<div
|
||||
key={oi.id}
|
||||
className="flex justify-between pt-2 border-t border-white/10 text-sm"
|
||||
>
|
||||
<span>{oi.item?.name}</span>
|
||||
<span>
|
||||
{oi.quantity} {oi.item?.unit} x {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">
|
||||
Итого: {order.total_price}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
</main>
|
||||
</PageLayout>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user