diff --git a/contexts/LoaderContext.tsx b/contexts/LoaderContext.tsx new file mode 100644 index 0000000..c296054 --- /dev/null +++ b/contexts/LoaderContext.tsx @@ -0,0 +1,25 @@ +import { createContext, useContext } from 'react'; +import NProgress from 'nprogress'; + +type LoaderContextType = { + start: () => void; + stop: () => void; +}; + +const LoaderContext = createContext({ + start: () => {}, + stop: () => {}, +}); + +export const LoaderProvider = ({ children }: { children: React.ReactNode }) => { + const start = () => NProgress.start(); + const stop = () => NProgress.done(); + + return ( + + {children} + + ); +}; + +export const useLoader = () => useContext(LoaderContext); diff --git a/package-lock.json b/package-lock.json index 4d8376f..c3fb24e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "next": "^15.2.5", "next-auth": "^4.24.10", "nodemailer": "^6.10.0", + "nprogress": "^0.2.0", "react": "^18.3.1", "react-chartjs-2": "^5.3.0", "react-dom": "^18.3.1", @@ -33,6 +34,7 @@ "@types/bcryptjs": "^2.4.6", "@types/node": "^22.10.2", "@types/nodemailer": "^6.4.17", + "@types/nprogress": "^0.2.3", "@types/react": "^18.3.18", "@types/supertest": "^6.0.2", "eslint-config-next": "^15.3.1", @@ -1218,6 +1220,13 @@ "@types/node": "*" } }, + "node_modules/@types/nprogress": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@types/nprogress/-/nprogress-0.2.3.tgz", + "integrity": "sha512-k7kRA033QNtC+gLc4VPlfnue58CM1iQLgn1IMAU8VPHGOj7oIHPp9UlhedEnD/Gl8evoCjwkZjlBORtZ3JByUA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/parse-json": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", @@ -3753,21 +3762,6 @@ "node": ">= 0.6" } }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -5290,6 +5284,12 @@ "node": ">=6.0.0" } }, + "node_modules/nprogress": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", + "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==", + "license": "MIT" + }, "node_modules/oauth": { "version": "0.9.15", "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", @@ -7632,6 +7632,96 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.3.0.tgz", + "integrity": "sha512-PDQcByT0ZfF2q7QR9d+PNj3wlNN4K6Q8JoHMwFyk252gWo4gKt7BF8Y2+KBgDjTFBETXZ/TkBEUY7NIIY7A/Kw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.3.0.tgz", + "integrity": "sha512-m+eO21yg80En8HJ5c49AOQpFDq+nP51nu88ZOMCorvw3g//8g1JSUsEiPSiFpJo1KCTQ+jm9H0hwXK49H/RmXg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.3.0.tgz", + "integrity": "sha512-H0Kk04ZNzb6Aq/G6e0un4B3HekPnyy6D+eUBYPJv9Abx8KDYgNMWzKt4Qhj57HXV3sTTjsfc1Trc1SxuhQB+Tg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.3.0.tgz", + "integrity": "sha512-k8GVkdMrh/+J9uIv/GpnHakzgDQhrprJ/FbGQvwWmstaeFG06nnAoZCJV+wO/bb603iKV1BXt4gHG+s2buJqZA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.3.0.tgz", + "integrity": "sha512-a7kUbqa/k09xPjfCl0RSVAvEjAkYBYxUzSVAzk2ptXiNEL+4bDBo9wNC43G/osLA/EOGzG4CuNRFnQyIHfkRgQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.3.0.tgz", + "integrity": "sha512-vHUQS4YVGJPmpjn7r5lEZuMhK5UQBNBRSB+iGDvJjaNk649pTIcRluDWNb9siunyLLiu/LDPHfvxBtNamyuLTw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } } } } diff --git a/package.json b/package.json index c5c0345..94d6012 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "next": "^15.2.5", "next-auth": "^4.24.10", "nodemailer": "^6.10.0", + "nprogress": "^0.2.0", "react": "^18.3.1", "react-chartjs-2": "^5.3.0", "react-dom": "^18.3.1", @@ -38,6 +39,7 @@ "@types/bcryptjs": "^2.4.6", "@types/node": "^22.10.2", "@types/nodemailer": "^6.4.17", + "@types/nprogress": "^0.2.3", "@types/react": "^18.3.18", "@types/supertest": "^6.0.2", "eslint-config-next": "^15.3.1", diff --git a/pages/_app.tsx b/pages/_app.tsx index 813d076..8fde42f 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -4,22 +4,33 @@ import { ToastContainer } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.css'; import { SessionProvider } from 'next-auth/react'; import { AppProps } from 'next/app'; +import Router from 'next/router'; +import NProgress from 'nprogress'; //Components import Layout from '../Components/UI/Layout/Layout'; +import { LoaderProvider } from '~/contexts/LoaderContext'; + +NProgress.configure({ showSpinner: false }); + +Router.events.on('routeChangeStart', () => NProgress.start()); +Router.events.on('routeChangeComplete', () => NProgress.done()); +Router.events.on('routeChangeError', () => NProgress.done()); export default function MyApp({ Component, pageProps }: AppProps) { return ( - - - - - BorgWarehouse - - - - + + + + + + BorgWarehouse + + + + + ); } diff --git a/styles/default.css b/styles/default.css index f0623b5..77f5905 100644 --- a/styles/default.css +++ b/styles/default.css @@ -20,6 +20,20 @@ body { display: none; } +#nprogress { + pointer-events: none; +} + +#nprogress .bar { + background: #6d4aff; + position: fixed; + z-index: 9999; + top: 0; + left: 0; + width: 100%; + height: 2px; +} + code { font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace; }