├── .eslintrc.json ├── public ├── dark.png ├── light.png ├── favicon.ico └── vercel.svg ├── postcss.config.js ├── next.config.js ├── app ├── (auth) │ ├── login │ │ └── page.tsx │ ├── register │ │ └── page.tsx │ └── layout.tsx ├── (app) │ ├── accounts │ │ └── page.tsx │ ├── page.tsx │ └── layout.tsx ├── layout.tsx └── providers.tsx ├── components ├── hooks │ ├── useIsomorphicLayoutEffect.ts │ └── useBodyLock.ts ├── sidebar │ ├── sidebar-menu.tsx │ ├── sidebar-item.tsx │ ├── sidebar.styles.ts │ ├── companies-dropdown.tsx │ ├── collapse-items.tsx │ └── sidebar.tsx ├── layout │ ├── layout-context.ts │ └── layout.tsx ├── navbar │ ├── darkmodeswitch.tsx │ ├── burguer-button.tsx │ ├── navbar.styles.ts │ ├── notifications-dropdown.tsx │ ├── user-dropdown.tsx │ └── navbar.tsx ├── icons │ ├── sidebar │ │ ├── chevron-up-icon.tsx │ │ ├── chevron-down-icon.tsx │ │ ├── filter-icon.tsx │ │ ├── products-icon.tsx │ │ ├── bottom-icon.tsx │ │ ├── accounts-icon.tsx │ │ ├── payments-icon.tsx │ │ ├── home-icon.tsx │ │ ├── view-icon.tsx │ │ ├── balance-icon.tsx │ │ ├── reports-icon.tsx │ │ ├── dev-icon.tsx │ │ ├── customers-icon.tsx │ │ ├── changelog-icon.tsx │ │ └── settings-icon.tsx │ ├── accounts │ │ ├── info-icon.tsx │ │ ├── dots-icon.tsx │ │ ├── trash-icon.tsx │ │ └── export-icon.tsx │ ├── acmelogo.tsx │ ├── searchicon.tsx │ ├── breadcrumb │ │ ├── users-icon.tsx │ │ └── house-icon.tsx │ ├── navbar │ │ ├── github-icon.tsx │ │ ├── support-icon.tsx │ │ ├── notificationicon.tsx │ │ └── feedback-icon.tsx │ ├── table │ │ ├── eye-icon.tsx │ │ ├── edit-icon.tsx │ │ └── delete-icon.tsx │ ├── community.tsx │ └── acme-icon.tsx ├── table │ ├── table.tsx │ ├── render-cell.tsx │ └── data.ts ├── auth │ ├── authLayout.tsx │ ├── login.tsx │ └── register.tsx ├── home │ ├── card-agents.tsx │ ├── card-balance3.tsx │ ├── card-balance1.tsx │ ├── card-balance2.tsx │ ├── card-transactions.tsx │ └── content.tsx ├── accounts │ ├── add-user.tsx │ └── index.tsx └── charts │ └── steam.tsx ├── styles └── globals.css ├── helpers ├── types.ts └── schemas.ts ├── actions └── auth.action.ts ├── config └── fonts.ts ├── tailwind.config.js ├── .gitignore ├── .github └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── middleware.ts ├── tsconfig.json ├── package.json ├── LICENSE └── README.md /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /public/dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siumauricio/nextui-dashboard-template/HEAD/public/dark.png -------------------------------------------------------------------------------- /public/light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siumauricio/nextui-dashboard-template/HEAD/public/light.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Siumauricio/nextui-dashboard-template/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: true, 4 | }; 5 | 6 | module.exports = nextConfig; 7 | -------------------------------------------------------------------------------- /app/(auth)/login/page.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Login } from "@/components/auth/login"; 3 | 4 | const login = () => { 5 | return ; 6 | }; 7 | 8 | export default login; 9 | -------------------------------------------------------------------------------- /app/(app)/accounts/page.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Accounts } from "@/components/accounts"; 3 | 4 | const accounts = () => { 5 | return ; 6 | }; 7 | 8 | export default accounts; 9 | -------------------------------------------------------------------------------- /components/hooks/useIsomorphicLayoutEffect.ts: -------------------------------------------------------------------------------- 1 | import {useEffect, useLayoutEffect} from 'react'; 2 | 3 | export const useIsomorphicLayoutEffect = 4 | typeof window !== 'undefined' ? useLayoutEffect : useEffect; 5 | -------------------------------------------------------------------------------- /app/(app)/page.tsx: -------------------------------------------------------------------------------- 1 | import type { NextPage } from "next"; 2 | import { Content } from "@/components/home/content"; 3 | 4 | const Home: NextPage = () => { 5 | return ; 6 | }; 7 | 8 | export default Home; 9 | -------------------------------------------------------------------------------- /app/(auth)/register/page.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Register } from "@/components/auth/register"; 3 | 4 | const register = () => { 5 | return ; 6 | }; 7 | 8 | export default register; 9 | -------------------------------------------------------------------------------- /styles/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | html, 6 | body { 7 | padding: 0; 8 | margin: 0; 9 | } 10 | 11 | * { 12 | box-sizing: border-box; 13 | } 14 | -------------------------------------------------------------------------------- /helpers/types.ts: -------------------------------------------------------------------------------- 1 | // FORMS 2 | 3 | export type LoginFormType = { 4 | email: string; 5 | password: string; 6 | }; 7 | 8 | export type RegisterFormType = { 9 | name: string; 10 | email: string; 11 | password: string; 12 | confirmPassword: string; 13 | }; 14 | -------------------------------------------------------------------------------- /app/(app)/layout.tsx: -------------------------------------------------------------------------------- 1 | import { Layout } from "@/components/layout/layout"; 2 | import "@/styles/globals.css"; 3 | 4 | export default function RootLayout({ 5 | children, 6 | }: { 7 | children: React.ReactNode; 8 | }) { 9 | return {children}; 10 | } 11 | -------------------------------------------------------------------------------- /actions/auth.action.ts: -------------------------------------------------------------------------------- 1 | "use server"; 2 | 3 | import { cookies } from "next/headers"; 4 | 5 | export const createAuthCookie = async () => { 6 | cookies().set("userAuth", "myToken", { secure: true }); 7 | }; 8 | 9 | export const deleteAuthCookie = async () => { 10 | cookies().delete("userAuth"); 11 | }; 12 | -------------------------------------------------------------------------------- /app/(auth)/layout.tsx: -------------------------------------------------------------------------------- 1 | import { AuthLayoutWrapper } from "@/components/auth/authLayout"; 2 | import "@/styles/globals.css"; 3 | 4 | export default function RootLayout({ 5 | children, 6 | }: { 7 | children: React.ReactNode; 8 | }) { 9 | return {children}; 10 | } 11 | -------------------------------------------------------------------------------- /config/fonts.ts: -------------------------------------------------------------------------------- 1 | import { Fira_Code as FontMono, Inter as FontSans } from "next/font/google" 2 | 3 | export const fontSans = FontSans({ 4 | subsets: ["latin"], 5 | variable: "--font-sans", 6 | }) 7 | 8 | export const fontMono = FontMono({ 9 | subsets: ["latin"], 10 | variable: "--font-mono", 11 | }) 12 | -------------------------------------------------------------------------------- /components/sidebar/sidebar-menu.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | interface Props { 4 | title: string; 5 | children?: React.ReactNode; 6 | } 7 | 8 | export const SidebarMenu = ({ title, children }: Props) => { 9 | return ( 10 |
11 | {title} 12 | {children} 13 |
14 | ); 15 | }; 16 | -------------------------------------------------------------------------------- /components/layout/layout-context.ts: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { createContext, useContext } from "react"; 4 | 5 | interface SidebarContext { 6 | collapsed: boolean; 7 | setCollapsed: () => void; 8 | } 9 | 10 | export const SidebarContext = createContext({ 11 | collapsed: false, 12 | setCollapsed: () => {}, 13 | }); 14 | 15 | export const useSidebarContext = () => { 16 | return useContext(SidebarContext); 17 | }; 18 | -------------------------------------------------------------------------------- /components/navbar/darkmodeswitch.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useTheme as useNextTheme } from "next-themes"; 3 | import { Switch } from "@nextui-org/react"; 4 | 5 | export const DarkModeSwitch = () => { 6 | const { setTheme, resolvedTheme } = useNextTheme(); 7 | return ( 8 | setTheme(e ? "dark" : "light")} 11 | /> 12 | ); 13 | }; 14 | -------------------------------------------------------------------------------- /components/navbar/burguer-button.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useSidebarContext } from "../layout/layout-context"; 3 | import { StyledBurgerButton } from "./navbar.styles"; 4 | 5 | export const BurguerButton = () => { 6 | const { collapsed, setCollapsed } = useSidebarContext(); 7 | 8 | return ( 9 |
14 |
15 |
16 |
17 | ); 18 | }; 19 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | const { nextui } = require("@nextui-org/react"); 2 | 3 | /** @type {import('tailwindcss').Config} */ 4 | module.exports = { 5 | content: [ 6 | "./app/**/*.{js,ts,jsx,tsx,mdx}", 7 | "./pages/**/*.{js,ts,jsx,tsx,mdx}", 8 | "./components/**/*.{js,ts,jsx,tsx,mdx}", 9 | 10 | // Or if using `src` directory: 11 | "./src/**/*.{js,ts,jsx,tsx,mdx}", 12 | "./node_modules/@nextui-org/theme/dist/**/*.{js,ts,jsx,tsx}", 13 | ], 14 | theme: { 15 | extend: {}, 16 | }, 17 | darkMode: "class", 18 | plugins: [nextui()], 19 | }; 20 | -------------------------------------------------------------------------------- /.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 | 16 | 17 | # production 18 | /build 19 | 20 | # misc 21 | .DS_Store 22 | *.pem 23 | 24 | # debug 25 | npm-debug.log* 26 | yarn-debug.log* 27 | yarn-error.log* 28 | .pnpm-debug.log* 29 | 30 | # local env files 31 | .env*.local 32 | 33 | # vercel 34 | .vercel 35 | 36 | # typescript 37 | *.tsbuildinfo 38 | next-env.d.ts 39 | /.github/ -------------------------------------------------------------------------------- /components/icons/sidebar/chevron-up-icon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | interface Props extends React.SVGAttributes {} 4 | 5 | export const ChevronUpIcon = ({ ...props }: Props) => { 6 | return ( 7 | 14 | 18 | 19 | ); 20 | }; 21 | -------------------------------------------------------------------------------- /components/icons/sidebar/chevron-down-icon.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | interface Props extends React.SVGAttributes {} 4 | export const ChevronDownIcon = ({ ...props }: Props) => { 5 | return ( 6 | 12 | 15 | 16 | ); 17 | }; 18 | -------------------------------------------------------------------------------- /components/icons/accounts/info-icon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const InfoIcon = () => { 4 | return ( 5 | 12 | 17 | 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /app/layout.tsx: -------------------------------------------------------------------------------- 1 | import "@/styles/globals.css"; 2 | import type { Metadata } from "next"; 3 | import { Providers } from "./providers"; 4 | import { fontSans } from "@/config/fonts"; 5 | import clsx from "clsx"; 6 | 7 | export const metadata: Metadata = { 8 | title: "Next.js", 9 | description: "Generated by Next.js", 10 | }; 11 | 12 | export default function RootLayout({ 13 | children, 14 | }: { 15 | children: React.ReactNode; 16 | }) { 17 | return ( 18 | 19 | 20 | {children} 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /components/icons/sidebar/filter-icon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const FilterIcon = () => { 4 | return ( 5 | 12 | 17 | 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /components/icons/sidebar/products-icon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const ProductsIcon = () => { 4 | return ( 5 | 12 | 19 | 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /components/icons/sidebar/bottom-icon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const BottomIcon = () => { 4 | return ( 5 | 12 | 19 | 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /helpers/schemas.ts: -------------------------------------------------------------------------------- 1 | import { object, ref, string } from "yup"; 2 | 3 | export const LoginSchema = object().shape({ 4 | email: string() 5 | .email("This field must be an email") 6 | .required("Email is required"), 7 | password: string().required("Password is required"), 8 | }); 9 | 10 | export const RegisterSchema = object().shape({ 11 | name: string().required("Name is required"), 12 | email: string() 13 | .email("This field must be an email") 14 | .required("Email is required"), 15 | password: string().required("Password is required"), 16 | confirmPassword: string() 17 | .required("Confirm password is required") 18 | .oneOf([ref("password")], "Passwords must match"), 19 | }); 20 | -------------------------------------------------------------------------------- /app/providers.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import * as React from "react"; 3 | import { NextUIProvider } from "@nextui-org/system"; 4 | import { ThemeProvider as NextThemesProvider } from "next-themes"; 5 | import { ThemeProviderProps } from "next-themes/dist/types"; 6 | 7 | export interface ProvidersProps { 8 | children: React.ReactNode; 9 | themeProps?: ThemeProviderProps; 10 | } 11 | 12 | export function Providers({ children, themeProps }: ProvidersProps) { 13 | return ( 14 | 15 | 19 | {children} 20 | 21 | 22 | ); 23 | } 24 | -------------------------------------------------------------------------------- /components/icons/sidebar/accounts-icon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const AccountsIcon = () => { 4 | return ( 5 | 12 | 19 | 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /middleware.ts: -------------------------------------------------------------------------------- 1 | import { NextResponse } from "next/server"; 2 | import type { NextRequest } from "next/server"; 3 | 4 | export function middleware(request: NextRequest) { 5 | const { pathname } = request.nextUrl; 6 | 7 | if ( 8 | (pathname === "/login" || pathname === "/register") && 9 | request.cookies.has("userAuth") 10 | ) 11 | return NextResponse.redirect(new URL("/", request.url)); 12 | 13 | if ( 14 | (pathname === "/" || pathname === "/accounts") && 15 | !request.cookies.has("userAuth") 16 | ) 17 | return NextResponse.redirect(new URL("/login", request.url)); 18 | 19 | return NextResponse.next(); 20 | } 21 | 22 | export const config = { 23 | matcher: ["/", "/accounts", "/login", "/register"], 24 | }; 25 | -------------------------------------------------------------------------------- /components/icons/acmelogo.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const AcmeLogo = () => ( 4 | 12 | 13 | 20 | 21 | ); 22 | -------------------------------------------------------------------------------- /components/icons/accounts/dots-icon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const DotsIcon = () => { 4 | return ( 5 | 12 | 19 | 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /components/icons/accounts/trash-icon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const TrashIcon = () => { 4 | return ( 5 | 12 | 19 | 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /components/icons/sidebar/payments-icon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const PaymentsIcon = () => { 4 | return ( 5 | 12 | 19 | 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "strict": true, 12 | "forceConsistentCasingInFileNames": true, 13 | "noEmit": true, 14 | "esModuleInterop": true, 15 | "module": "esnext", 16 | "moduleResolution": "node", 17 | "resolveJsonModule": true, 18 | "isolatedModules": true, 19 | "jsx": "preserve", 20 | "incremental": true, 21 | "plugins": [ 22 | { 23 | "name": "next" 24 | } 25 | ], 26 | "paths": { 27 | "@/*": ["./*"] 28 | } 29 | }, 30 | "include": [ 31 | "next-env.d.ts", 32 | "**/*.ts", 33 | "**/*.tsx", 34 | ".next/types/**/*.ts" 35 | ], 36 | "exclude": [ 37 | "node_modules" 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /components/icons/searchicon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const SearchIcon = () => { 4 | return ( 5 | 29 | ); 30 | }; 31 | -------------------------------------------------------------------------------- /components/icons/sidebar/home-icon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const HomeIcon = () => { 4 | return ( 5 | 12 | 19 | 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /components/icons/breadcrumb/users-icon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const UsersIcon = () => { 4 | return ( 5 | 12 | 19 | 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /components/icons/breadcrumb/house-icon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const HouseIcon = () => { 4 | return ( 5 | 12 | 19 | 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /components/icons/accounts/export-icon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const ExportIcon = () => { 4 | return ( 5 | 12 | 19 | 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "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 | "@nextui-org/react": "2.0.22", 13 | "apexcharts": "^3.35.5", 14 | "clsx": "^2.0.0", 15 | "formik": "^2.4.6", 16 | "framer-motion": "^10.16.0", 17 | "next": "^14.0.4", 18 | "next-themes": "0.2.1", 19 | "react": "18.2.0", 20 | "react-apexcharts": "^1.4.0", 21 | "react-dom": "18.2.0", 22 | "yup": "^1.4.0" 23 | }, 24 | "devDependencies": { 25 | "@types/node": "18.7.18", 26 | "@types/react": "18.0.20", 27 | "@types/react-dom": "18.0.6", 28 | "autoprefixer": "^10.4.15", 29 | "eslint": "8.23.1", 30 | "eslint-config-next": "13.4.16", 31 | "postcss": "^8.4.28", 32 | "tailwindcss": "^3.3.3", 33 | "typescript": "4.8.3" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /components/icons/sidebar/view-icon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const ViewIcon = () => { 4 | return ( 5 | 12 | 19 | 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /components/icons/sidebar/balance-icon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const BalanceIcon = () => { 4 | return ( 5 | 12 | 19 | 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /components/icons/sidebar/reports-icon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const ReportsIcon = () => { 4 | return ( 5 | 12 | 19 | 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /components/layout/layout.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import React from "react"; 4 | import { useLockedBody } from "../hooks/useBodyLock"; 5 | import { NavbarWrapper } from "../navbar/navbar"; 6 | import { SidebarWrapper } from "../sidebar/sidebar"; 7 | import { SidebarContext } from "./layout-context"; 8 | 9 | interface Props { 10 | children: React.ReactNode; 11 | } 12 | 13 | export const Layout = ({ children }: Props) => { 14 | const [sidebarOpen, setSidebarOpen] = React.useState(false); 15 | const [_, setLocked] = useLockedBody(false); 16 | const handleToggleSidebar = () => { 17 | setSidebarOpen(!sidebarOpen); 18 | setLocked(!sidebarOpen); 19 | }; 20 | 21 | return ( 22 | 27 |
28 | 29 | {children} 30 |
31 |
32 | ); 33 | }; 34 | -------------------------------------------------------------------------------- /components/icons/sidebar/dev-icon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const DevIcon = () => { 4 | return ( 5 | 12 | 19 | 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /public/vercel.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /components/icons/navbar/github-icon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const GithubIcon = () => { 4 | return ( 5 | 6 | 12 | 13 | ); 14 | }; 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Mauricio Siu 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 | -------------------------------------------------------------------------------- /components/icons/sidebar/customers-icon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const CustomersIcon = () => { 4 | return ( 5 | 12 | 19 | 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /components/sidebar/sidebar-item.tsx: -------------------------------------------------------------------------------- 1 | import NextLink from "next/link"; 2 | import React from "react"; 3 | import { useSidebarContext } from "../layout/layout-context"; 4 | import clsx from "clsx"; 5 | 6 | interface Props { 7 | title: string; 8 | icon: React.ReactNode; 9 | isActive?: boolean; 10 | href?: string; 11 | } 12 | 13 | export const SidebarItem = ({ icon, title, isActive, href = "" }: Props) => { 14 | const { collapsed, setCollapsed } = useSidebarContext(); 15 | 16 | const handleClick = () => { 17 | if (window.innerWidth < 768) { 18 | setCollapsed(); 19 | } 20 | }; 21 | return ( 22 | 26 |
35 | {icon} 36 | {title} 37 |
38 |
39 | ); 40 | }; 41 | -------------------------------------------------------------------------------- /components/icons/navbar/support-icon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const SupportIcon = () => { 4 | return ( 5 | 12 | 19 | 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /components/table/table.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | Link, 3 | Table, 4 | TableBody, 5 | TableCell, 6 | TableColumn, 7 | TableHeader, 8 | TableRow, 9 | } from "@nextui-org/react"; 10 | import React from "react"; 11 | import { columns, users } from "./data"; 12 | import { RenderCell } from "./render-cell"; 13 | 14 | export const TableWrapper = () => { 15 | return ( 16 |
17 | 18 | 19 | {(column) => ( 20 | 25 | {column.name} 26 | 27 | )} 28 | 29 | 30 | {(item) => ( 31 | 32 | {(columnKey) => ( 33 | 34 | {RenderCell({ user: item, columnKey: columnKey })} 35 | 36 | )} 37 | 38 | )} 39 | 40 |
41 |
42 | ); 43 | }; 44 | -------------------------------------------------------------------------------- /components/icons/sidebar/changelog-icon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const ChangeLogIcon = () => { 4 | return ( 5 | 12 | 19 | 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /components/icons/table/eye-icon.tsx: -------------------------------------------------------------------------------- 1 | interface Props { 2 | size?: number; 3 | fill?: string; 4 | width?: number; 5 | height?: number; 6 | } 7 | 8 | export const EyeIcon = ({fill, size, height, width, ...props}: Props) => { 9 | return ( 10 | 18 | 25 | 32 | 33 | ); 34 | }; 35 | -------------------------------------------------------------------------------- /components/navbar/navbar.styles.ts: -------------------------------------------------------------------------------- 1 | import { tv } from "@nextui-org/react"; 2 | 3 | // NEEDS TO BE REFACTORED 4 | 5 | export const StyledBurgerButton = tv({ 6 | base: "absolute flex flex-col justify-around w-6 h-6 bg-transparent border-none cursor-pointer padding-0 z-[202] focus:outline-none [&_div]:w-6 [&_div]:h-px [&_div]:bg-default-900 [&_div]:rounded-xl [&_div]:transition-all [&_div]:relative [&_div]:origin-[1px] ", 7 | 8 | variants: { 9 | open: { 10 | true: "[&", 11 | }, 12 | }, 13 | // "", 14 | // "& div": { 15 | 16 | // "&:first-child": { 17 | // transform: "translateY(-4px) rotate(0deg)", 18 | // height: "1px", 19 | // marginTop: "10px", 20 | // }, 21 | // "&:nth-child(2)": { 22 | // transform: "translateY(4px) rotate(0deg)", 23 | // height: "1px", 24 | // marginBottom: "10px", 25 | // }, 26 | // }, 27 | // variants: { 28 | // open: { 29 | // true: { 30 | // "& div": { 31 | // "&:first-child": { 32 | // marginTop: "0px", 33 | // transform: "translateY(1px) rotate(45deg)", 34 | // }, 35 | // "&:nth-child(2)": { 36 | // marginBottom: "0px", 37 | // transform: "translateY(4px) rotate(-45deg)", 38 | // }, 39 | // }, 40 | // }, 41 | // }, 42 | // }, 43 | }); 44 | -------------------------------------------------------------------------------- /components/sidebar/sidebar.styles.ts: -------------------------------------------------------------------------------- 1 | import { tv } from "@nextui-org/react"; 2 | 3 | export const SidebarWrapper = tv({ 4 | base: "bg-background transition-transform h-full fixed -translate-x-full w-64 shrink-0 z-[202] overflow-y-auto border-r border-divider flex-col py-6 px-3 md:ml-0 md:flex md:static md:h-screen md:translate-x-0 ", 5 | 6 | variants: { 7 | collapsed: { 8 | true: "translate-x-0 ml-0 pt-20 [display:inherit]", 9 | }, 10 | }, 11 | // "" 12 | // "@md": { 13 | // marginLeft: "0", 14 | // display: "flex", 15 | // position: "static", 16 | // height: "100vh", 17 | // transform: "translateX(0)", 18 | // }, 19 | // variants: { 20 | // collapsed: { 21 | // true: { 22 | // display: "inherit", 23 | // marginLeft: "0 ", 24 | // transform: "translateX(0)", 25 | // }, 26 | // }, 27 | // }, 28 | }); 29 | export const Overlay = tv({ 30 | base: "bg-[rgb(15_23_42/0.3)] fixed inset-0 z-[201] opacity-80 transition-opacity md:hidden md:z-auto md:opacity-100", 31 | }); 32 | 33 | export const Header = tv({ 34 | base: "flex gap-8 items-center px-6", 35 | }); 36 | 37 | export const Body = tv({ 38 | base: "flex flex-col gap-6 mt-9 px-2", 39 | }); 40 | 41 | export const Footer = tv({ 42 | base: "flex items-center justify-center gap-6 pt-16 pb-8 px-8 md:pt-10 md:pb-0", 43 | }); 44 | 45 | export const Sidebar = Object.assign(SidebarWrapper, { 46 | Header, 47 | Body, 48 | Overlay, 49 | Footer, 50 | }); 51 | -------------------------------------------------------------------------------- /components/icons/table/edit-icon.tsx: -------------------------------------------------------------------------------- 1 | interface Props { 2 | size?: number; 3 | fill?: string; 4 | width?: number; 5 | height?: number; 6 | } 7 | 8 | export const EditIcon = ({fill, size, height, width, ...props}: Props) => { 9 | return ( 10 | 18 | 26 | 34 | 42 | 43 | ); 44 | }; 45 | -------------------------------------------------------------------------------- /components/icons/sidebar/settings-icon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const SettingsIcon = () => { 4 | return ( 5 | 12 | 19 | 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /components/hooks/useBodyLock.ts: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import {useEffect, useState} from 'react'; 3 | import {useIsomorphicLayoutEffect} from './useIsomorphicLayoutEffect'; 4 | 5 | type ReturnType = [boolean, (locked: boolean) => void]; 6 | 7 | export const useLockedBody = (initialLocked = false): ReturnType => { 8 | const [locked, setLocked] = useState(initialLocked); 9 | 10 | // Do the side effect before render 11 | useIsomorphicLayoutEffect(() => { 12 | if (!locked) { 13 | return; 14 | } 15 | 16 | // Save initial body style 17 | const originalOverflow = document.body.style.overflow; 18 | const originalPaddingRight = document.body.style.paddingRight; 19 | 20 | // Lock body scroll 21 | document.body.style.overflow = 'hidden'; 22 | 23 | // Get the scrollBar width 24 | const root = document.getElementById('___gatsby'); // or root 25 | const scrollBarWidth = root ? root.offsetWidth - root.scrollWidth : 0; 26 | 27 | // Avoid width reflow 28 | if (scrollBarWidth) { 29 | document.body.style.paddingRight = `${scrollBarWidth}px`; 30 | } 31 | 32 | return () => { 33 | document.body.style.overflow = originalOverflow; 34 | 35 | if (scrollBarWidth) { 36 | document.body.style.paddingRight = originalPaddingRight; 37 | } 38 | }; 39 | }, [locked]); 40 | 41 | // Update state if initialValue changes 42 | useEffect(() => { 43 | if (locked !== initialLocked) { 44 | setLocked(initialLocked); 45 | } 46 | // eslint-disable-next-line react-hooks/exhaustive-deps 47 | }, [initialLocked]); 48 | 49 | return [locked, setLocked]; 50 | }; 51 | -------------------------------------------------------------------------------- /components/auth/authLayout.tsx: -------------------------------------------------------------------------------- 1 | import { Image } from "@nextui-org/react"; 2 | import { Divider } from "@nextui-org/divider"; 3 | 4 | interface Props { 5 | children: React.ReactNode; 6 | } 7 | 8 | export const AuthLayoutWrapper = ({ children }: Props) => { 9 | return ( 10 |
11 |
12 |
13 | gradient 18 |
19 | {children} 20 |
21 | 22 |
23 | 24 |
25 | 26 |
27 |
28 | gradient 33 |
34 | 35 |
36 |

NextUI Dashboard Template

37 |
38 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Quasi 39 | possimus voluptate, sapiente assumenda deserunt repellendus, 40 | perferendis odit voluptas hic dolores laborum fugit ut? Architecto 41 | quo ex quidem vitae quae rem. 42 |
43 |
44 |
45 |
46 | ); 47 | }; 48 | -------------------------------------------------------------------------------- /components/home/card-agents.tsx: -------------------------------------------------------------------------------- 1 | import { Avatar, AvatarGroup, Card, CardBody } from "@nextui-org/react"; 2 | import React from "react"; 3 | 4 | const pictureUsers = [ 5 | "https://i.pravatar.cc/150?u=a042581f4e29026024d", 6 | "https://i.pravatar.cc/150?u=a042581f4e29026704d", 7 | "https://i.pravatar.cc/150?u=a04258114e29026702d", 8 | "https://i.pravatar.cc/150?u=a048581f4e29026701d", 9 | "https://i.pravatar.cc/150?u=a092581d4ef9026700d", 10 | ]; 11 | 12 | export const CardAgents = () => { 13 | return ( 14 | 15 | 16 |
17 |
18 | 19 | {" "} 20 | {"⭐"}Agents 21 | 22 |
23 |
24 | 25 |
26 | 27 | Meet your agenda and see their ranks to get the best results 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
38 |
39 |
40 | ); 41 | }; 42 | -------------------------------------------------------------------------------- /components/home/card-balance3.tsx: -------------------------------------------------------------------------------- 1 | import { Card, CardBody } from "@nextui-org/react"; 2 | import React from "react"; 3 | import { Community } from "../icons/community"; 4 | 5 | export const CardBalance3 = () => { 6 | return ( 7 | 8 | 9 |
10 | 11 |
12 | Card Insurance 13 | 1311 Cars 14 |
15 |
16 |
17 | $3,910 18 | - 4.5% 19 |
20 |
21 |
22 |
23 | {"↓"} 24 | 100,930 25 |
26 | USD 27 |
28 | 29 |
30 |
31 | {"↑"} 32 | 4,120 33 |
34 | USD 35 |
36 | 37 |
38 |
39 | {"⭐"} 40 | 125 41 |
42 | VIP 43 |
44 |
45 |
46 |
47 | ); 48 | }; 49 | -------------------------------------------------------------------------------- /components/home/card-balance1.tsx: -------------------------------------------------------------------------------- 1 | import { Card, CardBody } from "@nextui-org/react"; 2 | import React from "react"; 3 | import { Community } from "../icons/community"; 4 | 5 | export const CardBalance1 = () => { 6 | return ( 7 | 8 | 9 |
10 | 11 |
12 | Auto Insurance 13 | 1311 Cars 14 |
15 |
16 |
17 | $45,910 18 | + 4.5% 19 |
20 |
21 |
22 |
23 | {"↓"} 24 | 100,930 25 |
26 | USD 27 |
28 | 29 |
30 |
31 | {"↑"} 32 | 54,120 33 |
34 | USD 35 |
36 | 37 |
38 |
39 | {"⭐"} 40 | 125 41 |
42 | VIP 43 |
44 |
45 |
46 |
47 | ); 48 | }; 49 | -------------------------------------------------------------------------------- /components/accounts/add-user.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | Button, 3 | Input, 4 | Modal, 5 | ModalBody, 6 | ModalContent, 7 | ModalFooter, 8 | ModalHeader, 9 | useDisclosure, 10 | } from "@nextui-org/react"; 11 | import React from "react"; 12 | 13 | export const AddUser = () => { 14 | const { isOpen, onOpen, onOpenChange } = useDisclosure(); 15 | 16 | return ( 17 |
18 | <> 19 | 22 | 27 | 28 | {(onClose) => ( 29 | <> 30 | 31 | Add User 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 45 | 46 | 47 | 50 | 53 | 54 | 55 | )} 56 | 57 | 58 | 59 |
60 | ); 61 | }; 62 | -------------------------------------------------------------------------------- /components/icons/navbar/notificationicon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const NotificationIcon = () => { 4 | return ( 5 | 13 | 19 | 20 | 24 | 25 | ); 26 | }; 27 | -------------------------------------------------------------------------------- /components/navbar/notifications-dropdown.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | Dropdown, 3 | DropdownItem, 4 | DropdownMenu, 5 | DropdownSection, 6 | DropdownTrigger, 7 | NavbarItem, 8 | } from "@nextui-org/react"; 9 | import React from "react"; 10 | import { NotificationIcon } from "../icons/navbar/notificationicon"; 11 | 12 | export const NotificationsDropdown = () => { 13 | return ( 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 30 | 📣 Edit your information 31 | 32 | 40 | 🚀 Say goodbye to paper receipts! 41 | 42 | 50 | 📣 Edit your information 51 | 52 | 53 | 54 | 55 | ); 56 | }; 57 | -------------------------------------------------------------------------------- /components/icons/table/delete-icon.tsx: -------------------------------------------------------------------------------- 1 | interface Props { 2 | size?: number; 3 | fill?: string; 4 | width?: number; 5 | height?: number; 6 | } 7 | export const DeleteIcon = ({fill, size, height, width, ...props}: Props) => { 8 | return ( 9 | 17 | 24 | 31 | 38 | 45 | 52 | 53 | ); 54 | }; 55 | -------------------------------------------------------------------------------- /components/home/card-balance2.tsx: -------------------------------------------------------------------------------- 1 | import { Card, CardBody } from "@nextui-org/react"; 2 | import React from "react"; 3 | import { Community } from "../icons/community"; 4 | 5 | export const CardBalance2 = () => { 6 | return ( 7 | 8 | 9 |
10 | 11 |
12 | Health Insurance 13 | +2400 People 14 |
15 |
16 |
17 | 18 | $12,138 19 | 20 | - 4.5% 21 |
22 |
23 |
24 |
25 | 26 | {"↓"} 27 | 28 | 11,930 29 |
30 | USD 31 |
32 | 33 |
34 |
35 | {"↑"} 36 | 54,120 37 |
38 | USD 39 |
40 | 41 |
42 |
43 | {"⭐"} 44 | 150 45 |
46 | VIP 47 |
48 |
49 |
50 |
51 | ); 52 | }; 53 | -------------------------------------------------------------------------------- /components/charts/steam.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Chart, { Props } from "react-apexcharts"; 3 | 4 | const state: Props["series"] = [ 5 | { 6 | name: "Series1", 7 | data: [31, 40, 28, 51, 42, 109, 100], 8 | }, 9 | { 10 | name: "Series2", 11 | data: [11, 32, 45, 32, 34, 52, 41], 12 | }, 13 | ]; 14 | 15 | const options: Props["options"] = { 16 | chart: { 17 | type: "area", 18 | animations: { 19 | easing: "linear", 20 | speed: 300, 21 | }, 22 | sparkline: { 23 | enabled: false, 24 | }, 25 | brush: { 26 | enabled: false, 27 | }, 28 | id: "basic-bar", 29 | foreColor: "hsl(var(--nextui-default-800))", 30 | stacked: true, 31 | toolbar: { 32 | show: false, 33 | }, 34 | }, 35 | 36 | xaxis: { 37 | categories: [1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999], 38 | labels: { 39 | // show: false, 40 | style: { 41 | colors: "hsl(var(--nextui-default-800))", 42 | }, 43 | }, 44 | axisBorder: { 45 | color: "hsl(var(--nextui-nextui-default-200))", 46 | }, 47 | axisTicks: { 48 | color: "hsl(var(--nextui-nextui-default-200))", 49 | }, 50 | }, 51 | yaxis: { 52 | labels: { 53 | style: { 54 | // hsl(var(--nextui-content1-foreground)) 55 | colors: "hsl(var(--nextui-default-800))", 56 | }, 57 | }, 58 | }, 59 | tooltip: { 60 | enabled: false, 61 | }, 62 | grid: { 63 | show: true, 64 | borderColor: "hsl(var(--nextui-default-200))", 65 | strokeDashArray: 0, 66 | position: "back", 67 | }, 68 | stroke: { 69 | curve: "smooth", 70 | fill: { 71 | colors: ["red"], 72 | }, 73 | }, 74 | // @ts-ignore 75 | markers: false, 76 | }; 77 | 78 | export const Steam = () => { 79 | return ( 80 | <> 81 |
82 |
83 | 84 |
85 |
86 | 87 | ); 88 | }; 89 | -------------------------------------------------------------------------------- /components/navbar/user-dropdown.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | Avatar, 3 | Dropdown, 4 | DropdownItem, 5 | DropdownMenu, 6 | DropdownTrigger, 7 | Navbar, 8 | NavbarItem, 9 | } from "@nextui-org/react"; 10 | import React, { useCallback } from "react"; 11 | import { DarkModeSwitch } from "./darkmodeswitch"; 12 | import { useRouter } from "next/navigation"; 13 | import { deleteAuthCookie } from "@/actions/auth.action"; 14 | 15 | export const UserDropdown = () => { 16 | const router = useRouter(); 17 | 18 | const handleLogout = useCallback(async () => { 19 | await deleteAuthCookie(); 20 | router.replace("/login"); 21 | }, [router]); 22 | 23 | return ( 24 | 25 | 26 | 27 | 33 | 34 | 35 | console.log({ actionKey })}> 38 | 41 |

Signed in as

42 |

zoey@example.com

43 |
44 | My Settings 45 | Team Settings 46 | Analytics 47 | System 48 | Configurations 49 | Help & Feedback 50 | 55 | Log Out 56 | 57 | 58 | 59 | 60 |
61 |
62 | ); 63 | }; 64 | -------------------------------------------------------------------------------- /components/icons/navbar/feedback-icon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const FeedbackIcon = () => { 4 | return ( 5 | 12 | 17 | 22 | 27 | 32 | 37 | 38 | ); 39 | }; 40 | -------------------------------------------------------------------------------- /components/navbar/navbar.tsx: -------------------------------------------------------------------------------- 1 | import { Input, Link, Navbar, NavbarContent } from "@nextui-org/react"; 2 | import React from "react"; 3 | import { FeedbackIcon } from "../icons/navbar/feedback-icon"; 4 | import { GithubIcon } from "../icons/navbar/github-icon"; 5 | import { SupportIcon } from "../icons/navbar/support-icon"; 6 | import { SearchIcon } from "../icons/searchicon"; 7 | import { BurguerButton } from "./burguer-button"; 8 | import { NotificationsDropdown } from "./notifications-dropdown"; 9 | import { UserDropdown } from "./user-dropdown"; 10 | 11 | interface Props { 12 | children: React.ReactNode; 13 | } 14 | 15 | export const NavbarWrapper = ({ children }: Props) => { 16 | return ( 17 |
18 | 25 | 26 | 27 | 28 | 29 | } 31 | isClearable 32 | className="w-full" 33 | classNames={{ 34 | input: "w-full", 35 | mainWrapper: "w-full", 36 | }} 37 | placeholder="Search..." 38 | /> 39 | 40 | 44 |
45 | 46 | Feedback? 47 |
48 | 49 | 50 | 51 |
52 | 53 |
54 | 55 | 59 | 60 | 61 | 62 | 63 | 64 |
65 |
66 | {children} 67 |
68 | ); 69 | }; 70 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NextJS and NextUI Dashboard Template Starter 2 | 3 | You can deploy here directly to vercel [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/import/project?template=https://github.com/Siumauricio/nextui-dashboard-template) 4 | 5 | 6 | V1 Version Stitches https://v1-nextui-dashboard-template.vercel.app/ 7 | V1 Code: https://github.com/Siumauricio/nextui-dashboard-template/tree/v1 8 | 9 | This is a template for NextJS and NextUI. 10 | 11 | [NextJS](https://nextjs.org/) 12 | [NextUI](https://nextui.org/) 13 | 14 | You can see the demo here: https://nextui-dashboard-template.vercel.app/ 15 | For improve this template, you can create a pull request or open an issue here [Issues](https://github.com/Siumauricio/nextui-dashboard-template/issues) or [Pull Request]( 16 | https://github.com/Siumauricio/nextui-dashboard-template/pulls) 17 | 18 | ### Dark Mode 19 | ![Dashboard Dark Mode](./public/dark.png) 20 | 21 | ### Light Mode 22 | ![Dashboard Light Mode](./public/light.png) 23 | 24 | 25 | - Dark Mode Support 26 | - Full Responsive 27 | - Home Page with Charts 28 | - Accounts Page 29 | - More pages coming soon... 30 | 31 | ``` 32 | ├── components 33 | │ ├── accounts # Accounts components 34 | │ ├── charts # Charts components 35 | │ ├── breadcrumb # component 36 | | ├── home # Home components 37 | | ├── layout # Layout components 38 | | ├── navbar # Navbar components 39 | | ├── sidebar # Sidebar components 40 | | ├── table # Table components 41 | | ├── styles # Some reusable components 42 | | ├── icons # Icons 43 | | ├── hooks # Hooks 44 | ├── app # Documentation files 45 | │ ├── accounts # Accounts route 46 | | ├── page.tsx # Accounts page 47 | │ ├── page.tsx # Entry point for the app 48 | │ ├── layout.tsx # Layout applied to all application pages 49 | │ ├── providers.tsx # Theme provider 50 | │ ├── more... # Soon 51 | └── 52 | ``` 53 | 54 | ## For Run 55 | 56 | Install dependencies 57 | 58 | 59 | ```bash 60 | npm install 61 | ``` 62 | 63 | Start the server 64 | 65 | 66 | 67 | ```bash 68 | npm run dev 69 | ``` 70 | 71 | Now you can visit https://localhost:3000 in your browser. 72 | -------------------------------------------------------------------------------- /components/accounts/index.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import { Button, Input } from "@nextui-org/react"; 3 | import Link from "next/link"; 4 | import React from "react"; 5 | import { DotsIcon } from "@/components/icons/accounts/dots-icon"; 6 | import { ExportIcon } from "@/components/icons/accounts/export-icon"; 7 | import { InfoIcon } from "@/components/icons/accounts/info-icon"; 8 | import { TrashIcon } from "@/components/icons/accounts/trash-icon"; 9 | import { HouseIcon } from "@/components/icons/breadcrumb/house-icon"; 10 | import { UsersIcon } from "@/components/icons/breadcrumb/users-icon"; 11 | import { SettingsIcon } from "@/components/icons/sidebar/settings-icon"; 12 | import { TableWrapper } from "@/components/table/table"; 13 | import { AddUser } from "./add-user"; 14 | 15 | export const Accounts = () => { 16 | return ( 17 |
18 |
    19 |
  • 20 | 21 | 22 | Home 23 | 24 | / {" "} 25 |
  • 26 | 27 |
  • 28 | 29 | Users 30 | / {" "} 31 |
  • 32 |
  • 33 | List 34 |
  • 35 |
36 | 37 |

All Accounts

38 |
39 |
40 | 47 | 48 | 49 | 50 | 51 |
52 |
53 | 54 | 57 |
58 |
59 |
60 | 61 |
62 |
63 | ); 64 | }; 65 | -------------------------------------------------------------------------------- /components/home/card-transactions.tsx: -------------------------------------------------------------------------------- 1 | import { Avatar, Card, CardBody } from "@nextui-org/react"; 2 | import React from "react"; 3 | 4 | const items = [ 5 | { 6 | name: "Jose Perez", 7 | picture: "https://i.pravatar.cc/150?u=a042581f4e29026024d", 8 | amount: "4500 USD", 9 | date: "9/20/2021", 10 | }, 11 | { 12 | name: "Jose Perez", 13 | picture: "https://i.pravatar.cc/150?u=a042581f4e29026024d", 14 | amount: "4500 USD", 15 | date: "9/20/2021", 16 | }, 17 | { 18 | name: "Jose Perez", 19 | picture: "https://i.pravatar.cc/150?u=a042581f4e29026024d", 20 | amount: "4500 USD", 21 | date: "9/20/2021", 22 | }, 23 | { 24 | name: "Jose Perez", 25 | picture: "https://i.pravatar.cc/150?u=a042581f4e29026024d", 26 | amount: "4500 USD", 27 | date: "9/20/2021", 28 | }, 29 | { 30 | name: "Jose Perez", 31 | picture: "https://i.pravatar.cc/150?u=a042581f4e29026024d", 32 | amount: "4500 USD", 33 | date: "9/20/2021", 34 | }, 35 | ]; 36 | 37 | export const CardTransactions = () => { 38 | return ( 39 | 40 | 41 |
42 |
43 | 44 | Latest Transactions 45 | 46 |
47 |
48 | 49 |
50 | {items.map((item) => ( 51 |
52 |
53 | 58 |
59 | 60 | 61 | {item.name} 62 | 63 |
64 | {item.amount} 65 |
66 |
67 | {item.date} 68 |
69 |
70 | ))} 71 |
72 |
73 |
74 | ); 75 | }; 76 | -------------------------------------------------------------------------------- /components/auth/login.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { createAuthCookie } from "@/actions/auth.action"; 4 | import { LoginSchema } from "@/helpers/schemas"; 5 | import { LoginFormType } from "@/helpers/types"; 6 | import { Button, Input } from "@nextui-org/react"; 7 | import { Formik } from "formik"; 8 | import Link from "next/link"; 9 | import { useRouter } from "next/navigation"; 10 | import { useCallback } from "react"; 11 | 12 | export const Login = () => { 13 | const router = useRouter(); 14 | 15 | const initialValues: LoginFormType = { 16 | email: "admin@acme.com", 17 | password: "admin", 18 | }; 19 | 20 | const handleLogin = useCallback( 21 | async (values: LoginFormType) => { 22 | // `values` contains email & password. You can use provider to connect user 23 | 24 | await createAuthCookie(); 25 | router.replace("/"); 26 | }, 27 | [router] 28 | ); 29 | 30 | return ( 31 | <> 32 |
Login
33 | 34 | 38 | {({ values, errors, touched, handleChange, handleSubmit }) => ( 39 | <> 40 |
41 | 50 | 59 |
60 | 61 | 67 | 68 | )} 69 |
70 | 71 |
72 | Don't have an account ?{" "} 73 | 74 | Register here 75 | 76 |
77 | 78 | ); 79 | }; 80 | -------------------------------------------------------------------------------- /components/home/content.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import React from "react"; 3 | import dynamic from "next/dynamic"; 4 | import { TableWrapper } from "../table/table"; 5 | import { CardBalance1 } from "./card-balance1"; 6 | import { CardBalance2 } from "./card-balance2"; 7 | import { CardBalance3 } from "./card-balance3"; 8 | import { CardAgents } from "./card-agents"; 9 | import { CardTransactions } from "./card-transactions"; 10 | import { Link } from "@nextui-org/react"; 11 | import NextLink from "next/link"; 12 | 13 | const Chart = dynamic( 14 | () => import("../charts/steam").then((mod) => mod.Steam), 15 | { 16 | ssr: false, 17 | } 18 | ); 19 | 20 | export const Content = () => ( 21 |
22 |
23 |
24 | {/* Card Section Top */} 25 |
26 |

Available Balance

27 |
28 | 29 | 30 | 31 |
32 |
33 | 34 | {/* Chart */} 35 |
36 |

Statistics

37 |
38 | 39 |
40 |
41 |
42 | 43 | {/* Left Section */} 44 |
45 |

Section

46 |
47 | 48 | 49 |
50 |
51 |
52 | 53 | {/* Table Latest Users */} 54 |
55 |
56 |

Latest Users

57 | 63 | View All 64 | 65 |
66 | 67 |
68 |
69 | ); 70 | -------------------------------------------------------------------------------- /components/table/render-cell.tsx: -------------------------------------------------------------------------------- 1 | import { User, Tooltip, Chip } from "@nextui-org/react"; 2 | import React from "react"; 3 | import { DeleteIcon } from "../icons/table/delete-icon"; 4 | import { EditIcon } from "../icons/table/edit-icon"; 5 | import { EyeIcon } from "../icons/table/eye-icon"; 6 | import { users } from "./data"; 7 | 8 | interface Props { 9 | user: (typeof users)[number]; 10 | columnKey: string | React.Key; 11 | } 12 | 13 | export const RenderCell = ({ user, columnKey }: Props) => { 14 | // @ts-ignore 15 | const cellValue = user[columnKey]; 16 | switch (columnKey) { 17 | case "name": 18 | return ( 19 | 25 | {user.email} 26 | 27 | ); 28 | case "role": 29 | return ( 30 |
31 |
32 | {cellValue} 33 |
34 |
35 | {user.team} 36 |
37 |
38 | ); 39 | case "status": 40 | return ( 41 | 52 | {cellValue} 53 | 54 | ); 55 | 56 | case "actions": 57 | return ( 58 |
59 |
60 | 61 | 64 | 65 |
66 |
67 | 68 | 71 | 72 |
73 |
74 | console.log("Delete user", user.id)} 78 | > 79 | 82 | 83 |
84 |
85 | ); 86 | default: 87 | return cellValue; 88 | } 89 | }; 90 | -------------------------------------------------------------------------------- /components/auth/register.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { createAuthCookie } from "@/actions/auth.action"; 4 | import { RegisterSchema } from "@/helpers/schemas"; 5 | import { RegisterFormType } from "@/helpers/types"; 6 | import { Button, Input } from "@nextui-org/react"; 7 | import { Formik } from "formik"; 8 | import Link from "next/link"; 9 | import { useRouter } from "next/navigation"; 10 | import { useCallback } from "react"; 11 | 12 | export const Register = () => { 13 | const router = useRouter(); 14 | 15 | const initialValues: RegisterFormType = { 16 | name: "Acme", 17 | email: "admin@acme.com", 18 | password: "admin", 19 | confirmPassword: "admin", 20 | }; 21 | 22 | const handleRegister = useCallback( 23 | async (values: RegisterFormType) => { 24 | // `values` contains name, email & password. You can use provider to register user 25 | 26 | await createAuthCookie(); 27 | router.replace("/"); 28 | }, 29 | [router] 30 | ); 31 | 32 | return ( 33 | <> 34 |
Register
35 | 36 | 40 | {({ values, errors, touched, handleChange, handleSubmit }) => ( 41 | <> 42 |
43 | 51 | 60 | 69 | 80 |
81 | 82 | 88 | 89 | )} 90 |
91 | 92 |
93 | Already have an account ?{" "} 94 | 95 | Login here 96 | 97 |
98 | 99 | ); 100 | }; 101 | -------------------------------------------------------------------------------- /components/icons/community.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | interface Props { 4 | color?: string; 5 | } 6 | 7 | export const Community = ({ color = "white" }: Props) => { 8 | return ( 9 | 16 | 23 | 24 | ); 25 | }; 26 | -------------------------------------------------------------------------------- /components/sidebar/companies-dropdown.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import { 3 | Dropdown, 4 | DropdownItem, 5 | DropdownMenu, 6 | DropdownSection, 7 | DropdownTrigger, 8 | } from "@nextui-org/react"; 9 | import React, { useState } from "react"; 10 | import { AcmeIcon } from "../icons/acme-icon"; 11 | import { AcmeLogo } from "../icons/acmelogo"; 12 | import { BottomIcon } from "../icons/sidebar/bottom-icon"; 13 | 14 | interface Company { 15 | name: string; 16 | location: string; 17 | logo: React.ReactNode; 18 | } 19 | 20 | export const CompaniesDropdown = () => { 21 | const [company, setCompany] = useState({ 22 | name: "Acme Co.", 23 | location: "Palo Alto, CA", 24 | logo: , 25 | }); 26 | return ( 27 | 32 | 33 |
34 | {company.logo} 35 |
36 |

37 | {company.name} 38 |

39 | 40 | {company.location} 41 | 42 |
43 | 44 |
45 |
46 | { 48 | if (e === "1") { 49 | setCompany({ 50 | name: "Facebook", 51 | location: "San Fransico, CA", 52 | logo: , 53 | }); 54 | } 55 | if (e === "2") { 56 | setCompany({ 57 | name: "Instagram", 58 | location: "Austin, Tx", 59 | logo: , 60 | }); 61 | } 62 | if (e === "3") { 63 | setCompany({ 64 | name: "Twitter", 65 | location: "Brooklyn, NY", 66 | logo: , 67 | }); 68 | } 69 | if (e === "4") { 70 | setCompany({ 71 | name: "Acme Co.", 72 | location: "Palo Alto, CA", 73 | logo: , 74 | }); 75 | } 76 | }} 77 | aria-label="Avatar Actions" 78 | > 79 | 80 | } 83 | description="San Fransico, CA" 84 | classNames={{ 85 | base: "py-4", 86 | title: "text-base font-semibold", 87 | }} 88 | > 89 | Facebook 90 | 91 | } 94 | description="Austin, Tx" 95 | classNames={{ 96 | base: "py-4", 97 | title: "text-base font-semibold", 98 | }} 99 | > 100 | Instagram 101 | 102 | } 105 | description="Brooklyn, NY" 106 | classNames={{ 107 | base: "py-4", 108 | title: "text-base font-semibold", 109 | }} 110 | > 111 | Twitter 112 | 113 | } 116 | description="Palo Alto, CA" 117 | classNames={{ 118 | base: "py-4", 119 | title: "text-base font-semibold", 120 | }} 121 | > 122 | Acme Co. 123 | 124 | 125 | 126 |
127 | ); 128 | }; 129 | -------------------------------------------------------------------------------- /components/sidebar/collapse-items.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import React, { useState } from "react"; 3 | import { ChevronDownIcon } from "../icons/sidebar/chevron-down-icon"; 4 | import { Accordion, AccordionItem } from "@nextui-org/react"; 5 | import clsx from "clsx"; 6 | 7 | interface Props { 8 | icon: React.ReactNode; 9 | title: string; 10 | items: string[]; 11 | } 12 | 13 | export const CollapseItems = ({ icon, items, title }: Props) => { 14 | const [open, setOpen] = useState(false); 15 | 16 | return ( 17 |
18 | 19 | } 21 | classNames={{ 22 | indicator: "data-[open=true]:-rotate-180", 23 | trigger: 24 | "py-0 min-h-[44px] hover:bg-default-100 rounded-xl active:scale-[0.98] transition-transform px-3.5", 25 | 26 | title: 27 | "px-0 flex text-base gap-2 h-full items-center cursor-pointer", 28 | }} 29 | aria-label="Accordion 1" 30 | title={ 31 |
32 | {icon} 33 | {title} 34 |
35 | } 36 | > 37 |
38 | {items.map((item, index) => ( 39 | 43 | {item} 44 | 45 | ))} 46 |
47 |
48 |
49 | {/* 70 |
71 | {icon} 72 | 81 | {title} 82 | 83 |
84 | 85 | 95 |
96 | } 97 | // css={{ 98 | // width: "100%", 99 | // "& .nextui-collapse-view": { 100 | // p: "0", 101 | // }, 102 | // "& .nextui-collapse-content": { 103 | // marginTop: "$1", 104 | // padding: "0px", 105 | // }, 106 | // }} 107 | divider={false} 108 | showArrow={false} 109 | > 110 | {items.map((item, index) => ( 111 |
119 | 132 | {item} 133 | 134 |
135 | ))} 136 | */} 137 |
138 | ); 139 | }; 140 | -------------------------------------------------------------------------------- /components/table/data.ts: -------------------------------------------------------------------------------- 1 | export const columns = [ 2 | {name: 'NAME', uid: 'name'}, 3 | {name: 'ROLE', uid: 'role'}, 4 | {name: 'STATUS', uid: 'status'}, 5 | {name: 'ACTIONS', uid: 'actions'}, 6 | ]; 7 | export const users = [ 8 | { 9 | id: 1, 10 | name: 'Tony Reichert', 11 | role: 'CEO', 12 | team: 'Management', 13 | status: 'active', 14 | age: '29', 15 | avatar: 'https://i.pravatar.cc/150?u=a042581f4e29026024d', 16 | email: 'tony.reichert@example.com', 17 | }, 18 | { 19 | id: 2, 20 | name: 'Zoey Lang', 21 | role: 'Technical Lead', 22 | team: 'Development', 23 | status: 'paused', 24 | age: '25', 25 | avatar: 'https://i.pravatar.cc/150?u=a042581f4e29026704d', 26 | email: 'zoey.lang@example.com', 27 | }, 28 | { 29 | id: 3, 30 | name: 'Jane Fisher', 31 | role: 'Senior Developer', 32 | team: 'Development', 33 | status: 'active', 34 | age: '22', 35 | avatar: 'https://i.pravatar.cc/150?u=a04258114e29026702d', 36 | email: 'jane.fisher@example.com', 37 | }, 38 | { 39 | id: 4, 40 | name: 'William Howard', 41 | role: 'Community Manager', 42 | team: 'Marketing', 43 | status: 'vacation', 44 | age: '28', 45 | avatar: 'https://i.pravatar.cc/150?u=a048581f4e29026701d', 46 | email: 'william.howard@example.com', 47 | }, 48 | { 49 | id: 5, 50 | name: 'Kristen Copper', 51 | role: 'Sales Manager', 52 | team: 'Sales', 53 | status: 'active', 54 | age: '24', 55 | avatar: 'https://i.pravatar.cc/150?u=a092581d4ef9026700d', 56 | email: 'kristen.cooper@example.com', 57 | }, 58 | { 59 | id: 6, 60 | name: 'Tony Reichert', 61 | role: 'CEO', 62 | team: 'Management', 63 | status: 'active', 64 | age: '29', 65 | avatar: 'https://i.pravatar.cc/150?u=a042581f4e29026024d', 66 | email: 'tony.reichert@example.com', 67 | }, 68 | { 69 | id: 10, 70 | name: 'Kristen Copper', 71 | role: 'Sales Manager', 72 | team: 'Sales', 73 | status: 'active', 74 | age: '24', 75 | avatar: 'https://i.pravatar.cc/150?u=a092581d4ef9026700d', 76 | email: 'kristen.cooper@example.com', 77 | }, 78 | { 79 | id: 8, 80 | name: 'Jane Fisher', 81 | role: 'Senior Developer', 82 | team: 'Development', 83 | status: 'active', 84 | age: '22', 85 | avatar: 'https://i.pravatar.cc/150?u=a04258114e29026702d', 86 | email: 'jane.fisher@example.com', 87 | }, 88 | { 89 | id: 7, 90 | name: 'Zoey Lang', 91 | role: 'Technical Lead', 92 | team: 'Development', 93 | status: 'paused', 94 | age: '25', 95 | avatar: 'https://i.pravatar.cc/150?u=a042581f4e29026704d', 96 | email: 'zoey.lang@example.com', 97 | }, 98 | 99 | { 100 | id: 9, 101 | name: 'William Howard', 102 | role: 'Community Manager', 103 | team: 'Marketing', 104 | status: 'vacation', 105 | age: '28', 106 | avatar: 'https://i.pravatar.cc/150?u=a048581f4e29026701d', 107 | email: 'william.howard@example.com', 108 | }, 109 | { 110 | id: 11, 111 | name: 'Tony Reichert', 112 | role: 'CEO', 113 | team: 'Management', 114 | status: 'active', 115 | age: '29', 116 | avatar: 'https://i.pravatar.cc/150?u=a042581f4e29026024d', 117 | email: 'tony.reichert@example.com', 118 | }, 119 | { 120 | id: 12, 121 | name: 'Kristen Copper', 122 | role: 'Sales Manager', 123 | team: 'Sales', 124 | status: 'active', 125 | age: '24', 126 | avatar: 'https://i.pravatar.cc/150?u=a092581d4ef9026700d', 127 | email: 'kristen.cooper@example.com', 128 | }, 129 | { 130 | id: 13, 131 | name: 'Jane Fisher', 132 | role: 'Senior Developer', 133 | team: 'Development', 134 | status: 'active', 135 | age: '22', 136 | avatar: 'https://i.pravatar.cc/150?u=a04258114e29026702d', 137 | email: 'jane.fisher@example.com', 138 | }, 139 | { 140 | id: 14, 141 | name: 'Zoey Lang', 142 | role: 'Technical Lead', 143 | team: 'Development', 144 | status: 'paused', 145 | age: '25', 146 | avatar: 'https://i.pravatar.cc/150?u=a042581f4e29026704d', 147 | email: 'zoey.lang@example.com', 148 | }, 149 | { 150 | id: 15, 151 | name: 'Tony Reichert', 152 | role: 'CEO', 153 | team: 'Management', 154 | status: 'active', 155 | age: '29', 156 | avatar: 'https://i.pravatar.cc/150?u=a042581f4e29026024d', 157 | email: 'tony.reichert@example.com', 158 | }, 159 | { 160 | id: 16, 161 | name: 'Kristen Copper', 162 | role: 'Sales Manager', 163 | team: 'Sales', 164 | status: 'active', 165 | age: '24', 166 | avatar: 'https://i.pravatar.cc/150?u=a092581d4ef9026700d', 167 | email: 'kristen.cooper@example.com', 168 | }, 169 | ]; 170 | -------------------------------------------------------------------------------- /components/icons/acme-icon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const AcmeIcon = () => { 4 | return ( 5 | 13 | 21 | 28 | 29 | ); 30 | }; 31 | -------------------------------------------------------------------------------- /components/sidebar/sidebar.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Sidebar } from "./sidebar.styles"; 3 | import { Avatar, Tooltip } from "@nextui-org/react"; 4 | import { CompaniesDropdown } from "./companies-dropdown"; 5 | import { HomeIcon } from "../icons/sidebar/home-icon"; 6 | import { PaymentsIcon } from "../icons/sidebar/payments-icon"; 7 | import { BalanceIcon } from "../icons/sidebar/balance-icon"; 8 | import { AccountsIcon } from "../icons/sidebar/accounts-icon"; 9 | import { CustomersIcon } from "../icons/sidebar/customers-icon"; 10 | import { ProductsIcon } from "../icons/sidebar/products-icon"; 11 | import { ReportsIcon } from "../icons/sidebar/reports-icon"; 12 | import { DevIcon } from "../icons/sidebar/dev-icon"; 13 | import { ViewIcon } from "../icons/sidebar/view-icon"; 14 | import { SettingsIcon } from "../icons/sidebar/settings-icon"; 15 | import { CollapseItems } from "./collapse-items"; 16 | import { SidebarItem } from "./sidebar-item"; 17 | import { SidebarMenu } from "./sidebar-menu"; 18 | import { FilterIcon } from "../icons/sidebar/filter-icon"; 19 | import { useSidebarContext } from "../layout/layout-context"; 20 | import { ChangeLogIcon } from "../icons/sidebar/changelog-icon"; 21 | import { usePathname } from "next/navigation"; 22 | 23 | export const SidebarWrapper = () => { 24 | const pathname = usePathname(); 25 | const { collapsed, setCollapsed } = useSidebarContext(); 26 | 27 | return ( 28 | 129 | ); 130 | }; 131 | --------------------------------------------------------------------------------