673 lines
21 KiB
TypeScript
673 lines
21 KiB
TypeScript
"use client";
|
|
|
|
import {
|
|
Baby,
|
|
BadgeCheck,
|
|
Bell,
|
|
ChevronDown,
|
|
ChevronRight,
|
|
Clapperboard,
|
|
Clock,
|
|
CreditCard,
|
|
Download,
|
|
Film,
|
|
Flag,
|
|
HelpCircle,
|
|
History,
|
|
Home,
|
|
ListVideo,
|
|
LogOut,
|
|
type LucideIcon,
|
|
Menu,
|
|
MessageSquare,
|
|
Music,
|
|
Music2,
|
|
PlaySquare,
|
|
Radio,
|
|
Search,
|
|
Settings,
|
|
ShoppingBag,
|
|
Sparkles,
|
|
ThumbsUp,
|
|
} from "lucide-react";
|
|
import * as React from "react";
|
|
|
|
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
|
import { Button } from "@/components/ui/button";
|
|
import {
|
|
Collapsible,
|
|
CollapsibleContent,
|
|
CollapsibleTrigger,
|
|
} from "@/components/ui/collapsible";
|
|
import {
|
|
DropdownMenu,
|
|
DropdownMenuContent,
|
|
DropdownMenuGroup,
|
|
DropdownMenuItem,
|
|
DropdownMenuLabel,
|
|
DropdownMenuSeparator,
|
|
DropdownMenuTrigger,
|
|
} from "@/components/ui/dropdown-menu";
|
|
import {
|
|
InputGroup,
|
|
InputGroupAddon,
|
|
InputGroupInput,
|
|
} from "@/components/ui/input-group";
|
|
import { Kbd } from "@/components/ui/kbd";
|
|
import { ScrollArea } from "@/components/ui/scroll-area";
|
|
import {
|
|
Sidebar,
|
|
SidebarContent,
|
|
SidebarFooter,
|
|
SidebarGroup,
|
|
SidebarGroupLabel,
|
|
SidebarInset,
|
|
SidebarMenu,
|
|
SidebarMenuButton,
|
|
SidebarMenuItem,
|
|
SidebarProvider,
|
|
useSidebar,
|
|
} from "@/components/ui/sidebar";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
function getInitials(name: string) {
|
|
return (
|
|
name
|
|
.split(" ")
|
|
.filter(Boolean)
|
|
.slice(0, 2)
|
|
.map((part) => part[0]?.toUpperCase())
|
|
.join("") || "U"
|
|
);
|
|
}
|
|
|
|
const data = {
|
|
user: {
|
|
name: "علی رضایی",
|
|
email: "ali@example.com",
|
|
avatar:
|
|
"/block-media/shadcnblocks/block/avatar/avatar1.jpg",
|
|
},
|
|
navPrimary: [
|
|
{ title: "خانه", url: "#", icon: Home, isActive: true },
|
|
{ title: "ویدیوهای کوتاه", url: "#", icon: Clapperboard },
|
|
{ title: "اشتراکها", url: "#", icon: PlaySquare },
|
|
{ title: "شما", url: "#", icon: History },
|
|
],
|
|
subscriptions: [
|
|
{ name: "Theo - t3.gg", avatar: "/avatars/theo.jpg", isLive: true },
|
|
{ name: "Fireship", avatar: "/avatars/fireship.jpg", hasNew: true },
|
|
{ name: "Web Dev Simplified", avatar: "/avatars/webdev.jpg" },
|
|
{ name: "Traversy Media", avatar: "/avatars/traversy.jpg", hasNew: true },
|
|
{ name: "The Primeagen", avatar: "/avatars/prime.jpg" },
|
|
{ name: "Jack Herrington", avatar: "/avatars/jack.jpg", hasNew: true },
|
|
{ name: "Coding in Public", avatar: "/avatars/cip.jpg" },
|
|
],
|
|
navYou: [
|
|
{ title: "تاریخچه", url: "#", icon: History },
|
|
{ title: "لیستهای پخش", url: "#", icon: ListVideo },
|
|
{ title: "تماشا بعداً", url: "#", icon: Clock },
|
|
{ title: "ویدیوهای پسندیده", url: "#", icon: ThumbsUp },
|
|
{ title: "ویدیوهای شما", url: "#", icon: PlaySquare },
|
|
{ title: "دانلودها", url: "#", icon: Download },
|
|
],
|
|
navExplore: [
|
|
{ title: "خرید", url: "#", icon: ShoppingBag },
|
|
{ title: "موسیقی", url: "#", icon: Music },
|
|
{ title: "فیلم", url: "#", icon: Film },
|
|
],
|
|
navMoreFrom: [
|
|
{ title: "استودیوی ری یو آی", url: "#", icon: Radio },
|
|
{ title: "موسیقی ری یو آی", url: "#", icon: Music2 },
|
|
{ title: "ری یو آی کودکان", url: "#", icon: Baby },
|
|
],
|
|
navFooter: [
|
|
{ title: "تنظیمات", url: "#", icon: Settings },
|
|
{ title: "تاریخچه گزارش", url: "#", icon: Flag },
|
|
{ title: "راهنما", url: "#", icon: HelpCircle },
|
|
{ title: "ارسال بازخورد", url: "#", icon: MessageSquare },
|
|
],
|
|
};
|
|
|
|
// Primary nav (Home, Shorts, Subscriptions, You)
|
|
function NavPrimary({
|
|
items,
|
|
}: {
|
|
items: { title: string; url: string; icon: LucideIcon; isActive?: boolean }[];
|
|
}) {
|
|
return (
|
|
<SidebarGroup>
|
|
<SidebarMenu>
|
|
{items.map((item) => (
|
|
<SidebarMenuItem key={item.title}>
|
|
<SidebarMenuButton
|
|
asChild
|
|
isActive={item.isActive}
|
|
tooltip={item.title}
|
|
>
|
|
<a href={item.url}>
|
|
<item.icon />
|
|
<span>{item.title}</span>
|
|
</a>
|
|
</SidebarMenuButton>
|
|
</SidebarMenuItem>
|
|
))}
|
|
</SidebarMenu>
|
|
</SidebarGroup>
|
|
);
|
|
}
|
|
|
|
// Subscriptions section with channel avatars
|
|
function NavSubscriptions({
|
|
subscriptions,
|
|
}: {
|
|
subscriptions: {
|
|
name: string;
|
|
avatar: string;
|
|
isLive?: boolean;
|
|
hasNew?: boolean;
|
|
}[];
|
|
}) {
|
|
return (
|
|
<SidebarGroup className="group-data-[collapsible=icon]:hidden">
|
|
<Collapsible defaultOpen>
|
|
<SidebarGroupLabel asChild>
|
|
<CollapsibleTrigger className="group/collapsible flex w-full items-center text-start">
|
|
اشتراکها
|
|
<ChevronRight className="ms-auto transition-transform group-data-[state=open]/collapsible:rotate-90 rtl:rotate-180" />
|
|
</CollapsibleTrigger>
|
|
</SidebarGroupLabel>
|
|
<CollapsibleContent>
|
|
<SidebarMenu>
|
|
{subscriptions.map((channel) => (
|
|
<SidebarMenuItem key={channel.name}>
|
|
<SidebarMenuButton asChild>
|
|
<a href="#">
|
|
<Avatar className="size-6 ring-2 ring-muted">
|
|
<AvatarImage src={channel.avatar} />
|
|
<AvatarFallback className="bg-primary text-xs text-primary-foreground">
|
|
{channel.name[0]}
|
|
</AvatarFallback>
|
|
</Avatar>
|
|
<span className="truncate">{channel.name}</span>
|
|
{channel.isLive && (
|
|
<Radio className="ms-auto size-4 text-red-500" />
|
|
)}
|
|
{channel.hasNew && !channel.isLive && (
|
|
<span className="ms-auto size-2 rounded-full bg-blue-500" />
|
|
)}
|
|
</a>
|
|
</SidebarMenuButton>
|
|
</SidebarMenuItem>
|
|
))}
|
|
<SidebarMenuItem>
|
|
<SidebarMenuButton>
|
|
<ChevronDown className="size-4" />
|
|
<span>نمایش بیشتر</span>
|
|
</SidebarMenuButton>
|
|
</SidebarMenuItem>
|
|
</SidebarMenu>
|
|
</CollapsibleContent>
|
|
</Collapsible>
|
|
</SidebarGroup>
|
|
);
|
|
}
|
|
|
|
// "You" section - History, Playlists, etc.
|
|
function NavYou({
|
|
items,
|
|
}: {
|
|
items: { title: string; url: string; icon: LucideIcon }[];
|
|
}) {
|
|
return (
|
|
<SidebarGroup className="group-data-[collapsible=icon]:hidden">
|
|
<Collapsible defaultOpen>
|
|
<SidebarGroupLabel asChild>
|
|
<CollapsibleTrigger className="group/collapsible flex w-full items-center text-start">
|
|
شما
|
|
<ChevronRight className="ms-auto transition-transform group-data-[state=open]/collapsible:rotate-90 rtl:rotate-180" />
|
|
</CollapsibleTrigger>
|
|
</SidebarGroupLabel>
|
|
<CollapsibleContent>
|
|
<SidebarMenu>
|
|
{items.map((item) => (
|
|
<SidebarMenuItem key={item.title}>
|
|
<SidebarMenuButton asChild>
|
|
<a href={item.url}>
|
|
<item.icon />
|
|
<span>{item.title}</span>
|
|
</a>
|
|
</SidebarMenuButton>
|
|
</SidebarMenuItem>
|
|
))}
|
|
<SidebarMenuItem>
|
|
<SidebarMenuButton>
|
|
<ChevronDown className="size-4" />
|
|
<span>نمایش بیشتر</span>
|
|
</SidebarMenuButton>
|
|
</SidebarMenuItem>
|
|
</SidebarMenu>
|
|
</CollapsibleContent>
|
|
</Collapsible>
|
|
</SidebarGroup>
|
|
);
|
|
}
|
|
|
|
// Explore section - Shopping, Music, Movies
|
|
function NavExplore({
|
|
items,
|
|
}: {
|
|
items: { title: string; url: string; icon: LucideIcon }[];
|
|
}) {
|
|
return (
|
|
<SidebarGroup className="group-data-[collapsible=icon]:hidden">
|
|
<Collapsible defaultOpen>
|
|
<SidebarGroupLabel asChild>
|
|
<CollapsibleTrigger className="group/collapsible flex w-full items-center text-start">
|
|
کاوش
|
|
<ChevronRight className="ms-auto transition-transform group-data-[state=open]/collapsible:rotate-90 rtl:rotate-180" />
|
|
</CollapsibleTrigger>
|
|
</SidebarGroupLabel>
|
|
<CollapsibleContent>
|
|
<SidebarMenu>
|
|
{items.map((item) => (
|
|
<SidebarMenuItem key={item.title}>
|
|
<SidebarMenuButton asChild>
|
|
<a href={item.url}>
|
|
<item.icon />
|
|
<span>{item.title}</span>
|
|
</a>
|
|
</SidebarMenuButton>
|
|
</SidebarMenuItem>
|
|
))}
|
|
<SidebarMenuItem>
|
|
<SidebarMenuButton>
|
|
<ChevronDown className="size-4" />
|
|
<span>نمایش بیشتر</span>
|
|
</SidebarMenuButton>
|
|
</SidebarMenuItem>
|
|
</SidebarMenu>
|
|
</CollapsibleContent>
|
|
</Collapsible>
|
|
</SidebarGroup>
|
|
);
|
|
}
|
|
|
|
// More from Zerotube section
|
|
function NavMoreFrom({
|
|
items,
|
|
}: {
|
|
items: { title: string; url: string; icon: LucideIcon }[];
|
|
}) {
|
|
return (
|
|
<SidebarGroup className="group-data-[collapsible=icon]:hidden">
|
|
<SidebarGroupLabel>بیشتر از ری یو آی</SidebarGroupLabel>
|
|
<SidebarMenu>
|
|
{items.map((item) => (
|
|
<SidebarMenuItem key={item.title}>
|
|
<SidebarMenuButton asChild>
|
|
<a href={item.url}>
|
|
<item.icon />
|
|
<span>{item.title}</span>
|
|
</a>
|
|
</SidebarMenuButton>
|
|
</SidebarMenuItem>
|
|
))}
|
|
</SidebarMenu>
|
|
</SidebarGroup>
|
|
);
|
|
}
|
|
|
|
// Footer nav - Settings, Help, etc.
|
|
function NavFooter({
|
|
items,
|
|
}: {
|
|
items: { title: string; url: string; icon: LucideIcon }[];
|
|
}) {
|
|
return (
|
|
<SidebarGroup className="group-data-[collapsible=icon]:hidden">
|
|
<SidebarMenu>
|
|
{items.map((item) => (
|
|
<SidebarMenuItem key={item.title}>
|
|
<SidebarMenuButton asChild size="sm">
|
|
<a href={item.url}>
|
|
<item.icon />
|
|
<span>{item.title}</span>
|
|
</a>
|
|
</SidebarMenuButton>
|
|
</SidebarMenuItem>
|
|
))}
|
|
</SidebarMenu>
|
|
</SidebarGroup>
|
|
);
|
|
}
|
|
|
|
// Footer links at the very bottom
|
|
function FooterLinks() {
|
|
return (
|
|
<div className="px-4 py-4 text-start text-xs text-muted-foreground">
|
|
<div className="flex flex-wrap gap-x-2 gap-y-1">
|
|
<a href="#" className="hover:underline">
|
|
درباره
|
|
</a>
|
|
<a href="#" className="hover:underline">
|
|
مطبوعات
|
|
</a>
|
|
<a href="#" className="hover:underline">
|
|
حق نشر
|
|
</a>
|
|
<a href="#" className="hover:underline">
|
|
تماس با ما
|
|
</a>
|
|
<a href="#" className="hover:underline">
|
|
سازندگان
|
|
</a>
|
|
<a href="#" className="hover:underline">
|
|
تبلیغات
|
|
</a>
|
|
<a href="#" className="hover:underline">
|
|
توسعهدهندگان
|
|
</a>
|
|
</div>
|
|
<div className="mt-2 flex flex-wrap gap-x-2 gap-y-1">
|
|
<a href="#" className="hover:underline">
|
|
قوانین
|
|
</a>
|
|
<a href="#" className="hover:underline">
|
|
حریم خصوصی
|
|
</a>
|
|
<a href="#" className="hover:underline">
|
|
سیاست و ایمنی
|
|
</a>
|
|
</div>
|
|
<p className="mt-3">© ۱۴۰۴ ری یو آی</p>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function SiteHeader() {
|
|
const { toggleSidebar } = useSidebar();
|
|
|
|
return (
|
|
<header className="fixed top-0 z-50 hidden w-full items-center border-b bg-background md:flex">
|
|
{/* Left: Menu + Logo */}
|
|
<div className="flex h-(--header-height) w-(--sidebar-width-icon) shrink-0 items-center justify-center">
|
|
<Button
|
|
className="size-9"
|
|
variant="ghost"
|
|
size="icon"
|
|
onClick={toggleSidebar}
|
|
aria-label="منو"
|
|
>
|
|
<Menu className="size-5" />
|
|
</Button>
|
|
</div>
|
|
<div className="flex h-(--header-height) items-center pe-4">
|
|
<a href="#" className="flex items-center gap-2">
|
|
<div className="flex size-8 items-center justify-center rounded-sm bg-primary">
|
|
<img
|
|
src="/block-media/shadcnblocks/block/logos/NovaSales-logo.svg"
|
|
alt="شادسیان بلاکس"
|
|
className="size-5 invert dark:invert-0"
|
|
/>
|
|
</div>
|
|
<span className="hidden text-lg font-semibold sm:block">
|
|
ری یو آی
|
|
</span>
|
|
</a>
|
|
</div>
|
|
|
|
{/* Center: Search Bar */}
|
|
<div className="flex flex-1 justify-center px-4">
|
|
<InputGroup className="h-10 max-w-xl rounded-full">
|
|
<InputGroupAddon>
|
|
<Search className="text-muted-foreground" />
|
|
</InputGroupAddon>
|
|
<InputGroupInput placeholder="جستجو" />
|
|
<InputGroupAddon align="inline-end">
|
|
<Kbd>⌘K</Kbd>
|
|
</InputGroupAddon>
|
|
</InputGroup>
|
|
</div>
|
|
|
|
{/* Right: Avatar */}
|
|
<div className="flex h-(--header-height) items-center gap-1 px-4">
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger asChild>
|
|
<Button
|
|
variant="ghost"
|
|
className="flex h-auto items-center gap-2 px-2 py-1"
|
|
>
|
|
<Avatar className="size-8">
|
|
<AvatarImage src={data.user.avatar} alt={data.user.name} />
|
|
<AvatarFallback>{getInitials(data.user.name)}</AvatarFallback>
|
|
</Avatar>
|
|
<span className="hidden font-medium sm:inline">
|
|
{data.user.name}
|
|
</span>
|
|
<ChevronDown className="size-3 text-muted-foreground" />
|
|
</Button>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent className="w-56" align="start">
|
|
<DropdownMenuLabel className="font-normal">
|
|
<div className="flex flex-col space-y-1 text-start">
|
|
<p className="text-sm font-medium">{data.user.name}</p>
|
|
<p className="text-xs text-muted-foreground">
|
|
{data.user.email}
|
|
</p>
|
|
</div>
|
|
</DropdownMenuLabel>
|
|
<DropdownMenuSeparator />
|
|
<DropdownMenuGroup>
|
|
<DropdownMenuItem>
|
|
<Sparkles className="me-2 size-4" />
|
|
ارتقا به نسخه حرفهای
|
|
</DropdownMenuItem>
|
|
</DropdownMenuGroup>
|
|
<DropdownMenuSeparator />
|
|
<DropdownMenuGroup>
|
|
<DropdownMenuItem>
|
|
<BadgeCheck className="me-2 size-4" />
|
|
حساب کاربری
|
|
</DropdownMenuItem>
|
|
<DropdownMenuItem>
|
|
<CreditCard className="me-2 size-4" />
|
|
صورتحساب
|
|
</DropdownMenuItem>
|
|
<DropdownMenuItem>
|
|
<Bell className="me-2 size-4" />
|
|
اعلانها
|
|
</DropdownMenuItem>
|
|
</DropdownMenuGroup>
|
|
<DropdownMenuSeparator />
|
|
<DropdownMenuItem>
|
|
<LogOut className="me-2 size-4" />
|
|
خروج
|
|
</DropdownMenuItem>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
</div>
|
|
</header>
|
|
);
|
|
}
|
|
|
|
function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
|
|
return (
|
|
<Sidebar
|
|
side="right"
|
|
collapsible="icon"
|
|
className="top-(--header-height) hidden h-[calc(100svh-var(--header-height))]! md:flex"
|
|
{...props}
|
|
>
|
|
<SidebarContent className="overflow-hidden">
|
|
<ScrollArea className="min-h-0 flex-1">
|
|
<NavPrimary items={data.navPrimary} />
|
|
<NavSubscriptions subscriptions={data.subscriptions} />
|
|
<NavYou items={data.navYou} />
|
|
<NavExplore items={data.navExplore} />
|
|
<NavMoreFrom items={data.navMoreFrom} />
|
|
<NavFooter items={data.navFooter} />
|
|
</ScrollArea>
|
|
</SidebarContent>
|
|
<SidebarFooter className="group-data-[collapsible=icon]:hidden">
|
|
<FooterLinks />
|
|
</SidebarFooter>
|
|
</Sidebar>
|
|
);
|
|
}
|
|
|
|
export const iframeHeight = "800px";
|
|
|
|
export const description = "سایدبار با هدر و فرم جستجو.";
|
|
|
|
function MobileHeader() {
|
|
return (
|
|
<header className="sticky top-0 z-50 flex h-14 items-center justify-between border-b bg-background px-4 md:hidden">
|
|
<a href="#" className="flex items-center gap-2">
|
|
<div className="flex size-8 items-center justify-center rounded-sm bg-primary">
|
|
<img
|
|
src="/block-media/shadcnblocks/block/logos/NovaSales-logo.svg"
|
|
alt="شادسیان بلاکس"
|
|
className="size-5 invert dark:invert-0"
|
|
/>
|
|
</div>
|
|
<span className="text-lg font-semibold">ری یو آی</span>
|
|
</a>
|
|
<div className="flex items-center gap-1">
|
|
<Button variant="ghost" size="icon" className="size-9" aria-label="جستجو">
|
|
<Search className="size-5" />
|
|
<span className="sr-only">جستجو</span>
|
|
</Button>
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger asChild>
|
|
<Button variant="ghost" size="icon" className="size-9">
|
|
<Avatar className="size-8">
|
|
<AvatarImage src={data.user.avatar} alt={data.user.name} />
|
|
<AvatarFallback>{getInitials(data.user.name)}</AvatarFallback>
|
|
</Avatar>
|
|
</Button>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent className="w-56" align="start">
|
|
<DropdownMenuLabel className="font-normal">
|
|
<div className="flex flex-col space-y-1 text-start">
|
|
<p className="text-sm font-medium">{data.user.name}</p>
|
|
<p className="text-xs text-muted-foreground">
|
|
{data.user.email}
|
|
</p>
|
|
</div>
|
|
</DropdownMenuLabel>
|
|
<DropdownMenuSeparator />
|
|
<DropdownMenuGroup>
|
|
<DropdownMenuItem>
|
|
<Sparkles className="me-2 size-4" />
|
|
ارتقا به نسخه حرفهای
|
|
</DropdownMenuItem>
|
|
</DropdownMenuGroup>
|
|
<DropdownMenuSeparator />
|
|
<DropdownMenuGroup>
|
|
<DropdownMenuItem>
|
|
<BadgeCheck className="me-2 size-4" />
|
|
حساب کاربری
|
|
</DropdownMenuItem>
|
|
<DropdownMenuItem>
|
|
<CreditCard className="me-2 size-4" />
|
|
صورتحساب
|
|
</DropdownMenuItem>
|
|
<DropdownMenuItem>
|
|
<Bell className="me-2 size-4" />
|
|
اعلانها
|
|
</DropdownMenuItem>
|
|
</DropdownMenuGroup>
|
|
<DropdownMenuSeparator />
|
|
<DropdownMenuItem>
|
|
<LogOut className="me-2 size-4" />
|
|
خروج
|
|
</DropdownMenuItem>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
</div>
|
|
</header>
|
|
);
|
|
}
|
|
|
|
function MobileBottomNav() {
|
|
return (
|
|
<nav className="fixed inset-x-0 bottom-0 z-40 border-t bg-background/95 backdrop-blur md:hidden">
|
|
<div className="grid grid-cols-4">
|
|
{data.navPrimary.map((item) => {
|
|
const Icon = item.icon;
|
|
return (
|
|
<button
|
|
key={item.title}
|
|
type="button"
|
|
className={cn(
|
|
"flex flex-col items-center gap-1 py-2 text-xs transition-colors",
|
|
item.isActive
|
|
? "text-foreground"
|
|
: "text-muted-foreground hover:text-foreground",
|
|
)}
|
|
>
|
|
<Icon className="size-5" />
|
|
<span className="sr-only">{item.title}</span>
|
|
<span aria-hidden="true">{item.title}</span>
|
|
</button>
|
|
);
|
|
})}
|
|
</div>
|
|
</nav>
|
|
);
|
|
}
|
|
|
|
function ContentGrid() {
|
|
return (
|
|
<div className="flex flex-1 flex-col gap-4 p-4">
|
|
<div className="grid auto-rows-min gap-4 md:grid-cols-3">
|
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
|
</div>
|
|
<div className="grid auto-rows-min gap-4 md:grid-cols-3">
|
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
|
</div>
|
|
<div className="grid auto-rows-min gap-4 md:grid-cols-3">
|
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function ApplicationShell11() {
|
|
return (
|
|
<div className="w-full [--header-height:calc(--spacing(14))]">
|
|
<SidebarProvider
|
|
dir="rtl"
|
|
lang="fa"
|
|
className="flex flex-col"
|
|
style={{ "--sidebar-width-icon": "3rem" } as React.CSSProperties}
|
|
>
|
|
{/* Desktop layout */}
|
|
<SiteHeader />
|
|
<div className="hidden flex-1 pt-(--header-height) md:flex">
|
|
<AppSidebar />
|
|
<SidebarInset>
|
|
<ContentGrid />
|
|
</SidebarInset>
|
|
</div>
|
|
|
|
{/* Mobile layout */}
|
|
<div className="flex flex-col md:hidden">
|
|
<MobileHeader />
|
|
<div className="pb-16">
|
|
<ContentGrid />
|
|
</div>
|
|
<MobileBottomNav />
|
|
</div>
|
|
</SidebarProvider>
|
|
</div>
|
|
);
|
|
}
|