Vitron-Front/app/routes/profile.tsx
Arda Samadi 3156fb4204 Desktop: account area (shared sidebar) + brands list
- new profile.tsx layout: sticky desktop sidebar (user card + menu) wrapping all
  /profile/* pages; mobile renders page content only (unchanged)
- ProfilePagesHeader hidden at lg (one change covers all account sub-pages +
  cart); profile index shows a welcome on desktop (menu lives in the sidebar)
- sellers: 5-col brand grid with name overlay, contained, mobile header hidden
- MyLayout: desktop gate now covers /profile/* and /sellers
2026-06-16 12:46:22 +03:30

93 lines
3.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Link, Outlet, useLocation } from "@remix-run/react";
import {
ShoppingBag,
MessageCircle,
CircleFadingPlus,
BookmarkMinus,
Layers,
Wallet,
MapPin,
Settings,
LogOut,
CircleUserRound,
} from "lucide-react";
import { useServiceGetProfile } from "~/utils/RequestHandler";
import { useRootData } from "~/hooks/use-root-data";
const NAV = [
{ label: "سفارش‌ها", to: "/profile/orders", icon: ShoppingBag },
{ label: "پیام‌ها", to: "/profile/threads", icon: MessageCircle },
{ label: "دنبال‌شده‌ها", to: "/profile/following", icon: CircleFadingPlus },
{ label: "ذخیره‌شده‌ها", to: "/profile/bookmarks", icon: BookmarkMinus },
{ label: "ست‌های من", to: "/profile/sets", icon: Layers },
{ label: "کیف پول", to: "/profile/wallet", icon: Wallet },
{ label: "آدرس‌ها", to: "/profile/location", icon: MapPin },
{ label: "تنظیمات", to: "/profile/setting", icon: Settings },
];
/**
* Layout for the account area. On desktop it renders a sticky sidebar
* (user card + menu) next to the page content; on mobile it's just the
* page content (each profile page keeps its existing mobile UI).
*/
export default function ProfileLayout() {
const location = useLocation();
const { user } = useRootData();
const { data: profile } = useServiceGetProfile();
const isActive = (to: string) =>
location.pathname === to || location.pathname.startsWith(to + "/");
return (
<div className="lg:max-w-[1320px] lg:mx-auto lg:w-full lg:px-8 lg:py-8 lg:grid lg:grid-cols-[280px_1fr] lg:gap-7 lg:items-start">
{/* Desktop sidebar */}
<aside className="hidden lg:block lg:sticky lg:top-[88px] border border-WHITE3 rounded-2xl overflow-hidden">
<div className="p-5 border-b border-WHITE3 text-center">
<div className="w-20 h-20 rounded-full bg-WHITE3 grid place-items-center mx-auto mb-3 text-GRAY">
<CircleUserRound size={40} />
</div>
<p className="font-bold text-[16px]">
{profile?.username || "کاربر ویترون"}
</p>
{profile?.phoneNumber ? (
<p className="text-GRAY text-[13px] mt-1" dir="ltr">
{profile.phoneNumber}
</p>
) : null}
</div>
<nav className="p-2.5 flex flex-col gap-0.5">
{NAV.map((n) => (
<Link
key={n.to}
to={n.to}
prefetch="intent"
className={`flex items-center gap-3 px-3.5 py-3 rounded-xl text-[14.5px] font-semibold transition-colors ${
isActive(n.to)
? "bg-BLACK text-white"
: "text-BLACK2 hover:bg-WHITE2"
}`}
>
<n.icon size={20} />
{n.label}
</Link>
))}
{user?.access_token ? (
<Link
to="/logout"
className="flex items-center gap-3 px-3.5 py-3 rounded-xl text-[14.5px] font-semibold text-RED hover:bg-red-50 transition-colors"
>
<LogOut size={20} />
خروج از حساب
</Link>
) : null}
</nav>
</aside>
{/* Page content */}
<div className="min-w-0">
<Outlet />
</div>
</div>
);
}