Initial import of 1407 block sources under blocks/
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,672 @@
|
||||
"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/ShadcnBlocks-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/ShadcnBlocks-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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user