diff --git a/api/package-lock.json b/api/package-lock.json index 8e56cc615..05607bc31 100644 --- a/api/package-lock.json +++ b/api/package-lock.json @@ -21,7 +21,7 @@ "@types/express": "^4.17.21", "@types/jest": "^29.5.14", "@types/multer": "^1.4.12", - "@types/node": "^22.12.0", + "@types/node": "^22.13.0", "@types/nodemailer": "^6.4.17", "@types/supertest": "^6.0.2", "@types/validator": "^13.12.2", @@ -42,7 +42,7 @@ "i18n-js": "^4.5.1", "jest": "^29.7.0", "jose": "^5.9.6", - "mongoose": "^8.9.5", + "mongoose": "^8.9.6", "multer": "^1.4.5-lts.1", "nanoid": "^5.0.9", "nocache": "^4.0.0", @@ -3282,9 +3282,9 @@ } }, "node_modules/@types/node": { - "version": "22.12.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.12.0.tgz", - "integrity": "sha512-Fll2FZ1riMjNmlmJOdAyY5pUbkftXslB5DgEzlIuNaiWhXd00FhWxVC/r4yV/4wBb9JfImTu+jiSvXTkJ7F/gA==", + "version": "22.13.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.0.tgz", + "integrity": "sha512-ClIbNe36lawluuvq3+YYhnIN2CELi+6q8NpnM7PYp4hBn/TatfboPgVSm2rwKRfnV2M+Ty9GWDFI64KEe+kysA==", "license": "MIT", "dependencies": { "undici-types": "~6.20.0" @@ -8167,9 +8167,9 @@ } }, "node_modules/mongoose": { - "version": "8.9.5", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.9.5.tgz", - "integrity": "sha512-SPhOrgBm0nKV3b+IIHGqpUTOmgVL5Z3OO9AwkFEmvOZznXTvplbomstCnPOGAyungtRXE5pJTgKpKcZTdjeESg==", + "version": "8.9.6", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.9.6.tgz", + "integrity": "sha512-ipLvXwNPVuuuq5H3lnSD0lpaRH3DlCoC6emnMVJvweTwxU29uxDJWxMsNpERDQt8JMvYF1HGVuTK+Id2BlQLCA==", "license": "MIT", "dependencies": { "bson": "^6.10.1", diff --git a/api/package.json b/api/package.json index 086eb7db9..ef06462cf 100644 --- a/api/package.json +++ b/api/package.json @@ -1,6 +1,6 @@ { "name": "api", - "version": "5.5.0", + "version": "5.6.0", "description": "", "main": "index.js", "type": "module", @@ -29,7 +29,7 @@ "@types/express": "^4.17.21", "@types/jest": "^29.5.14", "@types/multer": "^1.4.12", - "@types/node": "^22.12.0", + "@types/node": "^22.13.0", "@types/nodemailer": "^6.4.17", "@types/supertest": "^6.0.2", "@types/validator": "^13.12.2", @@ -50,7 +50,7 @@ "i18n-js": "^4.5.1", "jest": "^29.7.0", "jose": "^5.9.6", - "mongoose": "^8.9.5", + "mongoose": "^8.9.6", "multer": "^1.4.5-lts.1", "nanoid": "^5.0.9", "nocache": "^4.0.0", diff --git a/backend/package-lock.json b/backend/package-lock.json index fc2848d56..6f762dfc4 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -1,20 +1,21 @@ { "name": "backend", - "version": "5.5.0", + "version": "5.6.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "backend", - "version": "5.5.0", + "version": "5.6.0", "dependencies": { "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.0", - "@mui/icons-material": "^6.4.1", - "@mui/material": "^6.4.1", - "@mui/x-data-grid": "^7.24.1", - "@mui/x-date-pickers": "^7.24.1", - "@types/node": "^22.12.0", + "@mui/icons-material": "^6.4.2", + "@mui/material": "^6.4.2", + "@mui/x-data-grid": "^7.25.0", + "@mui/x-date-pickers": "^7.25.0", + "@types/node": "^22.13.0", + "@types/nprogress": "^0.2.3", "@types/react": "^19.0.8", "@types/react-dom": "^19.0.3", "@types/validator": "^13.12.2", @@ -29,9 +30,10 @@ "eslint-plugin-react-refresh": "^0.4.11", "history": "^5.3.0", "localized-strings": "^2.0.3", + "nprogress": "^0.2.0", "react": "^19.0.0", "react-dom": "^19.0.0", - "react-router-dom": "^7.1.3", + "react-router-dom": "^7.1.5", "react-toastify": "^11.0.3", "rrule": "^2.8.1", "typescript": "^5.7.3", @@ -1393,9 +1395,9 @@ } }, "node_modules/@mui/core-downloads-tracker": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.4.1.tgz", - "integrity": "sha512-SfDLWMV5b5oXgDf3NTa2hCTPC1d2defhDH2WgFKmAiejC4mSfXYbyi+AFCLzpizauXhgBm8OaZy9BHKnrSpahQ==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.4.2.tgz", + "integrity": "sha512-Qmod9fHsFWrtLxdSkZ4iDLRz2AUKt3C2ZEimuY+qKlQGVKJDNS5DuSlNOAgqfHFDq8mzB17ATN6HFcThwJlvUw==", "license": "MIT", "funding": { "type": "opencollective", @@ -1403,9 +1405,9 @@ } }, "node_modules/@mui/icons-material": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.4.1.tgz", - "integrity": "sha512-wsxFcUTQxt4s+7Bg4GgobqRjyaHLmZGNOs+HJpbwrwmLbT6mhIJxhpqsKzzWq9aDY8xIe7HCjhpH7XI5UD6teA==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.4.2.tgz", + "integrity": "sha512-uwsH1KRmxkJwK3NZyo1xL9pEduL16ftCnzYBYjd6nPNtm05QAoIc0aqedS9tqDV+Ab3q5C04HHOVsMDDv1EBpg==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0" @@ -1418,7 +1420,7 @@ "url": "https://opencollective.com/mui-org" }, "peerDependencies": { - "@mui/material": "^6.4.1", + "@mui/material": "^6.4.2", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, @@ -1429,16 +1431,16 @@ } }, "node_modules/@mui/material": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.4.1.tgz", - "integrity": "sha512-MFBfia6UiKxyoLeGkAh8M15bkeDmfnsUTMRJd/vTQue6YQ8AQ6lw9HqDthyYghzDEWIvZO/lQQzLrZE8XwNJLA==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.4.2.tgz", + "integrity": "sha512-9jKr53KbAJyyBRx8LRmX7ATXHlGtxVQdPgm1uyXMoEPMVkSJW1yO3vFgfYoDbGx4ZHcCNuWa4FkFIPWVt9fghA==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0", - "@mui/core-downloads-tracker": "^6.4.1", - "@mui/system": "^6.4.1", + "@mui/core-downloads-tracker": "^6.4.2", + "@mui/system": "^6.4.2", "@mui/types": "^7.2.21", - "@mui/utils": "^6.4.1", + "@mui/utils": "^6.4.2", "@popperjs/core": "^2.11.8", "@types/react-transition-group": "^4.4.12", "clsx": "^2.1.1", @@ -1457,7 +1459,7 @@ "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", - "@mui/material-pigment-css": "^6.4.1", + "@mui/material-pigment-css": "^6.4.2", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" @@ -1478,13 +1480,13 @@ } }, "node_modules/@mui/private-theming": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.4.1.tgz", - "integrity": "sha512-DcT7mwK89owwgcEuiE7w458te4CIjHbYWW6Kn6PiR6eLtxBsoBYphA968uqsQAOBQDpbYxvkuFLwhgk4bxoN/Q==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.4.2.tgz", + "integrity": "sha512-2CkQT0gNlogM50qGTBJgWA7hPPx4AeH8RE2xJa+PHtIOowiVPX52ZsQ0e7Ho18DAqEbkngQ6Uju037ER+TCY5A==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0", - "@mui/utils": "^6.4.1", + "@mui/utils": "^6.4.2", "prop-types": "^15.8.1" }, "engines": { @@ -1505,9 +1507,9 @@ } }, "node_modules/@mui/styled-engine": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.4.0.tgz", - "integrity": "sha512-ek/ZrDujrger12P6o4luQIfRd2IziH7jQod2WMbLqGE03Iy0zUwYmckRTVhRQTLPNccpD8KXGcALJF+uaUQlbg==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.4.2.tgz", + "integrity": "sha512-cgjQK2bkllSYoWUBv93ALhCPJ0NhfO3NctsBf13/b4XSeQVfKPBAnR+P9mNpdFMa5a5RWwtWuBD3cZ5vktsN+g==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0", @@ -1539,16 +1541,16 @@ } }, "node_modules/@mui/system": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.4.1.tgz", - "integrity": "sha512-rgQzgcsHCTtzF9MZ+sL0tOhf2ZBLazpjrujClcb4Siju5lTrK0xX4PsiropActzCemNfM+mOu+0jezAVnfRK8g==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.4.2.tgz", + "integrity": "sha512-wQbaPCtsxNsM5nR+NZpkFJBKVKH03GQnAjlkKENM8JQqGdWcRyM3f4fJZgzzNdIFpSQw4wpAQKnhfHkjf3d6yQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0", - "@mui/private-theming": "^6.4.1", - "@mui/styled-engine": "^6.4.0", + "@mui/private-theming": "^6.4.2", + "@mui/styled-engine": "^6.4.2", "@mui/types": "^7.2.21", - "@mui/utils": "^6.4.1", + "@mui/utils": "^6.4.2", "clsx": "^2.1.1", "csstype": "^3.1.3", "prop-types": "^15.8.1" @@ -1593,9 +1595,9 @@ } }, "node_modules/@mui/utils": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.4.1.tgz", - "integrity": "sha512-iQUDUeYh87SvR4lVojaRaYnQix8BbRV51MxaV6MBmqthecQoxwSbS5e2wnbDJUeFxY2ppV505CiqPLtd0OWkqw==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.4.2.tgz", + "integrity": "sha512-5NkhzlJkmR5+5RSs/Irqin1GPy2Z8vbLk/UzQrH9FEAnm6OA9SvuXjzgklxUs7N65VwEkGpKK1jMZ5K84hRdzQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0", @@ -1623,14 +1625,14 @@ } }, "node_modules/@mui/x-data-grid": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-7.24.1.tgz", - "integrity": "sha512-4sYTbMwsDotuTd2Cwa2JGTPXPWQs8RGJvocAKnIsNOzNdZNMrikE//HO35snriK8s4dauAApY7RVbeisjpVT+A==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-7.25.0.tgz", + "integrity": "sha512-e9ZLbCgnDiADFiDyXo91ucZFHEMkKBNpwpkaTq5KohzefJfMpMQjTEbJeueSfBG2G1Q1Am2TPeBqrNeReIA7RQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.25.7", "@mui/utils": "^5.16.6 || ^6.0.0", - "@mui/x-internals": "7.24.1", + "@mui/x-internals": "7.25.0", "clsx": "^2.1.1", "prop-types": "^15.8.1", "reselect": "^5.1.1" @@ -1660,14 +1662,14 @@ } }, "node_modules/@mui/x-date-pickers": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-7.24.1.tgz", - "integrity": "sha512-ykQugMQHuQKBk3kViW/r0PpubtHQOlrd54bgbdafgTMCeM2VpXvv4zimzOu5IGnM6wEN8hupC7EXZbkrT6x46w==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-7.25.0.tgz", + "integrity": "sha512-t62OSFAKwj7KYQ8KcwTuKj6OgDuLQPSe4QUJcKDzD9rEhRIJVRUw2x27gBSdcls4l0PTrba19TghvDxCZprriw==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.25.7", "@mui/utils": "^5.16.6 || ^6.0.0", - "@mui/x-internals": "7.24.1", + "@mui/x-internals": "7.25.0", "@types/react-transition-group": "^4.4.11", "clsx": "^2.1.1", "prop-types": "^15.8.1", @@ -1726,9 +1728,9 @@ } }, "node_modules/@mui/x-internals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-7.24.1.tgz", - "integrity": "sha512-9BvJzpLJnS9BDphvkiv6v0QOLxbnu8jhwcexFjtCQ2ZyxtVuVsWzGZ2npT9sGOil7+eaFDmWnJtea/tgrPvSwQ==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-7.25.0.tgz", + "integrity": "sha512-tBUN54YznAkmtCIRAOl35Kgl0MjFDIjUbzIrbWRgVSIR3QJ8bXnVSkiRBi+P91SZEl9+ZW0rDj+osq7xFJV0kg==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.25.7", @@ -2121,14 +2123,20 @@ "peer": true }, "node_modules/@types/node": { - "version": "22.12.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.12.0.tgz", - "integrity": "sha512-Fll2FZ1riMjNmlmJOdAyY5pUbkftXslB5DgEzlIuNaiWhXd00FhWxVC/r4yV/4wBb9JfImTu+jiSvXTkJ7F/gA==", + "version": "22.13.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.0.tgz", + "integrity": "sha512-ClIbNe36lawluuvq3+YYhnIN2CELi+6q8NpnM7PYp4hBn/TatfboPgVSm2rwKRfnV2M+Ty9GWDFI64KEe+kysA==", "license": "MIT", "dependencies": { "undici-types": "~6.20.0" } }, + "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==", + "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", @@ -6169,6 +6177,12 @@ "npm": ">=8.12.1" } }, + "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/nth-check": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", @@ -6671,9 +6685,9 @@ } }, "node_modules/react-router": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.1.3.tgz", - "integrity": "sha512-EezYymLY6Guk/zLQ2vRA8WvdUhWFEj5fcE3RfWihhxXBW7+cd1LsIiA3lmx+KCmneAGQuyBv820o44L2+TtkSA==", + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.1.5.tgz", + "integrity": "sha512-8BUF+hZEU4/z/JD201yK6S+UYhsf58bzYIDq2NS1iGpwxSXDu7F+DeGSkIXMFBuHZB21FSiCzEcUb18cQNdRkA==", "license": "MIT", "dependencies": { "@types/cookie": "^0.6.0", @@ -6695,12 +6709,12 @@ } }, "node_modules/react-router-dom": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.1.3.tgz", - "integrity": "sha512-qQGTE+77hleBzv9SIUIkGRvuFBQGagW+TQKy53UTZAO/3+YFNBYvRsNIZ1GT17yHbc63FylMOdS+m3oUriF1GA==", + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.1.5.tgz", + "integrity": "sha512-/4f9+up0Qv92D3bB8iN5P1s3oHAepSGa9h5k6tpTFlixTTskJZwKGhJ6vRJ277tLD1zuaZTt95hyGWV1Z37csQ==", "license": "MIT", "dependencies": { - "react-router": "7.1.3" + "react-router": "7.1.5" }, "engines": { "node": ">=20.0.0" diff --git a/backend/package.json b/backend/package.json index 487fac9ff..4661a453a 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,7 +1,7 @@ { "name": "backend", "private": true, - "version": "5.5.0", + "version": "5.6.0", "type": "module", "scripts": { "install:dependencies": "cd ../packages/currency-converter && npm i && cd ../bookcars-helper && npm i && cd ../../backend", @@ -18,11 +18,12 @@ "dependencies": { "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.0", - "@mui/icons-material": "^6.4.1", - "@mui/material": "^6.4.1", - "@mui/x-data-grid": "^7.24.1", - "@mui/x-date-pickers": "^7.24.1", - "@types/node": "^22.12.0", + "@mui/icons-material": "^6.4.2", + "@mui/material": "^6.4.2", + "@mui/x-data-grid": "^7.25.0", + "@mui/x-date-pickers": "^7.25.0", + "@types/node": "^22.13.0", + "@types/nprogress": "^0.2.3", "@types/react": "^19.0.8", "@types/react-dom": "^19.0.3", "@types/validator": "^13.12.2", @@ -37,9 +38,10 @@ "eslint-plugin-react-refresh": "^0.4.11", "history": "^5.3.0", "localized-strings": "^2.0.3", + "nprogress": "^0.2.0", "react": "^19.0.0", "react-dom": "^19.0.0", - "react-router-dom": "^7.1.3", + "react-router-dom": "^7.1.5", "react-toastify": "^11.0.3", "rrule": "^2.8.1", "typescript": "^5.7.3", diff --git a/backend/src/App.tsx b/backend/src/App.tsx index 4a0ed23e2..5635ec8fa 100644 --- a/backend/src/App.tsx +++ b/backend/src/App.tsx @@ -1,8 +1,11 @@ import React, { lazy, Suspense } from 'react' import { BrowserRouter, Route, Routes } from 'react-router-dom' import { GlobalProvider } from '@/context/GlobalContext' +import { UserProvider } from '@/context/UserContext' import ScrollToTop from '@/components/ScrollToTop' +import NProgressIndicator from '@/components/NProgressIndicator' +const Header = lazy(() => import('@/components/Header')) const SignIn = lazy(() => import('@/pages/SignIn')) const Activate = lazy(() => import('@/pages/Activate')) const ForgotPassword = lazy(() => import('@/pages/ForgotPassword')) @@ -41,49 +44,53 @@ const Scheduler = lazy(() => import('@/pages/Scheduler')) const App = () => ( - + + -
- }> - - } /> - } /> - } /> - } /> - {/* } /> */} - } /> - } /> - } /> - {/* } /> */} - {/* } /> */} - } /> - {/* } /> */} - {/* } /> */} - } /> - } /> - {/* } /> */} - {/* } /> */} - } /> - } /> - } /> - } /> - {/* } /> */} - {/* } /> */} - } /> - } /> - {/* } /> */} - } /> - } /> - } /> - } /> - {/* } /> */} - {/* } /> */} - } /> +
+ }> +
- } /> - - -
+ + } /> + } /> + } /> + } /> + {/* } /> */} + } /> + } /> + } /> + {/* } /> */} + {/* } /> */} + } /> + {/* } /> */} + {/* } /> */} + } /> + } /> + {/* } /> */} + {/* } /> */} + } /> + } /> + } /> + } /> + {/* } /> */} + {/* } /> */} + } /> + } /> + {/* } /> */} + } /> + } /> + } /> + } /> + {/* } /> */} + {/* } /> */} + } /> + + } /> + +
+
+
) diff --git a/backend/src/assets/css/common.css b/backend/src/assets/css/common.css index 13585c6d8..249c66123 100644 --- a/backend/src/assets/css/common.css +++ b/backend/src/assets/css/common.css @@ -4,6 +4,10 @@ --toastify-icon-color-info: #fff !important; } +#nprogress .bar { + background: #1a1a1a !important; +} + .buttons button { margin-right: 15px; margin-left: 0 !important; @@ -34,6 +38,21 @@ margin-bottom: 10px !important; } +.btn-lnk { + background-color: transparent !important; + color: #1a1a1a !important; + font-weight: 400 !important; + text-decoration: underline !important; + font-size: 16px !important; + text-transform: none !important; + padding: 0 !important; +} + +.btn-lnk:hover { + opacity: 0.8; +} + + .validate-email { margin: 15px; } diff --git a/backend/src/assets/css/header.css b/backend/src/assets/css/header.css index 165185379..be594ed7f 100644 --- a/backend/src/assets/css/header.css +++ b/backend/src/assets/css/header.css @@ -10,6 +10,14 @@ z-index: 1401 !important; } +.side-menu li { + cursor: pointer; +} + +.side-menu li:hover { + background-color: #f1f1f1; +} + .header-action { margin-right: 20px; } diff --git a/backend/src/components/BookingList.tsx b/backend/src/components/BookingList.tsx index 1b6e434f2..a4e5e0da7 100644 --- a/backend/src/components/BookingList.tsx +++ b/backend/src/components/BookingList.tsx @@ -1,4 +1,5 @@ import React, { useState, useEffect } from 'react' +import { useNavigate } from 'react-router-dom' import { DataGrid, GridPaginationModel, @@ -70,6 +71,8 @@ const BookingList = ({ checkboxSelection, onLoad, }: BookingListProps) => { + const navigate = useNavigate() + const [loggedUser, setLoggedUser] = useState() const [user, setUser] = useState() const [page, setPage] = useState(0) @@ -260,7 +263,7 @@ const BookingList = ({ return (
- + navigate(`/update-booking?b=${row._id}`)}> @@ -490,7 +493,7 @@ const BookingList = ({ ) ) : env.isMobile ? ( <> - {rows.map((booking, _index) => { + {rows.map((booking, index) => { const from = new Date(booking.from) const to = new Date(booking.to) const days = bookcarsHelper.days(from, to) @@ -603,7 +606,7 @@ const BookingList = ({ variant="contained" className="btn-primary" size="small" - href={`update-booking?b=${booking._id}`} + onClick={() => navigate(`/update-booking?b=${booking._id}`)} > {commonStrings.UPDATE} diff --git a/backend/src/components/CarList.tsx b/backend/src/components/CarList.tsx index 625abe6de..742116356 100644 --- a/backend/src/components/CarList.tsx +++ b/backend/src/components/CarList.tsx @@ -1,4 +1,5 @@ import React, { useState, useEffect } from 'react' +import { useNavigate } from 'react-router-dom' import { IconButton, Button, @@ -96,6 +97,8 @@ const CarList = ({ onLoad, onDelete }: CarListProps) => { + const navigate = useNavigate() + const [user, setUser] = useState() const [init, setInit] = useState(true) const [loading, setLoading] = useState(false) @@ -397,7 +400,7 @@ const CarList = ({ ) - : rows.map((car) => { + : rows.map((car, _index) => { const edit = admin || car.supplier._id === user._id return (
@@ -617,17 +620,17 @@ const CarList = ({ {edit && ( <> - + navigate(`/car?cr=${car._id}`)}> - + navigate(`/update-car?cr=${car._id}`)}> {/* - + */} diff --git a/backend/src/components/CountryList.tsx b/backend/src/components/CountryList.tsx index 85e93af25..5a4e271c7 100644 --- a/backend/src/components/CountryList.tsx +++ b/backend/src/components/CountryList.tsx @@ -1,4 +1,5 @@ import React, { useState, useEffect } from 'react' +import { useNavigate } from 'react-router-dom' import { IconButton, Button, @@ -43,6 +44,8 @@ const CountryList = ({ onLoad, onDelete }: CountryListProps) => { + const navigate = useNavigate() + const [keyword, setKeyword] = useState(countryKeyword) const [init, setInit] = useState(true) const [loading, setLoading] = useState(false) @@ -218,12 +221,12 @@ const CountryList = ({ secondaryAction={(
- + navigate(`/update-country?loc=${country._id}`)}> {/* - + */} diff --git a/backend/src/components/Error.tsx b/backend/src/components/Error.tsx index b582d0cf0..d8ae32bcd 100644 --- a/backend/src/components/Error.tsx +++ b/backend/src/components/Error.tsx @@ -1,5 +1,6 @@ import React from 'react' -import { Link } from '@mui/material' +import { useNavigate } from 'react-router-dom' +import { Button } from '@mui/material' import { strings as commonStrings } from '@/lang/common' import '@/assets/css/error.css' @@ -10,17 +11,21 @@ interface ErrorProps { homeLink?: boolean } -const Error = ({ message, style, homeLink }: ErrorProps) => ( -
-
- {message} -
- {homeLink && ( -

- {commonStrings.GO_TO_HOME} -

+const Error = ({ message, style, homeLink }: ErrorProps) => { + const navigate = useNavigate() + + return ( +
+
+ {message} +
+ {homeLink && ( +

+ +

)} -
+
) +} export default Error diff --git a/backend/src/components/Header.tsx b/backend/src/components/Header.tsx index e7f2c4b1d..1ae4ff168 100644 --- a/backend/src/components/Header.tsx +++ b/backend/src/components/Header.tsx @@ -11,9 +11,9 @@ import { Button, Drawer, List, - ListItemButton, ListItemIcon, - ListItemText + ListItemText, + ListItem } from '@mui/material' import { Menu as MenuIcon, @@ -44,30 +44,31 @@ import Avatar from './Avatar' import * as langHelper from '@/common/langHelper' import * as helper from '@/common/helper' import { useGlobalContext, GlobalContextType } from '@/context/GlobalContext' +import { useUserContext, UserContextType } from '@/context/UserContext' +import { useInit } from '@/common/customHooks' import '@/assets/css/header.css' interface HeaderProps { - user?: bookcarsTypes.User hidden?: boolean } -const ListItemLink = (props: any) => - const Header = ({ - user, hidden, }: HeaderProps) => { const navigate = useNavigate() + + const { user, setUser, setUserLoaded, setUnauthorized } = useUserContext() as UserContextType const { notificationCount, setNotificationCount } = useGlobalContext() as GlobalContextType + const [currentUser, setCurrentUser] = useState() const [lang, setLang] = useState(helper.getLanguage(env.DEFAULT_LANGUAGE)) const [anchorEl, setAnchorEl] = useState(null) const [langAnchorEl, setLangAnchorEl] = useState(null) const [mobileMoreAnchorEl, setMobileMoreAnchorEl] = useState(null) const [sideAnchorEl, setSideAnchorEl] = useState(null) const [isSignedIn, setIsSignedIn] = useState(false) - const [loading, setIsLoading] = useState(true) + const [loading, setLoading] = useState(true) const [isLoaded, setIsLoaded] = useState(false) const isMenuOpen = Boolean(anchorEl) @@ -159,10 +160,12 @@ const Header = ({ } const handleSettingsClick = () => { + handleMenuClose() navigate('/settings') } const handleSignout = async () => { + handleMenuClose() await UserService.signout() } @@ -182,6 +185,50 @@ const Header = ({ navigate('/notifications') } + const exit = async () => { + setLoading(false) + setUserLoaded(true) + + await UserService.signout(false) + } + + useInit(async () => { + const _currentUser = UserService.getCurrentUser() + + if (_currentUser) { + try { + const status = await UserService.validateAccessToken() + + if (status === 200) { + const _user = await UserService.getUser(_currentUser._id) + + if (_user) { + if (_user.blacklisted) { + setUser(_user) + setUnauthorized(true) + setLoading(false) + return + } + + setUser(_user) + setCurrentUser(_user) + setIsSignedIn(true) + setLoading(false) + setUserLoaded(true) + } else { + await exit() + } + } else { + await exit() + } + } catch { + await exit() + } + } else { + await exit() + } + }) + useEffect(() => { const language = langHelper.getLanguage() setLang(helper.getLanguage(language)) @@ -189,21 +236,27 @@ const Header = ({ }, []) useEffect(() => { - if (!hidden) { - if (user) { - NotificationService.getNotificationCounter(user._id as string) - .then((notificationCounter) => { - setIsSignedIn(true) - setNotificationCount(notificationCounter.count) - setIsLoading(false) - setIsLoaded(true) - }) - } else { - setIsLoading(false) - setIsLoaded(true) + if (user) { + setCurrentUser(user) + } + }, [user]) + + useEffect(() => { + const init = async () => { + if (!hidden) { + if (currentUser) { + const notificationCounter = await NotificationService.getNotificationCounter(currentUser._id as string) + setIsSignedIn(true) + setNotificationCount(notificationCounter.count) + setIsLoaded(true) + } else { + setIsLoaded(true) + } } } - }, [hidden, user, setNotificationCount]) + + init() + }, [hidden, currentUser]) // eslint-disable-line react-hooks/exhaustive-deps const menuId = 'primary-account-menu' const renderMenu = ( @@ -277,8 +330,8 @@ const Header = ({ ) - return ( -
+ return !hidden && !loading && ( +
{isLoaded && !loading && isSignedIn && ( @@ -287,48 +340,98 @@ const Header = ({ )} <> - + - + { + navigate('/') + handleSideMenuClose() + }} + > - - + + { + navigate('/scheduler') + handleSideMenuClose() + }} + > - - + + { + navigate('/suppliers') + handleSideMenuClose() + }} + > - - + + { + navigate('/countries') + handleSideMenuClose() + }} + > - - + + { + navigate('/locations') + handleSideMenuClose() + }} + > - - + + { + navigate('/cars') + handleSideMenuClose() + }} + > - - + + { + navigate('/users') + handleSideMenuClose() + }} + > - - + + { + navigate('/about') + handleSideMenuClose() + }} + > - - + + { + navigate('/tos') + handleSideMenuClose() + }} + > - - + + { + navigate('/contact') + handleSideMenuClose() + }} + > - + diff --git a/backend/src/components/Layout.tsx b/backend/src/components/Layout.tsx index 82b9ae8e5..f592f2234 100644 --- a/backend/src/components/Layout.tsx +++ b/backend/src/components/Layout.tsx @@ -2,98 +2,49 @@ import React, { useState, useEffect, CSSProperties, ReactNode } from 'react' import { Button } from '@mui/material' import * as bookcarsTypes from ':bookcars-types' import { strings } from '@/lang/master' -import Header from './Header' import * as UserService from '@/services/UserService' import Unauthorized from './Unauthorized' import * as helper from '@/common/helper' -import { useInit } from '@/common/customHooks' +import { useUserContext, UserContextType } from '@/context/UserContext' interface LayoutProps { - user?: bookcarsTypes.User strict?: boolean admin?: boolean - hideHeader?: boolean style?: CSSProperties children: ReactNode onLoad?: (user?: bookcarsTypes.User) => void } const Layout = ({ - user: masterUser, strict, admin, - hideHeader, style, children, onLoad }: LayoutProps) => { - const [user, setUser] = useState() + const { user, userLoaded, setUnauthorized, unauthorized } = useUserContext() as UserContextType const [loading, setLoading] = useState(true) - const [unauthorized, setUnauthorized] = useState(false) useEffect(() => { - if (masterUser && user && user.avatar !== masterUser.avatar) { - setUser(masterUser) - } - }, [masterUser, user]) - - useInit(async () => { - const exit = async () => { - if (strict) { - await UserService.signout() + if (userLoaded) { + if (!user && strict) { + UserService.signout(true) } else { - await UserService.signout(false) setLoading(false) if (onLoad) { - onLoad() + onLoad(user || undefined) } } } + }, [user, userLoaded, strict]) // eslint-disable-line react-hooks/exhaustive-deps - const currentUser = UserService.getCurrentUser() - - if (currentUser) { - try { - const status = await UserService.validateAccessToken() - - if (status === 200) { - const _user = await UserService.getUser(currentUser._id) - - if (_user) { - if (_user.blacklisted) { - setUser(_user) - setUnauthorized(true) - setLoading(false) - return - } - - if (admin && _user.type !== bookcarsTypes.RecordType.Admin) { - setUser(_user) - setUnauthorized(true) - setLoading(false) - return - } - - setUser(_user) - setLoading(false) - - if (onLoad) { - onLoad(_user) - } - } else { - await exit() - } - } else { - await exit() - } - } catch { - await exit() - } - } else { - await exit() + useEffect(() => { + if (admin && user && user.type !== bookcarsTypes.RecordType.Admin) { + setUnauthorized(true) + setLoading(false) } - }) + }, [user, admin]) // eslint-disable-line react-hooks/exhaustive-deps const handleResend = async (e: React.MouseEvent) => { e.preventDefault() @@ -118,7 +69,6 @@ const Layout = ({ return ( <> -
diff --git a/backend/src/pages/Error.tsx b/backend/src/pages/Error.tsx index d8a93f5f3..554e6c24d 100644 --- a/backend/src/pages/Error.tsx +++ b/backend/src/pages/Error.tsx @@ -1,16 +1,21 @@ import React from 'react' -import { Link } from '@mui/material' +import { useNavigate } from 'react-router-dom' +import { Button } from '@mui/material' import { strings as commonStrings } from '@/lang/common' interface ErrorProps { style?: React.CSSProperties } -const Error = ({ style }: ErrorProps) => ( -
-

{commonStrings.GENERIC_ERROR}

- {commonStrings.GO_TO_HOME} -
+const Error = ({ style }: ErrorProps) => { + const navigate = useNavigate() + + return ( +
+

{commonStrings.GENERIC_ERROR}

+ +
) +} export default Error diff --git a/backend/src/pages/ForgotPassword.tsx b/backend/src/pages/ForgotPassword.tsx index 027df581c..617b8980d 100644 --- a/backend/src/pages/ForgotPassword.tsx +++ b/backend/src/pages/ForgotPassword.tsx @@ -1,4 +1,5 @@ import React, { useState } from 'react' +import { useNavigate } from 'react-router-dom' import { Input, InputLabel, @@ -6,7 +7,6 @@ import { FormHelperText, Button, Paper, - Link } from '@mui/material' import validator from 'validator' import * as bookcarsTypes from ':bookcars-types' @@ -21,6 +21,8 @@ import env from '@/config/env.config' import '@/assets/css/forgot-password.css' const ForgotPassword = () => { + const navigate = useNavigate() + const [email, setEmail] = useState('') const [visible, setVisible] = useState(false) const [error, setError] = useState(false) @@ -107,6 +109,7 @@ const ForgotPassword = () => { const onLoad = (user?: bookcarsTypes.User) => { if (user) { setNoMatch(true) + setVisible(false) } else { setVisible(true) } @@ -126,7 +129,7 @@ const ForgotPassword = () => {
{strings.EMAIL_SENT}

- {commonStrings.GO_TO_HOME} +

)} @@ -146,7 +149,7 @@ const ForgotPassword = () => { -
diff --git a/backend/src/pages/Locations.tsx b/backend/src/pages/Locations.tsx index a049bedf4..3da424dfa 100644 --- a/backend/src/pages/Locations.tsx +++ b/backend/src/pages/Locations.tsx @@ -1,4 +1,5 @@ import React, { useState } from 'react' +import { useNavigate } from 'react-router-dom' import { Button } from '@mui/material' import * as bookcarsTypes from ':bookcars-types' import Layout from '@/components/Layout' @@ -10,6 +11,8 @@ import InfoBox from '@/components/InfoBox' import '@/assets/css/locations.css' const Locations = () => { + const navigate = useNavigate() + const [keyword, setKeyword] = useState('') const [rowCount, setRowCount] = useState(-1) @@ -37,7 +40,7 @@ const Locations = () => { {rowCount > -1 && ( - )} diff --git a/backend/src/pages/NoMatch.tsx b/backend/src/pages/NoMatch.tsx index c6813d420..935317f8e 100644 --- a/backend/src/pages/NoMatch.tsx +++ b/backend/src/pages/NoMatch.tsx @@ -1,5 +1,6 @@ import React from 'react' -import { Link } from '@mui/material' +import { useNavigate } from 'react-router-dom' +import { Button } from '@mui/material' import { strings as commonStrings } from '@/lang/common' import { strings } from '@/lang/no-match' import Layout from '@/components/Layout' @@ -9,11 +10,13 @@ interface NoMatchProps { } const NoMatch = ({ hideHeader }: NoMatchProps) => { + const navigate = useNavigate() + const noMatch = () => (

{strings.NO_MATCH}

- {commonStrings.GO_TO_HOME} +

) diff --git a/backend/src/pages/ResetPassword.tsx b/backend/src/pages/ResetPassword.tsx index 4bcf77c17..1d589b909 100644 --- a/backend/src/pages/ResetPassword.tsx +++ b/backend/src/pages/ResetPassword.tsx @@ -1,4 +1,5 @@ import React, { useState } from 'react' +import { useNavigate } from 'react-router-dom' import { Input, InputLabel, @@ -7,7 +8,6 @@ import { Button, Paper } from '@mui/material' -import { useNavigate } from 'react-router-dom' import * as bookcarsTypes from ':bookcars-types' import * as UserService from '@/services/UserService' import Layout from '@/components/Layout' @@ -17,11 +17,15 @@ import { strings as rpStrings } from '@/lang/reset-password' import Error from './Error' import NoMatch from './NoMatch' import * as helper from '@/common/helper' +import { useUserContext, UserContextType } from '@/context/UserContext' import '@/assets/css/reset-password.css' const ResetPassword = () => { const navigate = useNavigate() + + const { setUser, setUserLoaded } = useUserContext() as UserContextType + const [userId, setUserId] = useState('') const [email, setEmail] = useState('') const [token, setToken] = useState('') @@ -71,6 +75,10 @@ const ResetPassword = () => { const signInResult = await UserService.signin({ email, password }) if (signInResult.status === 200) { + const user = await UserService.getUser(signInResult.data._id) + setUser(user) + setUserLoaded(true) + const _status = await UserService.deleteTokens(userId) if (_status === 200) { @@ -163,7 +171,7 @@ const ResetPassword = () => { -
diff --git a/backend/src/pages/Scheduler.tsx b/backend/src/pages/Scheduler.tsx index 9343d6b6f..58b64e123 100644 --- a/backend/src/pages/Scheduler.tsx +++ b/backend/src/pages/Scheduler.tsx @@ -1,4 +1,5 @@ import React, { useState } from 'react' +import { useNavigate } from 'react-router-dom' import { Button } from '@mui/material' import * as bookcarsTypes from ':bookcars-types' import * as bookcarsHelper from ':bookcars-helper' @@ -16,6 +17,8 @@ import Layout from '@/components/Layout' import '@/assets/css/scheduler.css' const Scheduler = () => { + const navigate = useNavigate() + const [user, setUser] = useState() const [leftPanel, setLeftPanel] = useState(false) const [admin, setAdmin] = useState(false) @@ -58,7 +61,7 @@ const Scheduler = () => {
{leftPanel && ( <> - {admin diff --git a/backend/src/pages/Settings.tsx b/backend/src/pages/Settings.tsx index a7f45cf7d..81dcd42b1 100644 --- a/backend/src/pages/Settings.tsx +++ b/backend/src/pages/Settings.tsx @@ -1,4 +1,5 @@ import React, { useState } from 'react' +import { useNavigate } from 'react-router-dom' import { Input, InputLabel, @@ -19,11 +20,15 @@ import * as UserService from '@/services/UserService' import Backdrop from '@/components/SimpleBackdrop' import Avatar from '@/components/Avatar' import * as helper from '@/common/helper' +import { useUserContext, UserContextType } from '@/context/UserContext' import '@/assets/css/settings.css' const Settings = () => { - const [user, setUser] = useState() + const navigate = useNavigate() + + const { user, setUser } = useUserContext() as UserContextType + const [admin, setAdmin] = useState(false) const [fullName, setFullName] = useState('') const [phone, setPhone] = useState('') @@ -154,7 +159,7 @@ const Settings = () => { } return ( - + {visible && user && (
@@ -164,8 +169,7 @@ const Settings = () => { mode="update" record={user} size="large" - // readonly={false} - readonly + readonly={false} onBeforeUpload={onBeforeUpload} onChange={onAvatarChange} hideDelete={!admin} @@ -194,13 +198,13 @@ const Settings = () => {
- - -
diff --git a/backend/src/pages/SignIn.tsx b/backend/src/pages/SignIn.tsx index 9b895cec9..8bab2cd7f 100644 --- a/backend/src/pages/SignIn.tsx +++ b/backend/src/pages/SignIn.tsx @@ -1,13 +1,12 @@ import React, { useState, useEffect } from 'react' +import { useNavigate } from 'react-router-dom' import { Paper, FormControl, InputLabel, Input, Button, - Link } from '@mui/material' -import { useNavigate } from 'react-router-dom' import * as bookcarsTypes from ':bookcars-types' import { strings as commonStrings } from '@/lang/common' import { strings } from '@/lang/sign-in' @@ -15,11 +14,15 @@ import * as UserService from '@/services/UserService' import Header from '@/components/Header' import Error from '@/components/Error' import * as langHelper from '@/common/langHelper' +import { useUserContext, UserContextType } from '@/context/UserContext' import '@/assets/css/signin.css' const SignIn = () => { const navigate = useNavigate() + + const { setUser, setUserLoaded } = useUserContext() as UserContextType + const [email, setEmail] = useState('') const [password, setPassword] = useState('') const [error, setError] = useState(false) @@ -55,6 +58,10 @@ const SignIn = () => { } else { setError(false) + const user = await UserService.getUser(res.data._id) + setUser(user) + setUserLoaded(true) + const params = new URLSearchParams(window.location.search) if (params.has('u')) { @@ -148,7 +155,7 @@ const SignIn = () => {
- {strings.RESET_PASSWORD} +
diff --git a/backend/src/pages/SignUp.tsx b/backend/src/pages/SignUp.tsx index e498fbff9..66645bef0 100644 --- a/backend/src/pages/SignUp.tsx +++ b/backend/src/pages/SignUp.tsx @@ -17,11 +17,15 @@ import Layout from '@/components/Layout' import Error from '@/components/Error' import Backdrop from '@/components/SimpleBackdrop' import * as helper from '@/common/helper' +import { useUserContext, UserContextType } from '@/context/UserContext' import '@/assets/css/signup.css' const SignUp = () => { const navigate = useNavigate() + + const { setUser, setUserLoaded } = useUserContext() as UserContextType + const [fullName, setFullName] = useState('') const [email, setEmail] = useState('') const [password, setPassword] = useState('') @@ -132,6 +136,9 @@ const SignUp = () => { }) if (signInResult.status === 200) { + const user = await UserService.getUser(signInResult.data._id) + setUser(user) + setUserLoaded(true) navigate(`/${window.location.search}`) } else { setPasswordError(false) @@ -221,7 +228,7 @@ const SignUp = () => { - diff --git a/backend/src/pages/Supplier.tsx b/backend/src/pages/Supplier.tsx index 1655b917c..c236a6f92 100644 --- a/backend/src/pages/Supplier.tsx +++ b/backend/src/pages/Supplier.tsx @@ -1,4 +1,5 @@ import React, { useState } from 'react' +import { useNavigate } from 'react-router-dom' import { Typography, IconButton, @@ -11,7 +12,6 @@ import { Link } from '@mui/material' import { Edit as EditIcon, Delete as DeleteIcon } from '@mui/icons-material' -import { useNavigate } from 'react-router-dom' import * as bookcarsTypes from ':bookcars-types' import * as bookcarsHelper from ':bookcars-helper' import env from '@/config/env.config' @@ -135,7 +135,7 @@ const Supplier = () => { const edit = user && supplier && (user.type === bookcarsTypes.RecordType.Admin || user._id === supplier._id) return ( - + {visible && supplier && suppliers && (
@@ -149,8 +149,7 @@ const Supplier = () => { hideDelete onBeforeUpload={onBeforeUpload} onChange={onAvatarChange} - // readonly={!edit} - readonly + readonly={!edit} color="disabled" className="supplier-avatar" /> @@ -170,7 +169,9 @@ const Supplier = () => { )} {supplier.bio && ( helper.isValidURL(supplier.bio) - ? ({supplier.bio}) : ( + ? ( + {supplier.bio} + ) : ( {supplier.bio} @@ -189,18 +190,18 @@ const Supplier = () => {
{edit && ( - + navigate(`/update-supplier?c=${supplier._id}`)}> )} - {/* {edit && ( + {edit && ( - )} */} + )}
{rowCount > 0 && 1 ? commonStrings.CARS : commonStrings.CAR}`} className="car-count" />}
diff --git a/backend/src/pages/Suppliers.tsx b/backend/src/pages/Suppliers.tsx index d320146f8..27ac43e76 100644 --- a/backend/src/pages/Suppliers.tsx +++ b/backend/src/pages/Suppliers.tsx @@ -1,4 +1,5 @@ import React, { useState } from 'react' +import { useNavigate } from 'react-router-dom' import { Button } from '@mui/material' import * as bookcarsTypes from ':bookcars-types' import Layout from '@/components/Layout' @@ -11,6 +12,8 @@ import * as helper from '@/common/helper' import '@/assets/css/suppliers.css' const Suppliers = () => { + const navigate = useNavigate() + const [user, setUser] = useState() const [keyword, setKeyword] = useState('') const [rowCount, setRowCount] = useState(-1) @@ -49,7 +52,7 @@ const Suppliers = () => { variant="contained" className="btn-primary new-supplier" size="small" - href="/create-supplier" + onClick={() => navigate('/create-supplier')} > {strings.NEW_SUPPLIER} diff --git a/backend/src/pages/UpdateBooking.tsx b/backend/src/pages/UpdateBooking.tsx index 3bb0b9f60..9820b893d 100644 --- a/backend/src/pages/UpdateBooking.tsx +++ b/backend/src/pages/UpdateBooking.tsx @@ -1,4 +1,5 @@ import React, { useState, useCallback } from 'react' +import { useNavigate } from 'react-router-dom' import { FormControl, FormControlLabel, @@ -19,7 +20,6 @@ import { import { DateTimeValidationError } from '@mui/x-date-pickers' import validator from 'validator' import { intervalToDuration } from 'date-fns' -import { useNavigate } from 'react-router-dom' import * as bookcarsTypes from ':bookcars-types' import * as bookcarsHelper from ':bookcars-helper' import env from '@/config/env.config' @@ -447,7 +447,7 @@ const UpdateBooking = () => { if (!helper.admin(_user) && (_booking.supplier as bookcarsTypes.User)._id !== _user._id) { setLoading(false) setNoMatch(true) - return + return } if (!_booking.driver) { @@ -819,10 +819,10 @@ const UpdateBooking = () => { - {/* */} - +
diff --git a/backend/src/pages/UpdateCar.tsx b/backend/src/pages/UpdateCar.tsx index 44de87351..02a1e1ba1 100644 --- a/backend/src/pages/UpdateCar.tsx +++ b/backend/src/pages/UpdateCar.tsx @@ -1,4 +1,5 @@ import React, { useState } from 'react' +import { useNavigate } from 'react-router-dom' import { Input, InputLabel, @@ -37,6 +38,8 @@ import CarRangeList from '@/components/CarRangeList' import '@/assets/css/create-car.css' const UpdateCar = () => { + const navigate = useNavigate() + const [user, setUser] = useState() const [car, setCar] = useState() const [noMatch, setNoMatch] = useState(false) @@ -800,7 +803,7 @@ const UpdateCar = () => { -
diff --git a/backend/src/pages/UpdateCountry.tsx b/backend/src/pages/UpdateCountry.tsx index 26870784c..42867571c 100644 --- a/backend/src/pages/UpdateCountry.tsx +++ b/backend/src/pages/UpdateCountry.tsx @@ -1,4 +1,5 @@ import React, { useState } from 'react' +import { useNavigate } from 'react-router-dom' import { Input, InputLabel, @@ -23,6 +24,8 @@ import env from '@/config/env.config' import '@/assets/css/update-country.css' const UpdateCountry = () => { + const navigate = useNavigate() + const [visible, setVisible] = useState(false) const [loading, setLoading] = useState(false) const [names, setNames] = useState([]) @@ -199,7 +202,7 @@ const UpdateCountry = () => { -
diff --git a/backend/src/pages/UpdateLocation.tsx b/backend/src/pages/UpdateLocation.tsx index d1608c0a0..96986f2c5 100644 --- a/backend/src/pages/UpdateLocation.tsx +++ b/backend/src/pages/UpdateLocation.tsx @@ -1,4 +1,5 @@ import React, { useState } from 'react' +import { useNavigate } from 'react-router-dom' import { Input, InputLabel, @@ -27,6 +28,8 @@ import ParkingSpotEditList from '@/components/ParkingSpotEditList' import '@/assets/css/update-location.css' const UpdateLocation = () => { + const navigate = useNavigate() + const [visible, setVisible] = useState(false) const [loading, setLoading] = useState(false) const [names, setNames] = useState([]) @@ -290,7 +293,7 @@ const UpdateLocation = () => { -
diff --git a/backend/src/pages/UpdateSupplier.tsx b/backend/src/pages/UpdateSupplier.tsx index 5ae1bbd21..5bb5fac5b 100644 --- a/backend/src/pages/UpdateSupplier.tsx +++ b/backend/src/pages/UpdateSupplier.tsx @@ -1,4 +1,5 @@ import React, { useState } from 'react' +import { useNavigate } from 'react-router-dom' import { Input, InputLabel, @@ -29,6 +30,8 @@ import ContractList from '@/components/ContractList' import '@/assets/css/update-supplier.css' const UpdateSupplier = () => { + const navigate = useNavigate() + const [user, setUser] = useState() const [supplier, setSupplier] = useState() const [fullName, setFullName] = useState('') @@ -268,7 +271,7 @@ const UpdateSupplier = () => { const admin = helper.admin(user) return ( - + {visible && (
@@ -375,13 +378,13 @@ const UpdateSupplier = () => { )}
- -
diff --git a/backend/src/pages/UpdateUser.tsx b/backend/src/pages/UpdateUser.tsx index b2d95ed14..3d5e097b6 100644 --- a/backend/src/pages/UpdateUser.tsx +++ b/backend/src/pages/UpdateUser.tsx @@ -1,4 +1,5 @@ import React, { useState } from 'react' +import { useNavigate } from 'react-router-dom' import { Input, InputLabel, @@ -15,7 +16,6 @@ import { import { Info as InfoIcon } from '@mui/icons-material' import { intervalToDuration } from 'date-fns' import validator from 'validator' -import { useNavigate } from 'react-router-dom' import * as bookcarsTypes from ':bookcars-types' import * as bookcarsHelper from ':bookcars-helper' import Layout from '@/components/Layout' @@ -38,6 +38,7 @@ import '@/assets/css/update-user.css' const UpdateUser = () => { const navigate = useNavigate() + const [loggedUser, setLoggedUser] = useState() const [user, setUser] = useState() const [visible, setVisible] = useState(false) @@ -332,7 +333,7 @@ const UpdateUser = () => { || (loggedUser && user && loggedUser.type === bookcarsTypes.RecordType.Supplier && user.type === bookcarsTypes.RecordType.User && user.supplier as string === loggedUser._id) return ( - + {loggedUser && user && visible && (
@@ -486,7 +487,7 @@ const UpdateUser = () => { )}
- diff --git a/backend/src/pages/User.tsx b/backend/src/pages/User.tsx index 256c7b191..f48e07701 100644 --- a/backend/src/pages/User.tsx +++ b/backend/src/pages/User.tsx @@ -1,4 +1,5 @@ import React, { useState, useEffect } from 'react' +import { useNavigate } from 'react-router-dom' import { Typography, IconButton, @@ -11,7 +12,6 @@ import { Link, } from '@mui/material' import { Edit as EditIcon, Delete as DeleteIcon } from '@mui/icons-material' -import { useNavigate } from 'react-router-dom' import * as bookcarsTypes from ':bookcars-types' import * as bookcarsHelper from ':bookcars-helper' import env from '@/config/env.config' @@ -30,6 +30,7 @@ import '@/assets/css/user.css' const User = () => { const navigate = useNavigate() + const statuses = helper.getBookingStatuses().map((status) => status.value) const [loggedUser, setLoggedUser] = useState() @@ -200,18 +201,18 @@ const User = () => {
{edit && ( - + navigate(`/update-user?u=${user._id}`)}> )} - {/* {edit && ( + {edit && ( - )} */} + )}
diff --git a/backend/src/pages/Users.tsx b/backend/src/pages/Users.tsx index 4e1ecb76d..1a9b3f58d 100644 --- a/backend/src/pages/Users.tsx +++ b/backend/src/pages/Users.tsx @@ -1,4 +1,5 @@ import React, { useState } from 'react' +import { useNavigate } from 'react-router-dom' import { Button } from '@mui/material' import * as bookcarsTypes from ':bookcars-types' import Layout from '@/components/Layout' @@ -12,6 +13,8 @@ import UserList from '@/components/UserList' import '@/assets/css/users.css' const Users = () => { + const navigate = useNavigate() + const [user, setUser] = useState() const [admin, setAdmin] = useState(false) const [types, setTypes] = useState() @@ -46,13 +49,13 @@ const Users = () => { {admin && ( - -)} + + )} -
diff --git a/backend/tsconfig.json b/backend/tsconfig.json index d2fcaab6a..21dadb7da 100644 --- a/backend/tsconfig.json +++ b/backend/tsconfig.json @@ -17,7 +17,7 @@ /* Linting */ "strict": true, "noUnusedLocals": false, - "noUnusedParameters": true, + "noUnusedParameters": false, "noFallthroughCasesInSwitch": true, "paths": { diff --git a/frontend/.env.docker.example b/frontend/.env.docker.example index b16822979..2c6b93078 100644 --- a/frontend/.env.docker.example +++ b/frontend/.env.docker.example @@ -34,3 +34,4 @@ VITE_BC_APPLE_ID=XXXXXXXXXX VITE_BC_GG_APP_ID=XXXXXXXXXX VITE_BC_MIN_LOCATIONS=4 VITE_BC_WEBSITE_NAME=BookCars +VITE_BC_HIDE_SUPPLIERS=false diff --git a/frontend/.env.example b/frontend/.env.example index c82f6e469..2b0b747d7 100644 --- a/frontend/.env.example +++ b/frontend/.env.example @@ -35,3 +35,4 @@ VITE_BC_APPLE_ID=XXXXXXXXXX VITE_BC_GG_APP_ID=XXXXXXXXXX VITE_BC_MIN_LOCATIONS=4 VITE_BC_WEBSITE_NAME=BookCars +VITE_BC_HIDE_SUPPLIERS=false diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 109b4fa8a..cd404ef7e 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -10,16 +10,16 @@ "dependencies": { "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.0", - "@mui/icons-material": "^6.4.1", - "@mui/material": "^6.4.1", - "@mui/x-data-grid": "^7.24.1", - "@mui/x-date-pickers": "^7.24.1", + "@mui/icons-material": "^6.4.2", + "@mui/material": "^6.4.2", + "@mui/x-data-grid": "^7.25.0", + "@mui/x-date-pickers": "^7.25.0", "@paypal/react-paypal-js": "^8.8.1", "@stripe/react-stripe-js": "^3.1.1", - "@stripe/stripe-js": "^5.5.0", + "@stripe/stripe-js": "^5.6.0", "@types/leaflet": "^1.9.16", "@types/leaflet-boundary-canvas": "^1.0.3", - "@types/node": "^22.12.0", + "@types/node": "^22.13.0", "@types/nprogress": "^0.2.3", "@types/react": "^19.0.8", "@types/react-dom": "^19.0.3", @@ -46,7 +46,7 @@ "react-dom": "^19.0.0", "react-ga4": "^2.1.0", "react-leaflet": "^5.0.0", - "react-router-dom": "^7.1.3", + "react-router-dom": "^7.1.5", "react-slick": "^0.30.3", "react-toastify": "^11.0.3", "slick-carousel": "^1.8.1", @@ -1409,9 +1409,9 @@ } }, "node_modules/@mui/core-downloads-tracker": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.4.1.tgz", - "integrity": "sha512-SfDLWMV5b5oXgDf3NTa2hCTPC1d2defhDH2WgFKmAiejC4mSfXYbyi+AFCLzpizauXhgBm8OaZy9BHKnrSpahQ==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.4.2.tgz", + "integrity": "sha512-Qmod9fHsFWrtLxdSkZ4iDLRz2AUKt3C2ZEimuY+qKlQGVKJDNS5DuSlNOAgqfHFDq8mzB17ATN6HFcThwJlvUw==", "license": "MIT", "funding": { "type": "opencollective", @@ -1419,9 +1419,9 @@ } }, "node_modules/@mui/icons-material": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.4.1.tgz", - "integrity": "sha512-wsxFcUTQxt4s+7Bg4GgobqRjyaHLmZGNOs+HJpbwrwmLbT6mhIJxhpqsKzzWq9aDY8xIe7HCjhpH7XI5UD6teA==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.4.2.tgz", + "integrity": "sha512-uwsH1KRmxkJwK3NZyo1xL9pEduL16ftCnzYBYjd6nPNtm05QAoIc0aqedS9tqDV+Ab3q5C04HHOVsMDDv1EBpg==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0" @@ -1434,7 +1434,7 @@ "url": "https://opencollective.com/mui-org" }, "peerDependencies": { - "@mui/material": "^6.4.1", + "@mui/material": "^6.4.2", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, @@ -1445,16 +1445,16 @@ } }, "node_modules/@mui/material": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.4.1.tgz", - "integrity": "sha512-MFBfia6UiKxyoLeGkAh8M15bkeDmfnsUTMRJd/vTQue6YQ8AQ6lw9HqDthyYghzDEWIvZO/lQQzLrZE8XwNJLA==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.4.2.tgz", + "integrity": "sha512-9jKr53KbAJyyBRx8LRmX7ATXHlGtxVQdPgm1uyXMoEPMVkSJW1yO3vFgfYoDbGx4ZHcCNuWa4FkFIPWVt9fghA==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0", - "@mui/core-downloads-tracker": "^6.4.1", - "@mui/system": "^6.4.1", + "@mui/core-downloads-tracker": "^6.4.2", + "@mui/system": "^6.4.2", "@mui/types": "^7.2.21", - "@mui/utils": "^6.4.1", + "@mui/utils": "^6.4.2", "@popperjs/core": "^2.11.8", "@types/react-transition-group": "^4.4.12", "clsx": "^2.1.1", @@ -1473,7 +1473,7 @@ "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", - "@mui/material-pigment-css": "^6.4.1", + "@mui/material-pigment-css": "^6.4.2", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" @@ -1494,13 +1494,13 @@ } }, "node_modules/@mui/private-theming": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.4.1.tgz", - "integrity": "sha512-DcT7mwK89owwgcEuiE7w458te4CIjHbYWW6Kn6PiR6eLtxBsoBYphA968uqsQAOBQDpbYxvkuFLwhgk4bxoN/Q==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.4.2.tgz", + "integrity": "sha512-2CkQT0gNlogM50qGTBJgWA7hPPx4AeH8RE2xJa+PHtIOowiVPX52ZsQ0e7Ho18DAqEbkngQ6Uju037ER+TCY5A==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0", - "@mui/utils": "^6.4.1", + "@mui/utils": "^6.4.2", "prop-types": "^15.8.1" }, "engines": { @@ -1521,9 +1521,9 @@ } }, "node_modules/@mui/styled-engine": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.4.0.tgz", - "integrity": "sha512-ek/ZrDujrger12P6o4luQIfRd2IziH7jQod2WMbLqGE03Iy0zUwYmckRTVhRQTLPNccpD8KXGcALJF+uaUQlbg==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.4.2.tgz", + "integrity": "sha512-cgjQK2bkllSYoWUBv93ALhCPJ0NhfO3NctsBf13/b4XSeQVfKPBAnR+P9mNpdFMa5a5RWwtWuBD3cZ5vktsN+g==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0", @@ -1555,16 +1555,16 @@ } }, "node_modules/@mui/system": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.4.1.tgz", - "integrity": "sha512-rgQzgcsHCTtzF9MZ+sL0tOhf2ZBLazpjrujClcb4Siju5lTrK0xX4PsiropActzCemNfM+mOu+0jezAVnfRK8g==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.4.2.tgz", + "integrity": "sha512-wQbaPCtsxNsM5nR+NZpkFJBKVKH03GQnAjlkKENM8JQqGdWcRyM3f4fJZgzzNdIFpSQw4wpAQKnhfHkjf3d6yQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0", - "@mui/private-theming": "^6.4.1", - "@mui/styled-engine": "^6.4.0", + "@mui/private-theming": "^6.4.2", + "@mui/styled-engine": "^6.4.2", "@mui/types": "^7.2.21", - "@mui/utils": "^6.4.1", + "@mui/utils": "^6.4.2", "clsx": "^2.1.1", "csstype": "^3.1.3", "prop-types": "^15.8.1" @@ -1609,9 +1609,9 @@ } }, "node_modules/@mui/utils": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.4.1.tgz", - "integrity": "sha512-iQUDUeYh87SvR4lVojaRaYnQix8BbRV51MxaV6MBmqthecQoxwSbS5e2wnbDJUeFxY2ppV505CiqPLtd0OWkqw==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.4.2.tgz", + "integrity": "sha512-5NkhzlJkmR5+5RSs/Irqin1GPy2Z8vbLk/UzQrH9FEAnm6OA9SvuXjzgklxUs7N65VwEkGpKK1jMZ5K84hRdzQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0", @@ -1639,14 +1639,14 @@ } }, "node_modules/@mui/x-data-grid": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-7.24.1.tgz", - "integrity": "sha512-4sYTbMwsDotuTd2Cwa2JGTPXPWQs8RGJvocAKnIsNOzNdZNMrikE//HO35snriK8s4dauAApY7RVbeisjpVT+A==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-7.25.0.tgz", + "integrity": "sha512-e9ZLbCgnDiADFiDyXo91ucZFHEMkKBNpwpkaTq5KohzefJfMpMQjTEbJeueSfBG2G1Q1Am2TPeBqrNeReIA7RQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.25.7", "@mui/utils": "^5.16.6 || ^6.0.0", - "@mui/x-internals": "7.24.1", + "@mui/x-internals": "7.25.0", "clsx": "^2.1.1", "prop-types": "^15.8.1", "reselect": "^5.1.1" @@ -1676,14 +1676,14 @@ } }, "node_modules/@mui/x-date-pickers": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-7.24.1.tgz", - "integrity": "sha512-ykQugMQHuQKBk3kViW/r0PpubtHQOlrd54bgbdafgTMCeM2VpXvv4zimzOu5IGnM6wEN8hupC7EXZbkrT6x46w==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-7.25.0.tgz", + "integrity": "sha512-t62OSFAKwj7KYQ8KcwTuKj6OgDuLQPSe4QUJcKDzD9rEhRIJVRUw2x27gBSdcls4l0PTrba19TghvDxCZprriw==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.25.7", "@mui/utils": "^5.16.6 || ^6.0.0", - "@mui/x-internals": "7.24.1", + "@mui/x-internals": "7.25.0", "@types/react-transition-group": "^4.4.11", "clsx": "^2.1.1", "prop-types": "^15.8.1", @@ -1742,9 +1742,9 @@ } }, "node_modules/@mui/x-internals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-7.24.1.tgz", - "integrity": "sha512-9BvJzpLJnS9BDphvkiv6v0QOLxbnu8jhwcexFjtCQ2ZyxtVuVsWzGZ2npT9sGOil7+eaFDmWnJtea/tgrPvSwQ==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-7.25.0.tgz", + "integrity": "sha512-tBUN54YznAkmtCIRAOl35Kgl0MjFDIjUbzIrbWRgVSIR3QJ8bXnVSkiRBi+P91SZEl9+ZW0rDj+osq7xFJV0kg==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.25.7", @@ -2133,9 +2133,9 @@ } }, "node_modules/@stripe/stripe-js": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@stripe/stripe-js/-/stripe-js-5.5.0.tgz", - "integrity": "sha512-lkfjyAd34aeMpTKKcEVfy8IUyEsjuAT3t9EXr5yZDtdIUncnZpedl/xLV16Dkd4z+fQwixScsCCDxSMNtBOgpQ==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@stripe/stripe-js/-/stripe-js-5.6.0.tgz", + "integrity": "sha512-w8CEY73X/7tw2KKlL3iOk679V9bWseE4GzNz3zlaYxcTjmcmWOathRb0emgo/QQ3eoNzmq68+2Y2gxluAv3xGw==", "license": "MIT", "engines": { "node": ">=12.16" @@ -2228,9 +2228,9 @@ } }, "node_modules/@types/node": { - "version": "22.12.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.12.0.tgz", - "integrity": "sha512-Fll2FZ1riMjNmlmJOdAyY5pUbkftXslB5DgEzlIuNaiWhXd00FhWxVC/r4yV/4wBb9JfImTu+jiSvXTkJ7F/gA==", + "version": "22.13.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.0.tgz", + "integrity": "sha512-ClIbNe36lawluuvq3+YYhnIN2CELi+6q8NpnM7PYp4hBn/TatfboPgVSm2rwKRfnV2M+Ty9GWDFI64KEe+kysA==", "license": "MIT", "dependencies": { "undici-types": "~6.20.0" @@ -6897,9 +6897,9 @@ } }, "node_modules/react-router": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.1.3.tgz", - "integrity": "sha512-EezYymLY6Guk/zLQ2vRA8WvdUhWFEj5fcE3RfWihhxXBW7+cd1LsIiA3lmx+KCmneAGQuyBv820o44L2+TtkSA==", + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.1.5.tgz", + "integrity": "sha512-8BUF+hZEU4/z/JD201yK6S+UYhsf58bzYIDq2NS1iGpwxSXDu7F+DeGSkIXMFBuHZB21FSiCzEcUb18cQNdRkA==", "license": "MIT", "dependencies": { "@types/cookie": "^0.6.0", @@ -6921,12 +6921,12 @@ } }, "node_modules/react-router-dom": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.1.3.tgz", - "integrity": "sha512-qQGTE+77hleBzv9SIUIkGRvuFBQGagW+TQKy53UTZAO/3+YFNBYvRsNIZ1GT17yHbc63FylMOdS+m3oUriF1GA==", + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.1.5.tgz", + "integrity": "sha512-/4f9+up0Qv92D3bB8iN5P1s3oHAepSGa9h5k6tpTFlixTTskJZwKGhJ6vRJ277tLD1zuaZTt95hyGWV1Z37csQ==", "license": "MIT", "dependencies": { - "react-router": "7.1.3" + "react-router": "7.1.5" }, "engines": { "node": ">=20.0.0" diff --git a/frontend/package.json b/frontend/package.json index 815dcaaaa..672483815 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "frontend", - "version": "5.5.0", + "version": "5.6.0", "private": true, "type": "module", "scripts": { @@ -20,16 +20,16 @@ "dependencies": { "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.0", - "@mui/icons-material": "^6.4.1", - "@mui/material": "^6.4.1", - "@mui/x-data-grid": "^7.24.1", - "@mui/x-date-pickers": "^7.24.1", + "@mui/icons-material": "^6.4.2", + "@mui/material": "^6.4.2", + "@mui/x-data-grid": "^7.25.0", + "@mui/x-date-pickers": "^7.25.0", "@paypal/react-paypal-js": "^8.8.1", "@stripe/react-stripe-js": "^3.1.1", - "@stripe/stripe-js": "^5.5.0", + "@stripe/stripe-js": "^5.6.0", "@types/leaflet": "^1.9.16", "@types/leaflet-boundary-canvas": "^1.0.3", - "@types/node": "^22.12.0", + "@types/node": "^22.13.0", "@types/nprogress": "^0.2.3", "@types/react": "^19.0.8", "@types/react-dom": "^19.0.3", @@ -56,7 +56,7 @@ "react-dom": "^19.0.0", "react-ga4": "^2.1.0", "react-leaflet": "^5.0.0", - "react-router-dom": "^7.1.3", + "react-router-dom": "^7.1.5", "react-slick": "^0.30.3", "react-toastify": "^11.0.3", "slick-carousel": "^1.8.1", diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index a8390a220..4f3a06aae 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -70,7 +70,7 @@ const App = () => ( } /> } /> } /> - } /> + {!env.HIDE_SUPPLIERS && } />} } /> } /> diff --git a/frontend/src/components/Footer.tsx b/frontend/src/components/Footer.tsx index 7c8f04cae..a266c396d 100644 --- a/frontend/src/components/Footer.tsx +++ b/frontend/src/components/Footer.tsx @@ -34,7 +34,7 @@ const Footer = () => {
{strings.RENT}
    -
  • navigate('/suppliers')}>{strings.SUPPLIERS}
  • + {!env.HIDE_SUPPLIERS &&
  • navigate('/suppliers')}>{strings.SUPPLIERS}
  • }
  • navigate('/locations')}>{strings.LOCATIONS}
diff --git a/frontend/src/components/Header.tsx b/frontend/src/components/Header.tsx index b28996fb7..62b551477 100644 --- a/frontend/src/components/Header.tsx +++ b/frontend/src/components/Header.tsx @@ -428,15 +428,17 @@ const Header = ({ )} - { - navigate('/suppliers') - handleSideMenuClose() - }} - > - - - + {!env.HIDE_SUPPLIERS && ( + { + navigate('/suppliers') + handleSideMenuClose() + }} + > + + + + )} { navigate('/locations') diff --git a/frontend/src/components/Layout.tsx b/frontend/src/components/Layout.tsx index a1eff1f5f..e3d3acb4e 100644 --- a/frontend/src/components/Layout.tsx +++ b/frontend/src/components/Layout.tsx @@ -24,14 +24,16 @@ const Layout = ({ const [loading, setLoading] = useState(true) useEffect(() => { - if (userLoaded && !user && strict) { - // UserService.signout(false, true) - UserService.signout(true, false) - } else { - setLoading(false) + if (userLoaded) { + if (!user && strict) { + // UserService.signout(false, true) + UserService.signout(true, false) + } else { + setLoading(false) - if (onLoad) { - onLoad(user || undefined) + if (onLoad) { + onLoad(user || undefined) + } } } }, [user, userLoaded, strict]) // eslint-disable-line react-hooks/exhaustive-deps diff --git a/frontend/src/config/env.config.ts b/frontend/src/config/env.config.ts index 53ebbb147..99d68b093 100644 --- a/frontend/src/config/env.config.ts +++ b/frontend/src/config/env.config.ts @@ -128,6 +128,7 @@ const env = { * Minimum number of locations required for country tabs in homepage. */ MIN_LOCATIONS: Number.parseInt(String(import.meta.env.VITE_BC_MIN_LOCATIONS), 10) || 4, + HIDE_SUPPLIERS: (import.meta.env.VITE_BC_HIDE_SUPPLIERS && import.meta.env.VITE_BC_HIDE_SUPPLIERS.toLowerCase()) === 'true', } export default env diff --git a/frontend/src/pages/Booking.tsx b/frontend/src/pages/Booking.tsx index e2608082f..80d93c32f 100644 --- a/frontend/src/pages/Booking.tsx +++ b/frontend/src/pages/Booking.tsx @@ -319,16 +319,18 @@ const Booking = () => {
- - - + {!env.HIDE_SUPPLIERS && ( + + + + )} { booking={booking} cars={[booking.car as bookcarsTypes.Car]} hidePrice + hideSupplier={env.HIDE_SUPPLIERS} />
diff --git a/frontend/src/pages/Bookings.tsx b/frontend/src/pages/Bookings.tsx index 346c14c7d..bfa581c87 100644 --- a/frontend/src/pages/Bookings.tsx +++ b/frontend/src/pages/Bookings.tsx @@ -68,6 +68,7 @@ const Bookings = () => { hideDates={env.isMobile} checkboxSelection={false} onLoad={() => setLoadingPage(false)} + hideSupplierColumn={env.HIDE_SUPPLIERS} />
diff --git a/frontend/src/pages/Checkout.tsx b/frontend/src/pages/Checkout.tsx index 160e58b6b..32cbfd391 100644 --- a/frontend/src/pages/Checkout.tsx +++ b/frontend/src/pages/Checkout.tsx @@ -578,7 +578,7 @@ const Checkout = () => { hidePrice sizeAuto onLoad={() => setLoadingPage(false)} - // hideSupplier + hideSupplier={env.HIDE_SUPPLIERS} /> { {strings.CAR}
{`${car.name} (${bookcarsHelper.formatPrice(price / days, commonStrings.CURRENCY, language)}${commonStrings.DAILY})`}
-
- {commonStrings.SUPPLIER} -
-
- {car.supplier.fullName} - {car.supplier.fullName} + {!env.HIDE_SUPPLIERS && ( +
+ {commonStrings.SUPPLIER} +
+
+ {car.supplier.fullName} + {car.supplier.fullName} +
-
+ )}
{strings.COST}
{bookcarsHelper.formatPrice(price, commonStrings.CURRENCY, language)}
diff --git a/frontend/src/pages/ForgotPassword.tsx b/frontend/src/pages/ForgotPassword.tsx index a73c31284..4383586c6 100644 --- a/frontend/src/pages/ForgotPassword.tsx +++ b/frontend/src/pages/ForgotPassword.tsx @@ -110,6 +110,7 @@ const ForgotPassword = () => { const onLoad = (user?: bookcarsTypes.User) => { if (user) { setNoMatch(true) + setVisible(false) } else { setVisible(true) } @@ -149,7 +150,7 @@ const ForgotPassword = () => {
-