diff --git a/.changeset/big-lamps-attack.md b/.changeset/big-lamps-attack.md
new file mode 100644
index 0000000..55b4367
--- /dev/null
+++ b/.changeset/big-lamps-attack.md
@@ -0,0 +1,5 @@
+---
+'analytics-dashboard': patch
+---
+
+added logic for active link styles
diff --git a/.changeset/curvy-walls-unite.md b/.changeset/curvy-walls-unite.md
new file mode 100644
index 0000000..bb6f932
--- /dev/null
+++ b/.changeset/curvy-walls-unite.md
@@ -0,0 +1,5 @@
+---
+'analytics-dashboard': patch
+---
+
+added mantine sliders, dates, buttons stories
diff --git a/.changeset/cyan-parents-cough.md b/.changeset/cyan-parents-cough.md
new file mode 100644
index 0000000..9eff06c
--- /dev/null
+++ b/.changeset/cyan-parents-cough.md
@@ -0,0 +1,5 @@
+---
+'analytics-dashboard': minor
+---
+
+added and setup prettier, husky and lint-staged
diff --git a/.changeset/dull-glasses-fold.md b/.changeset/dull-glasses-fold.md
new file mode 100644
index 0000000..0a55540
--- /dev/null
+++ b/.changeset/dull-glasses-fold.md
@@ -0,0 +1,5 @@
+---
+'analytics-dashboard': patch
+---
+
+added usefetchdata hook for all mock data replacing the previous data imports
diff --git a/.changeset/four-cougars-battle.md b/.changeset/four-cougars-battle.md
new file mode 100644
index 0000000..7aa6102
--- /dev/null
+++ b/.changeset/four-cougars-battle.md
@@ -0,0 +1,5 @@
+---
+'analytics-dashboard': minor
+---
+
+updated side nav background color
diff --git a/.changeset/large-deers-remember.md b/.changeset/large-deers-remember.md
new file mode 100644
index 0000000..e9433cf
--- /dev/null
+++ b/.changeset/large-deers-remember.md
@@ -0,0 +1,40 @@
+---
+"analytics-dashboard": major
+---
+
+Upgrade to Next.js 14 with App Router and Mantine 7
+
+# Summary
+
+This major release marks a significant upgrade to the website, transitioning from Next.js 13 to 14 with App Router and from Mantine 6 to 7. This upgrade brings about substantial enhancements in performance, accessibility, user experience, and overall development practices.
+
+# Next.js
+
+- Project Structure: Aligned the project structure with the recommended guidelines for Next.js and App Router, enhancing organization and maintainability.
+- Pages and Layouts: Optimized the pages and layouts structure to align with Next.js and App Router best practices, ensuring a more structured and efficient codebase.
+- Pages Metadata: Updated each page's metadata content to provide more accurate and informative descriptions for search engines.
+- Error Pages: Deprecated the individual 403, 404, and 500 error pages and adopted a unified "not-found" page for 404 errors and a generic error page for other server-side errors.
+- Navigation Progress Bar: Discontinued the navigation progress bar for in-page transitions and implemented a centralized loading.tsx file to handle all in-page loading animations.
+
+# Mantine
+
+- CreateStyles: Adopted CSS Modules as the preferred method for styling components, replacing the deprecated createStyles function.
+- Sx Prop: Replaced the deprecated sx prop with className or style prop for styling components in Mantine 7.0.
+- Theme and ColorScheme: Refactored the theme and colour scheme usage across the codebase to align with Mantine 7.0 conventions.
+- Dynamic Multicolor Theme: Deprecated the dynamic multicolour theme change feature and centralized theme configuration in the theme/index.tsx file.
+
+# New Features
+
+- Collapsible Side Navigation: Introduced a collapsible side navigation panel for enhanced user interface and navigation experience.
+- Active Link Styles: Implemented logic to dynamically apply active link styles to the side navigation menu, providing clear visual cues for the currently selected page.
+- Dark/Light Theme Switch: Integrated a dark/light theme toggle switch on the navigation header, enabling users to personalize their viewing experience.
+- Loading Animations: Added loading animations to components rendering mock data, providing visual feedback during data fetching and processing.
+- Custom useFetch Hook: Developed a custom useFetch hook to streamline data fetching across the application. This hook encapsulates data fetching logic, returning data, loading, and error states, and utilizes the native JavaScript fetch API.
+- Code Formatting: Implemented Prettier, Husky, and lint-staged to enforce consistent code formatting and maintain a high level of code quality.
+- Clerk Integration: Integrated Clerk (https://clerk.com/) to extend user authentication and management capabilities, providing a seamless user experience.
+- NextAuth with Auth0: Implemented NextAuth with Auth0 (https://auth0.com/) for user authentication, leveraging NextAuth's flexibility and Auth0's robust identity management platform.
+- Component Documentation Stories: Created component documentation stories using Storybook to provide clear and interactive documentation for each component.
+
+# Bug Fixes
+
+- General Bug Fixes: Addressed a variety of bugs and issues to enhance overall stability and performance.
diff --git a/.changeset/moody-peaches-train.md b/.changeset/moody-peaches-train.md
new file mode 100644
index 0000000..6b4a200
--- /dev/null
+++ b/.changeset/moody-peaches-train.md
@@ -0,0 +1,5 @@
+---
+'analytics-dashboard': minor
+---
+
+updated pages metadata bug removed head tags in pages added color mode switch moved color mode switch to header removed theme drawer because no logic for color switching yet
diff --git a/.changeset/odd-mails-invent.md b/.changeset/odd-mails-invent.md
new file mode 100644
index 0000000..4feff6f
--- /dev/null
+++ b/.changeset/odd-mails-invent.md
@@ -0,0 +1,5 @@
+---
+'analytics-dashboard': patch
+---
+
+added chats loading animation, updated chats data to fetch using fetch data hook
diff --git a/.changeset/plenty-seas-push.md b/.changeset/plenty-seas-push.md
new file mode 100644
index 0000000..bc99e04
--- /dev/null
+++ b/.changeset/plenty-seas-push.md
@@ -0,0 +1,5 @@
+---
+'analytics-dashboard': minor
+---
+
+updated all pages metatadata
diff --git a/.changeset/polite-adults-laugh.md b/.changeset/polite-adults-laugh.md
new file mode 100644
index 0000000..c23159b
--- /dev/null
+++ b/.changeset/polite-adults-laugh.md
@@ -0,0 +1,5 @@
+---
+'analytics-dashboard': patch
+---
+
+removed 403 page because of build time errors
diff --git a/.changeset/polite-apples-guess.md b/.changeset/polite-apples-guess.md
new file mode 100644
index 0000000..16ff916
--- /dev/null
+++ b/.changeset/polite-apples-guess.md
@@ -0,0 +1,5 @@
+---
+'analytics-dashboard': major
+---
+
+upgraded to next 14 and mantine 7
diff --git a/.changeset/seven-timers-flash.md b/.changeset/seven-timers-flash.md
new file mode 100644
index 0000000..9c50ded
--- /dev/null
+++ b/.changeset/seven-timers-flash.md
@@ -0,0 +1,5 @@
+---
+'analytics-dashboard': minor
+---
+
+refactored layouts to match recommended layouts file structure by next docs 13
diff --git a/.changeset/smooth-llamas-thank.md b/.changeset/smooth-llamas-thank.md
new file mode 100644
index 0000000..50042b1
--- /dev/null
+++ b/.changeset/smooth-llamas-thank.md
@@ -0,0 +1,5 @@
+---
+'analytics-dashboard': minor
+---
+
+Added storybook component stories
diff --git a/.changeset/soft-wolves-push.md b/.changeset/soft-wolves-push.md
new file mode 100644
index 0000000..70ef7f7
--- /dev/null
+++ b/.changeset/soft-wolves-push.md
@@ -0,0 +1,5 @@
+---
+'analytics-dashboard': patch
+---
+
+refactored 404 and 500 pages because they are ootb & designated special pages by nextjs
diff --git a/.changeset/tender-timers-shop.md b/.changeset/tender-timers-shop.md
new file mode 100644
index 0000000..9165dcf
--- /dev/null
+++ b/.changeset/tender-timers-shop.md
@@ -0,0 +1,5 @@
+---
+'analytics-dashboard': patch
+---
+
+finished app layout migrations
diff --git a/.changeset/yellow-radios-destroy.md b/.changeset/yellow-radios-destroy.md
new file mode 100644
index 0000000..2ff81ff
--- /dev/null
+++ b/.changeset/yellow-radios-destroy.md
@@ -0,0 +1,5 @@
+---
+'analytics-dashboard': minor
+---
+
+setup next-auth & added auth0 provicder
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..53b061a
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,9 @@
+root = true
+
+[*]
+indent_style = space
+indent_size = 2
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index dd84ea7..b5c68e5 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -4,7 +4,6 @@ about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
-
---
**Describe the bug**
@@ -12,6 +11,7 @@ A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
+
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
@@ -24,15 +24,17 @@ A clear and concise description of what you expected to happen.
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- - OS: [e.g. iOS]
- - Browser [e.g. chrome, safari]
- - Version [e.g. 22]
+
+- OS: [e.g. iOS]
+- Browser [e.g. chrome, safari]
+- Version [e.g. 22]
**Smartphone (please complete the following information):**
- - Device: [e.g. iPhone6]
- - OS: [e.g. iOS8.1]
- - Browser [e.g. stock browser, safari]
- - Version [e.g. 22]
+
+- Device: [e.g. iPhone6]
+- OS: [e.g. iOS8.1]
+- Browser [e.g. stock browser, safari]
+- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
index bbcbbe7..2f28cea 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -4,7 +4,6 @@ about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
-
---
**Is your feature request related to a problem? Please describe.**
diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml
new file mode 100644
index 0000000..712cef7
--- /dev/null
+++ b/.github/workflows/chromatic.yml
@@ -0,0 +1,25 @@
+# Workflow name
+name: 'Chromatic Deployment'
+
+# Event for the workflow
+on:
+ push:
+ branches: [master]
+ pull_request:
+ branches: [master]
+
+# List of jobs
+jobs:
+ test:
+ # Operating System
+ runs-on: ubuntu-latest
+ # Job steps
+ steps:
+ - uses: actions/checkout@v3
+ - run: yarn
+ #π Adds Chromatic as a step in the workflow
+ - uses: chromaui/action@v1
+ # Options required for Chromatic's GitHub Action
+ with:
+ #π Chromatic projectToken, see https://storybook.js.org/tutorials/intro-to-storybook/react/en/deploy/ to obtain it
+ projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 7750672..e55c9d9 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -26,4 +26,4 @@ jobs:
- name: Create Release Pull Request
uses: changesets/action@v1
env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.gitignore b/.gitignore
index fb30cbd..53c5b09 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,3 +35,28 @@ yarn-error.log*
next-env.d.ts
.idea
+
+### StorybookJs ###
+# gitignore template for the Storybook, UI guide for front apps
+# website: https://storybook.js.org/
+
+storybook-static/
+
+### yarn ###
+# https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored
+
+.yarn/*
+!.yarn/releases
+!.yarn/patches
+!.yarn/plugins
+!.yarn/sdks
+!.yarn/versions
+
+# if you are NOT using Zero-installs, then:
+# comment the following lines
+!.yarn/cache
+
+# and uncomment the following lines
+# .pnp.*
+
+# End of https://www.toptal.com/developers/gitignore/api/yarn
diff --git a/.husky/pre-commit b/.husky/pre-commit
new file mode 100644
index 0000000..610c2a5
--- /dev/null
+++ b/.husky/pre-commit
@@ -0,0 +1,4 @@
+#!/usr/bin/env sh
+. "$(dirname -- "$0")/_/husky.sh"
+
+npm test
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 0000000..1b8ac88
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,3 @@
+# Ignore artifacts:
+build
+coverage
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000..937375d
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,4 @@
+{
+ "semi": true,
+ "singleQuote": true
+}
diff --git a/.storybook/main.ts b/.storybook/main.ts
new file mode 100644
index 0000000..1b8c3db
--- /dev/null
+++ b/.storybook/main.ts
@@ -0,0 +1,41 @@
+import type { StorybookConfig } from '@storybook/nextjs';
+import { resolve } from 'node:path';
+import path from 'path';
+
+const config: StorybookConfig = {
+ stories: [
+ '../stories/**/*.mdx',
+ '../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)',
+ '../components/**/*.stories.mdx',
+ '../components/**/*.stories.@(js|jsx|ts|tsx)',
+ ],
+ addons: [
+ '@storybook/addon-links',
+ '@storybook/addon-essentials',
+ '@storybook/addon-onboarding',
+ '@storybook/addon-interactions',
+ '@storybook/addon-styling-webpack',
+ ],
+ framework: {
+ name: '@storybook/nextjs',
+ options: {
+ nextConfigPath: resolve(__dirname, '../../next.config.js'),
+ },
+ },
+ docs: {
+ autodocs: 'tag',
+ },
+ webpackFinal: async (config, { configType }) => {
+ if (!config.resolve) {
+ return config;
+ }
+
+ config.resolve.alias = {
+ ...config.resolve.alias,
+ '@': path.resolve(__dirname, '..'),
+ };
+
+ return config;
+ },
+};
+export default config;
diff --git a/.storybook/manager.ts b/.storybook/manager.ts
new file mode 100644
index 0000000..b2fb282
--- /dev/null
+++ b/.storybook/manager.ts
@@ -0,0 +1,8 @@
+// .storybook/manager.js
+
+import { addons } from '@storybook/manager-api';
+import myTheme from './theme';
+
+addons.setConfig({
+ theme: myTheme,
+});
diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx
new file mode 100644
index 0000000..af4f3cf
--- /dev/null
+++ b/.storybook/preview.tsx
@@ -0,0 +1,55 @@
+// Import styles of packages that you've installed.
+// All packages except `@mantine/hooks` require styles imports
+import '@mantine/core/styles.css';
+import '@mantine/dates/styles.css';
+import '@mantine/tiptap/styles.css';
+import '@mantine/carousel/styles.css';
+import '@mantine/notifications/styles.css';
+import 'mantine-datatable/styles.layer.css';
+
+import React, { useEffect } from 'react';
+import { addons } from '@storybook/preview-api';
+import { DARK_MODE_EVENT_NAME } from 'storybook-dark-mode';
+import { MantineProvider, useMantineColorScheme } from '@mantine/core';
+import { themes } from '@storybook/theming';
+import { Preview } from '@storybook/react';
+// @ts-ignore
+import { myTheme } from '../theme';
+
+// theme.ts file from previous step
+
+const channel = addons.getChannel();
+
+function ColorSchemeWrapper({ children }: { children: React.ReactNode }) {
+ const { setColorScheme } = useMantineColorScheme();
+ const handleColorScheme = (value: boolean) =>
+ setColorScheme(value ? 'dark' : 'light');
+
+ useEffect(() => {
+ channel.on(DARK_MODE_EVENT_NAME, handleColorScheme);
+ return () => channel.off(DARK_MODE_EVENT_NAME, handleColorScheme);
+ }, [channel]);
+
+ return <>{children}>;
+}
+
+export const decorators = [
+ (renderStory: any) => (
+ {renderStory()}
+ ),
+ (renderStory: any) => (
+ {renderStory()}
+ ),
+];
+
+const preview: Preview = {
+ parameters: {
+ nextjs: {
+ appDirectory: true,
+ },
+ docs: {
+ theme: themes.normal,
+ },
+ },
+ decorators: decorators,
+};
diff --git a/.storybook/theme.ts b/.storybook/theme.ts
new file mode 100644
index 0000000..d056e77
--- /dev/null
+++ b/.storybook/theme.ts
@@ -0,0 +1,13 @@
+// .storybook/YourTheme.js
+
+import { create } from '@storybook/theming/create';
+
+export default create({
+ base: 'light',
+ brandTitle: 'Mantine analytics dashboard',
+ brandUrl: 'https://mantine-analytics-dashboard.netlify.app/',
+ brandTarget: '_blank',
+
+ //
+ colorPrimary: '#2378c3',
+});
diff --git a/.yarn/install-state.gz b/.yarn/install-state.gz
new file mode 100644
index 0000000..8a54840
Binary files /dev/null and b/.yarn/install-state.gz differ
diff --git a/README.md b/README.md
index 0dd6ae2..ae0592d 100644
--- a/README.md
+++ b/README.md
@@ -1,32 +1,121 @@
-![thumbnail-img-b](https://github.com/design-sparx/mantine-analytics-dashboard/assets/26582923/b82ec1c2-479a-4eb3-9ef2-0c5e6435c78c)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+- [Live preview](https://mantine-analytics-dashboard.netlify.app/)
+- [Components preview](https://6546507b657a74164abf2db6-oniqlpqtfs.chromatic.com/)
+- [Medium](https://medium.com/stackademic/how-i-built-an-open-source-admin-dashboard-template-with-mantine-and-next-js-4f00a21ce04f)
+
+# About
+
+A professional admin & dashboard template built using on [Mantine 7](https://mantine.dev/) that comes with hundreds of
+UI components, forms, tables, charts, pages and icons. This template is built
+using [Next v14](https://nextjs.org/), [React](https://react.dev/), [Apex Charts](https://apexcharts.com/),[Mantine DataTable](https://icflorescu.github.io/mantine-datatable/)
+and [Storybook](https://storybook.js.org/).
+
+![preview image](public/dashboard.png)
+
+# Features
+
+- **Customizable:** You don't need to be an expert to customize the template. Our code is very readable and
+ well-documented.
+- **Fully Responsive:** With mobile, tablet & desktop support it doesn't matter what device you're using. Antd Dashboard
+ is responsive in all browsers.
+- **Cross-Browser:** Our themes are working perfectly with Chrome, Firefox, Opera, and Edge. We're working hard to
+ support them.
+- **Clean Code:** We strictly follow Ant Design's guidelines to make your integration as easy as possible. All code is
+ handwritten.
+- **Regular Updates:** From time to time you'll receive an update containing new components, improvements, and bug
+ fixes.
+
+# Tech stack
+
+To make this template awesome, I used the following packages:
+
+## Core
+
+- **Next js v14:** Next.js is an open-source web development framework created by the private company Vercel providing
+ React-based web applications with server-side rendering and static website generation.
+- **Mantine v7:** Mantine is a React UI components library. It's built on top of React and TypeScript, and provides a
+ variety of
+ components and hooks for building high-performance web applications.
+- **React v18:** React is a free and open-source front-end JavaScript library for building user interfaces based on
+ components.
+- **Typescript v5:** TypeScript is a free and open-source high-level programming language developed by Microsoft that
+ adds static typing with optional type annotations to JavaScript.
+- **Storybook v7:** Storybook is a free, open-source tool for developing UI components in isolation. It's used by web
+ developers to improve their UI development workflow and build better web applications.
+- **Changeset CLI v2:** Changeset is a package that helps in managing my versions and changelogs.
+- **NextAuth v4:** NextAuth.js is a flexible and secure authentication library that can be used for client-side
+ authentication in Next.js.
+- **Tabler icons v2:** Tabler Icons is a free, open-source icon library with over 4,700 icons. The icons are designed
+ with a modern aesthetic and are suitable for a wide range of applications.
+- **Mantine datatable v7:** Mantine DataTable is a React component that can be used to create data-rich user interfaces.
+ It is a table component that is aware of dark themes and is designed for Mantine UI.
+- **Lodash v4:** A JavaScript utility library delivering consistency, modularity, performance, & extras.
+- **Apex chart v3:s** ApexCharts is a free, open-source JavaScript charting library that allows developers to create
+ interactive data visualizations for web pages. It can be used for both commercial and non-commercial projects.
+- **Dayjs v1:** Day.js is a JavaScript library that handles dates and times.
+- **Tiptap v2:** A headless, framework-agnostic and extendable rich text editor, based on ProseMirror.
+- **Fullcalendar v6**: FullCalendar is a JavaScript event calendar with over 300 settings. It's open source and has a
+ free core.
+- **Dnd-Kit v6:** Dnd-kit is a lightweight, modular, and extensible drag-and-drop toolkit for React. It is also
+ accessible and performant.
+- **Embla carousel v7:** Embla Carousel is a lightweight carousel library with fluid motion and precise swiping.
+- **React simple maps v3:** An svg map chart component built with and for React.
+- **Clerk/nextjs v4:** Clerk Next.js is a wrapper around Clerk React. It allows users to use the hooks that Clerk React
+ provides.
+- **React countup v6:** A React component wrapper around CountUp.js.
+
+## Dev
+
+- **Prettier v3:** Prettier is a code formatter that automatically formats code to ensure it is consistent and easy to
+ read.
+- **Husky v8:** Husky is a tool that makes it easier to work with git hooks. Prettier is a code formatter.
+- **Lint staged v15:** Lint-staged will automatically add any modifications to the commit as long as there are no
+ errors.
+- **Postcss v8:** PostCSS is a JavaScript library that uses plugins to transform CSS. It transpiles CSS into an abstract
+ syntax tree, which is then represented by JavaScript objects.
+
+# Quick start
+
+## Download
+
+- Clone this repo git clone `https://github.com/design-sparx/mantine-analytics-dashboard.git`
+- [Download from GitHub](https://github.com/design-sparx/mantine-analytics-dashboard/archive/refs/heads/main.zip)
-[![Netlify Status](https://api.netlify.com/api/v1/badges/72758493-91b7-4ec0-ab26-697db44db93e/deploy-status)](https://app.netlify.com/sites/mantine-analytics-dashboard/deploys)
-
-[Live Preview](https://mantine-analytics-dashboard.netlify.app/)
-
-## Quick start
-
-This is a Next.js project bootstrapped with create-next-app. You'll need to install Node.js (v16 or up) before using
-Dashboard.
-
-Before proceeding, please ensure you have the following software installed on your computer.
-
-- Node
-- Yarn (optional but recommended)
-- Git command line tools
-
-## Useful links
-- Download Git CLI -
- - Windows: https://git-scm.com/download/windows
- - Mac: https://git-scm.com/download/mac
-- Download Node - https://nodejs.org/en/
-- Download Yarn CLI - https://yarnpkg.com/lang/en/docs/install/
-- Download IDE
- - vsCode: https://code.visualstudio.com/
- - Jetbrains webstorm - https://www.jetbrains.com/webstorm/
+## Build tools
-## Project Setup
-In your root project folder, open your terminal and run the command below.
+You'll need to install Node.js.
+Once Node.js is installed, run npm install to install the rest of the template's dependencies. All dependencies will be
+downloaded to the node_modules directory.
```bash copy
npm install
@@ -39,38 +128,111 @@ local webserver at http://localhost:3000, run the following command.
npm run dev
```
-## Build tools
-Start a local webserver at http://localhost:3000 and detect file changes:
-
-```bash copy
-npm run dev
-```
-
-Compile, optimize, minify and uglify all source files to build/:
+Compile, optimize, minify and uglify all source files to build/
```bash copy
npm run build
```
-## File structure
-Inside the zip-file you'll find the following directories and files. Both compiled and minified distrubution files, as
+# File structure
+
+Inside the zip-file you'll find the following directories and files. Both compiled and minified distribution files, as
+Inside the zip file, you'll find the following directories and files. Both compiled and minified distribution files, as
well as the source files are included in the package.
```
-theme/
- βββ .gitignore
- βββ package.json
- βββ package-lock.json
- βββ README.md
- βββ components/
- βββ layout/
- βββ mocks/
- βββ pages/
- βββ routes/
- βββ styles/
- βββ types/
- βββ utils/
- βββ public/
- β βββ index.html
- β βββ manifest.json
+mantine-analytics-dashboard/
+βββ .changeset
+βββ .github
+βββ .gitignore
+βββ .editorconfig
+βββ .prettierignore
+βββ .prettierrc
+βββ README.md
+βββ CHANGELOG.md
+βββ LICENSE
+βββ index.html
+βββ package.json
+βββ tsconfig.json
+βββ next.config.js
+βββ postcss.config.cjs
+βββ clerkMiddleware.ts
+βββ yarn.lock
+βββ public/
+β βββ mocks/
+β βββ _redirects
+β βββ favicon.ico
+βββ src/
+β βββ .changeset/
+β βββ .github/
+β βββ .husty/
+β βββ .storybook/
+β βββ .yarn/
+β βββ app/
+βββββββ api/
+βββββββ error.tsx
+βββββββ error.module.css
+βββββββ global.css
+βββββββ layout.tsx
+βββββββ loading.tsx
+βββββββ not-found.tsx
+βββββββ page.module.css
+βββββββ page.tsx
+β βββ components/
+β βββ hooks/
+β βββ layout/
+β βββ providers/
+β βββ public/
+β βββ routes/
+β βββ styles/
+β βββ theme/
+β βββ types/
+β βββ utils/
+βββ
```
+
+# Contributing and Support
+
+I welcome all developers and enthusiasts to contribute to the growth of our open-source admin dashboard template.
+Contributing is a collaborative process that empowers us to collectively enhance the templateβs capabilities and
+quality. To get started:
+
+- Fork the Repository: Fork the templateβs GitHub repository to your own GitHub account.
+- Clone the Fork: Clone the forked repository to your local machine using Git.
+- Create a Branch: Create a new branch for your contributions to keep the main codebase intact.
+- Implement Changes: Make your desired changes, add new components, or refine existing features.
+- Commit and Push: Commit your changes to the new branch and push them to your GitHub fork.
+- Submit a Pull Request: Submit a pull request from your forked repository to the main template repository. Your changes
+ will be reviewed and potentially merged.
+
+# Reporting Issues and Seeking Help
+
+Should you encounter any issues or need assistance while using the template, weβre here to help:
+
+- Issue Tracker: Visit the GitHub
+ repositoryβs [Issues](https://github.com/design-sparx/mantine-analytics-dashboard/issues) tab to report bugs, suggest
+ enhancements, or seek clarification on aspects of the template.
+- Community Interaction: Engage with the templateβs community on platforms
+ like [GitHub Discussions](https://github.com/design-sparx/mantine-analytics-dashboard/discussions) for assistance,
+ guidance, and insights.
+
+# Invitation to Explore and Utilize
+
+The Mantine and Next.js admin dashboard template isnβt just an end; itβs a beginning β a starting point for your
+creative journey. Whether youβre a seasoned developer seeking a rapid launch or an enthusiast keen on learning modern
+development practices, this template is your canvas.
+
+# Further resources
+
+- Nextjs - [https://nextjs.org/docs](https://nextjs.org/docs)
+- React - [https://react.dev/learn](https://react.dev/learn)
+- Mantine - [https://mantine.dev/getting-started/](https://mantine.dev/getting-started/)
+- Nextauth - [https://authjs.dev/](https://authjs.dev/)
+- Storybook - [https://storybook.js.org/docs/get-started/install](https://storybook.js.org/docs/get-started/install)
+- Apexcharts - [https://apexcharts.com/docs/installation/](https://apexcharts.com/docs/installation/)
+- Tiptap - [https://tiptap.dev/introduction](https://tiptap.dev/introduction)
+- Dndkit - [https://docs.dndkit.com/](https://docs.dndkit.com/)
+- Embla carousel - [https://www.embla-carousel.com/get-started/](https://www.embla-carousel.com/get-started/)
+- Fullcalendar - [https://fullcalendar.io/docs/getting-started](https://fullcalendar.io/docs/getting-started)
+- React simple
+ maps - [https://www.react-simple-maps.io/docs/getting-started/](https://www.react-simple-maps.io/docs/getting-started/)
diff --git a/app/api/auth/[...nextauth]/route.ts b/app/api/auth/[...nextauth]/route.ts
new file mode 100644
index 0000000..4c28971
--- /dev/null
+++ b/app/api/auth/[...nextauth]/route.ts
@@ -0,0 +1,6 @@
+import NextAuth from 'next-auth';
+import { authOptions } from '@/app/lib/auth';
+
+const handler = NextAuth(authOptions);
+
+export { handler as GET, handler as POST };
diff --git a/app/authProviders/auth0/layout.tsx b/app/authProviders/auth0/layout.tsx
new file mode 100644
index 0000000..186e88f
--- /dev/null
+++ b/app/authProviders/auth0/layout.tsx
@@ -0,0 +1,10 @@
+import { ReactNode } from 'react';
+import { Providers } from '@/providers/session';
+
+type Auth0LayoutProps = {
+ children: ReactNode;
+};
+
+export default function Auth0Layout({ children }: Auth0LayoutProps) {
+ return {children} ;
+}
diff --git a/app/authProviders/auth0/page.tsx b/app/authProviders/auth0/page.tsx
new file mode 100644
index 0000000..edc5c98
--- /dev/null
+++ b/app/authProviders/auth0/page.tsx
@@ -0,0 +1,117 @@
+'use client';
+
+import { signIn, signOut, useSession } from 'next-auth/react';
+import {
+ Button,
+ Center,
+ Container,
+ Divider,
+ Group,
+ Image,
+ Loader,
+ Paper,
+ Stack,
+ Text,
+ Title,
+} from '@mantine/core';
+import { IconBrandAuth0, IconLogin, IconLogin2 } from '@tabler/icons-react';
+
+const ICON_SIZE = 18;
+
+export default function Page() {
+ const { data: session, status } = useSession();
+ const userEmail = session?.user?.email;
+ const userImg = session?.user?.image;
+ const userName = session?.user?.name;
+
+ if (status === 'loading') {
+ return (
+
+
+
+ Hang on there...
+
+
+ );
+ }
+
+ if (status === 'authenticated') {
+ return (
+
+
+
+
+ Auth0
+
+
+
+
+ Signed In
+
+
+ {userName}
+
+ {userEmail}
+
+ signOut()}
+ leftSection={ }
+ color="red"
+ fullWidth
+ >
+ Sign out
+
+
+
+
+ );
+ }
+
+ return (
+ <>
+ <>
+ Auth0 | DesignSparx
+
+ >
+
+
+
+
+ Auth0
+
+
+
+
+
+ Not signed In
+
+ signIn()}
+ leftSection={ }
+ >
+ Sign in
+
+
+
+
+
+ >
+ );
+}
diff --git a/app/authProviders/clerk/page.tsx b/app/authProviders/clerk/page.tsx
new file mode 100644
index 0000000..09382da
--- /dev/null
+++ b/app/authProviders/clerk/page.tsx
@@ -0,0 +1,123 @@
+'use client';
+
+import {
+ ClerkProvider,
+ SignInButton,
+ SignUpButton,
+ SignIn,
+ SignUp,
+ SignOutButton,
+ UserButton,
+ UserProfile,
+ ClerkLoading,
+ ClerkLoaded,
+} from '@clerk/nextjs';
+import {
+ Container,
+ Image,
+ Stack,
+ Divider,
+ Group,
+ Title,
+ Text,
+ Paper,
+ Button,
+ useMantineColorScheme,
+ useMantineTheme,
+ parseThemeColor,
+ Select,
+ Flex,
+} from '@mantine/core';
+import { dark, neobrutalism, shadesOfPurple } from '@clerk/themes';
+import { useEffect, useState } from 'react';
+import { IconLogin, IconLogin2, IconUserCircle } from '@tabler/icons-react';
+
+const ICON_SIZE = 18;
+
+function Home() {
+ const { colorScheme } = useMantineColorScheme();
+ const theme = useMantineTheme();
+ const parsedThemeColor = parseThemeColor({
+ color: theme.primaryColor,
+ theme,
+ });
+ const [clerkTheme, setClerkTheme] = useState('');
+
+ const clerkAppearanceOptions: any = {
+ variables: { colorPrimary: parsedThemeColor.value },
+ };
+
+ useEffect(() => {
+ if (clerkTheme === 'dark') {
+ clerkAppearanceOptions['baseTheme'] = dark;
+ } else if (clerkTheme === 'neobrutalism') {
+ clerkAppearanceOptions['baseTheme'] = neobrutalism;
+ } else if (clerkTheme === 'purpleShades') {
+ clerkAppearanceOptions['baseTheme'] = shadesOfPurple;
+ }
+ }, [clerkTheme]);
+
+ return (
+ <>
+ <>
+ Clerk | DesignSparx
+
+ >
+
+
+
+
+
+
+
+ Buttons
+
+ Click on the buttons to trigger a signup/signin using Clerk
+
+
+
+ }>
+ Sign In
+
+
+
+ }>
+ Sign Up
+
+
+
+ }>
+ Sign out
+
+
+
+
+ Cards
+
+
+ Sign up
+
+
+
+ Sign in
+
+
+
+
+
+
+ >
+ );
+}
+
+export default Home;
diff --git a/app/authProviders/layout.tsx b/app/authProviders/layout.tsx
new file mode 100644
index 0000000..7bffe60
--- /dev/null
+++ b/app/authProviders/layout.tsx
@@ -0,0 +1,69 @@
+'use client';
+
+import { AppShell, Container, rem, useMantineTheme } from '@mantine/core';
+import { ReactNode, useState } from 'react';
+import { useDisclosure, useMediaQuery } from '@mantine/hooks';
+import AppMain from '@/components/AppMain';
+import Navigation from '@/components/Navigation';
+import HeaderNav from '@/components/HeaderNav';
+import FooterNav from '@/components/FooterNav';
+
+type Props = {
+ children: ReactNode;
+};
+
+function AuthProviderLayout({ children }: Props) {
+ const theme = useMantineTheme();
+ const [opened, setOpened] = useState(false);
+ const [themeOpened, { open: themeOpen, close: themeClose }] =
+ useDisclosure(false);
+ const tablet_match = useMediaQuery('(max-width: 768px)');
+ const [mobileOpened, { toggle: toggleMobile }] = useDisclosure();
+ const [desktopOpened, { toggle: toggleDesktop }] = useDisclosure(true);
+
+ return (
+
+
+
+ setOpened((o) => !o)}
+ desktopOpened={desktopOpened}
+ mobileOpened={mobileOpened}
+ toggleDesktop={toggleDesktop}
+ toggleMobile={toggleMobile}
+ />
+
+
+
+ setOpened(false)} />
+
+
+ {children}
+
+
+
+
+
+
+
+ );
+}
+
+export default AuthProviderLayout;
diff --git a/app/authentication/layout.tsx b/app/authentication/layout.tsx
new file mode 100644
index 0000000..a1f2844
--- /dev/null
+++ b/app/authentication/layout.tsx
@@ -0,0 +1,39 @@
+'use client';
+
+import { Center, Stack, useMantineTheme } from '@mantine/core';
+import Image from 'next/image';
+import React, { ReactNode } from 'react';
+import { useColorScheme } from '@mantine/hooks';
+
+type AuthProps = {
+ children: ReactNode;
+};
+
+function AuthLayout({ children }: AuthProps) {
+ const theme = useMantineTheme();
+ const colorScheme = useColorScheme();
+
+ return (
+
+
+
+
+
+ {children}
+
+
+ );
+}
+
+export default AuthLayout;
diff --git a/app/authentication/password-reset/page.module.css b/app/authentication/password-reset/page.module.css
new file mode 100644
index 0000000..286abec
--- /dev/null
+++ b/app/authentication/password-reset/page.module.css
@@ -0,0 +1,45 @@
+.card {
+ width: rem(420px);
+ margin-top: rem(15px);
+ padding: var(--mantine-spacing-lg);
+ border-radius: var(--mantine-radius-default);
+ box-shadow: var(--mantine-shadow-xl);
+ border: rem(1px) solid var(--mantine-color-gray-3);
+
+ @media (max-width: $mantine-breakpoint-sm) {
+ width: rem(360px);
+ }
+}
+
+.title {
+ font-size: rem(26px);
+ font-weight: 900;
+}
+
+.controls {
+ @media (max-width: $mantine-breakpoint-sm) {
+ flex-direction: column-reverse;
+ align-items: center;
+ }
+}
+
+.control {
+ padding: rem(6px) rem(10px);
+ border-radius: var(--mantine-radius-default);
+ font-weight: 500;
+
+ @media (max-width: $mantine-breakpoint-sm) {
+ width: 1000%;
+ text-align: center;
+ }
+
+ @mixin hover {
+ transition: all ease 150ms;
+ background-color: light-dark(
+ var(--mantine-color-gray-2),
+ var(--mantine-color-dark-4)
+ );
+ color: light-dark(var(--mantine-color-black), var(--mantine-color-white));
+ text-decoration: none;
+ }
+}
diff --git a/app/authentication/password-reset/page.tsx b/app/authentication/password-reset/page.tsx
new file mode 100644
index 0000000..69d0b3b
--- /dev/null
+++ b/app/authentication/password-reset/page.tsx
@@ -0,0 +1,75 @@
+'use client';
+
+import {
+ Button,
+ Group,
+ Paper,
+ rem,
+ Text,
+ TextInput,
+ Title,
+ UnstyledButton,
+} from '@mantine/core';
+import { IconChevronLeft } from '@tabler/icons-react';
+import React from 'react';
+import Link from 'next/link';
+import { PATH_AUTH, PATH_DASHBOARD } from '@/routes';
+import { useMediaQuery } from '@mantine/hooks';
+import classes from './page.module.css';
+import { Surface } from '@/components';
+import { Metadata } from 'next';
+
+const metadata: Metadata = {
+ title: 'Password Reset | DesignSparx',
+ description:
+ 'Explore our versatile dashboard website template featuring a stunning array of themes and meticulously crafted components. Elevate your web project with seamless integration, customizable themes, and a rich variety of components for a dynamic user experience. Effortlessly bring your data to life with our intuitive dashboard template, designed to streamline development and captivate users. Discover endless possibilities in design and functionality today!',
+};
+
+function Page() {
+ const mobile_match = useMediaQuery('(max-width: 425px)');
+
+ return (
+ <>
+ <>
+ Password Reset | DesignSparx
+
+ >
+ Forgot your password?
+ Enter your email to get a reset link
+
+
+
+
+
+
+
+
+ Back to the login page
+
+
+
+
+ Reset password
+
+
+
+ >
+ );
+}
+
+export default Page;
diff --git a/app/authentication/signin/page.module.css b/app/authentication/signin/page.module.css
new file mode 100644
index 0000000..de80836
--- /dev/null
+++ b/app/authentication/signin/page.module.css
@@ -0,0 +1,64 @@
+.card {
+ width: rem(420px);
+ margin-top: rem(15px);
+ padding: var(--mantine-spacing-lg);
+ border-radius: var(--mantine-radius-default);
+ box-shadow: var(--mantine-shadow-xl);
+ border: rem(1px) solid var(--mantine-color-gray-3);
+
+ @mixin light {
+ background-color: var(--mantine-color-gray-0);
+ color: var(--mantine-color-black);
+ }
+
+ @mixin dark {
+ background-color: var(--mantine-color-dark-7);
+ color: var(--mantine-color-white);
+ }
+
+ @media (max-width: $mantine-breakpoint-sm) {
+ width: rem(360);
+ }
+}
+
+.link {
+ padding: rem(6px) rem(10px);
+ border-radius: var(--mantine-radius-default);
+ color: light-dark(var(--mantine-color-black), var(--mantine-color-white));
+ font-weight: 500;
+
+ @mixin light {
+ color: var(--mantine-color-black);
+ }
+
+ @mixin dark {
+ color: var(--mantine-color-white);
+ }
+
+ @mixin hover {
+ background-color: light-dark(
+ var(--mantine-color-dark-5),
+ var(--mantine-color-gray-2)
+ );
+ text-decoration: none;
+ transition: all ease 150ms;
+
+ @mixin light {
+ background-color: var(--mantine-color-gray-2);
+ }
+
+ @mixin dark {
+ background-color: var(--mantine-color-dark-4);
+ }
+ }
+}
+
+.label {
+ @mixin light {
+ color: var(--mantine-color-black);
+ }
+
+ @mixin dark {
+ color: var(--mantine-color-white);
+ }
+}
diff --git a/app/authentication/signin/page.tsx b/app/authentication/signin/page.tsx
new file mode 100644
index 0000000..ccc0968
--- /dev/null
+++ b/app/authentication/signin/page.tsx
@@ -0,0 +1,87 @@
+'use client';
+
+import {
+ Button,
+ Center,
+ Checkbox,
+ Group,
+ Paper,
+ PasswordInput,
+ Text,
+ TextInput,
+ TextProps,
+ Title,
+} from '@mantine/core';
+import Link from 'next/link';
+import { PATH_AUTH, PATH_DASHBOARD } from '@/routes';
+import { Metadata } from 'next';
+import { Surface } from '@/components';
+import classes from './page.module.css';
+
+function Page() {
+ const LINK_PROPS: TextProps = {
+ className: classes.link,
+ };
+
+ return (
+ <>
+ <>
+ Sign in | DesignSparx
+
+ >
+ Welcome back!
+ Sign in to your account to continue
+
+
+
+
+
+
+
+ Forgot password?
+
+
+
+ Sign in
+
+
+
+ Do not have an account yet? Create account
+
+
+
+ >
+ );
+}
+
+export default Page;
diff --git a/app/authentication/signup/page.module.css b/app/authentication/signup/page.module.css
new file mode 100644
index 0000000..de80836
--- /dev/null
+++ b/app/authentication/signup/page.module.css
@@ -0,0 +1,64 @@
+.card {
+ width: rem(420px);
+ margin-top: rem(15px);
+ padding: var(--mantine-spacing-lg);
+ border-radius: var(--mantine-radius-default);
+ box-shadow: var(--mantine-shadow-xl);
+ border: rem(1px) solid var(--mantine-color-gray-3);
+
+ @mixin light {
+ background-color: var(--mantine-color-gray-0);
+ color: var(--mantine-color-black);
+ }
+
+ @mixin dark {
+ background-color: var(--mantine-color-dark-7);
+ color: var(--mantine-color-white);
+ }
+
+ @media (max-width: $mantine-breakpoint-sm) {
+ width: rem(360);
+ }
+}
+
+.link {
+ padding: rem(6px) rem(10px);
+ border-radius: var(--mantine-radius-default);
+ color: light-dark(var(--mantine-color-black), var(--mantine-color-white));
+ font-weight: 500;
+
+ @mixin light {
+ color: var(--mantine-color-black);
+ }
+
+ @mixin dark {
+ color: var(--mantine-color-white);
+ }
+
+ @mixin hover {
+ background-color: light-dark(
+ var(--mantine-color-dark-5),
+ var(--mantine-color-gray-2)
+ );
+ text-decoration: none;
+ transition: all ease 150ms;
+
+ @mixin light {
+ background-color: var(--mantine-color-gray-2);
+ }
+
+ @mixin dark {
+ background-color: var(--mantine-color-dark-4);
+ }
+ }
+}
+
+.label {
+ @mixin light {
+ color: var(--mantine-color-black);
+ }
+
+ @mixin dark {
+ color: var(--mantine-color-white);
+ }
+}
diff --git a/app/authentication/signup/page.tsx b/app/authentication/signup/page.tsx
new file mode 100644
index 0000000..7e8e9e1
--- /dev/null
+++ b/app/authentication/signup/page.tsx
@@ -0,0 +1,102 @@
+'use client';
+
+import {
+ Button,
+ Center,
+ Flex,
+ Paper,
+ PasswordInput,
+ Text,
+ TextInput,
+ TextProps,
+ Title,
+ useMantineTheme,
+} from '@mantine/core';
+import Link from 'next/link';
+import { PATH_AUTH, PATH_DASHBOARD } from '@/routes';
+import { useColorScheme, useMediaQuery } from '@mantine/hooks';
+import { Metadata } from 'next';
+import { Surface } from '@/components';
+import classes from './page.module.css';
+
+function Page() {
+ const theme = useMantineTheme();
+ const colorScheme = useColorScheme();
+ const mobile_match = useMediaQuery('(max-width: 425px)');
+
+ const LINK_PROPS: TextProps = {
+ className: classes.link,
+ };
+
+ return (
+ <>
+ <>
+ Sign up | DesignSparx
+
+ >
+ Welcome!
+ Create your account to continue
+
+
+
+
+
+
+
+
+
+
+ Create account
+
+
+
+ Already have an account? Sign in
+
+
+
+ >
+ );
+}
+
+export default Page;
diff --git a/app/calendar/layout.tsx b/app/calendar/layout.tsx
new file mode 100644
index 0000000..22dc793
--- /dev/null
+++ b/app/calendar/layout.tsx
@@ -0,0 +1,69 @@
+'use client';
+
+import { AppShell, Container, rem, useMantineTheme } from '@mantine/core';
+import { ReactNode, useState } from 'react';
+import { useDisclosure, useMediaQuery } from '@mantine/hooks';
+import AppMain from '@/components/AppMain';
+import Navigation from '@/components/Navigation';
+import HeaderNav from '@/components/HeaderNav';
+import FooterNav from '@/components/FooterNav';
+
+type Props = {
+ children: ReactNode;
+};
+
+function CalendarLayout({ children }: Props) {
+ const theme = useMantineTheme();
+ const [opened, setOpened] = useState(false);
+ const [themeOpened, { open: themeOpen, close: themeClose }] =
+ useDisclosure(false);
+ const tablet_match = useMediaQuery('(max-width: 768px)');
+ const [mobileOpened, { toggle: toggleMobile }] = useDisclosure();
+ const [desktopOpened, { toggle: toggleDesktop }] = useDisclosure(true);
+
+ return (
+
+
+
+ setOpened((o) => !o)}
+ desktopOpened={desktopOpened}
+ mobileOpened={mobileOpened}
+ toggleDesktop={toggleDesktop}
+ toggleMobile={toggleMobile}
+ />
+
+
+
+ setOpened(false)} />
+
+
+ {children}
+
+
+
+
+
+
+
+ );
+}
+
+export default CalendarLayout;
diff --git a/app/calendar/page.css b/app/calendar/page.css
new file mode 100644
index 0000000..689a273
--- /dev/null
+++ b/app/calendar/page.css
@@ -0,0 +1,45 @@
+/*Had to avoid using page.module.css naming conventions as I need to override the styles below*/
+
+.fc-event-bg-color,
+.fc-event-main,
+.fc-v-event,
+.fc-h-event {
+ background-color: var(--mantine-primary-color-filled);
+ border-color: var(--mantine-primary-color-filled);
+}
+
+.fc-button {
+ text-transform: capitalize !important;
+ font-weight: 600;
+ background-color: var(--mantine-primary-color-filled) !important;
+ border-color: var(--mantine-primary-color-filled) !important;
+}
+
+.fc .fc-button-primary:hover {
+ background-color: var(--mantine-primary-color-filled-hover) !important;
+ border-color: var(--mantine-primary-color-filled-hover) !important;
+}
+
+.fc .fc-button-primary:disabled {
+ background-color: var(--mantine-primary-color-light);
+ border-color: var(--mantine-primary-color-light);
+ cursor: not-allowed;
+}
+
+.active button,
+.fc .fc-button-primary:not(:disabled).fc-button-active,
+.fc .fc-button-primary:not(:disabled):active {
+ background-color: var(--mantine-primary-color-filled-hover);
+ border-color: var(--mantine-primary-color-filled-hover);
+}
+
+.fc-toolbar-title {
+ font-size: 20px;
+}
+
+.fc .fc-toolbar {
+ @media (max-width: em(768px)) {
+ flex-direction: column;
+ gap: 8px;
+ }
+}
diff --git a/app/calendar/page.tsx b/app/calendar/page.tsx
new file mode 100644
index 0000000..3c9fd0c
--- /dev/null
+++ b/app/calendar/page.tsx
@@ -0,0 +1,162 @@
+'use client';
+
+import React, { useState } from 'react';
+import { Anchor, Container, Paper, Stack } from '@mantine/core';
+import { formatDate } from '@fullcalendar/core';
+import FullCalendar from '@fullcalendar/react';
+import dayGridPlugin from '@fullcalendar/daygrid';
+import timeGridPlugin from '@fullcalendar/timegrid';
+import interactionPlugin from '@fullcalendar/interaction';
+import { PATH_DASHBOARD } from '@/routes';
+import { createEventId, INITIAL_EVENTS } from '@/utils';
+import { PageHeader, Surface } from '@/components';
+import { Metadata } from 'next';
+import './page.css';
+
+const items = [
+ { title: 'Dashboard', href: PATH_DASHBOARD.default },
+ { title: 'Calendar', href: '#' },
+].map((item, index) => (
+
+ {item.title}
+
+));
+
+function renderEventContent(eventInfo: any) {
+ return (
+ <>
+ {eventInfo.timeText}
+ {eventInfo.event.title}
+ >
+ );
+}
+
+function renderSidebarEvent(event: any) {
+ return (
+
+
+ {formatDate(event.start, {
+ year: 'numeric',
+ month: 'short',
+ day: 'numeric',
+ })}
+
+ {event.title}
+
+ );
+}
+
+function Calendar() {
+ const [weekendsVisible, setWeekendsVisible] = useState(true);
+ const [currentEvents, setCurrentEvents] = useState([]);
+
+ const handleWeekendsToggle = () => {
+ setWeekendsVisible(!weekendsVisible);
+ };
+
+ const handleDateSelect = (selectInfo: any) => {
+ let title = prompt('Please enter a new title for your event');
+ let calendarApi = selectInfo.view.calendar;
+
+ calendarApi.unselect(); // clear date selection
+
+ if (title) {
+ calendarApi.addEvent({
+ id: createEventId(),
+ title,
+ start: selectInfo.startStr,
+ end: selectInfo.endStr,
+ allDay: selectInfo.allDay,
+ });
+ }
+ };
+
+ const handleEventClick = (clickInfo: any) => {
+ if (
+ confirm(
+ `Are you sure you want to delete the event '${clickInfo.event.title}'`,
+ )
+ ) {
+ clickInfo.event.remove();
+ }
+ };
+
+ const handleEvents = (events: any) => {
+ setCurrentEvents(events);
+ };
+
+ const renderSidebar = () => {
+ return (
+
+
+
Instructions
+
+ Select dates and you will be prompted to create a new event
+ Drag, drop, and resize events
+ Click an event to delete it
+
+
+
+
+
+ toggle weekends
+
+
+
+
All Events ({currentEvents.length})
+
{currentEvents.map(renderSidebarEvent)}
+
+
+ );
+ };
+
+ return (
+ <>
+ <>
+ CalendarView | DesignSparx
+
+ >
+
+
+
+
+
+
+
+
+ >
+ );
+}
+
+export default Calendar;
diff --git a/app/dashboard/analytics/page.tsx b/app/dashboard/analytics/page.tsx
new file mode 100644
index 0000000..b7045ed
--- /dev/null
+++ b/app/dashboard/analytics/page.tsx
@@ -0,0 +1,122 @@
+'use client';
+
+import {
+ Container,
+ Grid,
+ PaperProps,
+ rem,
+ SimpleGrid,
+ Skeleton,
+ Stack,
+ useMantineTheme,
+} from '@mantine/core';
+import {
+ ErrorAlert,
+ LanguageTable,
+ MapChart,
+ MobileDesktopChart,
+ PageHeader,
+ SalesChart,
+ StatsCard,
+ TrafficTable,
+} from '@/components';
+import { useFetchData } from '@/hooks';
+
+const PRIMARY_COL_HEIGHT = rem(300);
+
+const PAPER_PROPS: PaperProps = {
+ p: 'md',
+ shadow: 'md',
+ radius: 'md',
+ style: { height: '100%' },
+};
+
+function Page() {
+ const theme = useMantineTheme();
+ const SECONDARY_COL_HEIGHT = `calc(${PRIMARY_COL_HEIGHT} / 2 - var(--mantine-spacing-md) / 2)`;
+ const {
+ data: statsData,
+ error: statsError,
+ loading: statsLoading,
+ } = useFetchData('/mocks/StatsGrid.json');
+ const {
+ data: languagesData,
+ error: languageError,
+ loading: languageLoading,
+ } = useFetchData('/mocks/Languages.json');
+ const {
+ data: trafficData,
+ error: trafficError,
+ loading: trafficLoading,
+ } = useFetchData('/mocks/Traffic.json');
+
+ return (
+ <>
+ <>
+ Analytics Dashboard | DesignSparx
+
+ >
+
+
+
+
+ {statsError ? (
+
+ ) : (
+
+ {statsLoading
+ ? Array.from({ length: 4 }).map((o, i) => (
+
+ ))
+ : statsData?.data?.map((s: any) => (
+
+ ))}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+}
+
+export default Page;
diff --git a/app/dashboard/default/page.tsx b/app/dashboard/default/page.tsx
new file mode 100644
index 0000000..5380e05
--- /dev/null
+++ b/app/dashboard/default/page.tsx
@@ -0,0 +1,102 @@
+'use client';
+
+import {
+ Button,
+ Container,
+ Grid,
+ Group,
+ Paper,
+ PaperProps,
+ Stack,
+ Text,
+} from '@mantine/core';
+import { IconChevronRight } from '@tabler/icons-react';
+import {
+ MobileDesktopChart,
+ PageHeader,
+ ProjectsTable,
+ RevenueChart,
+ SalesChart,
+ StatsGrid,
+} from '@/components';
+import Link from 'next/link';
+import { PATH_TASKS } from '@/routes';
+import { useFetchData } from '@/hooks';
+
+const PAPER_PROPS: PaperProps = {
+ p: 'md',
+ shadow: 'md',
+ radius: 'md',
+ style: { height: '100%' },
+};
+
+function Page() {
+ const {
+ data: projectsData,
+ error: projectsError,
+ loading: projectsLoading,
+ } = useFetchData('/mocks/Projects.json');
+ const {
+ data: statsData,
+ error: statsError,
+ loading: statsLoading,
+ } = useFetchData('/mocks/StatsGrid.json');
+
+ return (
+ <>
+ <>
+ Default Dashboard | DesignSparx
+
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Tasks
+
+ }
+ >
+ View all
+
+
+
+
+
+
+
+
+ >
+ );
+}
+
+export default Page;
diff --git a/app/dashboard/layout.tsx b/app/dashboard/layout.tsx
new file mode 100644
index 0000000..22dc793
--- /dev/null
+++ b/app/dashboard/layout.tsx
@@ -0,0 +1,69 @@
+'use client';
+
+import { AppShell, Container, rem, useMantineTheme } from '@mantine/core';
+import { ReactNode, useState } from 'react';
+import { useDisclosure, useMediaQuery } from '@mantine/hooks';
+import AppMain from '@/components/AppMain';
+import Navigation from '@/components/Navigation';
+import HeaderNav from '@/components/HeaderNav';
+import FooterNav from '@/components/FooterNav';
+
+type Props = {
+ children: ReactNode;
+};
+
+function CalendarLayout({ children }: Props) {
+ const theme = useMantineTheme();
+ const [opened, setOpened] = useState(false);
+ const [themeOpened, { open: themeOpen, close: themeClose }] =
+ useDisclosure(false);
+ const tablet_match = useMediaQuery('(max-width: 768px)');
+ const [mobileOpened, { toggle: toggleMobile }] = useDisclosure();
+ const [desktopOpened, { toggle: toggleDesktop }] = useDisclosure(true);
+
+ return (
+
+
+
+ setOpened((o) => !o)}
+ desktopOpened={desktopOpened}
+ mobileOpened={mobileOpened}
+ toggleDesktop={toggleDesktop}
+ toggleMobile={toggleMobile}
+ />
+
+
+
+ setOpened(false)} />
+
+
+ {children}
+
+
+
+
+
+
+
+ );
+}
+
+export default CalendarLayout;
diff --git a/app/dashboard/saas/page.tsx b/app/dashboard/saas/page.tsx
new file mode 100644
index 0000000..793f9cc
--- /dev/null
+++ b/app/dashboard/saas/page.tsx
@@ -0,0 +1,98 @@
+'use client';
+
+import {
+ Button,
+ Container,
+ Grid,
+ Group,
+ Paper,
+ PaperProps,
+ Stack,
+ Text,
+} from '@mantine/core';
+import { IconChevronRight } from '@tabler/icons-react';
+import {
+ MapChart,
+ PageHeader,
+ ProjectsTable,
+ RevenueChart,
+ SalesChart,
+ StatsGrid,
+} from '@/components';
+import { useFetchData } from '@/hooks';
+
+const PAPER_PROPS: PaperProps = {
+ p: 'md',
+ shadow: 'md',
+ radius: 'md',
+ style: { height: '100%' },
+};
+
+function Page() {
+ const {
+ data: statsData,
+ error: statsError,
+ loading: statsLoading,
+ } = useFetchData('/mocks/StatsGrid.json');
+ const {
+ data: projectsData,
+ error: projectsError,
+ loading: projectsLoading,
+ } = useFetchData('/mocks/Projects.json');
+
+ return (
+ <>
+ <>
+ Sass Dashboard | DesignSparx
+
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Tasks
+
+ }
+ >
+ View all
+
+
+
+
+
+
+
+
+ >
+ );
+}
+
+export default Page;
diff --git a/app/error.module.css b/app/error.module.css
new file mode 100644
index 0000000..ffb9a3f
--- /dev/null
+++ b/app/error.module.css
@@ -0,0 +1,30 @@
+.root {
+ padding: rem(80px) 0;
+}
+
+.label {
+ text-align: center;
+ font-weight: 900;
+ font-size: rem(220px);
+ line-height: 1;
+ color: light-dark(var(--mantine-color-black), var(--mantine-color-white));
+
+ @media (max-width: $mantine-breakpoint-sm) {
+ font-size: rem(120px);
+ }
+}
+
+.title {
+ text-align: center;
+ font-weight: 900;
+ font-size: rem(38px);
+
+ @media (max-width: $mantine-breakpoint-sm) {
+ font-size: rem(32px);
+ }
+}
+
+.description {
+ max-width: rem(500px);
+ margin: auto;
+}
diff --git a/app/error.tsx b/app/error.tsx
new file mode 100644
index 0000000..dbe640e
--- /dev/null
+++ b/app/error.tsx
@@ -0,0 +1,79 @@
+'use client';
+
+import { useEffect } from 'react';
+import {
+ Button,
+ Center,
+ Group,
+ Stack,
+ Text,
+ Title,
+ useMantineTheme,
+} from '@mantine/core';
+import { useRouter } from 'next/navigation';
+import { IconHome2, IconRefresh } from '@tabler/icons-react';
+import classes from './error.module.css';
+
+function Error({
+ error,
+ reset,
+}: {
+ error: Error & { digest?: string };
+ reset: () => void;
+}) {
+ const router = useRouter();
+ const theme = useMantineTheme();
+
+ useEffect(() => {
+ // Log the error to an error reporting service
+ console.error(error);
+ }, [error]);
+
+ return (
+ <>
+ <>
+ Server Error | DesignSparx
+
+ >
+
+
+ 400
+ Sorry, unexpected error..
+
+ {error.toString()}
+
+
+ }
+ variant="subtle"
+ onClick={() => window.location.reload}
+ >
+ Refresh Page
+
+ }
+ onClick={() => router.push('/')}
+ >
+ Take me to home page
+
+
+
+
+ >
+ );
+}
+
+export default Error;
diff --git a/app/favicon.ico b/app/favicon.ico
new file mode 100644
index 0000000..718d6fe
Binary files /dev/null and b/app/favicon.ico differ
diff --git a/app/globals.css b/app/globals.css
new file mode 100644
index 0000000..7ca559b
--- /dev/null
+++ b/app/globals.css
@@ -0,0 +1,5 @@
+@import url('https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;0,800;1,300;1,400;1,500;1,600;1,700;1,800&display=swap');
+
+html,
+body {
+}
diff --git a/app/invoices/details/[id]/page.tsx b/app/invoices/details/[id]/page.tsx
new file mode 100644
index 0000000..bc6c4a0
--- /dev/null
+++ b/app/invoices/details/[id]/page.tsx
@@ -0,0 +1,63 @@
+'use client';
+
+import { useEffect, useState } from 'react';
+import { Anchor, Container, PaperProps, Stack } from '@mantine/core';
+import { InvoiceDetailsCard, PageHeader } from '@/components';
+import { PATH_DASHBOARD, PATH_INVOICES } from '@/routes';
+import { Invoices } from '@/types';
+import { useFetchData } from '@/hooks';
+
+const items = [
+ { title: 'Dashboard', href: PATH_DASHBOARD.default },
+ { title: 'Invoices', href: PATH_INVOICES.invoices.all },
+ { title: 'Details', href: '#' },
+].map((item, index) => (
+
+ {item.title}
+
+));
+
+const PAPER_PROPS: PaperProps = {
+ p: 'md',
+ shadow: 'md',
+ radius: 'md',
+};
+
+function InvoiceDetails({ params }: { params: { id: string } }) {
+ const [selectedData, setSelectedData] = useState();
+ const {
+ data: invoicesData,
+ loading: invoicesLoading,
+ error: invoicesError,
+ } = useFetchData('mocks/Invoices.json');
+
+ useEffect(() => {
+ setSelectedData(invoicesData.find((_: Invoices) => _.id === params.id));
+ }, [invoicesData, params]);
+
+ return (
+ <>
+ <>
+
+ Invoice - {selectedData ? selectedData?.id : 'No invoice found'} |
+ DesignSparx
+
+
+ >
+
+
+
+
+
+
+ >
+ );
+}
+
+export default InvoiceDetails;
diff --git a/app/invoices/details/page.tsx b/app/invoices/details/page.tsx
new file mode 100644
index 0000000..f936410
--- /dev/null
+++ b/app/invoices/details/page.tsx
@@ -0,0 +1,71 @@
+'use client';
+
+import { Anchor, Container, PaperProps, Stack } from '@mantine/core';
+import { InvoiceDetailsCard, PageHeader } from '@/components';
+import { PATH_DASHBOARD, PATH_INVOICES } from '@/routes';
+import { Metadata } from 'next';
+
+const items = [
+ { title: 'Dashboard', href: PATH_DASHBOARD.default },
+ { title: 'Invoices', href: PATH_INVOICES.invoices.all },
+ { title: 'Details', href: '#' },
+].map((item, index) => (
+
+ {item.title}
+
+));
+
+const sampleData = {
+ id: '8677a3e2-dde3-4d04-8edd-9d0bcf178f89',
+ full_name: 'Dannie MacTrustie',
+ email: 'atysack2r@washingtonpost.com',
+ address: '5160 Iowa Point',
+ country: 'China',
+ status: 'approved',
+ amount: 6221.88,
+ issue_date: '7/12/2022',
+ description:
+ 'In quis justo. Maecenas rhoncus aliquam lacus. Morbi quis tortor id nulla ultrices aliquet.\n\nMaecenas leo odio, condimentum id, luctus nec, molestie sed, justo. Pellentesque viverra pede ac diam. Cras pellentesque volutpat dui.\n\nMaecenas tristique, est et tempus semper, est quam pharetra magna, ac consequat metus sapien ut nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris viverra diam vitae quam. Suspendisse potenti.\n\nNullam porttitor lacus at turpis. Donec posuere metus vitae ipsum. Aliquam non mauris.\n\nMorbi non lectus. Aliquam sit amet diam in magna bibendum imperdiet. Nullam orci pede, venenatis non, sodales sed, tincidunt eu, felis.',
+ client_email: 'atysack2r@illinois.edu',
+ client_address: '13 Loeprich Point',
+ client_country: 'Russia',
+ client_name: 'Alayne Tysack',
+ client_company: 'Raynor and Sons',
+};
+
+const PAPER_PROPS: PaperProps = {
+ p: 'md',
+ shadow: 'md',
+ radius: 'md',
+};
+
+const metadata: Metadata = {
+ title: 'Sample Invoice | DesignSparx',
+ description:
+ 'Explore our versatile dashboard website template featuring a stunning array of themes and meticulously crafted components. Elevate your web project with seamless integration, customizable themes, and a rich variety of components for a dynamic user experience. Effortlessly bring your data to life with our intuitive dashboard template, designed to streamline development and captivate users. Discover endless possibilities in design and functionality today!',
+};
+
+function SampleInvoiceDetails() {
+ return (
+ <>
+ <>
+ Sample Invoice Details | DesignSparx
+
+ >
+
+
+
+
+
+
+ >
+ );
+}
+
+export default SampleInvoiceDetails;
diff --git a/app/invoices/layout.tsx b/app/invoices/layout.tsx
new file mode 100644
index 0000000..22dc793
--- /dev/null
+++ b/app/invoices/layout.tsx
@@ -0,0 +1,69 @@
+'use client';
+
+import { AppShell, Container, rem, useMantineTheme } from '@mantine/core';
+import { ReactNode, useState } from 'react';
+import { useDisclosure, useMediaQuery } from '@mantine/hooks';
+import AppMain from '@/components/AppMain';
+import Navigation from '@/components/Navigation';
+import HeaderNav from '@/components/HeaderNav';
+import FooterNav from '@/components/FooterNav';
+
+type Props = {
+ children: ReactNode;
+};
+
+function CalendarLayout({ children }: Props) {
+ const theme = useMantineTheme();
+ const [opened, setOpened] = useState(false);
+ const [themeOpened, { open: themeOpen, close: themeClose }] =
+ useDisclosure(false);
+ const tablet_match = useMediaQuery('(max-width: 768px)');
+ const [mobileOpened, { toggle: toggleMobile }] = useDisclosure();
+ const [desktopOpened, { toggle: toggleDesktop }] = useDisclosure(true);
+
+ return (
+
+
+
+ setOpened((o) => !o)}
+ desktopOpened={desktopOpened}
+ mobileOpened={mobileOpened}
+ toggleDesktop={toggleDesktop}
+ toggleMobile={toggleMobile}
+ />
+
+
+
+ setOpened(false)} />
+
+
+ {children}
+
+
+
+
+
+
+
+ );
+}
+
+export default CalendarLayout;
diff --git a/app/invoices/list/page.tsx b/app/invoices/list/page.tsx
new file mode 100644
index 0000000..9ec7749
--- /dev/null
+++ b/app/invoices/list/page.tsx
@@ -0,0 +1,79 @@
+'use client';
+
+import {
+ ActionIcon,
+ Anchor,
+ Container,
+ Group,
+ Paper,
+ PaperProps,
+ Stack,
+ Text,
+} from '@mantine/core';
+import { PATH_DASHBOARD } from '@/routes';
+import { InvoicesTable, PageHeader } from '@/components';
+import InvoicesData from '@/public/mocks/Invoices.json';
+import { IconDotsVertical } from '@tabler/icons-react';
+import { Metadata } from 'next';
+import { useFetchData } from '@/hooks';
+
+const items = [
+ { title: 'Dashboard', href: PATH_DASHBOARD.default },
+ { title: 'Invoices', href: '#' },
+].map((item, index) => (
+
+ {item.title}
+
+));
+
+const PAPER_PROPS: PaperProps = {
+ p: 'md',
+ shadow: 'md',
+ radius: 'md',
+};
+
+function Page() {
+ const {
+ data: invoicesData,
+ loading: invoicesLoading,
+ error: invoicesError,
+ } = useFetchData('/mocks/Invoices.json');
+
+ return (
+ <>
+ <>
+ Invoices | DesignSparx
+
+ >
+
+
+
+
+
+
+ Invoices
+
+
+
+
+
+
+
+
+
+ >
+ );
+}
+
+export default Page;
diff --git a/app/layout.tsx b/app/layout.tsx
new file mode 100644
index 0000000..66d7ad2
--- /dev/null
+++ b/app/layout.tsx
@@ -0,0 +1,66 @@
+'use client';
+
+import { ColorSchemeScript, MantineProvider } from '@mantine/core';
+import { ModalsProvider } from '@mantine/modals';
+import { Notifications } from '@mantine/notifications';
+import { Open_Sans } from 'next/font/google';
+import { myTheme } from '@/theme';
+import '@mantine/core/styles.css';
+import '@mantine/dates/styles.css';
+import '@mantine/tiptap/styles.css';
+import '@mantine/carousel/styles.css';
+import '@mantine/notifications/styles.css';
+import 'mantine-datatable/styles.layer.css';
+import './globals.css';
+
+// If loading a variable font, you don't need to specify the font weight
+const openSans = Open_Sans({
+ subsets: ['latin'],
+ display: 'swap',
+});
+export default function RootLayout({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ return (
+
+
+ DesignSparx - Nextjs Mantine Admin Dashboard Template
+
+
+
+
+
+
+
+
+
+
+
+ {children}
+
+
+
+ );
+}
diff --git a/app/lib/auth.ts b/app/lib/auth.ts
new file mode 100644
index 0000000..4ce2af6
--- /dev/null
+++ b/app/lib/auth.ts
@@ -0,0 +1,21 @@
+import Auth0 from 'next-auth/providers/auth0';
+import { NextAuthOptions } from 'next-auth';
+
+const {
+ AUTH0_CLIENT_ID = '',
+ AUTH0_CLIENT_SECRET = '',
+ AUTH0_DOMAIN = '',
+ AUTH0_NEXT_SECRET = '',
+ AUTH0_ISSUER_BASE_URL = '',
+} = process.env;
+
+export const authOptions: NextAuthOptions = {
+ secret: AUTH0_NEXT_SECRET,
+ providers: [
+ Auth0({
+ clientId: AUTH0_CLIENT_ID,
+ clientSecret: AUTH0_CLIENT_SECRET,
+ issuer: AUTH0_ISSUER_BASE_URL,
+ }),
+ ],
+};
diff --git a/app/loading.tsx b/app/loading.tsx
new file mode 100644
index 0000000..b8c1c51
--- /dev/null
+++ b/app/loading.tsx
@@ -0,0 +1,12 @@
+import { Center, Loader, Text, Stack } from '@mantine/core';
+
+export default function Loading() {
+ return (
+
+
+
+ Hang in there...
+
+
+ );
+}
diff --git a/app/not-found.tsx b/app/not-found.tsx
new file mode 100644
index 0000000..f226121
--- /dev/null
+++ b/app/not-found.tsx
@@ -0,0 +1,75 @@
+'use client';
+
+import {
+ Button,
+ Center,
+ Group,
+ Stack,
+ Text,
+ Title,
+ useMantineTheme,
+} from '@mantine/core';
+import Link from 'next/link';
+import { PATH_DASHBOARD } from '@/routes';
+import { IconChevronLeft, IconHome2 } from '@tabler/icons-react';
+import { useRouter } from 'next/navigation';
+import classes from './error.module.css';
+
+function Error404() {
+ const router = useRouter();
+ const theme = useMantineTheme();
+
+ return (
+ <>
+ <>
+ Page Not Found | DesignSparx
+
+ >
+
+
+ 404
+
+ You have found a secret place.
+
+
+ Unfortunately, this is only a 404 page. You may have mistyped the
+ address, or the page has been moved to another URL.
+
+
+ }
+ onClick={() => {
+ router.back();
+ }}
+ >
+ Go back
+
+ }
+ href={PATH_DASHBOARD.default}
+ >
+ Take me to home page
+
+
+
+
+ >
+ );
+}
+
+export default Error404;
diff --git a/app/orders/layout.tsx b/app/orders/layout.tsx
new file mode 100644
index 0000000..22dc793
--- /dev/null
+++ b/app/orders/layout.tsx
@@ -0,0 +1,69 @@
+'use client';
+
+import { AppShell, Container, rem, useMantineTheme } from '@mantine/core';
+import { ReactNode, useState } from 'react';
+import { useDisclosure, useMediaQuery } from '@mantine/hooks';
+import AppMain from '@/components/AppMain';
+import Navigation from '@/components/Navigation';
+import HeaderNav from '@/components/HeaderNav';
+import FooterNav from '@/components/FooterNav';
+
+type Props = {
+ children: ReactNode;
+};
+
+function CalendarLayout({ children }: Props) {
+ const theme = useMantineTheme();
+ const [opened, setOpened] = useState(false);
+ const [themeOpened, { open: themeOpen, close: themeClose }] =
+ useDisclosure(false);
+ const tablet_match = useMediaQuery('(max-width: 768px)');
+ const [mobileOpened, { toggle: toggleMobile }] = useDisclosure();
+ const [desktopOpened, { toggle: toggleDesktop }] = useDisclosure(true);
+
+ return (
+
+
+
+ setOpened((o) => !o)}
+ desktopOpened={desktopOpened}
+ mobileOpened={mobileOpened}
+ toggleDesktop={toggleDesktop}
+ toggleMobile={toggleMobile}
+ />
+
+
+
+ setOpened(false)} />
+
+
+ {children}
+
+
+
+
+
+
+
+ );
+}
+
+export default CalendarLayout;
diff --git a/app/orders/page.tsx b/app/orders/page.tsx
new file mode 100644
index 0000000..dfd0d3a
--- /dev/null
+++ b/app/orders/page.tsx
@@ -0,0 +1,73 @@
+'use client';
+
+import {
+ ActionIcon,
+ Anchor,
+ Container,
+ Group,
+ Paper,
+ PaperProps,
+ Stack,
+ Text,
+} from '@mantine/core';
+import { PATH_DASHBOARD } from '@/routes';
+import { OrdersTable, PageHeader } from '@/components';
+import { IconDotsVertical } from '@tabler/icons-react';
+import { useFetchData } from '@/hooks';
+
+const items = [
+ { title: 'Dashboard', href: PATH_DASHBOARD.default },
+ { title: 'Orders', href: '#' },
+].map((item, index) => (
+
+ {item.title}
+
+));
+
+const PAPER_PROPS: PaperProps = {
+ p: 'md',
+ shadow: 'md',
+ radius: 'md',
+};
+
+function Page() {
+ const {
+ data: ordersData,
+ loading: ordersLoading,
+ error: ordersError,
+ } = useFetchData('/mocks/Orders.json');
+
+ return (
+ <>
+ <>
+ Orders | DesignSparx
+
+ >
+
+
+
+
+
+
+ Orders
+
+
+
+
+
+
+
+
+
+ >
+ );
+}
+
+export default Page;
diff --git a/app/page.module.css b/app/page.module.css
new file mode 100644
index 0000000..3b6b4df
--- /dev/null
+++ b/app/page.module.css
@@ -0,0 +1,70 @@
+.hero {
+ background-color: var(--mantine-color-black);
+ color: var(--mantine-color-white);
+ padding: calc(var(--mantine-spacing-xl) * 4);
+
+ @media (max-width: $mantine-breakpoint-sm) {
+ padding-top: var(--mantine-spacing-xl);
+ }
+}
+
+.title {
+ font-weight: 800;
+ font-size: rem(40);
+ letter-spacing: rem(-1);
+ margin-bottom: var(--mantine-spacing-xs);
+
+ @media (max-width: $mantine-breakpoint-sm) {
+ font-size: rem(28);
+ text-align: left;
+ }
+}
+
+.highlight {
+ color: var(--mantine-primary-color-filled);
+}
+
+.stackControl {
+ text-transform: capitalize;
+ background-color: var(--mantine-color-dark-6);
+ color: var(--mantine-color-white);
+ padding: rem(6) rem(10);
+ border-radius: var(--mantine-radius-md);
+}
+
+.variantImg {
+ max-height: rem(280);
+ width: 100%;
+ object-fit: contain;
+}
+
+.variantTitle {
+ text-align: center;
+ margin-top: var(--mantine-spacing-md);
+ font-weight: 600;
+}
+
+.paper {
+ height: 100%;
+ background-color: transparent;
+}
+
+.image {
+ height: 100%;
+ background-color: transparent;
+
+ @mixin hover {
+ box-shadow: var(--mantine-shadow-lg);
+ transition: all ease 150ms;
+ transform: scale(1.03);
+ }
+}
+
+.statsTitle {
+ color: var(--mantine-primary-color-filled);
+}
+
+.contactPaper {
+ background-color: transparent;
+ text-align: center;
+}
diff --git a/app/page.tsx b/app/page.tsx
new file mode 100644
index 0000000..9619517
--- /dev/null
+++ b/app/page.tsx
@@ -0,0 +1,381 @@
+'use client';
+
+import {
+ Badge,
+ Box,
+ BoxProps,
+ Button,
+ Center,
+ Container,
+ Flex,
+ Grid,
+ Group,
+ Image,
+ Paper,
+ PaperProps,
+ SimpleGrid,
+ Spoiler,
+ Stack,
+ Text,
+ ThemeIcon,
+ ThemeIconProps,
+ Title,
+ Tooltip,
+ UnstyledButton,
+} from '@mantine/core';
+import Link from 'next/link';
+import { PATH_DASHBOARD, PATH_DOCS } from '@/routes';
+import {
+ IconAdjustmentsHorizontal,
+ IconArrowRight,
+ IconBook,
+ IconColorSwatch,
+ IconDevices,
+ IconFolderCode,
+ IconScaleOutline,
+ IconSettingsCog,
+} from '@tabler/icons-react';
+import CountUp from 'react-countup';
+import { useMediaQuery } from '@mantine/hooks';
+import GuestLayout from '@/layout/Guest';
+import classes from './page.module.css';
+
+const TECH_STACK = [
+ { title: 'nextjs', version: '14.0.2', href: 'https://nextjs.org/' },
+ { title: 'react', version: '18.2.0', href: 'https://react.dev/' },
+ {
+ title: 'typescript',
+ version: '5.1.6',
+ href: 'https://www.typescriptlang.org/',
+ },
+ { title: 'mantine', version: '7.2.2', href: 'https://mantine.dev/' },
+ {
+ title: 'tabler icons',
+ version: '2.40.0',
+ href: 'https://tabler-icons.io/',
+ },
+ { title: 'tiptap', version: '2.1.12', href: 'https://tiptap.dev/' },
+ { title: 'apexcharts', version: '3.44.0', href: 'https://apexcharts.com/' },
+ { title: 'dayjs', version: '1.11.10', href: 'https://day.js.org/' },
+ { title: 'fullcalendar', version: '6.1.8', href: 'https://fullcalendar.io/' },
+ {
+ title: 'emotion',
+ version: '11.11.1',
+ href: 'https://emotion.sh/docs/introduction',
+ },
+ { title: 'dnd-kit', version: '6.0.8', href: 'https://dndkit.com/' },
+ {
+ title: 'embla-carousel',
+ version: '8.0.0',
+ href: 'https://www.embla-carousel.com/',
+ },
+ {
+ title: 'mantine datatable',
+ version: '7.1.7',
+ href: 'https://icflorescu.github.io/mantine-datatable',
+ },
+ { title: 'lodash', version: '4.17.21', href: 'https://lodash.com/' },
+ {
+ title: 'react simple maps',
+ version: '3.0.0',
+ href: 'https://www.react-simple-maps.io/',
+ },
+];
+
+const PAPER_PROPS: PaperProps = {
+ p: 'md',
+ shadow: 'md',
+ radius: 'md',
+ className: classes.paper,
+};
+
+const THEME_ICON_PROPS: Omit = {
+ variant: 'light',
+ size: 48,
+};
+
+const IMAGE_PAPER_PROPS: PaperProps = {
+ p: 'md',
+ className: classes.image,
+};
+
+export default function Home() {
+ const tablet_match = useMediaQuery('(max-width: 768px)');
+
+ const BOX_PROPS: BoxProps = {
+ mt: 120,
+ pb: 80,
+ px: tablet_match ? 20 : 48,
+ };
+
+ return (
+ <>
+ <>
+ DesignSparx | Website UI Kit
+
+
+
+ >
+
+
+
+
+
+ Build like a Pro
+
+ The simplest and fastest way to build your next{' '}
+
+ Mantine UI{' '}
+
+ &{' '}
+
+ Nextjs{' '}
+
+ dashboard or app.
+
+
+ This template comes with hundreds of UI elements, forms,
+ tables, charts, pages and icons that helps you to create your
+ web apps or applications faster.
+
+
+ }
+ >
+ Live Preview
+
+
+ Read Documentation
+
+
+
+ Tech Stack:
+
+
+ {TECH_STACK.map((t) => (
+
+
+ {t.title}
+
+
+ ))}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Carefully crafted components ready to use in your project
+
+
+
+
+
+ +
+
+ Beautifully coded page examples
+
+
+
+
+
+ +
+
+ Components and widgets
+
+
+
+
+
+ Optimized to work for most devices
+
+
+
+
+
+ Customize it to meet your brand's identity
+
+
+
+
+
+
+
+ Default variant
+
+
+
+ Pink variant
+
+
+
+ Orange variant
+
+
+
+ Green variant
+
+
+
+ Purple variant
+
+
+
+ Dark variant
+
+
+
+
+
+
+ Key features
+
+
+ Quick helps you build beautiful websites that stand out and
+ automatically adapt to your style.
+
+
+
+
+
+
+
+ Modular
+
+
+ All components are built to be used in any combination.
+
+
+
+
+
+
+
+ Responsive
+
+
+ Quick is optimized to work for most devices.
+
+
+
+
+
+
+
+ Scalable
+
+
+ Remain consistent while developing new features.
+
+
+
+
+
+
+
+ Customizable
+
+
+ Change a few variables and the whole theme adapts.
+
+
+
+
+ }
+ >
+ Read Documentation
+
+
+
+
+
+
+
+ For any queries?
+
+ }
+ >
+ Contact Us
+
+
+
+
+ >
+ );
+}
diff --git a/app/pages/blank/page.tsx b/app/pages/blank/page.tsx
new file mode 100644
index 0000000..9884139
--- /dev/null
+++ b/app/pages/blank/page.tsx
@@ -0,0 +1,56 @@
+'use client';
+
+import {
+ Anchor,
+ Container,
+ Paper,
+ PaperProps,
+ Stack,
+ Text,
+} from '@mantine/core';
+import { PATH_DASHBOARD } from '@/routes';
+import { PageHeader, Surface } from '@/components';
+import { Metadata } from 'next';
+
+const items = [
+ { title: 'Dashboard', href: PATH_DASHBOARD.default },
+ { title: 'Pages', href: '#' },
+ { title: 'Blank', href: '#' },
+].map((item, index) => (
+
+ {item.title}
+
+));
+
+const PAPER_PROPS: PaperProps = {
+ p: 'md',
+ shadow: 'md',
+ radius: 'md',
+};
+
+function Pricing() {
+ return (
+ <>
+ <>
+ Blank page | DesignSparx
+
+ >
+
+
+
+
+
+ Empty card header
+
+ Empty card text
+
+
+
+ >
+ );
+}
+
+export default Pricing;
diff --git a/app/pages/chat/page.module.css b/app/pages/chat/page.module.css
new file mode 100644
index 0000000..4353503
--- /dev/null
+++ b/app/pages/chat/page.module.css
@@ -0,0 +1,54 @@
+.chatItems {
+ @mixin light {
+ background-color: var(--mantine-color-gray-1);
+ border-left: rem(1px) solid var(--mantine-color-gray-3);
+ }
+
+ @mixin dark {
+ background-color: var(--mantine-color-dark-6);
+ border-left: rem(1px) solid var(--mantine-color-gray-7);
+ }
+
+ @media (max-width: $mantine-breakpoint-md) {
+ @mixin light {
+ border-left: rem(1px) solid var(--mantine-color-gray-3);
+ }
+
+ @mixin dark {
+ border-left: rem(1px) solid var(--mantine-color-gray-7);
+ }
+ }
+}
+
+.chatHeader {
+ padding: var(--mantine-spacing-sm) var(--mantine-spacing-md);
+ border-top-right-radius: var(--mantine-radius-default);
+ border-bottom: 1px solid
+ light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-0));
+
+ @mixin light {
+ background-color: var(--mantine-color-white);
+ border-bottom: rem(1px) solid var(--mantine-color-gray-3);
+ }
+
+ @mixin dark {
+ background-color: var(--mantine-color-black);
+ border-bottom: rem(1px) solid var(--mantine-color-gray-7);
+ }
+}
+
+.user {
+ border-radius: var(--mantine-radius-default);
+}
+
+.replyBox {
+ padding: var(--mantine-spacing-sm);
+
+ @mixin light {
+ background-color: var(--mantine-color-white);
+ }
+
+ @mixin dark {
+ background-color: var(--mantine-color-black);
+ }
+}
diff --git a/app/pages/chat/page.tsx b/app/pages/chat/page.tsx
new file mode 100644
index 0000000..84e36f4
--- /dev/null
+++ b/app/pages/chat/page.tsx
@@ -0,0 +1,281 @@
+'use client';
+
+import {
+ ActionIcon,
+ Anchor,
+ Box,
+ Container,
+ Divider,
+ Flex,
+ Grid,
+ Paper,
+ PaperProps,
+ rem,
+ ScrollArea,
+ Skeleton,
+ Stack,
+ TextInput,
+ Tooltip,
+ useMantineTheme,
+} from '@mantine/core';
+import { Link, RichTextEditor } from '@mantine/tiptap';
+import { BubbleMenu, useEditor } from '@tiptap/react';
+import StarterKit from '@tiptap/starter-kit';
+import Placeholder from '@tiptap/extension-placeholder';
+import { PATH_DASHBOARD } from '@/routes';
+import {
+ ChatItem,
+ ChatsList,
+ ErrorAlert,
+ PageHeader,
+ Surface,
+ UserButton,
+} from '@/components';
+import { IconDotsVertical, IconSearch, IconSend } from '@tabler/icons-react';
+import { useColorScheme, useMediaQuery } from '@mantine/hooks';
+import { Carousel } from '@mantine/carousel';
+import ChatsListData from '@/public/mocks/ChatsList.json';
+import ChatItemsData from '@/public/mocks/ChatItems.json';
+import UserProfileData from '@/public/mocks/UserProfile.json';
+import { useFetchData } from '@/hooks';
+
+import classes from './page.module.css';
+
+const items = [
+ { title: 'Dashboard', href: PATH_DASHBOARD.default },
+ { title: 'Pages', href: '#' },
+ { title: 'Chat', href: '#' },
+].map((item, index) => (
+
+ {item.title}
+
+));
+
+const ICON_SIZE = 16;
+
+const PAPER_PROPS: PaperProps = {
+ shadow: 'md',
+ radius: 'md',
+};
+
+function Chat() {
+ const theme = useMantineTheme();
+ const colorScheme = useColorScheme();
+ const tablet_match = useMediaQuery('(max-width: 768px)');
+ const editor = useEditor({
+ extensions: [
+ StarterKit,
+ Link,
+ Placeholder.configure({ placeholder: 'Type your message' }),
+ ],
+ content: 'Select some text to see a bubble menu
',
+ });
+ const {
+ data: chatsListData,
+ loading: chatsListLoading,
+ error: chatsListError,
+ } = useFetchData('/mocks/ChatsList.json');
+ const {
+ data: chatItemsData,
+ loading: chatsItemsLoading,
+ error: chatsItemsError,
+ } = useFetchData('/mocks/ChatItems.json');
+
+ return (
+ <>
+ <>
+ Chat | DesignSparx
+
+ >
+
+
+
+
+
+
+
+
+ }
+ />
+
+ {tablet_match ? (
+ <>
+
+ {chatsListLoading ? (
+ Array.from({ length: 6 }).map((o, i) => (
+
+
+
+ ))
+ ) : chatsListError ? (
+
+ ) : (
+ chatsListData.length > 0 &&
+ chatsListData.map((c: any) => (
+
+
+
+ ))
+ )}
+
+
+ >
+ ) : (
+
+ {chatsListLoading ? (
+ Array.from({ length: 6 }).map((o, i) => (
+
+
+
+
+ ))
+ ) : chatsListError ? (
+
+ ) : (
+ chatsListData.length > 0 &&
+ chatsListData.map((c: any) => (
+
+ ))
+ )}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {chatsItemsError ? (
+
+ ) : (
+ chatItemsData.length > 0 &&
+ chatItemsData.map((c: any) => (
+
+ ))
+ )}
+
+
+
+
+
+
+
+ {editor && (
+
+
+
+
+
+
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+}
+
+export default Chat;
diff --git a/app/pages/layout.tsx b/app/pages/layout.tsx
new file mode 100644
index 0000000..22dc793
--- /dev/null
+++ b/app/pages/layout.tsx
@@ -0,0 +1,69 @@
+'use client';
+
+import { AppShell, Container, rem, useMantineTheme } from '@mantine/core';
+import { ReactNode, useState } from 'react';
+import { useDisclosure, useMediaQuery } from '@mantine/hooks';
+import AppMain from '@/components/AppMain';
+import Navigation from '@/components/Navigation';
+import HeaderNav from '@/components/HeaderNav';
+import FooterNav from '@/components/FooterNav';
+
+type Props = {
+ children: ReactNode;
+};
+
+function CalendarLayout({ children }: Props) {
+ const theme = useMantineTheme();
+ const [opened, setOpened] = useState(false);
+ const [themeOpened, { open: themeOpen, close: themeClose }] =
+ useDisclosure(false);
+ const tablet_match = useMediaQuery('(max-width: 768px)');
+ const [mobileOpened, { toggle: toggleMobile }] = useDisclosure();
+ const [desktopOpened, { toggle: toggleDesktop }] = useDisclosure(true);
+
+ return (
+
+
+
+ setOpened((o) => !o)}
+ desktopOpened={desktopOpened}
+ mobileOpened={mobileOpened}
+ toggleDesktop={toggleDesktop}
+ toggleMobile={toggleMobile}
+ />
+
+
+
+ setOpened(false)} />
+
+
+ {children}
+
+
+
+
+
+
+
+ );
+}
+
+export default CalendarLayout;
diff --git a/app/pages/pricing/page.tsx b/app/pages/pricing/page.tsx
new file mode 100644
index 0000000..227f0b9
--- /dev/null
+++ b/app/pages/pricing/page.tsx
@@ -0,0 +1,161 @@
+'use client';
+
+import React, { useState } from 'react';
+import {
+ Anchor,
+ Button,
+ Container,
+ Flex,
+ Paper,
+ PaperProps,
+ SimpleGrid,
+ Stack,
+ Switch,
+ Text,
+ Title,
+} from '@mantine/core';
+import { PATH_DASHBOARD } from '@/routes';
+import { Faqs, PageHeader, PricingCard, Surface } from '@/components';
+import { IconChevronRight } from '@tabler/icons-react';
+import { Metadata } from 'next';
+
+const items = [
+ { title: 'Dashboard', href: PATH_DASHBOARD.default },
+ { title: 'Pages', href: '#' },
+ { title: 'Pricing', href: '#' },
+].map((item, index) => (
+
+ {item.title}
+
+));
+
+const ICON_SIZE = 16;
+
+const PAPER_PROPS: PaperProps = {
+ p: 'md',
+ shadow: 'md',
+ radius: 'md',
+ style: { height: '100%' },
+};
+
+const PRICING = [
+ {
+ tier: 'basic',
+ price: {
+ month: 0,
+ year: 0,
+ },
+ features: ['Rich landing pages', '100+ components'],
+ preferred: false,
+ actionText: 'start for free',
+ description: 'All the basics for starting a new business',
+ },
+ {
+ tier: 'standard',
+ price: {
+ month: 25,
+ year: 45,
+ },
+ features: [
+ 'Rich landing pages',
+ '100+ components',
+ 'Flexible licensing',
+ 'Speedy build tooling',
+ '6 months free support',
+ ],
+ preferred: true,
+ actionText: 'start with standard',
+ description: 'Everything you need for a growing business',
+ },
+ {
+ tier: 'premium',
+ price: {
+ month: 40,
+ year: 70,
+ },
+ features: [
+ 'Rich landing pages',
+ '100+ components',
+ 'Flexible licensing',
+ 'Speedy build tooling',
+ '6 months free support',
+ '256-bit encryption',
+ 'Guaranteed 100% uptime',
+ 'Unlimited users',
+ ],
+ preferred: false,
+ actionText: 'start with premium',
+ description: 'Advanced features for scaling your business',
+ },
+];
+
+function Pricing() {
+ const [checked, setChecked] = useState(false);
+ const pricingItems = PRICING.map((p) => (
+
+ ));
+
+ return (
+ <>
+ <>
+ Pricing | DesignSparx
+
+ >
+
+
+
+
+
+
+ Simple, fair pricing.
+
+
+ All types of businesses need access to development resources, so
+ we give you the option to decide how much you need to use.
+
+
+ Annual
+ setChecked(event.currentTarget.checked)}
+ />
+ Monthly
+
+
+
+
+ {pricingItems}
+
+
+
+
+
+
+ Still have questions?
+ }
+ >
+ Contact Us
+
+
+
+
+
+ >
+ );
+}
+
+export default Pricing;
diff --git a/app/pages/profile/page.module.css b/app/pages/profile/page.module.css
new file mode 100644
index 0000000..ca91520
--- /dev/null
+++ b/app/pages/profile/page.module.css
@@ -0,0 +1,11 @@
+.socialLink {
+ border-radius: var(--mantine-radius-default);
+ padding: rem(6px) rem(8px);
+
+ @mixin hover {
+ transition: all ease 150ms;
+ background-color: var(--mantine-color-gray-3);
+ color: var(--mantine-color-black);
+ text-decoration: none;
+ }
+}
diff --git a/app/pages/profile/page.tsx b/app/pages/profile/page.tsx
new file mode 100644
index 0000000..1662a45
--- /dev/null
+++ b/app/pages/profile/page.tsx
@@ -0,0 +1,239 @@
+'use client';
+
+import {
+ ActionIcon,
+ Anchor,
+ Badge,
+ Container,
+ Flex,
+ Grid,
+ Group,
+ Paper,
+ PaperProps,
+ SimpleGrid,
+ Stack,
+ Text,
+ UnstyledButton,
+ useMantineTheme,
+} from '@mantine/core';
+import { PATH_DASHBOARD } from '@/routes';
+import {
+ PageHeader,
+ ProfileStatsCard,
+ ProjectsTable,
+ RevenueChart,
+ Surface,
+ UserProfileCard,
+} from '@/components';
+import {
+ IconBrandFacebook,
+ IconBrandGithub,
+ IconBrandLinkedin,
+ IconBrandTwitter,
+ IconBusinessplan,
+ IconCoins,
+ IconDotsVertical,
+ IconHome,
+ IconListCheck,
+ IconMapPinFilled,
+} from '@tabler/icons-react';
+import UserData from '@/public/mocks/UserProfile.json';
+import classes from './page.module.css';
+import { useFetchData } from '@/hooks';
+
+const items = [
+ { title: 'Dashboard', href: PATH_DASHBOARD.default },
+ { title: 'Pages', href: '#' },
+ { title: 'Profile', href: '#' },
+].map((item, index) => (
+
+ {item.title}
+
+));
+
+const ICON_SIZE = 16;
+
+const skills = [
+ 'React',
+ 'Mantine',
+ 'Figma',
+ 'Bootstrap',
+ 'Typescript',
+ 'Sass/SCSS',
+];
+
+const PAPER_PROPS: PaperProps = {
+ p: 'md',
+ shadow: 'md',
+ radius: 'md',
+ style: { height: '100%' },
+};
+
+function Profile() {
+ const theme = useMantineTheme();
+ const {
+ data: projectsData,
+ loading: projectsLoading,
+ error: projectsError,
+ } = useFetchData('/mocks/Projects.json');
+ const linkProps = {
+ target: '_blank',
+ className: classes.socialLink,
+ };
+
+ return (
+ <>
+ <>
+ Profile | DesignSparx
+
+ >
+
+
+
+
+
+
+
+
+
+ Skills
+
+
+ {skills.map((s) => (
+
+ {s}
+
+ ))}
+
+
+
+
+
+ About
+
+
+
+ Lives in Nairobi, Kenya
+
+
+
+ Works at Company ABC
+
+
+
+
+
+
+ Social
+
+
+
+
+ Facebook
+
+
+
+
+
+ Twitter
+
+
+
+
+
+ LinkedIn
+
+
+
+
+
+ Github
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Projects
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+}
+
+export default Profile;
diff --git a/app/pages/settings/page.tsx b/app/pages/settings/page.tsx
new file mode 100644
index 0000000..be25221
--- /dev/null
+++ b/app/pages/settings/page.tsx
@@ -0,0 +1,197 @@
+'use client';
+
+import React, { useState } from 'react';
+import {
+ Anchor,
+ Box,
+ Button,
+ Container,
+ FileButton,
+ Grid,
+ Group,
+ Image,
+ Paper,
+ PaperProps,
+ Stack,
+ Text,
+ TextInput,
+} from '@mantine/core';
+import { PATH_DASHBOARD } from '@/routes';
+import { useForm } from '@mantine/form';
+import { IconCloudUpload, IconDeviceFloppy } from '@tabler/icons-react';
+import { PageHeader, Surface, TextEditor } from '@/components';
+import { Metadata } from 'next';
+
+const items = [
+ { title: 'Dashboard', href: PATH_DASHBOARD.default },
+ { title: 'Pages', href: '#' },
+ { title: 'Settings', href: '#' },
+].map((item, index) => (
+
+ {item.title}
+
+));
+
+const ICON_SIZE = 16;
+
+const PAPER_PROPS: PaperProps = {
+ p: 'md',
+ shadow: 'md',
+ radius: 'md',
+ style: { height: '100%' },
+};
+
+const BIO =
+ 'A dynamic software engineering graduate from Nairobi, Kenya with 5+ years of experience. Passionate about turning creative sparks into seamless applications through technological experimentation. Experienced in crafting intuitive solutions and translating innovative concepts into user-friendly applications. Thrives on transforming the way we experience technology, one line of code at a time.\n' +
+ '\n' +
+ 'Enthusiastic pioneer, constantly seeking the next big thing in tech. Eager to apply my passion and skills at Alternate Limited to bring ideas to life.';
+
+function Settings() {
+ const [file, setFile] = useState(null);
+
+ const accountForm = useForm({
+ initialValues: {
+ username: 'kelvinkiprop',
+ biograghy:
+ 'A dynamic software engineering graduate from Nairobi, Kenya with 5+ years of experience. Passionate about turning creative sparks into seamless applications through technological experimentation. Experienced in crafting intuitive solutions and translating innovative concepts into user-friendly applications. Thrives on transforming the way we experience technology, one line of code at a time.\n' +
+ '\n' +
+ 'Enthusiastic pioneer, constantly seeking the next big thing in tech. Eager to apply my passion and skills at Alternate Limited to bring ideas to life.',
+ },
+ });
+
+ const accountInfoForm = useForm({
+ initialValues: {
+ firstname: 'kelvin',
+ lastname: 'kiprop',
+ email: 'kelvin.kiprop96@gmail.com',
+ address: '',
+ apartment: '',
+ city: '',
+ state: '',
+ zip: '',
+ },
+ });
+
+ return (
+ <>
+ <>
+ Settings | DesignSparx
+
+ >
+
+
+
+
+
+ User information
+
+
+
+
+
+
+ }
+ >
+ Save Changes
+
+
+
+
+
+
+
+ {(props) => (
+ }
+ >
+ Upload image
+
+ )}
+
+
+ For best results, use an image at least 128px by 128px in
+ .jpg format
+
+
+
+
+
+
+
+
+ Account information
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }>
+ Save changes
+
+
+
+
+
+
+ >
+ );
+}
+
+export default Settings;
diff --git a/app/projects/layout.tsx b/app/projects/layout.tsx
new file mode 100644
index 0000000..22dc793
--- /dev/null
+++ b/app/projects/layout.tsx
@@ -0,0 +1,69 @@
+'use client';
+
+import { AppShell, Container, rem, useMantineTheme } from '@mantine/core';
+import { ReactNode, useState } from 'react';
+import { useDisclosure, useMediaQuery } from '@mantine/hooks';
+import AppMain from '@/components/AppMain';
+import Navigation from '@/components/Navigation';
+import HeaderNav from '@/components/HeaderNav';
+import FooterNav from '@/components/FooterNav';
+
+type Props = {
+ children: ReactNode;
+};
+
+function CalendarLayout({ children }: Props) {
+ const theme = useMantineTheme();
+ const [opened, setOpened] = useState(false);
+ const [themeOpened, { open: themeOpen, close: themeClose }] =
+ useDisclosure(false);
+ const tablet_match = useMediaQuery('(max-width: 768px)');
+ const [mobileOpened, { toggle: toggleMobile }] = useDisclosure();
+ const [desktopOpened, { toggle: toggleDesktop }] = useDisclosure(true);
+
+ return (
+
+
+
+ setOpened((o) => !o)}
+ desktopOpened={desktopOpened}
+ mobileOpened={mobileOpened}
+ toggleDesktop={toggleDesktop}
+ toggleMobile={toggleMobile}
+ />
+
+
+
+ setOpened(false)} />
+
+
+ {children}
+
+
+
+
+
+
+
+ );
+}
+
+export default CalendarLayout;
diff --git a/app/projects/page.tsx b/app/projects/page.tsx
new file mode 100644
index 0000000..a32c612
--- /dev/null
+++ b/app/projects/page.tsx
@@ -0,0 +1,82 @@
+'use client';
+
+import {
+ Anchor,
+ CardProps,
+ Container,
+ SimpleGrid,
+ Skeleton,
+ Stack,
+} from '@mantine/core';
+import { PATH_DASHBOARD } from '@/routes';
+import { ErrorAlert, PageHeader, ProjectsCard } from '@/components';
+import { useFetchData } from '@/hooks';
+
+const items = [
+ { title: 'Dashboard', href: PATH_DASHBOARD.default },
+ { title: 'Projects', href: '#' },
+].map((item, index) => (
+
+ {item.title}
+
+));
+
+const ICON_SIZE = 18;
+
+const CARD_PROPS: Omit = {
+ p: 'md',
+ shadow: 'md',
+ radius: 'md',
+};
+
+function Projects() {
+ const {
+ data: projectsData,
+ loading: projectsLoading,
+ error: projectsError,
+ } = useFetchData('/mocks/Projects2.json');
+ const projectItems = projectsData.map((p: any) => (
+
+ ));
+
+ return (
+ <>
+ <>
+ Projects | DesignSparx
+
+ >
+
+
+
+ {projectsError ? (
+
+ ) : (
+
+ {projectsLoading
+ ? Array.from({ length: 8 }).map((o, i) => (
+
+ ))
+ : projectItems}
+
+ )}
+
+
+ >
+ );
+}
+
+export default Projects;
diff --git a/app/tasks/layout.tsx b/app/tasks/layout.tsx
new file mode 100644
index 0000000..22dc793
--- /dev/null
+++ b/app/tasks/layout.tsx
@@ -0,0 +1,69 @@
+'use client';
+
+import { AppShell, Container, rem, useMantineTheme } from '@mantine/core';
+import { ReactNode, useState } from 'react';
+import { useDisclosure, useMediaQuery } from '@mantine/hooks';
+import AppMain from '@/components/AppMain';
+import Navigation from '@/components/Navigation';
+import HeaderNav from '@/components/HeaderNav';
+import FooterNav from '@/components/FooterNav';
+
+type Props = {
+ children: ReactNode;
+};
+
+function CalendarLayout({ children }: Props) {
+ const theme = useMantineTheme();
+ const [opened, setOpened] = useState(false);
+ const [themeOpened, { open: themeOpen, close: themeClose }] =
+ useDisclosure(false);
+ const tablet_match = useMediaQuery('(max-width: 768px)');
+ const [mobileOpened, { toggle: toggleMobile }] = useDisclosure();
+ const [desktopOpened, { toggle: toggleDesktop }] = useDisclosure(true);
+
+ return (
+
+
+
+ setOpened((o) => !o)}
+ desktopOpened={desktopOpened}
+ mobileOpened={mobileOpened}
+ toggleDesktop={toggleDesktop}
+ toggleMobile={toggleMobile}
+ />
+
+
+
+ setOpened(false)} />
+
+
+ {children}
+
+
+
+
+
+
+
+ );
+}
+
+export default CalendarLayout;
diff --git a/app/tasks/page.tsx b/app/tasks/page.tsx
new file mode 100644
index 0000000..e6fee56
--- /dev/null
+++ b/app/tasks/page.tsx
@@ -0,0 +1,30 @@
+import { Anchor, Container, Stack } from '@mantine/core';
+import { KanbanBoard, PageHeader } from '@/components';
+import { PATH_DASHBOARD } from '@/routes';
+
+const items = [
+ { title: 'Dashboard', href: PATH_DASHBOARD.default },
+ { title: 'Tasks', href: '#' },
+].map((item, index) => (
+
+ {item.title}
+
+));
+
+function Tasks() {
+ return (
+ <>
+ <>
+ Tasks | DesignSparx
+ >
+
+
+
+
+
+
+ >
+ );
+}
+
+export default Tasks;
diff --git a/build-storybook.log b/build-storybook.log
new file mode 100644
index 0000000..bf74cbb
--- /dev/null
+++ b/build-storybook.log
@@ -0,0 +1,607 @@
+@storybook/cli v7.5.3
+
+info => Cleaning outputDir: C:\Users\Kelvin\AppData\Local\Temp\chromatic--14152-nhk6vEBmjTCq
+info => Loading presets
+info => Building manager..
+info => Manager built (2.81 s)
+info => Building preview..
+info => Copying static files: D:\PhpstormProjects\design-sparx\mantine-analytics-dashboard\node_modules\@storybook\manager\static at C:\Users\Kelvin\AppData\Local\Temp\chromatic--14152-nhk6vEBmjTCq\sb-common-assets
+info Addon-docs: using MDX2
+info => Using implicit CSS loaders
+info => [@storybook/addon-styling] Applying custom Storybook webpack configuration styling.
+info => Using default Webpack5 setup
+ [webpack.Progress] 0%
+
+ [webpack.Progress] 1% setup before run
+ [webpack.Progress] 1% setup before run NodeEnvironmentPlugin
+ [webpack.Progress] 1% setup before run
+ [webpack.Progress] 2% setup run
+ [webpack.Progress] 2% setup run
+ [webpack.Progress] 4% setup normal module factory
+ [webpack.Progress] 4% setup normal module factory CaseSensitivePathsPlugin
+ [webpack.Progress] 4% setup normal module factory IgnorePlugin
+ [webpack.Progress] 4% setup normal module factory
+ [webpack.Progress] 5% setup context module factory
+ [webpack.Progress] 5% setup context module factory IgnorePlugin
+ [webpack.Progress] 5% setup context module factory
+ [webpack.Progress] 6% setup before compile
+ [webpack.Progress] 6% setup before compile ProgressPlugin
+ [webpack.Progress] 6% setup before compile
+ [webpack.Progress] 7% setup compile
+ [webpack.Progress] 7% setup compile ExternalsPlugin
+ [webpack.Progress] 7% setup compile ExternalsPlugin
+ [webpack.Progress] 7% setup compile
+ [webpack.Progress] 8% setup compilation
+ [webpack.Progress] 8% setup compilation unplugin-csf
+ [webpack.Progress] 8% setup compilation ArrayPushCallbackChunkFormatPlugin
+ [webpack.Progress] 8% setup compilation JsonpChunkLoadingPlugin
+ [webpack.Progress] 8% setup compilation StartupChunkDependenciesPlugin
+ [webpack.Progress] 8% setup compilation ImportScriptsChunkLoadingPlugin
+ [webpack.Progress] 8% setup compilation FetchCompileWasmPlugin
+ [webpack.Progress] 8% setup compilation FetchCompileAsyncWasmPlugin
+ [webpack.Progress] 8% setup compilation WorkerPlugin
+ [webpack.Progress] 8% setup compilation SplitChunksPlugin
+ [webpack.Progress] 8% setup compilation RuntimeChunkPlugin
+ [webpack.Progress] 8% setup compilation ResolverCachePlugin
+ [webpack.Progress] 8% setup compilation HtmlWebpackPlugin
+ [webpack.Progress] 8% setup compilation
+ [webpack.Progress] 9% setup compilation
+ [webpack.Progress] 9% setup compilation DefinePlugin
+ [webpack.Progress] 9% setup compilation ProvidePlugin
+ [webpack.Progress] 9% setup compilation ProgressPlugin
+ [webpack.Progress] 9% setup compilation DocGenPlugin
+ [webpack.Progress] 9% setup compilation DefinePlugin
+ [webpack.Progress] 9% setup compilation DefinePlugin
+ [webpack.Progress] 9% setup compilation ProvidePlugin
+ [webpack.Progress] 9% setup compilation ChunkPrefetchPreloadPlugin
+ [webpack.Progress] 9% setup compilation SourceMapDevToolPlugin
+ [webpack.Progress] 9% setup compilation JavascriptModulesPlugin
+ [webpack.Progress] 9% setup compilation JsonModulesPlugin
+ [webpack.Progress] 9% setup compilation AssetModulesPlugin
+ [webpack.Progress] 9% setup compilation EntryPlugin
+ [webpack.Progress] 9% setup compilation RuntimePlugin
+ [webpack.Progress] 9% setup compilation InferAsyncModulesPlugin
+ [webpack.Progress] 9% setup compilation DataUriPlugin
+ [webpack.Progress] 9% setup compilation FileUriPlugin
+ [webpack.Progress] 9% setup compilation CompatibilityPlugin
+ [webpack.Progress] 9% setup compilation HarmonyModulesPlugin
+ [webpack.Progress] 9% setup compilation AMDPlugin
+ [webpack.Progress] 9% setup compilation RequireJsStuffPlugin
+ [webpack.Progress] 9% setup compilation CommonJsPlugin
+ [webpack.Progress] 9% setup compilation LoaderPlugin
+ [webpack.Progress] 9% setup compilation LoaderPlugin
+ [webpack.Progress] 9% setup compilation NodeStuffPlugin
+ [webpack.Progress] 9% setup compilation APIPlugin
+ [webpack.Progress] 9% setup compilation ExportsInfoApiPlugin
+ [webpack.Progress] 9% setup compilation WebpackIsIncludedPlugin
+ [webpack.Progress] 9% setup compilation ConstPlugin
+ [webpack.Progress] 9% setup compilation UseStrictPlugin
+ [webpack.Progress] 9% setup compilation RequireIncludePlugin
+ [webpack.Progress] 9% setup compilation RequireEnsurePlugin
+ [webpack.Progress] 9% setup compilation RequireContextPlugin
+ [webpack.Progress] 9% setup compilation ImportPlugin
+ [webpack.Progress] 9% setup compilation ImportMetaContextPlugin
+ [webpack.Progress] 9% setup compilation SystemPlugin
+ [webpack.Progress] 9% setup compilation ImportMetaPlugin
+ [webpack.Progress] 9% setup compilation URLPlugin
+ [webpack.Progress] 9% setup compilation DefaultStatsFactoryPlugin
+ [webpack.Progress] 9% setup compilation DefaultStatsPresetPlugin
+ [webpack.Progress] 9% setup compilation DefaultStatsPrinterPlugin
+ [webpack.Progress] 9% setup compilation JavascriptMetaInfoPlugin
+ [webpack.Progress] 9% setup compilation EnsureChunkConditionsPlugin
+ [webpack.Progress] 9% setup compilation RemoveEmptyChunksPlugin
+ [webpack.Progress] 9% setup compilation MergeDuplicateChunksPlugin
+ [webpack.Progress] 9% setup compilation FlagIncludedChunksPlugin
+ [webpack.Progress] 9% setup compilation SideEffectsFlagPlugin
+ [webpack.Progress] 9% setup compilation FlagDependencyExportsPlugin
+ [webpack.Progress] 9% setup compilation FlagDependencyUsagePlugin
+ [webpack.Progress] 9% setup compilation InnerGraphPlugin
+ [webpack.Progress] 9% setup compilation MangleExportsPlugin
+ [webpack.Progress] 9% setup compilation ModuleConcatenationPlugin
+ [webpack.Progress] 9% setup compilation NoEmitOnErrorsPlugin
+ [webpack.Progress] 9% setup compilation RealContentHashPlugin
+ [webpack.Progress] 9% setup compilation WasmFinalizeExportsPlugin
+ [webpack.Progress] 9% setup compilation NamedModuleIdsPlugin
+ [webpack.Progress] 9% setup compilation DeterministicChunkIdsPlugin
+ [webpack.Progress] 9% setup compilation DefinePlugin
+ [webpack.Progress] 9% setup compilation TerserPlugin
+ [webpack.Progress] 9% setup compilation TemplatedPathPlugin
+ [webpack.Progress] 9% setup compilation RecordIdsPlugin
+ [webpack.Progress] 9% setup compilation WarnCaseSensitiveModulesPlugin
+ [webpack.Progress] 9% setup compilation IgnoreWarningsPlugin
+ [webpack.Progress] 9% setup compilation
+ [webpack.Progress] 10% building
+ [webpack.Progress] 10% building 0/1 entries 0/0 dependencies 0/0 modules
+WARN No story files found for the specified pattern: components\**\*.stories.mdx
+ [webpack.Progress] 10% building 0/1 entries 1/1 dependencies 0/0 modules
+ [webpack.Progress] 26% building 0/1 entries 11/20 dependencies 3/10 modules
+ [webpack.Progress] 18% building import loader ./node_modules/babel-loader/lib/index.js
+ [webpack.Progress] 18% building 0/1 entries 20/28 dependencies 3/20 modules
+ [webpack.Progress] 20% building 0/1 entries 25/104 dependencies 4/21 modules
+ [webpack.Progress] 20% building 0/1 entries 31/110 dependencies 5/27 modules
+ [webpack.Progress] 21% building 0/1 entries 31/110 dependencies 6/28 modules
+ [webpack.Progress] 21% building import loader ./node_modules/@storybook/mdx2-csf/loader.js
+ [webpack.Progress] 21% building 0/1 entries 31/110 dependencies 6/28 modules
+ [webpack.Progress] 16% building import loader ./node_modules/unplugin/dist/webpack/loaders/load.js
+ [webpack.Progress] 16% building 0/1 entries 103/156 dependencies 8/63 modules
+ [webpack.Progress] 15% building import loader ./node_modules/@storybook/nextjs/dist/next-image-loader-stub.js
+ [webpack.Progress] 15% building 0/1 entries 121/161 dependencies 8/79 modules
+ [webpack.Progress] 16% building 0/1 entries 159/192 dependencies 11/96 modules
+ [webpack.Progress] 24% building 0/1 entries 240/594 dependencies 38/148 modules
+ [webpack.Progress] 15% building import loader ./node_modules/style-loader/dist/cjs.js
+ [webpack.Progress] 15% building import loader ./node_modules/css-loader/dist/cjs.js
+ [webpack.Progress] 15% building import loader ./node_modules/postcss-loader/dist/cjs.js
+ [webpack.Progress] 15% building 0/1 entries 524/595 dependencies 39/398 modules
+ [webpack.Progress] 14% building 0/1 entries 583/642 dependencies 41/454 modules
+ [webpack.Progress] 15% building 0/1 entries 659/686 dependencies 46/480 modules
+ [webpack.Progress] 16% building 0/1 entries 674/700 dependencies 55/490 modules
+ [webpack.Progress] 19% building 0/1 entries 783/900 dependencies 86/511 modules
+ [webpack.Progress] 22% building 0/1 entries 985/1100 dependencies 120/550 modules
+ [webpack.Progress] 21% building 0/1 entries 1300/1362 dependencies 126/627 modules
+ [webpack.Progress] 21% building 0/1 entries 1700/1906 dependencies 134/660 modules
+ [webpack.Progress] 21% building 0/1 entries 1890/2000 dependencies 137/684 modules
+ [webpack.Progress] 21% building 0/1 entries 1995/2500 dependencies 138/689 modules
+ [webpack.Progress] 20% building 0/1 entries 2100/2532 dependencies 138/694 modules
+ [webpack.Progress] 20% building 0/1 entries 2600/7430 dependencies 141/766 modules
+ [webpack.Progress] 17% building 0/1 entries 2900/7430 dependencies 141/1066 modules
+ [webpack.Progress] 15% building 0/1 entries 3200/7430 dependencies 141/1366 modules
+ [webpack.Progress] 14% building 0/1 entries 3700/7430 dependencies 141/1866 modules
+ [webpack.Progress] 12% building 0/1 entries 4433/7430 dependencies 141/2600 modules
+ [webpack.Progress] 12% building 0/1 entries 5000/7430 dependencies 141/3166 modules
+ [webpack.Progress] 12% building 0/1 entries 5400/7430 dependencies 141/3566 modules
+ [webpack.Progress] 11% building 0/1 entries 6000/7432 dependencies 141/4166 modules
+ [webpack.Progress] 11% building 0/1 entries 6300/7432 dependencies 141/4466 modules
+ [webpack.Progress] 11% building 0/1 entries 6533/7432 dependencies 141/4700 modules
+ [webpack.Progress] 11% building 0/1 entries 6833/7442 dependencies 141/5000 modules
+ [webpack.Progress] 11% building 0/1 entries 7200/7442 dependencies 141/5366 modules
+ [webpack.Progress] 11% building 0/1 entries 7500/7526 dependencies 143/5594 modules
+ [webpack.Progress] 11% building 0/1 entries 7600/7764 dependencies 160/5610 modules
+ [webpack.Progress] 11% building 0/1 entries 7679/7800 dependencies 164/5625 modules
+ [webpack.Progress] 12% building 0/1 entries 7900/7970 dependencies 225/5732 modules
+ [webpack.Progress] 13% building 0/1 entries 8162/8200 dependencies 382/5875 modules
+ [webpack.Progress] 14% building 0/1 entries 8252/8300 dependencies 460/5880 modules
+ [webpack.Progress] 14% building 0/1 entries 8391/8400 dependencies 462/5910 modules
+ [webpack.Progress] 14% building 0/1 entries 8572/8600 dependencies 462/5910 modules
+ [webpack.Progress] 14% building 0/1 entries 8700/8734 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 8800/8836 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 8976/9000 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 9087/9100 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 9278/9300 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 9356/9400 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 9500/9534 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 9600/9637 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 9778/9800 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 9878/9900 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 9982/10000 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 10038/10100 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 10100/10135 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 10138/10200 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 10238/10300 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 10348/10400 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 10451/10500 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 10551/10600 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 10651/10700 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 10853/10900 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 10957/11000 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 11058/11100 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 11162/11200 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 11392/11400 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 11559/11600 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 11678/11700 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 11777/11800 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 11979/12000 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 12092/12100 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 12291/12300 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 12473/12500 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 12578/12600 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 12669/12700 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 12778/12800 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 12900/12972 dependencies 462/5917 modules
+ [webpack.Progress] 14% building 0/1 entries 13075/13100 dependencies 462/5917 modules
+ [webpack.Progress] 15% building 0/1 entries 13242/13400 dependencies 572/5958 modules
+ [webpack.Progress] 15% building 0/1 entries 13400/13434 dependencies 629/5992 modules
+ [webpack.Progress] 16% building 0/1 entries 13461/13492 dependencies 682/6000 modules
+ [webpack.Progress] 16% building 0/1 entries 13500/13527 dependencies 698/6007 modules
+ [webpack.Progress] 16% building 0/1 entries 13534/13600 dependencies 719/6014 modules
+ [webpack.Progress] 16% building 0/1 entries 13600/13687 dependencies 743/6021 modules
+ [webpack.Progress] 16% building 0/1 entries 13685/13800 dependencies 766/6043 modules
+ [webpack.Progress] 60% building 0/1 entries 13900/13930 dependencies 5614/6158 modules
+ [webpack.Progress] 60% building 0/1 entries 14100/14124 dependencies 5679/6229 modules
+ [webpack.Progress] 60% building 0/1 entries 14336/14400 dependencies 5798/6293 modules
+ [webpack.Progress] 59% building 0/1 entries 14641/14700 dependencies 5836/6512 modules
+ [webpack.Progress] 60% building 0/1 entries 14818/14900 dependencies 5976/6551 modules
+ [webpack.Progress] 60% building 0/1 entries 15099/15132 dependencies 6100/6622 modules
+ [webpack.Progress] 60% building 0/1 entries 15255/15500 dependencies 6177/6662 modules
+ [webpack.Progress] 59% building 0/1 entries 15580/15700 dependencies 6252/6897 modules
+ [webpack.Progress] 60% building 0/1 entries 15816/15930 dependencies 6300/6919 modules
+ [webpack.Progress] 61% building 0/1 entries 15980/16000 dependencies 6499/6978 modules
+ [webpack.Progress] 61% building 0/1 entries 16057/16121 dependencies 6600/7004 modules
+ [webpack.Progress] 62% building 0/1 entries 16362/16400 dependencies 6694/7064 modules
+ [webpack.Progress] 63% building 0/1 entries 16579/16700 dependencies 6853/7092 modules
+ [webpack.Progress] 64% building 0/1 entries 16861/16871 dependencies 7100/7183 modules
+ [webpack.Progress] 64% building 0/1 entries 17002/17002 dependencies 7200/7230 modules
+ [webpack.Progress] 65% building 1/1 entries 17002/17002 dependencies 7230/7230 modules
+ [webpack.Progress] 65% building
+ [webpack.Progress] 69% building finish
+ [webpack.Progress] 69% building finish
+ [webpack.Progress] 70% sealing finish module graph
+ [webpack.Progress] 70% sealing finish module graph ResolverCachePlugin
+ [webpack.Progress] 70% sealing finish module graph InferAsyncModulesPlugin
+ [webpack.Progress] 70% sealing finish module graph FlagDependencyExportsPlugin
+ [webpack.Progress] 70% sealing finish module graph InnerGraphPlugin
+ [webpack.Progress] 70% sealing finish module graph WasmFinalizeExportsPlugin
+ [webpack.Progress] 70% sealing finish module graph
+ [webpack.Progress] 70% sealing plugins
+ [webpack.Progress] 70% sealing plugins DocGenPlugin
+ [webpack.Progress] 70% sealing plugins WarnCaseSensitiveModulesPlugin
+ [webpack.Progress] 70% sealing plugins
+ [webpack.Progress] 71% sealing dependencies optimization
+ [webpack.Progress] 71% sealing dependencies optimization SideEffectsFlagPlugin
+ [webpack.Progress] 71% sealing dependencies optimization FlagDependencyUsagePlugin
+ [webpack.Progress] 71% sealing dependencies optimization
+ [webpack.Progress] 71% sealing after dependencies optimization
+ [webpack.Progress] 71% sealing after dependencies optimization
+ [webpack.Progress] 72% sealing chunk graph
+ [webpack.Progress] 72% sealing chunk graph
+ [webpack.Progress] 73% sealing after chunk graph
+ [webpack.Progress] 73% sealing after chunk graph
+ [webpack.Progress] 73% sealing optimizing
+ [webpack.Progress] 73% sealing optimizing
+ [webpack.Progress] 74% sealing module optimization
+ [webpack.Progress] 74% sealing module optimization
+ [webpack.Progress] 75% sealing after module optimization
+ [webpack.Progress] 75% sealing after module optimization
+ [webpack.Progress] 75% sealing chunk optimization
+ [webpack.Progress] 75% sealing chunk optimization EnsureChunkConditionsPlugin
+ [webpack.Progress] 75% sealing chunk optimization RemoveEmptyChunksPlugin
+ [webpack.Progress] 75% sealing chunk optimization MergeDuplicateChunksPlugin
+ [webpack.Progress] 75% sealing chunk optimization SplitChunksPlugin
+ [webpack.Progress] 75% sealing chunk optimization RemoveEmptyChunksPlugin
+ [webpack.Progress] 75% sealing chunk optimization
+ [webpack.Progress] 76% sealing after chunk optimization
+ [webpack.Progress] 76% sealing after chunk optimization
+