├── .env.example ├── .eslintignore ├── .eslintrc.json ├── .gitignore ├── .husky ├── .gitignore ├── install.mjs └── pre-commit ├── .prettierignore ├── .prettierrc.json ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── components.json ├── next.config.js ├── package-lock.json ├── package.json ├── postcss.config.js ├── public └── placeholder.png ├── screenshots ├── screenshot-1.png ├── screenshot-2.png ├── screenshot-3.png └── screenshot-4.png ├── src ├── app │ ├── api │ │ └── auth │ │ │ └── [...nextauth] │ │ │ └── route.ts │ ├── dashboard │ │ ├── (example) │ │ │ ├── account │ │ │ │ └── page.tsx │ │ │ ├── categories │ │ │ │ └── page.tsx │ │ │ ├── posts │ │ │ │ ├── new │ │ │ │ │ └── page.tsx │ │ │ │ └── page.tsx │ │ │ ├── tags │ │ │ │ └── page.tsx │ │ │ └── users │ │ │ │ └── page.tsx │ │ ├── layout.tsx │ │ └── page.tsx │ ├── globals.css │ ├── layout.tsx │ └── page.tsx ├── components │ ├── admin-panel │ │ ├── admin-panel-layout.tsx │ │ ├── collapse-menu-button.tsx │ │ ├── content-layout.tsx │ │ ├── footer.tsx │ │ ├── menu.tsx │ │ ├── navbar.tsx │ │ ├── sheet-menu.tsx │ │ ├── sidebar-toggle.tsx │ │ ├── sidebar.tsx │ │ └── user-nav.tsx │ ├── admin-provider.tsx │ ├── forms │ │ └── login.tsx │ ├── icons.tsx │ ├── mode-toggle.tsx │ ├── placeholder-content.tsx │ ├── theme-provider.tsx │ └── ui │ │ ├── alert.tsx │ │ ├── avatar.tsx │ │ ├── breadcrumb.tsx │ │ ├── button.tsx │ │ ├── card.tsx │ │ ├── collapsible.tsx │ │ ├── dropdown-menu.tsx │ │ ├── form.tsx │ │ ├── input.tsx │ │ ├── label.tsx │ │ ├── scroll-area.tsx │ │ ├── sheet.tsx │ │ └── tooltip.tsx ├── hooks │ ├── use-sidebar-toggle.ts │ └── use-store.ts ├── lib │ ├── auth │ │ ├── options.ts │ │ ├── session.ts │ │ └── validate.tsx │ ├── env.ts │ ├── menu-list.ts │ └── utils.ts ├── middleware.ts ├── services │ └── directus.ts └── types │ ├── default.d.ts │ └── next-auth.d.ts ├── tailwind.config.js └── tsconfig.json /.env.example: -------------------------------------------------------------------------------- 1 | NEXT_PUBLIC_DIRECTUS_API=http://127.0.0.1:8055 2 | NEXTAUTH_SECRET= 3 | NEXTAUTH_URL=http://localhost:3000 4 | NEXT_PUBLIC_SITE_NAME="Acme Inc" 5 | NEXT_PUBLIC_SITE_DESCRIPTION="This library has saved me countless hours of work and helped me deliver stunning designs to my clients faster than ever before." 6 | 7 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | 3 | /types/next-auth.d.ts 4 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "next/core-web-vitals", 4 | "eslint:recommended", 5 | "plugin:prettier/recommended" 6 | ], 7 | "plugins": ["prettier", "import"], 8 | "overrides": [ 9 | { 10 | "files": ["*.ts", "*.tsx"], 11 | "rules": { 12 | "no-undef": "off", 13 | "no-unused-vars": "off" 14 | } 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /.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 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env*.local 29 | .env 30 | # vercel 31 | .vercel 32 | 33 | # typescript 34 | *.tsbuildinfo 35 | next-env.d.ts 36 | 37 | .eslintcache 38 | -------------------------------------------------------------------------------- /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /.husky/install.mjs: -------------------------------------------------------------------------------- 1 | // Skip Husky install in production and CI 2 | if (process.env.NODE_ENV === "production" || process.env.CI === "true") { 3 | process.exit(0) 4 | } 5 | const husky = (await import("husky")).default 6 | console.log(husky()) 7 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npx next lint 5 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | /.next 2 | /build 3 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": false, 3 | "jsxSingleQuote": false, 4 | "semi": false, 5 | "trailingComma": "es5", 6 | "endOfLine": "auto", 7 | "tabWidth": 2, 8 | "plugins": ["prettier-plugin-tailwindcss"] 9 | } 10 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.insertFinalNewline": true, 3 | "editor.formatOnSave": true, 4 | "editor.formatOnPaste": true, 5 | "editor.fontWeight": "normal", 6 | "editor.codeActionsOnSave": { 7 | "source.fixAll.eslint": "explicit" 8 | }, 9 | "[javascript]": { 10 | "editor.defaultFormatter": "esbenp.prettier-vscode" 11 | }, 12 | "[typescript]": { 13 | "editor.defaultFormatter": "vscode.typescript-language-features" 14 | }, 15 | "[typescriptreact]": { 16 | "editor.defaultFormatter": "esbenp.prettier-vscode" 17 | }, 18 | "json.format.enable": true, 19 | "[json]": { 20 | "editor.defaultFormatter": "esbenp.prettier-vscode" 21 | }, 22 | "[css]": { 23 | "editor.defaultFormatter": "esbenp.prettier-vscode" 24 | }, 25 | "files.associations": { 26 | "*.css": "tailwindcss" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Derian Pinto 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Simple Dashboard Template with Next.js 14, Tailwind CSS, NextAuth.js, and Directus 2 | 3 | This project is a starting point for building a modern web dashboard using a robust technology stack. It provides you with the basic structure and tools necessary to kickstart the development of your own dashboard application. 4 | 5 | ## Screenshots 6 | 7 | #### Login Page 8 | 9 | ![Login page](/screenshots/screenshot-1.png) 10 | 11 | #### Light mode 12 | 13 | ![Light mode](/screenshots/screenshot-2.png) 14 | 15 | #### Dark mode 16 | 17 | ![Dark mode](/screenshots/screenshot-3.png) 18 | 19 | #### Sheet menu 20 | 21 | 22 | 23 | ## Key Features 24 | 25 | - A solid foundation for developing a modern web dashboard. 26 | - An attractive and customizable style thanks to Tailwind CSS. 27 | - Secure user authentication through NextAuth.js. 28 | - Dynamic content management with Directus. 29 | - Streamlines the initial setup of your project, saving you time. 30 | 31 | ## Technologies Used 32 | 33 | - [Next.js](https://nextjs.org/): React framework for web applications. 34 | - [Tailwind CSS](https://tailwindcss.com/): CSS design framework. 35 | - [Shadcn](https://ui.shadcn.com/): Beautifully designed components built with Radix UI and Tailwind CSS. 36 | - [next-auth](https://next-auth.js.org/): Authentication and authorization in Next.js. 37 | - [next-themes](https://github.com/pacocoursey/next-themes): Theme switching in Next.js. 38 | - [TypeScript](https://www.typescriptlang.org/): Programming language. 39 | - [@directus/sdk](https://docs.directus.io/guides/sdk/): Client for Directus API. 40 | - [zustand](https://github.com/pmndrs/zustand): Lightweight state management for React. 41 | - [zod](https://github.com/colinhacks/zod): TypeScript schema validation. 42 | - [Husky](https://github.com/typicode/husky): Git hooks for running commands on pre-commit and pre-push actions. 43 | - [Prettier](https://prettier.io/): Automatic code formatter. 44 | - [ESLint](https://eslint.org/): Static code analysis tool. 45 | - [shadcn/ui sidebar](https://github.com/salimi-my/shadcn-ui-sidebar): Shadcn UI Sidebar. 46 | 47 | ## Requirements 48 | 49 | Make sure you have the following installed before running the project: 50 | 51 | - [Node.js](https://nodejs.org/): version 20.9.0 52 | - [npm](https://www.npmjs.com/): JavaScript package manager 53 | 54 | ## Configuration 55 | 56 | Clone the repository: 57 | 58 | ```bash 59 | git clone https://github.com/pintoderian/next-directus-auth-ts.git 60 | cd your-project 61 | ``` 62 | 63 | Install dependencies: 64 | 65 | ```bash 66 | npm run install 67 | ``` 68 | 69 | Prepare husky: 70 | 71 | ```bash 72 | npm run prepare 73 | ``` 74 | 75 | Configure environment variables: 76 | Create a .env.local file at the root of the project and define the necessary environment variables. Here's an example: 77 | 78 | ```bash 79 | NEXT_PUBLIC_DIRECTUS_API= 80 | NEXTAUTH_SECRET= 81 | NEXTAUTH_URL=http://localhost:3000 82 | NEXT_PUBLIC_SITE_NAME="Acme Inc" 83 | NEXT_PUBLIC_SITE_DESCRIPTION="Lorem, ipsum dolor sit amet consectetur adipisicing elit." 84 | 85 | ``` 86 | 87 | Command for **NEXTAUTH_SECRET** 88 | 89 | ```bash 90 | openssl rand -base64 32 91 | ``` 92 | 93 | ## Running the Project 94 | 95 | To run the project in a development environment, use the following command: 96 | 97 | ```bash 98 | npm run dev 99 | ``` 100 | 101 | The project will be available at http://localhost:3000. 102 | 103 | ## Production 104 | 105 | To build and run the project in a production environment, use the following commands: 106 | 107 | ```bash 108 | npm run build 109 | 110 | npm start 111 | ``` 112 | 113 |
114 | 115 | ### If you like my work, consider buying me a coffee! 116 | 117 | [Ko-fi](https://ko-fi.com/dpinto) 118 | -------------------------------------------------------------------------------- /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": "app/globals.css", 9 | "baseColor": "slate", 10 | "cssVariables": true 11 | }, 12 | "aliases": { 13 | "components": "@/components", 14 | "utils": "@/lib/utils" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {} 3 | 4 | module.exports = nextConfig 5 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-app", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint", 10 | "prepare": "node .husky/install.mjs" 11 | }, 12 | "dependencies": { 13 | "@directus/sdk": "^17.0.1", 14 | "@hookform/resolvers": "^3.9.0", 15 | "@radix-ui/react-avatar": "^1.1.0", 16 | "@radix-ui/react-collapsible": "^1.1.0", 17 | "@radix-ui/react-dialog": "^1.1.1", 18 | "@radix-ui/react-dropdown-menu": "^2.1.1", 19 | "@radix-ui/react-icons": "^1.3.0", 20 | "@radix-ui/react-label": "^2.1.0", 21 | "@radix-ui/react-scroll-area": "^1.1.0", 22 | "@radix-ui/react-slot": "^1.1.0", 23 | "@radix-ui/react-tooltip": "^1.1.2", 24 | "@types/node": "22.5.4", 25 | "@types/react": "18.3.5", 26 | "@types/react-dom": "18.3.0", 27 | "autoprefixer": "10.4.20", 28 | "class-variance-authority": "^0.7.0", 29 | "clsx": "^2.1.1", 30 | "eslint": "8.57.0", 31 | "eslint-config-next": "14.2.11", 32 | "lucide-react": "^0.441.0", 33 | "next": "14.2.11", 34 | "next-auth": "^4.24.7", 35 | "next-themes": "^0.3.0", 36 | "postcss": "8.4.45", 37 | "react": "18.3.1", 38 | "react-dom": "18.3.1", 39 | "react-hook-form": "^7.53.0", 40 | "tailwind-merge": "^2.5.2", 41 | "tailwindcss": "3.4.11", 42 | "tailwindcss-animate": "^1.0.7", 43 | "typescript": "5.6.2", 44 | "zod": "^3.23.8", 45 | "zustand": "^4.5.5" 46 | }, 47 | "devDependencies": { 48 | "eslint-config-prettier": "^9.1.0", 49 | "eslint-plugin-import": "^2.30.0", 50 | "eslint-plugin-prettier": "^5.2.1", 51 | "husky": "^9.1.6", 52 | "prettier": "^3.3.3", 53 | "prettier-plugin-tailwindcss": "^0.6.6" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /public/placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pintoderian/next-directus-auth-ts/7fd49dd9990bf28c31d0cc98f52eb6080a9d855f/public/placeholder.png -------------------------------------------------------------------------------- /screenshots/screenshot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pintoderian/next-directus-auth-ts/7fd49dd9990bf28c31d0cc98f52eb6080a9d855f/screenshots/screenshot-1.png -------------------------------------------------------------------------------- /screenshots/screenshot-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pintoderian/next-directus-auth-ts/7fd49dd9990bf28c31d0cc98f52eb6080a9d855f/screenshots/screenshot-2.png -------------------------------------------------------------------------------- /screenshots/screenshot-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pintoderian/next-directus-auth-ts/7fd49dd9990bf28c31d0cc98f52eb6080a9d855f/screenshots/screenshot-3.png -------------------------------------------------------------------------------- /screenshots/screenshot-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pintoderian/next-directus-auth-ts/7fd49dd9990bf28c31d0cc98f52eb6080a9d855f/screenshots/screenshot-4.png -------------------------------------------------------------------------------- /src/app/api/auth/[...nextauth]/route.ts: -------------------------------------------------------------------------------- 1 | import NextAuth from "next-auth" 2 | import { options } from "@/lib/auth/options" 3 | 4 | const handler = NextAuth(options) 5 | 6 | export { handler as GET, handler as POST } 7 | -------------------------------------------------------------------------------- /src/app/dashboard/(example)/account/page.tsx: -------------------------------------------------------------------------------- 1 | import Link from "next/link" 2 | 3 | import PlaceholderContent from "@/components/placeholder-content" 4 | import { ContentLayout } from "@/components/admin-panel/content-layout" 5 | import { 6 | Breadcrumb, 7 | BreadcrumbItem, 8 | BreadcrumbLink, 9 | BreadcrumbList, 10 | BreadcrumbPage, 11 | BreadcrumbSeparator, 12 | } from "@/components/ui/breadcrumb" 13 | 14 | export default function AccountPage() { 15 | return ( 16 | 17 | 18 | 19 | 20 | 21 | Home 22 | 23 | 24 | 25 | 26 | 27 | Dashboard 28 | 29 | 30 | 31 | 32 | Account 33 | 34 | 35 | 36 | 37 | 38 | ) 39 | } 40 | -------------------------------------------------------------------------------- /src/app/dashboard/(example)/categories/page.tsx: -------------------------------------------------------------------------------- 1 | import Link from "next/link" 2 | 3 | import PlaceholderContent from "@/components/placeholder-content" 4 | import { ContentLayout } from "@/components/admin-panel/content-layout" 5 | import { 6 | Breadcrumb, 7 | BreadcrumbItem, 8 | BreadcrumbLink, 9 | BreadcrumbList, 10 | BreadcrumbPage, 11 | BreadcrumbSeparator, 12 | } from "@/components/ui/breadcrumb" 13 | 14 | export default function CategoriesPage() { 15 | return ( 16 | 17 | 18 | 19 | 20 | 21 | Home 22 | 23 | 24 | 25 | 26 | 27 | Dashboard 28 | 29 | 30 | 31 | 32 | Categories 33 | 34 | 35 | 36 | 37 | 38 | ) 39 | } 40 | -------------------------------------------------------------------------------- /src/app/dashboard/(example)/posts/new/page.tsx: -------------------------------------------------------------------------------- 1 | import Link from "next/link" 2 | 3 | import PlaceholderContent from "@/components/placeholder-content" 4 | import { ContentLayout } from "@/components/admin-panel/content-layout" 5 | import { 6 | Breadcrumb, 7 | BreadcrumbItem, 8 | BreadcrumbLink, 9 | BreadcrumbList, 10 | BreadcrumbPage, 11 | BreadcrumbSeparator, 12 | } from "@/components/ui/breadcrumb" 13 | 14 | export default function NewPostPage() { 15 | return ( 16 | 17 | 18 | 19 | 20 | 21 | Home 22 | 23 | 24 | 25 | 26 | 27 | Dashboard 28 | 29 | 30 | 31 | 32 | 33 | Posts 34 | 35 | 36 | 37 | 38 | New 39 | 40 | 41 | 42 | 43 | 44 | ) 45 | } 46 | -------------------------------------------------------------------------------- /src/app/dashboard/(example)/posts/page.tsx: -------------------------------------------------------------------------------- 1 | import Link from "next/link" 2 | 3 | import PlaceholderContent from "@/components/placeholder-content" 4 | import { ContentLayout } from "@/components/admin-panel/content-layout" 5 | import { 6 | Breadcrumb, 7 | BreadcrumbItem, 8 | BreadcrumbLink, 9 | BreadcrumbList, 10 | BreadcrumbPage, 11 | BreadcrumbSeparator, 12 | } from "@/components/ui/breadcrumb" 13 | 14 | export default function PostsPage() { 15 | return ( 16 | 17 | 18 | 19 | 20 | 21 | Home 22 | 23 | 24 | 25 | 26 | 27 | Dashboard 28 | 29 | 30 | 31 | 32 | Posts 33 | 34 | 35 | 36 | 37 | 38 | ) 39 | } 40 | -------------------------------------------------------------------------------- /src/app/dashboard/(example)/tags/page.tsx: -------------------------------------------------------------------------------- 1 | import Link from "next/link" 2 | 3 | import PlaceholderContent from "@/components/placeholder-content" 4 | import { ContentLayout } from "@/components/admin-panel/content-layout" 5 | import { 6 | Breadcrumb, 7 | BreadcrumbItem, 8 | BreadcrumbLink, 9 | BreadcrumbList, 10 | BreadcrumbPage, 11 | BreadcrumbSeparator, 12 | } from "@/components/ui/breadcrumb" 13 | 14 | export default function TagsPage() { 15 | return ( 16 | 17 | 18 | 19 | 20 | 21 | Home 22 | 23 | 24 | 25 | 26 | 27 | Dashboard 28 | 29 | 30 | 31 | 32 | Tags 33 | 34 | 35 | 36 | 37 | 38 | ) 39 | } 40 | -------------------------------------------------------------------------------- /src/app/dashboard/(example)/users/page.tsx: -------------------------------------------------------------------------------- 1 | import Link from "next/link" 2 | 3 | import PlaceholderContent from "@/components/placeholder-content" 4 | import { ContentLayout } from "@/components/admin-panel/content-layout" 5 | import { 6 | Breadcrumb, 7 | BreadcrumbItem, 8 | BreadcrumbLink, 9 | BreadcrumbList, 10 | BreadcrumbPage, 11 | BreadcrumbSeparator, 12 | } from "@/components/ui/breadcrumb" 13 | 14 | export default function UsersPage() { 15 | return ( 16 | 17 | 18 | 19 | 20 | 21 | Home 22 | 23 | 24 | 25 | 26 | 27 | Dashboard 28 | 29 | 30 | 31 | 32 | Users 33 | 34 | 35 | 36 | 37 | 38 | ) 39 | } 40 | -------------------------------------------------------------------------------- /src/app/dashboard/layout.tsx: -------------------------------------------------------------------------------- 1 | import AdminPanelLayout from "@/components/admin-panel/admin-panel-layout" 2 | import AdminProvider from "@/components/admin-provider" 3 | import { options } from "@/lib/auth/options" 4 | import { getServerSession } from "next-auth" 5 | 6 | export default async function DashboardLayout({ 7 | children, 8 | }: { 9 | children: React.ReactNode 10 | }) { 11 | const session = await getServerSession(options) 12 | 13 | return ( 14 | 15 | {children} 16 | 17 | ) 18 | } 19 | -------------------------------------------------------------------------------- /src/app/dashboard/page.tsx: -------------------------------------------------------------------------------- 1 | import { ContentLayout } from "@/components/admin-panel/content-layout" 2 | import { 3 | Card, 4 | CardContent, 5 | CardDescription, 6 | CardHeader, 7 | CardTitle, 8 | } from "@/components/ui/card" 9 | import type { Metadata } from "next" 10 | 11 | export const metadata: Metadata = { 12 | title: "Dashboard", 13 | description: "Generated by create next app", 14 | } 15 | 16 | export default async function Dashboard() { 17 | return ( 18 | 19 |
20 |
21 | 22 | 23 | 24 | Total Revenue 25 | 26 | 36 | 37 | 38 | 39 | 40 |
$45,231.89
41 |

42 | +20.1% from last month 43 |

44 |
45 |
46 | 47 | 48 | 49 | Subscriptions 50 | 51 | 61 | 62 | 63 | 64 | 65 | 66 | 67 |
+2350
68 |

69 | +180.1% from last month 70 |

71 |
72 |
73 | 74 | 75 | Sales 76 | 86 | 87 | 88 | 89 | 90 | 91 |
+12,234
92 |

93 | +19% from last month 94 |

95 |
96 |
97 | 98 | 99 | Active Now 100 | 110 | 111 | 112 | 113 | 114 |
+573
115 |

116 | +201 since last hour 117 |

118 |
119 |
120 |
121 |
122 | 123 | 124 | Overview 125 | 126 | Hello World! 127 | 128 | 129 | 130 | Custom Text 131 | 132 | 133 |

134 | Lorem, ipsum dolor sit amet consectetur adipisicing elit. 135 | Molestias perspiciatis reprehenderit ipsum totam, facilis fugit 136 | explicabo quisquam saepe delectus sapiente aliquam recusandae, 137 | in similique sit? Nesciunt praesentium totam quae eius. 138 |

139 |
140 |
141 |
142 |
143 |
144 | ) 145 | } 146 | -------------------------------------------------------------------------------- /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: 224 71.4% 4.1%; 9 | --card: 0 0% 100%; 10 | --card-foreground: 224 71.4% 4.1%; 11 | --popover: 0 0% 100%; 12 | --popover-foreground: 224 71.4% 4.1%; 13 | --primary: 262.1 83.3% 57.8%; 14 | --primary-foreground: 210 20% 98%; 15 | --secondary: 220 14.3% 95.9%; 16 | --secondary-foreground: 220.9 39.3% 11%; 17 | --muted: 220 14.3% 95.9%; 18 | --muted-foreground: 220 8.9% 46.1%; 19 | --accent: 220 14.3% 95.9%; 20 | --accent-foreground: 220.9 39.3% 11%; 21 | --destructive: 0 84.2% 60.2%; 22 | --destructive-foreground: 210 20% 98%; 23 | --border: 220 13% 91%; 24 | --input: 220 13% 91%; 25 | --ring: 262.1 83.3% 57.8%; 26 | --radius: 0.5rem; 27 | --chart-1: 12 76% 61%; 28 | --chart-2: 173 58% 39%; 29 | --chart-3: 197 37% 24%; 30 | --chart-4: 43 74% 66%; 31 | --chart-5: 27 87% 67%; 32 | /* Variables adicionales */ 33 | --sidebar: #693dc3; 34 | --background-white-30: rgb(255 255 255 / 30%); 35 | --card-foreground-30: rgba(255, 255, 255, 0.3); 36 | --button-foreground: rgb(255 255 255 / 30%); 37 | --button-50: rgb(255 255 255 / 50%); 38 | --outline: rgba(255, 255, 255, 0.05); 39 | --outline-50: rgba(255, 255, 255, 0.15); 40 | } 41 | 42 | .dark { 43 | --background: 240 10% 3.9%; 44 | --foreground: 0 0% 98%; 45 | --card: 240 10% 3.9%; 46 | --card-foreground: 0 0% 98%; 47 | --popover: 240 10% 3.9%; 48 | --popover-foreground: 0 0% 98%; 49 | --primary: 0 0% 98%; 50 | --primary-foreground: 240 5.9% 10%; 51 | --secondary: 240 3.7% 15.9%; 52 | --secondary-foreground: 0 0% 98%; 53 | --muted: 240 3.7% 15.9%; 54 | --muted-foreground: 240 5% 64.9%; 55 | --accent: 240 3.7% 15.9%; 56 | --accent-foreground: 0 0% 98%; 57 | --destructive: 0 62.8% 30.6%; 58 | --destructive-foreground: 0 0% 98%; 59 | --border: 240 3.7% 15.9%; 60 | --input: 240 3.7% 15.9%; 61 | --ring: 240 4.9% 83.9%; 62 | --chart-1: 220 70% 50%; 63 | --chart-2: 160 60% 45%; 64 | --chart-3: 30 80% 55%; 65 | --chart-4: 280 65% 60%; 66 | --chart-5: 340 75% 55%; 67 | /* Variables adicionales */ 68 | --sidebar: #693dc3; 69 | --background-white-30: rgb(255 255 255 / 30%); 70 | --card-foreground-30: rgba(255, 255, 255, 0.3); 71 | --button-foreground: rgb(255 255 255 / 30%); 72 | --button-50: rgb(255 255 255 / 50%); 73 | --outline: rgba(255, 255, 255, 0.05); 74 | --outline-50: rgba(255, 255, 255, 0.15); 75 | } 76 | } 77 | 78 | @layer base { 79 | * { 80 | @apply border-border; 81 | } 82 | body { 83 | @apply bg-background text-foreground; 84 | } 85 | } 86 | 87 | @layer utilities { 88 | /* Chrome, Safari and Opera */ 89 | .no-scrollbar::-webkit-scrollbar { 90 | display: none; 91 | } 92 | 93 | .no-scrollbar { 94 | -ms-overflow-style: none; /* IE and Edge */ 95 | scrollbar-width: none; /* Firefox */ 96 | } 97 | } 98 | 99 | .menu .active { 100 | @apply rounded bg-primary text-white; 101 | } 102 | -------------------------------------------------------------------------------- /src/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import "./globals.css" 2 | import { Inter } from "next/font/google" 3 | const inter = Inter({ subsets: ["latin"] }) 4 | 5 | export default function RootLayout({ 6 | children, 7 | }: { 8 | children: React.ReactNode 9 | }) { 10 | return ( 11 | 12 | {children} 13 | 14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /src/app/page.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from "next" 2 | import env from "@/lib/env" 3 | import LoginForm from "@/components/forms/login" 4 | import Link from "next/link" 5 | 6 | export const metadata: Metadata = { 7 | title: "Create Next App", 8 | description: "Generated by create next app", 9 | } 10 | 11 | const { siteName, siteDescription } = env 12 | 13 | export default async function Home() { 14 | return ( 15 | <> 16 |
17 |
18 |
19 |
20 | 30 | 31 | 32 | {siteName} 33 |
34 |
35 |
36 |

“{siteDescription}”

37 |
38 | 39 | Derian Pinto 40 | 41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |

Welcome

49 |

50 | Enter your credentials 51 |

52 |
53 | 54 |
55 |
56 |
57 | 58 | ) 59 | } 60 | -------------------------------------------------------------------------------- /src/components/admin-panel/admin-panel-layout.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import { cn } from "@/lib/utils" 4 | import { useStore } from "@/hooks/use-store" 5 | import { Footer } from "@/components/admin-panel/footer" 6 | import { Sidebar } from "@/components/admin-panel/sidebar" 7 | import { useSidebarToggle } from "@/hooks/use-sidebar-toggle" 8 | 9 | export default function AdminPanelLayout({ 10 | children, 11 | }: { 12 | children: React.ReactNode 13 | }) { 14 | const sidebar = useStore(useSidebarToggle, (state) => state) 15 | 16 | if (!sidebar) return null 17 | 18 | return ( 19 | <> 20 | 21 |
27 | {children} 28 |
29 |