diff --git a/apps/v4/__registry__/index.tsx b/apps/v4/__registry__/index.tsx index 624cf5bfc8..49843dde87 100644 --- a/apps/v4/__registry__/index.tsx +++ b/apps/v4/__registry__/index.tsx @@ -1081,6 +1081,101 @@ export const Index: Record = { }), meta: undefined, }, + "dashboard-01": { + name: "dashboard-01", + description: "A dashboard with sidebar, charts and data table.", + type: "registry:block", + registryDependencies: [ + "sidebar", + "breadcrumb", + "separator", + "label", + "chart", + "card", + "select", + "tabs", + "table", + "toggle-group", + "badge", + "button", + "checkbox", + "dropdown-menu", + "drawer", + "input", + "avatar", + "sheet", + "sonner", + ], + files: [ + { + path: "registry/blocks/dashboard-01/page.tsx", + type: "registry:page", + target: "app/dashboard/page.tsx", + }, + { + path: "registry/blocks/dashboard-01/data.json", + type: "registry:file", + target: "app/dashboard/data.json", + }, + { + path: "registry/blocks/dashboard-01/components/app-sidebar.tsx", + type: "registry:component", + target: "", + }, + { + path: "registry/blocks/dashboard-01/components/chart-area-interactive.tsx", + type: "registry:component", + target: "", + }, + { + path: "registry/blocks/dashboard-01/components/data-table.tsx", + type: "registry:component", + target: "", + }, + { + path: "registry/blocks/dashboard-01/components/nav-documents.tsx", + type: "registry:component", + target: "", + }, + { + path: "registry/blocks/dashboard-01/components/nav-main.tsx", + type: "registry:component", + target: "", + }, + { + path: "registry/blocks/dashboard-01/components/nav-secondary.tsx", + type: "registry:component", + target: "", + }, + { + path: "registry/blocks/dashboard-01/components/nav-user.tsx", + type: "registry:component", + target: "", + }, + { + path: "registry/blocks/dashboard-01/components/section-cards.tsx", + type: "registry:component", + target: "", + }, + { + path: "registry/blocks/dashboard-01/components/site-header.tsx", + type: "registry:component", + target: "", + }, + ], + component: React.lazy(async () => { + const mod = await import( + "@/registry/new-york-v4/blocks/dashboard-01/page.tsx" + ) + const exportName = + Object.keys(mod).find( + (key) => + typeof mod[key] === "function" || typeof mod[key] === "object" + ) || item.name + return { default: mod.default || mod[exportName] } + }), + meta: undefined, + }, "sidebar-01": { name: "sidebar-01", description: "A simple sidebar with navigation grouped by section.", diff --git a/apps/v4/app/(examples)/dashboard/components/section-cards.tsx b/apps/v4/app/(examples)/dashboard/components/section-cards.tsx index f723986c3c..4a69bf5ea8 100644 --- a/apps/v4/app/(examples)/dashboard/components/section-cards.tsx +++ b/apps/v4/app/(examples)/dashboard/components/section-cards.tsx @@ -26,7 +26,7 @@ export function SectionCards() { - +
Trending up this month
diff --git a/apps/v4/public/android-chrome-192x192.png b/apps/v4/public/android-chrome-192x192.png new file mode 100644 index 0000000000..12cf161a08 Binary files /dev/null and b/apps/v4/public/android-chrome-192x192.png differ diff --git a/apps/v4/public/android-chrome-512x512.png b/apps/v4/public/android-chrome-512x512.png new file mode 100644 index 0000000000..5bafcab380 Binary files /dev/null and b/apps/v4/public/android-chrome-512x512.png differ diff --git a/apps/v4/public/apple-touch-icon.png b/apps/v4/public/apple-touch-icon.png new file mode 100644 index 0000000000..10279359cb Binary files /dev/null and b/apps/v4/public/apple-touch-icon.png differ diff --git a/apps/v4/public/favicon-16x16.png b/apps/v4/public/favicon-16x16.png new file mode 100644 index 0000000000..d2ad2370f8 Binary files /dev/null and b/apps/v4/public/favicon-16x16.png differ diff --git a/apps/v4/public/favicon-32x32.png b/apps/v4/public/favicon-32x32.png new file mode 100644 index 0000000000..2aaeed4bb1 Binary files /dev/null and b/apps/v4/public/favicon-32x32.png differ diff --git a/apps/v4/public/favicon.ico b/apps/v4/public/favicon.ico new file mode 100644 index 0000000000..f4f7adbb9f Binary files /dev/null and b/apps/v4/public/favicon.ico differ diff --git a/apps/v4/public/site.webmanifest b/apps/v4/public/site.webmanifest new file mode 100644 index 0000000000..fa99de77db --- /dev/null +++ b/apps/v4/public/site.webmanifest @@ -0,0 +1,19 @@ +{ + "name": "", + "short_name": "", + "icons": [ + { + "src": "/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} diff --git a/apps/v4/registry.json b/apps/v4/registry.json index b330ecdc62..3a094cc01b 100644 --- a/apps/v4/registry.json +++ b/apps/v4/registry.json @@ -716,6 +716,92 @@ } ] }, + { + "name": "dashboard-01", + "type": "registry:block", + "description": "A dashboard with sidebar, charts and data table.", + "dependencies": [ + "@dnd-kit/core", + "@dnd-kit/modifiers", + "@dnd-kit/sortable", + "@dnd-kit/utilities", + "@tanstack/react-table", + "zod", + "@tabler/icons-react" + ], + "registryDependencies": [ + "sidebar", + "breadcrumb", + "separator", + "label", + "chart", + "card", + "select", + "tabs", + "table", + "toggle-group", + "badge", + "button", + "checkbox", + "dropdown-menu", + "drawer", + "input", + "avatar", + "sheet", + "sonner" + ], + "files": [ + { + "path": "registry/new-york-v4/blocks/dashboard-01/page.tsx", + "type": "registry:page", + "target": "app/dashboard/page.tsx" + }, + { + "path": "registry/new-york-v4/blocks/dashboard-01/data.json", + "type": "registry:file", + "target": "app/dashboard/data.json" + }, + { + "path": "registry/new-york-v4/blocks/dashboard-01/components/app-sidebar.tsx", + "type": "registry:component" + }, + { + "path": "registry/new-york-v4/blocks/dashboard-01/components/chart-area-interactive.tsx", + "type": "registry:component" + }, + { + "path": "registry/new-york-v4/blocks/dashboard-01/components/data-table.tsx", + "type": "registry:component" + }, + { + "path": "registry/new-york-v4/blocks/dashboard-01/components/nav-documents.tsx", + "type": "registry:component" + }, + { + "path": "registry/new-york-v4/blocks/dashboard-01/components/nav-main.tsx", + "type": "registry:component" + }, + { + "path": "registry/new-york-v4/blocks/dashboard-01/components/nav-secondary.tsx", + "type": "registry:component" + }, + { + "path": "registry/new-york-v4/blocks/dashboard-01/components/nav-user.tsx", + "type": "registry:component" + }, + { + "path": "registry/new-york-v4/blocks/dashboard-01/components/section-cards.tsx", + "type": "registry:component" + }, + { + "path": "registry/new-york-v4/blocks/dashboard-01/components/site-header.tsx", + "type": "registry:component" + } + ], + "categories": [ + "dashboard" + ] + }, { "name": "sidebar-01", "type": "registry:block", diff --git a/apps/v4/registry/new-york-v4/blocks/dashboard-01/components/app-sidebar.tsx b/apps/v4/registry/new-york-v4/blocks/dashboard-01/components/app-sidebar.tsx new file mode 100644 index 0000000000..ef40779e51 --- /dev/null +++ b/apps/v4/registry/new-york-v4/blocks/dashboard-01/components/app-sidebar.tsx @@ -0,0 +1,181 @@ +"use client" + +import * as React from "react" +import { + IconCamera, + IconChartBar, + IconDashboard, + IconDatabase, + IconFileAi, + IconFileDescription, + IconFileWord, + IconFolder, + IconHelp, + IconInnerShadowTop, + IconListDetails, + IconReport, + IconSearch, + IconSettings, + IconUsers, +} from "@tabler/icons-react" + +import { NavDocuments } from "@/registry/new-york-v4/blocks/dashboard-01/components/nav-documents" +import { NavMain } from "@/registry/new-york-v4/blocks/dashboard-01/components/nav-main" +import { NavSecondary } from "@/registry/new-york-v4/blocks/dashboard-01/components/nav-secondary" +import { NavUser } from "@/registry/new-york-v4/blocks/dashboard-01/components/nav-user" +import { + Sidebar, + SidebarContent, + SidebarFooter, + SidebarHeader, + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, +} from "@/registry/new-york-v4/ui/sidebar" + +const data = { + user: { + name: "shadcn", + email: "m@example.com", + avatar: "/avatars/shadcn.jpg", + }, + navMain: [ + { + title: "Dashboard", + url: "#", + icon: IconDashboard, + }, + { + title: "Lifecycle", + url: "#", + icon: IconListDetails, + }, + { + title: "Analytics", + url: "#", + icon: IconChartBar, + }, + { + title: "Projects", + url: "#", + icon: IconFolder, + }, + { + title: "Team", + url: "#", + icon: IconUsers, + }, + ], + navClouds: [ + { + title: "Capture", + icon: IconCamera, + isActive: true, + url: "#", + items: [ + { + title: "Active Proposals", + url: "#", + }, + { + title: "Archived", + url: "#", + }, + ], + }, + { + title: "Proposal", + icon: IconFileDescription, + url: "#", + items: [ + { + title: "Active Proposals", + url: "#", + }, + { + title: "Archived", + url: "#", + }, + ], + }, + { + title: "Prompts", + icon: IconFileAi, + url: "#", + items: [ + { + title: "Active Proposals", + url: "#", + }, + { + title: "Archived", + url: "#", + }, + ], + }, + ], + navSecondary: [ + { + title: "Settings", + url: "#", + icon: IconSettings, + }, + { + title: "Get Help", + url: "#", + icon: IconHelp, + }, + { + title: "Search", + url: "#", + icon: IconSearch, + }, + ], + documents: [ + { + name: "Data Library", + url: "#", + icon: IconDatabase, + }, + { + name: "Reports", + url: "#", + icon: IconReport, + }, + { + name: "Word Assistant", + url: "#", + icon: IconFileWord, + }, + ], +} + +export function AppSidebar({ ...props }: React.ComponentProps) { + return ( + + + + + + + + Acme Inc. + + + + + + + + + + + + + + + ) +} diff --git a/apps/v4/registry/new-york-v4/blocks/dashboard-01/components/chart-area-interactive.tsx b/apps/v4/registry/new-york-v4/blocks/dashboard-01/components/chart-area-interactive.tsx new file mode 100644 index 0000000000..dab596a813 --- /dev/null +++ b/apps/v4/registry/new-york-v4/blocks/dashboard-01/components/chart-area-interactive.tsx @@ -0,0 +1,292 @@ +"use client" + +import * as React from "react" +import { Area, AreaChart, CartesianGrid, XAxis } from "recharts" + +import { useIsMobile } from "@/registry/new-york-v4/hooks/use-mobile" +import { + Card, + CardAction, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from "@/registry/new-york-v4/ui/card" +import { + ChartConfig, + ChartContainer, + ChartTooltip, + ChartTooltipContent, +} from "@/registry/new-york-v4/ui/chart" +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/registry/new-york-v4/ui/select" +import { + ToggleGroup, + ToggleGroupItem, +} from "@/registry/new-york-v4/ui/toggle-group" + +export const description = "An interactive area chart" + +const chartData = [ + { date: "2024-04-01", desktop: 222, mobile: 150 }, + { date: "2024-04-02", desktop: 97, mobile: 180 }, + { date: "2024-04-03", desktop: 167, mobile: 120 }, + { date: "2024-04-04", desktop: 242, mobile: 260 }, + { date: "2024-04-05", desktop: 373, mobile: 290 }, + { date: "2024-04-06", desktop: 301, mobile: 340 }, + { date: "2024-04-07", desktop: 245, mobile: 180 }, + { date: "2024-04-08", desktop: 409, mobile: 320 }, + { date: "2024-04-09", desktop: 59, mobile: 110 }, + { date: "2024-04-10", desktop: 261, mobile: 190 }, + { date: "2024-04-11", desktop: 327, mobile: 350 }, + { date: "2024-04-12", desktop: 292, mobile: 210 }, + { date: "2024-04-13", desktop: 342, mobile: 380 }, + { date: "2024-04-14", desktop: 137, mobile: 220 }, + { date: "2024-04-15", desktop: 120, mobile: 170 }, + { date: "2024-04-16", desktop: 138, mobile: 190 }, + { date: "2024-04-17", desktop: 446, mobile: 360 }, + { date: "2024-04-18", desktop: 364, mobile: 410 }, + { date: "2024-04-19", desktop: 243, mobile: 180 }, + { date: "2024-04-20", desktop: 89, mobile: 150 }, + { date: "2024-04-21", desktop: 137, mobile: 200 }, + { date: "2024-04-22", desktop: 224, mobile: 170 }, + { date: "2024-04-23", desktop: 138, mobile: 230 }, + { date: "2024-04-24", desktop: 387, mobile: 290 }, + { date: "2024-04-25", desktop: 215, mobile: 250 }, + { date: "2024-04-26", desktop: 75, mobile: 130 }, + { date: "2024-04-27", desktop: 383, mobile: 420 }, + { date: "2024-04-28", desktop: 122, mobile: 180 }, + { date: "2024-04-29", desktop: 315, mobile: 240 }, + { date: "2024-04-30", desktop: 454, mobile: 380 }, + { date: "2024-05-01", desktop: 165, mobile: 220 }, + { date: "2024-05-02", desktop: 293, mobile: 310 }, + { date: "2024-05-03", desktop: 247, mobile: 190 }, + { date: "2024-05-04", desktop: 385, mobile: 420 }, + { date: "2024-05-05", desktop: 481, mobile: 390 }, + { date: "2024-05-06", desktop: 498, mobile: 520 }, + { date: "2024-05-07", desktop: 388, mobile: 300 }, + { date: "2024-05-08", desktop: 149, mobile: 210 }, + { date: "2024-05-09", desktop: 227, mobile: 180 }, + { date: "2024-05-10", desktop: 293, mobile: 330 }, + { date: "2024-05-11", desktop: 335, mobile: 270 }, + { date: "2024-05-12", desktop: 197, mobile: 240 }, + { date: "2024-05-13", desktop: 197, mobile: 160 }, + { date: "2024-05-14", desktop: 448, mobile: 490 }, + { date: "2024-05-15", desktop: 473, mobile: 380 }, + { date: "2024-05-16", desktop: 338, mobile: 400 }, + { date: "2024-05-17", desktop: 499, mobile: 420 }, + { date: "2024-05-18", desktop: 315, mobile: 350 }, + { date: "2024-05-19", desktop: 235, mobile: 180 }, + { date: "2024-05-20", desktop: 177, mobile: 230 }, + { date: "2024-05-21", desktop: 82, mobile: 140 }, + { date: "2024-05-22", desktop: 81, mobile: 120 }, + { date: "2024-05-23", desktop: 252, mobile: 290 }, + { date: "2024-05-24", desktop: 294, mobile: 220 }, + { date: "2024-05-25", desktop: 201, mobile: 250 }, + { date: "2024-05-26", desktop: 213, mobile: 170 }, + { date: "2024-05-27", desktop: 420, mobile: 460 }, + { date: "2024-05-28", desktop: 233, mobile: 190 }, + { date: "2024-05-29", desktop: 78, mobile: 130 }, + { date: "2024-05-30", desktop: 340, mobile: 280 }, + { date: "2024-05-31", desktop: 178, mobile: 230 }, + { date: "2024-06-01", desktop: 178, mobile: 200 }, + { date: "2024-06-02", desktop: 470, mobile: 410 }, + { date: "2024-06-03", desktop: 103, mobile: 160 }, + { date: "2024-06-04", desktop: 439, mobile: 380 }, + { date: "2024-06-05", desktop: 88, mobile: 140 }, + { date: "2024-06-06", desktop: 294, mobile: 250 }, + { date: "2024-06-07", desktop: 323, mobile: 370 }, + { date: "2024-06-08", desktop: 385, mobile: 320 }, + { date: "2024-06-09", desktop: 438, mobile: 480 }, + { date: "2024-06-10", desktop: 155, mobile: 200 }, + { date: "2024-06-11", desktop: 92, mobile: 150 }, + { date: "2024-06-12", desktop: 492, mobile: 420 }, + { date: "2024-06-13", desktop: 81, mobile: 130 }, + { date: "2024-06-14", desktop: 426, mobile: 380 }, + { date: "2024-06-15", desktop: 307, mobile: 350 }, + { date: "2024-06-16", desktop: 371, mobile: 310 }, + { date: "2024-06-17", desktop: 475, mobile: 520 }, + { date: "2024-06-18", desktop: 107, mobile: 170 }, + { date: "2024-06-19", desktop: 341, mobile: 290 }, + { date: "2024-06-20", desktop: 408, mobile: 450 }, + { date: "2024-06-21", desktop: 169, mobile: 210 }, + { date: "2024-06-22", desktop: 317, mobile: 270 }, + { date: "2024-06-23", desktop: 480, mobile: 530 }, + { date: "2024-06-24", desktop: 132, mobile: 180 }, + { date: "2024-06-25", desktop: 141, mobile: 190 }, + { date: "2024-06-26", desktop: 434, mobile: 380 }, + { date: "2024-06-27", desktop: 448, mobile: 490 }, + { date: "2024-06-28", desktop: 149, mobile: 200 }, + { date: "2024-06-29", desktop: 103, mobile: 160 }, + { date: "2024-06-30", desktop: 446, mobile: 400 }, +] + +const chartConfig = { + visitors: { + label: "Visitors", + }, + desktop: { + label: "Desktop", + color: "var(--primary)", + }, + mobile: { + label: "Mobile", + color: "var(--primary)", + }, +} satisfies ChartConfig + +export function ChartAreaInteractive() { + const isMobile = useIsMobile() + const [timeRange, setTimeRange] = React.useState("90d") + + React.useEffect(() => { + if (isMobile) { + setTimeRange("7d") + } + }, [isMobile]) + + const filteredData = chartData.filter((item) => { + const date = new Date(item.date) + const referenceDate = new Date("2024-06-30") + let daysToSubtract = 90 + if (timeRange === "30d") { + daysToSubtract = 30 + } else if (timeRange === "7d") { + daysToSubtract = 7 + } + const startDate = new Date(referenceDate) + startDate.setDate(startDate.getDate() - daysToSubtract) + return date >= startDate + }) + + return ( + + + Total Visitors + + + Total for the last 3 months + + Last 3 months + + + + Last 3 months + Last 30 days + Last 7 days + + + + + + + + + + + + + + + + + + + { + const date = new Date(value) + return date.toLocaleDateString("en-US", { + month: "short", + day: "numeric", + }) + }} + /> + { + return new Date(value).toLocaleDateString("en-US", { + month: "short", + day: "numeric", + }) + }} + indicator="dot" + /> + } + /> + + + + + + + ) +} diff --git a/apps/v4/registry/new-york-v4/blocks/dashboard-01/components/data-table.tsx b/apps/v4/registry/new-york-v4/blocks/dashboard-01/components/data-table.tsx new file mode 100644 index 0000000000..857d769d5e --- /dev/null +++ b/apps/v4/registry/new-york-v4/blocks/dashboard-01/components/data-table.tsx @@ -0,0 +1,807 @@ +"use client" + +import * as React from "react" +import { + DndContext, + KeyboardSensor, + MouseSensor, + TouchSensor, + closestCenter, + useSensor, + useSensors, + type DragEndEvent, + type UniqueIdentifier, +} from "@dnd-kit/core" +import { restrictToVerticalAxis } from "@dnd-kit/modifiers" +import { + SortableContext, + arrayMove, + useSortable, + verticalListSortingStrategy, +} from "@dnd-kit/sortable" +import { CSS } from "@dnd-kit/utilities" +import { + IconChevronDown, + IconChevronLeft, + IconChevronRight, + IconChevronsLeft, + IconChevronsRight, + IconCircleCheckFilled, + IconDotsVertical, + IconGripVertical, + IconLayoutColumns, + IconLoader, + IconPlus, + IconTrendingUp, +} from "@tabler/icons-react" +import { + ColumnDef, + ColumnFiltersState, + Row, + SortingState, + VisibilityState, + flexRender, + getCoreRowModel, + getFacetedRowModel, + getFacetedUniqueValues, + getFilteredRowModel, + getPaginationRowModel, + getSortedRowModel, + useReactTable, +} from "@tanstack/react-table" +import { Area, AreaChart, CartesianGrid, XAxis } from "recharts" +import { toast } from "sonner" +import { z } from "zod" + +import { useIsMobile } from "@/registry/new-york-v4/hooks/use-mobile" +import { Badge } from "@/registry/new-york-v4/ui/badge" +import { Button } from "@/registry/new-york-v4/ui/button" +import { + ChartConfig, + ChartContainer, + ChartTooltip, + ChartTooltipContent, +} from "@/registry/new-york-v4/ui/chart" +import { Checkbox } from "@/registry/new-york-v4/ui/checkbox" +import { + Drawer, + DrawerClose, + DrawerContent, + DrawerDescription, + DrawerFooter, + DrawerHeader, + DrawerTitle, + DrawerTrigger, +} from "@/registry/new-york-v4/ui/drawer" +import { + DropdownMenu, + DropdownMenuCheckboxItem, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "@/registry/new-york-v4/ui/dropdown-menu" +import { Input } from "@/registry/new-york-v4/ui/input" +import { Label } from "@/registry/new-york-v4/ui/label" +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/registry/new-york-v4/ui/select" +import { Separator } from "@/registry/new-york-v4/ui/separator" +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/registry/new-york-v4/ui/table" +import { + Tabs, + TabsContent, + TabsList, + TabsTrigger, +} from "@/registry/new-york-v4/ui/tabs" + +export const schema = z.object({ + id: z.number(), + header: z.string(), + type: z.string(), + status: z.string(), + target: z.string(), + limit: z.string(), + reviewer: z.string(), +}) + +// Create a separate component for the drag handle +function DragHandle({ id }: { id: number }) { + const { attributes, listeners } = useSortable({ + id, + }) + + return ( + + ) +} + +const columns: ColumnDef>[] = [ + { + id: "drag", + header: () => null, + cell: ({ row }) => , + }, + { + id: "select", + header: ({ table }) => ( +
+ table.toggleAllPageRowsSelected(!!value)} + aria-label="Select all" + /> +
+ ), + cell: ({ row }) => ( +
+ row.toggleSelected(!!value)} + aria-label="Select row" + /> +
+ ), + enableSorting: false, + enableHiding: false, + }, + { + accessorKey: "header", + header: "Header", + cell: ({ row }) => { + return + }, + enableHiding: false, + }, + { + accessorKey: "type", + header: "Section Type", + cell: ({ row }) => ( +
+ + {row.original.type} + +
+ ), + }, + { + accessorKey: "status", + header: "Status", + cell: ({ row }) => ( + + {row.original.status === "Done" ? ( + + ) : ( + + )} + {row.original.status} + + ), + }, + { + accessorKey: "target", + header: () =>
Target
, + cell: ({ row }) => ( +
{ + e.preventDefault() + toast.promise(new Promise((resolve) => setTimeout(resolve, 1000)), { + loading: `Saving ${row.original.header}`, + success: "Done", + error: "Error", + }) + }} + > + + +
+ ), + }, + { + accessorKey: "limit", + header: () =>
Limit
, + cell: ({ row }) => ( +
{ + e.preventDefault() + toast.promise(new Promise((resolve) => setTimeout(resolve, 1000)), { + loading: `Saving ${row.original.header}`, + success: "Done", + error: "Error", + }) + }} + > + + +
+ ), + }, + { + accessorKey: "reviewer", + header: "Reviewer", + cell: ({ row }) => { + const isAssigned = row.original.reviewer !== "Assign reviewer" + + if (isAssigned) { + return row.original.reviewer + } + + return ( + <> + + + + ) + }, + }, + { + id: "actions", + cell: () => ( + + + + + + Edit + Make a copy + Favorite + + Delete + + + ), + }, +] + +function DraggableRow({ row }: { row: Row> }) { + const { transform, transition, setNodeRef, isDragging } = useSortable({ + id: row.original.id, + }) + + return ( + + {row.getVisibleCells().map((cell) => ( + + {flexRender(cell.column.columnDef.cell, cell.getContext())} + + ))} + + ) +} + +export function DataTable({ + data: initialData, +}: { + data: z.infer[] +}) { + const [data, setData] = React.useState(() => initialData) + const [rowSelection, setRowSelection] = React.useState({}) + const [columnVisibility, setColumnVisibility] = + React.useState({}) + const [columnFilters, setColumnFilters] = React.useState( + [] + ) + const [sorting, setSorting] = React.useState([]) + const [pagination, setPagination] = React.useState({ + pageIndex: 0, + pageSize: 10, + }) + const sortableId = React.useId() + const sensors = useSensors( + useSensor(MouseSensor, {}), + useSensor(TouchSensor, {}), + useSensor(KeyboardSensor, {}) + ) + + const dataIds = React.useMemo( + () => data?.map(({ id }) => id) || [], + [data] + ) + + const table = useReactTable({ + data, + columns, + state: { + sorting, + columnVisibility, + rowSelection, + columnFilters, + pagination, + }, + getRowId: (row) => row.id.toString(), + enableRowSelection: true, + onRowSelectionChange: setRowSelection, + onSortingChange: setSorting, + onColumnFiltersChange: setColumnFilters, + onColumnVisibilityChange: setColumnVisibility, + onPaginationChange: setPagination, + getCoreRowModel: getCoreRowModel(), + getFilteredRowModel: getFilteredRowModel(), + getPaginationRowModel: getPaginationRowModel(), + getSortedRowModel: getSortedRowModel(), + getFacetedRowModel: getFacetedRowModel(), + getFacetedUniqueValues: getFacetedUniqueValues(), + }) + + function handleDragEnd(event: DragEndEvent) { + const { active, over } = event + if (active && over && active.id !== over.id) { + setData((data) => { + const oldIndex = dataIds.indexOf(active.id) + const newIndex = dataIds.indexOf(over.id) + return arrayMove(data, oldIndex, newIndex) + }) + } + } + + return ( + +
+ + + + Outline + + Past Performance 3 + + + Key Personnel 2 + + Focus Documents + +
+ + + + + + {table + .getAllColumns() + .filter( + (column) => + typeof column.accessorFn !== "undefined" && + column.getCanHide() + ) + .map((column) => { + return ( + + column.toggleVisibility(!!value) + } + > + {column.id} + + ) + })} + + + +
+
+ +
+ + + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => { + return ( + + {header.isPlaceholder + ? null + : flexRender( + header.column.columnDef.header, + header.getContext() + )} + + ) + })} + + ))} + + + {table.getRowModel().rows?.length ? ( + + {table.getRowModel().rows.map((row) => ( + + ))} + + ) : ( + + + No results. + + + )} + +
+
+
+
+
+ {table.getFilteredSelectedRowModel().rows.length} of{" "} + {table.getFilteredRowModel().rows.length} row(s) selected. +
+
+
+ + +
+
+ Page {table.getState().pagination.pageIndex + 1} of{" "} + {table.getPageCount()} +
+
+ + + + +
+
+
+
+ +
+
+ +
+
+ +
+
+
+ ) +} + +const chartData = [ + { month: "January", desktop: 186, mobile: 80 }, + { month: "February", desktop: 305, mobile: 200 }, + { month: "March", desktop: 237, mobile: 120 }, + { month: "April", desktop: 73, mobile: 190 }, + { month: "May", desktop: 209, mobile: 130 }, + { month: "June", desktop: 214, mobile: 140 }, +] + +const chartConfig = { + desktop: { + label: "Desktop", + color: "var(--primary)", + }, + mobile: { + label: "Mobile", + color: "var(--primary)", + }, +} satisfies ChartConfig + +function TableCellViewer({ item }: { item: z.infer }) { + const isMobile = useIsMobile() + + return ( + + + + + + + {item.header} + + Showing total visitors for the last 6 months + + +
+ {!isMobile && ( + <> + + + + value.slice(0, 3)} + hide + /> + } + /> + + + + + +
+
+ Trending up by 5.2% this month{" "} + +
+
+ Showing total visitors for the last 6 months. This is just + some random text to test the layout. It spans multiple lines + and should wrap around. +
+
+ + + )} +
+
+ + +
+
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+
+ + +
+
+
+ + + + + + +
+
+ ) +} diff --git a/apps/v4/registry/new-york-v4/blocks/dashboard-01/components/nav-documents.tsx b/apps/v4/registry/new-york-v4/blocks/dashboard-01/components/nav-documents.tsx new file mode 100644 index 0000000000..503c59938a --- /dev/null +++ b/apps/v4/registry/new-york-v4/blocks/dashboard-01/components/nav-documents.tsx @@ -0,0 +1,92 @@ +"use client" + +import { + IconDots, + IconFolder, + IconShare3, + IconTrash, + type Icon, +} from "@tabler/icons-react" + +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "@/registry/new-york-v4/ui/dropdown-menu" +import { + SidebarGroup, + SidebarGroupLabel, + SidebarMenu, + SidebarMenuAction, + SidebarMenuButton, + SidebarMenuItem, + useSidebar, +} from "@/registry/new-york-v4/ui/sidebar" + +export function NavDocuments({ + items, +}: { + items: { + name: string + url: string + icon: Icon + }[] +}) { + const { isMobile } = useSidebar() + + return ( + + Documents + + {items.map((item) => ( + + + + + {item.name} + + + + + + + More + + + + + + Open + + + + Share + + + + + Delete + + + + + ))} + + + + More + + + + + ) +} diff --git a/apps/v4/registry/new-york-v4/blocks/dashboard-01/components/nav-main.tsx b/apps/v4/registry/new-york-v4/blocks/dashboard-01/components/nav-main.tsx new file mode 100644 index 0000000000..79ffb5cd6e --- /dev/null +++ b/apps/v4/registry/new-york-v4/blocks/dashboard-01/components/nav-main.tsx @@ -0,0 +1,58 @@ +"use client" + +import { IconCirclePlusFilled, IconMail, type Icon } from "@tabler/icons-react" + +import { Button } from "@/registry/new-york-v4/ui/button" +import { + SidebarGroup, + SidebarGroupContent, + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, +} from "@/registry/new-york-v4/ui/sidebar" + +export function NavMain({ + items, +}: { + items: { + title: string + url: string + icon?: Icon + }[] +}) { + return ( + + + + + + + Quick Create + + + + + + {items.map((item) => ( + + + {item.icon && } + {item.title} + + + ))} + + + + ) +} diff --git a/apps/v4/registry/new-york-v4/blocks/dashboard-01/components/nav-secondary.tsx b/apps/v4/registry/new-york-v4/blocks/dashboard-01/components/nav-secondary.tsx new file mode 100644 index 0000000000..c4f2ea77e6 --- /dev/null +++ b/apps/v4/registry/new-york-v4/blocks/dashboard-01/components/nav-secondary.tsx @@ -0,0 +1,42 @@ +"use client" + +import * as React from "react" +import { type Icon } from "@tabler/icons-react" + +import { + SidebarGroup, + SidebarGroupContent, + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, +} from "@/registry/new-york-v4/ui/sidebar" + +export function NavSecondary({ + items, + ...props +}: { + items: { + title: string + url: string + icon: Icon + }[] +} & React.ComponentPropsWithoutRef) { + return ( + + + + {items.map((item) => ( + + + + + {item.title} + + + + ))} + + + + ) +} diff --git a/apps/v4/registry/new-york-v4/blocks/dashboard-01/components/nav-user.tsx b/apps/v4/registry/new-york-v4/blocks/dashboard-01/components/nav-user.tsx new file mode 100644 index 0000000000..4d63e06cf8 --- /dev/null +++ b/apps/v4/registry/new-york-v4/blocks/dashboard-01/components/nav-user.tsx @@ -0,0 +1,110 @@ +"use client" + +import { + IconCreditCard, + IconDotsVertical, + IconLogout, + IconNotification, + IconUserCircle, +} from "@tabler/icons-react" + +import { + Avatar, + AvatarFallback, + AvatarImage, +} from "@/registry/new-york-v4/ui/avatar" +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuGroup, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "@/registry/new-york-v4/ui/dropdown-menu" +import { + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, + useSidebar, +} from "@/registry/new-york-v4/ui/sidebar" + +export function NavUser({ + user, +}: { + user: { + name: string + email: string + avatar: string + } +}) { + const { isMobile } = useSidebar() + + return ( + + + + + + + + CN + +
+ {user.name} + + {user.email} + +
+ +
+
+ + +
+ + + CN + +
+ {user.name} + + {user.email} + +
+
+
+ + + + + Account + + + + Billing + + + + Notifications + + + + + + Log out + +
+
+
+
+ ) +} diff --git a/apps/v4/registry/new-york-v4/blocks/dashboard-01/components/section-cards.tsx b/apps/v4/registry/new-york-v4/blocks/dashboard-01/components/section-cards.tsx new file mode 100644 index 0000000000..4a69bf5ea8 --- /dev/null +++ b/apps/v4/registry/new-york-v4/blocks/dashboard-01/components/section-cards.tsx @@ -0,0 +1,102 @@ +import { IconTrendingDown, IconTrendingUp } from "@tabler/icons-react" + +import { Badge } from "@/registry/new-york-v4/ui/badge" +import { + Card, + CardAction, + CardDescription, + CardFooter, + CardHeader, + CardTitle, +} from "@/registry/new-york-v4/ui/card" + +export function SectionCards() { + return ( +
+ + + Total Revenue + + $1,250.00 + + + + + +12.5% + + + + +
+ Trending up this month +
+
+ Visitors for the last 6 months +
+
+
+ + + New Customers + + 1,234 + + + + + -20% + + + + +
+ Down 20% this period +
+
+ Acquisition needs attention +
+
+
+ + + Active Accounts + + 45,678 + + + + + +12.5% + + + + +
+ Strong user retention +
+
Engagement exceed targets
+
+
+ + + Growth Rate + + 4.5% + + + + + +4.5% + + + + +
+ Steady performance increase +
+
Meets growth projections
+
+
+
+ ) +} diff --git a/apps/v4/registry/new-york-v4/blocks/dashboard-01/components/site-header.tsx b/apps/v4/registry/new-york-v4/blocks/dashboard-01/components/site-header.tsx new file mode 100644 index 0000000000..dd4210d31c --- /dev/null +++ b/apps/v4/registry/new-york-v4/blocks/dashboard-01/components/site-header.tsx @@ -0,0 +1,30 @@ +import { Button } from "@/registry/new-york-v4/ui/button" +import { Separator } from "@/registry/new-york-v4/ui/separator" +import { SidebarTrigger } from "@/registry/new-york-v4/ui/sidebar" + +export function SiteHeader() { + return ( +
+
+ + +

Documents

+
+ +
+
+
+ ) +} diff --git a/apps/v4/registry/new-york-v4/blocks/dashboard-01/data.json b/apps/v4/registry/new-york-v4/blocks/dashboard-01/data.json new file mode 100644 index 0000000000..ec0873641b --- /dev/null +++ b/apps/v4/registry/new-york-v4/blocks/dashboard-01/data.json @@ -0,0 +1,614 @@ +[ + { + "id": 1, + "header": "Cover page", + "type": "Cover page", + "status": "In Process", + "target": "18", + "limit": "5", + "reviewer": "Eddie Lake" + }, + { + "id": 2, + "header": "Table of contents", + "type": "Table of contents", + "status": "Done", + "target": "29", + "limit": "24", + "reviewer": "Eddie Lake" + }, + { + "id": 3, + "header": "Executive summary", + "type": "Narrative", + "status": "Done", + "target": "10", + "limit": "13", + "reviewer": "Eddie Lake" + }, + { + "id": 4, + "header": "Technical approach", + "type": "Narrative", + "status": "Done", + "target": "27", + "limit": "23", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 5, + "header": "Design", + "type": "Narrative", + "status": "In Process", + "target": "2", + "limit": "16", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 6, + "header": "Capabilities", + "type": "Narrative", + "status": "In Process", + "target": "20", + "limit": "8", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 7, + "header": "Integration with existing systems", + "type": "Narrative", + "status": "In Process", + "target": "19", + "limit": "21", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 8, + "header": "Innovation and Advantages", + "type": "Narrative", + "status": "Done", + "target": "25", + "limit": "26", + "reviewer": "Assign reviewer" + }, + { + "id": 9, + "header": "Overview of EMR's Innovative Solutions", + "type": "Technical content", + "status": "Done", + "target": "7", + "limit": "23", + "reviewer": "Assign reviewer" + }, + { + "id": 10, + "header": "Advanced Algorithms and Machine Learning", + "type": "Narrative", + "status": "Done", + "target": "30", + "limit": "28", + "reviewer": "Assign reviewer" + }, + { + "id": 11, + "header": "Adaptive Communication Protocols", + "type": "Narrative", + "status": "Done", + "target": "9", + "limit": "31", + "reviewer": "Assign reviewer" + }, + { + "id": 12, + "header": "Advantages Over Current Technologies", + "type": "Narrative", + "status": "Done", + "target": "12", + "limit": "0", + "reviewer": "Assign reviewer" + }, + { + "id": 13, + "header": "Past Performance", + "type": "Narrative", + "status": "Done", + "target": "22", + "limit": "33", + "reviewer": "Assign reviewer" + }, + { + "id": 14, + "header": "Customer Feedback and Satisfaction Levels", + "type": "Narrative", + "status": "Done", + "target": "15", + "limit": "34", + "reviewer": "Assign reviewer" + }, + { + "id": 15, + "header": "Implementation Challenges and Solutions", + "type": "Narrative", + "status": "Done", + "target": "3", + "limit": "35", + "reviewer": "Assign reviewer" + }, + { + "id": 16, + "header": "Security Measures and Data Protection Policies", + "type": "Narrative", + "status": "In Process", + "target": "6", + "limit": "36", + "reviewer": "Assign reviewer" + }, + { + "id": 17, + "header": "Scalability and Future Proofing", + "type": "Narrative", + "status": "Done", + "target": "4", + "limit": "37", + "reviewer": "Assign reviewer" + }, + { + "id": 18, + "header": "Cost-Benefit Analysis", + "type": "Plain language", + "status": "Done", + "target": "14", + "limit": "38", + "reviewer": "Assign reviewer" + }, + { + "id": 19, + "header": "User Training and Onboarding Experience", + "type": "Narrative", + "status": "Done", + "target": "17", + "limit": "39", + "reviewer": "Assign reviewer" + }, + { + "id": 20, + "header": "Future Development Roadmap", + "type": "Narrative", + "status": "Done", + "target": "11", + "limit": "40", + "reviewer": "Assign reviewer" + }, + { + "id": 21, + "header": "System Architecture Overview", + "type": "Technical content", + "status": "In Process", + "target": "24", + "limit": "18", + "reviewer": "Maya Johnson" + }, + { + "id": 22, + "header": "Risk Management Plan", + "type": "Narrative", + "status": "Done", + "target": "15", + "limit": "22", + "reviewer": "Carlos Rodriguez" + }, + { + "id": 23, + "header": "Compliance Documentation", + "type": "Legal", + "status": "In Process", + "target": "31", + "limit": "27", + "reviewer": "Sarah Chen" + }, + { + "id": 24, + "header": "API Documentation", + "type": "Technical content", + "status": "Done", + "target": "8", + "limit": "12", + "reviewer": "Raj Patel" + }, + { + "id": 25, + "header": "User Interface Mockups", + "type": "Visual", + "status": "In Process", + "target": "19", + "limit": "25", + "reviewer": "Leila Ahmadi" + }, + { + "id": 26, + "header": "Database Schema", + "type": "Technical content", + "status": "Done", + "target": "22", + "limit": "20", + "reviewer": "Thomas Wilson" + }, + { + "id": 27, + "header": "Testing Methodology", + "type": "Technical content", + "status": "In Process", + "target": "17", + "limit": "14", + "reviewer": "Assign reviewer" + }, + { + "id": 28, + "header": "Deployment Strategy", + "type": "Narrative", + "status": "Done", + "target": "26", + "limit": "30", + "reviewer": "Eddie Lake" + }, + { + "id": 29, + "header": "Budget Breakdown", + "type": "Financial", + "status": "In Process", + "target": "13", + "limit": "16", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 30, + "header": "Market Analysis", + "type": "Research", + "status": "Done", + "target": "29", + "limit": "32", + "reviewer": "Sophia Martinez" + }, + { + "id": 31, + "header": "Competitor Comparison", + "type": "Research", + "status": "In Process", + "target": "21", + "limit": "19", + "reviewer": "Assign reviewer" + }, + { + "id": 32, + "header": "Maintenance Plan", + "type": "Technical content", + "status": "Done", + "target": "16", + "limit": "23", + "reviewer": "Alex Thompson" + }, + { + "id": 33, + "header": "User Personas", + "type": "Research", + "status": "In Process", + "target": "27", + "limit": "24", + "reviewer": "Nina Patel" + }, + { + "id": 34, + "header": "Accessibility Compliance", + "type": "Legal", + "status": "Done", + "target": "18", + "limit": "21", + "reviewer": "Assign reviewer" + }, + { + "id": 35, + "header": "Performance Metrics", + "type": "Technical content", + "status": "In Process", + "target": "23", + "limit": "26", + "reviewer": "David Kim" + }, + { + "id": 36, + "header": "Disaster Recovery Plan", + "type": "Technical content", + "status": "Done", + "target": "14", + "limit": "17", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 37, + "header": "Third-party Integrations", + "type": "Technical content", + "status": "In Process", + "target": "25", + "limit": "28", + "reviewer": "Eddie Lake" + }, + { + "id": 38, + "header": "User Feedback Summary", + "type": "Research", + "status": "Done", + "target": "20", + "limit": "15", + "reviewer": "Assign reviewer" + }, + { + "id": 39, + "header": "Localization Strategy", + "type": "Narrative", + "status": "In Process", + "target": "12", + "limit": "19", + "reviewer": "Maria Garcia" + }, + { + "id": 40, + "header": "Mobile Compatibility", + "type": "Technical content", + "status": "Done", + "target": "28", + "limit": "31", + "reviewer": "James Wilson" + }, + { + "id": 41, + "header": "Data Migration Plan", + "type": "Technical content", + "status": "In Process", + "target": "19", + "limit": "22", + "reviewer": "Assign reviewer" + }, + { + "id": 42, + "header": "Quality Assurance Protocols", + "type": "Technical content", + "status": "Done", + "target": "30", + "limit": "33", + "reviewer": "Priya Singh" + }, + { + "id": 43, + "header": "Stakeholder Analysis", + "type": "Research", + "status": "In Process", + "target": "11", + "limit": "14", + "reviewer": "Eddie Lake" + }, + { + "id": 44, + "header": "Environmental Impact Assessment", + "type": "Research", + "status": "Done", + "target": "24", + "limit": "27", + "reviewer": "Assign reviewer" + }, + { + "id": 45, + "header": "Intellectual Property Rights", + "type": "Legal", + "status": "In Process", + "target": "17", + "limit": "20", + "reviewer": "Sarah Johnson" + }, + { + "id": 46, + "header": "Customer Support Framework", + "type": "Narrative", + "status": "Done", + "target": "22", + "limit": "25", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 47, + "header": "Version Control Strategy", + "type": "Technical content", + "status": "In Process", + "target": "15", + "limit": "18", + "reviewer": "Assign reviewer" + }, + { + "id": 48, + "header": "Continuous Integration Pipeline", + "type": "Technical content", + "status": "Done", + "target": "26", + "limit": "29", + "reviewer": "Michael Chen" + }, + { + "id": 49, + "header": "Regulatory Compliance", + "type": "Legal", + "status": "In Process", + "target": "13", + "limit": "16", + "reviewer": "Assign reviewer" + }, + { + "id": 50, + "header": "User Authentication System", + "type": "Technical content", + "status": "Done", + "target": "28", + "limit": "31", + "reviewer": "Eddie Lake" + }, + { + "id": 51, + "header": "Data Analytics Framework", + "type": "Technical content", + "status": "In Process", + "target": "21", + "limit": "24", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 52, + "header": "Cloud Infrastructure", + "type": "Technical content", + "status": "Done", + "target": "16", + "limit": "19", + "reviewer": "Assign reviewer" + }, + { + "id": 53, + "header": "Network Security Measures", + "type": "Technical content", + "status": "In Process", + "target": "29", + "limit": "32", + "reviewer": "Lisa Wong" + }, + { + "id": 54, + "header": "Project Timeline", + "type": "Planning", + "status": "Done", + "target": "14", + "limit": "17", + "reviewer": "Eddie Lake" + }, + { + "id": 55, + "header": "Resource Allocation", + "type": "Planning", + "status": "In Process", + "target": "27", + "limit": "30", + "reviewer": "Assign reviewer" + }, + { + "id": 56, + "header": "Team Structure and Roles", + "type": "Planning", + "status": "Done", + "target": "20", + "limit": "23", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 57, + "header": "Communication Protocols", + "type": "Planning", + "status": "In Process", + "target": "15", + "limit": "18", + "reviewer": "Assign reviewer" + }, + { + "id": 58, + "header": "Success Metrics", + "type": "Planning", + "status": "Done", + "target": "30", + "limit": "33", + "reviewer": "Eddie Lake" + }, + { + "id": 59, + "header": "Internationalization Support", + "type": "Technical content", + "status": "In Process", + "target": "23", + "limit": "26", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 60, + "header": "Backup and Recovery Procedures", + "type": "Technical content", + "status": "Done", + "target": "18", + "limit": "21", + "reviewer": "Assign reviewer" + }, + { + "id": 61, + "header": "Monitoring and Alerting System", + "type": "Technical content", + "status": "In Process", + "target": "25", + "limit": "28", + "reviewer": "Daniel Park" + }, + { + "id": 62, + "header": "Code Review Guidelines", + "type": "Technical content", + "status": "Done", + "target": "12", + "limit": "15", + "reviewer": "Eddie Lake" + }, + { + "id": 63, + "header": "Documentation Standards", + "type": "Technical content", + "status": "In Process", + "target": "27", + "limit": "30", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 64, + "header": "Release Management Process", + "type": "Planning", + "status": "Done", + "target": "22", + "limit": "25", + "reviewer": "Assign reviewer" + }, + { + "id": 65, + "header": "Feature Prioritization Matrix", + "type": "Planning", + "status": "In Process", + "target": "19", + "limit": "22", + "reviewer": "Emma Davis" + }, + { + "id": 66, + "header": "Technical Debt Assessment", + "type": "Technical content", + "status": "Done", + "target": "24", + "limit": "27", + "reviewer": "Eddie Lake" + }, + { + "id": 67, + "header": "Capacity Planning", + "type": "Planning", + "status": "In Process", + "target": "21", + "limit": "24", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 68, + "header": "Service Level Agreements", + "type": "Legal", + "status": "Done", + "target": "26", + "limit": "29", + "reviewer": "Assign reviewer" + } +] diff --git a/apps/v4/registry/new-york-v4/blocks/dashboard-01/page.tsx b/apps/v4/registry/new-york-v4/blocks/dashboard-01/page.tsx new file mode 100644 index 0000000000..c936e0c06d --- /dev/null +++ b/apps/v4/registry/new-york-v4/blocks/dashboard-01/page.tsx @@ -0,0 +1,40 @@ +import { AppSidebar } from "@/registry/new-york-v4/blocks/dashboard-01/components/app-sidebar" +import { ChartAreaInteractive } from "@/registry/new-york-v4/blocks/dashboard-01/components/chart-area-interactive" +import { DataTable } from "@/registry/new-york-v4/blocks/dashboard-01/components/data-table" +import { SectionCards } from "@/registry/new-york-v4/blocks/dashboard-01/components/section-cards" +import { SiteHeader } from "@/registry/new-york-v4/blocks/dashboard-01/components/site-header" +import { + SidebarInset, + SidebarProvider, +} from "@/registry/new-york-v4/ui/sidebar" + +import data from "./data.json" + +export default function Page() { + return ( + + + + +
+
+
+ +
+ +
+ +
+
+
+
+
+ ) +} diff --git a/apps/v4/scripts/build-registry.mts b/apps/v4/scripts/build-registry.mts index 4af9071c0c..7eeb8ed6a0 100644 --- a/apps/v4/scripts/build-registry.mts +++ b/apps/v4/scripts/build-registry.mts @@ -74,9 +74,17 @@ const registry = { }, ], }, - ].filter((item) => { - return !DEPRECATED_ITEMS.includes(item.name) - }) + ] + .filter((item) => { + return !DEPRECATED_ITEMS.includes(item.name) + }) + .map((item) => { + // Temporary fix for dashboard-01. + if (item.name === "dashboard-01") { + item.dependencies?.push("@tabler/icons-react") + } + return item + }) ), } satisfies Registry diff --git a/apps/www/__registry__/default/blocks/dashboard-01/page.tsx b/apps/www/__registry__/default/blocks/dashboard-01/page.tsx new file mode 100644 index 0000000000..083e2a7f01 --- /dev/null +++ b/apps/www/__registry__/default/blocks/dashboard-01/page.tsx @@ -0,0 +1,30 @@ +import { AppSidebar } from "@/registry/default/blocks/dashboard-01/components/app-sidebar" +import { ChartAreaInteractive } from "@/registry/default/blocks/dashboard-01/components/chart-area-interactive" +import { DataTable } from "@/registry/default/blocks/dashboard-01/components/data-table" +import { SectionCards } from "@/registry/default/blocks/dashboard-01/components/section-cards" +import { SiteHeader } from "@/registry/default/blocks/dashboard-01/components/site-header" +import { SidebarInset, SidebarProvider } from "@/registry/default/ui/sidebar" + +import data from "./data.json" + +export default function Page() { + return ( + + + + +
+
+
+ +
+ +
+ +
+
+
+
+
+ ) +} diff --git a/apps/www/__registry__/index.tsx b/apps/www/__registry__/index.tsx index 5f33147abd..21f232da8a 100644 --- a/apps/www/__registry__/index.tsx +++ b/apps/www/__registry__/index.tsx @@ -718,6 +718,61 @@ export const Index: Record = { source: "", meta: undefined, }, + "dashboard-01": { + name: "dashboard-01", + description: "A dashboard with sidebar, charts and data table.", + type: "registry:block", + registryDependencies: ["sidebar","breadcrumb","separator","label","chart","card","select","tabs","table","toggle-group","badge","button","checkbox","dropdown-menu","drawer","input","avatar","sheet","sonner"], + files: [{ + path: "registry/new-york/blocks/dashboard-01/page.tsx", + type: "registry:page", + target: "app/dashboard/page.tsx" + },{ + path: "registry/new-york/blocks/dashboard-01/data.json", + type: "registry:file", + target: "app/dashboard/data.json" + },{ + path: "registry/new-york/blocks/dashboard-01/components/app-sidebar.tsx", + type: "registry:component", + target: "" + },{ + path: "registry/new-york/blocks/dashboard-01/components/chart-area-interactive.tsx", + type: "registry:component", + target: "" + },{ + path: "registry/new-york/blocks/dashboard-01/components/data-table.tsx", + type: "registry:component", + target: "" + },{ + path: "registry/new-york/blocks/dashboard-01/components/nav-documents.tsx", + type: "registry:component", + target: "" + },{ + path: "registry/new-york/blocks/dashboard-01/components/nav-main.tsx", + type: "registry:component", + target: "" + },{ + path: "registry/new-york/blocks/dashboard-01/components/nav-secondary.tsx", + type: "registry:component", + target: "" + },{ + path: "registry/new-york/blocks/dashboard-01/components/nav-user.tsx", + type: "registry:component", + target: "" + },{ + path: "registry/new-york/blocks/dashboard-01/components/section-cards.tsx", + type: "registry:component", + target: "" + },{ + path: "registry/new-york/blocks/dashboard-01/components/site-header.tsx", + type: "registry:component", + target: "" + }], + categories: ["dashboard"], + component: React.lazy(() => import("@/registry/new-york/blocks/dashboard-01/page.tsx")), + source: "__registry__/new-york/blocks/dashboard-01/page.tsx", + meta: undefined, + }, "sidebar-01": { name: "sidebar-01", description: "A simple sidebar with navigation grouped by section.", @@ -6016,6 +6071,61 @@ export const Index: Record = { source: "", meta: undefined, }, + "dashboard-01": { + name: "dashboard-01", + description: "A dashboard with sidebar, charts and data table.", + type: "registry:block", + registryDependencies: ["sidebar","breadcrumb","separator","label","chart","card","select","tabs","table","toggle-group","badge","button","checkbox","dropdown-menu","drawer","input","avatar","sheet","sonner"], + files: [{ + path: "registry/default/blocks/dashboard-01/page.tsx", + type: "registry:page", + target: "app/dashboard/page.tsx" + },{ + path: "registry/default/blocks/dashboard-01/data.json", + type: "registry:file", + target: "app/dashboard/data.json" + },{ + path: "registry/default/blocks/dashboard-01/components/app-sidebar.tsx", + type: "registry:component", + target: "" + },{ + path: "registry/default/blocks/dashboard-01/components/chart-area-interactive.tsx", + type: "registry:component", + target: "" + },{ + path: "registry/default/blocks/dashboard-01/components/data-table.tsx", + type: "registry:component", + target: "" + },{ + path: "registry/default/blocks/dashboard-01/components/nav-documents.tsx", + type: "registry:component", + target: "" + },{ + path: "registry/default/blocks/dashboard-01/components/nav-main.tsx", + type: "registry:component", + target: "" + },{ + path: "registry/default/blocks/dashboard-01/components/nav-secondary.tsx", + type: "registry:component", + target: "" + },{ + path: "registry/default/blocks/dashboard-01/components/nav-user.tsx", + type: "registry:component", + target: "" + },{ + path: "registry/default/blocks/dashboard-01/components/section-cards.tsx", + type: "registry:component", + target: "" + },{ + path: "registry/default/blocks/dashboard-01/components/site-header.tsx", + type: "registry:component", + target: "" + }], + categories: ["dashboard"], + component: React.lazy(() => import("@/registry/default/blocks/dashboard-01/page.tsx")), + source: "__registry__/default/blocks/dashboard-01/page.tsx", + meta: undefined, + }, "sidebar-01": { name: "sidebar-01", description: "A simple sidebar with navigation grouped by section.", diff --git a/apps/www/__registry__/new-york/blocks/dashboard-01/page.tsx b/apps/www/__registry__/new-york/blocks/dashboard-01/page.tsx new file mode 100644 index 0000000000..e5602a4af1 --- /dev/null +++ b/apps/www/__registry__/new-york/blocks/dashboard-01/page.tsx @@ -0,0 +1,30 @@ +import { AppSidebar } from "@/registry/new-york/blocks/dashboard-01/components/app-sidebar" +import { ChartAreaInteractive } from "@/registry/new-york/blocks/dashboard-01/components/chart-area-interactive" +import { DataTable } from "@/registry/new-york/blocks/dashboard-01/components/data-table" +import { SectionCards } from "@/registry/new-york/blocks/dashboard-01/components/section-cards" +import { SiteHeader } from "@/registry/new-york/blocks/dashboard-01/components/site-header" +import { SidebarInset, SidebarProvider } from "@/registry/new-york/ui/sidebar" + +import data from "./data.json" + +export default function Page() { + return ( + + + + +
+
+
+ +
+ +
+ +
+
+
+
+
+ ) +} diff --git a/apps/www/actions/edit-in-v0.ts b/apps/www/actions/edit-in-v0.ts index ca10b12654..98caeffa6f 100644 --- a/apps/www/actions/edit-in-v0.ts +++ b/apps/www/actions/edit-in-v0.ts @@ -6,6 +6,8 @@ import { capitalCase } from "change-case" import { getRegistryItem } from "@/lib/registry" import { Style } from "@/registry/registry-styles" +const TAILWIND_CONFIG_BLOCKS = ["dashboard-01"] + export async function editInV0({ name, style, @@ -48,6 +50,15 @@ export async function editInV0({ return file }) + if (TAILWIND_CONFIG_BLOCKS.includes(name)) { + registryItem.files?.push({ + path: "tailwind.config.js", + type: "registry:file", + target: "tailwind.config.js", + content: TAILWIND_CONFIG, + }) + } + const payload = { version: 2, payload: registryItem, @@ -95,3 +106,93 @@ export async function editInV0({ } } } + +const TAILWIND_CONFIG = `const { fontFamily } = require("tailwindcss/defaultTheme") + +/** @type {import('tailwindcss').Config} */ +module.exports = { + darkMode: ["class"], + content: ["app/**/*.{ts,tsx}", "components/**/*.{ts,tsx}"], + theme: { + extend: { + fontFamily: { + sans: ["var(--font-geist-sans)", ...fontFamily.sans], + mono: ["var(--font-geist-mono)", ...fontFamily.mono], + }, + colors: { + border: "hsl(var(--border))", + input: "hsl(var(--input))", + ring: "hsl(var(--ring))", + background: "hsl(var(--background))", + foreground: "hsl(var(--foreground))", + primary: { + DEFAULT: "hsl(var(--primary))", + foreground: "hsl(var(--primary-foreground))", + }, + secondary: { + DEFAULT: "hsl(var(--secondary))", + foreground: "hsl(var(--secondary-foreground))", + }, + destructive: { + DEFAULT: "hsl(var(--destructive) / )", + foreground: "hsl(var(--destructive-foreground) / )", + }, + muted: { + DEFAULT: "hsl(var(--muted))", + foreground: "hsl(var(--muted-foreground))", + }, + accent: { + DEFAULT: "hsl(var(--accent))", + foreground: "hsl(var(--accent-foreground))", + }, + popover: { + DEFAULT: "hsl(var(--popover))", + foreground: "hsl(var(--popover-foreground))", + }, + card: { + DEFAULT: "hsl(var(--card))", + foreground: "hsl(var(--card-foreground))", + }, + sidebar: { + DEFAULT: "hsl(var(--sidebar-background))", + foreground: "hsl(var(--sidebar-foreground))", + primary: "hsl(var(--sidebar-primary))", + "primary-foreground": "hsl(var(--sidebar-primary-foreground))", + accent: "hsl(var(--sidebar-accent))", + "accent-foreground": "hsl(var(--sidebar-accent-foreground))", + border: "hsl(var(--sidebar-border))", + ring: "hsl(var(--sidebar-ring))", + }, + }, + borderRadius: { + xl: "calc(var(--radius) + 4px)", + lg: "var(--radius)", + md: "calc(var(--radius) - 2px)", + sm: "calc(var(--radius) - 4px)", + }, + keyframes: { + "accordion-down": { + from: { height: "0" }, + to: { height: "var(--radix-accordion-content-height)" }, + }, + "accordion-up": { + from: { height: "var(--radix-accordion-content-height)" }, + to: { height: "0" }, + }, + "caret-blink": { + "0%,70%,100%": { opacity: "1" }, + "20%,50%": { opacity: "0" }, + }, + }, + animation: { + "accordion-down": "accordion-down 0.2s ease-out", + "accordion-up": "accordion-up 0.2s ease-out", + "caret-blink": "caret-blink 1.25s ease-out infinite", + }, + }, + }, + plugins: [ + require("tailwindcss-animate"), + require("@tailwindcss/container-queries"), + ], +}` diff --git a/apps/www/app/(app)/blocks/page.tsx b/apps/www/app/(app)/blocks/page.tsx index 9e5a5544cf..199985bf68 100644 --- a/apps/www/app/(app)/blocks/page.tsx +++ b/apps/www/app/(app)/blocks/page.tsx @@ -3,7 +3,13 @@ import Link from "next/link" import { BlockDisplay } from "@/components/block-display" import { Button } from "@/registry/new-york/ui/button" -const FEATURED_BLOCKS = ["sidebar-07", "sidebar-03", "login-03", "login-04"] +const FEATURED_BLOCKS = [ + "dashboard-01", + "sidebar-07", + "sidebar-03", + "login-03", + "login-04", +] export default async function BlocksPage() { return ( diff --git a/apps/www/package.json b/apps/www/package.json index 10ce6e2034..9a7917b2cd 100644 --- a/apps/www/package.json +++ b/apps/www/package.json @@ -20,6 +20,10 @@ "format:check": "prettier --check \"**/*.{ts,tsx,mdx}\" --cache" }, "dependencies": { + "@dnd-kit/core": "^6.3.1", + "@dnd-kit/modifiers": "^9.0.0", + "@dnd-kit/sortable": "^10.0.0", + "@dnd-kit/utilities": "^3.2.2", "@emotion/is-prop-valid": "^1.3.1", "@faker-js/faker": "^8.2.0", "@hookform/resolvers": "^3.1.0", @@ -53,6 +57,7 @@ "@radix-ui/react-toggle": "^1.0.3", "@radix-ui/react-toggle-group": "^1.0.4", "@radix-ui/react-tooltip": "^1.0.6", + "@tailwindcss/container-queries": "^0.1.1", "@tanstack/react-table": "^8.9.1", "@vercel/analytics": "^1.2.2", "@vercel/og": "^0.0.21", diff --git a/apps/www/public/r/styles/default/dashboard-01.json b/apps/www/public/r/styles/default/dashboard-01.json new file mode 100644 index 0000000000..9bde5db6e6 --- /dev/null +++ b/apps/www/public/r/styles/default/dashboard-01.json @@ -0,0 +1,107 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "dashboard-01", + "type": "registry:block", + "author": "shadcn (https://ui.shadcn.com)", + "description": "A dashboard with sidebar, charts and data table.", + "dependencies": [ + "@dnd-kit/core", + "@dnd-kit/modifiers", + "@dnd-kit/sortable", + "@dnd-kit/utilities", + "@tanstack/react-table", + "zod" + ], + "registryDependencies": [ + "sidebar", + "breadcrumb", + "separator", + "label", + "chart", + "card", + "select", + "tabs", + "table", + "toggle-group", + "badge", + "button", + "checkbox", + "dropdown-menu", + "drawer", + "input", + "avatar", + "sheet", + "sonner" + ], + "files": [ + { + "path": "blocks/dashboard-01/page.tsx", + "content": "import { AppSidebar } from \"@/registry/default/blocks/dashboard-01/components/app-sidebar\"\nimport { ChartAreaInteractive } from \"@/registry/default/blocks/dashboard-01/components/chart-area-interactive\"\nimport { DataTable } from \"@/registry/default/blocks/dashboard-01/components/data-table\"\nimport { SectionCards } from \"@/registry/default/blocks/dashboard-01/components/section-cards\"\nimport { SiteHeader } from \"@/registry/default/blocks/dashboard-01/components/site-header\"\nimport { SidebarInset, SidebarProvider } from \"@/registry/default/ui/sidebar\"\n\nimport data from \"./data.json\"\n\nexport default function Page() {\n return (\n \n \n \n \n
\n
\n
\n \n
\n \n
\n \n
\n
\n
\n
\n
\n )\n}\n", + "type": "registry:page", + "target": "app/dashboard/page.tsx" + }, + { + "path": "blocks/dashboard-01/data.json", + "content": "[\n {\n \"id\": 1,\n \"header\": \"Cover page\",\n \"type\": \"Cover page\",\n \"status\": \"In Process\",\n \"target\": \"18\",\n \"limit\": \"5\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 2,\n \"header\": \"Table of contents\",\n \"type\": \"Table of contents\",\n \"status\": \"Done\",\n \"target\": \"29\",\n \"limit\": \"24\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 3,\n \"header\": \"Executive summary\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"10\",\n \"limit\": \"13\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 4,\n \"header\": \"Technical approach\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"27\",\n \"limit\": \"23\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 5,\n \"header\": \"Design\",\n \"type\": \"Narrative\",\n \"status\": \"In Process\",\n \"target\": \"2\",\n \"limit\": \"16\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 6,\n \"header\": \"Capabilities\",\n \"type\": \"Narrative\",\n \"status\": \"In Process\",\n \"target\": \"20\",\n \"limit\": \"8\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 7,\n \"header\": \"Integration with existing systems\",\n \"type\": \"Narrative\",\n \"status\": \"In Process\",\n \"target\": \"19\",\n \"limit\": \"21\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 8,\n \"header\": \"Innovation and Advantages\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"25\",\n \"limit\": \"26\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 9,\n \"header\": \"Overview of EMR's Innovative Solutions\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"7\",\n \"limit\": \"23\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 10,\n \"header\": \"Advanced Algorithms and Machine Learning\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"30\",\n \"limit\": \"28\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 11,\n \"header\": \"Adaptive Communication Protocols\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"9\",\n \"limit\": \"31\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 12,\n \"header\": \"Advantages Over Current Technologies\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"12\",\n \"limit\": \"0\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 13,\n \"header\": \"Past Performance\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"22\",\n \"limit\": \"33\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 14,\n \"header\": \"Customer Feedback and Satisfaction Levels\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"15\",\n \"limit\": \"34\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 15,\n \"header\": \"Implementation Challenges and Solutions\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"3\",\n \"limit\": \"35\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 16,\n \"header\": \"Security Measures and Data Protection Policies\",\n \"type\": \"Narrative\",\n \"status\": \"In Process\",\n \"target\": \"6\",\n \"limit\": \"36\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 17,\n \"header\": \"Scalability and Future Proofing\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"4\",\n \"limit\": \"37\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 18,\n \"header\": \"Cost-Benefit Analysis\",\n \"type\": \"Plain language\",\n \"status\": \"Done\",\n \"target\": \"14\",\n \"limit\": \"38\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 19,\n \"header\": \"User Training and Onboarding Experience\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"17\",\n \"limit\": \"39\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 20,\n \"header\": \"Future Development Roadmap\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"11\",\n \"limit\": \"40\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 21,\n \"header\": \"System Architecture Overview\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"24\",\n \"limit\": \"18\",\n \"reviewer\": \"Maya Johnson\"\n },\n {\n \"id\": 22,\n \"header\": \"Risk Management Plan\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"15\",\n \"limit\": \"22\",\n \"reviewer\": \"Carlos Rodriguez\"\n },\n {\n \"id\": 23,\n \"header\": \"Compliance Documentation\",\n \"type\": \"Legal\",\n \"status\": \"In Process\",\n \"target\": \"31\",\n \"limit\": \"27\",\n \"reviewer\": \"Sarah Chen\"\n },\n {\n \"id\": 24,\n \"header\": \"API Documentation\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"8\",\n \"limit\": \"12\",\n \"reviewer\": \"Raj Patel\"\n },\n {\n \"id\": 25,\n \"header\": \"User Interface Mockups\",\n \"type\": \"Visual\",\n \"status\": \"In Process\",\n \"target\": \"19\",\n \"limit\": \"25\",\n \"reviewer\": \"Leila Ahmadi\"\n },\n {\n \"id\": 26,\n \"header\": \"Database Schema\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"22\",\n \"limit\": \"20\",\n \"reviewer\": \"Thomas Wilson\"\n },\n {\n \"id\": 27,\n \"header\": \"Testing Methodology\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"17\",\n \"limit\": \"14\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 28,\n \"header\": \"Deployment Strategy\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"26\",\n \"limit\": \"30\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 29,\n \"header\": \"Budget Breakdown\",\n \"type\": \"Financial\",\n \"status\": \"In Process\",\n \"target\": \"13\",\n \"limit\": \"16\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 30,\n \"header\": \"Market Analysis\",\n \"type\": \"Research\",\n \"status\": \"Done\",\n \"target\": \"29\",\n \"limit\": \"32\",\n \"reviewer\": \"Sophia Martinez\"\n },\n {\n \"id\": 31,\n \"header\": \"Competitor Comparison\",\n \"type\": \"Research\",\n \"status\": \"In Process\",\n \"target\": \"21\",\n \"limit\": \"19\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 32,\n \"header\": \"Maintenance Plan\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"16\",\n \"limit\": \"23\",\n \"reviewer\": \"Alex Thompson\"\n },\n {\n \"id\": 33,\n \"header\": \"User Personas\",\n \"type\": \"Research\",\n \"status\": \"In Process\",\n \"target\": \"27\",\n \"limit\": \"24\",\n \"reviewer\": \"Nina Patel\"\n },\n {\n \"id\": 34,\n \"header\": \"Accessibility Compliance\",\n \"type\": \"Legal\",\n \"status\": \"Done\",\n \"target\": \"18\",\n \"limit\": \"21\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 35,\n \"header\": \"Performance Metrics\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"23\",\n \"limit\": \"26\",\n \"reviewer\": \"David Kim\"\n },\n {\n \"id\": 36,\n \"header\": \"Disaster Recovery Plan\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"14\",\n \"limit\": \"17\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 37,\n \"header\": \"Third-party Integrations\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"25\",\n \"limit\": \"28\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 38,\n \"header\": \"User Feedback Summary\",\n \"type\": \"Research\",\n \"status\": \"Done\",\n \"target\": \"20\",\n \"limit\": \"15\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 39,\n \"header\": \"Localization Strategy\",\n \"type\": \"Narrative\",\n \"status\": \"In Process\",\n \"target\": \"12\",\n \"limit\": \"19\",\n \"reviewer\": \"Maria Garcia\"\n },\n {\n \"id\": 40,\n \"header\": \"Mobile Compatibility\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"28\",\n \"limit\": \"31\",\n \"reviewer\": \"James Wilson\"\n },\n {\n \"id\": 41,\n \"header\": \"Data Migration Plan\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"19\",\n \"limit\": \"22\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 42,\n \"header\": \"Quality Assurance Protocols\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"30\",\n \"limit\": \"33\",\n \"reviewer\": \"Priya Singh\"\n },\n {\n \"id\": 43,\n \"header\": \"Stakeholder Analysis\",\n \"type\": \"Research\",\n \"status\": \"In Process\",\n \"target\": \"11\",\n \"limit\": \"14\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 44,\n \"header\": \"Environmental Impact Assessment\",\n \"type\": \"Research\",\n \"status\": \"Done\",\n \"target\": \"24\",\n \"limit\": \"27\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 45,\n \"header\": \"Intellectual Property Rights\",\n \"type\": \"Legal\",\n \"status\": \"In Process\",\n \"target\": \"17\",\n \"limit\": \"20\",\n \"reviewer\": \"Sarah Johnson\"\n },\n {\n \"id\": 46,\n \"header\": \"Customer Support Framework\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"22\",\n \"limit\": \"25\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 47,\n \"header\": \"Version Control Strategy\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"15\",\n \"limit\": \"18\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 48,\n \"header\": \"Continuous Integration Pipeline\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"26\",\n \"limit\": \"29\",\n \"reviewer\": \"Michael Chen\"\n },\n {\n \"id\": 49,\n \"header\": \"Regulatory Compliance\",\n \"type\": \"Legal\",\n \"status\": \"In Process\",\n \"target\": \"13\",\n \"limit\": \"16\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 50,\n \"header\": \"User Authentication System\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"28\",\n \"limit\": \"31\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 51,\n \"header\": \"Data Analytics Framework\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"21\",\n \"limit\": \"24\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 52,\n \"header\": \"Cloud Infrastructure\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"16\",\n \"limit\": \"19\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 53,\n \"header\": \"Network Security Measures\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"29\",\n \"limit\": \"32\",\n \"reviewer\": \"Lisa Wong\"\n },\n {\n \"id\": 54,\n \"header\": \"Project Timeline\",\n \"type\": \"Planning\",\n \"status\": \"Done\",\n \"target\": \"14\",\n \"limit\": \"17\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 55,\n \"header\": \"Resource Allocation\",\n \"type\": \"Planning\",\n \"status\": \"In Process\",\n \"target\": \"27\",\n \"limit\": \"30\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 56,\n \"header\": \"Team Structure and Roles\",\n \"type\": \"Planning\",\n \"status\": \"Done\",\n \"target\": \"20\",\n \"limit\": \"23\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 57,\n \"header\": \"Communication Protocols\",\n \"type\": \"Planning\",\n \"status\": \"In Process\",\n \"target\": \"15\",\n \"limit\": \"18\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 58,\n \"header\": \"Success Metrics\",\n \"type\": \"Planning\",\n \"status\": \"Done\",\n \"target\": \"30\",\n \"limit\": \"33\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 59,\n \"header\": \"Internationalization Support\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"23\",\n \"limit\": \"26\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 60,\n \"header\": \"Backup and Recovery Procedures\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"18\",\n \"limit\": \"21\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 61,\n \"header\": \"Monitoring and Alerting System\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"25\",\n \"limit\": \"28\",\n \"reviewer\": \"Daniel Park\"\n },\n {\n \"id\": 62,\n \"header\": \"Code Review Guidelines\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"12\",\n \"limit\": \"15\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 63,\n \"header\": \"Documentation Standards\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"27\",\n \"limit\": \"30\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 64,\n \"header\": \"Release Management Process\",\n \"type\": \"Planning\",\n \"status\": \"Done\",\n \"target\": \"22\",\n \"limit\": \"25\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 65,\n \"header\": \"Feature Prioritization Matrix\",\n \"type\": \"Planning\",\n \"status\": \"In Process\",\n \"target\": \"19\",\n \"limit\": \"22\",\n \"reviewer\": \"Emma Davis\"\n },\n {\n \"id\": 66,\n \"header\": \"Technical Debt Assessment\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"24\",\n \"limit\": \"27\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 67,\n \"header\": \"Capacity Planning\",\n \"type\": \"Planning\",\n \"status\": \"In Process\",\n \"target\": \"21\",\n \"limit\": \"24\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 68,\n \"header\": \"Service Level Agreements\",\n \"type\": \"Legal\",\n \"status\": \"Done\",\n \"target\": \"26\",\n \"limit\": \"29\",\n \"reviewer\": \"Assign reviewer\"\n }\n]\n", + "type": "registry:file", + "target": "app/dashboard/data.json" + }, + { + "path": "blocks/dashboard-01/components/app-sidebar.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport {\n ArrowUpCircleIcon,\n BarChartIcon,\n CameraIcon,\n ClipboardListIcon,\n DatabaseIcon,\n FileCodeIcon,\n FileIcon,\n FileTextIcon,\n FolderIcon,\n HelpCircleIcon,\n LayoutDashboardIcon,\n ListIcon,\n SearchIcon,\n SettingsIcon,\n UsersIcon,\n} from \"lucide-react\"\n\nimport { NavDocuments } from \"@/registry/default/blocks/dashboard-01/components/nav-documents\"\nimport { NavMain } from \"@/registry/default/blocks/dashboard-01/components/nav-main\"\nimport { NavSecondary } from \"@/registry/default/blocks/dashboard-01/components/nav-secondary\"\nimport { NavUser } from \"@/registry/default/blocks/dashboard-01/components/nav-user\"\nimport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from \"@/registry/default/ui/sidebar\"\n\nconst data = {\n user: {\n name: \"shadcn\",\n email: \"m@example.com\",\n avatar: \"/avatars/shadcn.jpg\",\n },\n navMain: [\n {\n title: \"Dashboard\",\n url: \"#\",\n icon: LayoutDashboardIcon,\n },\n {\n title: \"Lifecycle\",\n url: \"#\",\n icon: ListIcon,\n },\n {\n title: \"Analytics\",\n url: \"#\",\n icon: BarChartIcon,\n },\n {\n title: \"Projects\",\n url: \"#\",\n icon: FolderIcon,\n },\n {\n title: \"Team\",\n url: \"#\",\n icon: UsersIcon,\n },\n ],\n navClouds: [\n {\n title: \"Capture\",\n icon: CameraIcon,\n isActive: true,\n url: \"#\",\n items: [\n {\n title: \"Active Proposals\",\n url: \"#\",\n },\n {\n title: \"Archived\",\n url: \"#\",\n },\n ],\n },\n {\n title: \"Proposal\",\n icon: FileTextIcon,\n url: \"#\",\n items: [\n {\n title: \"Active Proposals\",\n url: \"#\",\n },\n {\n title: \"Archived\",\n url: \"#\",\n },\n ],\n },\n {\n title: \"Prompts\",\n icon: FileCodeIcon,\n url: \"#\",\n items: [\n {\n title: \"Active Proposals\",\n url: \"#\",\n },\n {\n title: \"Archived\",\n url: \"#\",\n },\n ],\n },\n ],\n navSecondary: [\n {\n title: \"Settings\",\n url: \"#\",\n icon: SettingsIcon,\n },\n {\n title: \"Get Help\",\n url: \"#\",\n icon: HelpCircleIcon,\n },\n {\n title: \"Search\",\n url: \"#\",\n icon: SearchIcon,\n },\n ],\n documents: [\n {\n name: \"Data Library\",\n url: \"#\",\n icon: DatabaseIcon,\n },\n {\n name: \"Reports\",\n url: \"#\",\n icon: ClipboardListIcon,\n },\n {\n name: \"Word Assistant\",\n url: \"#\",\n icon: FileIcon,\n },\n ],\n}\n\nexport function AppSidebar({ ...props }: React.ComponentProps) {\n return (\n \n \n \n \n \n \n \n Acme Inc.\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n )\n}\n", + "type": "registry:component", + "target": "" + }, + { + "path": "blocks/dashboard-01/components/chart-area-interactive.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Area, AreaChart, CartesianGrid, XAxis } from \"recharts\"\n\nimport { useIsMobile } from \"@/registry/default/hooks/use-mobile\"\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@/registry/default/ui/card\"\nimport {\n ChartConfig,\n ChartContainer,\n ChartTooltip,\n ChartTooltipContent,\n} from \"@/registry/default/ui/chart\"\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/registry/default/ui/select\"\nimport {\n ToggleGroup,\n ToggleGroupItem,\n} from \"@/registry/default/ui/toggle-group\"\nconst chartData = [\n { date: \"2024-04-01\", desktop: 222, mobile: 150 },\n { date: \"2024-04-02\", desktop: 97, mobile: 180 },\n { date: \"2024-04-03\", desktop: 167, mobile: 120 },\n { date: \"2024-04-04\", desktop: 242, mobile: 260 },\n { date: \"2024-04-05\", desktop: 373, mobile: 290 },\n { date: \"2024-04-06\", desktop: 301, mobile: 340 },\n { date: \"2024-04-07\", desktop: 245, mobile: 180 },\n { date: \"2024-04-08\", desktop: 409, mobile: 320 },\n { date: \"2024-04-09\", desktop: 59, mobile: 110 },\n { date: \"2024-04-10\", desktop: 261, mobile: 190 },\n { date: \"2024-04-11\", desktop: 327, mobile: 350 },\n { date: \"2024-04-12\", desktop: 292, mobile: 210 },\n { date: \"2024-04-13\", desktop: 342, mobile: 380 },\n { date: \"2024-04-14\", desktop: 137, mobile: 220 },\n { date: \"2024-04-15\", desktop: 120, mobile: 170 },\n { date: \"2024-04-16\", desktop: 138, mobile: 190 },\n { date: \"2024-04-17\", desktop: 446, mobile: 360 },\n { date: \"2024-04-18\", desktop: 364, mobile: 410 },\n { date: \"2024-04-19\", desktop: 243, mobile: 180 },\n { date: \"2024-04-20\", desktop: 89, mobile: 150 },\n { date: \"2024-04-21\", desktop: 137, mobile: 200 },\n { date: \"2024-04-22\", desktop: 224, mobile: 170 },\n { date: \"2024-04-23\", desktop: 138, mobile: 230 },\n { date: \"2024-04-24\", desktop: 387, mobile: 290 },\n { date: \"2024-04-25\", desktop: 215, mobile: 250 },\n { date: \"2024-04-26\", desktop: 75, mobile: 130 },\n { date: \"2024-04-27\", desktop: 383, mobile: 420 },\n { date: \"2024-04-28\", desktop: 122, mobile: 180 },\n { date: \"2024-04-29\", desktop: 315, mobile: 240 },\n { date: \"2024-04-30\", desktop: 454, mobile: 380 },\n { date: \"2024-05-01\", desktop: 165, mobile: 220 },\n { date: \"2024-05-02\", desktop: 293, mobile: 310 },\n { date: \"2024-05-03\", desktop: 247, mobile: 190 },\n { date: \"2024-05-04\", desktop: 385, mobile: 420 },\n { date: \"2024-05-05\", desktop: 481, mobile: 390 },\n { date: \"2024-05-06\", desktop: 498, mobile: 520 },\n { date: \"2024-05-07\", desktop: 388, mobile: 300 },\n { date: \"2024-05-08\", desktop: 149, mobile: 210 },\n { date: \"2024-05-09\", desktop: 227, mobile: 180 },\n { date: \"2024-05-10\", desktop: 293, mobile: 330 },\n { date: \"2024-05-11\", desktop: 335, mobile: 270 },\n { date: \"2024-05-12\", desktop: 197, mobile: 240 },\n { date: \"2024-05-13\", desktop: 197, mobile: 160 },\n { date: \"2024-05-14\", desktop: 448, mobile: 490 },\n { date: \"2024-05-15\", desktop: 473, mobile: 380 },\n { date: \"2024-05-16\", desktop: 338, mobile: 400 },\n { date: \"2024-05-17\", desktop: 499, mobile: 420 },\n { date: \"2024-05-18\", desktop: 315, mobile: 350 },\n { date: \"2024-05-19\", desktop: 235, mobile: 180 },\n { date: \"2024-05-20\", desktop: 177, mobile: 230 },\n { date: \"2024-05-21\", desktop: 82, mobile: 140 },\n { date: \"2024-05-22\", desktop: 81, mobile: 120 },\n { date: \"2024-05-23\", desktop: 252, mobile: 290 },\n { date: \"2024-05-24\", desktop: 294, mobile: 220 },\n { date: \"2024-05-25\", desktop: 201, mobile: 250 },\n { date: \"2024-05-26\", desktop: 213, mobile: 170 },\n { date: \"2024-05-27\", desktop: 420, mobile: 460 },\n { date: \"2024-05-28\", desktop: 233, mobile: 190 },\n { date: \"2024-05-29\", desktop: 78, mobile: 130 },\n { date: \"2024-05-30\", desktop: 340, mobile: 280 },\n { date: \"2024-05-31\", desktop: 178, mobile: 230 },\n { date: \"2024-06-01\", desktop: 178, mobile: 200 },\n { date: \"2024-06-02\", desktop: 470, mobile: 410 },\n { date: \"2024-06-03\", desktop: 103, mobile: 160 },\n { date: \"2024-06-04\", desktop: 439, mobile: 380 },\n { date: \"2024-06-05\", desktop: 88, mobile: 140 },\n { date: \"2024-06-06\", desktop: 294, mobile: 250 },\n { date: \"2024-06-07\", desktop: 323, mobile: 370 },\n { date: \"2024-06-08\", desktop: 385, mobile: 320 },\n { date: \"2024-06-09\", desktop: 438, mobile: 480 },\n { date: \"2024-06-10\", desktop: 155, mobile: 200 },\n { date: \"2024-06-11\", desktop: 92, mobile: 150 },\n { date: \"2024-06-12\", desktop: 492, mobile: 420 },\n { date: \"2024-06-13\", desktop: 81, mobile: 130 },\n { date: \"2024-06-14\", desktop: 426, mobile: 380 },\n { date: \"2024-06-15\", desktop: 307, mobile: 350 },\n { date: \"2024-06-16\", desktop: 371, mobile: 310 },\n { date: \"2024-06-17\", desktop: 475, mobile: 520 },\n { date: \"2024-06-18\", desktop: 107, mobile: 170 },\n { date: \"2024-06-19\", desktop: 341, mobile: 290 },\n { date: \"2024-06-20\", desktop: 408, mobile: 450 },\n { date: \"2024-06-21\", desktop: 169, mobile: 210 },\n { date: \"2024-06-22\", desktop: 317, mobile: 270 },\n { date: \"2024-06-23\", desktop: 480, mobile: 530 },\n { date: \"2024-06-24\", desktop: 132, mobile: 180 },\n { date: \"2024-06-25\", desktop: 141, mobile: 190 },\n { date: \"2024-06-26\", desktop: 434, mobile: 380 },\n { date: \"2024-06-27\", desktop: 448, mobile: 490 },\n { date: \"2024-06-28\", desktop: 149, mobile: 200 },\n { date: \"2024-06-29\", desktop: 103, mobile: 160 },\n { date: \"2024-06-30\", desktop: 446, mobile: 400 },\n]\n\nconst chartConfig = {\n visitors: {\n label: \"Visitors\",\n },\n desktop: {\n label: \"Desktop\",\n color: \"hsl(var(--chart-1))\",\n },\n mobile: {\n label: \"Mobile\",\n color: \"hsl(var(--chart-2))\",\n },\n} satisfies ChartConfig\n\nexport function ChartAreaInteractive() {\n const isMobile = useIsMobile()\n const [timeRange, setTimeRange] = React.useState(\"30d\")\n\n React.useEffect(() => {\n if (isMobile) {\n setTimeRange(\"7d\")\n }\n }, [isMobile])\n\n const filteredData = chartData.filter((item) => {\n const date = new Date(item.date)\n const referenceDate = new Date(\"2024-06-30\")\n let daysToSubtract = 90\n if (timeRange === \"30d\") {\n daysToSubtract = 30\n } else if (timeRange === \"7d\") {\n daysToSubtract = 7\n }\n const startDate = new Date(referenceDate)\n startDate.setDate(startDate.getDate() - daysToSubtract)\n return date >= startDate\n })\n\n return (\n \n \n Total Visitors\n \n \n Total for the last 3 months\n \n Last 3 months\n \n
\n \n \n Last 3 months\n \n \n Last 30 days\n \n \n Last 7 days\n \n \n \n
\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n {\n const date = new Date(value)\n return date.toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n })\n }}\n />\n {\n return new Date(value).toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n })\n }}\n indicator=\"dot\"\n />\n }\n />\n \n \n \n \n \n
\n )\n}\n", + "type": "registry:component", + "target": "" + }, + { + "path": "blocks/dashboard-01/components/data-table.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport {\n DndContext,\n KeyboardSensor,\n MouseSensor,\n TouchSensor,\n closestCenter,\n useSensor,\n useSensors,\n type DragEndEvent,\n type UniqueIdentifier,\n} from \"@dnd-kit/core\"\nimport { restrictToVerticalAxis } from \"@dnd-kit/modifiers\"\nimport {\n SortableContext,\n arrayMove,\n useSortable,\n verticalListSortingStrategy,\n} from \"@dnd-kit/sortable\"\nimport { CSS } from \"@dnd-kit/utilities\"\nimport {\n ColumnDef,\n ColumnFiltersState,\n Row,\n SortingState,\n VisibilityState,\n flexRender,\n getCoreRowModel,\n getFacetedRowModel,\n getFacetedUniqueValues,\n getFilteredRowModel,\n getPaginationRowModel,\n getSortedRowModel,\n useReactTable,\n} from \"@tanstack/react-table\"\nimport {\n CheckCircle2Icon,\n CheckCircleIcon,\n ChevronDownIcon,\n ChevronLeftIcon,\n ChevronRightIcon,\n ChevronsLeftIcon,\n ChevronsRightIcon,\n ColumnsIcon,\n GripVerticalIcon,\n LoaderIcon,\n MoreVerticalIcon,\n PlusIcon,\n TrendingUpIcon,\n} from \"lucide-react\"\nimport { Area, AreaChart, CartesianGrid, XAxis } from \"recharts\"\nimport { toast } from \"sonner\"\nimport { z } from \"zod\"\n\nimport { useIsMobile } from \"@/registry/default/hooks/use-mobile\"\nimport { Badge } from \"@/registry/default/ui/badge\"\nimport { Button } from \"@/registry/default/ui/button\"\nimport {\n ChartConfig,\n ChartContainer,\n ChartTooltip,\n ChartTooltipContent,\n} from \"@/registry/default/ui/chart\"\nimport { Checkbox } from \"@/registry/default/ui/checkbox\"\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/registry/default/ui/dropdown-menu\"\nimport { Input } from \"@/registry/default/ui/input\"\nimport { Label } from \"@/registry/default/ui/label\"\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/registry/default/ui/select\"\nimport { Separator } from \"@/registry/default/ui/separator\"\nimport {\n Sheet,\n SheetClose,\n SheetContent,\n SheetDescription,\n SheetFooter,\n SheetHeader,\n SheetTitle,\n SheetTrigger,\n} from \"@/registry/default/ui/sheet\"\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from \"@/registry/default/ui/table\"\nimport {\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from \"@/registry/default/ui/tabs\"\n\nexport const schema = z.object({\n id: z.number(),\n header: z.string(),\n type: z.string(),\n status: z.string(),\n target: z.string(),\n limit: z.string(),\n reviewer: z.string(),\n})\n\n// Create a separate component for the drag handle\nfunction DragHandle({ id }: { id: number }) {\n const { attributes, listeners } = useSortable({\n id,\n })\n\n return (\n \n \n Drag to reorder\n \n )\n}\n\nconst columns: ColumnDef>[] = [\n {\n id: \"drag\",\n header: () => null,\n cell: ({ row }) => ,\n },\n {\n id: \"select\",\n header: ({ table }) => (\n
\n table.toggleAllPageRowsSelected(!!value)}\n aria-label=\"Select all\"\n />\n
\n ),\n cell: ({ row }) => (\n
\n row.toggleSelected(!!value)}\n aria-label=\"Select row\"\n />\n
\n ),\n enableSorting: false,\n enableHiding: false,\n },\n {\n accessorKey: \"header\",\n header: \"Header\",\n cell: ({ row }) => {\n return \n },\n enableHiding: false,\n },\n {\n accessorKey: \"type\",\n header: \"Section Type\",\n cell: ({ row }) => (\n
\n \n {row.original.type}\n \n
\n ),\n },\n {\n accessorKey: \"status\",\n header: \"Status\",\n cell: ({ row }) => (\n \n {row.original.status === \"Done\" ? (\n \n ) : (\n \n )}\n {row.original.status}\n \n ),\n },\n {\n accessorKey: \"target\",\n header: () =>
Target
,\n cell: ({ row }) => (\n {\n e.preventDefault()\n toast.promise(new Promise((resolve) => setTimeout(resolve, 1000)), {\n loading: `Saving ${row.original.header}`,\n success: \"Done\",\n error: \"Error\",\n })\n }}\n >\n \n \n \n ),\n },\n {\n accessorKey: \"limit\",\n header: () =>
Limit
,\n cell: ({ row }) => (\n {\n e.preventDefault()\n toast.promise(new Promise((resolve) => setTimeout(resolve, 1000)), {\n loading: `Saving ${row.original.header}`,\n success: \"Done\",\n error: \"Error\",\n })\n }}\n >\n \n \n \n ),\n },\n {\n accessorKey: \"reviewer\",\n header: \"Reviewer\",\n cell: ({ row }) => {\n const isAssigned = row.original.reviewer !== \"Assign reviewer\"\n\n if (isAssigned) {\n return row.original.reviewer\n }\n\n return (\n <>\n \n \n \n )\n },\n },\n {\n id: \"actions\",\n cell: () => (\n \n \n \n \n Open menu\n \n \n \n Edit\n Make a copy\n Favorite\n \n Delete\n \n \n ),\n },\n]\n\nfunction DraggableRow({ row }: { row: Row> }) {\n const { transform, transition, setNodeRef, isDragging } = useSortable({\n id: row.original.id,\n })\n\n return (\n \n {row.getVisibleCells().map((cell) => (\n \n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n \n ))}\n \n )\n}\n\nexport function DataTable({\n data: initialData,\n}: {\n data: z.infer[]\n}) {\n const [data, setData] = React.useState(() => initialData)\n const [rowSelection, setRowSelection] = React.useState({})\n const [columnVisibility, setColumnVisibility] =\n React.useState({})\n const [columnFilters, setColumnFilters] = React.useState(\n []\n )\n const [sorting, setSorting] = React.useState([])\n const [pagination, setPagination] = React.useState({\n pageIndex: 0,\n pageSize: 10,\n })\n const sortableId = React.useId()\n const sensors = useSensors(\n useSensor(MouseSensor, {}),\n useSensor(TouchSensor, {}),\n useSensor(KeyboardSensor, {})\n )\n\n const dataIds = React.useMemo(\n () => data?.map(({ id }) => id) || [],\n [data]\n )\n\n const table = useReactTable({\n data,\n columns,\n state: {\n sorting,\n columnVisibility,\n rowSelection,\n columnFilters,\n pagination,\n },\n getRowId: (row) => row.id.toString(),\n enableRowSelection: true,\n onRowSelectionChange: setRowSelection,\n onSortingChange: setSorting,\n onColumnFiltersChange: setColumnFilters,\n onColumnVisibilityChange: setColumnVisibility,\n onPaginationChange: setPagination,\n getCoreRowModel: getCoreRowModel(),\n getFilteredRowModel: getFilteredRowModel(),\n getPaginationRowModel: getPaginationRowModel(),\n getSortedRowModel: getSortedRowModel(),\n getFacetedRowModel: getFacetedRowModel(),\n getFacetedUniqueValues: getFacetedUniqueValues(),\n })\n\n function handleDragEnd(event: DragEndEvent) {\n const { active, over } = event\n if (active && over && active.id !== over.id) {\n setData((data) => {\n const oldIndex = dataIds.indexOf(active.id)\n const newIndex = dataIds.indexOf(over.id)\n return arrayMove(data, oldIndex, newIndex)\n })\n }\n }\n\n return (\n \n
\n \n \n \n Outline\n \n Past Performance{\" \"}\n \n 3\n \n \n \n Key Personnel{\" \"}\n \n 2\n \n \n Focus Documents\n \n
\n \n \n \n \n \n {table\n .getAllColumns()\n .filter(\n (column) =>\n typeof column.accessorFn !== \"undefined\" &&\n column.getCanHide()\n )\n .map((column) => {\n return (\n \n column.toggleVisibility(!!value)\n }\n >\n {column.id}\n \n )\n })}\n \n \n \n
\n
\n \n
\n \n \n \n {table.getHeaderGroups().map((headerGroup) => (\n \n {headerGroup.headers.map((header) => {\n return (\n \n {header.isPlaceholder\n ? null\n : flexRender(\n header.column.columnDef.header,\n header.getContext()\n )}\n \n )\n })}\n \n ))}\n \n \n {table.getRowModel().rows?.length ? (\n \n {table.getRowModel().rows.map((row) => (\n \n ))}\n \n ) : (\n \n \n No results.\n \n \n )}\n \n
\n \n
\n
\n
\n {table.getFilteredSelectedRowModel().rows.length} of{\" \"}\n {table.getFilteredRowModel().rows.length} row(s) selected.\n
\n
\n
\n \n {\n table.setPageSize(Number(value))\n }}\n >\n \n \n \n \n {[10, 20, 30, 40, 50].map((pageSize) => (\n \n {pageSize}\n \n ))}\n \n \n
\n
\n Page {table.getState().pagination.pageIndex + 1} of{\" \"}\n {table.getPageCount()}\n
\n
\n table.setPageIndex(0)}\n disabled={!table.getCanPreviousPage()}\n >\n Go to first page\n \n \n table.previousPage()}\n disabled={!table.getCanPreviousPage()}\n >\n Go to previous page\n \n \n table.nextPage()}\n disabled={!table.getCanNextPage()}\n >\n Go to next page\n \n \n table.setPageIndex(table.getPageCount() - 1)}\n disabled={!table.getCanNextPage()}\n >\n Go to last page\n \n \n
\n
\n
\n \n \n
\n \n \n
\n
\n \n
\n \n \n )\n}\n\nconst chartData = [\n { month: \"January\", desktop: 186, mobile: 80 },\n { month: \"February\", desktop: 305, mobile: 200 },\n { month: \"March\", desktop: 237, mobile: 120 },\n { month: \"April\", desktop: 73, mobile: 190 },\n { month: \"May\", desktop: 209, mobile: 130 },\n { month: \"June\", desktop: 214, mobile: 140 },\n]\n\nconst chartConfig = {\n desktop: {\n label: \"Desktop\",\n color: \"var(--primary)\",\n },\n mobile: {\n label: \"Mobile\",\n color: \"var(--primary)\",\n },\n} satisfies ChartConfig\n\nfunction TableCellViewer({ item }: { item: z.infer }) {\n const isMobile = useIsMobile()\n\n return (\n \n \n \n \n \n \n {item.header}\n \n Showing total visitors for the last 6 months\n \n \n
\n {!isMobile && (\n <>\n \n \n \n value.slice(0, 3)}\n hide\n />\n }\n />\n \n \n \n \n \n
\n
\n Trending up by 5.2% this month{\" \"}\n \n
\n
\n Showing total visitors for the last 6 months. This is just\n some random text to test the layout. It spans multiple lines\n and should wrap around.\n
\n
\n \n \n )}\n
\n
\n \n \n
\n
\n
\n \n \n
\n
\n \n \n
\n
\n
\n
\n \n \n
\n
\n \n \n
\n
\n
\n \n \n
\n
\n
\n \n \n \n \n \n \n
\n
\n )\n}\n", + "type": "registry:component", + "target": "" + }, + { + "path": "blocks/dashboard-01/components/nav-documents.tsx", + "content": "\"use client\"\n\nimport {\n FolderIcon,\n MoreHorizontalIcon,\n ShareIcon,\n type LucideIcon,\n} from \"lucide-react\"\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@/registry/default/ui/dropdown-menu\"\nimport {\n SidebarGroup,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuButton,\n SidebarMenuItem,\n useSidebar,\n} from \"@/registry/default/ui/sidebar\"\n\nexport function NavDocuments({\n items,\n}: {\n items: {\n name: string\n url: string\n icon: LucideIcon\n }[]\n}) {\n const { isMobile } = useSidebar()\n\n return (\n \n Documents\n \n {items.map((item) => (\n \n \n \n \n {item.name}\n \n \n \n \n \n \n More\n \n \n \n \n \n Open\n \n \n \n Share\n \n \n \n \n ))}\n \n \n \n More\n \n \n \n \n )\n}\n", + "type": "registry:component", + "target": "" + }, + { + "path": "blocks/dashboard-01/components/nav-main.tsx", + "content": "\"use client\"\n\nimport { MailIcon, PlusCircleIcon, type LucideIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/default/ui/button\"\nimport {\n SidebarGroup,\n SidebarGroupContent,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from \"@/registry/default/ui/sidebar\"\n\nexport function NavMain({\n items,\n}: {\n items: {\n title: string\n url: string\n icon?: LucideIcon\n }[]\n}) {\n return (\n \n \n \n \n \n \n Quick Create\n \n \n \n Inbox\n \n \n \n \n {items.map((item) => (\n \n \n {item.icon && }\n {item.title}\n \n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component", + "target": "" + }, + { + "path": "blocks/dashboard-01/components/nav-secondary.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { LucideIcon } from \"lucide-react\"\n\nimport {\n SidebarGroup,\n SidebarGroupContent,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from \"@/registry/default/ui/sidebar\"\n\nexport function NavSecondary({\n items,\n ...props\n}: {\n items: {\n title: string\n url: string\n icon: LucideIcon\n }[]\n} & React.ComponentPropsWithoutRef) {\n return (\n \n \n \n {items.map((item) => (\n \n \n \n \n {item.title}\n \n \n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component", + "target": "" + }, + { + "path": "blocks/dashboard-01/components/nav-user.tsx", + "content": "\"use client\"\n\nimport {\n BellIcon,\n CreditCardIcon,\n LogOutIcon,\n MoreVerticalIcon,\n UserCircleIcon,\n} from \"lucide-react\"\n\nimport {\n Avatar,\n AvatarFallback,\n AvatarImage,\n} from \"@/registry/default/ui/avatar\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/registry/default/ui/dropdown-menu\"\nimport {\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n useSidebar,\n} from \"@/registry/default/ui/sidebar\"\n\nexport function NavUser({\n user,\n}: {\n user: {\n name: string\n email: string\n avatar: string\n }\n}) {\n const { isMobile } = useSidebar()\n\n return (\n \n \n \n \n \n \n \n CN\n \n
\n {user.name}\n \n {user.email}\n \n
\n \n \n
\n \n \n
\n \n \n CN\n \n
\n {user.name}\n \n {user.email}\n \n
\n
\n
\n \n \n \n \n Account\n \n \n \n Billing\n \n \n \n Notifications\n \n \n \n \n \n Log out\n \n \n
\n
\n
\n )\n}\n", + "type": "registry:component", + "target": "" + }, + { + "path": "blocks/dashboard-01/components/section-cards.tsx", + "content": "import { TrendingDownIcon, TrendingUpIcon } from \"lucide-react\"\n\nimport { Badge } from \"@/registry/default/ui/badge\"\nimport {\n Card,\n CardDescription,\n CardFooter,\n CardHeader,\n CardTitle,\n} from \"@/registry/default/ui/card\"\n\nexport function SectionCards() {\n return (\n
\n \n \n Total Revenue\n \n $1,250.00\n \n
\n \n \n +12.5%\n \n
\n
\n \n
\n Trending up this month \n
\n
\n Visitors for the last 6 months\n
\n
\n
\n \n \n New Customers\n \n 1,234\n \n
\n \n \n -20%\n \n
\n
\n \n
\n Down 20% this period \n
\n
\n Acquisition needs attention\n
\n
\n
\n \n \n Active Accounts\n \n 45,678\n \n
\n \n \n +12.5%\n \n
\n
\n \n
\n Strong user retention \n
\n
Engagement exceed targets
\n
\n
\n \n \n Growth Rate\n \n 4.5%\n \n
\n \n \n +4.5%\n \n
\n
\n \n
\n Steady performance \n
\n
Meets growth projections
\n
\n
\n
\n )\n}\n", + "type": "registry:component", + "target": "" + }, + { + "path": "blocks/dashboard-01/components/site-header.tsx", + "content": "import { Separator } from \"@/registry/default/ui/separator\"\nimport { SidebarTrigger } from \"@/registry/default/ui/sidebar\"\n\nexport function SiteHeader() {\n return (\n
\n
\n \n \n

Documents

\n
\n
\n )\n}\n", + "type": "registry:component", + "target": "" + } + ], + "categories": [ + "dashboard" + ] +} \ No newline at end of file diff --git a/apps/www/public/r/styles/new-york-v4/dashboard-01.json b/apps/www/public/r/styles/new-york-v4/dashboard-01.json new file mode 100644 index 0000000000..c2cff77439 --- /dev/null +++ b/apps/www/public/r/styles/new-york-v4/dashboard-01.json @@ -0,0 +1,98 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "dashboard-01", + "type": "registry:block", + "description": "A dashboard with sidebar, charts and data table.", + "dependencies": [ + "@dnd-kit/core", + "@dnd-kit/modifiers", + "@dnd-kit/sortable", + "@dnd-kit/utilities", + "@tanstack/react-table", + "zod", + "@tabler/icons-react" + ], + "registryDependencies": [ + "sidebar", + "breadcrumb", + "separator", + "label", + "chart", + "card", + "select", + "tabs", + "table", + "toggle-group", + "badge", + "button", + "checkbox", + "dropdown-menu", + "drawer", + "input", + "avatar", + "sheet", + "sonner" + ], + "files": [ + { + "path": "registry/new-york-v4/blocks/dashboard-01/page.tsx", + "content": "import { AppSidebar } from \"@/registry/new-york-v4/blocks/dashboard-01/components/app-sidebar\"\nimport { ChartAreaInteractive } from \"@/registry/new-york-v4/blocks/dashboard-01/components/chart-area-interactive\"\nimport { DataTable } from \"@/registry/new-york-v4/blocks/dashboard-01/components/data-table\"\nimport { SectionCards } from \"@/registry/new-york-v4/blocks/dashboard-01/components/section-cards\"\nimport { SiteHeader } from \"@/registry/new-york-v4/blocks/dashboard-01/components/site-header\"\nimport {\n SidebarInset,\n SidebarProvider,\n} from \"@/registry/new-york-v4/ui/sidebar\"\n\nimport data from \"./data.json\"\n\nexport default function Page() {\n return (\n \n \n \n \n
\n
\n
\n \n
\n \n
\n \n
\n
\n
\n
\n \n )\n}\n", + "type": "registry:page", + "target": "app/dashboard/page.tsx" + }, + { + "path": "registry/new-york-v4/blocks/dashboard-01/data.json", + "content": "[\n {\n \"id\": 1,\n \"header\": \"Cover page\",\n \"type\": \"Cover page\",\n \"status\": \"In Process\",\n \"target\": \"18\",\n \"limit\": \"5\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 2,\n \"header\": \"Table of contents\",\n \"type\": \"Table of contents\",\n \"status\": \"Done\",\n \"target\": \"29\",\n \"limit\": \"24\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 3,\n \"header\": \"Executive summary\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"10\",\n \"limit\": \"13\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 4,\n \"header\": \"Technical approach\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"27\",\n \"limit\": \"23\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 5,\n \"header\": \"Design\",\n \"type\": \"Narrative\",\n \"status\": \"In Process\",\n \"target\": \"2\",\n \"limit\": \"16\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 6,\n \"header\": \"Capabilities\",\n \"type\": \"Narrative\",\n \"status\": \"In Process\",\n \"target\": \"20\",\n \"limit\": \"8\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 7,\n \"header\": \"Integration with existing systems\",\n \"type\": \"Narrative\",\n \"status\": \"In Process\",\n \"target\": \"19\",\n \"limit\": \"21\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 8,\n \"header\": \"Innovation and Advantages\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"25\",\n \"limit\": \"26\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 9,\n \"header\": \"Overview of EMR's Innovative Solutions\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"7\",\n \"limit\": \"23\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 10,\n \"header\": \"Advanced Algorithms and Machine Learning\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"30\",\n \"limit\": \"28\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 11,\n \"header\": \"Adaptive Communication Protocols\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"9\",\n \"limit\": \"31\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 12,\n \"header\": \"Advantages Over Current Technologies\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"12\",\n \"limit\": \"0\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 13,\n \"header\": \"Past Performance\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"22\",\n \"limit\": \"33\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 14,\n \"header\": \"Customer Feedback and Satisfaction Levels\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"15\",\n \"limit\": \"34\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 15,\n \"header\": \"Implementation Challenges and Solutions\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"3\",\n \"limit\": \"35\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 16,\n \"header\": \"Security Measures and Data Protection Policies\",\n \"type\": \"Narrative\",\n \"status\": \"In Process\",\n \"target\": \"6\",\n \"limit\": \"36\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 17,\n \"header\": \"Scalability and Future Proofing\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"4\",\n \"limit\": \"37\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 18,\n \"header\": \"Cost-Benefit Analysis\",\n \"type\": \"Plain language\",\n \"status\": \"Done\",\n \"target\": \"14\",\n \"limit\": \"38\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 19,\n \"header\": \"User Training and Onboarding Experience\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"17\",\n \"limit\": \"39\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 20,\n \"header\": \"Future Development Roadmap\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"11\",\n \"limit\": \"40\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 21,\n \"header\": \"System Architecture Overview\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"24\",\n \"limit\": \"18\",\n \"reviewer\": \"Maya Johnson\"\n },\n {\n \"id\": 22,\n \"header\": \"Risk Management Plan\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"15\",\n \"limit\": \"22\",\n \"reviewer\": \"Carlos Rodriguez\"\n },\n {\n \"id\": 23,\n \"header\": \"Compliance Documentation\",\n \"type\": \"Legal\",\n \"status\": \"In Process\",\n \"target\": \"31\",\n \"limit\": \"27\",\n \"reviewer\": \"Sarah Chen\"\n },\n {\n \"id\": 24,\n \"header\": \"API Documentation\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"8\",\n \"limit\": \"12\",\n \"reviewer\": \"Raj Patel\"\n },\n {\n \"id\": 25,\n \"header\": \"User Interface Mockups\",\n \"type\": \"Visual\",\n \"status\": \"In Process\",\n \"target\": \"19\",\n \"limit\": \"25\",\n \"reviewer\": \"Leila Ahmadi\"\n },\n {\n \"id\": 26,\n \"header\": \"Database Schema\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"22\",\n \"limit\": \"20\",\n \"reviewer\": \"Thomas Wilson\"\n },\n {\n \"id\": 27,\n \"header\": \"Testing Methodology\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"17\",\n \"limit\": \"14\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 28,\n \"header\": \"Deployment Strategy\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"26\",\n \"limit\": \"30\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 29,\n \"header\": \"Budget Breakdown\",\n \"type\": \"Financial\",\n \"status\": \"In Process\",\n \"target\": \"13\",\n \"limit\": \"16\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 30,\n \"header\": \"Market Analysis\",\n \"type\": \"Research\",\n \"status\": \"Done\",\n \"target\": \"29\",\n \"limit\": \"32\",\n \"reviewer\": \"Sophia Martinez\"\n },\n {\n \"id\": 31,\n \"header\": \"Competitor Comparison\",\n \"type\": \"Research\",\n \"status\": \"In Process\",\n \"target\": \"21\",\n \"limit\": \"19\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 32,\n \"header\": \"Maintenance Plan\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"16\",\n \"limit\": \"23\",\n \"reviewer\": \"Alex Thompson\"\n },\n {\n \"id\": 33,\n \"header\": \"User Personas\",\n \"type\": \"Research\",\n \"status\": \"In Process\",\n \"target\": \"27\",\n \"limit\": \"24\",\n \"reviewer\": \"Nina Patel\"\n },\n {\n \"id\": 34,\n \"header\": \"Accessibility Compliance\",\n \"type\": \"Legal\",\n \"status\": \"Done\",\n \"target\": \"18\",\n \"limit\": \"21\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 35,\n \"header\": \"Performance Metrics\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"23\",\n \"limit\": \"26\",\n \"reviewer\": \"David Kim\"\n },\n {\n \"id\": 36,\n \"header\": \"Disaster Recovery Plan\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"14\",\n \"limit\": \"17\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 37,\n \"header\": \"Third-party Integrations\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"25\",\n \"limit\": \"28\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 38,\n \"header\": \"User Feedback Summary\",\n \"type\": \"Research\",\n \"status\": \"Done\",\n \"target\": \"20\",\n \"limit\": \"15\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 39,\n \"header\": \"Localization Strategy\",\n \"type\": \"Narrative\",\n \"status\": \"In Process\",\n \"target\": \"12\",\n \"limit\": \"19\",\n \"reviewer\": \"Maria Garcia\"\n },\n {\n \"id\": 40,\n \"header\": \"Mobile Compatibility\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"28\",\n \"limit\": \"31\",\n \"reviewer\": \"James Wilson\"\n },\n {\n \"id\": 41,\n \"header\": \"Data Migration Plan\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"19\",\n \"limit\": \"22\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 42,\n \"header\": \"Quality Assurance Protocols\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"30\",\n \"limit\": \"33\",\n \"reviewer\": \"Priya Singh\"\n },\n {\n \"id\": 43,\n \"header\": \"Stakeholder Analysis\",\n \"type\": \"Research\",\n \"status\": \"In Process\",\n \"target\": \"11\",\n \"limit\": \"14\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 44,\n \"header\": \"Environmental Impact Assessment\",\n \"type\": \"Research\",\n \"status\": \"Done\",\n \"target\": \"24\",\n \"limit\": \"27\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 45,\n \"header\": \"Intellectual Property Rights\",\n \"type\": \"Legal\",\n \"status\": \"In Process\",\n \"target\": \"17\",\n \"limit\": \"20\",\n \"reviewer\": \"Sarah Johnson\"\n },\n {\n \"id\": 46,\n \"header\": \"Customer Support Framework\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"22\",\n \"limit\": \"25\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 47,\n \"header\": \"Version Control Strategy\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"15\",\n \"limit\": \"18\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 48,\n \"header\": \"Continuous Integration Pipeline\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"26\",\n \"limit\": \"29\",\n \"reviewer\": \"Michael Chen\"\n },\n {\n \"id\": 49,\n \"header\": \"Regulatory Compliance\",\n \"type\": \"Legal\",\n \"status\": \"In Process\",\n \"target\": \"13\",\n \"limit\": \"16\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 50,\n \"header\": \"User Authentication System\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"28\",\n \"limit\": \"31\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 51,\n \"header\": \"Data Analytics Framework\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"21\",\n \"limit\": \"24\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 52,\n \"header\": \"Cloud Infrastructure\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"16\",\n \"limit\": \"19\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 53,\n \"header\": \"Network Security Measures\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"29\",\n \"limit\": \"32\",\n \"reviewer\": \"Lisa Wong\"\n },\n {\n \"id\": 54,\n \"header\": \"Project Timeline\",\n \"type\": \"Planning\",\n \"status\": \"Done\",\n \"target\": \"14\",\n \"limit\": \"17\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 55,\n \"header\": \"Resource Allocation\",\n \"type\": \"Planning\",\n \"status\": \"In Process\",\n \"target\": \"27\",\n \"limit\": \"30\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 56,\n \"header\": \"Team Structure and Roles\",\n \"type\": \"Planning\",\n \"status\": \"Done\",\n \"target\": \"20\",\n \"limit\": \"23\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 57,\n \"header\": \"Communication Protocols\",\n \"type\": \"Planning\",\n \"status\": \"In Process\",\n \"target\": \"15\",\n \"limit\": \"18\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 58,\n \"header\": \"Success Metrics\",\n \"type\": \"Planning\",\n \"status\": \"Done\",\n \"target\": \"30\",\n \"limit\": \"33\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 59,\n \"header\": \"Internationalization Support\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"23\",\n \"limit\": \"26\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 60,\n \"header\": \"Backup and Recovery Procedures\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"18\",\n \"limit\": \"21\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 61,\n \"header\": \"Monitoring and Alerting System\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"25\",\n \"limit\": \"28\",\n \"reviewer\": \"Daniel Park\"\n },\n {\n \"id\": 62,\n \"header\": \"Code Review Guidelines\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"12\",\n \"limit\": \"15\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 63,\n \"header\": \"Documentation Standards\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"27\",\n \"limit\": \"30\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 64,\n \"header\": \"Release Management Process\",\n \"type\": \"Planning\",\n \"status\": \"Done\",\n \"target\": \"22\",\n \"limit\": \"25\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 65,\n \"header\": \"Feature Prioritization Matrix\",\n \"type\": \"Planning\",\n \"status\": \"In Process\",\n \"target\": \"19\",\n \"limit\": \"22\",\n \"reviewer\": \"Emma Davis\"\n },\n {\n \"id\": 66,\n \"header\": \"Technical Debt Assessment\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"24\",\n \"limit\": \"27\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 67,\n \"header\": \"Capacity Planning\",\n \"type\": \"Planning\",\n \"status\": \"In Process\",\n \"target\": \"21\",\n \"limit\": \"24\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 68,\n \"header\": \"Service Level Agreements\",\n \"type\": \"Legal\",\n \"status\": \"Done\",\n \"target\": \"26\",\n \"limit\": \"29\",\n \"reviewer\": \"Assign reviewer\"\n }\n]\n", + "type": "registry:file", + "target": "app/dashboard/data.json" + }, + { + "path": "registry/new-york-v4/blocks/dashboard-01/components/app-sidebar.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport {\n IconCamera,\n IconChartBar,\n IconDashboard,\n IconDatabase,\n IconFileAi,\n IconFileDescription,\n IconFileWord,\n IconFolder,\n IconHelp,\n IconInnerShadowTop,\n IconListDetails,\n IconReport,\n IconSearch,\n IconSettings,\n IconUsers,\n} from \"@tabler/icons-react\"\n\nimport { NavDocuments } from \"@/registry/new-york-v4/blocks/dashboard-01/components/nav-documents\"\nimport { NavMain } from \"@/registry/new-york-v4/blocks/dashboard-01/components/nav-main\"\nimport { NavSecondary } from \"@/registry/new-york-v4/blocks/dashboard-01/components/nav-secondary\"\nimport { NavUser } from \"@/registry/new-york-v4/blocks/dashboard-01/components/nav-user\"\nimport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from \"@/registry/new-york-v4/ui/sidebar\"\n\nconst data = {\n user: {\n name: \"shadcn\",\n email: \"m@example.com\",\n avatar: \"/avatars/shadcn.jpg\",\n },\n navMain: [\n {\n title: \"Dashboard\",\n url: \"#\",\n icon: IconDashboard,\n },\n {\n title: \"Lifecycle\",\n url: \"#\",\n icon: IconListDetails,\n },\n {\n title: \"Analytics\",\n url: \"#\",\n icon: IconChartBar,\n },\n {\n title: \"Projects\",\n url: \"#\",\n icon: IconFolder,\n },\n {\n title: \"Team\",\n url: \"#\",\n icon: IconUsers,\n },\n ],\n navClouds: [\n {\n title: \"Capture\",\n icon: IconCamera,\n isActive: true,\n url: \"#\",\n items: [\n {\n title: \"Active Proposals\",\n url: \"#\",\n },\n {\n title: \"Archived\",\n url: \"#\",\n },\n ],\n },\n {\n title: \"Proposal\",\n icon: IconFileDescription,\n url: \"#\",\n items: [\n {\n title: \"Active Proposals\",\n url: \"#\",\n },\n {\n title: \"Archived\",\n url: \"#\",\n },\n ],\n },\n {\n title: \"Prompts\",\n icon: IconFileAi,\n url: \"#\",\n items: [\n {\n title: \"Active Proposals\",\n url: \"#\",\n },\n {\n title: \"Archived\",\n url: \"#\",\n },\n ],\n },\n ],\n navSecondary: [\n {\n title: \"Settings\",\n url: \"#\",\n icon: IconSettings,\n },\n {\n title: \"Get Help\",\n url: \"#\",\n icon: IconHelp,\n },\n {\n title: \"Search\",\n url: \"#\",\n icon: IconSearch,\n },\n ],\n documents: [\n {\n name: \"Data Library\",\n url: \"#\",\n icon: IconDatabase,\n },\n {\n name: \"Reports\",\n url: \"#\",\n icon: IconReport,\n },\n {\n name: \"Word Assistant\",\n url: \"#\",\n icon: IconFileWord,\n },\n ],\n}\n\nexport function AppSidebar({ ...props }: React.ComponentProps) {\n return (\n \n \n \n \n \n \n \n Acme Inc.\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "registry/new-york-v4/blocks/dashboard-01/components/chart-area-interactive.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Area, AreaChart, CartesianGrid, XAxis } from \"recharts\"\n\nimport { useIsMobile } from \"@/registry/new-york-v4/hooks/use-mobile\"\nimport {\n Card,\n CardAction,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@/registry/new-york-v4/ui/card\"\nimport {\n ChartConfig,\n ChartContainer,\n ChartTooltip,\n ChartTooltipContent,\n} from \"@/registry/new-york-v4/ui/chart\"\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/registry/new-york-v4/ui/select\"\nimport {\n ToggleGroup,\n ToggleGroupItem,\n} from \"@/registry/new-york-v4/ui/toggle-group\"\n\nexport const description = \"An interactive area chart\"\n\nconst chartData = [\n { date: \"2024-04-01\", desktop: 222, mobile: 150 },\n { date: \"2024-04-02\", desktop: 97, mobile: 180 },\n { date: \"2024-04-03\", desktop: 167, mobile: 120 },\n { date: \"2024-04-04\", desktop: 242, mobile: 260 },\n { date: \"2024-04-05\", desktop: 373, mobile: 290 },\n { date: \"2024-04-06\", desktop: 301, mobile: 340 },\n { date: \"2024-04-07\", desktop: 245, mobile: 180 },\n { date: \"2024-04-08\", desktop: 409, mobile: 320 },\n { date: \"2024-04-09\", desktop: 59, mobile: 110 },\n { date: \"2024-04-10\", desktop: 261, mobile: 190 },\n { date: \"2024-04-11\", desktop: 327, mobile: 350 },\n { date: \"2024-04-12\", desktop: 292, mobile: 210 },\n { date: \"2024-04-13\", desktop: 342, mobile: 380 },\n { date: \"2024-04-14\", desktop: 137, mobile: 220 },\n { date: \"2024-04-15\", desktop: 120, mobile: 170 },\n { date: \"2024-04-16\", desktop: 138, mobile: 190 },\n { date: \"2024-04-17\", desktop: 446, mobile: 360 },\n { date: \"2024-04-18\", desktop: 364, mobile: 410 },\n { date: \"2024-04-19\", desktop: 243, mobile: 180 },\n { date: \"2024-04-20\", desktop: 89, mobile: 150 },\n { date: \"2024-04-21\", desktop: 137, mobile: 200 },\n { date: \"2024-04-22\", desktop: 224, mobile: 170 },\n { date: \"2024-04-23\", desktop: 138, mobile: 230 },\n { date: \"2024-04-24\", desktop: 387, mobile: 290 },\n { date: \"2024-04-25\", desktop: 215, mobile: 250 },\n { date: \"2024-04-26\", desktop: 75, mobile: 130 },\n { date: \"2024-04-27\", desktop: 383, mobile: 420 },\n { date: \"2024-04-28\", desktop: 122, mobile: 180 },\n { date: \"2024-04-29\", desktop: 315, mobile: 240 },\n { date: \"2024-04-30\", desktop: 454, mobile: 380 },\n { date: \"2024-05-01\", desktop: 165, mobile: 220 },\n { date: \"2024-05-02\", desktop: 293, mobile: 310 },\n { date: \"2024-05-03\", desktop: 247, mobile: 190 },\n { date: \"2024-05-04\", desktop: 385, mobile: 420 },\n { date: \"2024-05-05\", desktop: 481, mobile: 390 },\n { date: \"2024-05-06\", desktop: 498, mobile: 520 },\n { date: \"2024-05-07\", desktop: 388, mobile: 300 },\n { date: \"2024-05-08\", desktop: 149, mobile: 210 },\n { date: \"2024-05-09\", desktop: 227, mobile: 180 },\n { date: \"2024-05-10\", desktop: 293, mobile: 330 },\n { date: \"2024-05-11\", desktop: 335, mobile: 270 },\n { date: \"2024-05-12\", desktop: 197, mobile: 240 },\n { date: \"2024-05-13\", desktop: 197, mobile: 160 },\n { date: \"2024-05-14\", desktop: 448, mobile: 490 },\n { date: \"2024-05-15\", desktop: 473, mobile: 380 },\n { date: \"2024-05-16\", desktop: 338, mobile: 400 },\n { date: \"2024-05-17\", desktop: 499, mobile: 420 },\n { date: \"2024-05-18\", desktop: 315, mobile: 350 },\n { date: \"2024-05-19\", desktop: 235, mobile: 180 },\n { date: \"2024-05-20\", desktop: 177, mobile: 230 },\n { date: \"2024-05-21\", desktop: 82, mobile: 140 },\n { date: \"2024-05-22\", desktop: 81, mobile: 120 },\n { date: \"2024-05-23\", desktop: 252, mobile: 290 },\n { date: \"2024-05-24\", desktop: 294, mobile: 220 },\n { date: \"2024-05-25\", desktop: 201, mobile: 250 },\n { date: \"2024-05-26\", desktop: 213, mobile: 170 },\n { date: \"2024-05-27\", desktop: 420, mobile: 460 },\n { date: \"2024-05-28\", desktop: 233, mobile: 190 },\n { date: \"2024-05-29\", desktop: 78, mobile: 130 },\n { date: \"2024-05-30\", desktop: 340, mobile: 280 },\n { date: \"2024-05-31\", desktop: 178, mobile: 230 },\n { date: \"2024-06-01\", desktop: 178, mobile: 200 },\n { date: \"2024-06-02\", desktop: 470, mobile: 410 },\n { date: \"2024-06-03\", desktop: 103, mobile: 160 },\n { date: \"2024-06-04\", desktop: 439, mobile: 380 },\n { date: \"2024-06-05\", desktop: 88, mobile: 140 },\n { date: \"2024-06-06\", desktop: 294, mobile: 250 },\n { date: \"2024-06-07\", desktop: 323, mobile: 370 },\n { date: \"2024-06-08\", desktop: 385, mobile: 320 },\n { date: \"2024-06-09\", desktop: 438, mobile: 480 },\n { date: \"2024-06-10\", desktop: 155, mobile: 200 },\n { date: \"2024-06-11\", desktop: 92, mobile: 150 },\n { date: \"2024-06-12\", desktop: 492, mobile: 420 },\n { date: \"2024-06-13\", desktop: 81, mobile: 130 },\n { date: \"2024-06-14\", desktop: 426, mobile: 380 },\n { date: \"2024-06-15\", desktop: 307, mobile: 350 },\n { date: \"2024-06-16\", desktop: 371, mobile: 310 },\n { date: \"2024-06-17\", desktop: 475, mobile: 520 },\n { date: \"2024-06-18\", desktop: 107, mobile: 170 },\n { date: \"2024-06-19\", desktop: 341, mobile: 290 },\n { date: \"2024-06-20\", desktop: 408, mobile: 450 },\n { date: \"2024-06-21\", desktop: 169, mobile: 210 },\n { date: \"2024-06-22\", desktop: 317, mobile: 270 },\n { date: \"2024-06-23\", desktop: 480, mobile: 530 },\n { date: \"2024-06-24\", desktop: 132, mobile: 180 },\n { date: \"2024-06-25\", desktop: 141, mobile: 190 },\n { date: \"2024-06-26\", desktop: 434, mobile: 380 },\n { date: \"2024-06-27\", desktop: 448, mobile: 490 },\n { date: \"2024-06-28\", desktop: 149, mobile: 200 },\n { date: \"2024-06-29\", desktop: 103, mobile: 160 },\n { date: \"2024-06-30\", desktop: 446, mobile: 400 },\n]\n\nconst chartConfig = {\n visitors: {\n label: \"Visitors\",\n },\n desktop: {\n label: \"Desktop\",\n color: \"var(--primary)\",\n },\n mobile: {\n label: \"Mobile\",\n color: \"var(--primary)\",\n },\n} satisfies ChartConfig\n\nexport function ChartAreaInteractive() {\n const isMobile = useIsMobile()\n const [timeRange, setTimeRange] = React.useState(\"90d\")\n\n React.useEffect(() => {\n if (isMobile) {\n setTimeRange(\"7d\")\n }\n }, [isMobile])\n\n const filteredData = chartData.filter((item) => {\n const date = new Date(item.date)\n const referenceDate = new Date(\"2024-06-30\")\n let daysToSubtract = 90\n if (timeRange === \"30d\") {\n daysToSubtract = 30\n } else if (timeRange === \"7d\") {\n daysToSubtract = 7\n }\n const startDate = new Date(referenceDate)\n startDate.setDate(startDate.getDate() - daysToSubtract)\n return date >= startDate\n })\n\n return (\n \n \n Total Visitors\n \n \n Total for the last 3 months\n \n Last 3 months\n \n \n \n Last 3 months\n Last 30 days\n Last 7 days\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n {\n const date = new Date(value)\n return date.toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n })\n }}\n />\n {\n return new Date(value).toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n })\n }}\n indicator=\"dot\"\n />\n }\n />\n \n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "registry/new-york-v4/blocks/dashboard-01/components/data-table.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport {\n DndContext,\n KeyboardSensor,\n MouseSensor,\n TouchSensor,\n closestCenter,\n useSensor,\n useSensors,\n type DragEndEvent,\n type UniqueIdentifier,\n} from \"@dnd-kit/core\"\nimport { restrictToVerticalAxis } from \"@dnd-kit/modifiers\"\nimport {\n SortableContext,\n arrayMove,\n useSortable,\n verticalListSortingStrategy,\n} from \"@dnd-kit/sortable\"\nimport { CSS } from \"@dnd-kit/utilities\"\nimport {\n IconChevronDown,\n IconChevronLeft,\n IconChevronRight,\n IconChevronsLeft,\n IconChevronsRight,\n IconCircleCheckFilled,\n IconDotsVertical,\n IconGripVertical,\n IconLayoutColumns,\n IconLoader,\n IconPlus,\n IconTrendingUp,\n} from \"@tabler/icons-react\"\nimport {\n ColumnDef,\n ColumnFiltersState,\n Row,\n SortingState,\n VisibilityState,\n flexRender,\n getCoreRowModel,\n getFacetedRowModel,\n getFacetedUniqueValues,\n getFilteredRowModel,\n getPaginationRowModel,\n getSortedRowModel,\n useReactTable,\n} from \"@tanstack/react-table\"\nimport { Area, AreaChart, CartesianGrid, XAxis } from \"recharts\"\nimport { toast } from \"sonner\"\nimport { z } from \"zod\"\n\nimport { useIsMobile } from \"@/registry/new-york-v4/hooks/use-mobile\"\nimport { Badge } from \"@/registry/new-york-v4/ui/badge\"\nimport { Button } from \"@/registry/new-york-v4/ui/button\"\nimport {\n ChartConfig,\n ChartContainer,\n ChartTooltip,\n ChartTooltipContent,\n} from \"@/registry/new-york-v4/ui/chart\"\nimport { Checkbox } from \"@/registry/new-york-v4/ui/checkbox\"\nimport {\n Drawer,\n DrawerClose,\n DrawerContent,\n DrawerDescription,\n DrawerFooter,\n DrawerHeader,\n DrawerTitle,\n DrawerTrigger,\n} from \"@/registry/new-york-v4/ui/drawer\"\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/registry/new-york-v4/ui/dropdown-menu\"\nimport { Input } from \"@/registry/new-york-v4/ui/input\"\nimport { Label } from \"@/registry/new-york-v4/ui/label\"\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/registry/new-york-v4/ui/select\"\nimport { Separator } from \"@/registry/new-york-v4/ui/separator\"\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from \"@/registry/new-york-v4/ui/table\"\nimport {\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from \"@/registry/new-york-v4/ui/tabs\"\n\nexport const schema = z.object({\n id: z.number(),\n header: z.string(),\n type: z.string(),\n status: z.string(),\n target: z.string(),\n limit: z.string(),\n reviewer: z.string(),\n})\n\n// Create a separate component for the drag handle\nfunction DragHandle({ id }: { id: number }) {\n const { attributes, listeners } = useSortable({\n id,\n })\n\n return (\n \n \n Drag to reorder\n \n )\n}\n\nconst columns: ColumnDef>[] = [\n {\n id: \"drag\",\n header: () => null,\n cell: ({ row }) => ,\n },\n {\n id: \"select\",\n header: ({ table }) => (\n
\n table.toggleAllPageRowsSelected(!!value)}\n aria-label=\"Select all\"\n />\n
\n ),\n cell: ({ row }) => (\n
\n row.toggleSelected(!!value)}\n aria-label=\"Select row\"\n />\n
\n ),\n enableSorting: false,\n enableHiding: false,\n },\n {\n accessorKey: \"header\",\n header: \"Header\",\n cell: ({ row }) => {\n return \n },\n enableHiding: false,\n },\n {\n accessorKey: \"type\",\n header: \"Section Type\",\n cell: ({ row }) => (\n
\n \n {row.original.type}\n \n
\n ),\n },\n {\n accessorKey: \"status\",\n header: \"Status\",\n cell: ({ row }) => (\n \n {row.original.status === \"Done\" ? (\n \n ) : (\n \n )}\n {row.original.status}\n \n ),\n },\n {\n accessorKey: \"target\",\n header: () =>
Target
,\n cell: ({ row }) => (\n {\n e.preventDefault()\n toast.promise(new Promise((resolve) => setTimeout(resolve, 1000)), {\n loading: `Saving ${row.original.header}`,\n success: \"Done\",\n error: \"Error\",\n })\n }}\n >\n \n \n \n ),\n },\n {\n accessorKey: \"limit\",\n header: () =>
Limit
,\n cell: ({ row }) => (\n {\n e.preventDefault()\n toast.promise(new Promise((resolve) => setTimeout(resolve, 1000)), {\n loading: `Saving ${row.original.header}`,\n success: \"Done\",\n error: \"Error\",\n })\n }}\n >\n \n \n \n ),\n },\n {\n accessorKey: \"reviewer\",\n header: \"Reviewer\",\n cell: ({ row }) => {\n const isAssigned = row.original.reviewer !== \"Assign reviewer\"\n\n if (isAssigned) {\n return row.original.reviewer\n }\n\n return (\n <>\n \n \n \n )\n },\n },\n {\n id: \"actions\",\n cell: () => (\n \n \n \n \n Open menu\n \n \n \n Edit\n Make a copy\n Favorite\n \n Delete\n \n \n ),\n },\n]\n\nfunction DraggableRow({ row }: { row: Row> }) {\n const { transform, transition, setNodeRef, isDragging } = useSortable({\n id: row.original.id,\n })\n\n return (\n \n {row.getVisibleCells().map((cell) => (\n \n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n \n ))}\n \n )\n}\n\nexport function DataTable({\n data: initialData,\n}: {\n data: z.infer[]\n}) {\n const [data, setData] = React.useState(() => initialData)\n const [rowSelection, setRowSelection] = React.useState({})\n const [columnVisibility, setColumnVisibility] =\n React.useState({})\n const [columnFilters, setColumnFilters] = React.useState(\n []\n )\n const [sorting, setSorting] = React.useState([])\n const [pagination, setPagination] = React.useState({\n pageIndex: 0,\n pageSize: 10,\n })\n const sortableId = React.useId()\n const sensors = useSensors(\n useSensor(MouseSensor, {}),\n useSensor(TouchSensor, {}),\n useSensor(KeyboardSensor, {})\n )\n\n const dataIds = React.useMemo(\n () => data?.map(({ id }) => id) || [],\n [data]\n )\n\n const table = useReactTable({\n data,\n columns,\n state: {\n sorting,\n columnVisibility,\n rowSelection,\n columnFilters,\n pagination,\n },\n getRowId: (row) => row.id.toString(),\n enableRowSelection: true,\n onRowSelectionChange: setRowSelection,\n onSortingChange: setSorting,\n onColumnFiltersChange: setColumnFilters,\n onColumnVisibilityChange: setColumnVisibility,\n onPaginationChange: setPagination,\n getCoreRowModel: getCoreRowModel(),\n getFilteredRowModel: getFilteredRowModel(),\n getPaginationRowModel: getPaginationRowModel(),\n getSortedRowModel: getSortedRowModel(),\n getFacetedRowModel: getFacetedRowModel(),\n getFacetedUniqueValues: getFacetedUniqueValues(),\n })\n\n function handleDragEnd(event: DragEndEvent) {\n const { active, over } = event\n if (active && over && active.id !== over.id) {\n setData((data) => {\n const oldIndex = dataIds.indexOf(active.id)\n const newIndex = dataIds.indexOf(over.id)\n return arrayMove(data, oldIndex, newIndex)\n })\n }\n }\n\n return (\n \n
\n \n \n \n
\n \n \n \n \n \n {table\n .getAllColumns()\n .filter(\n (column) =>\n typeof column.accessorFn !== \"undefined\" &&\n column.getCanHide()\n )\n .map((column) => {\n return (\n \n column.toggleVisibility(!!value)\n }\n >\n {column.id}\n \n )\n })}\n \n \n \n
\n
\n \n
\n \n \n \n {table.getHeaderGroups().map((headerGroup) => (\n \n {headerGroup.headers.map((header) => {\n return (\n \n {header.isPlaceholder\n ? null\n : flexRender(\n header.column.columnDef.header,\n header.getContext()\n )}\n \n )\n })}\n \n ))}\n \n \n {table.getRowModel().rows?.length ? (\n \n {table.getRowModel().rows.map((row) => (\n \n ))}\n \n ) : (\n \n \n No results.\n \n \n )}\n \n
\n \n
\n
\n \n
\n
\n \n {\n table.setPageSize(Number(value))\n }}\n >\n \n \n \n \n {[10, 20, 30, 40, 50].map((pageSize) => (\n \n {pageSize}\n \n ))}\n \n \n
\n
\n Page {table.getState().pagination.pageIndex + 1} of{\" \"}\n {table.getPageCount()}\n
\n
\n table.setPageIndex(0)}\n disabled={!table.getCanPreviousPage()}\n >\n Go to first page\n \n \n table.previousPage()}\n disabled={!table.getCanPreviousPage()}\n >\n Go to previous page\n \n \n table.nextPage()}\n disabled={!table.getCanNextPage()}\n >\n Go to next page\n \n \n table.setPageIndex(table.getPageCount() - 1)}\n disabled={!table.getCanNextPage()}\n >\n Go to last page\n \n \n
\n
\n
\n \n \n
\n \n \n
\n
\n \n
\n \n \n )\n}\n\nconst chartData = [\n { month: \"January\", desktop: 186, mobile: 80 },\n { month: \"February\", desktop: 305, mobile: 200 },\n { month: \"March\", desktop: 237, mobile: 120 },\n { month: \"April\", desktop: 73, mobile: 190 },\n { month: \"May\", desktop: 209, mobile: 130 },\n { month: \"June\", desktop: 214, mobile: 140 },\n]\n\nconst chartConfig = {\n desktop: {\n label: \"Desktop\",\n color: \"var(--primary)\",\n },\n mobile: {\n label: \"Mobile\",\n color: \"var(--primary)\",\n },\n} satisfies ChartConfig\n\nfunction TableCellViewer({ item }: { item: z.infer }) {\n const isMobile = useIsMobile()\n\n return (\n \n \n \n \n \n \n {item.header}\n \n Showing total visitors for the last 6 months\n \n \n
\n {!isMobile && (\n <>\n \n \n \n value.slice(0, 3)}\n hide\n />\n }\n />\n \n \n \n \n \n
\n
\n Trending up by 5.2% this month{\" \"}\n \n
\n
\n Showing total visitors for the last 6 months. This is just\n some random text to test the layout. It spans multiple lines\n and should wrap around.\n
\n
\n \n \n )}\n
\n
\n \n \n
\n
\n
\n \n \n
\n
\n \n \n
\n
\n
\n
\n \n \n
\n
\n \n \n
\n
\n
\n \n \n
\n
\n
\n \n \n \n \n \n \n
\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "registry/new-york-v4/blocks/dashboard-01/components/nav-documents.tsx", + "content": "\"use client\"\n\nimport {\n IconDots,\n IconFolder,\n IconShare3,\n IconTrash,\n type Icon,\n} from \"@tabler/icons-react\"\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/registry/new-york-v4/ui/dropdown-menu\"\nimport {\n SidebarGroup,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuButton,\n SidebarMenuItem,\n useSidebar,\n} from \"@/registry/new-york-v4/ui/sidebar\"\n\nexport function NavDocuments({\n items,\n}: {\n items: {\n name: string\n url: string\n icon: Icon\n }[]\n}) {\n const { isMobile } = useSidebar()\n\n return (\n \n Documents\n \n {items.map((item) => (\n \n \n \n \n {item.name}\n \n \n \n \n \n \n More\n \n \n \n \n \n Open\n \n \n \n Share\n \n \n \n \n Delete\n \n \n \n \n ))}\n \n \n \n More\n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "registry/new-york-v4/blocks/dashboard-01/components/nav-main.tsx", + "content": "\"use client\"\n\nimport { IconCirclePlusFilled, IconMail, type Icon } from \"@tabler/icons-react\"\n\nimport { Button } from \"@/registry/new-york-v4/ui/button\"\nimport {\n SidebarGroup,\n SidebarGroupContent,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from \"@/registry/new-york-v4/ui/sidebar\"\n\nexport function NavMain({\n items,\n}: {\n items: {\n title: string\n url: string\n icon?: Icon\n }[]\n}) {\n return (\n \n \n \n \n \n \n Quick Create\n \n \n \n Inbox\n \n \n \n \n {items.map((item) => (\n \n \n {item.icon && }\n {item.title}\n \n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "registry/new-york-v4/blocks/dashboard-01/components/nav-secondary.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { type Icon } from \"@tabler/icons-react\"\n\nimport {\n SidebarGroup,\n SidebarGroupContent,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from \"@/registry/new-york-v4/ui/sidebar\"\n\nexport function NavSecondary({\n items,\n ...props\n}: {\n items: {\n title: string\n url: string\n icon: Icon\n }[]\n} & React.ComponentPropsWithoutRef) {\n return (\n \n \n \n {items.map((item) => (\n \n \n \n \n {item.title}\n \n \n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "registry/new-york-v4/blocks/dashboard-01/components/nav-user.tsx", + "content": "\"use client\"\n\nimport {\n IconCreditCard,\n IconDotsVertical,\n IconLogout,\n IconNotification,\n IconUserCircle,\n} from \"@tabler/icons-react\"\n\nimport {\n Avatar,\n AvatarFallback,\n AvatarImage,\n} from \"@/registry/new-york-v4/ui/avatar\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/registry/new-york-v4/ui/dropdown-menu\"\nimport {\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n useSidebar,\n} from \"@/registry/new-york-v4/ui/sidebar\"\n\nexport function NavUser({\n user,\n}: {\n user: {\n name: string\n email: string\n avatar: string\n }\n}) {\n const { isMobile } = useSidebar()\n\n return (\n \n \n \n \n \n \n \n CN\n \n
\n {user.name}\n \n {user.email}\n \n
\n \n \n
\n \n \n
\n \n \n CN\n \n
\n {user.name}\n \n {user.email}\n \n
\n
\n
\n \n \n \n \n Account\n \n \n \n Billing\n \n \n \n Notifications\n \n \n \n \n \n Log out\n \n \n
\n
\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "registry/new-york-v4/blocks/dashboard-01/components/section-cards.tsx", + "content": "import { IconTrendingDown, IconTrendingUp } from \"@tabler/icons-react\"\n\nimport { Badge } from \"@/registry/new-york-v4/ui/badge\"\nimport {\n Card,\n CardAction,\n CardDescription,\n CardFooter,\n CardHeader,\n CardTitle,\n} from \"@/registry/new-york-v4/ui/card\"\n\nexport function SectionCards() {\n return (\n
\n \n \n Total Revenue\n \n $1,250.00\n \n \n \n \n +12.5%\n \n \n \n \n
\n Trending up this month \n
\n
\n Visitors for the last 6 months\n
\n
\n
\n \n \n New Customers\n \n 1,234\n \n \n \n \n -20%\n \n \n \n \n
\n Down 20% this period \n
\n
\n Acquisition needs attention\n
\n
\n
\n \n \n Active Accounts\n \n 45,678\n \n \n \n \n +12.5%\n \n \n \n \n
\n Strong user retention \n
\n
Engagement exceed targets
\n
\n
\n \n \n Growth Rate\n \n 4.5%\n \n \n \n \n +4.5%\n \n \n \n \n
\n Steady performance increase \n
\n
Meets growth projections
\n
\n
\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "registry/new-york-v4/blocks/dashboard-01/components/site-header.tsx", + "content": "import { Button } from \"@/registry/new-york-v4/ui/button\"\nimport { Separator } from \"@/registry/new-york-v4/ui/separator\"\nimport { SidebarTrigger } from \"@/registry/new-york-v4/ui/sidebar\"\n\nexport function SiteHeader() {\n return (\n
\n
\n \n \n

Documents

\n
\n \n
\n
\n
\n )\n}\n", + "type": "registry:component" + } + ], + "categories": [ + "dashboard" + ] +} \ No newline at end of file diff --git a/apps/www/public/r/styles/new-york/dashboard-01-dark.png b/apps/www/public/r/styles/new-york/dashboard-01-dark.png new file mode 100644 index 0000000000..e5e3d644ec Binary files /dev/null and b/apps/www/public/r/styles/new-york/dashboard-01-dark.png differ diff --git a/apps/www/public/r/styles/new-york/dashboard-01-light.png b/apps/www/public/r/styles/new-york/dashboard-01-light.png new file mode 100644 index 0000000000..5bbf9c2194 Binary files /dev/null and b/apps/www/public/r/styles/new-york/dashboard-01-light.png differ diff --git a/apps/www/public/r/styles/new-york/dashboard-01.json b/apps/www/public/r/styles/new-york/dashboard-01.json new file mode 100644 index 0000000000..db4780f315 --- /dev/null +++ b/apps/www/public/r/styles/new-york/dashboard-01.json @@ -0,0 +1,107 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "dashboard-01", + "type": "registry:block", + "author": "shadcn (https://ui.shadcn.com)", + "description": "A dashboard with sidebar, charts and data table.", + "dependencies": [ + "@dnd-kit/core", + "@dnd-kit/modifiers", + "@dnd-kit/sortable", + "@dnd-kit/utilities", + "@tanstack/react-table", + "zod" + ], + "registryDependencies": [ + "sidebar", + "breadcrumb", + "separator", + "label", + "chart", + "card", + "select", + "tabs", + "table", + "toggle-group", + "badge", + "button", + "checkbox", + "dropdown-menu", + "drawer", + "input", + "avatar", + "sheet", + "sonner" + ], + "files": [ + { + "path": "blocks/dashboard-01/page.tsx", + "content": "import { AppSidebar } from \"@/registry/new-york/blocks/dashboard-01/components/app-sidebar\"\nimport { ChartAreaInteractive } from \"@/registry/new-york/blocks/dashboard-01/components/chart-area-interactive\"\nimport { DataTable } from \"@/registry/new-york/blocks/dashboard-01/components/data-table\"\nimport { SectionCards } from \"@/registry/new-york/blocks/dashboard-01/components/section-cards\"\nimport { SiteHeader } from \"@/registry/new-york/blocks/dashboard-01/components/site-header\"\nimport { SidebarInset, SidebarProvider } from \"@/registry/new-york/ui/sidebar\"\n\nimport data from \"./data.json\"\n\nexport default function Page() {\n return (\n \n \n \n \n
\n
\n
\n \n
\n \n
\n \n
\n
\n
\n
\n
\n )\n}\n", + "type": "registry:page", + "target": "app/dashboard/page.tsx" + }, + { + "path": "blocks/dashboard-01/data.json", + "content": "[\n {\n \"id\": 1,\n \"header\": \"Cover page\",\n \"type\": \"Cover page\",\n \"status\": \"In Process\",\n \"target\": \"18\",\n \"limit\": \"5\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 2,\n \"header\": \"Table of contents\",\n \"type\": \"Table of contents\",\n \"status\": \"Done\",\n \"target\": \"29\",\n \"limit\": \"24\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 3,\n \"header\": \"Executive summary\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"10\",\n \"limit\": \"13\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 4,\n \"header\": \"Technical approach\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"27\",\n \"limit\": \"23\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 5,\n \"header\": \"Design\",\n \"type\": \"Narrative\",\n \"status\": \"In Process\",\n \"target\": \"2\",\n \"limit\": \"16\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 6,\n \"header\": \"Capabilities\",\n \"type\": \"Narrative\",\n \"status\": \"In Process\",\n \"target\": \"20\",\n \"limit\": \"8\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 7,\n \"header\": \"Integration with existing systems\",\n \"type\": \"Narrative\",\n \"status\": \"In Process\",\n \"target\": \"19\",\n \"limit\": \"21\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 8,\n \"header\": \"Innovation and Advantages\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"25\",\n \"limit\": \"26\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 9,\n \"header\": \"Overview of EMR's Innovative Solutions\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"7\",\n \"limit\": \"23\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 10,\n \"header\": \"Advanced Algorithms and Machine Learning\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"30\",\n \"limit\": \"28\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 11,\n \"header\": \"Adaptive Communication Protocols\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"9\",\n \"limit\": \"31\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 12,\n \"header\": \"Advantages Over Current Technologies\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"12\",\n \"limit\": \"0\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 13,\n \"header\": \"Past Performance\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"22\",\n \"limit\": \"33\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 14,\n \"header\": \"Customer Feedback and Satisfaction Levels\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"15\",\n \"limit\": \"34\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 15,\n \"header\": \"Implementation Challenges and Solutions\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"3\",\n \"limit\": \"35\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 16,\n \"header\": \"Security Measures and Data Protection Policies\",\n \"type\": \"Narrative\",\n \"status\": \"In Process\",\n \"target\": \"6\",\n \"limit\": \"36\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 17,\n \"header\": \"Scalability and Future Proofing\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"4\",\n \"limit\": \"37\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 18,\n \"header\": \"Cost-Benefit Analysis\",\n \"type\": \"Plain language\",\n \"status\": \"Done\",\n \"target\": \"14\",\n \"limit\": \"38\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 19,\n \"header\": \"User Training and Onboarding Experience\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"17\",\n \"limit\": \"39\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 20,\n \"header\": \"Future Development Roadmap\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"11\",\n \"limit\": \"40\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 21,\n \"header\": \"System Architecture Overview\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"24\",\n \"limit\": \"18\",\n \"reviewer\": \"Maya Johnson\"\n },\n {\n \"id\": 22,\n \"header\": \"Risk Management Plan\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"15\",\n \"limit\": \"22\",\n \"reviewer\": \"Carlos Rodriguez\"\n },\n {\n \"id\": 23,\n \"header\": \"Compliance Documentation\",\n \"type\": \"Legal\",\n \"status\": \"In Process\",\n \"target\": \"31\",\n \"limit\": \"27\",\n \"reviewer\": \"Sarah Chen\"\n },\n {\n \"id\": 24,\n \"header\": \"API Documentation\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"8\",\n \"limit\": \"12\",\n \"reviewer\": \"Raj Patel\"\n },\n {\n \"id\": 25,\n \"header\": \"User Interface Mockups\",\n \"type\": \"Visual\",\n \"status\": \"In Process\",\n \"target\": \"19\",\n \"limit\": \"25\",\n \"reviewer\": \"Leila Ahmadi\"\n },\n {\n \"id\": 26,\n \"header\": \"Database Schema\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"22\",\n \"limit\": \"20\",\n \"reviewer\": \"Thomas Wilson\"\n },\n {\n \"id\": 27,\n \"header\": \"Testing Methodology\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"17\",\n \"limit\": \"14\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 28,\n \"header\": \"Deployment Strategy\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"26\",\n \"limit\": \"30\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 29,\n \"header\": \"Budget Breakdown\",\n \"type\": \"Financial\",\n \"status\": \"In Process\",\n \"target\": \"13\",\n \"limit\": \"16\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 30,\n \"header\": \"Market Analysis\",\n \"type\": \"Research\",\n \"status\": \"Done\",\n \"target\": \"29\",\n \"limit\": \"32\",\n \"reviewer\": \"Sophia Martinez\"\n },\n {\n \"id\": 31,\n \"header\": \"Competitor Comparison\",\n \"type\": \"Research\",\n \"status\": \"In Process\",\n \"target\": \"21\",\n \"limit\": \"19\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 32,\n \"header\": \"Maintenance Plan\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"16\",\n \"limit\": \"23\",\n \"reviewer\": \"Alex Thompson\"\n },\n {\n \"id\": 33,\n \"header\": \"User Personas\",\n \"type\": \"Research\",\n \"status\": \"In Process\",\n \"target\": \"27\",\n \"limit\": \"24\",\n \"reviewer\": \"Nina Patel\"\n },\n {\n \"id\": 34,\n \"header\": \"Accessibility Compliance\",\n \"type\": \"Legal\",\n \"status\": \"Done\",\n \"target\": \"18\",\n \"limit\": \"21\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 35,\n \"header\": \"Performance Metrics\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"23\",\n \"limit\": \"26\",\n \"reviewer\": \"David Kim\"\n },\n {\n \"id\": 36,\n \"header\": \"Disaster Recovery Plan\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"14\",\n \"limit\": \"17\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 37,\n \"header\": \"Third-party Integrations\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"25\",\n \"limit\": \"28\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 38,\n \"header\": \"User Feedback Summary\",\n \"type\": \"Research\",\n \"status\": \"Done\",\n \"target\": \"20\",\n \"limit\": \"15\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 39,\n \"header\": \"Localization Strategy\",\n \"type\": \"Narrative\",\n \"status\": \"In Process\",\n \"target\": \"12\",\n \"limit\": \"19\",\n \"reviewer\": \"Maria Garcia\"\n },\n {\n \"id\": 40,\n \"header\": \"Mobile Compatibility\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"28\",\n \"limit\": \"31\",\n \"reviewer\": \"James Wilson\"\n },\n {\n \"id\": 41,\n \"header\": \"Data Migration Plan\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"19\",\n \"limit\": \"22\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 42,\n \"header\": \"Quality Assurance Protocols\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"30\",\n \"limit\": \"33\",\n \"reviewer\": \"Priya Singh\"\n },\n {\n \"id\": 43,\n \"header\": \"Stakeholder Analysis\",\n \"type\": \"Research\",\n \"status\": \"In Process\",\n \"target\": \"11\",\n \"limit\": \"14\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 44,\n \"header\": \"Environmental Impact Assessment\",\n \"type\": \"Research\",\n \"status\": \"Done\",\n \"target\": \"24\",\n \"limit\": \"27\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 45,\n \"header\": \"Intellectual Property Rights\",\n \"type\": \"Legal\",\n \"status\": \"In Process\",\n \"target\": \"17\",\n \"limit\": \"20\",\n \"reviewer\": \"Sarah Johnson\"\n },\n {\n \"id\": 46,\n \"header\": \"Customer Support Framework\",\n \"type\": \"Narrative\",\n \"status\": \"Done\",\n \"target\": \"22\",\n \"limit\": \"25\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 47,\n \"header\": \"Version Control Strategy\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"15\",\n \"limit\": \"18\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 48,\n \"header\": \"Continuous Integration Pipeline\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"26\",\n \"limit\": \"29\",\n \"reviewer\": \"Michael Chen\"\n },\n {\n \"id\": 49,\n \"header\": \"Regulatory Compliance\",\n \"type\": \"Legal\",\n \"status\": \"In Process\",\n \"target\": \"13\",\n \"limit\": \"16\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 50,\n \"header\": \"User Authentication System\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"28\",\n \"limit\": \"31\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 51,\n \"header\": \"Data Analytics Framework\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"21\",\n \"limit\": \"24\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 52,\n \"header\": \"Cloud Infrastructure\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"16\",\n \"limit\": \"19\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 53,\n \"header\": \"Network Security Measures\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"29\",\n \"limit\": \"32\",\n \"reviewer\": \"Lisa Wong\"\n },\n {\n \"id\": 54,\n \"header\": \"Project Timeline\",\n \"type\": \"Planning\",\n \"status\": \"Done\",\n \"target\": \"14\",\n \"limit\": \"17\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 55,\n \"header\": \"Resource Allocation\",\n \"type\": \"Planning\",\n \"status\": \"In Process\",\n \"target\": \"27\",\n \"limit\": \"30\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 56,\n \"header\": \"Team Structure and Roles\",\n \"type\": \"Planning\",\n \"status\": \"Done\",\n \"target\": \"20\",\n \"limit\": \"23\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 57,\n \"header\": \"Communication Protocols\",\n \"type\": \"Planning\",\n \"status\": \"In Process\",\n \"target\": \"15\",\n \"limit\": \"18\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 58,\n \"header\": \"Success Metrics\",\n \"type\": \"Planning\",\n \"status\": \"Done\",\n \"target\": \"30\",\n \"limit\": \"33\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 59,\n \"header\": \"Internationalization Support\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"23\",\n \"limit\": \"26\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 60,\n \"header\": \"Backup and Recovery Procedures\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"18\",\n \"limit\": \"21\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 61,\n \"header\": \"Monitoring and Alerting System\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"25\",\n \"limit\": \"28\",\n \"reviewer\": \"Daniel Park\"\n },\n {\n \"id\": 62,\n \"header\": \"Code Review Guidelines\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"12\",\n \"limit\": \"15\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 63,\n \"header\": \"Documentation Standards\",\n \"type\": \"Technical content\",\n \"status\": \"In Process\",\n \"target\": \"27\",\n \"limit\": \"30\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 64,\n \"header\": \"Release Management Process\",\n \"type\": \"Planning\",\n \"status\": \"Done\",\n \"target\": \"22\",\n \"limit\": \"25\",\n \"reviewer\": \"Assign reviewer\"\n },\n {\n \"id\": 65,\n \"header\": \"Feature Prioritization Matrix\",\n \"type\": \"Planning\",\n \"status\": \"In Process\",\n \"target\": \"19\",\n \"limit\": \"22\",\n \"reviewer\": \"Emma Davis\"\n },\n {\n \"id\": 66,\n \"header\": \"Technical Debt Assessment\",\n \"type\": \"Technical content\",\n \"status\": \"Done\",\n \"target\": \"24\",\n \"limit\": \"27\",\n \"reviewer\": \"Eddie Lake\"\n },\n {\n \"id\": 67,\n \"header\": \"Capacity Planning\",\n \"type\": \"Planning\",\n \"status\": \"In Process\",\n \"target\": \"21\",\n \"limit\": \"24\",\n \"reviewer\": \"Jamik Tashpulatov\"\n },\n {\n \"id\": 68,\n \"header\": \"Service Level Agreements\",\n \"type\": \"Legal\",\n \"status\": \"Done\",\n \"target\": \"26\",\n \"limit\": \"29\",\n \"reviewer\": \"Assign reviewer\"\n }\n]\n", + "type": "registry:file", + "target": "app/dashboard/data.json" + }, + { + "path": "blocks/dashboard-01/components/app-sidebar.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport {\n ArrowUpCircleIcon,\n BarChartIcon,\n CameraIcon,\n ClipboardListIcon,\n DatabaseIcon,\n FileCodeIcon,\n FileIcon,\n FileTextIcon,\n FolderIcon,\n HelpCircleIcon,\n LayoutDashboardIcon,\n ListIcon,\n SearchIcon,\n SettingsIcon,\n UsersIcon,\n} from \"lucide-react\"\n\nimport { NavDocuments } from \"@/registry/new-york/blocks/dashboard-01/components/nav-documents\"\nimport { NavMain } from \"@/registry/new-york/blocks/dashboard-01/components/nav-main\"\nimport { NavSecondary } from \"@/registry/new-york/blocks/dashboard-01/components/nav-secondary\"\nimport { NavUser } from \"@/registry/new-york/blocks/dashboard-01/components/nav-user\"\nimport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from \"@/registry/new-york/ui/sidebar\"\n\nconst data = {\n user: {\n name: \"shadcn\",\n email: \"m@example.com\",\n avatar: \"/avatars/shadcn.jpg\",\n },\n navMain: [\n {\n title: \"Dashboard\",\n url: \"#\",\n icon: LayoutDashboardIcon,\n },\n {\n title: \"Lifecycle\",\n url: \"#\",\n icon: ListIcon,\n },\n {\n title: \"Analytics\",\n url: \"#\",\n icon: BarChartIcon,\n },\n {\n title: \"Projects\",\n url: \"#\",\n icon: FolderIcon,\n },\n {\n title: \"Team\",\n url: \"#\",\n icon: UsersIcon,\n },\n ],\n navClouds: [\n {\n title: \"Capture\",\n icon: CameraIcon,\n isActive: true,\n url: \"#\",\n items: [\n {\n title: \"Active Proposals\",\n url: \"#\",\n },\n {\n title: \"Archived\",\n url: \"#\",\n },\n ],\n },\n {\n title: \"Proposal\",\n icon: FileTextIcon,\n url: \"#\",\n items: [\n {\n title: \"Active Proposals\",\n url: \"#\",\n },\n {\n title: \"Archived\",\n url: \"#\",\n },\n ],\n },\n {\n title: \"Prompts\",\n icon: FileCodeIcon,\n url: \"#\",\n items: [\n {\n title: \"Active Proposals\",\n url: \"#\",\n },\n {\n title: \"Archived\",\n url: \"#\",\n },\n ],\n },\n ],\n navSecondary: [\n {\n title: \"Settings\",\n url: \"#\",\n icon: SettingsIcon,\n },\n {\n title: \"Get Help\",\n url: \"#\",\n icon: HelpCircleIcon,\n },\n {\n title: \"Search\",\n url: \"#\",\n icon: SearchIcon,\n },\n ],\n documents: [\n {\n name: \"Data Library\",\n url: \"#\",\n icon: DatabaseIcon,\n },\n {\n name: \"Reports\",\n url: \"#\",\n icon: ClipboardListIcon,\n },\n {\n name: \"Word Assistant\",\n url: \"#\",\n icon: FileIcon,\n },\n ],\n}\n\nexport function AppSidebar({ ...props }: React.ComponentProps) {\n return (\n \n \n \n \n \n \n \n Acme Inc.\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n )\n}\n", + "type": "registry:component", + "target": "" + }, + { + "path": "blocks/dashboard-01/components/chart-area-interactive.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Area, AreaChart, CartesianGrid, XAxis } from \"recharts\"\n\nimport { useIsMobile } from \"@/registry/new-york/hooks/use-mobile\"\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@/registry/new-york/ui/card\"\nimport {\n ChartConfig,\n ChartContainer,\n ChartTooltip,\n ChartTooltipContent,\n} from \"@/registry/new-york/ui/chart\"\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/registry/new-york/ui/select\"\nimport {\n ToggleGroup,\n ToggleGroupItem,\n} from \"@/registry/new-york/ui/toggle-group\"\nconst chartData = [\n { date: \"2024-04-01\", desktop: 222, mobile: 150 },\n { date: \"2024-04-02\", desktop: 97, mobile: 180 },\n { date: \"2024-04-03\", desktop: 167, mobile: 120 },\n { date: \"2024-04-04\", desktop: 242, mobile: 260 },\n { date: \"2024-04-05\", desktop: 373, mobile: 290 },\n { date: \"2024-04-06\", desktop: 301, mobile: 340 },\n { date: \"2024-04-07\", desktop: 245, mobile: 180 },\n { date: \"2024-04-08\", desktop: 409, mobile: 320 },\n { date: \"2024-04-09\", desktop: 59, mobile: 110 },\n { date: \"2024-04-10\", desktop: 261, mobile: 190 },\n { date: \"2024-04-11\", desktop: 327, mobile: 350 },\n { date: \"2024-04-12\", desktop: 292, mobile: 210 },\n { date: \"2024-04-13\", desktop: 342, mobile: 380 },\n { date: \"2024-04-14\", desktop: 137, mobile: 220 },\n { date: \"2024-04-15\", desktop: 120, mobile: 170 },\n { date: \"2024-04-16\", desktop: 138, mobile: 190 },\n { date: \"2024-04-17\", desktop: 446, mobile: 360 },\n { date: \"2024-04-18\", desktop: 364, mobile: 410 },\n { date: \"2024-04-19\", desktop: 243, mobile: 180 },\n { date: \"2024-04-20\", desktop: 89, mobile: 150 },\n { date: \"2024-04-21\", desktop: 137, mobile: 200 },\n { date: \"2024-04-22\", desktop: 224, mobile: 170 },\n { date: \"2024-04-23\", desktop: 138, mobile: 230 },\n { date: \"2024-04-24\", desktop: 387, mobile: 290 },\n { date: \"2024-04-25\", desktop: 215, mobile: 250 },\n { date: \"2024-04-26\", desktop: 75, mobile: 130 },\n { date: \"2024-04-27\", desktop: 383, mobile: 420 },\n { date: \"2024-04-28\", desktop: 122, mobile: 180 },\n { date: \"2024-04-29\", desktop: 315, mobile: 240 },\n { date: \"2024-04-30\", desktop: 454, mobile: 380 },\n { date: \"2024-05-01\", desktop: 165, mobile: 220 },\n { date: \"2024-05-02\", desktop: 293, mobile: 310 },\n { date: \"2024-05-03\", desktop: 247, mobile: 190 },\n { date: \"2024-05-04\", desktop: 385, mobile: 420 },\n { date: \"2024-05-05\", desktop: 481, mobile: 390 },\n { date: \"2024-05-06\", desktop: 498, mobile: 520 },\n { date: \"2024-05-07\", desktop: 388, mobile: 300 },\n { date: \"2024-05-08\", desktop: 149, mobile: 210 },\n { date: \"2024-05-09\", desktop: 227, mobile: 180 },\n { date: \"2024-05-10\", desktop: 293, mobile: 330 },\n { date: \"2024-05-11\", desktop: 335, mobile: 270 },\n { date: \"2024-05-12\", desktop: 197, mobile: 240 },\n { date: \"2024-05-13\", desktop: 197, mobile: 160 },\n { date: \"2024-05-14\", desktop: 448, mobile: 490 },\n { date: \"2024-05-15\", desktop: 473, mobile: 380 },\n { date: \"2024-05-16\", desktop: 338, mobile: 400 },\n { date: \"2024-05-17\", desktop: 499, mobile: 420 },\n { date: \"2024-05-18\", desktop: 315, mobile: 350 },\n { date: \"2024-05-19\", desktop: 235, mobile: 180 },\n { date: \"2024-05-20\", desktop: 177, mobile: 230 },\n { date: \"2024-05-21\", desktop: 82, mobile: 140 },\n { date: \"2024-05-22\", desktop: 81, mobile: 120 },\n { date: \"2024-05-23\", desktop: 252, mobile: 290 },\n { date: \"2024-05-24\", desktop: 294, mobile: 220 },\n { date: \"2024-05-25\", desktop: 201, mobile: 250 },\n { date: \"2024-05-26\", desktop: 213, mobile: 170 },\n { date: \"2024-05-27\", desktop: 420, mobile: 460 },\n { date: \"2024-05-28\", desktop: 233, mobile: 190 },\n { date: \"2024-05-29\", desktop: 78, mobile: 130 },\n { date: \"2024-05-30\", desktop: 340, mobile: 280 },\n { date: \"2024-05-31\", desktop: 178, mobile: 230 },\n { date: \"2024-06-01\", desktop: 178, mobile: 200 },\n { date: \"2024-06-02\", desktop: 470, mobile: 410 },\n { date: \"2024-06-03\", desktop: 103, mobile: 160 },\n { date: \"2024-06-04\", desktop: 439, mobile: 380 },\n { date: \"2024-06-05\", desktop: 88, mobile: 140 },\n { date: \"2024-06-06\", desktop: 294, mobile: 250 },\n { date: \"2024-06-07\", desktop: 323, mobile: 370 },\n { date: \"2024-06-08\", desktop: 385, mobile: 320 },\n { date: \"2024-06-09\", desktop: 438, mobile: 480 },\n { date: \"2024-06-10\", desktop: 155, mobile: 200 },\n { date: \"2024-06-11\", desktop: 92, mobile: 150 },\n { date: \"2024-06-12\", desktop: 492, mobile: 420 },\n { date: \"2024-06-13\", desktop: 81, mobile: 130 },\n { date: \"2024-06-14\", desktop: 426, mobile: 380 },\n { date: \"2024-06-15\", desktop: 307, mobile: 350 },\n { date: \"2024-06-16\", desktop: 371, mobile: 310 },\n { date: \"2024-06-17\", desktop: 475, mobile: 520 },\n { date: \"2024-06-18\", desktop: 107, mobile: 170 },\n { date: \"2024-06-19\", desktop: 341, mobile: 290 },\n { date: \"2024-06-20\", desktop: 408, mobile: 450 },\n { date: \"2024-06-21\", desktop: 169, mobile: 210 },\n { date: \"2024-06-22\", desktop: 317, mobile: 270 },\n { date: \"2024-06-23\", desktop: 480, mobile: 530 },\n { date: \"2024-06-24\", desktop: 132, mobile: 180 },\n { date: \"2024-06-25\", desktop: 141, mobile: 190 },\n { date: \"2024-06-26\", desktop: 434, mobile: 380 },\n { date: \"2024-06-27\", desktop: 448, mobile: 490 },\n { date: \"2024-06-28\", desktop: 149, mobile: 200 },\n { date: \"2024-06-29\", desktop: 103, mobile: 160 },\n { date: \"2024-06-30\", desktop: 446, mobile: 400 },\n]\n\nconst chartConfig = {\n visitors: {\n label: \"Visitors\",\n },\n desktop: {\n label: \"Desktop\",\n color: \"hsl(var(--chart-1))\",\n },\n mobile: {\n label: \"Mobile\",\n color: \"hsl(var(--chart-2))\",\n },\n} satisfies ChartConfig\n\nexport function ChartAreaInteractive() {\n const isMobile = useIsMobile()\n const [timeRange, setTimeRange] = React.useState(\"30d\")\n\n React.useEffect(() => {\n if (isMobile) {\n setTimeRange(\"7d\")\n }\n }, [isMobile])\n\n const filteredData = chartData.filter((item) => {\n const date = new Date(item.date)\n const referenceDate = new Date(\"2024-06-30\")\n let daysToSubtract = 90\n if (timeRange === \"30d\") {\n daysToSubtract = 30\n } else if (timeRange === \"7d\") {\n daysToSubtract = 7\n }\n const startDate = new Date(referenceDate)\n startDate.setDate(startDate.getDate() - daysToSubtract)\n return date >= startDate\n })\n\n return (\n \n \n Total Visitors\n \n \n Total for the last 3 months\n \n Last 3 months\n \n
\n \n \n Last 3 months\n \n \n Last 30 days\n \n \n Last 7 days\n \n \n \n
\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n {\n const date = new Date(value)\n return date.toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n })\n }}\n />\n {\n return new Date(value).toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n })\n }}\n indicator=\"dot\"\n />\n }\n />\n \n \n \n \n \n
\n )\n}\n", + "type": "registry:component", + "target": "" + }, + { + "path": "blocks/dashboard-01/components/data-table.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport {\n DndContext,\n KeyboardSensor,\n MouseSensor,\n TouchSensor,\n closestCenter,\n useSensor,\n useSensors,\n type DragEndEvent,\n type UniqueIdentifier,\n} from \"@dnd-kit/core\"\nimport { restrictToVerticalAxis } from \"@dnd-kit/modifiers\"\nimport {\n SortableContext,\n arrayMove,\n useSortable,\n verticalListSortingStrategy,\n} from \"@dnd-kit/sortable\"\nimport { CSS } from \"@dnd-kit/utilities\"\nimport {\n ColumnDef,\n ColumnFiltersState,\n Row,\n SortingState,\n VisibilityState,\n flexRender,\n getCoreRowModel,\n getFacetedRowModel,\n getFacetedUniqueValues,\n getFilteredRowModel,\n getPaginationRowModel,\n getSortedRowModel,\n useReactTable,\n} from \"@tanstack/react-table\"\nimport {\n CheckCircle2Icon,\n CheckCircleIcon,\n ChevronDownIcon,\n ChevronLeftIcon,\n ChevronRightIcon,\n ChevronsLeftIcon,\n ChevronsRightIcon,\n ColumnsIcon,\n GripVerticalIcon,\n LoaderIcon,\n MoreVerticalIcon,\n PlusIcon,\n TrendingUpIcon,\n} from \"lucide-react\"\nimport { Area, AreaChart, CartesianGrid, XAxis } from \"recharts\"\nimport { toast } from \"sonner\"\nimport { z } from \"zod\"\n\nimport { useIsMobile } from \"@/registry/new-york/hooks/use-mobile\"\nimport { Badge } from \"@/registry/new-york/ui/badge\"\nimport { Button } from \"@/registry/new-york/ui/button\"\nimport {\n ChartConfig,\n ChartContainer,\n ChartTooltip,\n ChartTooltipContent,\n} from \"@/registry/new-york/ui/chart\"\nimport { Checkbox } from \"@/registry/new-york/ui/checkbox\"\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/registry/new-york/ui/dropdown-menu\"\nimport { Input } from \"@/registry/new-york/ui/input\"\nimport { Label } from \"@/registry/new-york/ui/label\"\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/registry/new-york/ui/select\"\nimport { Separator } from \"@/registry/new-york/ui/separator\"\nimport {\n Sheet,\n SheetClose,\n SheetContent,\n SheetDescription,\n SheetFooter,\n SheetHeader,\n SheetTitle,\n SheetTrigger,\n} from \"@/registry/new-york/ui/sheet\"\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from \"@/registry/new-york/ui/table\"\nimport {\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from \"@/registry/new-york/ui/tabs\"\n\nexport const schema = z.object({\n id: z.number(),\n header: z.string(),\n type: z.string(),\n status: z.string(),\n target: z.string(),\n limit: z.string(),\n reviewer: z.string(),\n})\n\n// Create a separate component for the drag handle\nfunction DragHandle({ id }: { id: number }) {\n const { attributes, listeners } = useSortable({\n id,\n })\n\n return (\n \n \n Drag to reorder\n \n )\n}\n\nconst columns: ColumnDef>[] = [\n {\n id: \"drag\",\n header: () => null,\n cell: ({ row }) => ,\n },\n {\n id: \"select\",\n header: ({ table }) => (\n
\n table.toggleAllPageRowsSelected(!!value)}\n aria-label=\"Select all\"\n />\n
\n ),\n cell: ({ row }) => (\n
\n row.toggleSelected(!!value)}\n aria-label=\"Select row\"\n />\n
\n ),\n enableSorting: false,\n enableHiding: false,\n },\n {\n accessorKey: \"header\",\n header: \"Header\",\n cell: ({ row }) => {\n return \n },\n enableHiding: false,\n },\n {\n accessorKey: \"type\",\n header: \"Section Type\",\n cell: ({ row }) => (\n
\n \n {row.original.type}\n \n
\n ),\n },\n {\n accessorKey: \"status\",\n header: \"Status\",\n cell: ({ row }) => (\n \n {row.original.status === \"Done\" ? (\n \n ) : (\n \n )}\n {row.original.status}\n \n ),\n },\n {\n accessorKey: \"target\",\n header: () =>
Target
,\n cell: ({ row }) => (\n {\n e.preventDefault()\n toast.promise(new Promise((resolve) => setTimeout(resolve, 1000)), {\n loading: `Saving ${row.original.header}`,\n success: \"Done\",\n error: \"Error\",\n })\n }}\n >\n \n \n \n ),\n },\n {\n accessorKey: \"limit\",\n header: () =>
Limit
,\n cell: ({ row }) => (\n {\n e.preventDefault()\n toast.promise(new Promise((resolve) => setTimeout(resolve, 1000)), {\n loading: `Saving ${row.original.header}`,\n success: \"Done\",\n error: \"Error\",\n })\n }}\n >\n \n \n \n ),\n },\n {\n accessorKey: \"reviewer\",\n header: \"Reviewer\",\n cell: ({ row }) => {\n const isAssigned = row.original.reviewer !== \"Assign reviewer\"\n\n if (isAssigned) {\n return row.original.reviewer\n }\n\n return (\n <>\n \n \n \n )\n },\n },\n {\n id: \"actions\",\n cell: () => (\n \n \n \n \n Open menu\n \n \n \n Edit\n Make a copy\n Favorite\n \n Delete\n \n \n ),\n },\n]\n\nfunction DraggableRow({ row }: { row: Row> }) {\n const { transform, transition, setNodeRef, isDragging } = useSortable({\n id: row.original.id,\n })\n\n return (\n \n {row.getVisibleCells().map((cell) => (\n \n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n \n ))}\n \n )\n}\n\nexport function DataTable({\n data: initialData,\n}: {\n data: z.infer[]\n}) {\n const [data, setData] = React.useState(() => initialData)\n const [rowSelection, setRowSelection] = React.useState({})\n const [columnVisibility, setColumnVisibility] =\n React.useState({})\n const [columnFilters, setColumnFilters] = React.useState(\n []\n )\n const [sorting, setSorting] = React.useState([])\n const [pagination, setPagination] = React.useState({\n pageIndex: 0,\n pageSize: 10,\n })\n const sortableId = React.useId()\n const sensors = useSensors(\n useSensor(MouseSensor, {}),\n useSensor(TouchSensor, {}),\n useSensor(KeyboardSensor, {})\n )\n\n const dataIds = React.useMemo(\n () => data?.map(({ id }) => id) || [],\n [data]\n )\n\n const table = useReactTable({\n data,\n columns,\n state: {\n sorting,\n columnVisibility,\n rowSelection,\n columnFilters,\n pagination,\n },\n getRowId: (row) => row.id.toString(),\n enableRowSelection: true,\n onRowSelectionChange: setRowSelection,\n onSortingChange: setSorting,\n onColumnFiltersChange: setColumnFilters,\n onColumnVisibilityChange: setColumnVisibility,\n onPaginationChange: setPagination,\n getCoreRowModel: getCoreRowModel(),\n getFilteredRowModel: getFilteredRowModel(),\n getPaginationRowModel: getPaginationRowModel(),\n getSortedRowModel: getSortedRowModel(),\n getFacetedRowModel: getFacetedRowModel(),\n getFacetedUniqueValues: getFacetedUniqueValues(),\n })\n\n function handleDragEnd(event: DragEndEvent) {\n const { active, over } = event\n if (active && over && active.id !== over.id) {\n setData((data) => {\n const oldIndex = dataIds.indexOf(active.id)\n const newIndex = dataIds.indexOf(over.id)\n return arrayMove(data, oldIndex, newIndex)\n })\n }\n }\n\n return (\n \n
\n \n \n \n Outline\n \n Past Performance{\" \"}\n \n 3\n \n \n \n Key Personnel{\" \"}\n \n 2\n \n \n Focus Documents\n \n
\n \n \n \n \n \n {table\n .getAllColumns()\n .filter(\n (column) =>\n typeof column.accessorFn !== \"undefined\" &&\n column.getCanHide()\n )\n .map((column) => {\n return (\n \n column.toggleVisibility(!!value)\n }\n >\n {column.id}\n \n )\n })}\n \n \n \n
\n
\n \n
\n \n \n \n {table.getHeaderGroups().map((headerGroup) => (\n \n {headerGroup.headers.map((header) => {\n return (\n \n {header.isPlaceholder\n ? null\n : flexRender(\n header.column.columnDef.header,\n header.getContext()\n )}\n \n )\n })}\n \n ))}\n \n \n {table.getRowModel().rows?.length ? (\n \n {table.getRowModel().rows.map((row) => (\n \n ))}\n \n ) : (\n \n \n No results.\n \n \n )}\n \n
\n \n
\n
\n
\n {table.getFilteredSelectedRowModel().rows.length} of{\" \"}\n {table.getFilteredRowModel().rows.length} row(s) selected.\n
\n
\n
\n \n {\n table.setPageSize(Number(value))\n }}\n >\n \n \n \n \n {[10, 20, 30, 40, 50].map((pageSize) => (\n \n {pageSize}\n \n ))}\n \n \n
\n
\n Page {table.getState().pagination.pageIndex + 1} of{\" \"}\n {table.getPageCount()}\n
\n
\n table.setPageIndex(0)}\n disabled={!table.getCanPreviousPage()}\n >\n Go to first page\n \n \n table.previousPage()}\n disabled={!table.getCanPreviousPage()}\n >\n Go to previous page\n \n \n table.nextPage()}\n disabled={!table.getCanNextPage()}\n >\n Go to next page\n \n \n table.setPageIndex(table.getPageCount() - 1)}\n disabled={!table.getCanNextPage()}\n >\n Go to last page\n \n \n
\n
\n
\n \n \n
\n \n \n
\n
\n \n
\n \n \n )\n}\n\nconst chartData = [\n { month: \"January\", desktop: 186, mobile: 80 },\n { month: \"February\", desktop: 305, mobile: 200 },\n { month: \"March\", desktop: 237, mobile: 120 },\n { month: \"April\", desktop: 73, mobile: 190 },\n { month: \"May\", desktop: 209, mobile: 130 },\n { month: \"June\", desktop: 214, mobile: 140 },\n]\n\nconst chartConfig = {\n desktop: {\n label: \"Desktop\",\n color: \"var(--primary)\",\n },\n mobile: {\n label: \"Mobile\",\n color: \"var(--primary)\",\n },\n} satisfies ChartConfig\n\nfunction TableCellViewer({ item }: { item: z.infer }) {\n const isMobile = useIsMobile()\n\n return (\n \n \n \n \n \n \n {item.header}\n \n Showing total visitors for the last 6 months\n \n \n
\n {!isMobile && (\n <>\n \n \n \n value.slice(0, 3)}\n hide\n />\n }\n />\n \n \n \n \n \n
\n
\n Trending up by 5.2% this month{\" \"}\n \n
\n
\n Showing total visitors for the last 6 months. This is just\n some random text to test the layout. It spans multiple lines\n and should wrap around.\n
\n
\n \n \n )}\n
\n
\n \n \n
\n
\n
\n \n \n
\n
\n \n \n
\n
\n
\n
\n \n \n
\n
\n \n \n
\n
\n
\n \n \n
\n
\n
\n \n \n \n \n \n \n
\n
\n )\n}\n", + "type": "registry:component", + "target": "" + }, + { + "path": "blocks/dashboard-01/components/nav-documents.tsx", + "content": "\"use client\"\n\nimport {\n FolderIcon,\n MoreHorizontalIcon,\n ShareIcon,\n type LucideIcon,\n} from \"lucide-react\"\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@/registry/new-york/ui/dropdown-menu\"\nimport {\n SidebarGroup,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuButton,\n SidebarMenuItem,\n useSidebar,\n} from \"@/registry/new-york/ui/sidebar\"\n\nexport function NavDocuments({\n items,\n}: {\n items: {\n name: string\n url: string\n icon: LucideIcon\n }[]\n}) {\n const { isMobile } = useSidebar()\n\n return (\n \n Documents\n \n {items.map((item) => (\n \n \n \n \n {item.name}\n \n \n \n \n \n \n More\n \n \n \n \n \n Open\n \n \n \n Share\n \n \n \n \n ))}\n \n \n \n More\n \n \n \n \n )\n}\n", + "type": "registry:component", + "target": "" + }, + { + "path": "blocks/dashboard-01/components/nav-main.tsx", + "content": "\"use client\"\n\nimport { MailIcon, PlusCircleIcon, type LucideIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/new-york/ui/button\"\nimport {\n SidebarGroup,\n SidebarGroupContent,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from \"@/registry/new-york/ui/sidebar\"\n\nexport function NavMain({\n items,\n}: {\n items: {\n title: string\n url: string\n icon?: LucideIcon\n }[]\n}) {\n return (\n \n \n \n \n \n \n Quick Create\n \n \n \n Inbox\n \n \n \n \n {items.map((item) => (\n \n \n {item.icon && }\n {item.title}\n \n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component", + "target": "" + }, + { + "path": "blocks/dashboard-01/components/nav-secondary.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { LucideIcon } from \"lucide-react\"\n\nimport {\n SidebarGroup,\n SidebarGroupContent,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from \"@/registry/new-york/ui/sidebar\"\n\nexport function NavSecondary({\n items,\n ...props\n}: {\n items: {\n title: string\n url: string\n icon: LucideIcon\n }[]\n} & React.ComponentPropsWithoutRef) {\n return (\n \n \n \n {items.map((item) => (\n \n \n \n \n {item.title}\n \n \n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component", + "target": "" + }, + { + "path": "blocks/dashboard-01/components/nav-user.tsx", + "content": "\"use client\"\n\nimport {\n BellIcon,\n CreditCardIcon,\n LogOutIcon,\n MoreVerticalIcon,\n UserCircleIcon,\n} from \"lucide-react\"\n\nimport {\n Avatar,\n AvatarFallback,\n AvatarImage,\n} from \"@/registry/new-york/ui/avatar\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/registry/new-york/ui/dropdown-menu\"\nimport {\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n useSidebar,\n} from \"@/registry/new-york/ui/sidebar\"\n\nexport function NavUser({\n user,\n}: {\n user: {\n name: string\n email: string\n avatar: string\n }\n}) {\n const { isMobile } = useSidebar()\n\n return (\n \n \n \n \n \n \n \n CN\n \n
\n {user.name}\n \n {user.email}\n \n
\n \n \n
\n \n \n
\n \n \n CN\n \n
\n {user.name}\n \n {user.email}\n \n
\n
\n
\n \n \n \n \n Account\n \n \n \n Billing\n \n \n \n Notifications\n \n \n \n \n \n Log out\n \n \n
\n
\n
\n )\n}\n", + "type": "registry:component", + "target": "" + }, + { + "path": "blocks/dashboard-01/components/section-cards.tsx", + "content": "import { TrendingDownIcon, TrendingUpIcon } from \"lucide-react\"\n\nimport { Badge } from \"@/registry/new-york/ui/badge\"\nimport {\n Card,\n CardDescription,\n CardFooter,\n CardHeader,\n CardTitle,\n} from \"@/registry/new-york/ui/card\"\n\nexport function SectionCards() {\n return (\n
\n \n \n Total Revenue\n \n $1,250.00\n \n
\n \n \n +12.5%\n \n
\n
\n \n
\n Trending up this month \n
\n
\n Visitors for the last 6 months\n
\n
\n
\n \n \n New Customers\n \n 1,234\n \n
\n \n \n -20%\n \n
\n
\n \n
\n Down 20% this period \n
\n
\n Acquisition needs attention\n
\n
\n
\n \n \n Active Accounts\n \n 45,678\n \n
\n \n \n +12.5%\n \n
\n
\n \n
\n Strong user retention \n
\n
Engagement exceed targets
\n
\n
\n \n \n Growth Rate\n \n 4.5%\n \n
\n \n \n +4.5%\n \n
\n
\n \n
\n Steady performance \n
\n
Meets growth projections
\n
\n
\n
\n )\n}\n", + "type": "registry:component", + "target": "" + }, + { + "path": "blocks/dashboard-01/components/site-header.tsx", + "content": "import { Separator } from \"@/registry/new-york/ui/separator\"\nimport { SidebarTrigger } from \"@/registry/new-york/ui/sidebar\"\n\nexport function SiteHeader() {\n return (\n
\n
\n \n \n

Documents

\n
\n
\n )\n}\n", + "type": "registry:component", + "target": "" + } + ], + "categories": [ + "dashboard" + ] +} \ No newline at end of file diff --git a/apps/www/public/r/styles/new-york/sidebar-16-dark.png b/apps/www/public/r/styles/new-york/sidebar-16-dark.png new file mode 100644 index 0000000000..a52e11ff9d Binary files /dev/null and b/apps/www/public/r/styles/new-york/sidebar-16-dark.png differ diff --git a/apps/www/public/r/styles/new-york/sidebar-16-light.png b/apps/www/public/r/styles/new-york/sidebar-16-light.png new file mode 100644 index 0000000000..cd0f455981 Binary files /dev/null and b/apps/www/public/r/styles/new-york/sidebar-16-light.png differ diff --git a/apps/www/registry/default/blocks/dashboard-01/components/app-sidebar.tsx b/apps/www/registry/default/blocks/dashboard-01/components/app-sidebar.tsx new file mode 100644 index 0000000000..669efbfe4a --- /dev/null +++ b/apps/www/registry/default/blocks/dashboard-01/components/app-sidebar.tsx @@ -0,0 +1,181 @@ +"use client" + +import * as React from "react" +import { + ArrowUpCircleIcon, + BarChartIcon, + CameraIcon, + ClipboardListIcon, + DatabaseIcon, + FileCodeIcon, + FileIcon, + FileTextIcon, + FolderIcon, + HelpCircleIcon, + LayoutDashboardIcon, + ListIcon, + SearchIcon, + SettingsIcon, + UsersIcon, +} from "lucide-react" + +import { NavDocuments } from "@/registry/default/blocks/dashboard-01/components/nav-documents" +import { NavMain } from "@/registry/default/blocks/dashboard-01/components/nav-main" +import { NavSecondary } from "@/registry/default/blocks/dashboard-01/components/nav-secondary" +import { NavUser } from "@/registry/default/blocks/dashboard-01/components/nav-user" +import { + Sidebar, + SidebarContent, + SidebarFooter, + SidebarHeader, + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, +} from "@/registry/default/ui/sidebar" + +const data = { + user: { + name: "shadcn", + email: "m@example.com", + avatar: "/avatars/shadcn.jpg", + }, + navMain: [ + { + title: "Dashboard", + url: "#", + icon: LayoutDashboardIcon, + }, + { + title: "Lifecycle", + url: "#", + icon: ListIcon, + }, + { + title: "Analytics", + url: "#", + icon: BarChartIcon, + }, + { + title: "Projects", + url: "#", + icon: FolderIcon, + }, + { + title: "Team", + url: "#", + icon: UsersIcon, + }, + ], + navClouds: [ + { + title: "Capture", + icon: CameraIcon, + isActive: true, + url: "#", + items: [ + { + title: "Active Proposals", + url: "#", + }, + { + title: "Archived", + url: "#", + }, + ], + }, + { + title: "Proposal", + icon: FileTextIcon, + url: "#", + items: [ + { + title: "Active Proposals", + url: "#", + }, + { + title: "Archived", + url: "#", + }, + ], + }, + { + title: "Prompts", + icon: FileCodeIcon, + url: "#", + items: [ + { + title: "Active Proposals", + url: "#", + }, + { + title: "Archived", + url: "#", + }, + ], + }, + ], + navSecondary: [ + { + title: "Settings", + url: "#", + icon: SettingsIcon, + }, + { + title: "Get Help", + url: "#", + icon: HelpCircleIcon, + }, + { + title: "Search", + url: "#", + icon: SearchIcon, + }, + ], + documents: [ + { + name: "Data Library", + url: "#", + icon: DatabaseIcon, + }, + { + name: "Reports", + url: "#", + icon: ClipboardListIcon, + }, + { + name: "Word Assistant", + url: "#", + icon: FileIcon, + }, + ], +} + +export function AppSidebar({ ...props }: React.ComponentProps) { + return ( + + + + + + + + Acme Inc. + + + + + + + + + + + + + + + ) +} diff --git a/apps/www/registry/default/blocks/dashboard-01/components/chart-area-interactive.tsx b/apps/www/registry/default/blocks/dashboard-01/components/chart-area-interactive.tsx new file mode 100644 index 0000000000..1b77f6c425 --- /dev/null +++ b/apps/www/registry/default/blocks/dashboard-01/components/chart-area-interactive.tsx @@ -0,0 +1,295 @@ +"use client" + +import * as React from "react" +import { Area, AreaChart, CartesianGrid, XAxis } from "recharts" + +import { useIsMobile } from "@/registry/default/hooks/use-mobile" +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from "@/registry/default/ui/card" +import { + ChartConfig, + ChartContainer, + ChartTooltip, + ChartTooltipContent, +} from "@/registry/default/ui/chart" +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/registry/default/ui/select" +import { + ToggleGroup, + ToggleGroupItem, +} from "@/registry/default/ui/toggle-group" + +export const description = "An interactive area chart" + +const chartData = [ + { date: "2024-04-01", desktop: 222, mobile: 150 }, + { date: "2024-04-02", desktop: 97, mobile: 180 }, + { date: "2024-04-03", desktop: 167, mobile: 120 }, + { date: "2024-04-04", desktop: 242, mobile: 260 }, + { date: "2024-04-05", desktop: 373, mobile: 290 }, + { date: "2024-04-06", desktop: 301, mobile: 340 }, + { date: "2024-04-07", desktop: 245, mobile: 180 }, + { date: "2024-04-08", desktop: 409, mobile: 320 }, + { date: "2024-04-09", desktop: 59, mobile: 110 }, + { date: "2024-04-10", desktop: 261, mobile: 190 }, + { date: "2024-04-11", desktop: 327, mobile: 350 }, + { date: "2024-04-12", desktop: 292, mobile: 210 }, + { date: "2024-04-13", desktop: 342, mobile: 380 }, + { date: "2024-04-14", desktop: 137, mobile: 220 }, + { date: "2024-04-15", desktop: 120, mobile: 170 }, + { date: "2024-04-16", desktop: 138, mobile: 190 }, + { date: "2024-04-17", desktop: 446, mobile: 360 }, + { date: "2024-04-18", desktop: 364, mobile: 410 }, + { date: "2024-04-19", desktop: 243, mobile: 180 }, + { date: "2024-04-20", desktop: 89, mobile: 150 }, + { date: "2024-04-21", desktop: 137, mobile: 200 }, + { date: "2024-04-22", desktop: 224, mobile: 170 }, + { date: "2024-04-23", desktop: 138, mobile: 230 }, + { date: "2024-04-24", desktop: 387, mobile: 290 }, + { date: "2024-04-25", desktop: 215, mobile: 250 }, + { date: "2024-04-26", desktop: 75, mobile: 130 }, + { date: "2024-04-27", desktop: 383, mobile: 420 }, + { date: "2024-04-28", desktop: 122, mobile: 180 }, + { date: "2024-04-29", desktop: 315, mobile: 240 }, + { date: "2024-04-30", desktop: 454, mobile: 380 }, + { date: "2024-05-01", desktop: 165, mobile: 220 }, + { date: "2024-05-02", desktop: 293, mobile: 310 }, + { date: "2024-05-03", desktop: 247, mobile: 190 }, + { date: "2024-05-04", desktop: 385, mobile: 420 }, + { date: "2024-05-05", desktop: 481, mobile: 390 }, + { date: "2024-05-06", desktop: 498, mobile: 520 }, + { date: "2024-05-07", desktop: 388, mobile: 300 }, + { date: "2024-05-08", desktop: 149, mobile: 210 }, + { date: "2024-05-09", desktop: 227, mobile: 180 }, + { date: "2024-05-10", desktop: 293, mobile: 330 }, + { date: "2024-05-11", desktop: 335, mobile: 270 }, + { date: "2024-05-12", desktop: 197, mobile: 240 }, + { date: "2024-05-13", desktop: 197, mobile: 160 }, + { date: "2024-05-14", desktop: 448, mobile: 490 }, + { date: "2024-05-15", desktop: 473, mobile: 380 }, + { date: "2024-05-16", desktop: 338, mobile: 400 }, + { date: "2024-05-17", desktop: 499, mobile: 420 }, + { date: "2024-05-18", desktop: 315, mobile: 350 }, + { date: "2024-05-19", desktop: 235, mobile: 180 }, + { date: "2024-05-20", desktop: 177, mobile: 230 }, + { date: "2024-05-21", desktop: 82, mobile: 140 }, + { date: "2024-05-22", desktop: 81, mobile: 120 }, + { date: "2024-05-23", desktop: 252, mobile: 290 }, + { date: "2024-05-24", desktop: 294, mobile: 220 }, + { date: "2024-05-25", desktop: 201, mobile: 250 }, + { date: "2024-05-26", desktop: 213, mobile: 170 }, + { date: "2024-05-27", desktop: 420, mobile: 460 }, + { date: "2024-05-28", desktop: 233, mobile: 190 }, + { date: "2024-05-29", desktop: 78, mobile: 130 }, + { date: "2024-05-30", desktop: 340, mobile: 280 }, + { date: "2024-05-31", desktop: 178, mobile: 230 }, + { date: "2024-06-01", desktop: 178, mobile: 200 }, + { date: "2024-06-02", desktop: 470, mobile: 410 }, + { date: "2024-06-03", desktop: 103, mobile: 160 }, + { date: "2024-06-04", desktop: 439, mobile: 380 }, + { date: "2024-06-05", desktop: 88, mobile: 140 }, + { date: "2024-06-06", desktop: 294, mobile: 250 }, + { date: "2024-06-07", desktop: 323, mobile: 370 }, + { date: "2024-06-08", desktop: 385, mobile: 320 }, + { date: "2024-06-09", desktop: 438, mobile: 480 }, + { date: "2024-06-10", desktop: 155, mobile: 200 }, + { date: "2024-06-11", desktop: 92, mobile: 150 }, + { date: "2024-06-12", desktop: 492, mobile: 420 }, + { date: "2024-06-13", desktop: 81, mobile: 130 }, + { date: "2024-06-14", desktop: 426, mobile: 380 }, + { date: "2024-06-15", desktop: 307, mobile: 350 }, + { date: "2024-06-16", desktop: 371, mobile: 310 }, + { date: "2024-06-17", desktop: 475, mobile: 520 }, + { date: "2024-06-18", desktop: 107, mobile: 170 }, + { date: "2024-06-19", desktop: 341, mobile: 290 }, + { date: "2024-06-20", desktop: 408, mobile: 450 }, + { date: "2024-06-21", desktop: 169, mobile: 210 }, + { date: "2024-06-22", desktop: 317, mobile: 270 }, + { date: "2024-06-23", desktop: 480, mobile: 530 }, + { date: "2024-06-24", desktop: 132, mobile: 180 }, + { date: "2024-06-25", desktop: 141, mobile: 190 }, + { date: "2024-06-26", desktop: 434, mobile: 380 }, + { date: "2024-06-27", desktop: 448, mobile: 490 }, + { date: "2024-06-28", desktop: 149, mobile: 200 }, + { date: "2024-06-29", desktop: 103, mobile: 160 }, + { date: "2024-06-30", desktop: 446, mobile: 400 }, +] + +const chartConfig = { + visitors: { + label: "Visitors", + }, + desktop: { + label: "Desktop", + color: "hsl(var(--chart-1))", + }, + mobile: { + label: "Mobile", + color: "hsl(var(--chart-2))", + }, +} satisfies ChartConfig + +export function ChartAreaInteractive() { + const isMobile = useIsMobile() + const [timeRange, setTimeRange] = React.useState("30d") + + React.useEffect(() => { + if (isMobile) { + setTimeRange("7d") + } + }, [isMobile]) + + const filteredData = chartData.filter((item) => { + const date = new Date(item.date) + const referenceDate = new Date("2024-06-30") + let daysToSubtract = 90 + if (timeRange === "30d") { + daysToSubtract = 30 + } else if (timeRange === "7d") { + daysToSubtract = 7 + } + const startDate = new Date(referenceDate) + startDate.setDate(startDate.getDate() - daysToSubtract) + return date >= startDate + }) + + return ( + + + Total Visitors + + + Total for the last 3 months + + Last 3 months + +
+ + + Last 3 months + + + Last 30 days + + + Last 7 days + + + +
+
+ + + + + + + + + + + + + + + { + const date = new Date(value) + return date.toLocaleDateString("en-US", { + month: "short", + day: "numeric", + }) + }} + /> + { + return new Date(value).toLocaleDateString("en-US", { + month: "short", + day: "numeric", + }) + }} + indicator="dot" + /> + } + /> + + + + + +
+ ) +} diff --git a/apps/www/registry/default/blocks/dashboard-01/components/data-table.tsx b/apps/www/registry/default/blocks/dashboard-01/components/data-table.tsx new file mode 100644 index 0000000000..3cc784ddc2 --- /dev/null +++ b/apps/www/registry/default/blocks/dashboard-01/components/data-table.tsx @@ -0,0 +1,823 @@ +"use client" + +import * as React from "react" +import { + DndContext, + KeyboardSensor, + MouseSensor, + TouchSensor, + closestCenter, + useSensor, + useSensors, + type DragEndEvent, + type UniqueIdentifier, +} from "@dnd-kit/core" +import { restrictToVerticalAxis } from "@dnd-kit/modifiers" +import { + SortableContext, + arrayMove, + useSortable, + verticalListSortingStrategy, +} from "@dnd-kit/sortable" +import { CSS } from "@dnd-kit/utilities" +import { + ColumnDef, + ColumnFiltersState, + Row, + SortingState, + VisibilityState, + flexRender, + getCoreRowModel, + getFacetedRowModel, + getFacetedUniqueValues, + getFilteredRowModel, + getPaginationRowModel, + getSortedRowModel, + useReactTable, +} from "@tanstack/react-table" +import { + CheckCircle2Icon, + CheckCircleIcon, + ChevronDownIcon, + ChevronLeftIcon, + ChevronRightIcon, + ChevronsLeftIcon, + ChevronsRightIcon, + ColumnsIcon, + GripVerticalIcon, + LoaderIcon, + MoreVerticalIcon, + PlusIcon, + TrendingUpIcon, +} from "lucide-react" +import { Area, AreaChart, CartesianGrid, XAxis } from "recharts" +import { toast } from "sonner" +import { z } from "zod" + +import { useIsMobile } from "@/registry/default/hooks/use-mobile" +import { Badge } from "@/registry/default/ui/badge" +import { Button } from "@/registry/default/ui/button" +import { + ChartConfig, + ChartContainer, + ChartTooltip, + ChartTooltipContent, +} from "@/registry/default/ui/chart" +import { Checkbox } from "@/registry/default/ui/checkbox" +import { + DropdownMenu, + DropdownMenuCheckboxItem, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "@/registry/default/ui/dropdown-menu" +import { Input } from "@/registry/default/ui/input" +import { Label } from "@/registry/default/ui/label" +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/registry/default/ui/select" +import { Separator } from "@/registry/default/ui/separator" +import { + Sheet, + SheetClose, + SheetContent, + SheetDescription, + SheetFooter, + SheetHeader, + SheetTitle, + SheetTrigger, +} from "@/registry/default/ui/sheet" +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/registry/default/ui/table" +import { + Tabs, + TabsContent, + TabsList, + TabsTrigger, +} from "@/registry/default/ui/tabs" + +export const schema = z.object({ + id: z.number(), + header: z.string(), + type: z.string(), + status: z.string(), + target: z.string(), + limit: z.string(), + reviewer: z.string(), +}) + +// Create a separate component for the drag handle +function DragHandle({ id }: { id: number }) { + const { attributes, listeners } = useSortable({ + id, + }) + + return ( + + ) +} + +const columns: ColumnDef>[] = [ + { + id: "drag", + header: () => null, + cell: ({ row }) => , + }, + { + id: "select", + header: ({ table }) => ( +
+ table.toggleAllPageRowsSelected(!!value)} + aria-label="Select all" + /> +
+ ), + cell: ({ row }) => ( +
+ row.toggleSelected(!!value)} + aria-label="Select row" + /> +
+ ), + enableSorting: false, + enableHiding: false, + }, + { + accessorKey: "header", + header: "Header", + cell: ({ row }) => { + return + }, + enableHiding: false, + }, + { + accessorKey: "type", + header: "Section Type", + cell: ({ row }) => ( +
+ + {row.original.type} + +
+ ), + }, + { + accessorKey: "status", + header: "Status", + cell: ({ row }) => ( + + {row.original.status === "Done" ? ( + + ) : ( + + )} + {row.original.status} + + ), + }, + { + accessorKey: "target", + header: () =>
Target
, + cell: ({ row }) => ( +
{ + e.preventDefault() + toast.promise(new Promise((resolve) => setTimeout(resolve, 1000)), { + loading: `Saving ${row.original.header}`, + success: "Done", + error: "Error", + }) + }} + > + + +
+ ), + }, + { + accessorKey: "limit", + header: () =>
Limit
, + cell: ({ row }) => ( +
{ + e.preventDefault() + toast.promise(new Promise((resolve) => setTimeout(resolve, 1000)), { + loading: `Saving ${row.original.header}`, + success: "Done", + error: "Error", + }) + }} + > + + +
+ ), + }, + { + accessorKey: "reviewer", + header: "Reviewer", + cell: ({ row }) => { + const isAssigned = row.original.reviewer !== "Assign reviewer" + + if (isAssigned) { + return row.original.reviewer + } + + return ( + <> + + + + ) + }, + }, + { + id: "actions", + cell: () => ( + + + + + + Edit + Make a copy + Favorite + + Delete + + + ), + }, +] + +function DraggableRow({ row }: { row: Row> }) { + const { transform, transition, setNodeRef, isDragging } = useSortable({ + id: row.original.id, + }) + + return ( + + {row.getVisibleCells().map((cell) => ( + + {flexRender(cell.column.columnDef.cell, cell.getContext())} + + ))} + + ) +} + +export function DataTable({ + data: initialData, +}: { + data: z.infer[] +}) { + const [data, setData] = React.useState(() => initialData) + const [rowSelection, setRowSelection] = React.useState({}) + const [columnVisibility, setColumnVisibility] = + React.useState({}) + const [columnFilters, setColumnFilters] = React.useState( + [] + ) + const [sorting, setSorting] = React.useState([]) + const [pagination, setPagination] = React.useState({ + pageIndex: 0, + pageSize: 10, + }) + const sortableId = React.useId() + const sensors = useSensors( + useSensor(MouseSensor, {}), + useSensor(TouchSensor, {}), + useSensor(KeyboardSensor, {}) + ) + + const dataIds = React.useMemo( + () => data?.map(({ id }) => id) || [], + [data] + ) + + const table = useReactTable({ + data, + columns, + state: { + sorting, + columnVisibility, + rowSelection, + columnFilters, + pagination, + }, + getRowId: (row) => row.id.toString(), + enableRowSelection: true, + onRowSelectionChange: setRowSelection, + onSortingChange: setSorting, + onColumnFiltersChange: setColumnFilters, + onColumnVisibilityChange: setColumnVisibility, + onPaginationChange: setPagination, + getCoreRowModel: getCoreRowModel(), + getFilteredRowModel: getFilteredRowModel(), + getPaginationRowModel: getPaginationRowModel(), + getSortedRowModel: getSortedRowModel(), + getFacetedRowModel: getFacetedRowModel(), + getFacetedUniqueValues: getFacetedUniqueValues(), + }) + + function handleDragEnd(event: DragEndEvent) { + const { active, over } = event + if (active && over && active.id !== over.id) { + setData((data) => { + const oldIndex = dataIds.indexOf(active.id) + const newIndex = dataIds.indexOf(over.id) + return arrayMove(data, oldIndex, newIndex) + }) + } + } + + return ( + +
+ + + + Outline + + Past Performance{" "} + + 3 + + + + Key Personnel{" "} + + 2 + + + Focus Documents + +
+ + + + + + {table + .getAllColumns() + .filter( + (column) => + typeof column.accessorFn !== "undefined" && + column.getCanHide() + ) + .map((column) => { + return ( + + column.toggleVisibility(!!value) + } + > + {column.id} + + ) + })} + + + +
+
+ +
+ + + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => { + return ( + + {header.isPlaceholder + ? null + : flexRender( + header.column.columnDef.header, + header.getContext() + )} + + ) + })} + + ))} + + + {table.getRowModel().rows?.length ? ( + + {table.getRowModel().rows.map((row) => ( + + ))} + + ) : ( + + + No results. + + + )} + +
+
+
+
+
+ {table.getFilteredSelectedRowModel().rows.length} of{" "} + {table.getFilteredRowModel().rows.length} row(s) selected. +
+
+
+ + +
+
+ Page {table.getState().pagination.pageIndex + 1} of{" "} + {table.getPageCount()} +
+
+ + + + +
+
+
+
+ +
+
+ +
+
+ +
+
+
+ ) +} + +const chartData = [ + { month: "January", desktop: 186, mobile: 80 }, + { month: "February", desktop: 305, mobile: 200 }, + { month: "March", desktop: 237, mobile: 120 }, + { month: "April", desktop: 73, mobile: 190 }, + { month: "May", desktop: 209, mobile: 130 }, + { month: "June", desktop: 214, mobile: 140 }, +] + +const chartConfig = { + desktop: { + label: "Desktop", + color: "var(--primary)", + }, + mobile: { + label: "Mobile", + color: "var(--primary)", + }, +} satisfies ChartConfig + +function TableCellViewer({ item }: { item: z.infer }) { + const isMobile = useIsMobile() + + return ( + + + + + + + {item.header} + + Showing total visitors for the last 6 months + + +
+ {!isMobile && ( + <> + + + + value.slice(0, 3)} + hide + /> + } + /> + + + + + +
+
+ Trending up by 5.2% this month{" "} + +
+
+ Showing total visitors for the last 6 months. This is just + some random text to test the layout. It spans multiple lines + and should wrap around. +
+
+ + + )} +
+
+ + +
+
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+
+ + +
+
+
+ + + + + + +
+
+ ) +} diff --git a/apps/www/registry/default/blocks/dashboard-01/components/nav-documents.tsx b/apps/www/registry/default/blocks/dashboard-01/components/nav-documents.tsx new file mode 100644 index 0000000000..8dca2a5403 --- /dev/null +++ b/apps/www/registry/default/blocks/dashboard-01/components/nav-documents.tsx @@ -0,0 +1,85 @@ +"use client" + +import { + FolderIcon, + MoreHorizontalIcon, + ShareIcon, + type LucideIcon, +} from "lucide-react" + +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/registry/default/ui/dropdown-menu" +import { + SidebarGroup, + SidebarGroupLabel, + SidebarMenu, + SidebarMenuAction, + SidebarMenuButton, + SidebarMenuItem, + useSidebar, +} from "@/registry/default/ui/sidebar" + +export function NavDocuments({ + items, +}: { + items: { + name: string + url: string + icon: LucideIcon + }[] +}) { + const { isMobile } = useSidebar() + + return ( + + Documents + + {items.map((item) => ( + + + + + {item.name} + + + + + + + More + + + + + + Open + + + + Share + + + + + ))} + + + + More + + + + + ) +} diff --git a/apps/www/registry/default/blocks/dashboard-01/components/nav-main.tsx b/apps/www/registry/default/blocks/dashboard-01/components/nav-main.tsx new file mode 100644 index 0000000000..9c32f65ba8 --- /dev/null +++ b/apps/www/registry/default/blocks/dashboard-01/components/nav-main.tsx @@ -0,0 +1,58 @@ +"use client" + +import { MailIcon, PlusCircleIcon, type LucideIcon } from "lucide-react" + +import { Button } from "@/registry/default/ui/button" +import { + SidebarGroup, + SidebarGroupContent, + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, +} from "@/registry/default/ui/sidebar" + +export function NavMain({ + items, +}: { + items: { + title: string + url: string + icon?: LucideIcon + }[] +}) { + return ( + + + + + + + Quick Create + + + + + + {items.map((item) => ( + + + {item.icon && } + {item.title} + + + ))} + + + + ) +} diff --git a/apps/www/registry/default/blocks/dashboard-01/components/nav-secondary.tsx b/apps/www/registry/default/blocks/dashboard-01/components/nav-secondary.tsx new file mode 100644 index 0000000000..a4dc62d28d --- /dev/null +++ b/apps/www/registry/default/blocks/dashboard-01/components/nav-secondary.tsx @@ -0,0 +1,42 @@ +"use client" + +import * as React from "react" +import { LucideIcon } from "lucide-react" + +import { + SidebarGroup, + SidebarGroupContent, + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, +} from "@/registry/default/ui/sidebar" + +export function NavSecondary({ + items, + ...props +}: { + items: { + title: string + url: string + icon: LucideIcon + }[] +} & React.ComponentPropsWithoutRef) { + return ( + + + + {items.map((item) => ( + + + + + {item.title} + + + + ))} + + + + ) +} diff --git a/apps/www/registry/default/blocks/dashboard-01/components/nav-user.tsx b/apps/www/registry/default/blocks/dashboard-01/components/nav-user.tsx new file mode 100644 index 0000000000..8bc522afba --- /dev/null +++ b/apps/www/registry/default/blocks/dashboard-01/components/nav-user.tsx @@ -0,0 +1,110 @@ +"use client" + +import { + BellIcon, + CreditCardIcon, + LogOutIcon, + MoreVerticalIcon, + UserCircleIcon, +} from "lucide-react" + +import { + Avatar, + AvatarFallback, + AvatarImage, +} from "@/registry/default/ui/avatar" +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuGroup, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "@/registry/default/ui/dropdown-menu" +import { + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, + useSidebar, +} from "@/registry/default/ui/sidebar" + +export function NavUser({ + user, +}: { + user: { + name: string + email: string + avatar: string + } +}) { + const { isMobile } = useSidebar() + + return ( + + + + + + + + CN + +
+ {user.name} + + {user.email} + +
+ +
+
+ + +
+ + + CN + +
+ {user.name} + + {user.email} + +
+
+
+ + + + + Account + + + + Billing + + + + Notifications + + + + + + Log out + +
+
+
+
+ ) +} diff --git a/apps/www/registry/default/blocks/dashboard-01/components/section-cards.tsx b/apps/www/registry/default/blocks/dashboard-01/components/section-cards.tsx new file mode 100644 index 0000000000..3281cb5e9a --- /dev/null +++ b/apps/www/registry/default/blocks/dashboard-01/components/section-cards.tsx @@ -0,0 +1,101 @@ +import { TrendingDownIcon, TrendingUpIcon } from "lucide-react" + +import { Badge } from "@/registry/default/ui/badge" +import { + Card, + CardDescription, + CardFooter, + CardHeader, + CardTitle, +} from "@/registry/default/ui/card" + +export function SectionCards() { + return ( +
+ + + Total Revenue + + $1,250.00 + +
+ + + +12.5% + +
+
+ +
+ Trending up this month +
+
+ Visitors for the last 6 months +
+
+
+ + + New Customers + + 1,234 + +
+ + + -20% + +
+
+ +
+ Down 20% this period +
+
+ Acquisition needs attention +
+
+
+ + + Active Accounts + + 45,678 + +
+ + + +12.5% + +
+
+ +
+ Strong user retention +
+
Engagement exceed targets
+
+
+ + + Growth Rate + + 4.5% + +
+ + + +4.5% + +
+
+ +
+ Steady performance +
+
Meets growth projections
+
+
+
+ ) +} diff --git a/apps/www/registry/default/blocks/dashboard-01/components/site-header.tsx b/apps/www/registry/default/blocks/dashboard-01/components/site-header.tsx new file mode 100644 index 0000000000..2ed6e6abb5 --- /dev/null +++ b/apps/www/registry/default/blocks/dashboard-01/components/site-header.tsx @@ -0,0 +1,17 @@ +import { Separator } from "@/registry/default/ui/separator" +import { SidebarTrigger } from "@/registry/default/ui/sidebar" + +export function SiteHeader() { + return ( +
+
+ + +

Documents

+
+
+ ) +} diff --git a/apps/www/registry/default/blocks/dashboard-01/data.json b/apps/www/registry/default/blocks/dashboard-01/data.json new file mode 100644 index 0000000000..ec0873641b --- /dev/null +++ b/apps/www/registry/default/blocks/dashboard-01/data.json @@ -0,0 +1,614 @@ +[ + { + "id": 1, + "header": "Cover page", + "type": "Cover page", + "status": "In Process", + "target": "18", + "limit": "5", + "reviewer": "Eddie Lake" + }, + { + "id": 2, + "header": "Table of contents", + "type": "Table of contents", + "status": "Done", + "target": "29", + "limit": "24", + "reviewer": "Eddie Lake" + }, + { + "id": 3, + "header": "Executive summary", + "type": "Narrative", + "status": "Done", + "target": "10", + "limit": "13", + "reviewer": "Eddie Lake" + }, + { + "id": 4, + "header": "Technical approach", + "type": "Narrative", + "status": "Done", + "target": "27", + "limit": "23", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 5, + "header": "Design", + "type": "Narrative", + "status": "In Process", + "target": "2", + "limit": "16", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 6, + "header": "Capabilities", + "type": "Narrative", + "status": "In Process", + "target": "20", + "limit": "8", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 7, + "header": "Integration with existing systems", + "type": "Narrative", + "status": "In Process", + "target": "19", + "limit": "21", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 8, + "header": "Innovation and Advantages", + "type": "Narrative", + "status": "Done", + "target": "25", + "limit": "26", + "reviewer": "Assign reviewer" + }, + { + "id": 9, + "header": "Overview of EMR's Innovative Solutions", + "type": "Technical content", + "status": "Done", + "target": "7", + "limit": "23", + "reviewer": "Assign reviewer" + }, + { + "id": 10, + "header": "Advanced Algorithms and Machine Learning", + "type": "Narrative", + "status": "Done", + "target": "30", + "limit": "28", + "reviewer": "Assign reviewer" + }, + { + "id": 11, + "header": "Adaptive Communication Protocols", + "type": "Narrative", + "status": "Done", + "target": "9", + "limit": "31", + "reviewer": "Assign reviewer" + }, + { + "id": 12, + "header": "Advantages Over Current Technologies", + "type": "Narrative", + "status": "Done", + "target": "12", + "limit": "0", + "reviewer": "Assign reviewer" + }, + { + "id": 13, + "header": "Past Performance", + "type": "Narrative", + "status": "Done", + "target": "22", + "limit": "33", + "reviewer": "Assign reviewer" + }, + { + "id": 14, + "header": "Customer Feedback and Satisfaction Levels", + "type": "Narrative", + "status": "Done", + "target": "15", + "limit": "34", + "reviewer": "Assign reviewer" + }, + { + "id": 15, + "header": "Implementation Challenges and Solutions", + "type": "Narrative", + "status": "Done", + "target": "3", + "limit": "35", + "reviewer": "Assign reviewer" + }, + { + "id": 16, + "header": "Security Measures and Data Protection Policies", + "type": "Narrative", + "status": "In Process", + "target": "6", + "limit": "36", + "reviewer": "Assign reviewer" + }, + { + "id": 17, + "header": "Scalability and Future Proofing", + "type": "Narrative", + "status": "Done", + "target": "4", + "limit": "37", + "reviewer": "Assign reviewer" + }, + { + "id": 18, + "header": "Cost-Benefit Analysis", + "type": "Plain language", + "status": "Done", + "target": "14", + "limit": "38", + "reviewer": "Assign reviewer" + }, + { + "id": 19, + "header": "User Training and Onboarding Experience", + "type": "Narrative", + "status": "Done", + "target": "17", + "limit": "39", + "reviewer": "Assign reviewer" + }, + { + "id": 20, + "header": "Future Development Roadmap", + "type": "Narrative", + "status": "Done", + "target": "11", + "limit": "40", + "reviewer": "Assign reviewer" + }, + { + "id": 21, + "header": "System Architecture Overview", + "type": "Technical content", + "status": "In Process", + "target": "24", + "limit": "18", + "reviewer": "Maya Johnson" + }, + { + "id": 22, + "header": "Risk Management Plan", + "type": "Narrative", + "status": "Done", + "target": "15", + "limit": "22", + "reviewer": "Carlos Rodriguez" + }, + { + "id": 23, + "header": "Compliance Documentation", + "type": "Legal", + "status": "In Process", + "target": "31", + "limit": "27", + "reviewer": "Sarah Chen" + }, + { + "id": 24, + "header": "API Documentation", + "type": "Technical content", + "status": "Done", + "target": "8", + "limit": "12", + "reviewer": "Raj Patel" + }, + { + "id": 25, + "header": "User Interface Mockups", + "type": "Visual", + "status": "In Process", + "target": "19", + "limit": "25", + "reviewer": "Leila Ahmadi" + }, + { + "id": 26, + "header": "Database Schema", + "type": "Technical content", + "status": "Done", + "target": "22", + "limit": "20", + "reviewer": "Thomas Wilson" + }, + { + "id": 27, + "header": "Testing Methodology", + "type": "Technical content", + "status": "In Process", + "target": "17", + "limit": "14", + "reviewer": "Assign reviewer" + }, + { + "id": 28, + "header": "Deployment Strategy", + "type": "Narrative", + "status": "Done", + "target": "26", + "limit": "30", + "reviewer": "Eddie Lake" + }, + { + "id": 29, + "header": "Budget Breakdown", + "type": "Financial", + "status": "In Process", + "target": "13", + "limit": "16", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 30, + "header": "Market Analysis", + "type": "Research", + "status": "Done", + "target": "29", + "limit": "32", + "reviewer": "Sophia Martinez" + }, + { + "id": 31, + "header": "Competitor Comparison", + "type": "Research", + "status": "In Process", + "target": "21", + "limit": "19", + "reviewer": "Assign reviewer" + }, + { + "id": 32, + "header": "Maintenance Plan", + "type": "Technical content", + "status": "Done", + "target": "16", + "limit": "23", + "reviewer": "Alex Thompson" + }, + { + "id": 33, + "header": "User Personas", + "type": "Research", + "status": "In Process", + "target": "27", + "limit": "24", + "reviewer": "Nina Patel" + }, + { + "id": 34, + "header": "Accessibility Compliance", + "type": "Legal", + "status": "Done", + "target": "18", + "limit": "21", + "reviewer": "Assign reviewer" + }, + { + "id": 35, + "header": "Performance Metrics", + "type": "Technical content", + "status": "In Process", + "target": "23", + "limit": "26", + "reviewer": "David Kim" + }, + { + "id": 36, + "header": "Disaster Recovery Plan", + "type": "Technical content", + "status": "Done", + "target": "14", + "limit": "17", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 37, + "header": "Third-party Integrations", + "type": "Technical content", + "status": "In Process", + "target": "25", + "limit": "28", + "reviewer": "Eddie Lake" + }, + { + "id": 38, + "header": "User Feedback Summary", + "type": "Research", + "status": "Done", + "target": "20", + "limit": "15", + "reviewer": "Assign reviewer" + }, + { + "id": 39, + "header": "Localization Strategy", + "type": "Narrative", + "status": "In Process", + "target": "12", + "limit": "19", + "reviewer": "Maria Garcia" + }, + { + "id": 40, + "header": "Mobile Compatibility", + "type": "Technical content", + "status": "Done", + "target": "28", + "limit": "31", + "reviewer": "James Wilson" + }, + { + "id": 41, + "header": "Data Migration Plan", + "type": "Technical content", + "status": "In Process", + "target": "19", + "limit": "22", + "reviewer": "Assign reviewer" + }, + { + "id": 42, + "header": "Quality Assurance Protocols", + "type": "Technical content", + "status": "Done", + "target": "30", + "limit": "33", + "reviewer": "Priya Singh" + }, + { + "id": 43, + "header": "Stakeholder Analysis", + "type": "Research", + "status": "In Process", + "target": "11", + "limit": "14", + "reviewer": "Eddie Lake" + }, + { + "id": 44, + "header": "Environmental Impact Assessment", + "type": "Research", + "status": "Done", + "target": "24", + "limit": "27", + "reviewer": "Assign reviewer" + }, + { + "id": 45, + "header": "Intellectual Property Rights", + "type": "Legal", + "status": "In Process", + "target": "17", + "limit": "20", + "reviewer": "Sarah Johnson" + }, + { + "id": 46, + "header": "Customer Support Framework", + "type": "Narrative", + "status": "Done", + "target": "22", + "limit": "25", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 47, + "header": "Version Control Strategy", + "type": "Technical content", + "status": "In Process", + "target": "15", + "limit": "18", + "reviewer": "Assign reviewer" + }, + { + "id": 48, + "header": "Continuous Integration Pipeline", + "type": "Technical content", + "status": "Done", + "target": "26", + "limit": "29", + "reviewer": "Michael Chen" + }, + { + "id": 49, + "header": "Regulatory Compliance", + "type": "Legal", + "status": "In Process", + "target": "13", + "limit": "16", + "reviewer": "Assign reviewer" + }, + { + "id": 50, + "header": "User Authentication System", + "type": "Technical content", + "status": "Done", + "target": "28", + "limit": "31", + "reviewer": "Eddie Lake" + }, + { + "id": 51, + "header": "Data Analytics Framework", + "type": "Technical content", + "status": "In Process", + "target": "21", + "limit": "24", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 52, + "header": "Cloud Infrastructure", + "type": "Technical content", + "status": "Done", + "target": "16", + "limit": "19", + "reviewer": "Assign reviewer" + }, + { + "id": 53, + "header": "Network Security Measures", + "type": "Technical content", + "status": "In Process", + "target": "29", + "limit": "32", + "reviewer": "Lisa Wong" + }, + { + "id": 54, + "header": "Project Timeline", + "type": "Planning", + "status": "Done", + "target": "14", + "limit": "17", + "reviewer": "Eddie Lake" + }, + { + "id": 55, + "header": "Resource Allocation", + "type": "Planning", + "status": "In Process", + "target": "27", + "limit": "30", + "reviewer": "Assign reviewer" + }, + { + "id": 56, + "header": "Team Structure and Roles", + "type": "Planning", + "status": "Done", + "target": "20", + "limit": "23", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 57, + "header": "Communication Protocols", + "type": "Planning", + "status": "In Process", + "target": "15", + "limit": "18", + "reviewer": "Assign reviewer" + }, + { + "id": 58, + "header": "Success Metrics", + "type": "Planning", + "status": "Done", + "target": "30", + "limit": "33", + "reviewer": "Eddie Lake" + }, + { + "id": 59, + "header": "Internationalization Support", + "type": "Technical content", + "status": "In Process", + "target": "23", + "limit": "26", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 60, + "header": "Backup and Recovery Procedures", + "type": "Technical content", + "status": "Done", + "target": "18", + "limit": "21", + "reviewer": "Assign reviewer" + }, + { + "id": 61, + "header": "Monitoring and Alerting System", + "type": "Technical content", + "status": "In Process", + "target": "25", + "limit": "28", + "reviewer": "Daniel Park" + }, + { + "id": 62, + "header": "Code Review Guidelines", + "type": "Technical content", + "status": "Done", + "target": "12", + "limit": "15", + "reviewer": "Eddie Lake" + }, + { + "id": 63, + "header": "Documentation Standards", + "type": "Technical content", + "status": "In Process", + "target": "27", + "limit": "30", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 64, + "header": "Release Management Process", + "type": "Planning", + "status": "Done", + "target": "22", + "limit": "25", + "reviewer": "Assign reviewer" + }, + { + "id": 65, + "header": "Feature Prioritization Matrix", + "type": "Planning", + "status": "In Process", + "target": "19", + "limit": "22", + "reviewer": "Emma Davis" + }, + { + "id": 66, + "header": "Technical Debt Assessment", + "type": "Technical content", + "status": "Done", + "target": "24", + "limit": "27", + "reviewer": "Eddie Lake" + }, + { + "id": 67, + "header": "Capacity Planning", + "type": "Planning", + "status": "In Process", + "target": "21", + "limit": "24", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 68, + "header": "Service Level Agreements", + "type": "Legal", + "status": "Done", + "target": "26", + "limit": "29", + "reviewer": "Assign reviewer" + } +] diff --git a/apps/www/registry/default/blocks/dashboard-01/page.tsx b/apps/www/registry/default/blocks/dashboard-01/page.tsx new file mode 100644 index 0000000000..083e2a7f01 --- /dev/null +++ b/apps/www/registry/default/blocks/dashboard-01/page.tsx @@ -0,0 +1,30 @@ +import { AppSidebar } from "@/registry/default/blocks/dashboard-01/components/app-sidebar" +import { ChartAreaInteractive } from "@/registry/default/blocks/dashboard-01/components/chart-area-interactive" +import { DataTable } from "@/registry/default/blocks/dashboard-01/components/data-table" +import { SectionCards } from "@/registry/default/blocks/dashboard-01/components/section-cards" +import { SiteHeader } from "@/registry/default/blocks/dashboard-01/components/site-header" +import { SidebarInset, SidebarProvider } from "@/registry/default/ui/sidebar" + +import data from "./data.json" + +export default function Page() { + return ( + + + + +
+
+
+ +
+ +
+ +
+
+
+
+
+ ) +} diff --git a/apps/www/registry/new-york/blocks/dashboard-01/components/app-sidebar.tsx b/apps/www/registry/new-york/blocks/dashboard-01/components/app-sidebar.tsx new file mode 100644 index 0000000000..dfe2cad679 --- /dev/null +++ b/apps/www/registry/new-york/blocks/dashboard-01/components/app-sidebar.tsx @@ -0,0 +1,181 @@ +"use client" + +import * as React from "react" +import { + ArrowUpCircleIcon, + BarChartIcon, + CameraIcon, + ClipboardListIcon, + DatabaseIcon, + FileCodeIcon, + FileIcon, + FileTextIcon, + FolderIcon, + HelpCircleIcon, + LayoutDashboardIcon, + ListIcon, + SearchIcon, + SettingsIcon, + UsersIcon, +} from "lucide-react" + +import { NavDocuments } from "@/registry/new-york/blocks/dashboard-01/components/nav-documents" +import { NavMain } from "@/registry/new-york/blocks/dashboard-01/components/nav-main" +import { NavSecondary } from "@/registry/new-york/blocks/dashboard-01/components/nav-secondary" +import { NavUser } from "@/registry/new-york/blocks/dashboard-01/components/nav-user" +import { + Sidebar, + SidebarContent, + SidebarFooter, + SidebarHeader, + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, +} from "@/registry/new-york/ui/sidebar" + +const data = { + user: { + name: "shadcn", + email: "m@example.com", + avatar: "/avatars/shadcn.jpg", + }, + navMain: [ + { + title: "Dashboard", + url: "#", + icon: LayoutDashboardIcon, + }, + { + title: "Lifecycle", + url: "#", + icon: ListIcon, + }, + { + title: "Analytics", + url: "#", + icon: BarChartIcon, + }, + { + title: "Projects", + url: "#", + icon: FolderIcon, + }, + { + title: "Team", + url: "#", + icon: UsersIcon, + }, + ], + navClouds: [ + { + title: "Capture", + icon: CameraIcon, + isActive: true, + url: "#", + items: [ + { + title: "Active Proposals", + url: "#", + }, + { + title: "Archived", + url: "#", + }, + ], + }, + { + title: "Proposal", + icon: FileTextIcon, + url: "#", + items: [ + { + title: "Active Proposals", + url: "#", + }, + { + title: "Archived", + url: "#", + }, + ], + }, + { + title: "Prompts", + icon: FileCodeIcon, + url: "#", + items: [ + { + title: "Active Proposals", + url: "#", + }, + { + title: "Archived", + url: "#", + }, + ], + }, + ], + navSecondary: [ + { + title: "Settings", + url: "#", + icon: SettingsIcon, + }, + { + title: "Get Help", + url: "#", + icon: HelpCircleIcon, + }, + { + title: "Search", + url: "#", + icon: SearchIcon, + }, + ], + documents: [ + { + name: "Data Library", + url: "#", + icon: DatabaseIcon, + }, + { + name: "Reports", + url: "#", + icon: ClipboardListIcon, + }, + { + name: "Word Assistant", + url: "#", + icon: FileIcon, + }, + ], +} + +export function AppSidebar({ ...props }: React.ComponentProps) { + return ( + + + + + + + + Acme Inc. + + + + + + + + + + + + + + + ) +} diff --git a/apps/www/registry/new-york/blocks/dashboard-01/components/chart-area-interactive.tsx b/apps/www/registry/new-york/blocks/dashboard-01/components/chart-area-interactive.tsx new file mode 100644 index 0000000000..ae148f4dfb --- /dev/null +++ b/apps/www/registry/new-york/blocks/dashboard-01/components/chart-area-interactive.tsx @@ -0,0 +1,295 @@ +"use client" + +import * as React from "react" +import { Area, AreaChart, CartesianGrid, XAxis } from "recharts" + +import { useIsMobile } from "@/registry/new-york/hooks/use-mobile" +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from "@/registry/new-york/ui/card" +import { + ChartConfig, + ChartContainer, + ChartTooltip, + ChartTooltipContent, +} from "@/registry/new-york/ui/chart" +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/registry/new-york/ui/select" +import { + ToggleGroup, + ToggleGroupItem, +} from "@/registry/new-york/ui/toggle-group" + +export const description = "An interactive area chart" + +const chartData = [ + { date: "2024-04-01", desktop: 222, mobile: 150 }, + { date: "2024-04-02", desktop: 97, mobile: 180 }, + { date: "2024-04-03", desktop: 167, mobile: 120 }, + { date: "2024-04-04", desktop: 242, mobile: 260 }, + { date: "2024-04-05", desktop: 373, mobile: 290 }, + { date: "2024-04-06", desktop: 301, mobile: 340 }, + { date: "2024-04-07", desktop: 245, mobile: 180 }, + { date: "2024-04-08", desktop: 409, mobile: 320 }, + { date: "2024-04-09", desktop: 59, mobile: 110 }, + { date: "2024-04-10", desktop: 261, mobile: 190 }, + { date: "2024-04-11", desktop: 327, mobile: 350 }, + { date: "2024-04-12", desktop: 292, mobile: 210 }, + { date: "2024-04-13", desktop: 342, mobile: 380 }, + { date: "2024-04-14", desktop: 137, mobile: 220 }, + { date: "2024-04-15", desktop: 120, mobile: 170 }, + { date: "2024-04-16", desktop: 138, mobile: 190 }, + { date: "2024-04-17", desktop: 446, mobile: 360 }, + { date: "2024-04-18", desktop: 364, mobile: 410 }, + { date: "2024-04-19", desktop: 243, mobile: 180 }, + { date: "2024-04-20", desktop: 89, mobile: 150 }, + { date: "2024-04-21", desktop: 137, mobile: 200 }, + { date: "2024-04-22", desktop: 224, mobile: 170 }, + { date: "2024-04-23", desktop: 138, mobile: 230 }, + { date: "2024-04-24", desktop: 387, mobile: 290 }, + { date: "2024-04-25", desktop: 215, mobile: 250 }, + { date: "2024-04-26", desktop: 75, mobile: 130 }, + { date: "2024-04-27", desktop: 383, mobile: 420 }, + { date: "2024-04-28", desktop: 122, mobile: 180 }, + { date: "2024-04-29", desktop: 315, mobile: 240 }, + { date: "2024-04-30", desktop: 454, mobile: 380 }, + { date: "2024-05-01", desktop: 165, mobile: 220 }, + { date: "2024-05-02", desktop: 293, mobile: 310 }, + { date: "2024-05-03", desktop: 247, mobile: 190 }, + { date: "2024-05-04", desktop: 385, mobile: 420 }, + { date: "2024-05-05", desktop: 481, mobile: 390 }, + { date: "2024-05-06", desktop: 498, mobile: 520 }, + { date: "2024-05-07", desktop: 388, mobile: 300 }, + { date: "2024-05-08", desktop: 149, mobile: 210 }, + { date: "2024-05-09", desktop: 227, mobile: 180 }, + { date: "2024-05-10", desktop: 293, mobile: 330 }, + { date: "2024-05-11", desktop: 335, mobile: 270 }, + { date: "2024-05-12", desktop: 197, mobile: 240 }, + { date: "2024-05-13", desktop: 197, mobile: 160 }, + { date: "2024-05-14", desktop: 448, mobile: 490 }, + { date: "2024-05-15", desktop: 473, mobile: 380 }, + { date: "2024-05-16", desktop: 338, mobile: 400 }, + { date: "2024-05-17", desktop: 499, mobile: 420 }, + { date: "2024-05-18", desktop: 315, mobile: 350 }, + { date: "2024-05-19", desktop: 235, mobile: 180 }, + { date: "2024-05-20", desktop: 177, mobile: 230 }, + { date: "2024-05-21", desktop: 82, mobile: 140 }, + { date: "2024-05-22", desktop: 81, mobile: 120 }, + { date: "2024-05-23", desktop: 252, mobile: 290 }, + { date: "2024-05-24", desktop: 294, mobile: 220 }, + { date: "2024-05-25", desktop: 201, mobile: 250 }, + { date: "2024-05-26", desktop: 213, mobile: 170 }, + { date: "2024-05-27", desktop: 420, mobile: 460 }, + { date: "2024-05-28", desktop: 233, mobile: 190 }, + { date: "2024-05-29", desktop: 78, mobile: 130 }, + { date: "2024-05-30", desktop: 340, mobile: 280 }, + { date: "2024-05-31", desktop: 178, mobile: 230 }, + { date: "2024-06-01", desktop: 178, mobile: 200 }, + { date: "2024-06-02", desktop: 470, mobile: 410 }, + { date: "2024-06-03", desktop: 103, mobile: 160 }, + { date: "2024-06-04", desktop: 439, mobile: 380 }, + { date: "2024-06-05", desktop: 88, mobile: 140 }, + { date: "2024-06-06", desktop: 294, mobile: 250 }, + { date: "2024-06-07", desktop: 323, mobile: 370 }, + { date: "2024-06-08", desktop: 385, mobile: 320 }, + { date: "2024-06-09", desktop: 438, mobile: 480 }, + { date: "2024-06-10", desktop: 155, mobile: 200 }, + { date: "2024-06-11", desktop: 92, mobile: 150 }, + { date: "2024-06-12", desktop: 492, mobile: 420 }, + { date: "2024-06-13", desktop: 81, mobile: 130 }, + { date: "2024-06-14", desktop: 426, mobile: 380 }, + { date: "2024-06-15", desktop: 307, mobile: 350 }, + { date: "2024-06-16", desktop: 371, mobile: 310 }, + { date: "2024-06-17", desktop: 475, mobile: 520 }, + { date: "2024-06-18", desktop: 107, mobile: 170 }, + { date: "2024-06-19", desktop: 341, mobile: 290 }, + { date: "2024-06-20", desktop: 408, mobile: 450 }, + { date: "2024-06-21", desktop: 169, mobile: 210 }, + { date: "2024-06-22", desktop: 317, mobile: 270 }, + { date: "2024-06-23", desktop: 480, mobile: 530 }, + { date: "2024-06-24", desktop: 132, mobile: 180 }, + { date: "2024-06-25", desktop: 141, mobile: 190 }, + { date: "2024-06-26", desktop: 434, mobile: 380 }, + { date: "2024-06-27", desktop: 448, mobile: 490 }, + { date: "2024-06-28", desktop: 149, mobile: 200 }, + { date: "2024-06-29", desktop: 103, mobile: 160 }, + { date: "2024-06-30", desktop: 446, mobile: 400 }, +] + +const chartConfig = { + visitors: { + label: "Visitors", + }, + desktop: { + label: "Desktop", + color: "hsl(var(--chart-1))", + }, + mobile: { + label: "Mobile", + color: "hsl(var(--chart-2))", + }, +} satisfies ChartConfig + +export function ChartAreaInteractive() { + const isMobile = useIsMobile() + const [timeRange, setTimeRange] = React.useState("30d") + + React.useEffect(() => { + if (isMobile) { + setTimeRange("7d") + } + }, [isMobile]) + + const filteredData = chartData.filter((item) => { + const date = new Date(item.date) + const referenceDate = new Date("2024-06-30") + let daysToSubtract = 90 + if (timeRange === "30d") { + daysToSubtract = 30 + } else if (timeRange === "7d") { + daysToSubtract = 7 + } + const startDate = new Date(referenceDate) + startDate.setDate(startDate.getDate() - daysToSubtract) + return date >= startDate + }) + + return ( + + + Total Visitors + + + Total for the last 3 months + + Last 3 months + +
+ + + Last 3 months + + + Last 30 days + + + Last 7 days + + + +
+
+ + + + + + + + + + + + + + + { + const date = new Date(value) + return date.toLocaleDateString("en-US", { + month: "short", + day: "numeric", + }) + }} + /> + { + return new Date(value).toLocaleDateString("en-US", { + month: "short", + day: "numeric", + }) + }} + indicator="dot" + /> + } + /> + + + + + +
+ ) +} diff --git a/apps/www/registry/new-york/blocks/dashboard-01/components/data-table.tsx b/apps/www/registry/new-york/blocks/dashboard-01/components/data-table.tsx new file mode 100644 index 0000000000..b35db2c920 --- /dev/null +++ b/apps/www/registry/new-york/blocks/dashboard-01/components/data-table.tsx @@ -0,0 +1,823 @@ +"use client" + +import * as React from "react" +import { + DndContext, + KeyboardSensor, + MouseSensor, + TouchSensor, + closestCenter, + useSensor, + useSensors, + type DragEndEvent, + type UniqueIdentifier, +} from "@dnd-kit/core" +import { restrictToVerticalAxis } from "@dnd-kit/modifiers" +import { + SortableContext, + arrayMove, + useSortable, + verticalListSortingStrategy, +} from "@dnd-kit/sortable" +import { CSS } from "@dnd-kit/utilities" +import { + ColumnDef, + ColumnFiltersState, + Row, + SortingState, + VisibilityState, + flexRender, + getCoreRowModel, + getFacetedRowModel, + getFacetedUniqueValues, + getFilteredRowModel, + getPaginationRowModel, + getSortedRowModel, + useReactTable, +} from "@tanstack/react-table" +import { + CheckCircle2Icon, + CheckCircleIcon, + ChevronDownIcon, + ChevronLeftIcon, + ChevronRightIcon, + ChevronsLeftIcon, + ChevronsRightIcon, + ColumnsIcon, + GripVerticalIcon, + LoaderIcon, + MoreVerticalIcon, + PlusIcon, + TrendingUpIcon, +} from "lucide-react" +import { Area, AreaChart, CartesianGrid, XAxis } from "recharts" +import { toast } from "sonner" +import { z } from "zod" + +import { useIsMobile } from "@/registry/new-york/hooks/use-mobile" +import { Badge } from "@/registry/new-york/ui/badge" +import { Button } from "@/registry/new-york/ui/button" +import { + ChartConfig, + ChartContainer, + ChartTooltip, + ChartTooltipContent, +} from "@/registry/new-york/ui/chart" +import { Checkbox } from "@/registry/new-york/ui/checkbox" +import { + DropdownMenu, + DropdownMenuCheckboxItem, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "@/registry/new-york/ui/dropdown-menu" +import { Input } from "@/registry/new-york/ui/input" +import { Label } from "@/registry/new-york/ui/label" +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/registry/new-york/ui/select" +import { Separator } from "@/registry/new-york/ui/separator" +import { + Sheet, + SheetClose, + SheetContent, + SheetDescription, + SheetFooter, + SheetHeader, + SheetTitle, + SheetTrigger, +} from "@/registry/new-york/ui/sheet" +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/registry/new-york/ui/table" +import { + Tabs, + TabsContent, + TabsList, + TabsTrigger, +} from "@/registry/new-york/ui/tabs" + +export const schema = z.object({ + id: z.number(), + header: z.string(), + type: z.string(), + status: z.string(), + target: z.string(), + limit: z.string(), + reviewer: z.string(), +}) + +// Create a separate component for the drag handle +function DragHandle({ id }: { id: number }) { + const { attributes, listeners } = useSortable({ + id, + }) + + return ( + + ) +} + +const columns: ColumnDef>[] = [ + { + id: "drag", + header: () => null, + cell: ({ row }) => , + }, + { + id: "select", + header: ({ table }) => ( +
+ table.toggleAllPageRowsSelected(!!value)} + aria-label="Select all" + /> +
+ ), + cell: ({ row }) => ( +
+ row.toggleSelected(!!value)} + aria-label="Select row" + /> +
+ ), + enableSorting: false, + enableHiding: false, + }, + { + accessorKey: "header", + header: "Header", + cell: ({ row }) => { + return + }, + enableHiding: false, + }, + { + accessorKey: "type", + header: "Section Type", + cell: ({ row }) => ( +
+ + {row.original.type} + +
+ ), + }, + { + accessorKey: "status", + header: "Status", + cell: ({ row }) => ( + + {row.original.status === "Done" ? ( + + ) : ( + + )} + {row.original.status} + + ), + }, + { + accessorKey: "target", + header: () =>
Target
, + cell: ({ row }) => ( +
{ + e.preventDefault() + toast.promise(new Promise((resolve) => setTimeout(resolve, 1000)), { + loading: `Saving ${row.original.header}`, + success: "Done", + error: "Error", + }) + }} + > + + +
+ ), + }, + { + accessorKey: "limit", + header: () =>
Limit
, + cell: ({ row }) => ( +
{ + e.preventDefault() + toast.promise(new Promise((resolve) => setTimeout(resolve, 1000)), { + loading: `Saving ${row.original.header}`, + success: "Done", + error: "Error", + }) + }} + > + + +
+ ), + }, + { + accessorKey: "reviewer", + header: "Reviewer", + cell: ({ row }) => { + const isAssigned = row.original.reviewer !== "Assign reviewer" + + if (isAssigned) { + return row.original.reviewer + } + + return ( + <> + + + + ) + }, + }, + { + id: "actions", + cell: () => ( + + + + + + Edit + Make a copy + Favorite + + Delete + + + ), + }, +] + +function DraggableRow({ row }: { row: Row> }) { + const { transform, transition, setNodeRef, isDragging } = useSortable({ + id: row.original.id, + }) + + return ( + + {row.getVisibleCells().map((cell) => ( + + {flexRender(cell.column.columnDef.cell, cell.getContext())} + + ))} + + ) +} + +export function DataTable({ + data: initialData, +}: { + data: z.infer[] +}) { + const [data, setData] = React.useState(() => initialData) + const [rowSelection, setRowSelection] = React.useState({}) + const [columnVisibility, setColumnVisibility] = + React.useState({}) + const [columnFilters, setColumnFilters] = React.useState( + [] + ) + const [sorting, setSorting] = React.useState([]) + const [pagination, setPagination] = React.useState({ + pageIndex: 0, + pageSize: 10, + }) + const sortableId = React.useId() + const sensors = useSensors( + useSensor(MouseSensor, {}), + useSensor(TouchSensor, {}), + useSensor(KeyboardSensor, {}) + ) + + const dataIds = React.useMemo( + () => data?.map(({ id }) => id) || [], + [data] + ) + + const table = useReactTable({ + data, + columns, + state: { + sorting, + columnVisibility, + rowSelection, + columnFilters, + pagination, + }, + getRowId: (row) => row.id.toString(), + enableRowSelection: true, + onRowSelectionChange: setRowSelection, + onSortingChange: setSorting, + onColumnFiltersChange: setColumnFilters, + onColumnVisibilityChange: setColumnVisibility, + onPaginationChange: setPagination, + getCoreRowModel: getCoreRowModel(), + getFilteredRowModel: getFilteredRowModel(), + getPaginationRowModel: getPaginationRowModel(), + getSortedRowModel: getSortedRowModel(), + getFacetedRowModel: getFacetedRowModel(), + getFacetedUniqueValues: getFacetedUniqueValues(), + }) + + function handleDragEnd(event: DragEndEvent) { + const { active, over } = event + if (active && over && active.id !== over.id) { + setData((data) => { + const oldIndex = dataIds.indexOf(active.id) + const newIndex = dataIds.indexOf(over.id) + return arrayMove(data, oldIndex, newIndex) + }) + } + } + + return ( + +
+ + + + Outline + + Past Performance{" "} + + 3 + + + + Key Personnel{" "} + + 2 + + + Focus Documents + +
+ + + + + + {table + .getAllColumns() + .filter( + (column) => + typeof column.accessorFn !== "undefined" && + column.getCanHide() + ) + .map((column) => { + return ( + + column.toggleVisibility(!!value) + } + > + {column.id} + + ) + })} + + + +
+
+ +
+ + + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => { + return ( + + {header.isPlaceholder + ? null + : flexRender( + header.column.columnDef.header, + header.getContext() + )} + + ) + })} + + ))} + + + {table.getRowModel().rows?.length ? ( + + {table.getRowModel().rows.map((row) => ( + + ))} + + ) : ( + + + No results. + + + )} + +
+
+
+
+
+ {table.getFilteredSelectedRowModel().rows.length} of{" "} + {table.getFilteredRowModel().rows.length} row(s) selected. +
+
+
+ + +
+
+ Page {table.getState().pagination.pageIndex + 1} of{" "} + {table.getPageCount()} +
+
+ + + + +
+
+
+
+ +
+
+ +
+
+ +
+
+
+ ) +} + +const chartData = [ + { month: "January", desktop: 186, mobile: 80 }, + { month: "February", desktop: 305, mobile: 200 }, + { month: "March", desktop: 237, mobile: 120 }, + { month: "April", desktop: 73, mobile: 190 }, + { month: "May", desktop: 209, mobile: 130 }, + { month: "June", desktop: 214, mobile: 140 }, +] + +const chartConfig = { + desktop: { + label: "Desktop", + color: "var(--primary)", + }, + mobile: { + label: "Mobile", + color: "var(--primary)", + }, +} satisfies ChartConfig + +function TableCellViewer({ item }: { item: z.infer }) { + const isMobile = useIsMobile() + + return ( + + + + + + + {item.header} + + Showing total visitors for the last 6 months + + +
+ {!isMobile && ( + <> + + + + value.slice(0, 3)} + hide + /> + } + /> + + + + + +
+
+ Trending up by 5.2% this month{" "} + +
+
+ Showing total visitors for the last 6 months. This is just + some random text to test the layout. It spans multiple lines + and should wrap around. +
+
+ + + )} +
+
+ + +
+
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+
+ + +
+
+
+ + + + + + +
+
+ ) +} diff --git a/apps/www/registry/new-york/blocks/dashboard-01/components/nav-documents.tsx b/apps/www/registry/new-york/blocks/dashboard-01/components/nav-documents.tsx new file mode 100644 index 0000000000..bcfad7ea2f --- /dev/null +++ b/apps/www/registry/new-york/blocks/dashboard-01/components/nav-documents.tsx @@ -0,0 +1,85 @@ +"use client" + +import { + FolderIcon, + MoreHorizontalIcon, + ShareIcon, + type LucideIcon, +} from "lucide-react" + +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/registry/new-york/ui/dropdown-menu" +import { + SidebarGroup, + SidebarGroupLabel, + SidebarMenu, + SidebarMenuAction, + SidebarMenuButton, + SidebarMenuItem, + useSidebar, +} from "@/registry/new-york/ui/sidebar" + +export function NavDocuments({ + items, +}: { + items: { + name: string + url: string + icon: LucideIcon + }[] +}) { + const { isMobile } = useSidebar() + + return ( + + Documents + + {items.map((item) => ( + + + + + {item.name} + + + + + + + More + + + + + + Open + + + + Share + + + + + ))} + + + + More + + + + + ) +} diff --git a/apps/www/registry/new-york/blocks/dashboard-01/components/nav-main.tsx b/apps/www/registry/new-york/blocks/dashboard-01/components/nav-main.tsx new file mode 100644 index 0000000000..eeaf24184b --- /dev/null +++ b/apps/www/registry/new-york/blocks/dashboard-01/components/nav-main.tsx @@ -0,0 +1,58 @@ +"use client" + +import { MailIcon, PlusCircleIcon, type LucideIcon } from "lucide-react" + +import { Button } from "@/registry/new-york/ui/button" +import { + SidebarGroup, + SidebarGroupContent, + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, +} from "@/registry/new-york/ui/sidebar" + +export function NavMain({ + items, +}: { + items: { + title: string + url: string + icon?: LucideIcon + }[] +}) { + return ( + + + + + + + Quick Create + + + + + + {items.map((item) => ( + + + {item.icon && } + {item.title} + + + ))} + + + + ) +} diff --git a/apps/www/registry/new-york/blocks/dashboard-01/components/nav-secondary.tsx b/apps/www/registry/new-york/blocks/dashboard-01/components/nav-secondary.tsx new file mode 100644 index 0000000000..151138c9b9 --- /dev/null +++ b/apps/www/registry/new-york/blocks/dashboard-01/components/nav-secondary.tsx @@ -0,0 +1,42 @@ +"use client" + +import * as React from "react" +import { LucideIcon } from "lucide-react" + +import { + SidebarGroup, + SidebarGroupContent, + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, +} from "@/registry/new-york/ui/sidebar" + +export function NavSecondary({ + items, + ...props +}: { + items: { + title: string + url: string + icon: LucideIcon + }[] +} & React.ComponentPropsWithoutRef) { + return ( + + + + {items.map((item) => ( + + + + + {item.title} + + + + ))} + + + + ) +} diff --git a/apps/www/registry/new-york/blocks/dashboard-01/components/nav-user.tsx b/apps/www/registry/new-york/blocks/dashboard-01/components/nav-user.tsx new file mode 100644 index 0000000000..b75da56331 --- /dev/null +++ b/apps/www/registry/new-york/blocks/dashboard-01/components/nav-user.tsx @@ -0,0 +1,110 @@ +"use client" + +import { + BellIcon, + CreditCardIcon, + LogOutIcon, + MoreVerticalIcon, + UserCircleIcon, +} from "lucide-react" + +import { + Avatar, + AvatarFallback, + AvatarImage, +} from "@/registry/new-york/ui/avatar" +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuGroup, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "@/registry/new-york/ui/dropdown-menu" +import { + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, + useSidebar, +} from "@/registry/new-york/ui/sidebar" + +export function NavUser({ + user, +}: { + user: { + name: string + email: string + avatar: string + } +}) { + const { isMobile } = useSidebar() + + return ( + + + + + + + + CN + +
+ {user.name} + + {user.email} + +
+ +
+
+ + +
+ + + CN + +
+ {user.name} + + {user.email} + +
+
+
+ + + + + Account + + + + Billing + + + + Notifications + + + + + + Log out + +
+
+
+
+ ) +} diff --git a/apps/www/registry/new-york/blocks/dashboard-01/components/section-cards.tsx b/apps/www/registry/new-york/blocks/dashboard-01/components/section-cards.tsx new file mode 100644 index 0000000000..e2d5943088 --- /dev/null +++ b/apps/www/registry/new-york/blocks/dashboard-01/components/section-cards.tsx @@ -0,0 +1,101 @@ +import { TrendingDownIcon, TrendingUpIcon } from "lucide-react" + +import { Badge } from "@/registry/new-york/ui/badge" +import { + Card, + CardDescription, + CardFooter, + CardHeader, + CardTitle, +} from "@/registry/new-york/ui/card" + +export function SectionCards() { + return ( +
+ + + Total Revenue + + $1,250.00 + +
+ + + +12.5% + +
+
+ +
+ Trending up this month +
+
+ Visitors for the last 6 months +
+
+
+ + + New Customers + + 1,234 + +
+ + + -20% + +
+
+ +
+ Down 20% this period +
+
+ Acquisition needs attention +
+
+
+ + + Active Accounts + + 45,678 + +
+ + + +12.5% + +
+
+ +
+ Strong user retention +
+
Engagement exceed targets
+
+
+ + + Growth Rate + + 4.5% + +
+ + + +4.5% + +
+
+ +
+ Steady performance +
+
Meets growth projections
+
+
+
+ ) +} diff --git a/apps/www/registry/new-york/blocks/dashboard-01/components/site-header.tsx b/apps/www/registry/new-york/blocks/dashboard-01/components/site-header.tsx new file mode 100644 index 0000000000..83c3755eab --- /dev/null +++ b/apps/www/registry/new-york/blocks/dashboard-01/components/site-header.tsx @@ -0,0 +1,17 @@ +import { Separator } from "@/registry/new-york/ui/separator" +import { SidebarTrigger } from "@/registry/new-york/ui/sidebar" + +export function SiteHeader() { + return ( +
+
+ + +

Documents

+
+
+ ) +} diff --git a/apps/www/registry/new-york/blocks/dashboard-01/data.json b/apps/www/registry/new-york/blocks/dashboard-01/data.json new file mode 100644 index 0000000000..ec0873641b --- /dev/null +++ b/apps/www/registry/new-york/blocks/dashboard-01/data.json @@ -0,0 +1,614 @@ +[ + { + "id": 1, + "header": "Cover page", + "type": "Cover page", + "status": "In Process", + "target": "18", + "limit": "5", + "reviewer": "Eddie Lake" + }, + { + "id": 2, + "header": "Table of contents", + "type": "Table of contents", + "status": "Done", + "target": "29", + "limit": "24", + "reviewer": "Eddie Lake" + }, + { + "id": 3, + "header": "Executive summary", + "type": "Narrative", + "status": "Done", + "target": "10", + "limit": "13", + "reviewer": "Eddie Lake" + }, + { + "id": 4, + "header": "Technical approach", + "type": "Narrative", + "status": "Done", + "target": "27", + "limit": "23", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 5, + "header": "Design", + "type": "Narrative", + "status": "In Process", + "target": "2", + "limit": "16", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 6, + "header": "Capabilities", + "type": "Narrative", + "status": "In Process", + "target": "20", + "limit": "8", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 7, + "header": "Integration with existing systems", + "type": "Narrative", + "status": "In Process", + "target": "19", + "limit": "21", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 8, + "header": "Innovation and Advantages", + "type": "Narrative", + "status": "Done", + "target": "25", + "limit": "26", + "reviewer": "Assign reviewer" + }, + { + "id": 9, + "header": "Overview of EMR's Innovative Solutions", + "type": "Technical content", + "status": "Done", + "target": "7", + "limit": "23", + "reviewer": "Assign reviewer" + }, + { + "id": 10, + "header": "Advanced Algorithms and Machine Learning", + "type": "Narrative", + "status": "Done", + "target": "30", + "limit": "28", + "reviewer": "Assign reviewer" + }, + { + "id": 11, + "header": "Adaptive Communication Protocols", + "type": "Narrative", + "status": "Done", + "target": "9", + "limit": "31", + "reviewer": "Assign reviewer" + }, + { + "id": 12, + "header": "Advantages Over Current Technologies", + "type": "Narrative", + "status": "Done", + "target": "12", + "limit": "0", + "reviewer": "Assign reviewer" + }, + { + "id": 13, + "header": "Past Performance", + "type": "Narrative", + "status": "Done", + "target": "22", + "limit": "33", + "reviewer": "Assign reviewer" + }, + { + "id": 14, + "header": "Customer Feedback and Satisfaction Levels", + "type": "Narrative", + "status": "Done", + "target": "15", + "limit": "34", + "reviewer": "Assign reviewer" + }, + { + "id": 15, + "header": "Implementation Challenges and Solutions", + "type": "Narrative", + "status": "Done", + "target": "3", + "limit": "35", + "reviewer": "Assign reviewer" + }, + { + "id": 16, + "header": "Security Measures and Data Protection Policies", + "type": "Narrative", + "status": "In Process", + "target": "6", + "limit": "36", + "reviewer": "Assign reviewer" + }, + { + "id": 17, + "header": "Scalability and Future Proofing", + "type": "Narrative", + "status": "Done", + "target": "4", + "limit": "37", + "reviewer": "Assign reviewer" + }, + { + "id": 18, + "header": "Cost-Benefit Analysis", + "type": "Plain language", + "status": "Done", + "target": "14", + "limit": "38", + "reviewer": "Assign reviewer" + }, + { + "id": 19, + "header": "User Training and Onboarding Experience", + "type": "Narrative", + "status": "Done", + "target": "17", + "limit": "39", + "reviewer": "Assign reviewer" + }, + { + "id": 20, + "header": "Future Development Roadmap", + "type": "Narrative", + "status": "Done", + "target": "11", + "limit": "40", + "reviewer": "Assign reviewer" + }, + { + "id": 21, + "header": "System Architecture Overview", + "type": "Technical content", + "status": "In Process", + "target": "24", + "limit": "18", + "reviewer": "Maya Johnson" + }, + { + "id": 22, + "header": "Risk Management Plan", + "type": "Narrative", + "status": "Done", + "target": "15", + "limit": "22", + "reviewer": "Carlos Rodriguez" + }, + { + "id": 23, + "header": "Compliance Documentation", + "type": "Legal", + "status": "In Process", + "target": "31", + "limit": "27", + "reviewer": "Sarah Chen" + }, + { + "id": 24, + "header": "API Documentation", + "type": "Technical content", + "status": "Done", + "target": "8", + "limit": "12", + "reviewer": "Raj Patel" + }, + { + "id": 25, + "header": "User Interface Mockups", + "type": "Visual", + "status": "In Process", + "target": "19", + "limit": "25", + "reviewer": "Leila Ahmadi" + }, + { + "id": 26, + "header": "Database Schema", + "type": "Technical content", + "status": "Done", + "target": "22", + "limit": "20", + "reviewer": "Thomas Wilson" + }, + { + "id": 27, + "header": "Testing Methodology", + "type": "Technical content", + "status": "In Process", + "target": "17", + "limit": "14", + "reviewer": "Assign reviewer" + }, + { + "id": 28, + "header": "Deployment Strategy", + "type": "Narrative", + "status": "Done", + "target": "26", + "limit": "30", + "reviewer": "Eddie Lake" + }, + { + "id": 29, + "header": "Budget Breakdown", + "type": "Financial", + "status": "In Process", + "target": "13", + "limit": "16", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 30, + "header": "Market Analysis", + "type": "Research", + "status": "Done", + "target": "29", + "limit": "32", + "reviewer": "Sophia Martinez" + }, + { + "id": 31, + "header": "Competitor Comparison", + "type": "Research", + "status": "In Process", + "target": "21", + "limit": "19", + "reviewer": "Assign reviewer" + }, + { + "id": 32, + "header": "Maintenance Plan", + "type": "Technical content", + "status": "Done", + "target": "16", + "limit": "23", + "reviewer": "Alex Thompson" + }, + { + "id": 33, + "header": "User Personas", + "type": "Research", + "status": "In Process", + "target": "27", + "limit": "24", + "reviewer": "Nina Patel" + }, + { + "id": 34, + "header": "Accessibility Compliance", + "type": "Legal", + "status": "Done", + "target": "18", + "limit": "21", + "reviewer": "Assign reviewer" + }, + { + "id": 35, + "header": "Performance Metrics", + "type": "Technical content", + "status": "In Process", + "target": "23", + "limit": "26", + "reviewer": "David Kim" + }, + { + "id": 36, + "header": "Disaster Recovery Plan", + "type": "Technical content", + "status": "Done", + "target": "14", + "limit": "17", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 37, + "header": "Third-party Integrations", + "type": "Technical content", + "status": "In Process", + "target": "25", + "limit": "28", + "reviewer": "Eddie Lake" + }, + { + "id": 38, + "header": "User Feedback Summary", + "type": "Research", + "status": "Done", + "target": "20", + "limit": "15", + "reviewer": "Assign reviewer" + }, + { + "id": 39, + "header": "Localization Strategy", + "type": "Narrative", + "status": "In Process", + "target": "12", + "limit": "19", + "reviewer": "Maria Garcia" + }, + { + "id": 40, + "header": "Mobile Compatibility", + "type": "Technical content", + "status": "Done", + "target": "28", + "limit": "31", + "reviewer": "James Wilson" + }, + { + "id": 41, + "header": "Data Migration Plan", + "type": "Technical content", + "status": "In Process", + "target": "19", + "limit": "22", + "reviewer": "Assign reviewer" + }, + { + "id": 42, + "header": "Quality Assurance Protocols", + "type": "Technical content", + "status": "Done", + "target": "30", + "limit": "33", + "reviewer": "Priya Singh" + }, + { + "id": 43, + "header": "Stakeholder Analysis", + "type": "Research", + "status": "In Process", + "target": "11", + "limit": "14", + "reviewer": "Eddie Lake" + }, + { + "id": 44, + "header": "Environmental Impact Assessment", + "type": "Research", + "status": "Done", + "target": "24", + "limit": "27", + "reviewer": "Assign reviewer" + }, + { + "id": 45, + "header": "Intellectual Property Rights", + "type": "Legal", + "status": "In Process", + "target": "17", + "limit": "20", + "reviewer": "Sarah Johnson" + }, + { + "id": 46, + "header": "Customer Support Framework", + "type": "Narrative", + "status": "Done", + "target": "22", + "limit": "25", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 47, + "header": "Version Control Strategy", + "type": "Technical content", + "status": "In Process", + "target": "15", + "limit": "18", + "reviewer": "Assign reviewer" + }, + { + "id": 48, + "header": "Continuous Integration Pipeline", + "type": "Technical content", + "status": "Done", + "target": "26", + "limit": "29", + "reviewer": "Michael Chen" + }, + { + "id": 49, + "header": "Regulatory Compliance", + "type": "Legal", + "status": "In Process", + "target": "13", + "limit": "16", + "reviewer": "Assign reviewer" + }, + { + "id": 50, + "header": "User Authentication System", + "type": "Technical content", + "status": "Done", + "target": "28", + "limit": "31", + "reviewer": "Eddie Lake" + }, + { + "id": 51, + "header": "Data Analytics Framework", + "type": "Technical content", + "status": "In Process", + "target": "21", + "limit": "24", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 52, + "header": "Cloud Infrastructure", + "type": "Technical content", + "status": "Done", + "target": "16", + "limit": "19", + "reviewer": "Assign reviewer" + }, + { + "id": 53, + "header": "Network Security Measures", + "type": "Technical content", + "status": "In Process", + "target": "29", + "limit": "32", + "reviewer": "Lisa Wong" + }, + { + "id": 54, + "header": "Project Timeline", + "type": "Planning", + "status": "Done", + "target": "14", + "limit": "17", + "reviewer": "Eddie Lake" + }, + { + "id": 55, + "header": "Resource Allocation", + "type": "Planning", + "status": "In Process", + "target": "27", + "limit": "30", + "reviewer": "Assign reviewer" + }, + { + "id": 56, + "header": "Team Structure and Roles", + "type": "Planning", + "status": "Done", + "target": "20", + "limit": "23", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 57, + "header": "Communication Protocols", + "type": "Planning", + "status": "In Process", + "target": "15", + "limit": "18", + "reviewer": "Assign reviewer" + }, + { + "id": 58, + "header": "Success Metrics", + "type": "Planning", + "status": "Done", + "target": "30", + "limit": "33", + "reviewer": "Eddie Lake" + }, + { + "id": 59, + "header": "Internationalization Support", + "type": "Technical content", + "status": "In Process", + "target": "23", + "limit": "26", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 60, + "header": "Backup and Recovery Procedures", + "type": "Technical content", + "status": "Done", + "target": "18", + "limit": "21", + "reviewer": "Assign reviewer" + }, + { + "id": 61, + "header": "Monitoring and Alerting System", + "type": "Technical content", + "status": "In Process", + "target": "25", + "limit": "28", + "reviewer": "Daniel Park" + }, + { + "id": 62, + "header": "Code Review Guidelines", + "type": "Technical content", + "status": "Done", + "target": "12", + "limit": "15", + "reviewer": "Eddie Lake" + }, + { + "id": 63, + "header": "Documentation Standards", + "type": "Technical content", + "status": "In Process", + "target": "27", + "limit": "30", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 64, + "header": "Release Management Process", + "type": "Planning", + "status": "Done", + "target": "22", + "limit": "25", + "reviewer": "Assign reviewer" + }, + { + "id": 65, + "header": "Feature Prioritization Matrix", + "type": "Planning", + "status": "In Process", + "target": "19", + "limit": "22", + "reviewer": "Emma Davis" + }, + { + "id": 66, + "header": "Technical Debt Assessment", + "type": "Technical content", + "status": "Done", + "target": "24", + "limit": "27", + "reviewer": "Eddie Lake" + }, + { + "id": 67, + "header": "Capacity Planning", + "type": "Planning", + "status": "In Process", + "target": "21", + "limit": "24", + "reviewer": "Jamik Tashpulatov" + }, + { + "id": 68, + "header": "Service Level Agreements", + "type": "Legal", + "status": "Done", + "target": "26", + "limit": "29", + "reviewer": "Assign reviewer" + } +] diff --git a/apps/www/registry/new-york/blocks/dashboard-01/page.tsx b/apps/www/registry/new-york/blocks/dashboard-01/page.tsx new file mode 100644 index 0000000000..e5602a4af1 --- /dev/null +++ b/apps/www/registry/new-york/blocks/dashboard-01/page.tsx @@ -0,0 +1,30 @@ +import { AppSidebar } from "@/registry/new-york/blocks/dashboard-01/components/app-sidebar" +import { ChartAreaInteractive } from "@/registry/new-york/blocks/dashboard-01/components/chart-area-interactive" +import { DataTable } from "@/registry/new-york/blocks/dashboard-01/components/data-table" +import { SectionCards } from "@/registry/new-york/blocks/dashboard-01/components/section-cards" +import { SiteHeader } from "@/registry/new-york/blocks/dashboard-01/components/site-header" +import { SidebarInset, SidebarProvider } from "@/registry/new-york/ui/sidebar" + +import data from "./data.json" + +export default function Page() { + return ( + + + + +
+
+
+ +
+ +
+ +
+
+
+
+
+ ) +} diff --git a/apps/www/registry/registry-blocks.ts b/apps/www/registry/registry-blocks.ts index 7f78413e58..f9cd06995f 100644 --- a/apps/www/registry/registry-blocks.ts +++ b/apps/www/registry/registry-blocks.ts @@ -1,6 +1,89 @@ import { type Registry } from "shadcn/registry" export const blocks: Registry["items"] = [ + { + name: "dashboard-01", + type: "registry:block", + description: "A dashboard with sidebar, charts and data table.", + dependencies: [ + "@dnd-kit/core", + "@dnd-kit/modifiers", + "@dnd-kit/sortable", + "@dnd-kit/utilities", + "@tanstack/react-table", + "zod", + ], + registryDependencies: [ + "sidebar", + "breadcrumb", + "separator", + "label", + "chart", + "card", + "select", + "tabs", + "table", + "toggle-group", + "badge", + "button", + "checkbox", + "dropdown-menu", + "drawer", + "input", + "avatar", + "sheet", + "sonner", + ], + files: [ + { + path: "blocks/dashboard-01/page.tsx", + type: "registry:page", + target: "app/dashboard/page.tsx", + }, + { + path: "blocks/dashboard-01/data.json", + type: "registry:file", + target: "app/dashboard/data.json", + }, + { + path: "blocks/dashboard-01/components/app-sidebar.tsx", + type: "registry:component", + }, + { + path: "blocks/dashboard-01/components/chart-area-interactive.tsx", + type: "registry:component", + }, + { + path: "blocks/dashboard-01/components/data-table.tsx", + type: "registry:component", + }, + { + path: "blocks/dashboard-01/components/nav-documents.tsx", + type: "registry:component", + }, + { + path: "blocks/dashboard-01/components/nav-main.tsx", + type: "registry:component", + }, + { + path: "blocks/dashboard-01/components/nav-secondary.tsx", + type: "registry:component", + }, + { + path: "blocks/dashboard-01/components/nav-user.tsx", + type: "registry:component", + }, + { + path: "blocks/dashboard-01/components/section-cards.tsx", + type: "registry:component", + }, + { + path: "blocks/dashboard-01/components/site-header.tsx", + type: "registry:component", + }, + ], + categories: ["dashboard"], + }, { name: "sidebar-01", type: "registry:block", diff --git a/apps/www/scripts/capture-registry.mts b/apps/www/scripts/capture-registry.mts index c40342ffc8..12c6f0f615 100644 --- a/apps/www/scripts/capture-registry.mts +++ b/apps/www/scripts/capture-registry.mts @@ -65,8 +65,8 @@ async function captureScreenshots() { await page.reload({ waitUntil: "networkidle2" }) // Wait for animations to complete - if (block.startsWith("chart")) { - await new Promise((resolve) => setTimeout(resolve, 500)) + if (block.startsWith("chart") || block.startsWith("dashboard")) { + await new Promise((resolve) => setTimeout(resolve, 1000)) } // Hide Tailwind indicator diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fcb87db8dd..4cdb945053 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -346,6 +346,18 @@ importers: apps/www: dependencies: + '@dnd-kit/core': + specifier: ^6.3.1 + version: 6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@dnd-kit/modifiers': + specifier: ^9.0.0 + version: 9.0.0(@dnd-kit/core@6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + '@dnd-kit/sortable': + specifier: ^10.0.0 + version: 10.0.0(@dnd-kit/core@6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + '@dnd-kit/utilities': + specifier: ^3.2.2 + version: 3.2.2(react@18.3.1) '@emotion/is-prop-valid': specifier: ^1.3.1 version: 1.3.1 @@ -445,6 +457,9 @@ importers: '@radix-ui/react-tooltip': specifier: ^1.0.6 version: 1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@tailwindcss/container-queries': + specifier: ^0.1.1 + version: 0.1.1(tailwindcss@3.4.6(ts-node@10.9.2(@types/node@17.0.45)(typescript@5.7.3))) '@tanstack/react-table': specifier: ^8.9.1 version: 8.20.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -2980,6 +2995,11 @@ packages: '@tabler/icons@3.31.0': resolution: {integrity: sha512-dblAdeKY3+GA1U+Q9eziZ0ooVlZMHsE8dqP0RkwvRtEsAULoKOYaCUOcJ4oW1DjWegdxk++UAt2SlQVnmeHv+g==} + '@tailwindcss/container-queries@0.1.1': + resolution: {integrity: sha512-p18dswChx6WnTSaJCSGx6lTmrGzNNvm2FtXmiO6AuA1V4U5REyoqwmT6kgAsIMdjo07QdAfYXHJ4hnMtfHzWgA==} + peerDependencies: + tailwindcss: '>=3.2.0' + '@tailwindcss/node@4.0.2': resolution: {integrity: sha512-/q5HXvgEc5GaaAhoVj8oeAw1TPRlZtRAnzWz2ChpFdKsEAVoHUAW6EX/tDr3tkUfQ1VVSBpxeGUg0V0gPZSs1A==} @@ -8816,11 +8836,24 @@ snapshots: dependencies: '@jridgewell/trace-mapping': 0.3.9 + '@dnd-kit/accessibility@3.1.1(react@18.3.1)': + dependencies: + react: 18.3.1 + tslib: 2.8.1 + '@dnd-kit/accessibility@3.1.1(react@19.0.0)': dependencies: react: 19.0.0 tslib: 2.8.1 + '@dnd-kit/core@6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@dnd-kit/accessibility': 3.1.1(react@18.3.1) + '@dnd-kit/utilities': 3.2.2(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + tslib: 2.8.1 + '@dnd-kit/core@6.3.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': dependencies: '@dnd-kit/accessibility': 3.1.1(react@19.0.0) @@ -8829,6 +8862,13 @@ snapshots: react-dom: 19.0.0(react@19.0.0) tslib: 2.8.1 + '@dnd-kit/modifiers@9.0.0(@dnd-kit/core@6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': + dependencies: + '@dnd-kit/core': 6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@dnd-kit/utilities': 3.2.2(react@18.3.1) + react: 18.3.1 + tslib: 2.8.1 + '@dnd-kit/modifiers@9.0.0(@dnd-kit/core@6.3.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0)': dependencies: '@dnd-kit/core': 6.3.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) @@ -8836,6 +8876,13 @@ snapshots: react: 19.0.0 tslib: 2.8.1 + '@dnd-kit/sortable@10.0.0(@dnd-kit/core@6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': + dependencies: + '@dnd-kit/core': 6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@dnd-kit/utilities': 3.2.2(react@18.3.1) + react: 18.3.1 + tslib: 2.8.1 + '@dnd-kit/sortable@10.0.0(@dnd-kit/core@6.3.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0)': dependencies: '@dnd-kit/core': 6.3.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) @@ -8843,6 +8890,11 @@ snapshots: react: 19.0.0 tslib: 2.8.1 + '@dnd-kit/utilities@3.2.2(react@18.3.1)': + dependencies: + react: 18.3.1 + tslib: 2.8.1 + '@dnd-kit/utilities@3.2.2(react@19.0.0)': dependencies: react: 19.0.0 @@ -11310,6 +11362,10 @@ snapshots: '@tabler/icons@3.31.0': {} + '@tailwindcss/container-queries@0.1.1(tailwindcss@3.4.6(ts-node@10.9.2(@types/node@17.0.45)(typescript@5.7.3)))': + dependencies: + tailwindcss: 3.4.6(ts-node@10.9.2(@types/node@17.0.45)(typescript@5.7.3)) + '@tailwindcss/node@4.0.2': dependencies: enhanced-resolve: 5.18.0 diff --git a/tailwind.config.cjs b/tailwind.config.cjs index 04e06cae50..2947cd26a7 100644 --- a/tailwind.config.cjs +++ b/tailwind.config.cjs @@ -82,5 +82,8 @@ module.exports = { }, }, }, - plugins: [require("tailwindcss-animate")], + plugins: [ + require("tailwindcss-animate"), + require("@tailwindcss/container-queries"), + ], }