2026-07-11 21:21:29 +03:30
|
|
|
|
"use client";
|
|
|
|
|
|
|
|
|
|
|
|
import {
|
|
|
|
|
|
ArrowDownRight,
|
|
|
|
|
|
ArrowLeftRight,
|
|
|
|
|
|
ArrowUpRight,
|
|
|
|
|
|
BarChart3,
|
|
|
|
|
|
Bell,
|
|
|
|
|
|
ChevronDown,
|
|
|
|
|
|
Copy,
|
|
|
|
|
|
Gift,
|
|
|
|
|
|
HelpCircle,
|
|
|
|
|
|
LayoutGrid,
|
|
|
|
|
|
LogOut,
|
|
|
|
|
|
type LucideIcon,
|
|
|
|
|
|
Menu,
|
|
|
|
|
|
Moon,
|
|
|
|
|
|
Search,
|
|
|
|
|
|
Settings,
|
|
|
|
|
|
Star,
|
|
|
|
|
|
TrendingUp,
|
|
|
|
|
|
Wallet,
|
|
|
|
|
|
} from "lucide-react";
|
|
|
|
|
|
|
|
|
|
|
|
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
|
|
|
|
|
import { Button } from "@/components/ui/button";
|
|
|
|
|
|
import {
|
|
|
|
|
|
DropdownMenu,
|
|
|
|
|
|
DropdownMenuContent,
|
|
|
|
|
|
DropdownMenuItem,
|
|
|
|
|
|
DropdownMenuSeparator,
|
|
|
|
|
|
DropdownMenuTrigger,
|
|
|
|
|
|
} from "@/components/ui/dropdown-menu";
|
|
|
|
|
|
import { Input } from "@/components/ui/input";
|
|
|
|
|
|
import { ScrollArea } from "@/components/ui/scroll-area";
|
|
|
|
|
|
import {
|
|
|
|
|
|
Sheet,
|
|
|
|
|
|
SheetContent,
|
|
|
|
|
|
SheetHeader,
|
|
|
|
|
|
SheetTitle,
|
|
|
|
|
|
SheetTrigger,
|
|
|
|
|
|
} from "@/components/ui/sheet";
|
|
|
|
|
|
import { cn } from "@/lib/utils";
|
|
|
|
|
|
|
|
|
|
|
|
type NavLink = {
|
|
|
|
|
|
label: string;
|
|
|
|
|
|
href: string;
|
|
|
|
|
|
isActive?: boolean;
|
|
|
|
|
|
icon: LucideIcon;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
type TokenItem = {
|
|
|
|
|
|
name: string;
|
|
|
|
|
|
symbol: string;
|
|
|
|
|
|
color: string;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
type NotificationItem = {
|
|
|
|
|
|
title: string;
|
|
|
|
|
|
detail: string;
|
|
|
|
|
|
time: string;
|
|
|
|
|
|
tone: string;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const data = {
|
|
|
|
|
|
brand: {
|
|
|
|
|
|
name: "NexoChain",
|
|
|
|
|
|
},
|
|
|
|
|
|
user: {
|
|
|
|
|
|
name: "علی رضایی",
|
|
|
|
|
|
email: "ali@example.com",
|
|
|
|
|
|
avatar:
|
|
|
|
|
|
"/block-media/shadcnblocks/block/avatar-2.webp",
|
|
|
|
|
|
},
|
|
|
|
|
|
wallet: {
|
|
|
|
|
|
address: "0x1cf2...9a56",
|
|
|
|
|
|
balance: "$460,890.02",
|
|
|
|
|
|
status: "متصل",
|
|
|
|
|
|
},
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const navLinks: NavLink[] = [
|
|
|
|
|
|
{ label: "نمای کلی", href: "#", isActive: true, icon: LayoutGrid },
|
|
|
|
|
|
{ label: "بازارها", href: "#", icon: BarChart3 },
|
|
|
|
|
|
{ label: "معامله", href: "#", icon: ArrowLeftRight },
|
|
|
|
|
|
{ label: "پاداشها", href: "#", icon: TrendingUp },
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
const favorites: TokenItem[] = [
|
|
|
|
|
|
{ name: "Bitcoin", symbol: "BTC", color: "bg-orange-500" },
|
|
|
|
|
|
{ name: "Ethereum", symbol: "ETH", color: "bg-indigo-500" },
|
|
|
|
|
|
{ name: "XRP", symbol: "XRP", color: "bg-neutral-900" },
|
|
|
|
|
|
{ name: "TetherUS", symbol: "IRRT", color: "bg-emerald-500" },
|
|
|
|
|
|
{ name: "Tron", symbol: "TRX", color: "bg-red-500" },
|
|
|
|
|
|
{ name: "Solana", symbol: "SOL", color: "bg-violet-500" },
|
|
|
|
|
|
{ name: "IRRC", symbol: "IRRC", color: "bg-blue-500" },
|
|
|
|
|
|
{ name: "BNB", symbol: "BNB", color: "bg-yellow-500" },
|
|
|
|
|
|
{ name: "Avalanche", symbol: "AVAX", color: "bg-rose-500" },
|
|
|
|
|
|
{ name: "Cardano", symbol: "ADA", color: "bg-sky-500" },
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
const walletAssets: TokenItem[] = [
|
|
|
|
|
|
{ name: "Bitcoin", symbol: "BTC", color: "bg-orange-500" },
|
|
|
|
|
|
{ name: "Ethereum", symbol: "ETH", color: "bg-indigo-500" },
|
|
|
|
|
|
{ name: "XRP", symbol: "XRP", color: "bg-neutral-900" },
|
|
|
|
|
|
{ name: "TetherUS", symbol: "IRRT", color: "bg-emerald-500" },
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
const notifications: NotificationItem[] = [
|
|
|
|
|
|
{
|
|
|
|
|
|
title: "برای امنیت حساب، احراز دو مرحلهای را فعال کنید",
|
|
|
|
|
|
detail: "کروم روی macOS، استانبول",
|
|
|
|
|
|
time: "۵ دقیقه",
|
|
|
|
|
|
tone: "text-rose-500",
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: "مبادله انجام شد",
|
|
|
|
|
|
detail: "۰٫۵ BTC - ۱۲٬۳۵۰ IRRC",
|
|
|
|
|
|
time: "اکنون",
|
|
|
|
|
|
tone: "text-emerald-500",
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: "۱۵ IRRC پاداش معاملاتی دریافت کردید",
|
|
|
|
|
|
detail: "در انتظار تأیید بلاک",
|
|
|
|
|
|
time: "۱ ساعت",
|
|
|
|
|
|
tone: "text-emerald-500",
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: "ورود جدید",
|
|
|
|
|
|
detail: "کروم روی macOS، استانبول",
|
|
|
|
|
|
time: "۱۰ دقیقه",
|
|
|
|
|
|
tone: "text-orange-500",
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: "تعمیرات برنامهریزیشده",
|
|
|
|
|
|
detail: "فردا ساعت ۰۳:۰۰ UTC",
|
|
|
|
|
|
time: "دیروز",
|
|
|
|
|
|
tone: "text-muted-foreground",
|
|
|
|
|
|
},
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
function TokenBadge({ item }: { item: TokenItem }) {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<span
|
|
|
|
|
|
className={cn(
|
|
|
|
|
|
"flex size-6 items-center justify-center rounded-full text-[11px] font-semibold text-white",
|
|
|
|
|
|
item.color,
|
|
|
|
|
|
)}
|
|
|
|
|
|
>
|
|
|
|
|
|
{item.symbol.slice(0, 1)}
|
|
|
|
|
|
</span>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function HeaderTab({ item }: { item: NavLink }) {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<a
|
|
|
|
|
|
href={item.href}
|
|
|
|
|
|
className={cn(
|
|
|
|
|
|
"rounded-full px-3 py-1 text-sm",
|
|
|
|
|
|
item.isActive
|
|
|
|
|
|
? "bg-accent text-foreground"
|
|
|
|
|
|
: "text-muted-foreground hover:bg-accent/50 hover:text-foreground",
|
|
|
|
|
|
)}
|
|
|
|
|
|
>
|
|
|
|
|
|
{item.label}
|
|
|
|
|
|
</a>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function SearchField({ className }: { className?: string }) {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div className={cn("relative", className)}>
|
|
|
|
|
|
<Search className="pointer-events-none absolute top-1/2 start-3 size-4 -translate-y-1/2 text-muted-foreground" />
|
|
|
|
|
|
<Input
|
|
|
|
|
|
placeholder="جستجوی توکن یا جفت..."
|
|
|
|
|
|
className="h-9 w-full rounded-full bg-muted ps-9"
|
|
|
|
|
|
aria-label="جستجوی توکن"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<span className="pointer-events-none absolute top-1/2 end-2.5 -translate-y-1/2 rounded-full bg-accent px-2 py-0.5 text-[10px] text-muted-foreground">
|
|
|
|
|
|
/
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function WalletMenu() {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<DropdownMenu>
|
|
|
|
|
|
<DropdownMenuTrigger asChild>
|
|
|
|
|
|
<Button
|
|
|
|
|
|
variant="ghost"
|
|
|
|
|
|
className="gap-2 rounded-full border border-border bg-background px-3"
|
|
|
|
|
|
>
|
|
|
|
|
|
<span className="flex size-5 items-center justify-center rounded-full bg-primary/10 text-primary">
|
|
|
|
|
|
<Wallet className="size-3.5" />
|
|
|
|
|
|
</span>
|
|
|
|
|
|
<span className="text-sm font-medium text-foreground">
|
|
|
|
|
|
{data.wallet.address}
|
|
|
|
|
|
</span>
|
|
|
|
|
|
<ChevronDown className="size-3 text-muted-foreground" />
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</DropdownMenuTrigger>
|
|
|
|
|
|
<DropdownMenuContent align="start" className="w-80 p-3 text-start">
|
|
|
|
|
|
<div className="flex items-start justify-between gap-3">
|
|
|
|
|
|
<div className="flex items-center gap-2">
|
|
|
|
|
|
<span className="flex size-9 items-center justify-center rounded-full bg-primary/10 text-primary">
|
|
|
|
|
|
<Wallet className="size-4" />
|
|
|
|
|
|
</span>
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<div className="text-sm font-medium text-foreground">
|
|
|
|
|
|
{data.wallet.address}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="text-xs text-primary">{data.wallet.status}</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<Button variant="outline" size="sm" className="h-7 gap-1">
|
|
|
|
|
|
<Copy className="size-3" />
|
|
|
|
|
|
کپی
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="mt-4 rounded-lg border border-border bg-muted px-3 py-2">
|
|
|
|
|
|
<div className="text-xs text-muted-foreground">موجودی کل</div>
|
|
|
|
|
|
<div className="mt-1 text-xl font-semibold text-foreground">
|
|
|
|
|
|
{data.wallet.balance}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<Button variant="outline" size="sm" className="mt-2 h-7 gap-1">
|
|
|
|
|
|
<span className="flex size-4 items-center justify-center rounded-full bg-primary text-[10px] text-primary-foreground">
|
|
|
|
|
|
E
|
|
|
|
|
|
</span>
|
|
|
|
|
|
ارز دیجیتال
|
|
|
|
|
|
<ChevronDown className="size-3" />
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="mt-3 flex items-center gap-2">
|
|
|
|
|
|
<Button variant="outline" size="sm" className="h-8 gap-1">
|
|
|
|
|
|
<ArrowLeftRight className="size-3.5" />
|
|
|
|
|
|
مبادله
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
<Button variant="outline" size="sm" className="h-8 gap-1">
|
|
|
|
|
|
<ArrowDownRight className="size-3.5" />
|
|
|
|
|
|
خرید
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
<Button variant="outline" size="sm" className="h-8 gap-1">
|
|
|
|
|
|
<ArrowUpRight className="size-3.5" />
|
|
|
|
|
|
ارسال
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="mt-4 flex items-center justify-between text-xs font-medium text-muted-foreground">
|
|
|
|
|
|
<span>داراییهای برتر</span>
|
|
|
|
|
|
<span className="text-primary">مشاهده همه</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="mt-2 space-y-2">
|
|
|
|
|
|
{walletAssets.map((asset) => (
|
|
|
|
|
|
<div
|
|
|
|
|
|
key={asset.symbol}
|
|
|
|
|
|
className="flex items-center justify-between rounded-md px-2 py-1 text-sm hover:bg-accent/50"
|
|
|
|
|
|
>
|
|
|
|
|
|
<div className="flex items-center gap-2">
|
|
|
|
|
|
<TokenBadge item={asset} />
|
|
|
|
|
|
<span>
|
|
|
|
|
|
{asset.name}
|
|
|
|
|
|
<span className="ms-1 text-xs text-muted-foreground">
|
|
|
|
|
|
{asset.symbol}
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<span className="text-xs text-muted-foreground">۰٫۰۰۹۵</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<DropdownMenuSeparator className="my-3" />
|
|
|
|
|
|
<DropdownMenuItem className="flex items-center justify-between">
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<div className="text-sm">تأیید ۲FA</div>
|
|
|
|
|
|
<div className="text-xs text-muted-foreground">
|
|
|
|
|
|
برای امنیت بیشتر ۲FA را فعال کنید
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<span className="rounded-full bg-primary/10 px-2 py-0.5 text-xs text-primary">
|
|
|
|
|
|
تأیید
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</DropdownMenuItem>
|
|
|
|
|
|
<DropdownMenuSeparator />
|
|
|
|
|
|
<DropdownMenuItem>تنظیمات کیف پول</DropdownMenuItem>
|
|
|
|
|
|
<DropdownMenuItem className="text-rose-500">
|
|
|
|
|
|
قطع اتصال کیف پول
|
|
|
|
|
|
</DropdownMenuItem>
|
|
|
|
|
|
<div className="mt-2 text-[11px] text-muted-foreground">
|
|
|
|
|
|
نسخه ۱٫۵٫۶۹ قوانین و مقررات
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</DropdownMenuContent>
|
|
|
|
|
|
</DropdownMenu>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function FavoritesMenu() {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<DropdownMenu>
|
|
|
|
|
|
<DropdownMenuTrigger asChild>
|
|
|
|
|
|
<Button variant="ghost" size="icon" className="rounded-full">
|
|
|
|
|
|
<Star className="size-4" />
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</DropdownMenuTrigger>
|
|
|
|
|
|
<DropdownMenuContent align="start" className="w-80 p-3 text-start">
|
|
|
|
|
|
<div className="flex items-center justify-between text-sm">
|
|
|
|
|
|
<span className="font-medium">علاقهمندیهای من (۴)</span>
|
|
|
|
|
|
<button className="text-xs text-muted-foreground">پاک کردن</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="relative mt-3">
|
|
|
|
|
|
<Search className="pointer-events-none absolute top-1/2 start-2.5 size-3.5 -translate-y-1/2 text-muted-foreground" />
|
|
|
|
|
|
<Input
|
|
|
|
|
|
placeholder="جستجوی توکن..."
|
|
|
|
|
|
className="h-8 ps-8 text-sm"
|
|
|
|
|
|
aria-label="جستجوی توکن"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="mt-3 max-h-56 space-y-2 overflow-auto pe-1">
|
|
|
|
|
|
{favorites.map((token) => (
|
|
|
|
|
|
<div
|
|
|
|
|
|
key={token.symbol}
|
|
|
|
|
|
className="flex items-center justify-between rounded-md px-2 py-1 text-sm hover:bg-accent/50"
|
|
|
|
|
|
>
|
|
|
|
|
|
<div className="flex items-center gap-2">
|
|
|
|
|
|
<TokenBadge item={token} />
|
|
|
|
|
|
<span>
|
|
|
|
|
|
{token.name}
|
|
|
|
|
|
<span className="ms-1 text-xs text-muted-foreground">
|
|
|
|
|
|
{token.symbol}
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<Star className="size-3 text-amber-400" />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</DropdownMenuContent>
|
|
|
|
|
|
</DropdownMenu>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function NotificationsMenu() {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<DropdownMenu>
|
|
|
|
|
|
<DropdownMenuTrigger asChild>
|
|
|
|
|
|
<Button variant="ghost" size="icon" className="rounded-full">
|
|
|
|
|
|
<Bell className="size-4" />
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</DropdownMenuTrigger>
|
|
|
|
|
|
<DropdownMenuContent align="start" className="w-80 p-3 text-start">
|
|
|
|
|
|
<div className="flex items-center justify-between text-sm">
|
|
|
|
|
|
<span className="font-medium">اعلانها</span>
|
|
|
|
|
|
<button className="text-xs text-primary">علامتگذاری همه بهعنوان خواندهشده</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="mt-3 space-y-2">
|
|
|
|
|
|
{notifications.map((item) => (
|
|
|
|
|
|
<div
|
|
|
|
|
|
key={item.title}
|
|
|
|
|
|
className="flex items-start gap-2 rounded-md border border-border px-2 py-2"
|
|
|
|
|
|
>
|
|
|
|
|
|
<span
|
|
|
|
|
|
aria-hidden="true"
|
|
|
|
|
|
className={cn(
|
|
|
|
|
|
"mt-1 flex size-7 items-center justify-center rounded-full bg-accent text-xs",
|
|
|
|
|
|
item.tone,
|
|
|
|
|
|
)}
|
|
|
|
|
|
/>
|
|
|
|
|
|
<div className="flex-1">
|
|
|
|
|
|
<div className="text-sm font-medium text-foreground">
|
|
|
|
|
|
{item.title}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="text-xs text-muted-foreground">
|
|
|
|
|
|
{item.detail}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<span className="text-xs text-muted-foreground">{item.time}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<button className="mt-3 w-full rounded-md border border-border py-1 text-xs text-muted-foreground">
|
|
|
|
|
|
مشاهده همه اعلانها
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</DropdownMenuContent>
|
|
|
|
|
|
</DropdownMenu>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function UserMenu() {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<DropdownMenu>
|
|
|
|
|
|
<DropdownMenuTrigger asChild>
|
|
|
|
|
|
<button className="flex items-center gap-2 rounded-full border border-transparent px-2 py-1 text-sm hover:bg-accent/50">
|
|
|
|
|
|
<Avatar className="size-7">
|
|
|
|
|
|
<AvatarImage src={data.user.avatar} alt={data.user.name} />
|
|
|
|
|
|
<AvatarFallback className="text-xs">
|
|
|
|
|
|
{data.user.name
|
|
|
|
|
|
.split(" ")
|
|
|
|
|
|
.map((part) => part[0])
|
|
|
|
|
|
.join("")}
|
|
|
|
|
|
</AvatarFallback>
|
|
|
|
|
|
</Avatar>
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</DropdownMenuTrigger>
|
|
|
|
|
|
<DropdownMenuContent align="start" className="w-64 p-3 text-start">
|
|
|
|
|
|
<div className="flex items-center gap-3">
|
|
|
|
|
|
<Avatar className="size-9">
|
|
|
|
|
|
<AvatarImage src={data.user.avatar} alt={data.user.name} />
|
|
|
|
|
|
<AvatarFallback className="text-xs">
|
|
|
|
|
|
{data.user.name
|
|
|
|
|
|
.split(" ")
|
|
|
|
|
|
.map((part) => part[0])
|
|
|
|
|
|
.join("")}
|
|
|
|
|
|
</AvatarFallback>
|
|
|
|
|
|
</Avatar>
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<div className="text-sm font-medium text-foreground">
|
|
|
|
|
|
{data.user.name}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="text-xs text-muted-foreground">
|
|
|
|
|
|
{data.user.email}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<DropdownMenuSeparator className="my-2" />
|
|
|
|
|
|
<DropdownMenuItem className="gap-2">
|
|
|
|
|
|
<Moon className="size-4" />
|
|
|
|
|
|
حالت تیره
|
|
|
|
|
|
</DropdownMenuItem>
|
|
|
|
|
|
<DropdownMenuItem className="gap-2">
|
|
|
|
|
|
<Settings className="size-4" />
|
|
|
|
|
|
تنظیمات حساب
|
|
|
|
|
|
</DropdownMenuItem>
|
|
|
|
|
|
<DropdownMenuItem className="gap-2">
|
|
|
|
|
|
<Wallet className="size-4" />
|
|
|
|
|
|
ترجیحها
|
|
|
|
|
|
</DropdownMenuItem>
|
|
|
|
|
|
<DropdownMenuItem className="gap-2">
|
|
|
|
|
|
<HelpCircle className="size-4" />
|
2026-07-15 20:22:14 +02:00
|
|
|
|
راهنمای اعضای تیم
|
2026-07-11 21:21:29 +03:30
|
|
|
|
</DropdownMenuItem>
|
|
|
|
|
|
<DropdownMenuItem className="gap-2">
|
|
|
|
|
|
<Gift className="size-4" />
|
|
|
|
|
|
انجمن
|
|
|
|
|
|
</DropdownMenuItem>
|
|
|
|
|
|
<DropdownMenuSeparator className="my-2" />
|
|
|
|
|
|
<DropdownMenuItem className="gap-2 text-rose-500">
|
|
|
|
|
|
<LogOut className="size-4" />
|
|
|
|
|
|
خروج
|
|
|
|
|
|
</DropdownMenuItem>
|
|
|
|
|
|
<div className="mt-2 text-[11px] text-muted-foreground">
|
|
|
|
|
|
نسخه ۲٫۸٫۶۹ قوانین و مقررات
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</DropdownMenuContent>
|
|
|
|
|
|
</DropdownMenu>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function MobileMenu() {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<Sheet>
|
|
|
|
|
|
<SheetTrigger asChild>
|
|
|
|
|
|
<Button
|
|
|
|
|
|
variant="ghost"
|
|
|
|
|
|
size="icon"
|
|
|
|
|
|
className="md:hidden"
|
|
|
|
|
|
aria-label="باز کردن منو"
|
|
|
|
|
|
>
|
|
|
|
|
|
<Menu className="size-5" />
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</SheetTrigger>
|
|
|
|
|
|
<SheetContent side="right" dir="rtl" className="w-72 p-0 text-start">
|
|
|
|
|
|
<SheetHeader className="px-4 pt-4">
|
|
|
|
|
|
<SheetTitle className="flex items-center gap-2">
|
|
|
|
|
|
<span className="flex size-8 items-center justify-center rounded-full bg-primary/10 text-primary">
|
|
|
|
|
|
<Wallet className="size-4" />
|
|
|
|
|
|
</span>
|
|
|
|
|
|
{data.brand.name}
|
|
|
|
|
|
</SheetTitle>
|
|
|
|
|
|
</SheetHeader>
|
|
|
|
|
|
<ScrollArea className="min-h-0 flex-1">
|
|
|
|
|
|
<div className="flex flex-col gap-2 px-4 py-4">
|
|
|
|
|
|
{navLinks.map((link) => (
|
|
|
|
|
|
<a
|
|
|
|
|
|
key={link.label}
|
|
|
|
|
|
href={link.href}
|
|
|
|
|
|
className={cn(
|
|
|
|
|
|
"rounded-md px-3 py-2 text-sm",
|
|
|
|
|
|
link.isActive
|
|
|
|
|
|
? "bg-accent font-medium"
|
|
|
|
|
|
: "text-muted-foreground hover:bg-accent/50",
|
|
|
|
|
|
)}
|
|
|
|
|
|
>
|
|
|
|
|
|
{link.label}
|
|
|
|
|
|
</a>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="px-4 pb-4">
|
|
|
|
|
|
<WalletMenu />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</ScrollArea>
|
|
|
|
|
|
</SheetContent>
|
|
|
|
|
|
</Sheet>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function BottomNav() {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<nav className="fixed inset-x-0 bottom-0 z-40 border-t border-border bg-background/95 backdrop-blur md:hidden">
|
|
|
|
|
|
<div className="grid grid-cols-4">
|
|
|
|
|
|
{navLinks.map((link) => {
|
|
|
|
|
|
const Icon = link.icon;
|
|
|
|
|
|
return (
|
|
|
|
|
|
<a
|
|
|
|
|
|
key={link.label}
|
|
|
|
|
|
href={link.href}
|
|
|
|
|
|
className={cn(
|
|
|
|
|
|
"flex flex-col items-center gap-1 py-2 text-xs",
|
|
|
|
|
|
link.isActive
|
|
|
|
|
|
? "text-primary"
|
|
|
|
|
|
: "text-muted-foreground hover:text-foreground",
|
|
|
|
|
|
)}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Icon className="size-5" aria-hidden="true" />
|
|
|
|
|
|
<span className="sr-only">{link.label}</span>
|
|
|
|
|
|
<span aria-hidden="true">{link.label}</span>
|
|
|
|
|
|
</a>
|
|
|
|
|
|
);
|
|
|
|
|
|
})}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</nav>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface ApplicationShell14Props {
|
|
|
|
|
|
className?: string;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function ApplicationShell14({ className }: ApplicationShell14Props) {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div
|
|
|
|
|
|
dir="rtl"
|
|
|
|
|
|
lang="fa"
|
|
|
|
|
|
className={cn("min-h-svh bg-background", className)}
|
|
|
|
|
|
>
|
|
|
|
|
|
<div className="min-h-svh w-full bg-background">
|
|
|
|
|
|
<div className="border-b border-border">
|
|
|
|
|
|
<div className="mx-auto w-full max-w-7xl px-4">
|
|
|
|
|
|
<div className="grid grid-cols-[1fr_auto_1fr] items-center gap-3 py-2 text-xs text-muted-foreground">
|
|
|
|
|
|
<div />
|
|
|
|
|
|
<div className="flex flex-wrap items-center justify-center gap-2 text-center">
|
|
|
|
|
|
<Gift className="size-3.5 text-primary" />
|
|
|
|
|
|
<span>
|
2026-07-21 19:25:31 +03:30
|
|
|
|
۲۵ ریال پاداش خوشآمدگویی اولین مبادله را دریافت کنید
|
2026-07-11 21:21:29 +03:30
|
|
|
|
</span>
|
|
|
|
|
|
<button className="text-primary">دریافت کنید</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="flex justify-end">
|
|
|
|
|
|
<button className="text-muted-foreground" aria-label="بستن">
|
|
|
|
|
|
×
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="border-b border-border">
|
|
|
|
|
|
<div className="mx-auto w-full max-w-7xl px-4">
|
|
|
|
|
|
<div className="flex items-center justify-between gap-4 py-3">
|
|
|
|
|
|
<div className="flex items-center gap-2 md:gap-3">
|
|
|
|
|
|
<MobileMenu />
|
|
|
|
|
|
<div className="flex size-9 items-center justify-center rounded-full bg-primary/10 text-primary md:hidden">
|
|
|
|
|
|
<Wallet className="size-4" />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="hidden size-9 items-center justify-center rounded-full bg-primary/10 text-primary md:flex">
|
|
|
|
|
|
<Wallet className="size-5" />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<nav className="hidden items-center gap-1 md:flex">
|
|
|
|
|
|
{navLinks.map((link) => (
|
|
|
|
|
|
<HeaderTab key={link.label} item={link} />
|
|
|
|
|
|
))}
|
|
|
|
|
|
</nav>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="hidden w-full justify-self-center md:block md:max-w-md">
|
|
|
|
|
|
<SearchField />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="flex items-center gap-1 md:gap-2">
|
|
|
|
|
|
<WalletMenu />
|
|
|
|
|
|
<div className="hidden md:block">
|
|
|
|
|
|
<FavoritesMenu />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="hidden md:block">
|
|
|
|
|
|
<NotificationsMenu />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<UserMenu />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="border-b border-border md:hidden">
|
|
|
|
|
|
<div className="mx-auto w-full max-w-7xl px-4 py-3">
|
|
|
|
|
|
<SearchField />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="mx-auto w-full max-w-7xl px-4">
|
|
|
|
|
|
<div className="min-h-[360px]" />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<BottomNav />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|