From 30244439f413171dd593a3d7c0466f080841060a Mon Sep 17 00:00:00 2001 From: Iceship Date: Thu, 3 Oct 2024 17:08:41 +0900 Subject: [PATCH] add dashboard layout --- .vscode/settings.json | 3 + middleware.ts | 26 ---- package.json | 2 +- pnpm-lock.yaml | 120 +++++++-------- src/actions/auth.action.ts | 11 ++ src/app/(app)/layout.tsx | 10 ++ src/app/(app)/page.tsx | 9 ++ src/app/(auth)/layout.tsx | 10 ++ src/app/(auth)/login/page.tsx | 7 + src/app/(dashboard)/admin/layout.tsx | 10 ++ src/app/(dashboard)/admin/page.tsx | 16 +- src/app/_components/auth-button.tsx | 74 ---------- src/app/globals.css | 3 - src/app/layout.tsx | 21 ++- src/app/page.tsx | 42 ------ src/{components => app}/providers.tsx | 26 ++-- src/components/app-navbar/index.tsx | 4 +- src/components/auth/auth-button.tsx | 60 ++++++++ src/components/auth/auth-layout.tsx | 47 ++++++ src/components/auth/login.tsx | 19 +++ src/components/home/content.tsx | 46 ++++++ src/components/hooks/use-body-lock.ts | 52 +++++++ .../hooks/use-isomorphic-layout-effect.ts | 4 + src/components/icons/accounts/dots-icon.tsx | 21 +++ src/components/icons/accounts/export-icon.tsx | 21 +++ src/components/icons/accounts/info-icon.tsx | 19 +++ src/components/icons/accounts/trash-icon.tsx | 21 +++ src/components/icons/acme-icon.tsx | 30 ++++ src/components/icons/acmelogo.tsx | 21 +++ .../icons/breadcrumb/house-icon.tsx | 21 +++ .../icons/breadcrumb/users-icon.tsx | 21 +++ src/components/icons/community.tsx | 25 ++++ src/components/icons/navbar/feedback-icon.tsx | 39 +++++ src/components/icons/navbar/github-icon.tsx | 14 ++ .../icons/navbar/notificationicon.tsx | 26 ++++ src/components/icons/navbar/support-icon.tsx | 21 +++ src/components/icons/searchicon.tsx | 30 ++++ .../icons/sidebar/accounts-icon.tsx | 21 +++ src/components/icons/sidebar/balance-icon.tsx | 21 +++ src/components/icons/sidebar/bottom-icon.tsx | 21 +++ .../icons/sidebar/changelog-icon.tsx | 21 +++ .../icons/sidebar/chevron-down-icon.tsx | 17 +++ .../icons/sidebar/chevron-up-icon.tsx | 20 +++ .../icons/sidebar/customers-icon.tsx | 21 +++ src/components/icons/sidebar/dev-icon.tsx | 21 +++ src/components/icons/sidebar/filter-icon.tsx | 19 +++ src/components/icons/sidebar/home-icon.tsx | 21 +++ .../icons/sidebar/payments-icon.tsx | 21 +++ .../icons/sidebar/products-icon.tsx | 21 +++ src/components/icons/sidebar/reports-icon.tsx | 21 +++ .../icons/sidebar/settings-icon.tsx | 21 +++ src/components/icons/sidebar/view-icon.tsx | 21 +++ src/components/icons/table/delete-icon.tsx | 54 +++++++ src/components/icons/table/edit-icon.tsx | 44 ++++++ src/components/icons/table/eye-icon.tsx | 34 +++++ src/components/layout/layout-context.ts | 17 +++ src/components/layout/layout.tsx | 35 +++++ src/components/navbar/burguer-button.tsx | 18 +++ src/components/navbar/darkmodeswitch.tsx | 13 ++ src/components/navbar/navbar.styles.ts | 43 ++++++ src/components/navbar/navbar.tsx | 71 +++++++++ .../navbar/notifications-dropdown.tsx | 56 +++++++ src/components/navbar/user-dropdown.tsx | 63 ++++++++ src/components/sidebar/collapse-items.tsx | 139 ++++++++++++++++++ src/components/sidebar/companies-dropdown.tsx | 128 ++++++++++++++++ src/components/sidebar/sidebar-item.tsx | 40 +++++ src/components/sidebar/sidebar-menu.tsx | 15 ++ src/components/sidebar/sidebar.styles.ts | 50 +++++++ src/components/sidebar/sidebar.tsx | 130 ++++++++++++++++ src/helpers/schemas.ts | 19 +++ src/helpers/types.ts | 13 ++ src/middleware.ts | 7 + src/styles/globals.css | 13 ++ 73 files changed, 2024 insertions(+), 238 deletions(-) delete mode 100644 middleware.ts create mode 100644 src/actions/auth.action.ts create mode 100644 src/app/(app)/layout.tsx create mode 100644 src/app/(app)/page.tsx create mode 100644 src/app/(auth)/layout.tsx create mode 100644 src/app/(auth)/login/page.tsx create mode 100644 src/app/(dashboard)/admin/layout.tsx delete mode 100644 src/app/_components/auth-button.tsx delete mode 100644 src/app/globals.css delete mode 100644 src/app/page.tsx rename src/{components => app}/providers.tsx (50%) create mode 100644 src/components/auth/auth-button.tsx create mode 100644 src/components/auth/auth-layout.tsx create mode 100644 src/components/auth/login.tsx create mode 100644 src/components/home/content.tsx create mode 100644 src/components/hooks/use-body-lock.ts create mode 100644 src/components/hooks/use-isomorphic-layout-effect.ts create mode 100644 src/components/icons/accounts/dots-icon.tsx create mode 100644 src/components/icons/accounts/export-icon.tsx create mode 100644 src/components/icons/accounts/info-icon.tsx create mode 100644 src/components/icons/accounts/trash-icon.tsx create mode 100644 src/components/icons/acme-icon.tsx create mode 100644 src/components/icons/acmelogo.tsx create mode 100644 src/components/icons/breadcrumb/house-icon.tsx create mode 100644 src/components/icons/breadcrumb/users-icon.tsx create mode 100644 src/components/icons/community.tsx create mode 100644 src/components/icons/navbar/feedback-icon.tsx create mode 100644 src/components/icons/navbar/github-icon.tsx create mode 100644 src/components/icons/navbar/notificationicon.tsx create mode 100644 src/components/icons/navbar/support-icon.tsx create mode 100644 src/components/icons/searchicon.tsx create mode 100644 src/components/icons/sidebar/accounts-icon.tsx create mode 100644 src/components/icons/sidebar/balance-icon.tsx create mode 100644 src/components/icons/sidebar/bottom-icon.tsx create mode 100644 src/components/icons/sidebar/changelog-icon.tsx create mode 100644 src/components/icons/sidebar/chevron-down-icon.tsx create mode 100644 src/components/icons/sidebar/chevron-up-icon.tsx create mode 100644 src/components/icons/sidebar/customers-icon.tsx create mode 100644 src/components/icons/sidebar/dev-icon.tsx create mode 100644 src/components/icons/sidebar/filter-icon.tsx create mode 100644 src/components/icons/sidebar/home-icon.tsx create mode 100644 src/components/icons/sidebar/payments-icon.tsx create mode 100644 src/components/icons/sidebar/products-icon.tsx create mode 100644 src/components/icons/sidebar/reports-icon.tsx create mode 100644 src/components/icons/sidebar/settings-icon.tsx create mode 100644 src/components/icons/sidebar/view-icon.tsx create mode 100644 src/components/icons/table/delete-icon.tsx create mode 100644 src/components/icons/table/edit-icon.tsx create mode 100644 src/components/icons/table/eye-icon.tsx create mode 100644 src/components/layout/layout-context.ts create mode 100644 src/components/layout/layout.tsx create mode 100644 src/components/navbar/burguer-button.tsx create mode 100644 src/components/navbar/darkmodeswitch.tsx create mode 100644 src/components/navbar/navbar.styles.ts create mode 100644 src/components/navbar/navbar.tsx create mode 100644 src/components/navbar/notifications-dropdown.tsx create mode 100644 src/components/navbar/user-dropdown.tsx create mode 100644 src/components/sidebar/collapse-items.tsx create mode 100644 src/components/sidebar/companies-dropdown.tsx create mode 100644 src/components/sidebar/sidebar-item.tsx create mode 100644 src/components/sidebar/sidebar-menu.tsx create mode 100644 src/components/sidebar/sidebar.styles.ts create mode 100644 src/components/sidebar/sidebar.tsx create mode 100644 src/helpers/schemas.ts create mode 100644 src/helpers/types.ts create mode 100644 src/middleware.ts create mode 100644 src/styles/globals.css diff --git a/.vscode/settings.json b/.vscode/settings.json index 6e5059a..9d865f5 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -21,10 +21,13 @@ "editor.defaultFormatter": "Prisma.prisma" }, "cSpell.words": [ + "burguer", + "Burguer", "formik", "Formik", "jiti", "nextui", + "searchicon", "signin", "signout", "superjson", diff --git a/middleware.ts b/middleware.ts deleted file mode 100644 index 72030d7..0000000 --- a/middleware.ts +++ /dev/null @@ -1,26 +0,0 @@ -import type { NextRequest } from "next/server"; -import { NextResponse } from "next/server"; - -export function middleware(request: NextRequest) { - const { pathname } = request.nextUrl; - console.log("middle pathname:", pathname); - console.dir(request, { depth: 2 }); - - if ( - (pathname === "/login" || pathname === "/register") && - request.cookies.has("userAuth") - ) - return NextResponse.redirect(new URL("/", request.url)); - - if ( - (pathname === "/" || pathname === "/accounts") && - !request.cookies.has("userAuth") - ) - return NextResponse.redirect(new URL("/login", request.url)); - - return NextResponse.next(); -} - -export const config = { - matcher: ["/", "/accounts", "/login", "/register"], -}; diff --git a/package.json b/package.json index b88a391..71ab48b 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "framer-motion": "^11.7.0", "geist": "^1.3.1", "jiti": "^2.0.0", - "next": "14.2.13", + "next": "14.2.14", "next-auth": "^4.24.8", "next-themes": "^0.3.0", "postgres": "^3.4.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d23b906..7f7ac3f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -37,7 +37,7 @@ importers: version: 11.0.0-rc.532(@trpc/server@11.0.0-rc.532) '@trpc/next': specifier: 11.0.0-rc.532 - version: 11.0.0-rc.532(@tanstack/react-query@5.56.2(react@18.3.1))(@trpc/client@11.0.0-rc.532(@trpc/server@11.0.0-rc.532))(@trpc/react-query@11.0.0-rc.532(@tanstack/react-query@5.56.2(react@18.3.1))(@trpc/client@11.0.0-rc.532(@trpc/server@11.0.0-rc.532))(@trpc/server@11.0.0-rc.532)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@trpc/server@11.0.0-rc.532)(next@14.2.13(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 11.0.0-rc.532(@tanstack/react-query@5.56.2(react@18.3.1))(@trpc/client@11.0.0-rc.532(@trpc/server@11.0.0-rc.532))(@trpc/react-query@11.0.0-rc.532(@tanstack/react-query@5.56.2(react@18.3.1))(@trpc/client@11.0.0-rc.532(@trpc/server@11.0.0-rc.532))(@trpc/server@11.0.0-rc.532)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@trpc/server@11.0.0-rc.532)(next@14.2.14(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@trpc/react-query': specifier: 11.0.0-rc.532 version: 11.0.0-rc.532(@tanstack/react-query@5.56.2(react@18.3.1))(@trpc/client@11.0.0-rc.532(@trpc/server@11.0.0-rc.532))(@trpc/server@11.0.0-rc.532)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -52,16 +52,16 @@ importers: version: 11.7.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) geist: specifier: ^1.3.1 - version: 1.3.1(next@14.2.13(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + version: 1.3.1(next@14.2.14(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) jiti: specifier: ^2.0.0 version: 2.0.0 next: - specifier: 14.2.13 - version: 14.2.13(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 14.2.14 + version: 14.2.14(react-dom@18.3.1(react@18.3.1))(react@18.3.1) next-auth: specifier: ^4.24.8 - version: 4.24.8(next@14.2.13(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 4.24.8(next@14.2.14(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) next-themes: specifier: ^0.3.0 version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -316,62 +316,62 @@ packages: '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - '@next/env@14.2.13': - resolution: {integrity: sha512-s3lh6K8cbW1h5Nga7NNeXrbe0+2jIIYK9YaA9T7IufDWnZpozdFUp6Hf0d5rNWUKu4fEuSX2rCKlGjCrtylfDw==} + '@next/env@14.2.14': + resolution: {integrity: sha512-/0hWQfiaD5//LvGNgc8PjvyqV50vGK0cADYzaoOOGN8fxzBn3iAiaq3S0tCRnFBldq0LVveLcxCTi41ZoYgAgg==} '@next/eslint-plugin-next@14.2.13': resolution: {integrity: sha512-z8Mk0VljxhIzsSiZUSdt3wp+t2lKd+jk5a9Jsvh3zDGkItgDMfjv/ZbET6HsxEl/fSihVoHGsXV6VLyDH0lfTQ==} - '@next/swc-darwin-arm64@14.2.13': - resolution: {integrity: sha512-IkAmQEa2Htq+wHACBxOsslt+jMoV3msvxCn0WFSfJSkv/scy+i/EukBKNad36grRxywaXUYJc9mxEGkeIs8Bzg==} + '@next/swc-darwin-arm64@14.2.14': + resolution: {integrity: sha512-bsxbSAUodM1cjYeA4o6y7sp9wslvwjSkWw57t8DtC8Zig8aG8V6r+Yc05/9mDzLKcybb6EN85k1rJDnMKBd9Gw==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@next/swc-darwin-x64@14.2.13': - resolution: {integrity: sha512-Dv1RBGs2TTjkwEnFMVL5XIfJEavnLqqwYSD6LXgTPdEy/u6FlSrLBSSfe1pcfqhFEXRAgVL3Wpjibe5wXJzWog==} + '@next/swc-darwin-x64@14.2.14': + resolution: {integrity: sha512-cC9/I+0+SK5L1k9J8CInahduTVWGMXhQoXFeNvF0uNs3Bt1Ub0Azb8JzTU9vNCr0hnaMqiWu/Z0S1hfKc3+dww==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@next/swc-linux-arm64-gnu@14.2.13': - resolution: {integrity: sha512-yB1tYEFFqo4ZNWkwrJultbsw7NPAAxlPXURXioRl9SdW6aIefOLS+0TEsKrWBtbJ9moTDgU3HRILL6QBQnMevg==} + '@next/swc-linux-arm64-gnu@14.2.14': + resolution: {integrity: sha512-RMLOdA2NU4O7w1PQ3Z9ft3PxD6Htl4uB2TJpocm+4jcllHySPkFaUIFacQ3Jekcg6w+LBaFvjSPthZHiPmiAUg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-arm64-musl@14.2.13': - resolution: {integrity: sha512-v5jZ/FV/eHGoWhMKYrsAweQ7CWb8xsWGM/8m1mwwZQ/sutJjoFaXchwK4pX8NqwImILEvQmZWyb8pPTcP7htWg==} + '@next/swc-linux-arm64-musl@14.2.14': + resolution: {integrity: sha512-WgLOA4hT9EIP7jhlkPnvz49iSOMdZgDJVvbpb8WWzJv5wBD07M2wdJXLkDYIpZmCFfo/wPqFsFR4JS4V9KkQ2A==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-x64-gnu@14.2.13': - resolution: {integrity: sha512-aVc7m4YL7ViiRv7SOXK3RplXzOEe/qQzRA5R2vpXboHABs3w8vtFslGTz+5tKiQzWUmTmBNVW0UQdhkKRORmGA==} + '@next/swc-linux-x64-gnu@14.2.14': + resolution: {integrity: sha512-lbn7svjUps1kmCettV/R9oAvEW+eUI0lo0LJNFOXoQM5NGNxloAyFRNByYeZKL3+1bF5YE0h0irIJfzXBq9Y6w==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-linux-x64-musl@14.2.13': - resolution: {integrity: sha512-4wWY7/OsSaJOOKvMsu1Teylku7vKyTuocvDLTZQq0TYv9OjiYYWt63PiE1nTuZnqQ4RPvME7Xai+9enoiN0Wrg==} + '@next/swc-linux-x64-musl@14.2.14': + resolution: {integrity: sha512-7TcQCvLQ/hKfQRgjxMN4TZ2BRB0P7HwrGAYL+p+m3u3XcKTraUFerVbV3jkNZNwDeQDa8zdxkKkw2els/S5onQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-win32-arm64-msvc@14.2.13': - resolution: {integrity: sha512-uP1XkqCqV2NVH9+g2sC7qIw+w2tRbcMiXFEbMihkQ8B1+V6m28sshBwAB0SDmOe0u44ne1vFU66+gx/28RsBVQ==} + '@next/swc-win32-arm64-msvc@14.2.14': + resolution: {integrity: sha512-8i0Ou5XjTLEje0oj0JiI0Xo9L/93ghFtAUYZ24jARSeTMXLUx8yFIdhS55mTExq5Tj4/dC2fJuaT4e3ySvXU1A==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@next/swc-win32-ia32-msvc@14.2.13': - resolution: {integrity: sha512-V26ezyjPqQpDBV4lcWIh8B/QICQ4v+M5Bo9ykLN+sqeKKBxJVDpEc6biDVyluTXTC40f5IqCU0ttth7Es2ZuMw==} + '@next/swc-win32-ia32-msvc@14.2.14': + resolution: {integrity: sha512-2u2XcSaDEOj+96eXpyjHjtVPLhkAFw2nlaz83EPeuK4obF+HmtDJHqgR1dZB7Gb6V/d55FL26/lYVd0TwMgcOQ==} engines: {node: '>= 10'} cpu: [ia32] os: [win32] - '@next/swc-win32-x64-msvc@14.2.13': - resolution: {integrity: sha512-WwzOEAFBGhlDHE5Z73mNU8CO8mqMNLqaG+AO9ETmzdCQlJhVtWZnOl2+rqgVQS+YHunjOWptdFmNfbpwcUuEsw==} + '@next/swc-win32-x64-msvc@14.2.14': + resolution: {integrity: sha512-MZom+OvZ1NZxuRovKt1ApevjiUJTcU2PmdJKL66xUPaJeRywnbGGRWUlaAOwunD6dX+pm83vj979NTC8QXjGWg==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -2639,8 +2639,8 @@ packages: react: ^16.8 || ^17 || ^18 react-dom: ^16.8 || ^17 || ^18 - next@14.2.13: - resolution: {integrity: sha512-BseY9YNw8QJSwLYD7hlZzl6QVDoSFHL/URN5K64kVEVpCsSOWeyjbIGK+dZUaRViHTaMQX8aqmnn0PHBbGZezg==} + next@14.2.14: + resolution: {integrity: sha512-Q1coZG17MW0Ly5x76shJ4dkC23woLAhhnDnw+DfTc7EpZSGuWrlsZ3bZaO8t6u1Yu8FVfhkqJE+U8GC7E0GLPQ==} engines: {node: '>=18.17.0'} hasBin: true peerDependencies: @@ -3584,37 +3584,37 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 - '@next/env@14.2.13': {} + '@next/env@14.2.14': {} '@next/eslint-plugin-next@14.2.13': dependencies: glob: 10.3.10 - '@next/swc-darwin-arm64@14.2.13': + '@next/swc-darwin-arm64@14.2.14': optional: true - '@next/swc-darwin-x64@14.2.13': + '@next/swc-darwin-x64@14.2.14': optional: true - '@next/swc-linux-arm64-gnu@14.2.13': + '@next/swc-linux-arm64-gnu@14.2.14': optional: true - '@next/swc-linux-arm64-musl@14.2.13': + '@next/swc-linux-arm64-musl@14.2.14': optional: true - '@next/swc-linux-x64-gnu@14.2.13': + '@next/swc-linux-x64-gnu@14.2.14': optional: true - '@next/swc-linux-x64-musl@14.2.13': + '@next/swc-linux-x64-musl@14.2.14': optional: true - '@next/swc-win32-arm64-msvc@14.2.13': + '@next/swc-win32-arm64-msvc@14.2.14': optional: true - '@next/swc-win32-ia32-msvc@14.2.13': + '@next/swc-win32-ia32-msvc@14.2.14': optional: true - '@next/swc-win32-x64-msvc@14.2.13': + '@next/swc-win32-x64-msvc@14.2.14': optional: true '@nextui-org/accordion@2.0.40(@nextui-org/system@2.2.6(@nextui-org/theme@2.2.11(tailwindcss@3.4.13))(framer-motion@11.7.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@nextui-org/theme@2.2.11(tailwindcss@3.4.13))(framer-motion@11.7.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': @@ -5631,11 +5631,11 @@ snapshots: dependencies: '@trpc/server': 11.0.0-rc.532 - '@trpc/next@11.0.0-rc.532(@tanstack/react-query@5.56.2(react@18.3.1))(@trpc/client@11.0.0-rc.532(@trpc/server@11.0.0-rc.532))(@trpc/react-query@11.0.0-rc.532(@tanstack/react-query@5.56.2(react@18.3.1))(@trpc/client@11.0.0-rc.532(@trpc/server@11.0.0-rc.532))(@trpc/server@11.0.0-rc.532)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@trpc/server@11.0.0-rc.532)(next@14.2.13(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@trpc/next@11.0.0-rc.532(@tanstack/react-query@5.56.2(react@18.3.1))(@trpc/client@11.0.0-rc.532(@trpc/server@11.0.0-rc.532))(@trpc/react-query@11.0.0-rc.532(@tanstack/react-query@5.56.2(react@18.3.1))(@trpc/client@11.0.0-rc.532(@trpc/server@11.0.0-rc.532))(@trpc/server@11.0.0-rc.532)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@trpc/server@11.0.0-rc.532)(next@14.2.14(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@trpc/client': 11.0.0-rc.532(@trpc/server@11.0.0-rc.532) '@trpc/server': 11.0.0-rc.532 - next: 14.2.13(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 14.2.14(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: @@ -6211,7 +6211,7 @@ snapshots: '@typescript-eslint/parser': 8.7.0(eslint@8.57.1)(typescript@5.6.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.7.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0)(eslint@8.57.1) + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.7.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(@typescript-eslint/parser@8.7.0(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1))(eslint@8.57.1) eslint-plugin-import: 2.30.0(@typescript-eslint/parser@8.7.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) eslint-plugin-jsx-a11y: 6.10.0(eslint@8.57.1) eslint-plugin-react: 7.36.1(eslint@8.57.1) @@ -6235,13 +6235,13 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.7.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0)(eslint@8.57.1): + eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.7.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(@typescript-eslint/parser@8.7.0(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1))(eslint@8.57.1): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.3.7 enhanced-resolve: 5.17.1 eslint: 8.57.1 - eslint-module-utils: 2.11.1(@typescript-eslint/parser@8.7.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.7.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.11.1(@typescript-eslint/parser@8.7.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.7.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(@typescript-eslint/parser@8.7.0(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) fast-glob: 3.3.2 get-tsconfig: 4.8.1 is-bun-module: 1.2.1 @@ -6254,14 +6254,14 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.11.1(@typescript-eslint/parser@8.7.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.7.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1): + eslint-module-utils@2.11.1(@typescript-eslint/parser@8.7.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.7.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(@typescript-eslint/parser@8.7.0(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.7.0(eslint@8.57.1)(typescript@5.6.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.7.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0)(eslint@8.57.1) + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.7.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(@typescript-eslint/parser@8.7.0(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1))(eslint@8.57.1) transitivePeerDependencies: - supports-color @@ -6289,7 +6289,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.11.1(@typescript-eslint/parser@8.7.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.7.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.11.1(@typescript-eslint/parser@8.7.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.7.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(@typescript-eslint/parser@8.7.0(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -6517,9 +6517,9 @@ snapshots: functions-have-names@1.2.3: {} - geist@1.3.1(next@14.2.13(react-dom@18.3.1(react@18.3.1))(react@18.3.1)): + geist@1.3.1(next@14.2.14(react-dom@18.3.1(react@18.3.1))(react@18.3.1)): dependencies: - next: 14.2.13(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 14.2.14(react-dom@18.3.1(react@18.3.1))(react@18.3.1) get-intrinsic@1.2.4: dependencies: @@ -6909,13 +6909,13 @@ snapshots: natural-compare@1.4.0: {} - next-auth@4.24.8(next@14.2.13(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next-auth@4.24.8(next@14.2.14(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@babel/runtime': 7.25.6 '@panva/hkdf': 1.2.1 cookie: 0.5.0 jose: 4.15.9 - next: 14.2.13(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 14.2.14(react-dom@18.3.1(react@18.3.1))(react@18.3.1) oauth: 0.9.15 openid-client: 5.7.0 preact: 10.24.1 @@ -6929,9 +6929,9 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - next@14.2.13(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next@14.2.14(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@next/env': 14.2.13 + '@next/env': 14.2.14 '@swc/helpers': 0.5.5 busboy: 1.6.0 caniuse-lite: 1.0.30001664 @@ -6941,15 +6941,15 @@ snapshots: react-dom: 18.3.1(react@18.3.1) styled-jsx: 5.1.1(react@18.3.1) optionalDependencies: - '@next/swc-darwin-arm64': 14.2.13 - '@next/swc-darwin-x64': 14.2.13 - '@next/swc-linux-arm64-gnu': 14.2.13 - '@next/swc-linux-arm64-musl': 14.2.13 - '@next/swc-linux-x64-gnu': 14.2.13 - '@next/swc-linux-x64-musl': 14.2.13 - '@next/swc-win32-arm64-msvc': 14.2.13 - '@next/swc-win32-ia32-msvc': 14.2.13 - '@next/swc-win32-x64-msvc': 14.2.13 + '@next/swc-darwin-arm64': 14.2.14 + '@next/swc-darwin-x64': 14.2.14 + '@next/swc-linux-arm64-gnu': 14.2.14 + '@next/swc-linux-arm64-musl': 14.2.14 + '@next/swc-linux-x64-gnu': 14.2.14 + '@next/swc-linux-x64-musl': 14.2.14 + '@next/swc-win32-arm64-msvc': 14.2.14 + '@next/swc-win32-ia32-msvc': 14.2.14 + '@next/swc-win32-x64-msvc': 14.2.14 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros diff --git a/src/actions/auth.action.ts b/src/actions/auth.action.ts new file mode 100644 index 0000000..1eaa9ba --- /dev/null +++ b/src/actions/auth.action.ts @@ -0,0 +1,11 @@ +"use server"; + +import { cookies } from "next/headers"; + +export const createAuthCookie = async () => { + cookies().set("userAuth", "myToken", { secure: true }); +}; + +export const deleteAuthCookie = async () => { + cookies().delete("userAuth"); +}; diff --git a/src/app/(app)/layout.tsx b/src/app/(app)/layout.tsx new file mode 100644 index 0000000..bdbded6 --- /dev/null +++ b/src/app/(app)/layout.tsx @@ -0,0 +1,10 @@ +import { Layout } from "@/components/layout/layout"; +import "@/styles/globals.css"; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return {children}; +} diff --git a/src/app/(app)/page.tsx b/src/app/(app)/page.tsx new file mode 100644 index 0000000..b4323e9 --- /dev/null +++ b/src/app/(app)/page.tsx @@ -0,0 +1,9 @@ +import type { NextPage } from "next"; + +import { Content } from "@/components/home/content"; + +const Home: NextPage = () => { + return ; +}; + +export default Home; diff --git a/src/app/(auth)/layout.tsx b/src/app/(auth)/layout.tsx new file mode 100644 index 0000000..bf0f037 --- /dev/null +++ b/src/app/(auth)/layout.tsx @@ -0,0 +1,10 @@ +import { AuthLayoutWrapper } from "@/components/auth/auth-layout"; +import "@/styles/globals.css"; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return {children}; +} diff --git a/src/app/(auth)/login/page.tsx b/src/app/(auth)/login/page.tsx new file mode 100644 index 0000000..3665a19 --- /dev/null +++ b/src/app/(auth)/login/page.tsx @@ -0,0 +1,7 @@ +import Login from "@/components/auth/login"; + +const login = () => { + return ; +}; + +export default login; diff --git a/src/app/(dashboard)/admin/layout.tsx b/src/app/(dashboard)/admin/layout.tsx new file mode 100644 index 0000000..bdbded6 --- /dev/null +++ b/src/app/(dashboard)/admin/layout.tsx @@ -0,0 +1,10 @@ +import { Layout } from "@/components/layout/layout"; +import "@/styles/globals.css"; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return {children}; +} diff --git a/src/app/(dashboard)/admin/page.tsx b/src/app/(dashboard)/admin/page.tsx index 1c9564b..b4323e9 100644 --- a/src/app/(dashboard)/admin/page.tsx +++ b/src/app/(dashboard)/admin/page.tsx @@ -1,7 +1,9 @@ -export default function AdminPage() { - return ( -
-

Admin Dashboard

-
- ); -} +import type { NextPage } from "next"; + +import { Content } from "@/components/home/content"; + +const Home: NextPage = () => { + return ; +}; + +export default Home; diff --git a/src/app/_components/auth-button.tsx b/src/app/_components/auth-button.tsx deleted file mode 100644 index 5cd74a4..0000000 --- a/src/app/_components/auth-button.tsx +++ /dev/null @@ -1,74 +0,0 @@ -"use client"; - -import { - Avatar, - Button, - CircularProgress, - Dropdown, - DropdownItem, - DropdownMenu, - DropdownTrigger, -} from "@nextui-org/react"; -import { IconBrandGoogle } from "@tabler/icons-react"; -import { signIn, signOut, useSession } from "next-auth/react"; - -export default function AuthButton({ minimal = true }: { minimal?: boolean }) { - const { data, status } = useSession(); - - if (status === "loading") { - return ; - } - - if (status === "authenticated") { - const signOutClick = () => - signOut({ - callbackUrl: "/", - }); - if (minimal) { - return ( - - ); - } - - return ( - - - - - - -

Signed in as

-

{data.user?.email}

-
- - Sign Out - -
-
- ); - } - - return ( - - ); -} diff --git a/src/app/globals.css b/src/app/globals.css deleted file mode 100644 index b5c61c9..0000000 --- a/src/app/globals.css +++ /dev/null @@ -1,3 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 9973bad..c418a04 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -3,10 +3,9 @@ import { Suspense } from "react"; import { GeistSans } from "geist/font/sans"; -import Providers from "@/components/providers"; -import { TRPCReactProvider } from "@/trpc/react"; +import "@/styles/globals.css"; -import "./globals.css"; +import Providers from "./providers"; export const metadata: Metadata = { title: "Next.js Starter App", @@ -15,9 +14,9 @@ export const metadata: Metadata = { export default function RootLayout({ children, -}: Readonly<{ +}: { children: React.ReactNode; -}>) { +}) { return ( - - -
- {children} -
-
-
+ +
+ {children} +
+
); diff --git a/src/app/page.tsx b/src/app/page.tsx deleted file mode 100644 index 3597f0a..0000000 --- a/src/app/page.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import Link from "next/link"; -import { redirect } from "next/navigation"; - -import { Card, CardBody } from "@nextui-org/react"; -import { IconBrandGoogle } from "@tabler/icons-react"; - -import { getServerAuthSession } from "@/server/auth"; - -export default async function Home() { - const session = await getServerAuthSession(); - console.log("session", session); - if (session?.user) { - redirect("/admin"); - } - - return ( - <> - - -

Next.js Starter

-

A simple starter for Next.js

-
-
- - -

- {session && Logged in as {session.user?.name}} -

-
- - - {session ? "Sign out" : "Sign in"} - -
-
-
- - ); -} diff --git a/src/components/providers.tsx b/src/app/providers.tsx similarity index 50% rename from src/components/providers.tsx rename to src/app/providers.tsx index 1b76820..0e3ffd5 100644 --- a/src/components/providers.tsx +++ b/src/app/providers.tsx @@ -5,6 +5,8 @@ import { SessionProvider } from "next-auth/react"; import { ThemeProvider as NextThemesProvider } from "next-themes"; import { ThemeProviderProps } from "next-themes/dist/types"; +import { TRPCReactProvider } from "@/trpc/react"; + export interface ProvidersProps { children: React.ReactNode; themeProps?: ThemeProviderProps; @@ -12,16 +14,18 @@ export interface ProvidersProps { export default function Providers({ children, themeProps }: ProvidersProps) { return ( - - - - {children} - - - + + + + + {children} + + + + ); } diff --git a/src/components/app-navbar/index.tsx b/src/components/app-navbar/index.tsx index 6d8e085..7b47667 100644 --- a/src/components/app-navbar/index.tsx +++ b/src/components/app-navbar/index.tsx @@ -15,7 +15,7 @@ import { import { IconPackage } from "@tabler/icons-react"; import { useSession } from "next-auth/react"; -import AuthButton from "../../app/_components/auth-button"; +import AuthButton from "../auth/auth-button"; import SearchBox from "./search-box"; import { ThemeSwitcher } from "./theme-switcher"; @@ -78,7 +78,7 @@ export default function AppNavbar() { - + diff --git a/src/components/auth/auth-button.tsx b/src/components/auth/auth-button.tsx new file mode 100644 index 0000000..bbd31a5 --- /dev/null +++ b/src/components/auth/auth-button.tsx @@ -0,0 +1,60 @@ +"use client"; + +import { + Button, + Card, + CardBody, + CircularProgress, + User, +} from "@nextui-org/react"; +import { IconBrandGoogle } from "@tabler/icons-react"; +import { signIn, signOut, useSession } from "next-auth/react"; + +export default function AuthButton() { + const { data, status } = useSession(); + + if (status === "loading") { + return ; + } + + if (status === "authenticated") { + const signOutClick = () => + signOut({ + callbackUrl: "/", + }); + return ( + <> + + + + + + + + ); + } + + return ( + + ); +} diff --git a/src/components/auth/auth-layout.tsx b/src/components/auth/auth-layout.tsx new file mode 100644 index 0000000..b790797 --- /dev/null +++ b/src/components/auth/auth-layout.tsx @@ -0,0 +1,47 @@ +import { Divider } from "@nextui-org/divider"; +import { Image } from "@nextui-org/react"; + +interface Props { + children: React.ReactNode; +} + +export const AuthLayoutWrapper = ({ children }: Props) => { + return ( +
+
+
+ gradient +
+ {children} +
+ +
+ +
+ +
+
+ gradient +
+ +
+

NextUI Dashboard Template

+
+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Quasi + possimus voluptate, sapiente assumenda deserunt repellendus, + perferendis odit voluptas hic dolores laborum fugit ut? Architecto + quo ex quidem vitae quae rem. +
+
+
+
+ ); +}; diff --git a/src/components/auth/login.tsx b/src/components/auth/login.tsx new file mode 100644 index 0000000..a5cdecb --- /dev/null +++ b/src/components/auth/login.tsx @@ -0,0 +1,19 @@ +import { Card, CardBody } from "@nextui-org/react"; + +import AuthButton from "./auth-button"; + +export default async function Login() { + return ( +
+ + +
+
+ +
+
+
+
+
+ ); +} diff --git a/src/components/home/content.tsx b/src/components/home/content.tsx new file mode 100644 index 0000000..44d84e9 --- /dev/null +++ b/src/components/home/content.tsx @@ -0,0 +1,46 @@ +"use client"; + +import NextLink from "next/link"; + +import { Link } from "@nextui-org/react"; + +export const Content = () => ( +
+
+
+ {/* Card Section Top */} +
+

Available Balance

+
+
+ + {/* Chart */} +
+

Statistics

+
+
+
+ + {/* Left Section */} +
+

Section

+
+
+
+ + {/* Table Latest Users */} +
+
+

Latest Users

+ + View All + +
+
+
+); diff --git a/src/components/hooks/use-body-lock.ts b/src/components/hooks/use-body-lock.ts new file mode 100644 index 0000000..b3954a0 --- /dev/null +++ b/src/components/hooks/use-body-lock.ts @@ -0,0 +1,52 @@ +"use client"; + +import { useEffect, useState } from "react"; + +import { useIsomorphicLayoutEffect } from "./use-isomorphic-layout-effect"; + +type ReturnType = [boolean, (locked: boolean) => void]; + +export const useLockedBody = (initialLocked = false): ReturnType => { + const [locked, setLocked] = useState(initialLocked); + + // Do the side effect before render + useIsomorphicLayoutEffect(() => { + if (!locked) { + return; + } + + // Save initial body style + const originalOverflow = document.body.style.overflow; + const originalPaddingRight = document.body.style.paddingRight; + + // Lock body scroll + document.body.style.overflow = "hidden"; + + // Get the scrollBar width + const root = document.getElementById("___gatsby"); // or root + const scrollBarWidth = root ? root.offsetWidth - root.scrollWidth : 0; + + // Avoid width reflow + if (scrollBarWidth) { + document.body.style.paddingRight = `${scrollBarWidth}px`; + } + + return () => { + document.body.style.overflow = originalOverflow; + + if (scrollBarWidth) { + document.body.style.paddingRight = originalPaddingRight; + } + }; + }, [locked]); + + // Update state if initialValue changes + useEffect(() => { + if (locked !== initialLocked) { + setLocked(initialLocked); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [initialLocked]); + + return [locked, setLocked]; +}; diff --git a/src/components/hooks/use-isomorphic-layout-effect.ts b/src/components/hooks/use-isomorphic-layout-effect.ts new file mode 100644 index 0000000..cc909dd --- /dev/null +++ b/src/components/hooks/use-isomorphic-layout-effect.ts @@ -0,0 +1,4 @@ +import { useEffect, useLayoutEffect } from "react"; + +export const useIsomorphicLayoutEffect = + typeof window !== "undefined" ? useLayoutEffect : useEffect; diff --git a/src/components/icons/accounts/dots-icon.tsx b/src/components/icons/accounts/dots-icon.tsx new file mode 100644 index 0000000..0c0aaa2 --- /dev/null +++ b/src/components/icons/accounts/dots-icon.tsx @@ -0,0 +1,21 @@ +import React from "react"; + +export const DotsIcon = () => { + return ( + + + + ); +}; diff --git a/src/components/icons/accounts/export-icon.tsx b/src/components/icons/accounts/export-icon.tsx new file mode 100644 index 0000000..2c32bf7 --- /dev/null +++ b/src/components/icons/accounts/export-icon.tsx @@ -0,0 +1,21 @@ +import React from "react"; + +export const ExportIcon = () => { + return ( + + + + ); +}; diff --git a/src/components/icons/accounts/info-icon.tsx b/src/components/icons/accounts/info-icon.tsx new file mode 100644 index 0000000..64c550a --- /dev/null +++ b/src/components/icons/accounts/info-icon.tsx @@ -0,0 +1,19 @@ +import React from "react"; + +export const InfoIcon = () => { + return ( + + + + ); +}; diff --git a/src/components/icons/accounts/trash-icon.tsx b/src/components/icons/accounts/trash-icon.tsx new file mode 100644 index 0000000..d66d482 --- /dev/null +++ b/src/components/icons/accounts/trash-icon.tsx @@ -0,0 +1,21 @@ +import React from "react"; + +export const TrashIcon = () => { + return ( + + + + ); +}; diff --git a/src/components/icons/acme-icon.tsx b/src/components/icons/acme-icon.tsx new file mode 100644 index 0000000..ed160c6 --- /dev/null +++ b/src/components/icons/acme-icon.tsx @@ -0,0 +1,30 @@ +import React from "react"; + +export const AcmeIcon = () => { + return ( + + + + + ); +}; diff --git a/src/components/icons/acmelogo.tsx b/src/components/icons/acmelogo.tsx new file mode 100644 index 0000000..d0bc953 --- /dev/null +++ b/src/components/icons/acmelogo.tsx @@ -0,0 +1,21 @@ +import React from "react"; + +export const AcmeLogo = () => ( + + + + +); diff --git a/src/components/icons/breadcrumb/house-icon.tsx b/src/components/icons/breadcrumb/house-icon.tsx new file mode 100644 index 0000000..4cd9006 --- /dev/null +++ b/src/components/icons/breadcrumb/house-icon.tsx @@ -0,0 +1,21 @@ +import React from "react"; + +export const HouseIcon = () => { + return ( + + + + ); +}; diff --git a/src/components/icons/breadcrumb/users-icon.tsx b/src/components/icons/breadcrumb/users-icon.tsx new file mode 100644 index 0000000..9df571e --- /dev/null +++ b/src/components/icons/breadcrumb/users-icon.tsx @@ -0,0 +1,21 @@ +import React from "react"; + +export const UsersIcon = () => { + return ( + + + + ); +}; diff --git a/src/components/icons/community.tsx b/src/components/icons/community.tsx new file mode 100644 index 0000000..1296719 --- /dev/null +++ b/src/components/icons/community.tsx @@ -0,0 +1,25 @@ +import React from "react"; + +interface Props { + color?: string; +} + +export const Community = ({ color = "white" }: Props) => { + return ( + + + + ); +}; diff --git a/src/components/icons/navbar/feedback-icon.tsx b/src/components/icons/navbar/feedback-icon.tsx new file mode 100644 index 0000000..e2a757a --- /dev/null +++ b/src/components/icons/navbar/feedback-icon.tsx @@ -0,0 +1,39 @@ +import React from "react"; + +export const FeedbackIcon = () => { + return ( + + + + + + + + ); +}; diff --git a/src/components/icons/navbar/github-icon.tsx b/src/components/icons/navbar/github-icon.tsx new file mode 100644 index 0000000..ac9c0c0 --- /dev/null +++ b/src/components/icons/navbar/github-icon.tsx @@ -0,0 +1,14 @@ +import React from "react"; + +export const GithubIcon = () => { + return ( + + + + ); +}; diff --git a/src/components/icons/navbar/notificationicon.tsx b/src/components/icons/navbar/notificationicon.tsx new file mode 100644 index 0000000..cc3de08 --- /dev/null +++ b/src/components/icons/navbar/notificationicon.tsx @@ -0,0 +1,26 @@ +import React from "react"; + +export const NotificationIcon = () => { + return ( + + + + + + ); +}; diff --git a/src/components/icons/navbar/support-icon.tsx b/src/components/icons/navbar/support-icon.tsx new file mode 100644 index 0000000..8a6d9fd --- /dev/null +++ b/src/components/icons/navbar/support-icon.tsx @@ -0,0 +1,21 @@ +import React from "react"; + +export const SupportIcon = () => { + return ( + + + + ); +}; diff --git a/src/components/icons/searchicon.tsx b/src/components/icons/searchicon.tsx new file mode 100644 index 0000000..2363759 --- /dev/null +++ b/src/components/icons/searchicon.tsx @@ -0,0 +1,30 @@ +import React from "react"; + +export const SearchIcon = () => { + return ( + + ); +}; diff --git a/src/components/icons/sidebar/accounts-icon.tsx b/src/components/icons/sidebar/accounts-icon.tsx new file mode 100644 index 0000000..54aa13b --- /dev/null +++ b/src/components/icons/sidebar/accounts-icon.tsx @@ -0,0 +1,21 @@ +import React from "react"; + +export const AccountsIcon = () => { + return ( + + + + ); +}; diff --git a/src/components/icons/sidebar/balance-icon.tsx b/src/components/icons/sidebar/balance-icon.tsx new file mode 100644 index 0000000..c2a35ef --- /dev/null +++ b/src/components/icons/sidebar/balance-icon.tsx @@ -0,0 +1,21 @@ +import React from "react"; + +export const BalanceIcon = () => { + return ( + + + + ); +}; diff --git a/src/components/icons/sidebar/bottom-icon.tsx b/src/components/icons/sidebar/bottom-icon.tsx new file mode 100644 index 0000000..578d8cb --- /dev/null +++ b/src/components/icons/sidebar/bottom-icon.tsx @@ -0,0 +1,21 @@ +import React from "react"; + +export const BottomIcon = () => { + return ( + + + + ); +}; diff --git a/src/components/icons/sidebar/changelog-icon.tsx b/src/components/icons/sidebar/changelog-icon.tsx new file mode 100644 index 0000000..de3d1a8 --- /dev/null +++ b/src/components/icons/sidebar/changelog-icon.tsx @@ -0,0 +1,21 @@ +import React from "react"; + +export const ChangeLogIcon = () => { + return ( + + + + ); +}; diff --git a/src/components/icons/sidebar/chevron-down-icon.tsx b/src/components/icons/sidebar/chevron-down-icon.tsx new file mode 100644 index 0000000..ef17b44 --- /dev/null +++ b/src/components/icons/sidebar/chevron-down-icon.tsx @@ -0,0 +1,17 @@ +import React from 'react'; + +interface Props extends React.SVGAttributes {} +export const ChevronDownIcon = ({ ...props }: Props) => { + return ( + + + + ); +}; diff --git a/src/components/icons/sidebar/chevron-up-icon.tsx b/src/components/icons/sidebar/chevron-up-icon.tsx new file mode 100644 index 0000000..cb5cc11 --- /dev/null +++ b/src/components/icons/sidebar/chevron-up-icon.tsx @@ -0,0 +1,20 @@ +import React from "react"; + +interface Props extends React.SVGAttributes {} + +export const ChevronUpIcon = ({ ...props }: Props) => { + return ( + + + + ); +}; diff --git a/src/components/icons/sidebar/customers-icon.tsx b/src/components/icons/sidebar/customers-icon.tsx new file mode 100644 index 0000000..5349c17 --- /dev/null +++ b/src/components/icons/sidebar/customers-icon.tsx @@ -0,0 +1,21 @@ +import React from "react"; + +export const CustomersIcon = () => { + return ( + + + + ); +}; diff --git a/src/components/icons/sidebar/dev-icon.tsx b/src/components/icons/sidebar/dev-icon.tsx new file mode 100644 index 0000000..a9d7a1e --- /dev/null +++ b/src/components/icons/sidebar/dev-icon.tsx @@ -0,0 +1,21 @@ +import React from "react"; + +export const DevIcon = () => { + return ( + + + + ); +}; diff --git a/src/components/icons/sidebar/filter-icon.tsx b/src/components/icons/sidebar/filter-icon.tsx new file mode 100644 index 0000000..aca9312 --- /dev/null +++ b/src/components/icons/sidebar/filter-icon.tsx @@ -0,0 +1,19 @@ +import React from "react"; + +export const FilterIcon = () => { + return ( + + + + ); +}; diff --git a/src/components/icons/sidebar/home-icon.tsx b/src/components/icons/sidebar/home-icon.tsx new file mode 100644 index 0000000..bd1db79 --- /dev/null +++ b/src/components/icons/sidebar/home-icon.tsx @@ -0,0 +1,21 @@ +import React from "react"; + +export const HomeIcon = () => { + return ( + + + + ); +}; diff --git a/src/components/icons/sidebar/payments-icon.tsx b/src/components/icons/sidebar/payments-icon.tsx new file mode 100644 index 0000000..a17a7a5 --- /dev/null +++ b/src/components/icons/sidebar/payments-icon.tsx @@ -0,0 +1,21 @@ +import React from "react"; + +export const PaymentsIcon = () => { + return ( + + + + ); +}; diff --git a/src/components/icons/sidebar/products-icon.tsx b/src/components/icons/sidebar/products-icon.tsx new file mode 100644 index 0000000..d546e24 --- /dev/null +++ b/src/components/icons/sidebar/products-icon.tsx @@ -0,0 +1,21 @@ +import React from "react"; + +export const ProductsIcon = () => { + return ( + + + + ); +}; diff --git a/src/components/icons/sidebar/reports-icon.tsx b/src/components/icons/sidebar/reports-icon.tsx new file mode 100644 index 0000000..ada3f65 --- /dev/null +++ b/src/components/icons/sidebar/reports-icon.tsx @@ -0,0 +1,21 @@ +import React from "react"; + +export const ReportsIcon = () => { + return ( + + + + ); +}; diff --git a/src/components/icons/sidebar/settings-icon.tsx b/src/components/icons/sidebar/settings-icon.tsx new file mode 100644 index 0000000..0690676 --- /dev/null +++ b/src/components/icons/sidebar/settings-icon.tsx @@ -0,0 +1,21 @@ +import React from "react"; + +export const SettingsIcon = () => { + return ( + + + + ); +}; diff --git a/src/components/icons/sidebar/view-icon.tsx b/src/components/icons/sidebar/view-icon.tsx new file mode 100644 index 0000000..c8710df --- /dev/null +++ b/src/components/icons/sidebar/view-icon.tsx @@ -0,0 +1,21 @@ +import React from "react"; + +export const ViewIcon = () => { + return ( + + + + ); +}; diff --git a/src/components/icons/table/delete-icon.tsx b/src/components/icons/table/delete-icon.tsx new file mode 100644 index 0000000..8ef36ce --- /dev/null +++ b/src/components/icons/table/delete-icon.tsx @@ -0,0 +1,54 @@ +interface Props { + size?: number; + fill?: string; + width?: number; + height?: number; +} +export const DeleteIcon = ({fill, size, height, width, ...props}: Props) => { + return ( + + + + + + + + ); +}; diff --git a/src/components/icons/table/edit-icon.tsx b/src/components/icons/table/edit-icon.tsx new file mode 100644 index 0000000..105000a --- /dev/null +++ b/src/components/icons/table/edit-icon.tsx @@ -0,0 +1,44 @@ +interface Props { + size?: number; + fill?: string; + width?: number; + height?: number; +} + +export const EditIcon = ({fill, size, height, width, ...props}: Props) => { + return ( + + + + + + ); +}; diff --git a/src/components/icons/table/eye-icon.tsx b/src/components/icons/table/eye-icon.tsx new file mode 100644 index 0000000..e54308d --- /dev/null +++ b/src/components/icons/table/eye-icon.tsx @@ -0,0 +1,34 @@ +interface Props { + size?: number; + fill?: string; + width?: number; + height?: number; +} + +export const EyeIcon = ({fill, size, height, width, ...props}: Props) => { + return ( + + + + + ); +}; diff --git a/src/components/layout/layout-context.ts b/src/components/layout/layout-context.ts new file mode 100644 index 0000000..0ae902d --- /dev/null +++ b/src/components/layout/layout-context.ts @@ -0,0 +1,17 @@ +"use client"; + +import { createContext, useContext } from "react"; + +interface SidebarContext { + collapsed: boolean; + setCollapsed: () => void; +} + +export const SidebarContext = createContext({ + collapsed: false, + setCollapsed: () => {}, +}); + +export const useSidebarContext = () => { + return useContext(SidebarContext); +}; diff --git a/src/components/layout/layout.tsx b/src/components/layout/layout.tsx new file mode 100644 index 0000000..a5f2131 --- /dev/null +++ b/src/components/layout/layout.tsx @@ -0,0 +1,35 @@ +"use client"; + +import React from "react"; + +import { useLockedBody } from "../hooks/use-body-lock"; +import { NavbarWrapper } from "../navbar/navbar"; +import { SidebarWrapper } from "../sidebar/sidebar"; +import { SidebarContext } from "./layout-context"; + +interface Props { + children: React.ReactNode; +} + +export const Layout = ({ children }: Props) => { + const [sidebarOpen, setSidebarOpen] = React.useState(false); + const [_, setLocked] = useLockedBody(false); + const handleToggleSidebar = () => { + setSidebarOpen(!sidebarOpen); + setLocked(!sidebarOpen); + }; + + return ( + +
+ + {children} +
+
+ ); +}; diff --git a/src/components/navbar/burguer-button.tsx b/src/components/navbar/burguer-button.tsx new file mode 100644 index 0000000..4e359c1 --- /dev/null +++ b/src/components/navbar/burguer-button.tsx @@ -0,0 +1,18 @@ +import React from "react"; +import { useSidebarContext } from "../layout/layout-context"; +import { StyledBurgerButton } from "./navbar.styles"; + +export const BurguerButton = () => { + const { collapsed, setCollapsed } = useSidebarContext(); + + return ( +
+
+
+
+ ); +}; diff --git a/src/components/navbar/darkmodeswitch.tsx b/src/components/navbar/darkmodeswitch.tsx new file mode 100644 index 0000000..0c78c5a --- /dev/null +++ b/src/components/navbar/darkmodeswitch.tsx @@ -0,0 +1,13 @@ +import React from "react"; +import { useTheme as useNextTheme } from "next-themes"; +import { Switch } from "@nextui-org/react"; + +export const DarkModeSwitch = () => { + const { setTheme, resolvedTheme } = useNextTheme(); + return ( + setTheme(e ? "dark" : "light")} + /> + ); +}; diff --git a/src/components/navbar/navbar.styles.ts b/src/components/navbar/navbar.styles.ts new file mode 100644 index 0000000..9e36662 --- /dev/null +++ b/src/components/navbar/navbar.styles.ts @@ -0,0 +1,43 @@ +import { tv } from "@nextui-org/react"; + +// NEEDS TO BE REFACTORED + +export const StyledBurgerButton = tv({ + 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] ", + + variants: { + open: { + true: "[&", + }, + }, + // "", + // "& div": { + + // "&:first-child": { + // transform: "translateY(-4px) rotate(0deg)", + // height: "1px", + // marginTop: "10px", + // }, + // "&:nth-child(2)": { + // transform: "translateY(4px) rotate(0deg)", + // height: "1px", + // marginBottom: "10px", + // }, + // }, + // variants: { + // open: { + // true: { + // "& div": { + // "&:first-child": { + // marginTop: "0px", + // transform: "translateY(1px) rotate(45deg)", + // }, + // "&:nth-child(2)": { + // marginBottom: "0px", + // transform: "translateY(4px) rotate(-45deg)", + // }, + // }, + // }, + // }, + // }, +}); diff --git a/src/components/navbar/navbar.tsx b/src/components/navbar/navbar.tsx new file mode 100644 index 0000000..0fc1dea --- /dev/null +++ b/src/components/navbar/navbar.tsx @@ -0,0 +1,71 @@ +import React from "react"; + +import { Input, Link, Navbar, NavbarContent } from "@nextui-org/react"; + +import { FeedbackIcon } from "../icons/navbar/feedback-icon"; +import { GithubIcon } from "../icons/navbar/github-icon"; +import { SupportIcon } from "../icons/navbar/support-icon"; +import { SearchIcon } from "../icons/searchicon"; +import { BurguerButton } from "./burguer-button"; +import { NotificationsDropdown } from "./notifications-dropdown"; +import { UserDropdown } from "./user-dropdown"; + +interface Props { + children: React.ReactNode; +} + +export const NavbarWrapper = ({ children }: Props) => { + return ( +
+ + + + + + } + isClearable + className="w-full" + classNames={{ + input: "w-full", + mainWrapper: "w-full", + }} + placeholder="Search..." + /> + + +
+ + Feedback? +
+ + + +
+ +
+ + + + + + + +
+
+ {children} +
+ ); +}; diff --git a/src/components/navbar/notifications-dropdown.tsx b/src/components/navbar/notifications-dropdown.tsx new file mode 100644 index 0000000..7f6f635 --- /dev/null +++ b/src/components/navbar/notifications-dropdown.tsx @@ -0,0 +1,56 @@ +import { + Dropdown, + DropdownItem, + DropdownMenu, + DropdownSection, + DropdownTrigger, + NavbarItem, +} from "@nextui-org/react"; +import React from "react"; +import { NotificationIcon } from "../icons/navbar/notificationicon"; + +export const NotificationsDropdown = () => { + return ( + + + + + + + + + + 📣 Edit your information + + + 🚀 Say goodbye to paper receipts! + + + 📣 Edit your information + + + + + ); +}; diff --git a/src/components/navbar/user-dropdown.tsx b/src/components/navbar/user-dropdown.tsx new file mode 100644 index 0000000..d7d022c --- /dev/null +++ b/src/components/navbar/user-dropdown.tsx @@ -0,0 +1,63 @@ +import { + Avatar, + Dropdown, + DropdownItem, + DropdownMenu, + DropdownTrigger, + Navbar, + NavbarItem, +} from "@nextui-org/react"; +import React, { useCallback } from "react"; +import { DarkModeSwitch } from "./darkmodeswitch"; +import { useRouter } from "next/navigation"; +import { deleteAuthCookie } from "@/actions/auth.action"; + +export const UserDropdown = () => { + const router = useRouter(); + + const handleLogout = useCallback(async () => { + await deleteAuthCookie(); + router.replace("/login"); + }, [router]); + + return ( + + + + + + + console.log({ actionKey })}> + +

Signed in as

+

zoey@example.com

+
+ My Settings + Team Settings + Analytics + System + Configurations + Help & Feedback + + Log Out + + + + +
+
+ ); +}; diff --git a/src/components/sidebar/collapse-items.tsx b/src/components/sidebar/collapse-items.tsx new file mode 100644 index 0000000..c14630b --- /dev/null +++ b/src/components/sidebar/collapse-items.tsx @@ -0,0 +1,139 @@ +"use client"; +import React, { useState } from "react"; +import { ChevronDownIcon } from "../icons/sidebar/chevron-down-icon"; +import { Accordion, AccordionItem } from "@nextui-org/react"; +import clsx from "clsx"; + +interface Props { + icon: React.ReactNode; + title: string; + items: string[]; +} + +export const CollapseItems = ({ icon, items, title }: Props) => { + const [open, setOpen] = useState(false); + + return ( +
+ + } + classNames={{ + indicator: "data-[open=true]:-rotate-180", + trigger: + "py-0 min-h-[44px] hover:bg-default-100 rounded-xl active:scale-[0.98] transition-transform px-3.5", + + title: + "px-0 flex text-base gap-2 h-full items-center cursor-pointer", + }} + aria-label="Accordion 1" + title={ +
+ {icon} + {title} +
+ } + > +
+ {items.map((item, index) => ( + + {item} + + ))} +
+
+
+ {/* +
+ {icon} + + {title} + +
+ + +
+ } + // css={{ + // width: "100%", + // "& .nextui-collapse-view": { + // p: "0", + // }, + // "& .nextui-collapse-content": { + // marginTop: "$1", + // padding: "0px", + // }, + // }} + divider={false} + showArrow={false} + > + {items.map((item, index) => ( +
+ + {item} + +
+ ))} + */} +
+ ); +}; diff --git a/src/components/sidebar/companies-dropdown.tsx b/src/components/sidebar/companies-dropdown.tsx new file mode 100644 index 0000000..e71fbd0 --- /dev/null +++ b/src/components/sidebar/companies-dropdown.tsx @@ -0,0 +1,128 @@ +"use client"; +import { + Dropdown, + DropdownItem, + DropdownMenu, + DropdownSection, + DropdownTrigger, +} from "@nextui-org/react"; +import React, { useState } from "react"; +import { AcmeIcon } from "../icons/acme-icon"; +import { AcmeLogo } from "../icons/acmelogo"; +import { BottomIcon } from "../icons/sidebar/bottom-icon"; + +interface Company { + name: string; + location: string; + logo: React.ReactNode; +} + +export const CompaniesDropdown = () => { + const [company, setCompany] = useState({ + name: "Acme Co.", + location: "Palo Alto, CA", + logo: , + }); + return ( + + +
+ {company.logo} +
+

+ {company.name} +

+ + {company.location} + +
+ +
+
+ { + if (e === "1") { + setCompany({ + name: "Facebook", + location: "San Fransico, CA", + logo: , + }); + } + if (e === "2") { + setCompany({ + name: "Instagram", + location: "Austin, Tx", + logo: , + }); + } + if (e === "3") { + setCompany({ + name: "Twitter", + location: "Brooklyn, NY", + logo: , + }); + } + if (e === "4") { + setCompany({ + name: "Acme Co.", + location: "Palo Alto, CA", + logo: , + }); + } + }} + aria-label="Avatar Actions" + > + + } + description="San Fransico, CA" + classNames={{ + base: "py-4", + title: "text-base font-semibold", + }} + > + Facebook + + } + description="Austin, Tx" + classNames={{ + base: "py-4", + title: "text-base font-semibold", + }} + > + Instagram + + } + description="Brooklyn, NY" + classNames={{ + base: "py-4", + title: "text-base font-semibold", + }} + > + Twitter + + } + description="Palo Alto, CA" + classNames={{ + base: "py-4", + title: "text-base font-semibold", + }} + > + Acme Co. + + + +
+ ); +}; diff --git a/src/components/sidebar/sidebar-item.tsx b/src/components/sidebar/sidebar-item.tsx new file mode 100644 index 0000000..09e9fe5 --- /dev/null +++ b/src/components/sidebar/sidebar-item.tsx @@ -0,0 +1,40 @@ +import NextLink from "next/link"; +import React from "react"; +import { useSidebarContext } from "../layout/layout-context"; +import clsx from "clsx"; + +interface Props { + title: string; + icon: React.ReactNode; + isActive?: boolean; + href?: string; +} + +export const SidebarItem = ({ icon, title, isActive, href = "" }: Props) => { + const { collapsed, setCollapsed } = useSidebarContext(); + + const handleClick = () => { + if (window.innerWidth < 768) { + setCollapsed(); + } + }; + return ( + +
+ {icon} + {title} +
+
+ ); +}; diff --git a/src/components/sidebar/sidebar-menu.tsx b/src/components/sidebar/sidebar-menu.tsx new file mode 100644 index 0000000..d2f8364 --- /dev/null +++ b/src/components/sidebar/sidebar-menu.tsx @@ -0,0 +1,15 @@ +import React from "react"; + +interface Props { + title: string; + children?: React.ReactNode; +} + +export const SidebarMenu = ({ title, children }: Props) => { + return ( +
+ {title} + {children} +
+ ); +}; diff --git a/src/components/sidebar/sidebar.styles.ts b/src/components/sidebar/sidebar.styles.ts new file mode 100644 index 0000000..716c699 --- /dev/null +++ b/src/components/sidebar/sidebar.styles.ts @@ -0,0 +1,50 @@ +import { tv } from "@nextui-org/react"; + +export const SidebarWrapper = tv({ + 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 ", + + variants: { + collapsed: { + true: "translate-x-0 ml-0 pt-20 [display:inherit]", + }, + }, + // "" + // "@md": { + // marginLeft: "0", + // display: "flex", + // position: "static", + // height: "100vh", + // transform: "translateX(0)", + // }, + // variants: { + // collapsed: { + // true: { + // display: "inherit", + // marginLeft: "0 ", + // transform: "translateX(0)", + // }, + // }, + // }, +}); +export const Overlay = tv({ + 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", +}); + +export const Header = tv({ + base: "flex gap-8 items-center px-6", +}); + +export const Body = tv({ + base: "flex flex-col gap-6 mt-9 px-2", +}); + +export const Footer = tv({ + base: "flex items-center justify-center gap-6 pt-16 pb-8 px-8 md:pt-10 md:pb-0", +}); + +export const Sidebar = Object.assign(SidebarWrapper, { + Header, + Body, + Overlay, + Footer, +}); diff --git a/src/components/sidebar/sidebar.tsx b/src/components/sidebar/sidebar.tsx new file mode 100644 index 0000000..c3e3b5e --- /dev/null +++ b/src/components/sidebar/sidebar.tsx @@ -0,0 +1,130 @@ +import React from "react"; +import { Sidebar } from "./sidebar.styles"; +import { Avatar, Tooltip } from "@nextui-org/react"; +import { CompaniesDropdown } from "./companies-dropdown"; +import { HomeIcon } from "../icons/sidebar/home-icon"; +import { PaymentsIcon } from "../icons/sidebar/payments-icon"; +import { BalanceIcon } from "../icons/sidebar/balance-icon"; +import { AccountsIcon } from "../icons/sidebar/accounts-icon"; +import { CustomersIcon } from "../icons/sidebar/customers-icon"; +import { ProductsIcon } from "../icons/sidebar/products-icon"; +import { ReportsIcon } from "../icons/sidebar/reports-icon"; +import { DevIcon } from "../icons/sidebar/dev-icon"; +import { ViewIcon } from "../icons/sidebar/view-icon"; +import { SettingsIcon } from "../icons/sidebar/settings-icon"; +import { CollapseItems } from "./collapse-items"; +import { SidebarItem } from "./sidebar-item"; +import { SidebarMenu } from "./sidebar-menu"; +import { FilterIcon } from "../icons/sidebar/filter-icon"; +import { useSidebarContext } from "../layout/layout-context"; +import { ChangeLogIcon } from "../icons/sidebar/changelog-icon"; +import { usePathname } from "next/navigation"; + +export const SidebarWrapper = () => { + const pathname = usePathname(); + const { collapsed, setCollapsed } = useSidebarContext(); + + return ( + + ); +}; diff --git a/src/helpers/schemas.ts b/src/helpers/schemas.ts new file mode 100644 index 0000000..2a0df35 --- /dev/null +++ b/src/helpers/schemas.ts @@ -0,0 +1,19 @@ +import { object, ref, string } from "yup"; + +export const LoginSchema = object().shape({ + email: string() + .email("This field must be an email") + .required("Email is required"), + password: string().required("Password is required"), +}); + +export const RegisterSchema = object().shape({ + name: string().required("Name is required"), + email: string() + .email("This field must be an email") + .required("Email is required"), + password: string().required("Password is required"), + confirmPassword: string() + .required("Confirm password is required") + .oneOf([ref("password")], "Passwords must match"), +}); diff --git a/src/helpers/types.ts b/src/helpers/types.ts new file mode 100644 index 0000000..04c81c7 --- /dev/null +++ b/src/helpers/types.ts @@ -0,0 +1,13 @@ +// FORMS + +export type LoginFormType = { + email: string; + password: string; +}; + +export type RegisterFormType = { + name: string; + email: string; + password: string; + confirmPassword: string; +}; diff --git a/src/middleware.ts b/src/middleware.ts new file mode 100644 index 0000000..0706178 --- /dev/null +++ b/src/middleware.ts @@ -0,0 +1,7 @@ +import { withAuth } from "next-auth/middleware"; + +export default withAuth({ + pages: { + signIn: "/login", + }, +}); diff --git a/src/styles/globals.css b/src/styles/globals.css new file mode 100644 index 0000000..5443f26 --- /dev/null +++ b/src/styles/globals.css @@ -0,0 +1,13 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +html, +body { + padding: 0; + margin: 0; +} + +* { + box-sizing: border-box; +}