├── .eslintrc.json ├── src ├── app │ ├── favicon.ico │ ├── layout.tsx │ ├── settings │ │ └── page.tsx │ ├── globals.css │ ├── page.tsx │ ├── orders │ │ └── page.tsx │ └── users │ │ └── page.tsx ├── lib │ └── utils.ts └── components │ ├── PageTitle.tsx │ ├── SalesCard.tsx │ ├── card.tsx │ ├── ui │ ├── tooltip.tsx │ ├── button.tsx │ ├── sidebar.tsx │ ├── table.tsx │ └── nav.tsx │ ├── BarChart.tsx │ └── DataTable.tsx ├── next.config.js ├── postcss.config.js ├── components.json ├── .gitignore ├── public ├── vercel.svg └── next.svg ├── tsconfig.json ├── package.json ├── README.md └── tailwind.config.js /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sachidumaleesha/shadcn-dashboard/HEAD/src/app/favicon.ico -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {} 3 | 4 | module.exports = nextConfig 5 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /src/lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { type ClassValue, clsx } from "clsx" 2 | import { twMerge } from "tailwind-merge" 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)) 6 | } 7 | -------------------------------------------------------------------------------- /src/components/PageTitle.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from '@/lib/utils'; 2 | import React from 'react' 3 | 4 | type Props = { 5 | title: string; 6 | classname?: string 7 | } 8 | 9 | export default function PageTitle({title, classname}: Props) { 10 | return ( 11 |

12 | {title} 13 |

14 | ) 15 | } -------------------------------------------------------------------------------- /components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "default", 4 | "rsc": true, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.js", 8 | "css": "src/app/globals.css", 9 | "baseColor": "slate", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils" 16 | } 17 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "noEmit": true, 9 | "esModuleInterop": true, 10 | "module": "esnext", 11 | "moduleResolution": "bundler", 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "jsx": "preserve", 15 | "incremental": true, 16 | "plugins": [ 17 | { 18 | "name": "next" 19 | } 20 | ], 21 | "paths": { 22 | "@/*": ["./src/*"] 23 | } 24 | }, 25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 26 | "exclude": ["node_modules"] 27 | } 28 | -------------------------------------------------------------------------------- /src/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from "next"; 2 | import { Inter } from "next/font/google"; 3 | import "./globals.css"; 4 | import { cn } from "@/lib/utils"; 5 | import Sidebar from "@/components/ui/sidebar"; 6 | 7 | const inter = Inter({ subsets: ["latin"] }); 8 | 9 | export const metadata: Metadata = { 10 | title: "Create Next App", 11 | description: "Generated by create next app", 12 | }; 13 | 14 | export default function RootLayout({ 15 | children, 16 | }: { 17 | children: React.ReactNode; 18 | }) { 19 | return ( 20 | 21 | 28 | {/* Sidebar */} 29 | 30 | {/* main page */} 31 |
{children}
32 | 33 | 34 | ); 35 | } 36 | -------------------------------------------------------------------------------- /src/components/SalesCard.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export type SalesProps = { 4 | name: string 5 | email: string 6 | salesAmount: string 7 | } 8 | 9 | export default function SalesCard(props: SalesProps) { 10 | return ( 11 |
12 |
13 |
14 | avatar 15 |
16 |
17 |

{props.name}

18 |
19 | {props.email} 20 |
21 | 22 |
23 |
24 |

{props.salesAmount}

25 |
26 | ) 27 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shadcn-dashboard", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@radix-ui/react-slot": "^1.0.2", 13 | "@radix-ui/react-tooltip": "^1.0.7", 14 | "@react-hook/window-size": "^3.1.1", 15 | "@tanstack/react-table": "^8.11.3", 16 | "class-variance-authority": "^0.7.0", 17 | "clsx": "^2.1.0", 18 | "lucide-react": "^0.308.0", 19 | "next": "14.0.4", 20 | "react": "^18", 21 | "react-dom": "^18", 22 | "recharts": "^2.10.4", 23 | "tailwind-merge": "^2.2.0", 24 | "tailwindcss-animate": "^1.0.7" 25 | }, 26 | "devDependencies": { 27 | "@types/node": "^20", 28 | "@types/react": "^18", 29 | "@types/react-dom": "^18", 30 | "autoprefixer": "^10.0.1", 31 | "eslint": "^8", 32 | "eslint-config-next": "14.0.4", 33 | "postcss": "^8", 34 | "tailwindcss": "^3.3.0", 35 | "tailwindcss-debug-screens": "^2.2.1", 36 | "typescript": "^5" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/components/card.tsx: -------------------------------------------------------------------------------- 1 | import { LucideIcon } from "lucide-react"; 2 | import React from "react"; 3 | import { cn } from "@/lib/utils"; 4 | 5 | export type CardProps = { 6 | label: string; 7 | icon: LucideIcon; 8 | amount: string; 9 | discription: string; 10 | }; 11 | 12 | export default function Card(props: CardProps) { 13 | return ( 14 | 15 |
16 | {/* label */} 17 |

{props.label}

18 | {/* icon */} 19 | 20 |
21 |
22 |

{props.amount}

23 |

{props.discription}

24 |
25 |
26 | ); 27 | } 28 | 29 | export function CardContent(props: React.HTMLAttributes) { 30 | return ( 31 |
38 | ); 39 | } 40 | -------------------------------------------------------------------------------- /src/components/ui/tooltip.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as TooltipPrimitive from "@radix-ui/react-tooltip" 5 | 6 | import { cn } from "@/lib/utils" 7 | 8 | const TooltipProvider = TooltipPrimitive.Provider 9 | 10 | const Tooltip = TooltipPrimitive.Root 11 | 12 | const TooltipTrigger = TooltipPrimitive.Trigger 13 | 14 | const TooltipContent = React.forwardRef< 15 | React.ElementRef, 16 | React.ComponentPropsWithoutRef 17 | >(({ className, sideOffset = 4, ...props }, ref) => ( 18 | 27 | )) 28 | TooltipContent.displayName = TooltipPrimitive.Content.displayName 29 | 30 | export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } 31 | -------------------------------------------------------------------------------- /public/next.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/settings/page.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * eslint-disable @next/next/no-img-element 3 | * 4 | * @format 5 | */ 6 | 7 | /** 8 | * eslint-disable @next/next/no-img-element 9 | * 10 | * @format 11 | */ 12 | 13 | /** @format */ 14 | "use client"; 15 | 16 | import { DataTable } from "@/components/DataTable"; 17 | import { ColumnDef } from "@tanstack/react-table"; 18 | import React from "react"; 19 | import PageTitle from "@/components/PageTitle"; 20 | import { cn } from "@/lib/utils"; 21 | 22 | type Props = {}; 23 | 24 | interface Setting { 25 | category: string; 26 | value: string | number | boolean; 27 | } 28 | 29 | const columns: ColumnDef[] = [ 30 | { 31 | accessorKey: "category", 32 | header: "Category" 33 | }, 34 | { 35 | accessorKey: "value", 36 | header: "Value" 37 | } 38 | ]; 39 | const data: Setting[] = [ 40 | { 41 | category: "Account", 42 | value: true 43 | }, 44 | { 45 | category: "Notifications", 46 | value: false 47 | }, 48 | { 49 | category: "Language", 50 | value: "English" 51 | }, 52 | { 53 | category: "Theme", 54 | value: "Dark" 55 | } 56 | ]; 57 | 58 | export default function SettingsPage({}: Props) { 59 | return ( 60 |
61 | 62 | 63 |
64 | ); 65 | } 66 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![image](https://github.com/sachidumaleesha/shadcn-dashboard/assets/45502921/e14d0957-4216-4754-961c-c9ab1e0b0cbd) 2 | 3 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). 4 | 5 | ## Getting Started 6 | 7 | First, run the development server: 8 | 9 | ```bash 10 | npm run dev 11 | # or 12 | yarn dev 13 | # or 14 | pnpm dev 15 | # or 16 | bun dev 17 | ``` 18 | 19 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 20 | 21 | You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. 22 | 23 | This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. 24 | 25 | ## Learn More 26 | 27 | To learn more about Next.js, take a look at the following resources: 28 | 29 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. 30 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. 31 | 32 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! 33 | 34 | ## Deploy on Vercel 35 | 36 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. 37 | 38 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. 39 | -------------------------------------------------------------------------------- /src/app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | @layer base { 6 | :root { 7 | --background: 0 0% 100%; 8 | --foreground: 222.2 84% 4.9%; 9 | 10 | --card: 0 0% 100%; 11 | --card-foreground: 222.2 84% 4.9%; 12 | 13 | --popover: 0 0% 100%; 14 | --popover-foreground: 222.2 84% 4.9%; 15 | 16 | --primary: 222.2 47.4% 11.2%; 17 | --primary-foreground: 210 40% 98%; 18 | 19 | --secondary: 210 40% 96.1%; 20 | --secondary-foreground: 222.2 47.4% 11.2%; 21 | 22 | --muted: 210 40% 96.1%; 23 | --muted-foreground: 215.4 16.3% 46.9%; 24 | 25 | --accent: 210 40% 96.1%; 26 | --accent-foreground: 222.2 47.4% 11.2%; 27 | 28 | --destructive: 0 84.2% 60.2%; 29 | --destructive-foreground: 210 40% 98%; 30 | 31 | --border: 214.3 31.8% 91.4%; 32 | --input: 214.3 31.8% 91.4%; 33 | --ring: 222.2 84% 4.9%; 34 | 35 | --radius: 0.5rem; 36 | } 37 | 38 | .dark { 39 | --background: 222.2 84% 4.9%; 40 | --foreground: 210 40% 98%; 41 | 42 | --card: 222.2 84% 4.9%; 43 | --card-foreground: 210 40% 98%; 44 | 45 | --popover: 222.2 84% 4.9%; 46 | --popover-foreground: 210 40% 98%; 47 | 48 | --primary: 210 40% 98%; 49 | --primary-foreground: 222.2 47.4% 11.2%; 50 | 51 | --secondary: 217.2 32.6% 17.5%; 52 | --secondary-foreground: 210 40% 98%; 53 | 54 | --muted: 217.2 32.6% 17.5%; 55 | --muted-foreground: 215 20.2% 65.1%; 56 | 57 | --accent: 217.2 32.6% 17.5%; 58 | --accent-foreground: 210 40% 98%; 59 | 60 | --destructive: 0 62.8% 30.6%; 61 | --destructive-foreground: 210 40% 98%; 62 | 63 | --border: 217.2 32.6% 17.5%; 64 | --input: 217.2 32.6% 17.5%; 65 | --ring: 212.7 26.8% 83.9%; 66 | } 67 | } 68 | 69 | @layer base { 70 | * { 71 | @apply border-border; 72 | } 73 | body { 74 | @apply bg-background text-foreground; 75 | } 76 | } -------------------------------------------------------------------------------- /src/components/ui/button.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import { Slot } from "@radix-ui/react-slot" 3 | import { cva, type VariantProps } from "class-variance-authority" 4 | 5 | import { cn } from "@/lib/utils" 6 | 7 | const buttonVariants = cva( 8 | "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", 9 | { 10 | variants: { 11 | variant: { 12 | default: "bg-primary text-primary-foreground hover:bg-primary/90", 13 | destructive: 14 | "bg-destructive text-destructive-foreground hover:bg-destructive/90", 15 | outline: 16 | "border border-input bg-background hover:bg-accent hover:text-accent-foreground", 17 | secondary: 18 | "bg-secondary text-secondary-foreground hover:bg-secondary/80", 19 | ghost: "hover:bg-accent hover:text-accent-foreground", 20 | link: "text-primary underline-offset-4 hover:underline", 21 | }, 22 | size: { 23 | default: "h-10 px-4 py-2", 24 | sm: "h-9 rounded-md px-3", 25 | lg: "h-11 rounded-md px-8", 26 | icon: "h-10 w-10", 27 | }, 28 | }, 29 | defaultVariants: { 30 | variant: "default", 31 | size: "default", 32 | }, 33 | } 34 | ) 35 | 36 | export interface ButtonProps 37 | extends React.ButtonHTMLAttributes, 38 | VariantProps { 39 | asChild?: boolean 40 | } 41 | 42 | const Button = React.forwardRef( 43 | ({ className, variant, size, asChild = false, ...props }, ref) => { 44 | const Comp = asChild ? Slot : "button" 45 | return ( 46 | 51 | ) 52 | } 53 | ) 54 | Button.displayName = "Button" 55 | 56 | export { Button, buttonVariants } 57 | -------------------------------------------------------------------------------- /src/components/BarChart.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | import React from 'react' 3 | import { Bar, ResponsiveContainer } from 'recharts' 4 | import { BarChart as BarGraph, XAxis, YAxis } from 'recharts' 5 | 6 | type Props = {} 7 | 8 | const data = [ 9 | { 10 | name: "Jan", 11 | total: Math.floor(Math.random() * 5000) + 1000 12 | }, 13 | { 14 | name: "Feb", 15 | total: Math.floor(Math.random() * 5000) + 1000 16 | }, 17 | { 18 | name: "Mar", 19 | total: Math.floor(Math.random() * 5000) + 1000 20 | }, 21 | { 22 | name: "Apr", 23 | total: Math.floor(Math.random() * 5000) + 1000 24 | }, 25 | { 26 | name: "May", 27 | total: Math.floor(Math.random() * 5000) + 1000 28 | }, 29 | { 30 | name: "Jun", 31 | total: Math.floor(Math.random() * 5000) + 1000 32 | }, 33 | { 34 | name: "Jul", 35 | total: Math.floor(Math.random() * 5000) + 1000 36 | }, 37 | { 38 | name: "Aug", 39 | total: Math.floor(Math.random() * 5000) + 1000 40 | }, 41 | { 42 | name: "Sep", 43 | total: Math.floor(Math.random() * 5000) + 1000 44 | }, 45 | { 46 | name: "Oct", 47 | total: Math.floor(Math.random() * 5000) + 1000 48 | }, 49 | { 50 | name: "Nov", 51 | total: Math.floor(Math.random() * 5000) + 1000 52 | }, 53 | { 54 | name: "Dec", 55 | total: Math.floor(Math.random() * 5000) + 1000 56 | } 57 | ]; 58 | 59 | export default function BarChart({}: Props) { 60 | return ( 61 | 62 | 63 | 70 | `$${value}`} 76 | /> 77 | 78 | 79 | 80 | ) 81 | } -------------------------------------------------------------------------------- /src/components/ui/sidebar.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | import React from 'react' 3 | import { Nav } from './nav' 4 | import { 5 | ChevronRight, 6 | LayoutDashboard, 7 | Settings, 8 | ShoppingCart, 9 | UsersRound, 10 | } from "lucide-react" 11 | import { Button } from './button' 12 | 13 | import { useWindowWidth } from '@react-hook/window-size' 14 | 15 | type Props = {} 16 | 17 | export default function Sidebar({}: Props) { 18 | 19 | const [isCollapsed, setIsCollapsed] = React.useState(false) 20 | 21 | const onlyWidth = useWindowWidth() 22 | const mobileWidth = onlyWidth < 768 23 | 24 | function toggleSidebar(){ 25 | setIsCollapsed(!isCollapsed) 26 | } 27 | return ( 28 |
29 | {!mobileWidth && 30 |
31 | 34 |
35 | } 36 |
66 | ) 67 | } -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | darkMode: ["class"], 4 | content: [ 5 | './pages/**/*.{ts,tsx}', 6 | './components/**/*.{ts,tsx}', 7 | './app/**/*.{ts,tsx}', 8 | './src/**/*.{ts,tsx}', 9 | ], 10 | prefix: "", 11 | theme: { 12 | container: { 13 | center: true, 14 | padding: "2rem", 15 | screens: { 16 | "2xl": "1400px", 17 | }, 18 | }, 19 | extend: { 20 | colors: { 21 | border: "hsl(var(--border))", 22 | input: "hsl(var(--input))", 23 | ring: "hsl(var(--ring))", 24 | background: "hsl(var(--background))", 25 | foreground: "hsl(var(--foreground))", 26 | primary: { 27 | DEFAULT: "hsl(var(--primary))", 28 | foreground: "hsl(var(--primary-foreground))", 29 | }, 30 | secondary: { 31 | DEFAULT: "hsl(var(--secondary))", 32 | foreground: "hsl(var(--secondary-foreground))", 33 | }, 34 | destructive: { 35 | DEFAULT: "hsl(var(--destructive))", 36 | foreground: "hsl(var(--destructive-foreground))", 37 | }, 38 | muted: { 39 | DEFAULT: "hsl(var(--muted))", 40 | foreground: "hsl(var(--muted-foreground))", 41 | }, 42 | accent: { 43 | DEFAULT: "hsl(var(--accent))", 44 | foreground: "hsl(var(--accent-foreground))", 45 | }, 46 | popover: { 47 | DEFAULT: "hsl(var(--popover))", 48 | foreground: "hsl(var(--popover-foreground))", 49 | }, 50 | card: { 51 | DEFAULT: "hsl(var(--card))", 52 | foreground: "hsl(var(--card-foreground))", 53 | }, 54 | }, 55 | borderRadius: { 56 | lg: "var(--radius)", 57 | md: "calc(var(--radius) - 2px)", 58 | sm: "calc(var(--radius) - 4px)", 59 | }, 60 | keyframes: { 61 | "accordion-down": { 62 | from: { height: "0" }, 63 | to: { height: "var(--radix-accordion-content-height)" }, 64 | }, 65 | "accordion-up": { 66 | from: { height: "var(--radix-accordion-content-height)" }, 67 | to: { height: "0" }, 68 | }, 69 | }, 70 | animation: { 71 | "accordion-down": "accordion-down 0.2s ease-out", 72 | "accordion-up": "accordion-up 0.2s ease-out", 73 | }, 74 | }, 75 | }, 76 | plugins: [require("tailwindcss-animate"), 77 | require("tailwindcss-debug-screens") 78 | ], 79 | } -------------------------------------------------------------------------------- /src/app/page.tsx: -------------------------------------------------------------------------------- 1 | import BarChart from "@/components/BarChart"; 2 | import PageTitle from "@/components/PageTitle"; 3 | import Card, { CardContent, CardProps } from "@/components/card"; 4 | import { Activity, CreditCard, DollarSign, Users } from "lucide-react"; 5 | import SalesCard, { SalesProps } from "@/components/SalesCard"; 6 | 7 | const cardData: CardProps[] = [ 8 | { 9 | label: "Total Revenue", 10 | amount: "$45,231.89", 11 | discription: "+20.1% from last month", 12 | icon: DollarSign 13 | }, 14 | { 15 | label: "Subscription", 16 | amount: "+2350", 17 | discription: "+180.1% from last month", 18 | icon: Users 19 | }, 20 | { 21 | label: "Sales", 22 | amount: "+12,234", 23 | discription: "+19% from last month", 24 | icon: CreditCard 25 | }, 26 | { 27 | label: "Active Mow", 28 | amount: "+573", 29 | discription: "+201 from last month", 30 | icon: Activity 31 | } 32 | ] 33 | 34 | const userSalesData: SalesProps[] = [ 35 | { 36 | name: "Olivia Martin", 37 | email: "olivia.martin@email.com", 38 | salesAmount: "+$1,999.00" 39 | }, 40 | { 41 | name: "Jackson Lee", 42 | email: "isabella.nguyen@email.com", 43 | salesAmount: "+$1,999.00" 44 | }, 45 | { 46 | name: "Isabella Nguyen", 47 | email: "isabella.nguyen@email.com", 48 | salesAmount: "+$39.00" 49 | }, 50 | { 51 | name: "William Kim", 52 | email: "will@email.com", 53 | salesAmount: "+$299.00" 54 | }, 55 | { 56 | name: "Sofia Davis", 57 | email: "sofia.davis@email.com", 58 | salesAmount: "+$39.00" 59 | } 60 | ]; 61 | 62 | export default function Home() { 63 | return ( 64 |
65 | 66 |
67 | {cardData.map((data, index) => ( 68 | 75 | ))} 76 |
77 | 78 |
79 | 80 |

Overview

81 | 82 |
83 | 84 |
85 |

Recent Sales

86 |

87 | You made 265 sales this month. 88 |

89 |
90 | {userSalesData.map((data, index) => ( 91 | 97 | ))} 98 |
99 |
100 |
101 | ) 102 | } 103 | -------------------------------------------------------------------------------- /src/components/DataTable.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import { 4 | ColumnDef, 5 | flexRender, 6 | getCoreRowModel, 7 | getPaginationRowModel, 8 | useReactTable, 9 | } from "@tanstack/react-table" 10 | 11 | import { 12 | Table, 13 | TableBody, 14 | TableCell, 15 | TableHead, 16 | TableHeader, 17 | TableRow, 18 | } from "@/components/ui/table" 19 | import { Button } from "./ui/button" 20 | 21 | interface DataTableProps { 22 | columns: ColumnDef[] 23 | data: TData[] 24 | } 25 | 26 | export function DataTable({ 27 | columns, 28 | data, 29 | }: DataTableProps) { 30 | const table = useReactTable({ 31 | data, 32 | columns, 33 | getCoreRowModel: getCoreRowModel(), 34 | getPaginationRowModel: getPaginationRowModel(), 35 | }) 36 | 37 | return ( 38 |
39 |
40 | 41 | 42 | {table.getHeaderGroups().map((headerGroup) => ( 43 | 44 | {headerGroup.headers.map((header) => { 45 | return ( 46 | 47 | {header.isPlaceholder 48 | ? null 49 | : flexRender( 50 | header.column.columnDef.header, 51 | header.getContext() 52 | )} 53 | 54 | ) 55 | })} 56 | 57 | ))} 58 | 59 | 60 | {table.getRowModel().rows?.length ? ( 61 | table.getRowModel().rows.map((row) => ( 62 | 66 | {row.getVisibleCells().map((cell) => ( 67 | 68 | {flexRender(cell.column.columnDef.cell, cell.getContext())} 69 | 70 | ))} 71 | 72 | )) 73 | ) : ( 74 | 75 | 76 | No results. 77 | 78 | 79 | )} 80 | 81 |
82 |
83 |
84 | 92 | 100 |
101 |
102 | ) 103 | } 104 | -------------------------------------------------------------------------------- /src/components/ui/table.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | const Table = React.forwardRef< 6 | HTMLTableElement, 7 | React.HTMLAttributes 8 | >(({ className, ...props }, ref) => ( 9 |
10 | 15 | 16 | )) 17 | Table.displayName = "Table" 18 | 19 | const TableHeader = React.forwardRef< 20 | HTMLTableSectionElement, 21 | React.HTMLAttributes 22 | >(({ className, ...props }, ref) => ( 23 | 24 | )) 25 | TableHeader.displayName = "TableHeader" 26 | 27 | const TableBody = React.forwardRef< 28 | HTMLTableSectionElement, 29 | React.HTMLAttributes 30 | >(({ className, ...props }, ref) => ( 31 | 36 | )) 37 | TableBody.displayName = "TableBody" 38 | 39 | const TableFooter = React.forwardRef< 40 | HTMLTableSectionElement, 41 | React.HTMLAttributes 42 | >(({ className, ...props }, ref) => ( 43 | tr]:last:border-b-0", 47 | className 48 | )} 49 | {...props} 50 | /> 51 | )) 52 | TableFooter.displayName = "TableFooter" 53 | 54 | const TableRow = React.forwardRef< 55 | HTMLTableRowElement, 56 | React.HTMLAttributes 57 | >(({ className, ...props }, ref) => ( 58 | 66 | )) 67 | TableRow.displayName = "TableRow" 68 | 69 | const TableHead = React.forwardRef< 70 | HTMLTableCellElement, 71 | React.ThHTMLAttributes 72 | >(({ className, ...props }, ref) => ( 73 |
81 | )) 82 | TableHead.displayName = "TableHead" 83 | 84 | const TableCell = React.forwardRef< 85 | HTMLTableCellElement, 86 | React.TdHTMLAttributes 87 | >(({ className, ...props }, ref) => ( 88 | 93 | )) 94 | TableCell.displayName = "TableCell" 95 | 96 | const TableCaption = React.forwardRef< 97 | HTMLTableCaptionElement, 98 | React.HTMLAttributes 99 | >(({ className, ...props }, ref) => ( 100 |
105 | )) 106 | TableCaption.displayName = "TableCaption" 107 | 108 | export { 109 | Table, 110 | TableHeader, 111 | TableBody, 112 | TableFooter, 113 | TableHead, 114 | TableRow, 115 | TableCell, 116 | TableCaption, 117 | } 118 | -------------------------------------------------------------------------------- /src/components/ui/nav.tsx: -------------------------------------------------------------------------------- 1 | /** @format */ 2 | 3 | "use client"; 4 | 5 | import Link from "next/link"; 6 | import { LucideIcon } from "lucide-react"; 7 | 8 | import { cn } from "@/lib/utils"; 9 | import { buttonVariants } from "@/components/ui/button"; 10 | import { 11 | Tooltip, 12 | TooltipContent, 13 | TooltipTrigger 14 | } from "@/components/ui/tooltip"; 15 | import { TooltipProvider } from "@radix-ui/react-tooltip"; 16 | import { usePathname } from "next/navigation"; 17 | 18 | interface NavProps { 19 | isCollapsed: boolean; 20 | links: { 21 | title: string; 22 | label?: string; 23 | icon: LucideIcon; 24 | variant: "default" | "ghost"; 25 | href: string; 26 | }[]; 27 | } 28 | 29 | export function Nav({ links, isCollapsed }: NavProps) { 30 | const pathName = usePathname(); 31 | return ( 32 | 33 |
37 | 101 |
102 |
103 | ); 104 | } 105 | -------------------------------------------------------------------------------- /src/app/orders/page.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * eslint-disable @next/next/no-img-element 3 | * 4 | * @format 5 | */ 6 | 7 | /** 8 | * eslint-disable @next/next/no-img-element 9 | * 10 | * @format 11 | */ 12 | 13 | /** @format */ 14 | "use client"; 15 | 16 | import { DataTable } from "@/components/DataTable"; 17 | import { ColumnDef } from "@tanstack/react-table"; 18 | import React from "react"; 19 | import PageTitle from "@/components/PageTitle"; 20 | import { cn } from "@/lib/utils"; 21 | 22 | type Props = {}; 23 | type Payment = { 24 | order: string; 25 | status: string; 26 | lastOrder: string; 27 | method: string; 28 | }; 29 | 30 | const columns: ColumnDef[] = [ 31 | { 32 | accessorKey: "order", 33 | header: "Order" 34 | }, 35 | { 36 | accessorKey: "status", 37 | header: "Status", 38 | cell: ({ row }) => { 39 | return ( 40 |
47 | {row.getValue("status")} 48 |
49 | ); 50 | } 51 | }, 52 | { 53 | accessorKey: "lastOrder", 54 | header: "Last Order" 55 | }, 56 | { 57 | accessorKey: "method", 58 | header: "Method" 59 | } 60 | ]; 61 | 62 | const data: Payment[] = [ 63 | { 64 | order: "ORD001", 65 | status: "Pending", 66 | lastOrder: "2023-01-15", 67 | method: "Credit Card" 68 | }, 69 | { 70 | order: "ORD002", 71 | status: "Processing", 72 | lastOrder: "2023-02-20", 73 | method: "PayPal" 74 | }, 75 | { 76 | order: "ORD003", 77 | status: "Completed", 78 | lastOrder: "2023-03-10", 79 | method: "Stripe" 80 | }, 81 | { 82 | order: "ORD004", 83 | status: "Pending", 84 | lastOrder: "2023-04-05", 85 | method: "Venmo" 86 | }, 87 | { 88 | order: "ORD005", 89 | status: "Completed", 90 | lastOrder: "2023-05-12", 91 | method: "Bank Transfer" 92 | }, 93 | { 94 | order: "ORD006", 95 | status: "Processing", 96 | lastOrder: "2023-06-18", 97 | method: "Apple Pay" 98 | }, 99 | { 100 | order: "ORD007", 101 | status: "Completed", 102 | lastOrder: "2023-07-22", 103 | method: "Google Pay" 104 | }, 105 | { 106 | order: "ORD008", 107 | status: "Pending", 108 | lastOrder: "2023-08-30", 109 | method: "Cryptocurrency" 110 | }, 111 | { 112 | order: "ORD009", 113 | status: "Processing", 114 | lastOrder: "2023-09-05", 115 | method: "Alipay" 116 | }, 117 | { 118 | order: "ORD010", 119 | status: "Completed", 120 | lastOrder: "2023-10-18", 121 | method: "WeChat Pay" 122 | }, 123 | { 124 | order: "ORD011", 125 | status: "Pending", 126 | lastOrder: "2023-11-25", 127 | method: "Square Cash" 128 | }, 129 | { 130 | order: "ORD012", 131 | status: "Completed", 132 | lastOrder: "2023-12-08", 133 | method: "Zelle" 134 | }, 135 | { 136 | order: "ORD013", 137 | status: "Processing", 138 | lastOrder: "2024-01-15", 139 | method: "Stripe" 140 | }, 141 | { 142 | order: "ORD014", 143 | status: "Completed", 144 | lastOrder: "2024-02-20", 145 | method: "PayPal" 146 | }, 147 | { 148 | order: "ORD015", 149 | status: "Pending", 150 | lastOrder: "2024-03-30", 151 | method: "Credit Card" 152 | } 153 | ]; 154 | 155 | export default function OrdersPage({}: Props) { 156 | return ( 157 |
158 | 159 | 160 |
161 | ); 162 | } 163 | -------------------------------------------------------------------------------- /src/app/users/page.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * eslint-disable @next/next/no-img-element 3 | * 4 | * @format 5 | */ 6 | 7 | /** @format */ 8 | "use client"; 9 | 10 | import { DataTable } from "@/components/DataTable"; 11 | import { ColumnDef } from "@tanstack/react-table"; 12 | import React from "react"; 13 | import PageTitle from "@/components/PageTitle"; 14 | 15 | type Props = {}; 16 | type Payment = { 17 | name: string; 18 | email: string; 19 | lastOrder: string; 20 | method: string; 21 | }; 22 | 23 | const columns: ColumnDef[] = [ 24 | { 25 | accessorKey: "name", 26 | header: "Name", 27 | cell: ({ row }) => { 28 | return ( 29 |
30 | user-image 37 |

{row.getValue("name")}

38 |
39 | ); 40 | } 41 | }, 42 | { 43 | accessorKey: "email", 44 | header: "Email" 45 | }, 46 | { 47 | accessorKey: "lastOrder", 48 | header: "Last Order" 49 | }, 50 | { 51 | accessorKey: "method", 52 | header: "Method" 53 | } 54 | ]; 55 | 56 | const data: Payment[] = [ 57 | { 58 | name: "John Doe", 59 | email: "john@example.com", 60 | lastOrder: "2023-01-01", 61 | method: "Credit Card" 62 | }, 63 | { 64 | name: "Alice Smith", 65 | email: "alice@example.com", 66 | lastOrder: "2023-02-15", 67 | method: "PayPal" 68 | }, 69 | { 70 | name: "Bob Johnson", 71 | email: "bob@example.com", 72 | lastOrder: "2023-03-20", 73 | method: "Stripe" 74 | }, 75 | { 76 | name: "Emma Brown", 77 | email: "emma@example.com", 78 | lastOrder: "2023-04-10", 79 | method: "Venmo" 80 | }, 81 | { 82 | name: "Michael Davis", 83 | email: "michael@example.com", 84 | lastOrder: "2023-05-05", 85 | method: "Cash" 86 | }, 87 | { 88 | name: "Sophia Wilson", 89 | email: "sophia@example.com", 90 | lastOrder: "2023-06-18", 91 | method: "Bank Transfer" 92 | }, 93 | { 94 | name: "Liam Garcia", 95 | email: "liam@example.com", 96 | lastOrder: "2023-07-22", 97 | method: "Payoneer" 98 | }, 99 | { 100 | name: "Olivia Martinez", 101 | email: "olivia@example.com", 102 | lastOrder: "2023-08-30", 103 | method: "Apple Pay" 104 | }, 105 | { 106 | name: "Noah Rodriguez", 107 | email: "noah@example.com", 108 | lastOrder: "2023-09-12", 109 | method: "Google Pay" 110 | }, 111 | { 112 | name: "Ava Lopez", 113 | email: "ava@example.com", 114 | lastOrder: "2023-10-25", 115 | method: "Cryptocurrency" 116 | }, 117 | { 118 | name: "Elijah Hernandez", 119 | email: "elijah@example.com", 120 | lastOrder: "2023-11-05", 121 | method: "Alipay" 122 | }, 123 | { 124 | name: "Mia Gonzalez", 125 | email: "mia@example.com", 126 | lastOrder: "2023-12-08", 127 | method: "WeChat Pay" 128 | }, 129 | { 130 | name: "James Perez", 131 | email: "james@example.com", 132 | lastOrder: "2024-01-18", 133 | method: "Square Cash" 134 | }, 135 | { 136 | name: "Charlotte Carter", 137 | email: "charlotte@example.com", 138 | lastOrder: "2024-02-22", 139 | method: "Zelle" 140 | }, 141 | { 142 | name: "Benjamin Taylor", 143 | email: "benjamin@example.com", 144 | lastOrder: "2024-03-30", 145 | method: "Stripe" 146 | } 147 | ]; 148 | 149 | export default function UsersPage({}: Props) { 150 | return ( 151 |
152 | 153 | 154 |
155 | ); 156 | } 157 | --------------------------------------------------------------------------------