From c37aee97a9142ee7bed4c5c603430ab9c4206d8c Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Fri, 22 Mar 2024 08:56:25 +0800 Subject: [PATCH 01/69] added pages with router and navbar --- .gitignore | 2 + package-lock.json | 988 +++++++++++++++++- package.json | 5 + src/App.js | 76 +- src/components/navbar.js | 40 + src/firebase/firebase.js | 18 + src/index.js | 7 +- src/pages/adminPages/adminAnalyticsPage.js | 8 + .../adminPages/adminEventAttendancePage.js | 8 + src/pages/adminPages/adminEventPage.js | 8 + src/pages/adminPages/adminHomePage.js | 14 + src/pages/adminPages/adminProfilePage.js | 8 + src/pages/errorPage.js | 8 + src/pages/registerPage.js | 8 + src/pages/resetPasswordPage.js | 8 + src/pages/signInPage.js | 8 + src/pages/userPages/eventBookingPage.js | 8 + src/pages/userPages/eventDetailPage.js | 8 + src/pages/userPages/favPage.js | 8 + src/pages/userPages/homePage.js | 8 + src/pages/userPages/myBookingPage.js | 8 + src/pages/userPages/myProfilePage.js | 8 + src/pages/userPages/paymentPage.js | 8 + 23 files changed, 1244 insertions(+), 26 deletions(-) create mode 100644 src/components/navbar.js create mode 100644 src/firebase/firebase.js create mode 100644 src/pages/adminPages/adminAnalyticsPage.js create mode 100644 src/pages/adminPages/adminEventAttendancePage.js create mode 100644 src/pages/adminPages/adminEventPage.js create mode 100644 src/pages/adminPages/adminHomePage.js create mode 100644 src/pages/adminPages/adminProfilePage.js create mode 100644 src/pages/errorPage.js create mode 100644 src/pages/registerPage.js create mode 100644 src/pages/resetPasswordPage.js create mode 100644 src/pages/signInPage.js create mode 100644 src/pages/userPages/eventBookingPage.js create mode 100644 src/pages/userPages/eventDetailPage.js create mode 100644 src/pages/userPages/favPage.js create mode 100644 src/pages/userPages/homePage.js create mode 100644 src/pages/userPages/myBookingPage.js create mode 100644 src/pages/userPages/myProfilePage.js create mode 100644 src/pages/userPages/paymentPage.js diff --git a/.gitignore b/.gitignore index 4d29575d..8b182cf8 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,5 @@ npm-debug.log* yarn-debug.log* yarn-error.log* + +.env diff --git a/package-lock.json b/package-lock.json index 35392e08..a0d88b05 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,8 +8,13 @@ "name": "project-3-frontend-bootcamp", "version": "0.1.0", "dependencies": { + "@emotion/react": "^11.11.4", + "@emotion/styled": "^11.11.0", + "@mui/icons-material": "^5.15.14", + "@mui/material": "^5.15.14", "react": "^18.1.0", "react-dom": "^18.1.0", + "react-router-dom": "^6.22.3", "react-scripts": "5.0.1" } }, @@ -1764,11 +1769,11 @@ } }, "node_modules/@babel/runtime": { - "version": "7.17.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.9.tgz", - "integrity": "sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.1.tgz", + "integrity": "sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==", "dependencies": { - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" @@ -1786,6 +1791,11 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/runtime/node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, "node_modules/@babel/template": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", @@ -1997,6 +2007,158 @@ "postcss": "^8.3" } }, + "node_modules/@emotion/babel-plugin": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", + "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/serialize": "^1.1.2", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@emotion/cache": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", + "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", + "dependencies": { + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", + "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + }, + "node_modules/@emotion/react": { + "version": "11.11.4", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.4.tgz", + "integrity": "sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.3.tgz", + "integrity": "sha512-iD4D6QVZFDhcbH0RAG1uVu1CwVLMWUkCvAqqlewO/rxf8+87yIBAlt4+AxMiiKPLs5hFc0owNk/sLLAOROw3cA==", + "dependencies": { + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" + }, + "node_modules/@emotion/styled": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz", + "integrity": "sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/is-prop-valid": "^1.2.1", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" + }, "node_modules/@eslint/eslintrc": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.2.tgz", @@ -2057,6 +2219,40 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@floating-ui/core": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", + "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", + "dependencies": { + "@floating-ui/utils": "^0.2.1" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.3.tgz", + "integrity": "sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==", + "dependencies": { + "@floating-ui/core": "^1.0.0", + "@floating-ui/utils": "^0.2.0" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.8.tgz", + "integrity": "sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==", + "dependencies": { + "@floating-ui/dom": "^1.6.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", + "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" + }, "node_modules/@humanwhocodes/config-array": { "version": "0.9.5", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", @@ -2785,6 +2981,261 @@ "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.3.tgz", "integrity": "sha512-nkalE/f1RvRGChwBnEIoBfSEYOXnCRdleKuv6+lePbMDrMZXeDQnqak5XDOeBgrPPyPfAdcCu/B5z+v3VhplGg==" }, + "node_modules/@mui/base": { + "version": "5.0.0-beta.40", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40.tgz", + "integrity": "sha512-I/lGHztkCzvwlXpjD2+SNmvNQvB4227xBXhISPjEaJUXGImOQ9f3D2Yj/T3KasSI/h0MLWy74X0J6clhPmsRbQ==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@floating-ui/react-dom": "^2.0.8", + "@mui/types": "^7.2.14", + "@mui/utils": "^5.15.14", + "@popperjs/core": "^2.11.8", + "clsx": "^2.1.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/core-downloads-tracker": { + "version": "5.15.14", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.14.tgz", + "integrity": "sha512-on75VMd0XqZfaQW+9pGjSNiqW+ghc5E2ZSLRBXwcXl/C4YzjfyjrLPhrEpKnR9Uym9KXBvxrhoHfPcczYHweyA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + } + }, + "node_modules/@mui/icons-material": { + "version": "5.15.14", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.14.tgz", + "integrity": "sha512-vj/51k7MdFmt+XVw94sl30SCvGx6+wJLsNYjZRgxhS6y3UtnWnypMOsm3Kmg8TN+P0dqwsjy4/fX7B1HufJIhw==", + "dependencies": { + "@babel/runtime": "^7.23.9" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@mui/material": "^5.0.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material": { + "version": "5.15.14", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.14.tgz", + "integrity": "sha512-kEbRw6fASdQ1SQ7LVdWR5OlWV3y7Y54ZxkLzd6LV5tmz+NpO3MJKZXSfgR0LHMP7meKsPiMm4AuzV0pXDpk/BQ==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/base": "5.0.0-beta.40", + "@mui/core-downloads-tracker": "^5.15.14", + "@mui/system": "^5.15.14", + "@mui/types": "^7.2.14", + "@mui/utils": "^5.15.14", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1", + "react-is": "^18.2.0", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/@mui/private-theming": { + "version": "5.15.14", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.14.tgz", + "integrity": "sha512-UH0EiZckOWcxiXLX3Jbb0K7rC8mxTr9L9l6QhOZxYc4r8FHUkefltV9VDGLrzCaWh30SQiJvAEd7djX3XXY6Xw==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/utils": "^5.15.14", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "5.15.14", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.14.tgz", + "integrity": "sha512-RILkuVD8gY6PvjZjqnWhz8fu68dVkqhM5+jYWfB5yhlSQKg+2rHkmEwm75XIeAqI3qwOndK6zELK5H6Zxn4NHw==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "5.15.14", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.14.tgz", + "integrity": "sha512-auXLXzUaCSSOLqJXmsAaq7P96VPRXg2Rrz6OHNV7lr+kB8lobUF+/N84Vd9C4G/wvCXYPs5TYuuGBRhcGbiBGg==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/private-theming": "^5.15.14", + "@mui/styled-engine": "^5.15.14", + "@mui/types": "^7.2.14", + "@mui/utils": "^5.15.14", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.2.14", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.14.tgz", + "integrity": "sha512-MZsBZ4q4HfzBsywtXgM1Ksj6HDThtiwmOKUXH1pKYISI9gAVXCNHNpo7TlGoGrBaYWZTdNoirIN7JsQcQUjmQQ==", + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "5.15.14", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.14.tgz", + "integrity": "sha512-0lF/7Hh/ezDv5X7Pry6enMsbYyGKjADzvHyo3Qrc/SSlTsQ1VkbDMbH0m2t3OR5iIVLwMoxwM7yGd+6FCMtTFA==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@types/prop-types": "^15.7.11", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -2866,6 +3317,23 @@ } } }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@remix-run/router": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.3.tgz", + "integrity": "sha512-Oy8rmScVrVxWZVOpEF57ovlnhpZ8CCPlnIIumVcV9nFdiSIrus99+Lw78ekXyGvVDlIsFJbSfmSovJUhCWYV3w==", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -3387,6 +3855,11 @@ "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.0.tgz", "integrity": "sha512-G/AdOadiZhnJp0jXCaBQU449W2h716OW/EoXeYkCytxKL06X1WCXB4DZpp8TpZ8eyIJVS1cw4lrlkkSYU21cDw==" }, + "node_modules/@types/prop-types": { + "version": "15.7.11", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" + }, "node_modules/@types/q": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz", @@ -3402,6 +3875,24 @@ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, + "node_modules/@types/react": { + "version": "18.2.67", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.67.tgz", + "integrity": "sha512-vkIE2vTIMHQ/xL0rgmuoECBCkZFZeHr49HeWSc24AptMbNRo7pwSBvj73rlJJs9fGKj0koS+V7kQB1jHS0uCgw==", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/resolve": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", @@ -3415,6 +3906,11 @@ "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" }, + "node_modules/@types/scheduler": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", + "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" + }, "node_modules/@types/serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", @@ -4920,6 +5416,14 @@ "wrap-ansi": "^7.0.0" } }, + "node_modules/clsx": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", + "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", + "engines": { + "node": ">=6" + } + }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -5586,6 +6090,11 @@ "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, "node_modules/damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -5829,6 +6338,15 @@ "utila": "~0.4" } }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, "node_modules/dom-serializer": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", @@ -7138,6 +7656,11 @@ "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -7705,6 +8228,19 @@ "he": "bin/he" } }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, "node_modules/hoopy": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", @@ -13112,6 +13648,36 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "6.22.3", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.3.tgz", + "integrity": "sha512-dr2eb3Mj5zK2YISHK++foM9w4eBnO23eKnZEDs7c880P6oKbrjz/Svg9+nxqtHQK+oMW4OtjZca0RqPglXxguQ==", + "dependencies": { + "@remix-run/router": "1.15.3" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.22.3", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.3.tgz", + "integrity": "sha512-7ZILI7HjcE+p31oQvwbokjk6OA/bnFxrhJ19n82Ex9Ph8fNAq+Hm/7KchpMGlTgWhUxRHMMCut+vEtNpWpowKw==", + "dependencies": { + "@remix-run/router": "1.15.3", + "react-router": "6.22.3" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "node_modules/react-scripts": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", @@ -13184,6 +13750,21 @@ } } }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, "node_modules/readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -14246,6 +14827,11 @@ "postcss": "^8.2.15" } }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -17044,11 +17630,18 @@ } }, "@babel/runtime": { - "version": "7.17.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.9.tgz", - "integrity": "sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.1.tgz", + "integrity": "sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==", "requires": { - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.14.0" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + } } }, "@babel/runtime-corejs3": { @@ -17187,6 +17780,132 @@ "integrity": "sha512-T5ZyNSw9G0x0UDFiXV40a7VjKw2b+l4G+S0sctKqxhx8cg9QtMUAGwJBVU9mHPDPoZEmwm0tEoukjl4zb9MU7Q==", "requires": {} }, + "@emotion/babel-plugin": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", + "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", + "requires": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/serialize": "^1.1.2", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==" + } + } + }, + "@emotion/cache": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", + "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", + "requires": { + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" + } + }, + "@emotion/hash": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" + }, + "@emotion/is-prop-valid": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", + "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", + "requires": { + "@emotion/memoize": "^0.8.1" + } + }, + "@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + }, + "@emotion/react": { + "version": "11.11.4", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.4.tgz", + "integrity": "sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==", + "requires": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "hoist-non-react-statics": "^3.3.1" + } + }, + "@emotion/serialize": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.3.tgz", + "integrity": "sha512-iD4D6QVZFDhcbH0RAG1uVu1CwVLMWUkCvAqqlewO/rxf8+87yIBAlt4+AxMiiKPLs5hFc0owNk/sLLAOROw3cA==", + "requires": { + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", + "csstype": "^3.0.2" + } + }, + "@emotion/sheet": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" + }, + "@emotion/styled": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz", + "integrity": "sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==", + "requires": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/is-prop-valid": "^1.2.1", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1" + } + }, + "@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + }, + "@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", + "requires": {} + }, + "@emotion/utils": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" + }, + "@emotion/weak-memoize": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" + }, "@eslint/eslintrc": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.2.tgz", @@ -17231,6 +17950,36 @@ } } }, + "@floating-ui/core": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", + "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", + "requires": { + "@floating-ui/utils": "^0.2.1" + } + }, + "@floating-ui/dom": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.3.tgz", + "integrity": "sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==", + "requires": { + "@floating-ui/core": "^1.0.0", + "@floating-ui/utils": "^0.2.0" + } + }, + "@floating-ui/react-dom": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.8.tgz", + "integrity": "sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==", + "requires": { + "@floating-ui/dom": "^1.6.1" + } + }, + "@floating-ui/utils": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", + "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" + }, "@humanwhocodes/config-array": { "version": "0.9.5", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", @@ -17771,6 +18520,119 @@ "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.3.tgz", "integrity": "sha512-nkalE/f1RvRGChwBnEIoBfSEYOXnCRdleKuv6+lePbMDrMZXeDQnqak5XDOeBgrPPyPfAdcCu/B5z+v3VhplGg==" }, + "@mui/base": { + "version": "5.0.0-beta.40", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40.tgz", + "integrity": "sha512-I/lGHztkCzvwlXpjD2+SNmvNQvB4227xBXhISPjEaJUXGImOQ9f3D2Yj/T3KasSI/h0MLWy74X0J6clhPmsRbQ==", + "requires": { + "@babel/runtime": "^7.23.9", + "@floating-ui/react-dom": "^2.0.8", + "@mui/types": "^7.2.14", + "@mui/utils": "^5.15.14", + "@popperjs/core": "^2.11.8", + "clsx": "^2.1.0", + "prop-types": "^15.8.1" + } + }, + "@mui/core-downloads-tracker": { + "version": "5.15.14", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.14.tgz", + "integrity": "sha512-on75VMd0XqZfaQW+9pGjSNiqW+ghc5E2ZSLRBXwcXl/C4YzjfyjrLPhrEpKnR9Uym9KXBvxrhoHfPcczYHweyA==" + }, + "@mui/icons-material": { + "version": "5.15.14", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.14.tgz", + "integrity": "sha512-vj/51k7MdFmt+XVw94sl30SCvGx6+wJLsNYjZRgxhS6y3UtnWnypMOsm3Kmg8TN+P0dqwsjy4/fX7B1HufJIhw==", + "requires": { + "@babel/runtime": "^7.23.9" + } + }, + "@mui/material": { + "version": "5.15.14", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.14.tgz", + "integrity": "sha512-kEbRw6fASdQ1SQ7LVdWR5OlWV3y7Y54ZxkLzd6LV5tmz+NpO3MJKZXSfgR0LHMP7meKsPiMm4AuzV0pXDpk/BQ==", + "requires": { + "@babel/runtime": "^7.23.9", + "@mui/base": "5.0.0-beta.40", + "@mui/core-downloads-tracker": "^5.15.14", + "@mui/system": "^5.15.14", + "@mui/types": "^7.2.14", + "@mui/utils": "^5.15.14", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1", + "react-is": "^18.2.0", + "react-transition-group": "^4.4.5" + }, + "dependencies": { + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + } + } + }, + "@mui/private-theming": { + "version": "5.15.14", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.14.tgz", + "integrity": "sha512-UH0EiZckOWcxiXLX3Jbb0K7rC8mxTr9L9l6QhOZxYc4r8FHUkefltV9VDGLrzCaWh30SQiJvAEd7djX3XXY6Xw==", + "requires": { + "@babel/runtime": "^7.23.9", + "@mui/utils": "^5.15.14", + "prop-types": "^15.8.1" + } + }, + "@mui/styled-engine": { + "version": "5.15.14", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.14.tgz", + "integrity": "sha512-RILkuVD8gY6PvjZjqnWhz8fu68dVkqhM5+jYWfB5yhlSQKg+2rHkmEwm75XIeAqI3qwOndK6zELK5H6Zxn4NHw==", + "requires": { + "@babel/runtime": "^7.23.9", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + } + }, + "@mui/system": { + "version": "5.15.14", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.14.tgz", + "integrity": "sha512-auXLXzUaCSSOLqJXmsAaq7P96VPRXg2Rrz6OHNV7lr+kB8lobUF+/N84Vd9C4G/wvCXYPs5TYuuGBRhcGbiBGg==", + "requires": { + "@babel/runtime": "^7.23.9", + "@mui/private-theming": "^5.15.14", + "@mui/styled-engine": "^5.15.14", + "@mui/types": "^7.2.14", + "@mui/utils": "^5.15.14", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + } + }, + "@mui/types": { + "version": "7.2.14", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.14.tgz", + "integrity": "sha512-MZsBZ4q4HfzBsywtXgM1Ksj6HDThtiwmOKUXH1pKYISI9gAVXCNHNpo7TlGoGrBaYWZTdNoirIN7JsQcQUjmQQ==", + "requires": {} + }, + "@mui/utils": { + "version": "5.15.14", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.14.tgz", + "integrity": "sha512-0lF/7Hh/ezDv5X7Pry6enMsbYyGKjADzvHyo3Qrc/SSlTsQ1VkbDMbH0m2t3OR5iIVLwMoxwM7yGd+6FCMtTFA==", + "requires": { + "@babel/runtime": "^7.23.9", + "@types/prop-types": "^15.7.11", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "dependencies": { + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + } + } + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -17810,6 +18672,16 @@ "source-map": "^0.7.3" } }, + "@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==" + }, + "@remix-run/router": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.3.tgz", + "integrity": "sha512-Oy8rmScVrVxWZVOpEF57ovlnhpZ8CCPlnIIumVcV9nFdiSIrus99+Lw78ekXyGvVDlIsFJbSfmSovJUhCWYV3w==" + }, "@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -18201,6 +19073,11 @@ "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.0.tgz", "integrity": "sha512-G/AdOadiZhnJp0jXCaBQU449W2h716OW/EoXeYkCytxKL06X1WCXB4DZpp8TpZ8eyIJVS1cw4lrlkkSYU21cDw==" }, + "@types/prop-types": { + "version": "15.7.11", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" + }, "@types/q": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz", @@ -18216,6 +19093,24 @@ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, + "@types/react": { + "version": "18.2.67", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.67.tgz", + "integrity": "sha512-vkIE2vTIMHQ/xL0rgmuoECBCkZFZeHr49HeWSc24AptMbNRo7pwSBvj73rlJJs9fGKj0koS+V7kQB1jHS0uCgw==", + "requires": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "@types/react-transition-group": { + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", + "requires": { + "@types/react": "*" + } + }, "@types/resolve": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", @@ -18229,6 +19124,11 @@ "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" }, + "@types/scheduler": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", + "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" + }, "@types/serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", @@ -19343,6 +20243,11 @@ "wrap-ansi": "^7.0.0" } }, + "clsx": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", + "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==" + }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -19809,6 +20714,11 @@ } } }, + "csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, "damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -19990,6 +20900,15 @@ "utila": "~0.4" } }, + "dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "requires": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, "dom-serializer": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", @@ -20961,6 +21880,11 @@ "pkg-dir": "^4.1.0" } }, + "find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -21341,6 +22265,21 @@ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" }, + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + }, + "dependencies": { + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + } + } + }, "hoopy": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", @@ -25119,6 +26058,23 @@ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==" }, + "react-router": { + "version": "6.22.3", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.3.tgz", + "integrity": "sha512-dr2eb3Mj5zK2YISHK++foM9w4eBnO23eKnZEDs7c880P6oKbrjz/Svg9+nxqtHQK+oMW4OtjZca0RqPglXxguQ==", + "requires": { + "@remix-run/router": "1.15.3" + } + }, + "react-router-dom": { + "version": "6.22.3", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.3.tgz", + "integrity": "sha512-7ZILI7HjcE+p31oQvwbokjk6OA/bnFxrhJ19n82Ex9Ph8fNAq+Hm/7KchpMGlTgWhUxRHMMCut+vEtNpWpowKw==", + "requires": { + "@remix-run/router": "1.15.3", + "react-router": "6.22.3" + } + }, "react-scripts": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", @@ -25174,6 +26130,17 @@ "workbox-webpack-plugin": "^6.4.1" } }, + "react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "requires": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + } + }, "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -25955,6 +26922,11 @@ "postcss-selector-parser": "^6.0.4" } }, + "stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", diff --git a/package.json b/package.json index 6fd77e8c..6392cdc9 100644 --- a/package.json +++ b/package.json @@ -3,8 +3,13 @@ "version": "0.1.0", "private": true, "dependencies": { + "@emotion/react": "^11.11.4", + "@emotion/styled": "^11.11.0", + "@mui/icons-material": "^5.15.14", + "@mui/material": "^5.15.14", "react": "^18.1.0", "react-dom": "^18.1.0", + "react-router-dom": "^6.22.3", "react-scripts": "5.0.1" }, "scripts": { diff --git a/src/App.js b/src/App.js index 4a6f800f..a1fa2ab2 100644 --- a/src/App.js +++ b/src/App.js @@ -1,20 +1,62 @@ +//-----------Libraries-----------// import React from "react"; -import logo from "./logo.png"; -import "./App.css"; - -class App extends React.Component { - render() { - return ( -
-
- logo -

- Edit src/App.js and save to reload. -

-
-
- ); - } -} +import { BrowserRouter, Routes, Route } from "react-router-dom"; + +//-----------Components-----------// +import NavBar from "./components/navbar.js"; + +//-----------Styling-----------// +import "./index.css"; + +//-----------Pages-----------// +import RegisterPage from "./pages/registerPage.js"; +import SignInPage from "./pages/signInPage.js"; +import ResetPasswordPage from "./pages/resetPasswordPage.js"; +import ErrorPage from "./pages/errorPage.js"; + +//-----------UserPages-----------// +import HomePage from "./pages/userPages/homePage.js"; +import EventDetailPage from "./pages/userPages/eventDetailPage.js"; +import FavPage from "./pages/userPages/favPage.js"; +import MyBookingPage from "./pages/userPages/myBookingPage.js"; +import MyProfilePage from "./pages/userPages/myProfilePage.js"; + +//-----------AdminPages-----------// +import AdminHomePage from "./pages/adminPages/adminHomePage.js"; +import AdminProfilePage from "./pages/adminPages/adminProfilePage.js"; +import AdminEventPage from "./pages/adminPages/adminEventPage.js"; +import AdminEventAttendancePage from "./pages/adminPages/adminEventAttendancePage.js"; +import AdminAnalyticsPage from "./pages/adminPages/adminAnalyticsPage.js"; + +const AdminRoutes = () => ( + + } /> + } /> + } /> + } /> + } /> + } /> + +); + +const App = () => { + return ( + + + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + + ); +}; export default App; diff --git a/src/components/navbar.js b/src/components/navbar.js new file mode 100644 index 00000000..bf1cb70b --- /dev/null +++ b/src/components/navbar.js @@ -0,0 +1,40 @@ +//-----------Libraries-----------// +import AppBar from "@mui/material/AppBar"; +import Toolbar from "@mui/material/Toolbar"; +import { Link } from "react-router-dom"; +import ExploreIcon from "@mui/icons-material/Explore"; +import BookmarkIcon from "@mui/icons-material/Bookmark"; +import EventIcon from "@mui/icons-material/Event"; +import PersonIcon from "@mui/icons-material/Person"; + +//-----------Components-----------// + +//-----------Styling-----------// +import "../App.css"; + +export default function NavBar() { + return ( + + + + + + + + + + + + + + + + + ); +} diff --git a/src/firebase/firebase.js b/src/firebase/firebase.js new file mode 100644 index 00000000..f7cac98a --- /dev/null +++ b/src/firebase/firebase.js @@ -0,0 +1,18 @@ +// Import the functions you need from the SDKs you need +import { initializeApp } from "firebase/app"; +import { getStorage } from "firebase/storage"; + +const firebaseConfig = { + apiKey: process.env.REACT_APP_API_KEY, + authDomain: process.env.REACT_APP_AUTH_DOMAIN, + projectId: process.env.REACT_APP_PROJECT_ID, + storageBucket: process.env.REACT_APP_STORAGE_BUCKET, + messagingSenderId: process.env.REACT_APP_MESSAGING_SENDER_ID, + appId: process.env.REACT_APP_APP_ID, +}; + +// Initialize Firebase +const firebaseApp = initializeApp(firebaseConfig); + +// Get a reference to the database service and export the reference for other modules +export const storage = getStorage(firebaseApp); diff --git a/src/index.js b/src/index.js index a64e7d56..907b6d82 100644 --- a/src/index.js +++ b/src/index.js @@ -1,7 +1,12 @@ +//-----------Libraries-----------// import React from "react"; import ReactDOM from "react-dom/client"; -import "./index.css"; + +//-----------Components-----------// import App from "./App"; +//-----------Styling-----------// +import "./index.css"; + const root = ReactDOM.createRoot(document.getElementById("root")); root.render(); diff --git a/src/pages/adminPages/adminAnalyticsPage.js b/src/pages/adminPages/adminAnalyticsPage.js new file mode 100644 index 00000000..f44524c5 --- /dev/null +++ b/src/pages/adminPages/adminAnalyticsPage.js @@ -0,0 +1,8 @@ +//-----------Libraries-----------// +import { useState, useEffect } from "react"; + +//-----------Components-----------// + +export default function AdminAnalyticsPage() { + return
Admin Analytics page
; +} diff --git a/src/pages/adminPages/adminEventAttendancePage.js b/src/pages/adminPages/adminEventAttendancePage.js new file mode 100644 index 00000000..2a4e1b58 --- /dev/null +++ b/src/pages/adminPages/adminEventAttendancePage.js @@ -0,0 +1,8 @@ +//-----------Libraries-----------// +import { useState, useEffect } from "react"; + +//-----------Components-----------// + +export default function AdminEventAttendancePage() { + return
Event attendance page
; +} diff --git a/src/pages/adminPages/adminEventPage.js b/src/pages/adminPages/adminEventPage.js new file mode 100644 index 00000000..ed2c57d7 --- /dev/null +++ b/src/pages/adminPages/adminEventPage.js @@ -0,0 +1,8 @@ +//-----------Libraries-----------// +import { useState, useEffect } from "react"; + +//-----------Components-----------// + +export default function AdminEventPage() { + return
Create and edit event page
; +} diff --git a/src/pages/adminPages/adminHomePage.js b/src/pages/adminPages/adminHomePage.js new file mode 100644 index 00000000..3dfe7389 --- /dev/null +++ b/src/pages/adminPages/adminHomePage.js @@ -0,0 +1,14 @@ +//-----------Libraries-----------// +import { useState, useEffect } from "react"; +import { Outlet } from "react-router-dom"; + +//-----------Components-----------// + +export default function adminHomePage() { + return ( +
+ + Admin homepage +
+ ); +} diff --git a/src/pages/adminPages/adminProfilePage.js b/src/pages/adminPages/adminProfilePage.js new file mode 100644 index 00000000..379bc45b --- /dev/null +++ b/src/pages/adminPages/adminProfilePage.js @@ -0,0 +1,8 @@ +//-----------Libraries-----------// +import { useState, useEffect } from "react"; + +//-----------Components-----------// + +export default function AdminProfilePage() { + return
Admin profile page
; +} diff --git a/src/pages/errorPage.js b/src/pages/errorPage.js new file mode 100644 index 00000000..14668c8b --- /dev/null +++ b/src/pages/errorPage.js @@ -0,0 +1,8 @@ +//-----------Libraries-----------// +import { useState, useEffect } from "react"; + +//-----------Components-----------// + +export default function ErrorPage() { + return
Error page
; +} diff --git a/src/pages/registerPage.js b/src/pages/registerPage.js new file mode 100644 index 00000000..6e4c9e8f --- /dev/null +++ b/src/pages/registerPage.js @@ -0,0 +1,8 @@ +//-----------Libraries-----------// +import { useState, useEffect } from "react"; + +//-----------Components-----------// + +export default function RegisterPage() { + return
Register page
; +} diff --git a/src/pages/resetPasswordPage.js b/src/pages/resetPasswordPage.js new file mode 100644 index 00000000..9798195c --- /dev/null +++ b/src/pages/resetPasswordPage.js @@ -0,0 +1,8 @@ +//-----------Libraries-----------// +import { useState, useEffect } from "react"; + +//-----------Components-----------// + +export default function ResetPasswordPage() { + return
Reset Password Page
; +} diff --git a/src/pages/signInPage.js b/src/pages/signInPage.js new file mode 100644 index 00000000..56e6a8ed --- /dev/null +++ b/src/pages/signInPage.js @@ -0,0 +1,8 @@ +//-----------Libraries-----------// +import { useState, useEffect } from "react"; + +//-----------Components-----------// + +export default function SignInPage() { + return
SignInPage
; +} diff --git a/src/pages/userPages/eventBookingPage.js b/src/pages/userPages/eventBookingPage.js new file mode 100644 index 00000000..def21e1e --- /dev/null +++ b/src/pages/userPages/eventBookingPage.js @@ -0,0 +1,8 @@ +//-----------Libraries-----------// +import { useState, useEffect } from "react"; + +//-----------Components-----------// + +export default function EventBookingPage() { + return
Event booking page
; +} diff --git a/src/pages/userPages/eventDetailPage.js b/src/pages/userPages/eventDetailPage.js new file mode 100644 index 00000000..d89ca889 --- /dev/null +++ b/src/pages/userPages/eventDetailPage.js @@ -0,0 +1,8 @@ +//-----------Libraries-----------// +import { useState, useEffect } from "react"; + +//-----------Components-----------// + +export default function EventDetailPage() { + return
Event detail page
; +} diff --git a/src/pages/userPages/favPage.js b/src/pages/userPages/favPage.js new file mode 100644 index 00000000..f7611b6a --- /dev/null +++ b/src/pages/userPages/favPage.js @@ -0,0 +1,8 @@ +//-----------Libraries-----------// +import { useState, useEffect } from "react"; + +//-----------Components-----------// + +export default function FavPage() { + return
Favorites page
; +} diff --git a/src/pages/userPages/homePage.js b/src/pages/userPages/homePage.js new file mode 100644 index 00000000..0a7bc131 --- /dev/null +++ b/src/pages/userPages/homePage.js @@ -0,0 +1,8 @@ +//-----------Libraries-----------// +import { useState, useEffect } from "react"; + +//-----------Components-----------// + +export default function HomePage() { + return
Home
; +} diff --git a/src/pages/userPages/myBookingPage.js b/src/pages/userPages/myBookingPage.js new file mode 100644 index 00000000..8447a61b --- /dev/null +++ b/src/pages/userPages/myBookingPage.js @@ -0,0 +1,8 @@ +//-----------Libraries-----------// +import { useState, useEffect } from "react"; + +//-----------Components-----------// + +export default function MyBookingPage() { + return
My booking page
; +} diff --git a/src/pages/userPages/myProfilePage.js b/src/pages/userPages/myProfilePage.js new file mode 100644 index 00000000..b2078594 --- /dev/null +++ b/src/pages/userPages/myProfilePage.js @@ -0,0 +1,8 @@ +//-----------Libraries-----------// +import { useState, useEffect } from "react"; + +//-----------Components-----------// + +export default function MyProfilePage() { + return
My profile page
; +} diff --git a/src/pages/userPages/paymentPage.js b/src/pages/userPages/paymentPage.js new file mode 100644 index 00000000..62a5d047 --- /dev/null +++ b/src/pages/userPages/paymentPage.js @@ -0,0 +1,8 @@ +//-----------Libraries-----------// +import { useState, useEffect } from "react"; + +//-----------Components-----------// + +export default function PaymentPage() { + return
PaymentPage
; +} From bc71b92243e80a108dce1aff20c0a22ad9be5360 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Sat, 23 Mar 2024 00:30:54 +0800 Subject: [PATCH 02/69] linked homepage and eventdetail page with backend --- package-lock.json | 68 +++++++++++++++++++++++--- package.json | 1 + src/App.js | 2 +- src/components/EventPreview.js | 67 +++++++++++++++++++++++++ src/components/EventPreviewList.js | 30 ++++++++++++ src/pages/userPages/eventDetailPage.js | 49 ++++++++++++++++++- src/pages/userPages/homePage.js | 7 ++- 7 files changed, 215 insertions(+), 9 deletions(-) create mode 100644 src/components/EventPreview.js create mode 100644 src/components/EventPreviewList.js diff --git a/package-lock.json b/package-lock.json index a0d88b05..e7a5d1f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@emotion/styled": "^11.11.0", "@mui/icons-material": "^5.15.14", "@mui/material": "^5.15.14", + "axios": "^1.6.8", "react": "^18.1.0", "react-dom": "^18.1.0", "react-router-dom": "^6.22.3", @@ -4722,6 +4723,29 @@ "node": ">=4" } }, + "node_modules/axios": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", + "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/axios/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", @@ -7694,9 +7718,9 @@ "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==" }, "node_modules/follow-redirects": { - "version": "1.14.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", - "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "funding": [ { "type": "individual", @@ -13351,6 +13375,11 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -19718,6 +19747,28 @@ "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.1.tgz", "integrity": "sha512-gd1kmb21kwNuWr6BQz8fv6GNECPBnUasepcoLbekws23NVBLODdsClRZ+bQ8+9Uomf3Sm3+Vwn0oYG9NvwnJCw==" }, + "axios": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", + "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", + "requires": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + }, + "dependencies": { + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + } + } + }, "axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", @@ -21909,9 +21960,9 @@ "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==" }, "follow-redirects": { - "version": "1.14.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", - "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==" + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==" }, "fork-ts-checker-webpack-plugin": { "version": "6.5.2", @@ -25847,6 +25898,11 @@ } } }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", diff --git a/package.json b/package.json index 6392cdc9..f0da38a1 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "@emotion/styled": "^11.11.0", "@mui/icons-material": "^5.15.14", "@mui/material": "^5.15.14", + "axios": "^1.6.8", "react": "^18.1.0", "react-dom": "^18.1.0", "react-router-dom": "^6.22.3", diff --git a/src/App.js b/src/App.js index a1fa2ab2..43caa29a 100644 --- a/src/App.js +++ b/src/App.js @@ -51,7 +51,7 @@ const App = () => { } /> } /> } /> - } /> + } /> } /> } /> diff --git a/src/components/EventPreview.js b/src/components/EventPreview.js new file mode 100644 index 00000000..3fe93b24 --- /dev/null +++ b/src/components/EventPreview.js @@ -0,0 +1,67 @@ +//-----------Libraries-----------// +import Card from "@mui/material/Card"; +import CardContent from "@mui/material/CardContent"; +import CardActions from "@mui/material/CardActions"; +import Button from "@mui/material/Button"; +import Typography from "@mui/material/Typography"; +import { Link } from "react-router-dom"; + +const EventPreview = (props) => { + const formatDate = (string) => { + const date = new Date(string); + const options = { + day: "numeric", + month: "long", + hour: "2-digit", + minute: "2-digit", + }; + return date.toLocaleDateString("en-US", options); + }; + + //add logic to see whether start and end date is the same. + const formatHour = (string) => { + const date = new Date(string); + const options = { + hour: "2-digit", + minute: "2-digit", + }; + return date.toLocaleTimeString("en-US", options); + }; + + return ( + + {/* */} + + <> + + + {props.data.title} + + + {props.data.admin.name} + + + {formatDate(props.data.start)}-{formatHour(props.data.end)} + + + ${props.data.price} + + + + + + + + + ); +}; + +export default EventPreview; diff --git a/src/components/EventPreviewList.js b/src/components/EventPreviewList.js new file mode 100644 index 00000000..18fabf94 --- /dev/null +++ b/src/components/EventPreviewList.js @@ -0,0 +1,30 @@ +//-----------Libraries-----------// +import { useState, useEffect } from "react"; +import axios from "axios"; + +//-----------Components-----------// +import EventPreview from "./EventPreview"; + +const BACKEND_URL = process.env.REACT_APP_BACKEND_URL; + +const EventPreviewList = () => { + const [events, setEvents] = useState([]); + + useEffect(() => { + const fetchData = async () => { + try { + const response = await axios.get(`${BACKEND_URL}/events`); + setEvents(response.data); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + fetchData(); + }, []); + + const eventPreviews = events.map((event) => ); + return
{eventPreviews}
; +}; + +export default EventPreviewList; diff --git a/src/pages/userPages/eventDetailPage.js b/src/pages/userPages/eventDetailPage.js index d89ca889..e8a3a0db 100644 --- a/src/pages/userPages/eventDetailPage.js +++ b/src/pages/userPages/eventDetailPage.js @@ -1,8 +1,55 @@ //-----------Libraries-----------// import { useState, useEffect } from "react"; +import { useParams } from "react-router-dom"; +import axios from "axios"; +import Button from "@mui/material/Button"; //-----------Components-----------// +const BACKEND_URL = process.env.REACT_APP_BACKEND_URL; + export default function EventDetailPage() { - return
Event detail page
; + const [event, setEvent] = useState(); + const [eventId, setEventId] = useState(); + + useEffect(() => { + const fetchData = async () => { + try { + const response = await axios.get(`${BACKEND_URL}/events/${eventId}`); + setEvent(response.data); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + fetchData(); + }, [eventId]); + + // Update eventID in state if needed to trigger data retrieval + const params = useParams(); + if (eventId !== params.eventId) { + setEventId(params.eventId); + } + + console.log(event); + + const eventInfo = event ? ( +
+

{event.title}

+

{event.description}

+

{event.language.name}

+

Start: {event.start}

+

End: {event.end}

+

${event.price}

+

{event.admin.name}

+

{event.venue.address}

+
+ ) : null; + + return ( +
+ {eventInfo} + +
+ ); } diff --git a/src/pages/userPages/homePage.js b/src/pages/userPages/homePage.js index 0a7bc131..5580d4dc 100644 --- a/src/pages/userPages/homePage.js +++ b/src/pages/userPages/homePage.js @@ -2,7 +2,12 @@ import { useState, useEffect } from "react"; //-----------Components-----------// +import EventPreviewList from "../../components/EventPreviewList"; export default function HomePage() { - return
Home
; + return ( +
+ +
+ ); } From c7951514bc1d33afe64f4e2fb287a0a6b19b6e48 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Sat, 23 Mar 2024 00:38:07 +0800 Subject: [PATCH 03/69] test file --- src/pages/userPages/eventDetailPage.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/userPages/eventDetailPage.js b/src/pages/userPages/eventDetailPage.js index e8a3a0db..4208d12c 100644 --- a/src/pages/userPages/eventDetailPage.js +++ b/src/pages/userPages/eventDetailPage.js @@ -33,6 +33,7 @@ export default function EventDetailPage() { console.log(event); + //add image const eventInfo = event ? (

{event.title}

From 57b377e679508eb8e3d2d457f49310f5a526b3a0 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Sat, 23 Mar 2024 00:40:39 +0800 Subject: [PATCH 04/69] removed console log --- src/pages/userPages/eventDetailPage.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pages/userPages/eventDetailPage.js b/src/pages/userPages/eventDetailPage.js index e8a3a0db..da74d030 100644 --- a/src/pages/userPages/eventDetailPage.js +++ b/src/pages/userPages/eventDetailPage.js @@ -31,8 +31,6 @@ export default function EventDetailPage() { setEventId(params.eventId); } - console.log(event); - const eventInfo = event ? (

{event.title}

From f6f44d2eac16b363b6b2071b41f0ee7122e9e7e3 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Sat, 23 Mar 2024 11:11:14 +0800 Subject: [PATCH 05/69] added dialog link for booking --- src/pages/userPages/eventBookingPage.js | 13 ++++++++++++- src/pages/userPages/eventDetailPage.js | 19 ++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/pages/userPages/eventBookingPage.js b/src/pages/userPages/eventBookingPage.js index def21e1e..82349014 100644 --- a/src/pages/userPages/eventBookingPage.js +++ b/src/pages/userPages/eventBookingPage.js @@ -1,8 +1,19 @@ //-----------Libraries-----------// import { useState, useEffect } from "react"; +import Button from "@mui/material/Button"; +import TextField from "@mui/material/TextField"; +import Dialog from "@mui/material/Dialog"; +import DialogActions from "@mui/material/DialogActions"; +import DialogContent from "@mui/material/DialogContent"; +import DialogContentText from "@mui/material/DialogContentText"; +import DialogTitle from "@mui/material/DialogTitle"; //-----------Components-----------// export default function EventBookingPage() { - return
Event booking page
; + return ( +
+

Booking

+
+ ); } diff --git a/src/pages/userPages/eventDetailPage.js b/src/pages/userPages/eventDetailPage.js index 3f45de26..aae3139c 100644 --- a/src/pages/userPages/eventDetailPage.js +++ b/src/pages/userPages/eventDetailPage.js @@ -3,14 +3,18 @@ import { useState, useEffect } from "react"; import { useParams } from "react-router-dom"; import axios from "axios"; import Button from "@mui/material/Button"; +import Dialog from "@mui/material/Dialog"; +import DialogTitle from "@mui/material/DialogTitle"; //-----------Components-----------// +import EventBookingPage from "./eventBookingPage"; const BACKEND_URL = process.env.REACT_APP_BACKEND_URL; export default function EventDetailPage() { const [event, setEvent] = useState(); const [eventId, setEventId] = useState(); + const [showRegistration, setShowRegistraton] = useState(null); useEffect(() => { const fetchData = async () => { @@ -31,6 +35,14 @@ export default function EventDetailPage() { setEventId(params.eventId); } + const handleClickOpen = () => { + setShowRegistraton(true); + }; + + const handleClose = () => { + setShowRegistraton(false); + }; + //add image const eventInfo = event ? (
@@ -48,7 +60,12 @@ export default function EventDetailPage() { return (
{eventInfo} - + + {showRegistration && ( + + + + )}
); } From f27311423abc423339676e88a554c9f8283115c1 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Mon, 25 Mar 2024 23:53:18 +0800 Subject: [PATCH 06/69] added payment checkout --- package-lock.json | 36 +++++++++++++++++++ package.json | 2 ++ src/App.js | 4 +++ src/pages/userPages/checkOutPage.js | 39 ++++++++++++++++++++ src/pages/userPages/eventBookingPage.js | 3 +- src/pages/userPages/myBookingPage.js | 7 +++- src/pages/userPages/paymentPage.js | 8 ----- src/pages/userPages/returnPage.js | 48 +++++++++++++++++++++++++ 8 files changed, 137 insertions(+), 10 deletions(-) create mode 100644 src/pages/userPages/checkOutPage.js delete mode 100644 src/pages/userPages/paymentPage.js create mode 100644 src/pages/userPages/returnPage.js diff --git a/package-lock.json b/package-lock.json index e7a5d1f9..5f461fcf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,8 @@ "@emotion/styled": "^11.11.0", "@mui/icons-material": "^5.15.14", "@mui/material": "^5.15.14", + "@stripe/react-stripe-js": "^2.6.2", + "@stripe/stripe-js": "^3.0.10", "axios": "^1.6.8", "react": "^18.1.0", "react-dom": "^18.1.0", @@ -3435,6 +3437,27 @@ "@sinonjs/commons": "^1.7.0" } }, + "node_modules/@stripe/react-stripe-js": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@stripe/react-stripe-js/-/react-stripe-js-2.6.2.tgz", + "integrity": "sha512-FSjNg4v7BiCfojvx25PQ8DugOa09cGk1t816R/DLI/lT+1bgRAYpMvoPirLT4ZQ3ev/0VDtPdWNaabPsLDTOMA==", + "dependencies": { + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "@stripe/stripe-js": "^1.44.1 || ^2.0.0 || ^3.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@stripe/stripe-js": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@stripe/stripe-js/-/stripe-js-3.0.10.tgz", + "integrity": "sha512-CFRNha+aPXR8GrqJss2TbK1j4aSGZXQY8gx0hvaYiSp+dU7EK/Zs5uwFTSAgV+t8H4+jcZ/iBGajAvoMYOwy+A==", + "engines": { + "node": ">=12.16" + } + }, "node_modules/@surma/rollup-plugin-off-main-thread": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", @@ -18785,6 +18808,19 @@ "@sinonjs/commons": "^1.7.0" } }, + "@stripe/react-stripe-js": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@stripe/react-stripe-js/-/react-stripe-js-2.6.2.tgz", + "integrity": "sha512-FSjNg4v7BiCfojvx25PQ8DugOa09cGk1t816R/DLI/lT+1bgRAYpMvoPirLT4ZQ3ev/0VDtPdWNaabPsLDTOMA==", + "requires": { + "prop-types": "^15.7.2" + } + }, + "@stripe/stripe-js": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@stripe/stripe-js/-/stripe-js-3.0.10.tgz", + "integrity": "sha512-CFRNha+aPXR8GrqJss2TbK1j4aSGZXQY8gx0hvaYiSp+dU7EK/Zs5uwFTSAgV+t8H4+jcZ/iBGajAvoMYOwy+A==" + }, "@surma/rollup-plugin-off-main-thread": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", diff --git a/package.json b/package.json index f0da38a1..2c5bdd45 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,8 @@ "@emotion/styled": "^11.11.0", "@mui/icons-material": "^5.15.14", "@mui/material": "^5.15.14", + "@stripe/react-stripe-js": "^2.6.2", + "@stripe/stripe-js": "^3.0.10", "axios": "^1.6.8", "react": "^18.1.0", "react-dom": "^18.1.0", diff --git a/src/App.js b/src/App.js index 43caa29a..9a682c89 100644 --- a/src/App.js +++ b/src/App.js @@ -20,6 +20,8 @@ import EventDetailPage from "./pages/userPages/eventDetailPage.js"; import FavPage from "./pages/userPages/favPage.js"; import MyBookingPage from "./pages/userPages/myBookingPage.js"; import MyProfilePage from "./pages/userPages/myProfilePage.js"; +import CheckoutForm from "./pages/userPages/checkOutPage.js"; +import ReturnPage from "./pages/userPages/returnPage.js"; //-----------AdminPages-----------// import AdminHomePage from "./pages/adminPages/adminHomePage.js"; @@ -50,6 +52,8 @@ const App = () => { } /> } /> } /> + } /> + } /> } /> } /> } /> diff --git a/src/pages/userPages/checkOutPage.js b/src/pages/userPages/checkOutPage.js new file mode 100644 index 00000000..d4bbaa08 --- /dev/null +++ b/src/pages/userPages/checkOutPage.js @@ -0,0 +1,39 @@ +import React, { useCallback, useState } from "react"; +import { loadStripe } from "@stripe/stripe-js"; +import axios from "axios"; +import { + EmbeddedCheckoutProvider, + EmbeddedCheckout, +} from "@stripe/react-stripe-js"; + +const stripePromise = loadStripe( + "pk_test_51OyC8VEkRpzvMxvMLDTzSAtzYuI8Aj98G0UQ3IkjB4ERSxgMQKMb9RNDz0LUq30pttvyJo0TsbnZVVZDxdP8SnIy000n2nrCq9" +); + +const BACKEND_URL = process.env.REACT_APP_BACKEND_URL; + +const CheckoutForm = () => { + const fetchClientSecret = useCallback(() => { + // Create a Checkout Session using axios + return axios + .post("http://localhost:3000/bookings/create-checkout-session/4") + .then((response) => response.data.clientSecret) + .catch((error) => { + console.error("Error fetching client secret:", error); + throw error; // rethrow the error to handle it elsewhere if needed + }); + }, []); + + const options = { fetchClientSecret }; + console.log(options); + + return ( +
+ + + +
+ ); +}; + +export default CheckoutForm; diff --git a/src/pages/userPages/eventBookingPage.js b/src/pages/userPages/eventBookingPage.js index 82349014..4136b22f 100644 --- a/src/pages/userPages/eventBookingPage.js +++ b/src/pages/userPages/eventBookingPage.js @@ -7,13 +7,14 @@ import DialogActions from "@mui/material/DialogActions"; import DialogContent from "@mui/material/DialogContent"; import DialogContentText from "@mui/material/DialogContentText"; import DialogTitle from "@mui/material/DialogTitle"; +import { Link } from "react-router-dom"; //-----------Components-----------// export default function EventBookingPage() { return (
-

Booking

+ Checkout
); } diff --git a/src/pages/userPages/myBookingPage.js b/src/pages/userPages/myBookingPage.js index 8447a61b..f7a5ba68 100644 --- a/src/pages/userPages/myBookingPage.js +++ b/src/pages/userPages/myBookingPage.js @@ -1,8 +1,13 @@ //-----------Libraries-----------// import { useState, useEffect } from "react"; +import { Link } from "react-router-dom"; //-----------Components-----------// export default function MyBookingPage() { - return
My booking page
; + return ( +
+

My booking

+
+ ); } diff --git a/src/pages/userPages/paymentPage.js b/src/pages/userPages/paymentPage.js deleted file mode 100644 index 62a5d047..00000000 --- a/src/pages/userPages/paymentPage.js +++ /dev/null @@ -1,8 +0,0 @@ -//-----------Libraries-----------// -import { useState, useEffect } from "react"; - -//-----------Components-----------// - -export default function PaymentPage() { - return
PaymentPage
; -} diff --git a/src/pages/userPages/returnPage.js b/src/pages/userPages/returnPage.js new file mode 100644 index 00000000..aa61fcac --- /dev/null +++ b/src/pages/userPages/returnPage.js @@ -0,0 +1,48 @@ +import React, { useState, useEffect } from "react"; +import { loadStripe } from "@stripe/stripe-js"; +import { + BrowserRouter as Router, + Route, + Routes, + Navigate, +} from "react-router-dom"; + +const stripePromise = loadStripe( + "pk_test_51OyC8VEkRpzvMxvMLDTzSAtzYuI8Aj98G0UQ3IkjB4ERSxgMQKMb9RNDz0LUq30pttvyJo0TsbnZVVZDxdP8SnIy000n2nrCq9" +); + +export default function ReturnPage() { + const [status, setStatus] = useState(null); + const [customerEmail, setCustomerEmail] = useState(""); + + useEffect(() => { + const queryString = window.location.search; + const urlParams = new URLSearchParams(queryString); + const sessionId = urlParams.get("session_id"); + + fetch(`/session-status?session_id=${sessionId}`) + .then((res) => res.json()) + .then((data) => { + setStatus(data.status); + setCustomerEmail(data.customer_email); + }); + }, []); + + if (status === "open") { + return ; + } + + if (status === "complete") { + return ( +
+

+ We appreciate your business! A confirmation email will be sent to{" "} + {customerEmail}. If you have any questions, please email{" "} + orders@example.com. +

+
+ ); + } + + return null; +} From fc174075933108be938af89b11e52980bd780844 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Tue, 26 Mar 2024 19:29:12 +0800 Subject: [PATCH 07/69] fixed stripe get session status --- src/App.js | 2 +- src/pages/userPages/checkOutPage.js | 1 + src/pages/userPages/returnPage.js | 20 ++++++++++++++------ 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/App.js b/src/App.js index 9a682c89..44059555 100644 --- a/src/App.js +++ b/src/App.js @@ -53,7 +53,7 @@ const App = () => { } /> } /> } /> - } /> + } /> } /> } /> } /> diff --git a/src/pages/userPages/checkOutPage.js b/src/pages/userPages/checkOutPage.js index d4bbaa08..260591de 100644 --- a/src/pages/userPages/checkOutPage.js +++ b/src/pages/userPages/checkOutPage.js @@ -6,6 +6,7 @@ import { EmbeddedCheckout, } from "@stripe/react-stripe-js"; +//public key const stripePromise = loadStripe( "pk_test_51OyC8VEkRpzvMxvMLDTzSAtzYuI8Aj98G0UQ3IkjB4ERSxgMQKMb9RNDz0LUq30pttvyJo0TsbnZVVZDxdP8SnIy000n2nrCq9" ); diff --git a/src/pages/userPages/returnPage.js b/src/pages/userPages/returnPage.js index aa61fcac..de1af119 100644 --- a/src/pages/userPages/returnPage.js +++ b/src/pages/userPages/returnPage.js @@ -1,5 +1,6 @@ import React, { useState, useEffect } from "react"; import { loadStripe } from "@stripe/stripe-js"; +import axios from "axios"; import { BrowserRouter as Router, Route, @@ -11,6 +12,8 @@ const stripePromise = loadStripe( "pk_test_51OyC8VEkRpzvMxvMLDTzSAtzYuI8Aj98G0UQ3IkjB4ERSxgMQKMb9RNDz0LUq30pttvyJo0TsbnZVVZDxdP8SnIy000n2nrCq9" ); +const BACKEND_URL = process.env.REACT_APP_BACKEND_URL; + export default function ReturnPage() { const [status, setStatus] = useState(null); const [customerEmail, setCustomerEmail] = useState(""); @@ -20,11 +23,16 @@ export default function ReturnPage() { const urlParams = new URLSearchParams(queryString); const sessionId = urlParams.get("session_id"); - fetch(`/session-status?session_id=${sessionId}`) - .then((res) => res.json()) - .then((data) => { - setStatus(data.status); - setCustomerEmail(data.customer_email); + axios + .get( + `http://localhost:3000/bookings/session-status?session_id=${sessionId}` + ) + .then((response) => { + setStatus(response.data.status); + setCustomerEmail(response.data.customer_email); + }) + .catch((error) => { + console.error("Error fetching client secret:", error); }); }, []); @@ -44,5 +52,5 @@ export default function ReturnPage() { ); } - return null; + // return null; } From b765cff845f275e33b4fd80720b81a4f2af61aba Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Tue, 26 Mar 2024 23:06:24 +0800 Subject: [PATCH 08/69] combined stripe with booking controller --- src/pages/userPages/checkOutPage.js | 12 ++++- src/pages/userPages/eventBookingPage.js | 69 +++++++++++++++++++++---- src/pages/userPages/myBookingPage.js | 7 ++- src/pages/userPages/returnPage.js | 4 +- 4 files changed, 80 insertions(+), 12 deletions(-) diff --git a/src/pages/userPages/checkOutPage.js b/src/pages/userPages/checkOutPage.js index 260591de..0c66d44f 100644 --- a/src/pages/userPages/checkOutPage.js +++ b/src/pages/userPages/checkOutPage.js @@ -1,4 +1,5 @@ import React, { useCallback, useState } from "react"; +import { useLocation } from "react-router-dom"; import { loadStripe } from "@stripe/stripe-js"; import axios from "axios"; import { @@ -14,10 +15,19 @@ const stripePromise = loadStripe( const BACKEND_URL = process.env.REACT_APP_BACKEND_URL; const CheckoutForm = () => { + const location = useLocation(); + const eventId = location.state.eventId; + const quantity_bought = location.state.quantity; + + console.log(eventId); + console.log(quantity_bought); + const fetchClientSecret = useCallback(() => { // Create a Checkout Session using axios return axios - .post("http://localhost:3000/bookings/create-checkout-session/4") + .post(`${BACKEND_URL}/bookings/create-checkout-session/${eventId}`, { + quantity_bought: quantity_bought, + }) .then((response) => response.data.clientSecret) .catch((error) => { console.error("Error fetching client secret:", error); diff --git a/src/pages/userPages/eventBookingPage.js b/src/pages/userPages/eventBookingPage.js index 4136b22f..ae14c321 100644 --- a/src/pages/userPages/eventBookingPage.js +++ b/src/pages/userPages/eventBookingPage.js @@ -1,20 +1,71 @@ //-----------Libraries-----------// import { useState, useEffect } from "react"; -import Button from "@mui/material/Button"; -import TextField from "@mui/material/TextField"; -import Dialog from "@mui/material/Dialog"; -import DialogActions from "@mui/material/DialogActions"; -import DialogContent from "@mui/material/DialogContent"; -import DialogContentText from "@mui/material/DialogContentText"; -import DialogTitle from "@mui/material/DialogTitle"; import { Link } from "react-router-dom"; +import InputLabel from "@mui/material/InputLabel"; +import MenuItem from "@mui/material/MenuItem"; +import FormHelperText from "@mui/material/FormHelperText"; +import FormControl from "@mui/material/FormControl"; +import Button from "@mui/material/Button"; +import Select from "@mui/material/Select"; +import axios from "axios"; //-----------Components-----------// -export default function EventBookingPage() { +const BACKEND_URL = process.env.REACT_APP_BACKEND_URL; + +export default function EventBookingPage({ eventId }) { + const [quantity, setQuantity] = useState(""); + const [capacity, setCapacity] = useState(""); + + useEffect(() => { + const fetchData = async () => { + try { + const response = await axios.get( + `${BACKEND_URL}/bookings/capacity/${eventId}` + ); + setCapacity(response.data.availableCapacity); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + fetchData(); + }, [eventId]); + + const handleQuantityChange = (event) => { + setQuantity(event.target.value); + }; + + const arrayTickets = Array.from({ length: capacity }, (_, i) => i + 1); + return (
- Checkout + + Tickets + + Quantity + +
); } diff --git a/src/pages/userPages/myBookingPage.js b/src/pages/userPages/myBookingPage.js index f7a5ba68..217b9f2f 100644 --- a/src/pages/userPages/myBookingPage.js +++ b/src/pages/userPages/myBookingPage.js @@ -1,13 +1,18 @@ //-----------Libraries-----------// import { useState, useEffect } from "react"; import { Link } from "react-router-dom"; +import InputLabel from "@mui/material/InputLabel"; +import MenuItem from "@mui/material/MenuItem"; +import FormHelperText from "@mui/material/FormHelperText"; +import FormControl from "@mui/material/FormControl"; +import Select from "@mui/material/Select"; //-----------Components-----------// export default function MyBookingPage() { return (
-

My booking

+

My booking page

); } diff --git a/src/pages/userPages/returnPage.js b/src/pages/userPages/returnPage.js index de1af119..3a6c805c 100644 --- a/src/pages/userPages/returnPage.js +++ b/src/pages/userPages/returnPage.js @@ -22,10 +22,12 @@ export default function ReturnPage() { const queryString = window.location.search; const urlParams = new URLSearchParams(queryString); const sessionId = urlParams.get("session_id"); + const eventId = urlParams.get("eventId"); + const quantity = urlParams.get("quantity"); axios .get( - `http://localhost:3000/bookings/session-status?session_id=${sessionId}` + `${BACKEND_URL}/bookings/session-status?session_id=${sessionId}&eventId=${eventId}&quantity=${quantity}` ) .then((response) => { setStatus(response.data.status); From fbdc51ffe234da3f2e9fc45463e6a047bc64b8a5 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Wed, 27 Mar 2024 00:45:22 +0800 Subject: [PATCH 09/69] added condition logic free events routing without stripe checkout --- src/App.js | 2 + src/components/EventPreviewList.js | 3 +- src/constant.js | 1 + src/pages/userPages/checkOutPage.js | 3 +- src/pages/userPages/eventBookingPage.js | 9 +++-- src/pages/userPages/eventDetailPage.js | 7 ++-- src/pages/userPages/freeReturnPage.js | 52 +++++++++++++++++++++++++ src/pages/userPages/returnPage.js | 10 +++-- 8 files changed, 73 insertions(+), 14 deletions(-) create mode 100644 src/constant.js create mode 100644 src/pages/userPages/freeReturnPage.js diff --git a/src/App.js b/src/App.js index 44059555..2eb6a8d1 100644 --- a/src/App.js +++ b/src/App.js @@ -21,6 +21,7 @@ import FavPage from "./pages/userPages/favPage.js"; import MyBookingPage from "./pages/userPages/myBookingPage.js"; import MyProfilePage from "./pages/userPages/myProfilePage.js"; import CheckoutForm from "./pages/userPages/checkOutPage.js"; +import FreeReturnPage from "./pages/userPages/freeReturnPage.js"; import ReturnPage from "./pages/userPages/returnPage.js"; //-----------AdminPages-----------// @@ -53,6 +54,7 @@ const App = () => { } /> } /> } /> + } /> } /> } /> } /> diff --git a/src/components/EventPreviewList.js b/src/components/EventPreviewList.js index 18fabf94..a4db2de5 100644 --- a/src/components/EventPreviewList.js +++ b/src/components/EventPreviewList.js @@ -4,8 +4,7 @@ import axios from "axios"; //-----------Components-----------// import EventPreview from "./EventPreview"; - -const BACKEND_URL = process.env.REACT_APP_BACKEND_URL; +import { BACKEND_URL } from "../constant.js"; const EventPreviewList = () => { const [events, setEvents] = useState([]); diff --git a/src/constant.js b/src/constant.js new file mode 100644 index 00000000..1cc46964 --- /dev/null +++ b/src/constant.js @@ -0,0 +1 @@ +export const BACKEND_URL = "http://localhost:3000"; diff --git a/src/pages/userPages/checkOutPage.js b/src/pages/userPages/checkOutPage.js index 0c66d44f..ec4eb706 100644 --- a/src/pages/userPages/checkOutPage.js +++ b/src/pages/userPages/checkOutPage.js @@ -6,14 +6,13 @@ import { EmbeddedCheckoutProvider, EmbeddedCheckout, } from "@stripe/react-stripe-js"; +import { BACKEND_URL } from "../../constant.js"; //public key const stripePromise = loadStripe( "pk_test_51OyC8VEkRpzvMxvMLDTzSAtzYuI8Aj98G0UQ3IkjB4ERSxgMQKMb9RNDz0LUq30pttvyJo0TsbnZVVZDxdP8SnIy000n2nrCq9" ); -const BACKEND_URL = process.env.REACT_APP_BACKEND_URL; - const CheckoutForm = () => { const location = useLocation(); const eventId = location.state.eventId; diff --git a/src/pages/userPages/eventBookingPage.js b/src/pages/userPages/eventBookingPage.js index ae14c321..4d08bcfd 100644 --- a/src/pages/userPages/eventBookingPage.js +++ b/src/pages/userPages/eventBookingPage.js @@ -10,19 +10,20 @@ import Select from "@mui/material/Select"; import axios from "axios"; //-----------Components-----------// +import { BACKEND_URL } from "../../constant.js"; -const BACKEND_URL = process.env.REACT_APP_BACKEND_URL; - -export default function EventBookingPage({ eventId }) { +export default function EventBookingPage({ eventId, isFree }) { const [quantity, setQuantity] = useState(""); const [capacity, setCapacity] = useState(""); + //will add condition if price is free, don't need to go through stripe payment checkout useEffect(() => { const fetchData = async () => { try { const response = await axios.get( `${BACKEND_URL}/bookings/capacity/${eventId}` ); + setCapacity(response.data.availableCapacity); } catch (error) { console.error("Error fetching data:", error); @@ -59,7 +60,7 @@ export default function EventBookingPage({ eventId }) { {showRegistration && ( - + )}
diff --git a/src/pages/userPages/freeReturnPage.js b/src/pages/userPages/freeReturnPage.js new file mode 100644 index 00000000..fc357776 --- /dev/null +++ b/src/pages/userPages/freeReturnPage.js @@ -0,0 +1,52 @@ +import React, { useState, useEffect } from "react"; +import { Link } from "react-router-dom"; +import { useLocation } from "react-router-dom"; +import axios from "axios"; +import { + BrowserRouter as Router, + Route, + Routes, + Navigate, +} from "react-router-dom"; +import Button from "@mui/material/Button"; + +import { BACKEND_URL } from "../../constant.js"; + +export default function FreeReturnPage() { + const [status, setStatus] = useState(null); + const location = useLocation(); + const eventId = location.state.eventId; + const quantity_bought = location.state.quantity; + + console.log(eventId); + console.log(quantity_bought); + + useEffect(() => { + axios + .post(`${BACKEND_URL}/bookings/${eventId}`, { + eventId: eventId, + quantity_bought: quantity_bought, + }) + .then((response) => { + setStatus("complete"); + }) + .catch((error) => { + console.error("Error inserting data", error); + }); + }, []); + + return ( +
+

+ We appreciate your business! A confirmation email will be sent to you. + If you have any questions, please email{" "} + orders@example.com. + +

+
+ ); + + // return null; +} diff --git a/src/pages/userPages/returnPage.js b/src/pages/userPages/returnPage.js index 3a6c805c..0241c707 100644 --- a/src/pages/userPages/returnPage.js +++ b/src/pages/userPages/returnPage.js @@ -1,4 +1,5 @@ import React, { useState, useEffect } from "react"; +import { Link } from "react-router-dom"; import { loadStripe } from "@stripe/stripe-js"; import axios from "axios"; import { @@ -7,13 +8,13 @@ import { Routes, Navigate, } from "react-router-dom"; +import Button from "@mui/material/Button"; +import { BACKEND_URL } from "../../constant.js"; const stripePromise = loadStripe( "pk_test_51OyC8VEkRpzvMxvMLDTzSAtzYuI8Aj98G0UQ3IkjB4ERSxgMQKMb9RNDz0LUq30pttvyJo0TsbnZVVZDxdP8SnIy000n2nrCq9" ); -const BACKEND_URL = process.env.REACT_APP_BACKEND_URL; - export default function ReturnPage() { const [status, setStatus] = useState(null); const [customerEmail, setCustomerEmail] = useState(""); @@ -27,7 +28,7 @@ export default function ReturnPage() { axios .get( - `${BACKEND_URL}/bookings/session-status?session_id=${sessionId}&eventId=${eventId}&quantity=${quantity}` + `http://localhost:3000/bookings/session-status?session_id=${sessionId}&eventId=${eventId}&quantity=${quantity}` ) .then((response) => { setStatus(response.data.status); @@ -49,6 +50,9 @@ export default function ReturnPage() { We appreciate your business! A confirmation email will be sent to{" "} {customerEmail}. If you have any questions, please email{" "} orders@example.com. +

); From 0088e314cfa4183d22cdfef3249032c1bfb4f7de Mon Sep 17 00:00:00 2001 From: kendigm Date: Thu, 28 Mar 2024 10:10:06 +0500 Subject: [PATCH 10/69] Authentication SignIn Page Design. --- src/components/EventPreviewList.js | 1 - src/constant.js | 2 +- src/pages/signInPage.js | 193 ++++++++++++++++++++++++++++- 3 files changed, 188 insertions(+), 8 deletions(-) diff --git a/src/components/EventPreviewList.js b/src/components/EventPreviewList.js index a4db2de5..393f2fc9 100644 --- a/src/components/EventPreviewList.js +++ b/src/components/EventPreviewList.js @@ -18,7 +18,6 @@ const EventPreviewList = () => { console.error("Error fetching data:", error); } }; - fetchData(); }, []); diff --git a/src/constant.js b/src/constant.js index 1cc46964..3c6be070 100644 --- a/src/constant.js +++ b/src/constant.js @@ -1 +1 @@ -export const BACKEND_URL = "http://localhost:3000"; +export const BACKEND_URL = "http://localhost:5000"; diff --git a/src/pages/signInPage.js b/src/pages/signInPage.js index 56e6a8ed..42b1b60a 100644 --- a/src/pages/signInPage.js +++ b/src/pages/signInPage.js @@ -1,8 +1,189 @@ -//-----------Libraries-----------// -import { useState, useEffect } from "react"; +import React, { useState } from "react"; +import Grid from "@mui/material/Grid"; +import Paper from "@mui/material/Paper"; +import Typography from "@mui/material/Typography"; +import TextField from "@mui/material/TextField"; +import Button from "@mui/material/Button"; +import { Link } from "react-router-dom"; +import EmailIcon from "@mui/icons-material/Email"; +import InputAdornment from "@mui/material/InputAdornment"; +import LockIcon from "@mui/icons-material/Lock"; +import ArrowForwardIcon from "@mui/icons-material/ArrowForward"; +import ToggleButton from "@mui/material/ToggleButton"; +import ToggleButtonGroup from "@mui/material/ToggleButtonGroup"; +import { CheckCircleOutline, CheckCircle } from "@mui/icons-material"; +import CancelOutlinedIcon from "@mui/icons-material/CancelOutlined"; +const SignIn = () => { + const [rememberMe, setRememberMe] = useState(false); + const handleRememberMe = () => { + setRememberMe(!rememberMe); + }; + return ( +
+ + + + + EventLink + + + Sign in + +
+ + + + ), + }} + /> + + + + ), + }} + /> -//-----------Components-----------// +
+ + + {rememberMe ? ( + + ) : ( + + )}{" "} + + Remember me + + + + +
+ + + Don’t have any account?{" "} + + Sign Up + + + +
+
+
+
+ ); +}; -export default function SignInPage() { - return
SignInPage
; -} +export default SignIn; From 4291c02a81db502b15081b3fea2368f43362a2d7 Mon Sep 17 00:00:00 2001 From: kendigm Date: Thu, 28 Mar 2024 15:48:17 +0500 Subject: [PATCH 11/69] Authentication Sign up Screen Design. --- src/index.css | 12 +- src/pages/registerPage.js | 164 ++++++++++++++++++++++++++- src/pages/resetPasswordPage.js | 11 +- src/pages/signInPage.js | 17 +-- src/pages/userPages/myProfilePage.js | 11 +- 5 files changed, 184 insertions(+), 31 deletions(-) diff --git a/src/index.css b/src/index.css index 4a1df4db..aad72269 100644 --- a/src/index.css +++ b/src/index.css @@ -1,13 +1,13 @@ body { margin: 0; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", - "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", - sans-serif; + font-family: "Roboto", "Droid Sans", "Helvetica Neue", sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; + scroll-behavior: smooth; + padding: 0; + box-sizing: border-box; } code { - font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", - monospace; -} + font-family: "Roboto", "Droid Sans", "Helvetica Neue", sans-serif; +} \ No newline at end of file diff --git a/src/pages/registerPage.js b/src/pages/registerPage.js index 6e4c9e8f..67bc1526 100644 --- a/src/pages/registerPage.js +++ b/src/pages/registerPage.js @@ -1,8 +1,160 @@ -//-----------Libraries-----------// -import { useState, useEffect } from "react"; - -//-----------Components-----------// - +import Grid from "@mui/material/Grid"; +import Paper from "@mui/material/Paper"; +import Typography from "@mui/material/Typography"; +import TextField from "@mui/material/TextField"; +import Button from "@mui/material/Button"; +import { Link } from "react-router-dom"; +import MailOutlinedIcon from "@mui/icons-material/MailOutlined"; +import InputAdornment from "@mui/material/InputAdornment"; +import LockOutlinedIcon from "@mui/icons-material/LockOutlined"; +import ArrowForwardIcon from "@mui/icons-material/ArrowForward"; +import ArrowBackIcon from "@mui/icons-material/ArrowBack"; +import PersonOutlineOutlinedIcon from "@mui/icons-material/PersonOutlineOutlined"; export default function RegisterPage() { - return
Register page
; + return ( +
+ + + +
+ + + +
+ + Sign up + +
+ + + + ), + }} + />{" "} + + + + ), + }} + />{" "} + + + + ), + }} + /> + + + + ), + }} + /> + + + Already have an account?{" "} + + Sign in + + + +
+
+
+
+ ); } diff --git a/src/pages/resetPasswordPage.js b/src/pages/resetPasswordPage.js index 9798195c..73e76f1c 100644 --- a/src/pages/resetPasswordPage.js +++ b/src/pages/resetPasswordPage.js @@ -1,8 +1,7 @@ -//-----------Libraries-----------// -import { useState, useEffect } from "react"; +import React from 'react' -//-----------Components-----------// - -export default function ResetPasswordPage() { - return
Reset Password Page
; +const resetPasswordPage = () => { + return
resetPasswordPage
; } + +export default resetPasswordPage diff --git a/src/pages/signInPage.js b/src/pages/signInPage.js index 42b1b60a..62d34668 100644 --- a/src/pages/signInPage.js +++ b/src/pages/signInPage.js @@ -5,14 +5,15 @@ import Typography from "@mui/material/Typography"; import TextField from "@mui/material/TextField"; import Button from "@mui/material/Button"; import { Link } from "react-router-dom"; -import EmailIcon from "@mui/icons-material/Email"; +import MailOutlinedIcon from "@mui/icons-material/MailOutlined"; import InputAdornment from "@mui/material/InputAdornment"; -import LockIcon from "@mui/icons-material/Lock"; +import LockOutlinedIcon from "@mui/icons-material/LockOutlined"; import ArrowForwardIcon from "@mui/icons-material/ArrowForward"; import ToggleButton from "@mui/material/ToggleButton"; import ToggleButtonGroup from "@mui/material/ToggleButtonGroup"; -import { CheckCircleOutline, CheckCircle } from "@mui/icons-material"; +import { CheckCircle } from "@mui/icons-material"; import CancelOutlinedIcon from "@mui/icons-material/CancelOutlined"; + const SignIn = () => { const [rememberMe, setRememberMe] = useState(false); const handleRememberMe = () => { @@ -48,9 +49,9 @@ const SignIn = () => { variant="h5" component="h2" style={{ - marginBottom: ".5rem", + marginBottom: "1.5rem", fontWeight: "bold", - textAlign: "center", // Center-align the text + textAlign: "start", // Center-align the text }} > Sign in @@ -66,7 +67,7 @@ const SignIn = () => { InputProps={{ startAdornment: ( - + ), }} @@ -81,7 +82,7 @@ const SignIn = () => { InputProps={{ startAdornment: ( - + ), }} @@ -120,6 +121,8 @@ const SignIn = () => {
; +const myProfilePage = () => { + return
myProfilePage myProfilePage
; } + +export default myProfilePage From f09cb064c37efcd8aa467954ade5d0b7623d2eb3 Mon Sep 17 00:00:00 2001 From: kendigm Date: Fri, 29 Mar 2024 05:31:51 +0500 Subject: [PATCH 12/69] Authentication Reset Password Screen Design. --- src/pages/resetPasswordPage.js | 107 +++++++++++++++++++++++++-- src/pages/userPages/myProfilePage.js | 6 +- 2 files changed, 105 insertions(+), 8 deletions(-) diff --git a/src/pages/resetPasswordPage.js b/src/pages/resetPasswordPage.js index 73e76f1c..dfe431f8 100644 --- a/src/pages/resetPasswordPage.js +++ b/src/pages/resetPasswordPage.js @@ -1,7 +1,104 @@ -import React from 'react' +import Grid from "@mui/material/Grid"; +import Paper from "@mui/material/Paper"; +import Typography from "@mui/material/Typography"; +import TextField from "@mui/material/TextField"; +import Button from "@mui/material/Button"; +import { Link } from "react-router-dom"; +import MailOutlinedIcon from "@mui/icons-material/MailOutlined"; +import InputAdornment from "@mui/material/InputAdornment"; +import ArrowForwardIcon from "@mui/icons-material/ArrowForward"; +import ArrowBackIcon from "@mui/icons-material/ArrowBack"; -const resetPasswordPage = () => { - return
resetPasswordPage
; +export default function ResetPasswordPage() { + return ( +
+ + + +
+ + + +
+ + Reset Password + + + Please enter your email address to request a password reset + +
+ + + + ), + }} + />{" "} + + +
+
+
+
+ ); } - -export default resetPasswordPage diff --git a/src/pages/userPages/myProfilePage.js b/src/pages/userPages/myProfilePage.js index 0b3618de..0c86270b 100644 --- a/src/pages/userPages/myProfilePage.js +++ b/src/pages/userPages/myProfilePage.js @@ -1,7 +1,7 @@ -import React from 'react' +import React from "react"; const myProfilePage = () => { return
myProfilePage myProfilePage
; -} +}; -export default myProfilePage +export default myProfilePage; From 0d20dfd1986d4745ac406c32eaae367fcc02a733 Mon Sep 17 00:00:00 2001 From: kendigm Date: Fri, 29 Mar 2024 09:33:41 +0500 Subject: [PATCH 13/69] Authentication Sidebar Profile Screen Design. --- src/pages/userPages/myProfilePage.js | 106 ++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 4 deletions(-) diff --git a/src/pages/userPages/myProfilePage.js b/src/pages/userPages/myProfilePage.js index 0c86270b..9805610b 100644 --- a/src/pages/userPages/myProfilePage.js +++ b/src/pages/userPages/myProfilePage.js @@ -1,7 +1,105 @@ import React from "react"; +import Avatar from "@mui/material/Avatar"; +import Typography from "@mui/material/Typography"; +import List from "@mui/material/List"; +import ListItem from "@mui/material/ListItem"; +import ListItemIcon from "@mui/material/ListItemIcon"; +import ListItemText from "@mui/material/ListItemText"; +import MessageIcon from "@mui/icons-material/Message"; +import CalendarTodayIcon from "@mui/icons-material/CalendarToday"; +import BookmarkIcon from "@mui/icons-material/Bookmark"; +import ContactSupportIcon from "@mui/icons-material/ContactSupport"; +import SettingsIcon from "@mui/icons-material/Settings"; +import HelpIcon from "@mui/icons-material/Help"; +import ExitToAppIcon from "@mui/icons-material/ExitToApp"; +import { Link } from "react-router-dom"; -const myProfilePage = () => { - return
myProfilePage myProfilePage
; -}; +export default function myProfilePage() { + // + const user = { + name: "Glory Kendi", + profileImg: "/logo192.png", + unreadMessages: 3, // Number of unread messages + }; -export default myProfilePage; + return ( +
+
+
+ +
+ + {user.name} + +
+ + + + + + + {" "} + + + + + + {user.unreadMessages > 0 && ( + + {user.unreadMessages} + + )} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ ); +} From 6a5ec69b67c6fab5b8400d246f08d79acf6ef0dd Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Fri, 29 Mar 2024 19:36:40 +0800 Subject: [PATCH 14/69] added search bar --- src/App.js | 3 ++ src/components/searchBar.css | 8 +++++ src/components/searchBar.js | 31 +++++++++++++++++++ src/pages/userPages/homePage.js | 8 ++++- src/pages/userPages/searchPage.js | 50 +++++++++++++++++++++++++++++++ src/pages/userPages/userPages.css | 7 +++++ 6 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 src/components/searchBar.css create mode 100644 src/components/searchBar.js create mode 100644 src/pages/userPages/searchPage.js create mode 100644 src/pages/userPages/userPages.css diff --git a/src/App.js b/src/App.js index 2eb6a8d1..eea1f9a5 100644 --- a/src/App.js +++ b/src/App.js @@ -23,6 +23,7 @@ import MyProfilePage from "./pages/userPages/myProfilePage.js"; import CheckoutForm from "./pages/userPages/checkOutPage.js"; import FreeReturnPage from "./pages/userPages/freeReturnPage.js"; import ReturnPage from "./pages/userPages/returnPage.js"; +import SearchPage from "./pages/userPages/searchPage.js"; //-----------AdminPages-----------// import AdminHomePage from "./pages/adminPages/adminHomePage.js"; @@ -59,6 +60,8 @@ const App = () => { } /> } /> } /> + } /> + } /> } /> diff --git a/src/components/searchBar.css b/src/components/searchBar.css new file mode 100644 index 00000000..ed19d157 --- /dev/null +++ b/src/components/searchBar.css @@ -0,0 +1,8 @@ +.Search-bar { + display: flex; + width: 90vw; + justify-content: center; + margin-left: 5vw; + margin-right: 5vw; + margin-top: 5vh; +} diff --git a/src/components/searchBar.js b/src/components/searchBar.js new file mode 100644 index 00000000..5c9aae30 --- /dev/null +++ b/src/components/searchBar.js @@ -0,0 +1,31 @@ +//-----------Libraries-----------// +import { useState, useEffect } from "react"; +import { Link, useNavigate } from "react-router-dom"; +import SearchIcon from "@mui/icons-material/Search"; +import { styled, alpha } from "@mui/material/styles"; +import InputBase from "@mui/material/InputBase"; +import { Input, IconButton } from "@mui/material"; + +//-----------Components-----------// +import "./searchBar.css"; + +export default function SearchBar() { + const [keyword, setKeyword] = useState(""); + const navi = useNavigate(); + + return ( +
+ setKeyword(e.target.value)} + /> + { + setKeyword(""); + navi(`/search/${keyword}`); + }} + /> +
+ ); +} diff --git a/src/pages/userPages/homePage.js b/src/pages/userPages/homePage.js index 5580d4dc..74edb0d9 100644 --- a/src/pages/userPages/homePage.js +++ b/src/pages/userPages/homePage.js @@ -1,13 +1,19 @@ //-----------Libraries-----------// import { useState, useEffect } from "react"; +import SearchIcon from "@mui/icons-material/Search"; +import TextField from "@mui/material/TextField"; //-----------Components-----------// import EventPreviewList from "../../components/EventPreviewList"; +import SearchBar from "../../components/searchBar"; export default function HomePage() { return (
- +
+ + +
); } diff --git a/src/pages/userPages/searchPage.js b/src/pages/userPages/searchPage.js new file mode 100644 index 00000000..1ab9b817 --- /dev/null +++ b/src/pages/userPages/searchPage.js @@ -0,0 +1,50 @@ +//-----------Libraries-----------// +import { useState, useEffect } from "react"; +import { useOutletContext, useParams } from "react-router-dom"; +import axios from "axios"; + +//-----------Components-----------// +import { BACKEND_URL } from "../../constant.js"; +import EventPreview from "../../components/EventPreview.js"; +import SearchBar from "../../components/searchBar"; +import "./userPages.css"; + +export default function SearchPage() { + const { keyword } = useParams(); + const [events, setEvents] = useState([]); + + useEffect(() => { + const fetchData = async () => { + try { + const response = await axios.get( + `${BACKEND_URL}/events/search/${keyword}` + ); + + setEvents(response.data); + console.log(events); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + fetchData(); + }, [keyword]); + + const eventPreviews = + events && events.length > 0 ? ( +
+ {events.map((event) => ( + + ))} +
+ ) : ( +
No events found
+ ); + + return ( +
+ + {eventPreviews} +
+ ); +} diff --git a/src/pages/userPages/userPages.css b/src/pages/userPages/userPages.css new file mode 100644 index 00000000..0801dafc --- /dev/null +++ b/src/pages/userPages/userPages.css @@ -0,0 +1,7 @@ +.div-no-event { + display: flex; + width: 90vw; + margin-left: 5vw; + margin-right: 5vw; + justify-content: center; +} From 3dbf8a0f039297d58d0665c95ca838ce48937e45 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Fri, 29 Mar 2024 22:46:52 +0800 Subject: [PATCH 15/69] added auth0 loginwithredirect --- package-lock.json | 31 ++++++ package.json | 1 + src/App.js | 126 ++++++++++++------------- src/constant.js | 2 +- src/index.js | 71 +++++++++++++- src/pages/userPages/checkOutPage.js | 38 ++++++-- src/pages/userPages/eventDetailPage.js | 8 +- 7 files changed, 203 insertions(+), 74 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5f461fcf..692e456c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "project-3-frontend-bootcamp", "version": "0.1.0", "dependencies": { + "@auth0/auth0-react": "^2.2.4", "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.0", "@mui/icons-material": "^5.15.14", @@ -33,6 +34,23 @@ "node": ">=6.0.0" } }, + "node_modules/@auth0/auth0-react": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@auth0/auth0-react/-/auth0-react-2.2.4.tgz", + "integrity": "sha512-l29PQC0WdgkCoOc6WeMAY26gsy/yXJICW0jHfj0nz8rZZphYKrLNqTRWFFCMJY+sagza9tSgB1kG/UvQYgGh9A==", + "dependencies": { + "@auth0/auth0-spa-js": "^2.1.3" + }, + "peerDependencies": { + "react": "^16.11.0 || ^17 || ^18", + "react-dom": "^16.11.0 || ^17 || ^18" + } + }, + "node_modules/@auth0/auth0-spa-js": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@auth0/auth0-spa-js/-/auth0-spa-js-2.1.3.tgz", + "integrity": "sha512-NMTBNuuG4g3rame1aCnNS5qFYIzsTUV5qTFPRfTyYFS1feS6jsCBR+eTq9YkxCp1yuoM2UIcjunPaoPl77U9xQ==" + }, "node_modules/@babel/code-frame": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", @@ -16521,6 +16539,19 @@ "@jridgewell/trace-mapping": "^0.3.9" } }, + "@auth0/auth0-react": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@auth0/auth0-react/-/auth0-react-2.2.4.tgz", + "integrity": "sha512-l29PQC0WdgkCoOc6WeMAY26gsy/yXJICW0jHfj0nz8rZZphYKrLNqTRWFFCMJY+sagza9tSgB1kG/UvQYgGh9A==", + "requires": { + "@auth0/auth0-spa-js": "^2.1.3" + } + }, + "@auth0/auth0-spa-js": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@auth0/auth0-spa-js/-/auth0-spa-js-2.1.3.tgz", + "integrity": "sha512-NMTBNuuG4g3rame1aCnNS5qFYIzsTUV5qTFPRfTyYFS1feS6jsCBR+eTq9YkxCp1yuoM2UIcjunPaoPl77U9xQ==" + }, "@babel/code-frame": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", diff --git a/package.json b/package.json index 2c5bdd45..49dee4a3 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "version": "0.1.0", "private": true, "dependencies": { + "@auth0/auth0-react": "^2.2.4", "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.0", "@mui/icons-material": "^5.15.14", diff --git a/src/App.js b/src/App.js index eea1f9a5..f4b60178 100644 --- a/src/App.js +++ b/src/App.js @@ -1,71 +1,71 @@ -//-----------Libraries-----------// -import React from "react"; -import { BrowserRouter, Routes, Route } from "react-router-dom"; +// //-----------Libraries-----------// +// import React from "react"; +// import { BrowserRouter, Routes, Route } from "react-router-dom"; -//-----------Components-----------// -import NavBar from "./components/navbar.js"; +// //-----------Components-----------// +// import NavBar from "./components/navbar.js"; -//-----------Styling-----------// -import "./index.css"; +// //-----------Styling-----------// +// import "./index.css"; -//-----------Pages-----------// -import RegisterPage from "./pages/registerPage.js"; -import SignInPage from "./pages/signInPage.js"; -import ResetPasswordPage from "./pages/resetPasswordPage.js"; -import ErrorPage from "./pages/errorPage.js"; +// //-----------Pages-----------// +// import RegisterPage from "./pages/registerPage.js"; +// import SignInPage from "./pages/signInPage.js"; +// import ResetPasswordPage from "./pages/resetPasswordPage.js"; +// import ErrorPage from "./pages/errorPage.js"; -//-----------UserPages-----------// -import HomePage from "./pages/userPages/homePage.js"; -import EventDetailPage from "./pages/userPages/eventDetailPage.js"; -import FavPage from "./pages/userPages/favPage.js"; -import MyBookingPage from "./pages/userPages/myBookingPage.js"; -import MyProfilePage from "./pages/userPages/myProfilePage.js"; -import CheckoutForm from "./pages/userPages/checkOutPage.js"; -import FreeReturnPage from "./pages/userPages/freeReturnPage.js"; -import ReturnPage from "./pages/userPages/returnPage.js"; -import SearchPage from "./pages/userPages/searchPage.js"; +// //-----------UserPages-----------// +// import HomePage from "./pages/userPages/homePage.js"; +// import EventDetailPage from "./pages/userPages/eventDetailPage.js"; +// import FavPage from "./pages/userPages/favPage.js"; +// import MyBookingPage from "./pages/userPages/myBookingPage.js"; +// import MyProfilePage from "./pages/userPages/myProfilePage.js"; +// import CheckoutForm from "./pages/userPages/checkOutPage.js"; +// import FreeReturnPage from "./pages/userPages/freeReturnPage.js"; +// import ReturnPage from "./pages/userPages/returnPage.js"; +// import SearchPage from "./pages/userPages/searchPage.js"; -//-----------AdminPages-----------// -import AdminHomePage from "./pages/adminPages/adminHomePage.js"; -import AdminProfilePage from "./pages/adminPages/adminProfilePage.js"; -import AdminEventPage from "./pages/adminPages/adminEventPage.js"; -import AdminEventAttendancePage from "./pages/adminPages/adminEventAttendancePage.js"; -import AdminAnalyticsPage from "./pages/adminPages/adminAnalyticsPage.js"; +// //-----------AdminPages-----------// +// import AdminHomePage from "./pages/adminPages/adminHomePage.js"; +// import AdminProfilePage from "./pages/adminPages/adminProfilePage.js"; +// import AdminEventPage from "./pages/adminPages/adminEventPage.js"; +// import AdminEventAttendancePage from "./pages/adminPages/adminEventAttendancePage.js"; +// import AdminAnalyticsPage from "./pages/adminPages/adminAnalyticsPage.js"; -const AdminRoutes = () => ( - - } /> - } /> - } /> - } /> - } /> - } /> - -); +// const AdminRoutes = () => ( +// +// } /> +// } /> +// } /> +// } /> +// } /> +// } /> +// +// ); -const App = () => { - return ( - - - - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - - - ); -}; +// const App = () => { +// return ( +// +// +// +// } /> +// } /> +// } /> +// } /> +// } /> +// } /> +// } /> +// } /> +// } /> +// } /> +// } /> +// } /> +// } /> +// } /> +// } /> +// +// +// ); +// }; -export default App; +// export default App; diff --git a/src/constant.js b/src/constant.js index 3c6be070..1cc46964 100644 --- a/src/constant.js +++ b/src/constant.js @@ -1 +1 @@ -export const BACKEND_URL = "http://localhost:5000"; +export const BACKEND_URL = "http://localhost:3000"; diff --git a/src/index.js b/src/index.js index 907b6d82..998f56ff 100644 --- a/src/index.js +++ b/src/index.js @@ -1,12 +1,79 @@ //-----------Libraries-----------// import React from "react"; +import { BrowserRouter, Routes, Route } from "react-router-dom"; +import { Auth0Provider } from "@auth0/auth0-react"; import ReactDOM from "react-dom/client"; //-----------Components-----------// -import App from "./App"; +import NavBar from "./components/navbar.js"; //-----------Styling-----------// import "./index.css"; +//-----------Pages-----------// +import RegisterPage from "./pages/registerPage.js"; +import SignInPage from "./pages/signInPage.js"; +import ResetPasswordPage from "./pages/resetPasswordPage.js"; +import ErrorPage from "./pages/errorPage.js"; + +//-----------UserPages-----------// +import HomePage from "./pages/userPages/homePage.js"; +import EventDetailPage from "./pages/userPages/eventDetailPage.js"; +import FavPage from "./pages/userPages/favPage.js"; +import MyBookingPage from "./pages/userPages/myBookingPage.js"; +import MyProfilePage from "./pages/userPages/myProfilePage.js"; +import CheckoutForm from "./pages/userPages/checkOutPage.js"; +import FreeReturnPage from "./pages/userPages/freeReturnPage.js"; +import ReturnPage from "./pages/userPages/returnPage.js"; +import SearchPage from "./pages/userPages/searchPage.js"; + +//-----------AdminPages-----------// +import AdminHomePage from "./pages/adminPages/adminHomePage.js"; +import AdminProfilePage from "./pages/adminPages/adminProfilePage.js"; +import AdminEventPage from "./pages/adminPages/adminEventPage.js"; +import AdminEventAttendancePage from "./pages/adminPages/adminEventAttendancePage.js"; +import AdminAnalyticsPage from "./pages/adminPages/adminAnalyticsPage.js"; + const root = ReactDOM.createRoot(document.getElementById("root")); -root.render(); + +const AdminRoutes = () => ( + + } /> + } /> + } /> + } /> + } /> + } /> + +); + +root.render( + + + + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + + +); diff --git a/src/pages/userPages/checkOutPage.js b/src/pages/userPages/checkOutPage.js index ec4eb706..b625fbcd 100644 --- a/src/pages/userPages/checkOutPage.js +++ b/src/pages/userPages/checkOutPage.js @@ -1,4 +1,4 @@ -import React, { useCallback, useState } from "react"; +import React, { useCallback, useState, useEffect } from "react"; import { useLocation } from "react-router-dom"; import { loadStripe } from "@stripe/stripe-js"; import axios from "axios"; @@ -7,6 +7,7 @@ import { EmbeddedCheckout, } from "@stripe/react-stripe-js"; import { BACKEND_URL } from "../../constant.js"; +import { useAuth0 } from "@auth0/auth0-react"; //public key const stripePromise = loadStripe( @@ -17,22 +18,45 @@ const CheckoutForm = () => { const location = useLocation(); const eventId = location.state.eventId; const quantity_bought = location.state.quantity; + const { user, loginWithRedirect, isAuthenticated, getAccessTokenSilently } = + useAuth0(); + const [accessToken, setAccessToken] = useState(null); - console.log(eventId); - console.log(quantity_bought); + useEffect(() => { + const fetchAccessToken = async () => { + try { + const token = await getAccessTokenSilently(); + setAccessToken(token); + } catch (error) { + console.error("Error fetching access token:", error); + } + }; + + if (isAuthenticated) { + fetchAccessToken(); + } + }, [getAccessTokenSilently, isAuthenticated]); const fetchClientSecret = useCallback(() => { // Create a Checkout Session using axios return axios - .post(`${BACKEND_URL}/bookings/create-checkout-session/${eventId}`, { - quantity_bought: quantity_bought, - }) + .post( + `${BACKEND_URL}/bookings/create-checkout-session/${eventId}`, + { + quantity_bought: quantity_bought, + }, + { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + } + ) .then((response) => response.data.clientSecret) .catch((error) => { console.error("Error fetching client secret:", error); throw error; // rethrow the error to handle it elsewhere if needed }); - }, []); + }, [accessToken, eventId, quantity_bought]); const options = { fetchClientSecret }; console.log(options); diff --git a/src/pages/userPages/eventDetailPage.js b/src/pages/userPages/eventDetailPage.js index 210e2770..d8dbab0b 100644 --- a/src/pages/userPages/eventDetailPage.js +++ b/src/pages/userPages/eventDetailPage.js @@ -5,6 +5,7 @@ import axios from "axios"; import Button from "@mui/material/Button"; import Dialog from "@mui/material/Dialog"; import DialogTitle from "@mui/material/DialogTitle"; +import { useAuth0 } from "@auth0/auth0-react"; //-----------Components-----------// import EventBookingPage from "./eventBookingPage"; @@ -15,6 +16,8 @@ export default function EventDetailPage() { const [eventId, setEventId] = useState(); const [showRegistration, setShowRegistraton] = useState(null); const [isFree, setIsFree] = useState(null); + const { user, loginWithRedirect, isAuthenticated, getAccessTokenSilently } = + useAuth0(); useEffect(() => { const fetchData = async () => { @@ -36,7 +39,10 @@ export default function EventDetailPage() { setEventId(params.eventId); } - const handleClickOpen = () => { + const handleClickOpen = async () => { + if (!isAuthenticated) { + return loginWithRedirect(); + } setShowRegistraton(true); }; From d907c8e3e5f208e7e6be9a6ca8af307e8446d13c Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Sat, 30 Mar 2024 01:09:19 +0800 Subject: [PATCH 16/69] added checkbox filter --- src/components/searchBar.js | 140 +++++++++++++++++++++++-- src/pages/userPages/eventDetailPage.js | 63 +++++++++-- src/pages/userPages/returnPage.js | 1 + src/pages/userPages/searchPage.js | 11 +- 4 files changed, 195 insertions(+), 20 deletions(-) diff --git a/src/components/searchBar.js b/src/components/searchBar.js index 5c9aae30..4769dfc7 100644 --- a/src/components/searchBar.js +++ b/src/components/searchBar.js @@ -5,13 +5,138 @@ import SearchIcon from "@mui/icons-material/Search"; import { styled, alpha } from "@mui/material/styles"; import InputBase from "@mui/material/InputBase"; import { Input, IconButton } from "@mui/material"; +import Box from "@mui/material/Box"; +import Drawer from "@mui/material/Drawer"; +import Button from "@mui/material/Button"; +import List from "@mui/material/List"; +import Divider from "@mui/material/Divider"; +import ListItem from "@mui/material/ListItem"; +import ListItemText from "@mui/material/ListItemText"; +import TuneIcon from "@mui/icons-material/Tune"; +import Checkbox from "@mui/material/Checkbox"; +import FormGroup from "@mui/material/FormGroup"; +import FormControlLabel from "@mui/material/FormControlLabel"; +import axios from "axios"; //-----------Components-----------// import "./searchBar.css"; +import { BACKEND_URL } from "../constant.js"; export default function SearchBar() { const [keyword, setKeyword] = useState(""); - const navi = useNavigate(); + const [open, setOpen] = useState(false); + const navigate = useNavigate(); + const [categories, setCategories] = useState([]); + const [checkedCategories, setCheckedCategories] = useState({}); + + useEffect(() => { + const fetchData = async () => { + try { + const response = await axios.get(`${BACKEND_URL}/categories`); + const initialCheckedCategories = {}; + response.data.forEach((category) => { + initialCheckedCategories[category.id] = true; + }); + setCheckedCategories(initialCheckedCategories); + setCategories(response.data); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + fetchData(); + }, []); + + const toggleDrawer = (newOpen) => () => { + setOpen(newOpen); + }; + + const handleSubmit = async () => { + try { + const selectedCategories = Object.keys(checkedCategories).filter( + (categoryId) => checkedCategories[categoryId] + ); + navigate(`/search/${keyword}`, { + state: { categories: selectedCategories }, + }); + // Handle response from backend + } catch (error) { + console.error("Error searching", error); + } + }; + + const handleCategoryToggle = (categoryId) => { + setCheckedCategories((prevCheckedCategories) => ({ + ...prevCheckedCategories, + [categoryId]: !prevCheckedCategories[categoryId], + })); + }; + + const handleResetCategory = () => { + const resetCategories = {}; + Object.keys(checkedCategories).forEach((categoryId) => { + resetCategories[categoryId] = false; + }); + setCheckedCategories(resetCategories); + }; + + const categoriesList = categories.map((category) => ( + handleCategoryToggle(category.id)} + /> + } + label={category.name} + onClick={(e) => e.stopPropagation()} // Prevent closing the drawer when clicking on the checkbox + /> + )); + + const FilterList = ( + + + + + + + + + + + {categoriesList} + + + + + } + label="Free" + onClick={(e) => e.stopPropagation()} + /> + } + label="Paid" + onClick={(e) => e.stopPropagation()} + /> + + + + + + ); return (
@@ -20,12 +145,13 @@ export default function SearchBar() { value={keyword} onChange={(e) => setKeyword(e.target.value)} /> - { - setKeyword(""); - navi(`/search/${keyword}`); - }} - /> + + + + {FilterList} +
); } diff --git a/src/pages/userPages/eventDetailPage.js b/src/pages/userPages/eventDetailPage.js index d8dbab0b..ca07eb4d 100644 --- a/src/pages/userPages/eventDetailPage.js +++ b/src/pages/userPages/eventDetailPage.js @@ -4,8 +4,10 @@ import { useParams } from "react-router-dom"; import axios from "axios"; import Button from "@mui/material/Button"; import Dialog from "@mui/material/Dialog"; +import { Box } from "@mui/material"; import DialogTitle from "@mui/material/DialogTitle"; import { useAuth0 } from "@auth0/auth0-react"; +import { Typography, Grid } from "@mui/material"; //-----------Components-----------// import EventBookingPage from "./eventBookingPage"; @@ -52,22 +54,61 @@ export default function EventDetailPage() { //add image const eventInfo = event ? ( -
-

{event.title}

-

{event.description}

-

{event.language.name}

-

Start: {event.start}

-

End: {event.end}

-

${event.price}

-

{event.admin.name}

-

{event.venue.address}

-
+ + + + + {event.title} + + + + + {event.description} + + + + + Price: ${event.price} + + + + + + + + + + Language: {event.language.name} + + + {new Date(event.start).toLocaleString("en-US", { + weekday: "long", + day: "numeric", + month: "long", + hour: "numeric", + minute: "numeric", + })} + - + {new Date(event.end).toLocaleString("en-US", { + hour: "numeric", + minute: "numeric", + })} + + {event.admin.name} + {event.venue.address} + + + ) : null; return (
{eventInfo} - + {showRegistration && ( diff --git a/src/pages/userPages/returnPage.js b/src/pages/userPages/returnPage.js index 0241c707..27cfeebb 100644 --- a/src/pages/userPages/returnPage.js +++ b/src/pages/userPages/returnPage.js @@ -42,6 +42,7 @@ export default function ReturnPage() { if (status === "open") { return ; } + console.log(status); if (status === "complete") { return ( diff --git a/src/pages/userPages/searchPage.js b/src/pages/userPages/searchPage.js index 1ab9b817..07545f80 100644 --- a/src/pages/userPages/searchPage.js +++ b/src/pages/userPages/searchPage.js @@ -1,6 +1,7 @@ //-----------Libraries-----------// import { useState, useEffect } from "react"; import { useOutletContext, useParams } from "react-router-dom"; +import { useLocation } from "react-router-dom"; import axios from "axios"; //-----------Components-----------// @@ -11,17 +12,21 @@ import "./userPages.css"; export default function SearchPage() { const { keyword } = useParams(); + const { state } = useLocation(); + const selectedCategories = state && state.categories ? state.categories : []; const [events, setEvents] = useState([]); useEffect(() => { const fetchData = async () => { try { const response = await axios.get( - `${BACKEND_URL}/events/search/${keyword}` + `${BACKEND_URL}/events/search/${keyword}`, + { + params: { categories: selectedCategories }, + } ); setEvents(response.data); - console.log(events); } catch (error) { console.error("Error fetching data:", error); } @@ -30,6 +35,8 @@ export default function SearchPage() { fetchData(); }, [keyword]); + console.log(events); + const eventPreviews = events && events.length > 0 ? (
From 1baa6e3a8382f6e00ab83214f4014fb50ddbe4f0 Mon Sep 17 00:00:00 2001 From: kendigm Date: Sun, 31 Mar 2024 10:34:59 +0500 Subject: [PATCH 17/69] Authentication Api integration Redux Register Login Logout --- package-lock.json | 186 ++++++++++++++++++++++++++- package.json | 7 +- src/App.js | 2 + src/Store.jsx | 13 ++ src/index.js | 9 +- src/pages/registerPage.js | 44 ++++++- src/pages/signInPage.js | 38 +++++- src/pages/userPages/myProfilePage.js | 46 +++++-- src/slices/AuthSlices.js | 25 ++++ src/slices/apiSlices.js | 11 ++ src/slices/usersApiSlices.js | 30 +++++ 11 files changed, 396 insertions(+), 15 deletions(-) create mode 100644 src/Store.jsx create mode 100644 src/slices/AuthSlices.js create mode 100644 src/slices/apiSlices.js create mode 100644 src/slices/usersApiSlices.js diff --git a/package-lock.json b/package-lock.json index 5f461fcf..b46d72e5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,13 +12,17 @@ "@emotion/styled": "^11.11.0", "@mui/icons-material": "^5.15.14", "@mui/material": "^5.15.14", + "@reduxjs/toolkit": "^2.2.2", "@stripe/react-stripe-js": "^2.6.2", "@stripe/stripe-js": "^3.0.10", "axios": "^1.6.8", "react": "^18.1.0", "react-dom": "^18.1.0", + "react-hot-toast": "^2.4.1", + "react-redux": "^9.1.0", "react-router-dom": "^6.22.3", - "react-scripts": "5.0.1" + "react-scripts": "5.0.1", + "redux": "^5.0.1" } }, "node_modules/@ampproject/remapping": { @@ -3329,6 +3333,38 @@ "url": "https://opencollective.com/popperjs" } }, + "node_modules/@reduxjs/toolkit": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.2.2.tgz", + "integrity": "sha512-454GZrEx3G6QSYwIx9ROaso1HR6sTH8qyZBe3KEsdWVGU3ayV8jYCwdaEJV3vl9V6+pi3GRl+7Xl7AeDna6qwQ==", + "dependencies": { + "immer": "^10.0.3", + "redux": "^5.0.1", + "redux-thunk": "^3.1.0", + "reselect": "^5.0.1" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18", + "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, + "node_modules/@reduxjs/toolkit/node_modules/immer": { + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.0.4.tgz", + "integrity": "sha512-cuBuGK40P/sk5IzWa9QPUaAdvPHjkk1c+xYsd9oZw+YQQEV+10G0P5uMpGctZZKnyQ+ibRO08bD25nWLmYi2pw==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, "node_modules/@remix-run/router": { "version": "1.15.3", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.3.tgz", @@ -3970,6 +4006,11 @@ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz", "integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==" }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", + "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" + }, "node_modules/@types/ws": { "version": "8.5.3", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", @@ -8175,6 +8216,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/goober": { + "version": "2.1.14", + "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.14.tgz", + "integrity": "sha512-4UpC0NdGyAFqLNPnhCT2iHpza2q+RAY3GV85a/mRPdzyPQMsj0KmMMuetdIkzWRbJ+Hgau1EZztq8ImmiMGhsg==", + "peerDependencies": { + "csstype": "^3.0.10" + } + }, "node_modules/graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", @@ -13687,11 +13736,52 @@ "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" }, + "node_modules/react-hot-toast": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.4.1.tgz", + "integrity": "sha512-j8z+cQbWIM5LY37pR6uZR6D4LfseplqnuAO4co4u8917hBUvXlEqyP1ZzqVLcqoyUesZZv/ImreoCeHVDpE5pQ==", + "dependencies": { + "goober": "^2.1.10" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + } + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, + "node_modules/react-redux": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.1.0.tgz", + "integrity": "sha512-6qoDzIO+gbrza8h3hjMA9aq4nwVFCKFtY2iLxCtVT38Swyy2C/dJCGBXHeHLtx6qlg/8qzc2MrhOeduf5K32wQ==", + "dependencies": { + "@types/use-sync-external-store": "^0.0.3", + "use-sync-external-store": "^1.0.0" + }, + "peerDependencies": { + "@types/react": "^18.2.25", + "react": "^18.0", + "react-native": ">=0.69", + "redux": "^5.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react-native": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, "node_modules/react-refresh": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", @@ -13863,6 +13953,19 @@ "node": "*" } }, + "node_modules/redux": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==" + }, + "node_modules/redux-thunk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", + "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", + "peerDependencies": { + "redux": "^5.0.0" + } + }, "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -14005,6 +14108,11 @@ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" }, + "node_modules/reselect": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.0.tgz", + "integrity": "sha512-aw7jcGLDpSgNDyWBQLv2cedml85qd95/iszJjN988zX1t7AVRJi19d9kto5+W7oCfQ94gyo40dVbT6g2k4/kXg==" + }, "node_modules/resolve": { "version": "1.22.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", @@ -15539,6 +15647,14 @@ "punycode": "^2.1.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -18729,6 +18845,24 @@ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==" }, + "@reduxjs/toolkit": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.2.2.tgz", + "integrity": "sha512-454GZrEx3G6QSYwIx9ROaso1HR6sTH8qyZBe3KEsdWVGU3ayV8jYCwdaEJV3vl9V6+pi3GRl+7Xl7AeDna6qwQ==", + "requires": { + "immer": "^10.0.3", + "redux": "^5.0.1", + "redux-thunk": "^3.1.0", + "reselect": "^5.0.1" + }, + "dependencies": { + "immer": { + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.0.4.tgz", + "integrity": "sha512-cuBuGK40P/sk5IzWa9QPUaAdvPHjkk1c+xYsd9oZw+YQQEV+10G0P5uMpGctZZKnyQ+ibRO08bD25nWLmYi2pw==" + } + } + }, "@remix-run/router": { "version": "1.15.3", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.3.tgz", @@ -19229,6 +19363,11 @@ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz", "integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==" }, + "@types/use-sync-external-store": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", + "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" + }, "@types/ws": { "version": "8.5.3", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", @@ -22285,6 +22424,12 @@ "slash": "^3.0.0" } }, + "goober": { + "version": "2.1.14", + "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.14.tgz", + "integrity": "sha512-4UpC0NdGyAFqLNPnhCT2iHpza2q+RAY3GV85a/mRPdzyPQMsj0KmMMuetdIkzWRbJ+Hgau1EZztq8ImmiMGhsg==", + "requires": {} + }, "graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", @@ -26140,11 +26285,28 @@ "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" }, + "react-hot-toast": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.4.1.tgz", + "integrity": "sha512-j8z+cQbWIM5LY37pR6uZR6D4LfseplqnuAO4co4u8917hBUvXlEqyP1ZzqVLcqoyUesZZv/ImreoCeHVDpE5pQ==", + "requires": { + "goober": "^2.1.10" + } + }, "react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, + "react-redux": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.1.0.tgz", + "integrity": "sha512-6qoDzIO+gbrza8h3hjMA9aq4nwVFCKFtY2iLxCtVT38Swyy2C/dJCGBXHeHLtx6qlg/8qzc2MrhOeduf5K32wQ==", + "requires": { + "@types/use-sync-external-store": "^0.0.3", + "use-sync-external-store": "^1.0.0" + } + }, "react-refresh": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", @@ -26269,6 +26431,17 @@ } } }, + "redux": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==" + }, + "redux-thunk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", + "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", + "requires": {} + }, "regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -26380,6 +26553,11 @@ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" }, + "reselect": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.0.tgz", + "integrity": "sha512-aw7jcGLDpSgNDyWBQLv2cedml85qd95/iszJjN988zX1t7AVRJi19d9kto5+W7oCfQ94gyo40dVbT6g2k4/kXg==" + }, "resolve": { "version": "1.22.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", @@ -27513,6 +27691,12 @@ "punycode": "^2.1.0" } }, + "use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "requires": {} + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/package.json b/package.json index 2c5bdd45..a47b3cff 100644 --- a/package.json +++ b/package.json @@ -2,18 +2,23 @@ "name": "project-3-frontend-bootcamp", "version": "0.1.0", "private": true, + "proxy": "http://localhost:5000", "dependencies": { "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.0", "@mui/icons-material": "^5.15.14", "@mui/material": "^5.15.14", + "@reduxjs/toolkit": "^2.2.2", "@stripe/react-stripe-js": "^2.6.2", "@stripe/stripe-js": "^3.0.10", "axios": "^1.6.8", "react": "^18.1.0", "react-dom": "^18.1.0", + "react-hot-toast": "^2.4.1", + "react-redux": "^9.1.0", "react-router-dom": "^6.22.3", - "react-scripts": "5.0.1" + "react-scripts": "5.0.1", + "redux": "^5.0.1" }, "scripts": { "start": "react-scripts start", diff --git a/src/App.js b/src/App.js index 2eb6a8d1..e16ab3a5 100644 --- a/src/App.js +++ b/src/App.js @@ -30,6 +30,7 @@ import AdminProfilePage from "./pages/adminPages/adminProfilePage.js"; import AdminEventPage from "./pages/adminPages/adminEventPage.js"; import AdminEventAttendancePage from "./pages/adminPages/adminEventAttendancePage.js"; import AdminAnalyticsPage from "./pages/adminPages/adminAnalyticsPage.js"; +import { Toaster } from "react-hot-toast"; const AdminRoutes = () => ( @@ -61,6 +62,7 @@ const App = () => { } /> } /> + ); }; diff --git a/src/Store.jsx b/src/Store.jsx new file mode 100644 index 00000000..1d5d7206 --- /dev/null +++ b/src/Store.jsx @@ -0,0 +1,13 @@ +import { configureStore } from "@reduxjs/toolkit"; +import { apiSlice } from "./slices/apiSlices"; + +import authReducer from "./slices/AuthSlices"; +const store = configureStore({ + reducer: { + auth: authReducer, + [apiSlice.reducerPath]: apiSlice.reducer, + }, + middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(apiSlice.middleware), + devTools: true, +}); +export default store; diff --git a/src/index.js b/src/index.js index 907b6d82..dd8aa367 100644 --- a/src/index.js +++ b/src/index.js @@ -1,7 +1,8 @@ //-----------Libraries-----------// import React from "react"; import ReactDOM from "react-dom/client"; - +import store from "./Store.jsx"; +import { Provider } from "react-redux"; //-----------Components-----------// import App from "./App"; @@ -9,4 +10,8 @@ import App from "./App"; import "./index.css"; const root = ReactDOM.createRoot(document.getElementById("root")); -root.render(); +root.render( + + + +); diff --git a/src/pages/registerPage.js b/src/pages/registerPage.js index 67bc1526..43413ca1 100644 --- a/src/pages/registerPage.js +++ b/src/pages/registerPage.js @@ -3,14 +3,51 @@ import Paper from "@mui/material/Paper"; import Typography from "@mui/material/Typography"; import TextField from "@mui/material/TextField"; import Button from "@mui/material/Button"; -import { Link } from "react-router-dom"; +import { Link, useNavigate } from "react-router-dom"; import MailOutlinedIcon from "@mui/icons-material/MailOutlined"; import InputAdornment from "@mui/material/InputAdornment"; import LockOutlinedIcon from "@mui/icons-material/LockOutlined"; import ArrowForwardIcon from "@mui/icons-material/ArrowForward"; import ArrowBackIcon from "@mui/icons-material/ArrowBack"; import PersonOutlineOutlinedIcon from "@mui/icons-material/PersonOutlineOutlined"; +import { useRegisterMutation } from "../slices/usersApiSlices"; +import { useDispatch, useSelector } from "react-redux"; +import { useEffect, useState } from "react"; +import { setCredentials } from "../slices/AuthSlices"; + +import toast from "react-hot-toast"; + export default function RegisterPage() { + const [name, setName] = useState(); + const [email, setEmail] = useState(); + const [password, setPassword] = useState(); + const [confirmPassword, setConfirmPassword] = useState(); + const dispatch = useDispatch(); + const navigate = useNavigate(); + const { userInfo } = useSelector((state) => state.auth); + const [register, { isLoading }] = useRegisterMutation(); + + useEffect(() => { + if (userInfo) { + navigate("/profile"); + } + }, [navigate, userInfo]); + async function handleRegister(e) { + e.preventDefault(); + if (password !== confirmPassword) + return toast.error(`Password not matched 😶`); + try { + const res = await register({ email, password, name }).unwrap(); + setName(""); + setEmail(""); + setPassword(""); + setConfirmPassword(""); + toast.success(res.message); + navigate("/signin"); + } catch (err) { + console.log(err?.data?.message || err.error); + } + } return (
@@ -46,6 +83,7 @@ export default function RegisterPage() { variant="outlined" type="text" placeholder="Full name" + onChange={(e) => setName(e.target.value)} fullWidth style={{ marginBottom: "1.5rem" }} InputProps={{ @@ -61,6 +99,7 @@ export default function RegisterPage() { variant="outlined" type="email" placeholder="abc@email.com" + onChange={(e) => setEmail(e.target.value)} fullWidth style={{ marginBottom: "1.5rem" }} InputProps={{ @@ -77,6 +116,7 @@ export default function RegisterPage() { type="email" placeholder="Your password" fullWidth + onChange={(e) => setPassword(e.target.value)} style={{ marginBottom: "1.5rem" }} InputProps={{ startAdornment: ( @@ -91,6 +131,7 @@ export default function RegisterPage() { variant="outlined" type="password" placeholder="Confirm password" + onChange={(e) => setConfirmPassword(e.target.value)} fullWidth style={{ marginBottom: ".5rem" }} InputProps={{ @@ -104,6 +145,7 @@ export default function RegisterPage() {
); -} +}; + +export default MyProfilePage; diff --git a/src/slices/AuthSlices.js b/src/slices/AuthSlices.js new file mode 100644 index 00000000..18e3d2bc --- /dev/null +++ b/src/slices/AuthSlices.js @@ -0,0 +1,25 @@ +import { createSlice } from "@reduxjs/toolkit"; + +const initialState = { + userInfo: localStorage.getItem("userInfo") + ? JSON.parse(localStorage.getItem("userInfo")) + : null, +}; + +const authSlice = createSlice({ + name: "auth", + initialState, + reducers: { + setCredentials: (state, action) => { + state.userInfo = action.payload; + localStorage.setItem("userInfo", JSON.stringify(action.payload)); + }, + logoutt: (state, action) => { + state.userInfo = null; + localStorage.removeItem("userInfo"); + }, + }, +}); + +export const { setCredentials, logoutt } = authSlice.actions; +export default authSlice.reducer; diff --git a/src/slices/apiSlices.js b/src/slices/apiSlices.js new file mode 100644 index 00000000..cb84b46f --- /dev/null +++ b/src/slices/apiSlices.js @@ -0,0 +1,11 @@ +import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; + +const baseQuery = fetchBaseQuery({ + // baseUrl: "http://localhost:5000", + credentials: "include", +}); +export const apiSlice = createApi({ + baseQuery, + tagTypes: ["User"], + endpoints: (builder) => ({}), +}); diff --git a/src/slices/usersApiSlices.js b/src/slices/usersApiSlices.js new file mode 100644 index 00000000..23c9e03d --- /dev/null +++ b/src/slices/usersApiSlices.js @@ -0,0 +1,30 @@ +import { apiSlice } from "./apiSlices"; + +const USERS_URL = "/api/auth"; +export const userApiSlice = apiSlice.injectEndpoints({ + endpoints: (builder) => ({ + login: builder.mutation({ + query: (data) => ({ + url: `${USERS_URL}/signin`, + method: "POST", + body: data, + }), + }), + register: builder.mutation({ + query: (data) => ({ + url: `${USERS_URL}/signup`, + method: "POST", + body: data, + }), + }), + logout: builder.mutation({ + query: () => ({ + url: `${USERS_URL}/logout`, + method: "POST", + }), + }), + }), +}); + +export const { useLoginMutation, useRegisterMutation, useLogoutMutation } = + userApiSlice; From bb774f206aee6906c661010c22c01015014eca57 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Tue, 2 Apr 2024 19:33:03 +0800 Subject: [PATCH 18/69] updated event booking page layout --- src/pages/userPages/eventBookingPage.js | 55 ++++++++++++++----------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/src/pages/userPages/eventBookingPage.js b/src/pages/userPages/eventBookingPage.js index 4d08bcfd..952cc74c 100644 --- a/src/pages/userPages/eventBookingPage.js +++ b/src/pages/userPages/eventBookingPage.js @@ -8,6 +8,7 @@ import FormControl from "@mui/material/FormControl"; import Button from "@mui/material/Button"; import Select from "@mui/material/Select"; import axios from "axios"; +import { Box } from "@mui/material"; //-----------Components-----------// import { BACKEND_URL } from "../../constant.js"; @@ -41,32 +42,36 @@ export default function EventBookingPage({ eventId, isFree }) { return (
- - Tickets - + {arrayTickets.map((quantity) => ( + + {quantity} + + ))} + + Quantity + + + + + Checkout + +
); } From 11b20bf07809ac99459060192595fd27dbfb210a Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Tue, 2 Apr 2024 22:47:21 +0800 Subject: [PATCH 19/69] added upcoming events --- src/components/BookingPreview.js | 66 ++++++++++++++++ src/components/EventPreview.js | 4 +- src/pages/userPages/myBookingPage.js | 109 +++++++++++++++++++++++++-- 3 files changed, 170 insertions(+), 9 deletions(-) create mode 100644 src/components/BookingPreview.js diff --git a/src/components/BookingPreview.js b/src/components/BookingPreview.js new file mode 100644 index 00000000..88916188 --- /dev/null +++ b/src/components/BookingPreview.js @@ -0,0 +1,66 @@ +//-----------Libraries-----------// +import Card from "@mui/material/Card"; +import CardContent from "@mui/material/CardContent"; +import CardActions from "@mui/material/CardActions"; +import Button from "@mui/material/Button"; +import Typography from "@mui/material/Typography"; +import { Link } from "react-router-dom"; + +const EventPreview = (props) => { + const formatDate = (string) => { + const date = new Date(string); + const options = { + day: "numeric", + month: "long", + hour: "2-digit", + minute: "2-digit", + }; + return date.toLocaleDateString("en-US", options); + }; + + //add logic to see whether start and end date is the same. + const formatHour = (string) => { + const date = new Date(string); + const options = { + hour: "2-digit", + minute: "2-digit", + }; + return date.toLocaleTimeString("en-US", options); + }; + + return ( + + {/* */} + + <> + + + {props.data.event.title} + + + + {formatDate(props.data.event.start)}- + {formatHour(props.data.event.end)} + + + BookingId :${props.data.id} + + + Quantity :{props.data.quantity_bought} + + + + + + ); +}; + +export default EventPreview; diff --git a/src/components/EventPreview.js b/src/components/EventPreview.js index 3fe93b24..2023f2b5 100644 --- a/src/components/EventPreview.js +++ b/src/components/EventPreview.js @@ -45,9 +45,9 @@ const EventPreview = (props) => { {props.data.title} - + {/* {props.data.admin.name} - + */} {formatDate(props.data.start)}-{formatHour(props.data.end)} diff --git a/src/pages/userPages/myBookingPage.js b/src/pages/userPages/myBookingPage.js index 217b9f2f..47b4925a 100644 --- a/src/pages/userPages/myBookingPage.js +++ b/src/pages/userPages/myBookingPage.js @@ -1,18 +1,113 @@ //-----------Libraries-----------// import { useState, useEffect } from "react"; -import { Link } from "react-router-dom"; -import InputLabel from "@mui/material/InputLabel"; -import MenuItem from "@mui/material/MenuItem"; -import FormHelperText from "@mui/material/FormHelperText"; -import FormControl from "@mui/material/FormControl"; -import Select from "@mui/material/Select"; +import Tabs from "@mui/material/Tabs"; +import Tab from "@mui/material/Tab"; +import Typography from "@mui/material/Typography"; +import Box from "@mui/material/Box"; +import PropTypes from "prop-types"; +import axios from "axios"; //-----------Components-----------// +import { BACKEND_URL } from "../../constant.js"; +import BookingPreview from "../../components/BookingPreview.js"; + +function CustomTabPanel(props) { + const { children, value, index, ...other } = props; + + return ( + + ); +} + +CustomTabPanel.propTypes = { + children: PropTypes.node, + index: PropTypes.number.isRequired, + value: PropTypes.number.isRequired, +}; export default function MyBookingPage() { + const [value, setValue] = useState(0); + const [current, setCurrent] = useState([]); + const [past, setPast] = useState([]); + + useEffect(() => { + const fetchData = async () => { + try { + const response = await axios.get(`${BACKEND_URL}/bookings/current`, { + params: { userId: 1 }, + }); + console.log(response.data); + const output = response.data; + setCurrent(output); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + fetchData(); + }, []); + + // useEffect(() => { + // const fetchData = async () => { + // try { + // const response = await axios.get(`${BACKEND_URL}/bookings/past`, { + // params: { userId: 1 }, + // }); + // const output = response.data; + // setPast(output.event); + // } catch (error) { + // console.error("Error fetching data:", error); + // } + // }; + // fetchData(); + // }, []); + + const handleChange = (event, newValue) => { + setValue(newValue); + }; + + const currentPreviews = current.map((booking) => ( + + )); + + const pastPreviews = past.map((booking) => ( + + )); + return (
-

My booking page

+ + + + + + + + + {currentPreviews} + + + {pastPreviews} + +
); } From 78a33f89fb678c27d1b503560434fe74833460e3 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Tue, 2 Apr 2024 22:51:01 +0800 Subject: [PATCH 20/69] updated db --- src/constant.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/constant.js b/src/constant.js index 1cc46964..3c6be070 100644 --- a/src/constant.js +++ b/src/constant.js @@ -1 +1 @@ -export const BACKEND_URL = "http://localhost:3000"; +export const BACKEND_URL = "http://localhost:5000"; From 1a2fcdf16d4665ed46422c9990b4baa2e2a6e969 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Tue, 2 Apr 2024 23:13:39 +0800 Subject: [PATCH 21/69] updated user migration, model and seeders file --- src/components/BookingPreview.js | 40 ++++++++++++------------- src/pages/userPages/myBookingPage.js | 44 +++++++++++++++------------- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/src/components/BookingPreview.js b/src/components/BookingPreview.js index 88916188..e34592ef 100644 --- a/src/components/BookingPreview.js +++ b/src/components/BookingPreview.js @@ -36,28 +36,26 @@ const EventPreview = (props) => { title="green iguana" /> */} - <> - - - {props.data.event.title} - + + + {props.data.event.title} + - - {formatDate(props.data.event.start)}- - {formatHour(props.data.event.end)} - - - BookingId :${props.data.id} - - - Quantity :{props.data.quantity_bought} - - - + + {formatDate(props.data.event.start)}- + {formatHour(props.data.event.end)} + + + BookingId :${props.data.id} + + + Quantity :{props.data.quantity_bought} + + ); diff --git a/src/pages/userPages/myBookingPage.js b/src/pages/userPages/myBookingPage.js index 47b4925a..468fa009 100644 --- a/src/pages/userPages/myBookingPage.js +++ b/src/pages/userPages/myBookingPage.js @@ -46,7 +46,7 @@ export default function MyBookingPage() { const fetchData = async () => { try { const response = await axios.get(`${BACKEND_URL}/bookings/current`, { - params: { userId: 1 }, + params: { userId: "0a750c6d-758e-4113-806d-4061f49edd13" }, }); console.log(response.data); const output = response.data; @@ -58,32 +58,34 @@ export default function MyBookingPage() { fetchData(); }, []); - // useEffect(() => { - // const fetchData = async () => { - // try { - // const response = await axios.get(`${BACKEND_URL}/bookings/past`, { - // params: { userId: 1 }, - // }); - // const output = response.data; - // setPast(output.event); - // } catch (error) { - // console.error("Error fetching data:", error); - // } - // }; - // fetchData(); - // }, []); + useEffect(() => { + const fetchData = async () => { + try { + const response = await axios.get(`${BACKEND_URL}/bookings/past`, { + params: { userId: "0a750c6d-758e-4113-806d-4061f49edd13" }, + }); + const output = response.data; + setPast(output.event); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + fetchData(); + }, []); const handleChange = (event, newValue) => { setValue(newValue); }; - const currentPreviews = current.map((booking) => ( - - )); + const currentPreviews = current + ? current.map((booking) => ( + + )) + : null; - const pastPreviews = past.map((booking) => ( - - )); + const pastPreviews = past + ? past.map((booking) => ) + : null; return (
From 1d7b5cd46767a3adf9b99e31c0eda3da1578a895 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Sat, 6 Apr 2024 00:57:28 +0800 Subject: [PATCH 22/69] updated search and added map --- package-lock.json | 33 +++++++++++ package.json | 1 + public/shoes.jpg | Bin 0 -> 49053 bytes public/shoes.jpg:Zone.Identifier | 0 public/tennis.jpg | Bin 0 -> 358703 bytes src/components/EventPreview.js | 74 +++++++++++++++++------ src/components/EventPreviewList.js | 2 +- src/components/navbar.js | 50 +++++++++------- src/components/searchBar.js | 79 +++++++++++++++++++++---- src/pages/userPages/eventDetailPage.js | 44 +++++++++++++- src/pages/userPages/homePage.js | 29 ++++++--- src/pages/userPages/searchPage.js | 40 +++++++++++-- src/theme.js | 20 +++++++ 13 files changed, 307 insertions(+), 65 deletions(-) create mode 100644 public/shoes.jpg create mode 100644 public/shoes.jpg:Zone.Identifier create mode 100644 public/tennis.jpg create mode 100644 src/theme.js diff --git a/package-lock.json b/package-lock.json index d94f8d6c..4ea88abb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "@reduxjs/toolkit": "^2.2.3", "@stripe/react-stripe-js": "^2.6.2", "@stripe/stripe-js": "^3.0.10", + "@vis.gl/react-google-maps": "^0.8.3", "axios": "^1.6.8", "react": "^18.1.0", "react-dom": "^18.1.0", @@ -3861,6 +3862,11 @@ "@types/range-parser": "*" } }, + "node_modules/@types/google.maps": { + "version": "3.55.6", + "resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.55.6.tgz", + "integrity": "sha512-RDtveRsejIi7KRnahz+PE1+Uo+6axr98Susjn/7DxNPPej/T0sMMJfnwm3NcQgvVDWvixWCMOn2Sfukq5UVF2g==" + }, "node_modules/@types/graceful-fs": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", @@ -4264,6 +4270,19 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@vis.gl/react-google-maps": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@vis.gl/react-google-maps/-/react-google-maps-0.8.3.tgz", + "integrity": "sha512-iubZIH9MJSkJA9NCMwKkMlHb/iNSeXzVRE7fPVhkKJPId6TBvQcpKA98tirUXi2AfEkYL+IVcE3doL6WdeQ2QA==", + "dependencies": { + "@types/google.maps": "^3.54.10", + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, "node_modules/@webassemblyjs/ast": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", @@ -19231,6 +19250,11 @@ "@types/range-parser": "*" } }, + "@types/google.maps": { + "version": "3.55.6", + "resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.55.6.tgz", + "integrity": "sha512-RDtveRsejIi7KRnahz+PE1+Uo+6axr98Susjn/7DxNPPej/T0sMMJfnwm3NcQgvVDWvixWCMOn2Sfukq5UVF2g==" + }, "@types/graceful-fs": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", @@ -19531,6 +19555,15 @@ "eslint-visitor-keys": "^3.0.0" } }, + "@vis.gl/react-google-maps": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@vis.gl/react-google-maps/-/react-google-maps-0.8.3.tgz", + "integrity": "sha512-iubZIH9MJSkJA9NCMwKkMlHb/iNSeXzVRE7fPVhkKJPId6TBvQcpKA98tirUXi2AfEkYL+IVcE3doL6WdeQ2QA==", + "requires": { + "@types/google.maps": "^3.54.10", + "fast-deep-equal": "^3.1.3" + } + }, "@webassemblyjs/ast": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", diff --git a/package.json b/package.json index 17e385d6..a3fd3a27 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "@reduxjs/toolkit": "^2.2.3", "@stripe/react-stripe-js": "^2.6.2", "@stripe/stripe-js": "^3.0.10", + "@vis.gl/react-google-maps": "^0.8.3", "axios": "^1.6.8", "react": "^18.1.0", "react-dom": "^18.1.0", diff --git a/public/shoes.jpg b/public/shoes.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3645f9b9643605bc599ed2f840677256a2da98fc GIT binary patch literal 49053 zcmbrlXH=7E)HNJMMY@3WHj4BnO^ShxGJ=4BgeEnEGzro{f`nwGcSfr8K?oRHl-?r* zh;*eYAR!4wkdlC4gb=>WQ{HE-@7KHD=T5TnBUx8+u5!*kd++<~^VtgEikY#gG2q!Wn|^#6%@6!Z|Ugj=^OoV&)DR?shN$f zoxQ^&M<)+YFK?eGzR=LH@MjUQ$mg+f@d=4Z$thXcIk|cHuL=rZS5%^^s^6e%8k?G1 zTHD$?I{R@0gG2Za!y{AEGqZE^pT8^+N#xbF^^I?vTh#r7ABRUjX}^yDjq4nM<^N3C ze+Ksdi;Fo4=gwcaz;c20-?+}5k6^x7crRSMrhbXT&WEg=61#TII;?IGAxZ`-j{TrQ&Mx6BA2BW~f>+v%2&zXoP- zUXPrb{>f#}s#Xr$H0=-nZV7D4RWJp4+{1eRQ=xZnCL%M5&-6wX^J!@+mt|^Ty6d+$ z)tdT8vuPMe*S{^I_Ic~ir)B_oz(42zV!zblYrqfPIM4xY6DjjYIj2o$fB;t=^3M!} z4ovFkJ%tr7+#(fcs6r7M3KXU5Qhj320G`n%?|ZqjS5Rkweglxn9Eix@MG0GIX6Rc9 zH}{IqtBBzpo_8apGgR!i`ug87WRhR~^`bV9oUpoWD=6 zB}kyO7+(I+TDW%b$K&`zl?dW|fpY5lgP_6bT|@K$&ERH1DTh`?;4_gtQClUGywU9M zx?;vr&V{y-7^+VF89>evpP+{e)FwXNOHkLKy%Sd{uo+r$ZrN?@-a4qbI@JO+)XdIv zd1u||)sB5apvfmDnzm7qbp9eU>Wc)23|F5O!j3Pc@pxoihSh((A(d)mLJO=h&iMVj zh^l8hPAT&DMBA1Es({+h4Dq8mr_qar?o~yMZS|YD<{s~_Ej?e;P`FYF5?>z20JPoG z|Ba8hT%k>ISilq}-wxl`o4?u=rB#>8b>hPKoL!!2!JL#o>A`s?7j8VS#$&#On!M9E z_dfa_L+)!_YJ{WU!d;>DM@#hPGeB!oVkOM^X4hhwSl$pwPx+7fpZttBLGY&=B!tQ6 zEciovVckw=GqUNQqBav5pNi-QzYsFWK3gENcd;MR#Jb&eVt9A?k^bZmHnUfT)`8>< z8Cv$tTNa@itdv|IS>K&aJWeeWa&j`;5#{K(&Sws$x;Q2wJ4PCpF8EVDf)55w{cEaY zQ5R13M_$kSK3Wh7jCTw#)k&u1CwVr^if3P|$eAuF>jPQ_r`M2BbSlnm^pB#sCdPnN zv((TUKl^uRd{mO4Y*R2y?54WKPWL`(Clo$;y zc;??M5HyEX6cEvok{)SifS0||spv~R+mf!rYwdmpq%CmB;7mr>NN4`*Pfp|pso^rZ zJDnq&s5q$2IiC!*Be{&5`iaiGdEArd9ADQ^Wc#+oHgI(EMs8lz8Gt6sL+5vsX-naW zkz(!khc8}xH}w=r)I0r$4he^!zaD8H3~M5rq{_`y6?pKwYVS1XJJd~Eh;-*JVL5`P zQqqESpZ-x~YLnPDrr4u@$9~8z`&m~+SIgns3addizG9SuPh>B<;ZJSHGl0*k@cl|M z?4VoKCf+*6S9jn1rFI1WAf4k3aFLhx>*NVz%I(JKOXTCsm^=tO(3c3h;6lGcEgJ+a zDp^pi68z~p#M@CAmPL+qwG~3F{~p~Uq5;~9z0$2+OM8qTGL)hG)$_K?@$fc>w&`^# zy;syZnR#@~NaN2`a)ydj;kb;1)j~)ZMx7p$2-^e&i)=(*vVLJUvZo22<6Ke zK+xyAdY{7p(0~&gzx8RL=5W&%!`{5*BaGUT_2RdpJlY>CNNP{iSR)=W@T7Hw>?RVz9wwC=?_&9GD7u z!8htUXR+Kyigp_GY|eLznSMB1k71bb+6ZI}DhIfy)TR!|x8ut4uA=XCwSPigD7VmQ z$j_eD)AozjnWN|eI~`T;1O~T_?;6e#PG64_WQZzOBu7wy}96X=R{?< zo{}7%Y7~xw3(`PGT~R%XWHKRHYd+Iv9&QxHwOd39#pwtZrVr+x0n!fB#jK{gLW&!D zBh&IE)7DJb64zkcwvUTk=5m5&^s-YiV4VO9Gp&D$vesAAzUz!@Fs_U!_&B02dxUa6 zFC^0QYO_!&Ve3TTr1~l}cvRj}Rcmvwzsj)LRenUv1N{2e8Q@6gG(iRHg-MobRvTb$ zTQMj@r<+zws&$4WwmzRs0y>kD8IpA6se1qQ%zN!~aGx6JLT?4>3?K~4ZJ=9G`JJ3w z+o+f7{VLt!9sl{;;afKd_jcHCT_D%dQnzs29j#|+&J{o9Qamf8V1{yPLp%8{ggk8P z&m5+G9}r#g`ir=9_3hs{bCtf%g8C;@xT(m5Q0oy*jIg`MWfRu;f7Xo7nN_-)X>HA< zLig8CFJazvIyd(?{;Kc|xLTMtZJ}`Q+w?5Ru1WM8{YU52=C9h@ng>2d@ibj*6Csu% z4Szth3YSY{aKRG$B=u-W>QCaEj#-{WLm|2VZI*=P+`=}u4V?l0>Qu=gcu@i~Rl+1L z(>8`AMH<_zIAQIyXJnUY6)h>z(KlO$@@D`|!(!weH%@A-VlA1KWmWhoYZ{QXc(qsI zPl}_rkXj!RXw4k7@#z`h^v-bmP>N=cO#YlBddwpW>E^YR&o3##dc(w!oO}>44l0 z!vLC09o_M?ZjlVZBV!1hbcqH!=(MVyyDXThMk-4`WR^Q|1j`IU!KfN`u(E;6WQQS% z^XV;EUK-Njw2;Ax7%OAx4kkHw1+sk8_sOJRqh8;`S&(H~QhY&4-O{J|r8lUU%P=pK zWZEO*4`#!SQBNxw_HrezP{+LR0!DeYSc1y~3zM%*x&7=8Hoy=%ZEgMnyz|D7na8?iNJVFWD<&tV6|~G1o}qdj zd#Yt_En^mRl`aXlph}s2LfnFRtkjoerX$!9;|qcnlx!kb4&v5K-601)!Q%0W#dM35 z+#lN{wa>qXx(%#UTzK&=aznzLuibcODsbKAIi!7MRgXNHM4!mXFwEiR0CA(3Se*k) zB^~+3kr8^BLjed^T-@7^aLzEwtl;f|5yOIBiS?|k@wWwgJoA{-YLUls@fjLvGDW0s z-S=RpW>vD4KCz>|=B%*+iVkJi-7^5s!2wCIi!^R@R7{;5JOi-#NvfRY_sSq98B(;x zlRGpH;(Rh(uL>6EK*8enULe`&Hk9f2_RsUuWfD;CXu1fst^ZW#2uATqDZ>>q52$wC zcS$i?btTMiKppzr;V9`e|C`T`Xey|WTL%{unA9!1N!rJ71s5Y(Eyw<=zHRn%2QxNq@Mv2{YaD_zO(V729gS}`2J$MzE>`R+}^KT zex4fuy1%3xDyt|q9rvS>$9%zPtDllXt^5KnM&$nt))II$bYUR zWABpaP#@Kj&?tAGh~VmpJEcQWMX>d}iO2sa84X?R@h9n z-reA6vV6-8`n1Ws)P-KTEvLg#n$>^{tFV$%SK3 zD^k1)zQ%cDg~+>n{cAH7#cMga?0mJNkH%EAp;{>LR>^bqg<=^k^h{OHtlo4O`RZ!s z*KR#B(A&q!QPSW3QQ99*CR#Z}te0CJO*PdfVpO&!ZU)rrH~w6@W^J2O7;9*BE(U{cQZFF?TD!%~uijZDYZ1`E4&ZS2Ulx zLCkp*V#<^H9&f*kMBL^v5z8lmTY7qV_}O!6w7qkeWzq#5k^H;gZ36f+FX z$KUxV^zrG`4uUJ%Q8Hwn$l>69YUdIfRs3eCfma@0mlwYWXlO5lX6ky48+ zLLcN0as+9s1dt9rryjqW3|DR(D?`55HM~ZeP#T7r@C@>eLcRBgrg7v@WeMO&njbO9 z?p^aY%Uh_VkcPL1*Mvl;vI4f$@+NE9`so+TRu0mMO>0rGxJ z*DcGBuv&cU*5kK@q~&$(*3gh4ufj{#BAs?Je-|J^n_VPGpqWt4P#mQh?bUs|m?{BN z#%tQG#eaB5Tk5)rv#Dy_N_n&ZE4~O*45)n4HY^o5E?co~-e<^W_hu@QH&{8kRU_d% zcNMEjvE2hZeeG|yIeQ#7xr)OF?MhCj_^-NFQpmnOWShmd(5+f@MJ4wGqRgw!QJFBmZnDgX& zekpNkcl6QyTz4zHb2(vfPh`hoA|PcGB$KjVQ~9Z>p+=#$LC8KnyixpAmMYyi9V#6+~j) z@gQ4B{V{W>Vs*a^SH?+BBxawfQzeSMAZASAW36%cFY#}m zVi5b*bKf@ziDjY;ExPjCnM0lg0)O~qqUh{Ia`2n4unOXO36WVaX=Lj{=kMQCvu$aq z6~5N+yE7gyD>UAAQfBXrG&aYn-j>%XL-f6;^f5{AU3F5rxJn~g76w@Y{fwM;10B+6C=7w zGnFtv;IlC7p|TD-A!GmfsD*rj12ABNz_q;TiKaAJmPL{uS!t9j*PFIoVAi0-53Yyqm$-D+Ep6P|yOsO; zCAHW(saCPTo~u7kiYIP(e{-sj=xfuz@@7;Z@lk=ku0C%(yXx$(=nwZ6O+t_PFgb>g zm<$O|3NmnSL34o6%2PR8S}f^4YEgVyoRU}1mIb=0zhP}x)>NLDk|)jYR4N+hHi2@KuU6X~0#4^; zeocMW=!427QgZ#~2D~+Mff(gJ4^8+~rP|K5e6N}4Ub!y|^R?C?pI&Eo)q?dSDA+Hf zD-Maw<_{ECDoXPx-_p-d!qlZRy2ybNe$%EAq_SiPFWn+iwS_#H#88=$%ZjQu8gNsm z%6w&DqE*HR`&vzRek}T4OpmX$X3Xb!g=xSqa&mEKo9Upz!)7hMe)cWKy$UmV4OY%K zI;FSOr544eblrVSi_&lie#dMSO^tZ3 zMYE>X66N}_sb>IjpeA$YU#ESkquWuW5*X53hSD?%>PCNA<77XQyDhC*UVDv#=?_dO z<)fWaobjD|FS=!JU?~}!ZfZ2tty&URygQK0;g`C{<0q=YY^}9tYsowUIDwK?82uKH z+VPxh2LHvxf&QGOpxNp>wPxJ>SwZlr;)PBqV~R^{2b$A;VTIF6_3A{(n84GC1Su{X zk&JPTlwWmgKnpd0_Lg_r@{c`CXX4619tml_;56c{eABK}f>dMXb_sRSuAS1hjbVmx z@wA@7Nry~n?X?o%S80RF2YwSqZ$V`R&h~>ud5+;+K>z%G;;e6qUPi4V7u3j7Pq|IDK;l zaL3XV<`Wp~a45wp7Os6_fSAWp^5}}RWFm;&4{>o;jkzr+ldQk@UZXUiUq4Z4pv%xu zb+GTmR&2FN6f!WlVc7{DMOn&TaQ=D*@TOV%`m|1)OuGZ0_mgkx)(QIM&En=TarJjg zWz)Y~r<*mSF6zHs4=n`eYjt>BCDjYxy9Ezpq_;m1jL2EHP|yJ~lnmJU9pOMB8Ii1>lbSON=Bk3v3*qWU*rPjq3ieZ7Jd z0`3gJPS>UVByu^gG+^G~i0P7x_nY5Q!j{!y@cq~;x12sJSM3qol7T)|58@`dt3$;i zcTPZ@)I_%RS3p%U`Eg39ZP1S=L-A%Q@vsy9;6x>q-JK4lsHOVv&k*N^7~-_leD8uh z{}NB#Z8N-w`lBUdj~7;&IKBB={l?-gqMhkf{Az{BV}*~?dBAswt>Y32SG!NSpJrVp zgf$x9jx@f#A@JuNu3>&EG!V7O`lB|R@l3WU)hZt3 zEtQP8+SU9l=-4Mod%RZcLj%%~^u_4=+sfwL2N+(qQM+-=M|IlarsL3=K0f%!^kaj~ZY10M_RsV^6 zy+uRf$By?7kfmjY#DCHJe}no>EUQE|36$t4j6MS-V}Bzv{&XsVSBuN23XM&hVvbap zWz;>+5dW8qJT(AJT0rg`V@?FgJQ|oq?KrcACZE>FCaF49{`VMdWZWgFRz5(Rza9TLAxxqb{{g1Y5KRM@;7F z1!4#tn43=@SP4Z)6hGaIH16fUFz>MY3j&r0k-WkmtDg)|8wwp_I0%y{zr5Pb{l2J> z-?!Or1W!&8-y)`yG?f!9LdZ86>XdErSdOckG(LzRvi8H~lMW|V53jG_XsifMS$)}O zUvZqvX;-poo}ixIKzl@P?5vOIaZwS`sn%@tU!JI{kpB84=&P*GS2(b{=R3a0Loyfk z*Xk<$=LPQ2NtgMe0RgXqAUA#q5k1>6MrKEAXj68n()9|QV~JSc-ra^<=0y?Qz9taZ z{P|qYsW8!>PpIjfx9#V@kk$%5W=H3sr&52k8T*R7JOq3*{s8pxz3~TctY9ti$xDcI z8gPF94gSJkm+oWAQ7LH$DcUQ)uI1Clb4Z&8Ip3&i@iZv(b@r#b4LV8cSIeWSUE2v| z_wd`rK_O|gUoC|Prt(W3bQz*`1iOYZ1Pi0V!HY#Mt+&H!OM}F4l5zkaUB={G67U$a zpdUqrsGb2raU$`B-Q8ML<3jVORdGLgW2G)DvCCgoRC{M$5`2{VOAfOpHRQ%;PXm?G zrni613hvE~*YksVFtl3@);e_l$j?{qoR%}xP2Wp142y6MCBwtlSHv?eOZWQy;u&Zz zjZDCZIg1(T>xngsBe@UaI^Xas! zWa5vDkWwjK=0RdT_)eWXdRcVD0+lPT98YopuWk^-{_C2>(x}reMi(3(D%f6 z6U516ehnh}j|I?oy!2?AL_+3s&gbc?=`yp`soh3Vd@|T0*W#b9#Y#>YnyGKxC5qk? zgN5-z^j*pRlAjKi^$r4^LC@V(8W@_RwVtH{>y868X4PZAbnx;O@_RuQR@Eql|r9(()VLqdm(~-8<@8n$+0N$|ao^zkBUrmU5v!1yQ8|8XM zqB#R`UVJ&BqMzB{;zHmd*}Z8Ge4e!j(%r~Nq1@XkaP&e3cC=2L-0|` z($!j2+(29=#IHJJhwU?f7m4GfE17OC(e{@z(40abnczUYxZ0ip{mBO9Z%W_hfr+41#V0CI24tFlLH@0vkwnd?S_~|q-J;K z76qO}rNhNnCT?SZq3vdT+>b2-ihYK?QEgdSEsPW3h7Dr<662uz3bqx` zR-)$nGe3W4u=}lu`Msk1GZBw-!YFZD5YkS`K{lDZ=)Dfh@5{@3Tc%fM2!eZ4jj^Oj z-b!m}b6FJiHqK3b=8qJg_8HkYEmrE%q~?cUShC%F%IZyaOKQ3JsDQqbE7@#>nT+q) z`Ks_omG!Q@dVt_zV;81RRr$J!0{vZ7rMR5xo@O28P)3Bkl$4fpMNM0GOY`VQv<+$( zgNNT%0|ChlKxy1rO0*q$M{1WiOU4?5yAPr ztkGxN6iEbeLC009Q?#8wgr8~>4`*|pA*8d7W*n?C$WUG2l$K%FcF0&Z8=EekKe^)a zY-ox_KYy*2SVnPHFjT>WWV!ch>!?`77Fke^*LGQ=xs@)w(5@5`t2YRc_0# z;1gq-oa1Q<-H57xa0EZiqsyI0yTzZDw0yT_&>h}pUL z#uwXcoKMwcPHq{iU!lYH4sj9l7l=nYkd>)Znau4P-e7zYENiY#VQ|0|C~HiPvey7c zX7KY|W}+A)N-a6zUHBQ`vKE*wL~+aYM{l(f9?-rUkd%i?r9@0*ab}hBrX)$(2ENy* z#78Krd>+@+4iBh)?vqL0#4PL8dd1?LwF41kJY23n()+rw?nZkZm+rdV#*1QNX0Fq# zU!EYrLE@aI`zJW*FGLPKiT~; z?ss>_U)x_A+??aBRLf;NT9Ateqn!zyxSFyX-><@f|@xvbUXPTZmuH4z$IoH zN8#v+-1}cF1s)UShm}lqhh=-d)6=1^@BRnQ6cNRsf4}st@269@byjUb8g4y)ZFe z9o~>Jb{GPL%!H;j3I0gud?p%-{IRz%r0q~qp_sa!x!)c?ggz}%B0od>yfzPWE?f3< z;_e~V4*Y4dY`$nNu|igsmdrgJeKCMbK~vTZ>vAdv3qTh=n)K6``7lGp9C%5I^=6&s zTu$oj%r`dmDvH8+{9JicGI8|!oi_$VtaB(pYlTw!k2 z?$iA#u!Wpe$XoLh?V9?SNZTWfnB84Q6*T)2IpPRm}3oW{n z1w9zJ->>7`r``uoU$-k-o*)xC->qaB&W1~*;aTObJuPv@N?e|RcjpUJMP&Ik0uIpm zr{b{25G+-$(7QRr>>zL9MErFnRHn|$tfJ&KIUvnKTl~Sd<37GyN}q zt`=d9ErXpdpO-U=!U!q$=EdC3&Za9Hr?32nfA*1D#}u69$KEWDlyRNPYP@PW1Asj6 z!axgQ-#KA8m&wKM>}PWtzSa?g#3G9h4;cTIwbS{$*>dYe^OM8ZWvY{3w~>)Z%F_cT zaS;=+1PE<9ilr4AB%HFo4=MI&^&CC}_-WHaNh|@_%QNd~xd=`iNg|hdI`5Q?OdMAW zZU|z+{R|%OQ0Y$f10pdk9bR`qv`dmXLMzStK0l-(=i#53>VVW3WV^>*^<@Mlk?htg z-8|Rr&a5#1X7UvH4eIQc)BCJ(5@v=i2dVmZ-j4iaqhkdE?je&N0 zc8VrF;Jqg`M&W+^jaHOe;mmkU5iYzs{XEqDJ1G*})v~lD@2X_JaOeAzvKksbFWRr~ z!>N-(U2CaPhOeVj*@?Euu;bH;q@1Gd;?l9xV$2o`O)%t~inwB2nzF!ZB!P})`| z6T;2_QglQYrK*jH6s0-z>+hwu>?J`icH58$u>_%(`rG~b_a@rsxTvf|pCmXxX~&M< zqi)}ix1FzkdjfXeOHw><=wnFi6(7I(InCHV`%h{^u4oHN?_uhIsZF(lR*ms=PO*)( zrImf5gW*XmZ9aWJ%^Q*v^plU=cnll!7GpKyvabx*3m1J=L#bekwh~~cL4#}xLyy8% zmI68|I`;`*Y8jGLYU;|fRO-eGJ`JHw_oIoB4WfoV!Y+L$>g)_t7Oknf@5*ULgHD+- zn858iX4`{}J6QB{lj^3*#*!{j9MaT4Py7wf07D3YmT90P8YV{^oO=sY_n}vCPWFEw zD}EZMIg7>C6pL5H;vGs9gVC35=2S)i_WUqHz}zD+ZR$PY64 z!B=zSPMdH+m0R{HP?S~OpXw>R)jIXMKu#1FKU#%=N47@bkP9`8c@lB}v(U7Hp$j05 zY5tThVt#B(*@Z0#A47?*PU~1nMP@3HGx^O=t4V5!q7b}Q3aBYR1%5l4xjgLMDz9N4 z4{1>(SB^m;{fU-pSC}P7dmU;9kMMJcS5By<1+KS#mN8!FJa#{MicI;ZxR_Ba(mCfp? z+1R#J(}yi)-BWQ$cOBaZ)fm{%*3CgCEaHwbDUbxv69`QKv%^8MlKfX8 zm8R_VjXD#F(JU(<97Y1JM2jM;@zOOYOikCy4@19BV_BI@ES30J*IX70VP$AT^#w62 zprqpkxKSJ3o%FUv(ROfdy*i&L2fSq$Z##F*tjleBakkn%DBkJsxZLLlZkCk=#t@0SSYy# z(|-o|;z7*s7Yn>hS7*Ai3L6$_5%f5Vn&oqk!sM0+mh*B(4 zT(ErNVK3@DDA`bUD;Rq5!9pdb-{HHFx&s)bWo)9}%kD3Vs0cCHAPjiFR$pA_R|W>bdUV*Rb>7 zO{s&4Ne$hOD`x=7C#42+CC?ufiw)R<^8~e}Ij4CnqG+NmDx!|9mq7cw{J9lL)ned~ zfSkH&N!wl2=<96%ek(h*U64WDa@U@R&I(T|cBKH>A{E;$L>2p28}3y=_FeAoqO85oA3~tb_K17Xo;m4 zUk&TSbHVp#L^*dksa}6!-EY*&L6xds>6GCU(;et*i!;4dw@qj)Q|gT94EOSndi2X> zv_GwacO2Lyko4ZxzlD`CozSxvVAdE;ZYbTA&QoHz4y!ugm_M98-2jZPVw!9|QT9ke z+vC(d`^N5`Plf_;@3&JbLilIL7TuxWBe1Lp8JNu@s!l&9El<=;(-rz``8+ibO~UeQ zdM`etmc;`VRf#cJvyo6bM!$OJrfy-lxc{VSuUYeAYgY9QRF|n%Vc;K=Bbp4Z30hQP zgJNQ9pMpGIED6 z=1iXfvOJjNb%)yNBX=ImirOzF4a`aD8DKWx=7HI9#VXUN`QIY1JfOUGlkj^_i&IOD zIr1gLme3l}KS#TG;)0kaTn0~Xi$*ZdT1J^*bI*B}D}V8@`IhlMr3bG#$H(9J``$%D z%ppwGBkA_#75B>^1^kc61d(YtNA?If6|Mw4(q3w)#Lh5otzdXV2EF#o(p}ob2DF?J zd$W`lc^fD=804Mx=o>K@By`j&q*Qw=FAH6;+L2+B>{RRe_ze*y*OhJ2rUcn205m&d z<33wx6#yIih#1j3k;1^B3X9oX=PJI(`jQ|wCe6)e8+;4OJFNby?!ng`a4Cd{PZNd{ zxL5MKMreUa3vD=20luEqy*`flTpi5GQ)#gqW!ewE$Je@}Jbz{nt?k@1i2MgdeKZ>@ z`12Efgo8(d5V%5>Y{Ln{JHK(SHF@@%ik_Y?6*`~Ufouzy>9o06wtI()c-?sGvbfk#vmVkJP z$H0+d`-Ei$v8&!$>^Xc@P(=6Fi*NU$4TDY5>##>d)94|D>?$>Ob}(2f@k^qByw>r| z8+7|uKgE{;yB5W|zJ?DB%op<&KfL2U1B}0z*!)wV5}UhKf8-I6F7-8^E+!<$WQQ(H zWm$G%pGYM;0>dHPbdb?824P~x5G8e+%)K>~nsYh`5){SPe#=CaMnol=@o|$WwQUlJe5%$`W80+g8QF@A|{V7mdp~;egt0GM7AYv zPZLkP1`2;>^s+Inht)fnif@tRR%3qU^LB z<-7&T_YU`?Y=|&z7rF~q@Wk&OJ=YXMOvy=fcKQO_uA&8 zw7h0AWAS79Q!d7w%`*(14@2;cPP>Iu8MO% zLyNMWOq%4{`aARz>K|I_gVs5%DB5$z)`3-bTYF|%$8VTz7lY@I3bkrK6{3w>bZt@A zS~Em2Z?R{0v1jS%s1bd6$X#6op(gNRa5^mb5%Atq)$2KJ)es)AZ4G`hFE|V94A01D z)k~^M5PRj-)}Er28cE6$St-@Z6DiMSH^2JnzQ~P~KfFz)!#%@f9$mSQk{_}T&H|@p zgHs(W3`BjuO*?7*6!(&Ek#7^Zhc>qMH&cNYLdUfZEud{c52k)`(Szpt2IX(?cr!{E#S%zfS#?{+1kG0&W*vQq{uS*KX#m=*}OrPf4AZDKF zz2?9om7<9R~YRoSt>4>K2Usr=~_H$!H>oX|a_6K{1O`M62y< z)TpEPG!!+$nlis*M+qc5WFYtnbP<}w3igs8p~>MrHsMIBxdoE}bR}B>=n@}WB%nJ; z-$_=wHZ2rMv=DOnsP$QEkN*kFz;QsiKgpa;=vUW(B;RPe(#-+9Qic7ad-?m;Lyv=1 zQGpF)8Fo7ba9X7Ms1+Nyx#yduc_Ez&)nN=%y3*C@k+>YqVmwb=|6`@c>Nj&a`D)%6 z3qubTWKUb1avyIDv)ya0kehf-P%oJ2)>&D3e(7!KuZ$sZw?NK(Ppg+1|@^C9330Y9O<(j6+<9ffp9ZUpHb@fZF|}OysQv-`^l7dwKjq|uV26Y+?nfR!~tfr=+}O0 zS8fkZ$#qiX8vRxzMU&0wIkEcQ$&-S0FXN`)IV}L*@pwb?aHF#BOj9*YX+^JTAzQdU zr@{PmpwgvWVrE+7CV~G9@PxqUE2;IV+kix1fssvHr+_TPuT~aC10Ui3Geipqrotvw zNmf;-tP2a}uNH9BIuu%`q3_1CYoxv2oC%5ZNvf$)3@J>-aB9OW%@j3k&;pcY2?{3l z6?}Xh9y~Bp^XD3y=^A2AcgaPm!O8M;o>s_EnLcg7 zNop67@p2{FifKuW4L<=QmLV)HCHg~T9EcUWf|6u?*F#C9%d|S(K&vLIF|iYY>D`EF zXyM`X<24HZ2U;eK5FvaMoPS=O1ow>$jX1`#dTbJ*zzozq2R5goq18k0rJe?EDDcOP zuldcm2`FD$wy(DTMxgD*b8+2@9(=Z=&HFFZQ1jN^4MuK-=t7hFBhO{OQ)+rKWk4X#eJy)JUG> zf*}WCcPhoPRm9P)ZWicipZay+7SaCG7kkszmii07@~n0=sS!u7PSJ?-wD}d*L95Sl z#8rmQ+zuE5fZJ2rcAS0HaB7KCe9ix;!g;7=e^BpD;>s>CWn@SaoP{J4J8*15zeeEE zR=Z++QvGVKW<=qQY8ix@#q{q#*$wl*Kk55s^QWK_Dt^4Q?H}m# zq0HOn!PVM7oQ4W&H(MpE_yxpWh3DcF@0g?R>zW#<)~h@(lP+A#4N3ES8y+nDz^+2{ zZ%oX95kJ#u*&*KxgKN6<{(#35kVQ?UG)(dFNEaRNi zOjzI{nlO)jvLy76cMC{g=O;{?2XFmib-w7e4&QDOVmZO~=|p zU5~(JSD3CmDiCYk1s}=eUlq4_FT55;IxQO0WQgQsWd+p9chx#UYCLsI5u$zbJsY{R zL!a6Pwcf(EyFe9w-*TQ9sXufMK{q7P^;%WXiRmwVwHK9=eqFf9AW)*~_J7+*&?)2^ zZL5eaH35CngKq_EDG_tj9MVIc2Jo6aOD$(~!7TE)hSC1#=7Klh|x zH$LK7R@z^CRcO^|J<^`hqieVmZKaL!#_TqC7T(>ga>UREw+&gSzsa$P?Nzj4Z=3-l z{rzqA#NYhM3O#0b%$zGvpVV7>O1Q}E=Wk})`;O}OuSI_Kb6yT>EN+b#Igs0(b(@+4 zyI8;894X~zyx5`!m@BzrpT$viofQH~Oh;edcCEc#^@)G+rr*iaKTTN&%zrcBu88!i zGny&A+x^0Xh3n-<2W^)NuMf5x*a?r`M_NRs{f%T85g1xn}JF6!Q#K?~h8T|Sgiu;>`# zbD?IcuuXpfk7}lIm_OU!p3*DL|I)AO@Lbo`ZQkTx0{l|Xh%4U9PLE%R17km4C&r5ectM-m}C zaJ|#^-iw>QZ|I(6;k1GcbT#V)2m>kYt1%`0DybrP8W z{>Uw$@%X@xt94Bn3M!W1>(R3y&-nriGzDpC@)+X;IR$EaCeVGYu5qxlU zO3y?-HTCFe3hla^+IBs4cf*-#g`4CUOF>4U>1HD;1B zLuzEmq7Dnp*yM4VIO7s=PuI3wDAHkI#EMV?ZBJO*UX4D0prs}^{zA<5%2Tm1AaBS5 z%MgUCa2F&Avsw8$V8sgq`|D3|nb@|@g#~gzpU0z?GpoPif_;&7Us^gkKW#VcG}NoM z=+^(%+1%NdWgZFKCRJU}uzO|K@A}wxh06bW$^t!9T$p8{wd6mRZE-8h=OZOgNNtE} z!sD*#=8*q5w74@tRWm?q3ye-dv6|IYFmI88wxZ{9yhMz1*2y=feEJCQkjxzR#fYr- zLTe}LsPeQ6=|@OI2({$4^!Oe9amwu0eWVslZ0CAKmzN$nFF}#)peIs`EGrv*Dz^vA zMC#xQVaK`I%QWc$2nSr76y+SIQqtgEIA>GKZ}zjB*S z+vIehXR7_&RPNdgJXY6um{FX){_=F%D5hJ8SZ6OLmC+wG!ExG-8 zVv6{=us3>kmcj9yGTNez(BjBu!y?K=K1Gg*VUlYLCP&++Ng$ue3(Q6fvqK$&caQqY1Ot;tW5SM z;rUK!3Dc638StZM@~_dxC33Rnc2mOEV|$O(isVuyDKN?hoaS@6!9{BePl{Kxtq{!> z_*FB5_Eqz)#NMB1Dz1&!0OCOS&R0*d7ZdHOFDuN|%+C0J!aW4%M5CZt@rqi$`+XDU zkE*^L&i4_R=zD}FM!^&J-t#amrSImq%_+Bu5&Z;?Cz5QG7J6B8;9yzG-lh0|HYtxx zBGuxw)V>6+i0k)uAU;NSIrel=4U>+mYJ;QDOCRQS)UZFiRwN_RYaRGACxc$1?ItRJ z$=ha!W(S@eWol067Z~5J_CzQo9Y3JhU0&qK3FcM|_Ko`d^x|c$y5b6*SL0ZvJFPpY zhWS$Z?^GA5=J^+N_Z1$RVrDv1#o%J?H@rF3pk=;eb)-!#t$58CX7;;TzdLOm^dZ^9 zI3NqqV~(WUfR^uS3(h#K7=q3B=H1j#OvA7!nH-AbreWi2`y2RWP|4NCF4VyqsRh0_ z|LiVCpzo%+R!*6-xjnP5+MYog5hn#<9H|P%x=)W1cm%+T8lwk_sj7q1#ZzYLM@{L9 z`(38y9B$noJI$Sm-l^2QG z=p*=Brs4Fxs5THaNq-vq*{50S~e1N+76>{ zT_HM~(-lZl%HMVlX7WfD^Yp9yM@R}!vY`h3HVsXg|APYB$*15}Y+3B6XMh1r{DOzC z+cgU74l5=9+!l-y74NP{LZ1Pd8)a48RKyBnO_SRrh1BuD_cxRHk316_KU>g79~nR(vi|yFEztHO&<+i=w9g{HXIz^NFT3Ds5gbbV(jdc#9d6>;dCCjtlm3_6r}pxN_O=T=j^$V{<-9>igL zjrF3!tqlQ@1GAm72M%xkLoh?S_Ww&S{%^6GSQ#a(gBDRk%RF+M3sdpJ7|O%7AVS|D zSDH(7{+QpZ|AAzu9T6<4c-#w8;8my1Y?$+%IW=voIL6H~oTR|aVUZQTU!ni+kaH@-nS@HGxZq)4-vFc;1 zi_^6>D&s+i9-~J5K;YZ%1C)?`xIvXgMhUa!tk)0w=KbTe<^Ek;cl|KZYK__CFQBRP z)SiD;N5O9~{dAKXjg9!L_6vxv`b}S@`_F1v+(~|qO>f(=i|+t3x7lIEY8*a}&osqS zDqg(zbUf~};!iJQidkF@s;Ybx#DzMZikARtmglZ=IqfOIe>w=%#0LZpN)5fN!30wMuJGAg}} zbg6?e#t$y~v=X@r# ze_aHn>j$>@9$Ntse*hfr?T!yAYrLiIPbF+hgKdaO?UsM_IbXKRm zxU_53Z`3xbZ>Cpr;H2L_toXzU>o$cxzqbreBjA-iqYis(NkSuO9Pfy%Q%=WX-t)P<2 zWZ&E<{X4oakC#8R-5wGwY^^)9Dh)zh&Ma-)iH7-hOT;hckXdB9={fX~4`24o>q26m zMW|>tEejK6Hm{g?j%{6gz;~v#6!U6cw|2IrhB|Iu->0&dO*uEv?^fwTY_8v?sJzc{oX961w028g**#WcmRXzc z#$ZR!Z1+qi6FhSbWvYTFMO1g0fC`dJmzKWDrwYxjcUxrs3MkXY2+bCSa`YcsslWk)Khr@U?rC)8(Jk-wc<40OhKl$ zHC}P10$I%2OH-bkkwL%j&>DSx1L~7z{X34*M*q%7Hxf?212Y|ngUJB;?p}3_nu9(?$ZCvijXI$hYe%#Q(~9^pdA=;%krzhG=wDux=y+B;&UB?XR%uCQ5{5P! zyd8NvrHS7sx>mQx!#qgmTyjDu2&N=)jqg&fO!;5b8f;;1Hl|_vCU!h0`An+Xqko9% zR^*h=c|+0p?SZszu+p$`@>t>ZieN|+(ysbBN9UrW>n-CfP^WEj%W^qmRvY$o ze05at0%&7dWYd-_5Zuev$$N;j?^%O+Gk*PG;jfj}d4il#uL0T>&IoH@7g(FRD?QoF z^Ud(1fIa^bm0o9dX5M>EBsC5{6AC|luPdq-uOf&~ASU>0WcZ)!YhG=)3~UNz9R6AU z5iEJu#|k=x-!&^O-;%A|NZJ7t1pIs8i*)BjZuRkWS5#A#D$+ROk#%mXpLnOcgReu- zw`pJM>(gCLbHx>I!ZGTa91s~Wz@I}0kYspTZ2S9gSwIU7r1A8a9Z|_(q51kk+>0-X z6o-$$H#r|C5{X?conDaHDl&O-B=Xtnp84a51WJT2ap74B(I+4ra(8O%8z;Kd|By<( zo~m!<5i{*YqGOKs)9+4K=BplMzAhNmihV!ut+U_iozctHJ;t1P0gk_jv z5D7mnxCLx2*Xdfd-1~yg+}Vqqtg7alVt<*~;N)-j1;}{5JmQPC5ux7MQt(RaAt*Lq{f7Evw3b??S*8S*0-hWm9u zi=&!TpLcqQ{{@Id=}l82%u~*wzFon(MbGmVW%Pm^%v!S%;sReR&D%TqZcT-V@!XT9T6ShvIkv3mqxrXtI6y)l%43 z4beTeAwgZ&?D#EtwuEKbvHa+sl{>X=buJZ^v?ZkQ)rWEN7(;(vJUz*z z4`B2)0;prjCuy+Px}t>j=Kydbt>4o4=r7@}^#E1bnOC5kM- z0yulC6Usq1%>hxqS)jE6tiyGCf|}Zps!U5PyG}nK$iQ(@jaPa&NQLCu=PI0Ex3s$) z9qAZR=J5L#nT==}j(!|3!!XdECc%CniSG^&Skw(lWbJyqNS+I2Y>D};;?=OStWDqG zu5y-GG9olx8=6^0MPt=>y zP^vqjL{#ekJ$JU*>cRg#?>}$2yelY-0!zbr@U*%FreUb6__t>tgMXKZUKpiKb0LDF z$6mq_{Cb;G0x`+;+yBJl|97Bf-(_)&#;9?3o+JmcvBvdcw{14?U9pD3zv0RlBs(fi zbQ*JNCt65=$&rAOKhjW5esxerl@)N1UHtx8v1u8@jY|ihHU%E$Ub1f$NX#=DtI=K6rdQ_VuIM3~*>EW|mSB3KJs z;e!zm@Lbdf(*;%5&1tw4O<2-mn1>L@ny?*4GGJoMBOsmRzwgyAn6F6^Qg_x>a(cfO zJq;J_pN5@}q@dArKca#3pZ_ILYp>|L&V+tu`x`LhsYKzA_&y-ayrY00o{O13go=;Zu;(0`apRo9fR{&SKF78?QqB`w$hm?A*S>;LA=lkDB1KFI0 znKYTs8;H|n8>vjT+7ZCUw8+;bno_({#GME@DN#Xw8^l%0^u`8Azb=R-+ns%0>+UG_ zb@6C)m6m~M;w^8z8=*gF{9-&aX5Qq*-!I!!Z68vycTAshG?3z@mr<+N!tBgZ$94a5 zbh*h#E~5p3Zj`N$@GW}w;_3>={@E#h-<<20IO76U4yZRVC1(xsO0#Wm-q4aOyT((RMnlrc zx*xJHt$LF6bt%5h>z*Y|HHT}9!YzAa2g^CJdGf%xWktzOh4DM%97k`g0WyX0>5Et@ z`5+ic1_mxCzi>bz1B58WGEd4d(59Gt3A_ek3aow1ZX)N$@km!Vnc) z5wv$p7Hh;U$~gU3a8?gg3TwO@{A*2T@$!b}0y@W&yxEYDdMYZaG)ODzlPlFaI-v8V z^UpRi{{}+lhlGzg>h*wS{E0V?@iDQrjql)Evgf+unCu8pjtxH3iYEThs`{^8g1N-K z44s+t5)$w?s-eKWH}CsEuUrIUQIjV|*Q4)DeRF1K2+q`ns+6Rhe%<~6v-tv)mUDu9 zxi?EfP zN6o2qI_BwLKZ8fUOZ(;Jo;yS5O#X~uk*A{_zhxE5lf;x3zhzSupDfHa-@@xet2@E6 z(wndu78WI+G1&?_4!!prqbZ^hukwX74PRrTn+cXu>_21+l>$O`I{vFbq?BDIs>GCsV<%NBbPU&)q+j|gFN=a5sR}$rzYKQgPLY0BppmrYJBSR6;*nk6 z$H|W-=>J}*Gfj2>KtKCA#d0{UxfWM0K=Tj+c|DOt8#k7P&w@)}j|j^J2);b#p~INy zB&MH5&801Q_1Ry znjPG;HSQD?#^J|c4karU7arYE#@SZ}#yCDsIqb&x+#Kq3whk%fDK%LMIpT7x(z-O= zDIc7RQwRsv$9D?KcJTTC?i1_Q#87wO!fvofMH~~2EpeTqK)%@Tzz>e$4Bt&y)lxmD z+P8EBr?{pPy!8Ms5r#VebkN%Daow9(_uuVy1DprPoy-yck)v`>Cxdz*|Q!-7~dENy;`O4(%KK{z0LDi zE}3lwpYy3!38RUL&aVcXorFblmNL746?XaVjQEU2!mL0G#8Iv$jdulm?r%(%eLMHx zed(s?G&hV)A4o{E;Jy{u{EZIxl}YcsKoAXebko>Us-6>fx?*g;Zotw8+<02(rJaRtr{B)-G(~ECU$DGn55ESB06#jML1@ic_a%a==uxBsE zU4~3|!dBmg{tr&`f4MaO52`lkIbe>%YvJ()GJqEMOE0ZCYV&Zbxit}V4=km*t(kkO z|2i6Hdw0AO$)mE->0iHZf&M7&!gtrfIHFc&ODqQgnVk#3(>u6cIn+q4Mx>l2Ta9|^ z=}InBd#JbL&WSM3=X=^0A}Eco8@-%gU!lHWElLer=K2HS(TwGSPgMw6qWri+U$*-S z)ip9y>+qmszRM{7ENFc0Ylvk_dC?Ja_$V1kAgHe+j#+Fy@+Jz{tLL29ZTHPI zO0F+Lf%`lLGvHT%xD1sF=jw<@YvtfWmXcq7NOQ`#bs*N)S*sUc*Xdl=Cd~ND#q{{k zXr*3lvSzuP{}@5icg`_!_3>UL{Fmj8e2Ijekj-aB9~&$?FxGB~cQJ<~E-J~X)T!Kz4{mMT3 zN@8-2tzq{JX)ozCH%juX)VJCD&W&_ATIXg|k@QKqr3tPyhKK@f_b4F=dwh9hMwPMD zVn^d&0U|E)NQ|Wv+&*BFM|ra(CsJHb1ji+4MXYgoFa9t#B#ON>Gq>#3+jY)!G7>BG zY#lwjr^P&f0Vc7i+A$5gamVn`s>o`(8R{q254%#tUcHe}9Q$C1Tk7RjPWBS>l=k-h zT0wEiuF;LTUAXGjTuV1xa1?JX>=g9V4Gs*&WP7^XYt;Q^Z$wS$^Gd*-aH~VA-X~@g zk|}QLQFkJhACdi`G{`XcBN~P`^lrbKD{gEDS0U3EPH;1isY?Ax|6jnH?BWp!CFaHq##P#vx9 z%?cM!pNWe5?B}H0>1On`j&n=8$l=26;RMUx=4WJQ&7vRUQfA{%tI9T_-S!MP!7c`E zDp$!9cVkju&rnyZy~%^dL>-Ed8X`6$->o&ocgBsoyWWhDh0`ry7JfNnD-RF{&aKkpLRgl z80?+riODb!l=~yb6@#*++|NM;R|#Na+igU7Je;cD66S?v(m_?62<`32 zYT{8hKShI>u%%R-y5O#`1RuIJv&#rDnCv{q8rt8FRuL#z{K=X!qa8&CUmM5Z`Y+4W z0JQ&bKU1F1dSkl3^nmCa!wiAh&1rT0iO%B?24BjiPq8|x2=kcncv$O0Fpv@;aVN;C zonGmE@5U424<9qsSn|^%hu(JgDYs|j-gkmQOD;4k=2Gpma}X~ncLfRWY#VwY%d<-i zDJ71oG^Ae8aDupH>v}NUnU{%a^&BptqD#JM8zX!l z+&EMsK*y(hS}P6A(PixQ_tEyD=k@eMAdCBeCKf64_X|hJ>OuN891c%jT@{kUc0zT zrriRfhK4)=KcV{%`+sr-G6RMWX1%#krpzp9`J*|{dkrB?3;lPWJdj2=fAm`>6!^Ux z2E@{7&F7p#j`kNko5Ad|)0ogBALyCII}{dKe}j`bJaxF>J5HRsY20b2=~_&-l#Jh!AC$FpB8IKSr@sEvmVmJ~{nuckRS=@R)xF-}49J z#*#EJ-m@qVL@pbuVjTenckoR-6e8NUu6`JJT#vQkuB1i5wXpkn8nldVEzEfXGnrI% zZPAA|?oeL8p+uSU&{Nj>>)Q5B972!2%=;0f8^>#pRFgg> zD`EM{&eT8H$(YVJjM~ukET!SqF28crIpGi(V6M@S#= zO&ZO*1)j9IukN}sI0SvhFE0N1snPBq94oGE2#YnF30l|dl=>?No9oqrmUs6@XOeyE ze+frTure^li1Sgs-u6+O)Jco1=20mW8Ulw6>7{I&zjo z;!y6E`%9k|Jp@z`3fdIpb{_LCS`T#?rrixVVU8Au9W?m+<-0q2L-Eca_4UhR)~hip zTw!&#vG-(BYdoh4p?V<@Hcn;F z6a=&yW4g76BSK7dCSn;^jV3-7u~uxuyJ;v-N_u$&J5{|~MSQ6&_TeWKPD?aNYt-7< z=9`Mf@G|)2^6Eo^Fb+}U9(Qh+7#%pmJ~3rncZgr7Ky=& z=a4|35TM#$Ty++>$I3ZJ-{d+Wo2>6xgJUo&*7b3$1zDg8d0;u7L19~_Wz>3+QhTOQ z(Gkk7FWk#834CkJbvD_;&ZGR6u47rwe6T!mF9mmQxk|aNko(LTc8nQxdpp(X{=nLJ zmDtP}rq{XSgV#pQg=@Dzl$qQjHOCeH40Po?*#9{9pHb71BdflKso(u#!w3N0VZ7N{ zbK>pkzPU?dH(4)Vwi&&lr7tshTcLGZyY zb29blp6FNb<0jB#*S;n6%57@u_1a z0s8%NKVXLp6>f!G1Zhs^=daD8@ju@0VB!r)Ow^q{#*gGwYktvwkkZ3RC0(K(9YhRL(^&uk_`qVtxL{eG|{) zP9s=Bz%-|=FY00Uk?t;@bP5rk@pP?Q7l?{r%ZSfJ_@)w)z$m);=cVQ1Y8L+R;7^$& zgQwqVWR3s@&{RrRPC{QXM8Q+S5@R=>m7@GM)>p*I_8og0+lF6-Yx>(JGg!vAWZ&q5 z#&cfyYmeXY)mQ={S9W#y!OS1qwW6g!@d}I`jYCu`yyqse3OmL1_1Ojexr_?$FxTGRR0=K9@7>De)~#T58g^@ zr+B34;%@+TIZtZUH+Z8d=`^tPrHIx9gcuZCyJlulwFin7Gh5orvi&Q9#zuF`9Ccc; zI4Gmc^pv|f=g3x>?vIFG&x%0Rnb~>^Su@vfZ3Cc+{<_BQO$KKhtBFKPv7ihVx%$wmVAsY$Y?VT{L zc}DEN`;LvW@tIs7AE0riwhGBiDCx?32PZiCO?**Q$^_Htg|&^3TO;nJ9|p)+54cB>2l2y0{?_9~E} z1wIz*6fcT-+&`?$zE4I5E6w#vhh2!(%7i5ysXHYuq3)ECC2O+lRWSIglh|l@cp=Vh@-eu zSP5Yn$O(IBUEL4;bEzqB^PpzR6R`6kC2zt{gIMZ%Z2Y}i=O?(yfA_WQGVhFTeE;HX z)8ng^iPa%s#Q;1fGFBvuNL4x5m%-Zy+}O1RlH#~Ka}JiCsbU6$)5_7U#@XRFK5W3A zUyb;-4XZDxb899qkH02)y1dU0JltHr@Z+3ilNtNS;92HvuU|*0X;oM9*&*4(EH@0+ zT+EE(k{nafaziofT8-UPUMW!=Ri^~AF6&%T{vuk!H;rtn@>Oud0kW;raBXmO*3iF^ z!eekei-_1TVfrQ_VoO|L543UczhEy+v{Z)l<4%l;)UlUFJN>wW|LL9(_(_AkhAd2W zStb*G46cNEh~%lazYutIk9Ho6;_Y|Kq7Q9X$+FdkUjQMgwX6u%>O`eJb~5DRt!&>+ z5AAJz(-X+Dr#DuH4)^v|B(x(*%NvC3#+$T)Yz#@J+Or_}go;m+n*MV~B&*oW+P$w$ zOQ{~KA&$ryaIW^nnhEpavRE`v^Kl4w+#j&zpA)@DD;jkAv7=JjW~b@rwZQw3>w=#H z#W>s7?d5%sFld%n=B!~Rx?y+oOwA(k9pX6t22~8`r>jgewiG`AOU&8$KjB7U)?Vpx zNfyKZ0AFCNI}kJ1 zu^hFz#s38>F096x0jazEQ#}D%6Cfc^3=LTDs`g-S4=nA&hi+QXyVWE8JZQf|?k?`* znFj0wx~_`nZuOi|JGqBmRfn(_f93dICc>n>()wTZnY>}&e&s#j9;Qk5D6-U<*;J2M zsJGVvMfU+gSWmYhCVr$e80OA=JZxh-5TS7YU99p1{et;cX>b!0mHZnaUU!1yCj}BM zh~kdo-#fMhau&<#G>+k~5f)X}LZT`w4;(})gA@Rl68_mm+Yih~%HS$69pk z{0mh))*a?Sn>1IrFGqY;z3l1haKGNzXrB`mB$f@}@0Ti)!}n}&~J2z5jVb!K}f zz2!o33f61+d;|!)|Ftvtv@0cWrJ6AtMc=-6?zedH>#r+xWCdFa@4c~m6z4hB6b5@U zIM@x+GtnkwFj&;pC66SpLu@$hjTOqlbp7K@cXWQ6<^r;o9RRWJu|tNa#5Fvw2($Io zx#y%up-pFUW&R6K1wHY`g6QKT;J*}=m%j5vn=l5FdXPO|w+rslzBZKVw{{&~+W0of2vTz&3mfq31Gj@{rD2oUOAny(0uyeB zDAJ;TZ|OnH&^ZP~v15KwsjFDT9vy8KTJ(DIkkPF3UY;#{yCNc{@vv4oeJ|%zYnPfF zyy{d`>##QGta1Q6741F~6waz0XLxkA>kgP_7p!Se^~T1UI_3oC?P4sb* z9*z!ez0t(m-(NBtvhjF%=^$}1AO<%MEDlO7AJGsv&JSV4)QPXlh^`jai9m8k582s>!9q8DpJ;6lv^KVA#M}|mF zl~dg696iw1g>HnwP~XiB+WYVsNUBKpld0YWsU*bvreSkU3iA_C`wC_k@bPbwT{&Y! zDueObPV$2%VPi{yUwwBlgtH=$o8FleR@1;9X?B{8+=$~_;CtM0(lc1;G5E1{_`&fw zs4`$Z?#L5+*cr=#Dq;|vv--w+DbfJXBp+F(Ls_8A z1sq$3LDGD{Ib7l8-VkmvLb-H#m8~v*!!kGu<csi;Hj&!DfzM>XC#k$zuILp%1R!(3m;>JKz@El>PxHsU|HBz!ndy1A1)Ej#fZGe{6A_Tk$RI`)L zfvHC)7I>S0!{A}q3 zN;u#NfwmjN8ZJkAF%#1p(mt*9`$S1{TMbXYYp9-6Zt=<{`YEJQ#7D^(yByv1=2|P% zN{+^$OMbNmi2pB)9NL4QV!T+&g4z9JIsHp=n#}Dfv4cfHVSx?JIC81g_H_TXml68J zcifhRo2cOQsuSa+5ziOo+F@tv>NuE7)Bu*aCd*rW7oNWT8_|nMg&zX$N3(tsw@KU| zD_K~xXJ1M>4l?K5-?fh#8itJ3L&LvTjoIWzjMtz%YaAQfw!-MdVsdP+1Ldbh5T^;I z)+p#d{%67K9yU+OZ+3nl#mC*PiN<_F+&&-EV)_5rKqU74{|A4mrR50@vY?p(hj}54 zJZNY!s7`z3!Vt9px>rSk{ukTfCVZM9Y z#`qFT<*y>E`cM}GV`PZpi}4?qmZUPM51FpLfwhh~*z3HsCP~v)zIZ3y?dFP5(AM_ynSHT5f=t*etmm{9D*U@qU+vSx} zn0;JO1au}6YY)PXXgOG?#Mg!}WGzsDvhdAWqI-h6NyN4Dv?k_70~fa%i65tI7Z#ot z{(SN}=55T{z@xn!1jM9t)MGukJ;`xE7va4^RnRPIUy$_OVn?HnMb20fY*9^a(sv#F5EED8roNd6Mki^zY>f-Q$P;ggKGz6-dc~<56*eihR37<>7BU8ccF8g(!JO_0EF89knEd`=5hc+FDCC|AK`U=*mBKn}M z{vbrRkYf;z33t77yLn-uBDBxVE#GDSN3dIxyRXJHHXQ6$qwYh+yMGe|f*#{2DJ+cJ zO=e%Q8+T6IwC;W}Wdwa0s-p1Mi679TK$hFR^OB6c>*wmt&PTYu9N&Dj(w?K**b;h~ z=vL>TeX&Br%3)JMAs+vJ8-#QJEVhvPlVM-ht=p_U?%Cnub<3@7CfS1oAI*ZF6%sm8 zJQI=lzx%-J81$h;D&m_!A=(kK{PY;6zZZ^}{yzBO`b4+v>K>FaM?EI6g{w}Xf1Q4_ z)UeWX_-3~P)~LhN*__XTq{9q3Qg%IY$PBpdt5*VhJ;pWIe>mb+u};4{L`BOv_vaUj zi7Pv6y&DTy=tm_bw8y!&3(w^C1}{Rnh3c860g!`fS;%VDvd?B~tlMBPpKNt4I_}BJ zjRkAiw>3hM=W+(Bm^z8??9 z{Iq%(?CChMNr55XAdGg*G{@fl6?d8;v_RpdFed#0I`3gN%fdr_P-zf(>fAH~++)Je zwC-hFh=GnWrK+=>$JdN}%%KV?HL3JrUj87iLB-_`+0JR#^yMC17TtLl_dN<<{SLEb z@McBtzU4)wOXHal!9Ry}bUdEDRJt^fs?usu5u5nkBcZ`k;2*62d)S0KDc+5wM?OrW zz|}?lOUFCUM%M$M!4$sOrUMVs54RZCXyH+Nw{oFMv}?3<=yB1hu-%=lsDu!9o;>!l zu%Sgpq5e@)6zmJ=2Xd)NVo{~nJa2m`2xqT9>JO>#%eQ_>K4J$w!}zS+4K<`s zW*7Zo4Vq{CRE|;{UDKK<+H5_$XgAdSv=y)Ieq;-BW0jPNtrcthnq@>peyOHd&Js=BF(2 z-AFV=+4)WwbbXFn4Mix5py4#}J2Ln2ZK^8LzT&7B67=0??v!$$B+zJWmVP0=W9uIU$BNrVDVk_i6KdZg$=*mB@=C9elJnlc% zWXM{B?)BoAhh1hOJ#qjvT+gtSjdtxaNM`A)e04%zs--IE5q zdsNYTd{ckg3B+2NaQuqk1`zbO&CWucNCSg+>6*Hew}iFglQAvcu4Emr>U^vYPd$STGT>$2AXET|_ZYYe!SJ}K2ikn)ySf%v_@lnA z=8K9HwU0XE=gu7_lGcljkzx3tJF}lQTD>kipFU=973!bi5H(>r&~n7?oHq613%!f= zSF$QXT*7Y`X`v6V4I5`gN0-1}jK{Y<`l*%n%KwH~3Wj3%4y@lwv!M#t-&aB99PdP2 zW`cF(ihP57t^0F=_C#7^&etN&mhHf??COp4Sn~J(wJ7N4TmFCOk8ty}eP2&qX+(?O zg5R{j;>9mQb{G@_uCi+-Wh7#S_XY?8&7io zB)BmBphh^XI|v3Iqm8lr@~xfA{EqqW*23QfYCpHwij{n0!EK&ALL8Qa=TiDaaBj=U z&Q1wS8HTI@XZK@VJK_P^VesyKGZyC;m98!}RTmjx^@ImW3mI+k^9wuh2;G0Ay!@a3 z%Wq>t^k1vJw0uk14%F>1)4RB~=vdz68;`!FYwi1Puc8{#r)J_}CAzfzjw0!5Cu7Wb z-#a$gAXzm~6y8Yup%!dmHn_3Q4|jBN%|yx9eL{ewsqn2inn=8hJN*aHz}?SD%b|si zr22a03Zz&va@b#l>g*E*%c(S=L*zJj{*(F6UQiR;mA}kvN9!$9a^+ZsY1}mn=^0EY@d{djJ*7LOG`GL;Z-bVlv#Wzu0aXs*ht98QJQ?R;IG?@ z%3ci&eLhj+l9f$xoh0o-`m4c4vL$UZWw{H|yQG8%CD8-48_?W6XtF+M0({1(OlX@| zYNsroo9L~7@-^?^Vj5>_CV~-Q3{-;oyEQM~g1;Xi*$e&%c@JUE2NWsnPt8sD{;D4N zX%`JY-mmZC%=Ae)=i*YSFD=~}?wJ+6tLsK}Gljs%!xgIPqQG+c(&u)&D^<(2S4}#b z_LnZNV=>rZ%WK*Jn>u}FK?V-Q5b?gr-$cqYY6}zUa&{ zlw5W5gFlj4bOvhJ8h(MRoYm#>h^iLfLTv^iTm({}wU+=RqDmQg;I2QdvR{T}kzy2g z=C6<5WshR=OfVJf&g+}u0i*2g#P3w?UOTmktA!|n+$us0RK-9b>?VF0x=H0K?*Y=ro*4m@g7s=Q%ouHR1KAiX@^*~FY1+)^wLXV4 z1j}BBuqK%P`itmSWy+H}j^4PFJ%OiO24!@W4+RPpcruD6BcJ&aj@=xscW1 z@Pz-5`TGBm^0xmoR0%+fROEL0h57g!A*qZ1wF$^h{>YoN;Z#=io^E@^t$rhgy!a9{ zTP4|v4OsH*H|5wP2Y{)*g~@T(@oq`r*(~aw_tz&S%UGKsIN{Nt)S;rANwyc_JxaPf z11iY2-*-#gf8u5%8JR&*MD)&NM)K zhMUB5-O1f2fCq+h!1(fRS|@^UC+bH?Ky@1I?IXgYHE)nunV zPj%;kulhM|A@C_@+)AZv)euQ#O-kp?iWe^k4y^WO`_uY?rFoDkg_M zOGf$Fiw9IUGDba1nk&{(PBRxJE8lwLH+orP{VA0pg=^ehsSBRNM&OnSwC-(>Pu2;2 z>Mx>;)+gh_CJ6QiOFoT}+#%^yNSa$eEA*`k5#wIcj7(XDa&g5Sga0O2mctAKk9kGal4IJ)@$gU77AR$`_ADGy1DciE)JI zwPw(S^#9hiR zJBgBCqeR!T;ZC#T>F89867c+j3KSqB$qc?T(C7@0aEdTYt^QRIRVO&^w0etBrMjTV z*%<`HIEXag!WTPFW^DU=H-j$a&$8EUInE7A`eBbPi_Q#J;3#jr{f|RxKM^wts%BqF zsB4wB*LM>aH2Kxfu3^4B`1Z#@aY*0KEB>|!wr+ba+Djo~^;2rkMcC^F?a`d^4rlN0 z=cs@-dQ*$1dWk2q!Q%&jZz%$9g&SLH0KpA1Lxc#Z^0D!qn}7x17Kk|)3iW82irabs zMmiAT_)OoB41qmi;e!oZO00iLDvo+zWbnSz{@L0wj0NjXmA(qhBry+MP{SA}=FpeJ zSPg|;0E?4Tllk-``R#x%{&j_X(OO4bps#{eg%(KWFsuaq@sLR-QUV|ynZIJX0+SAN zETOrXP7r)C3J%Y$bezfjLJ*&FnxJg99kQXv#|lnPcb^tuK#KSrTOZL%V&vRn^jeo} zs&Y>;1NKke#DbdruArs(^eFd{EBqaYgx`OeUzykV6 zlVTOZ9X&_WYZZvgH33E5wawvnExIMqxAQB)do3W^mJ3z^20KyZadlh#c)k<}{zRmR zEHCg41Zu$M-=Z-@BaONACr(rNgcdw>Lq>_pG*rSKTntYtEnwB3VPofg&+`_7daLNXVuwxW3Rw|zy0A= z2X46PBuZz3>?G%K`fnmA?$ert^G{ix=5Z?4*T%49l4^kU;?yEM%Ly0qd1+&TZz<3O zK#S8s5W?~xdkHJo^|}BQcrYReM&?a`?C8o8cW`-y8I|2?g1s($j)Pz%BqL`7DrvoC zQS_1H5hCSrq95{5_@aLG#pdzm>)RUu#rz<;pa&0pBjQePYIkfGkPmlt zy$EuNz2``&v`=tu;>yTrUw-3BNF}%=>jpKTOpaV)9iU9-LZ#B^%f$42-wydN*KRkX zdw(Q)1nM~bB}7u25IXeu|H_9EIUIbJO zzPQ!m<>loWzUzG6i*2zn$OY*s8~q%xOh=0(+`&G7f+w>X#Qoy+9%jPIJA|909Wwm@ zw+@FNef41A8zKXG^anD<_uyg?Z-frF28iqkN?s;tt*0yxsrmr-gV~Ycc&X5iVhU?X z42XA2`$^4xWs*bjq)!b*OcL$)+g^Yf7o=*onXY^GP8J{cVDkNK9l$jqUNUAQZcdNK zla+goR{Q%8A6m^8H{84_pd;9DnJap{!^S-yEMQ(|=y? z4dm`_YuU3Rk{=ovcWxIxMTAgt_Io%Rh^9aVI;hu|+pgI7?(?D6Od7&J3B)D9>>QZi z8&IJ4!BEDveVjVv;x~he3pL*iQE?}@Rh2yGuwR`3pbwh#@9xit=`0aTeaBTQ%47t+ zEY$sk(sH$PEeKBzb?*hu)7n+Vu8^aJ*9Y{xd%^yzAre>EiOm zpz|q;C5mKS(V;6CVQw0jyG5h657p9LobPoHzkoD)g`s!9vnPqDSUoT=S&Zap>YCNw zuDU}id~Ro`JFwP&W;o$0G5*JTi|#}}@G(G1$Tdhc zF=%5;>5l1;@^&jmGJ%K_JvMSVLq?WZlV_C&UFxjv{XvP*HC^2{udGw|o_#wP^wUs_ zyPaoAI7>~VUsrDN_lOt@YVavid1WoH*B*fP@8uL}-wW0nvOZhEGbC!x(uRC3HbDL3 z;3eQ7_$q$^ojgHYWDl+J)5^vSm$H)w2=VNZ?5cA>JkO#p0M`0GE-D?bsxLUR9F+zY z|FHzc1UYu|6pOUS;y|~q9k1$fG>hM^(KOx(t@B@e)>ec2O%OJ?8hAUw&dEmB3*s*4 zd8}`^{0^Cq^*mW;q2iudWD80>wLSqyV{d=1K>fS#d2JGue51lPW5hDgnCO0{3VMcM zuk&U^HkD#n`{~uCgFe&m3>Bc)SBIaeq^Rhch2MjKzQO29>#Aw+33hlBMz|ST8;!mh z`8^A*4CH}ci$q!aJ%n;FA5^*L{g4X+f_ut;U@iyMPeZUpG3vqYU~Q zLSS6s-}4H4*`KA0lS=LUJ15t!HblB3XSS#QE(($SGO%vj5{L7P^;yN*c^99$4}{1% zOcotEWRd>O@m2@gJ4MYP!b{;{>WTh^xMIk$A{W1Uj7L*T-i!p>=zq?`U;mG(AXw_h zj-Swj7$oOL12=1VTA!Eo0pZ#^X{*w&#|D+t7pm-IBr-O764)ddsw# z0dV2XG#xz?vbsSyFkP^CNRFDp$AVnarGJ*sF>79s(^d_JILNcTDI#QLEL5QJ)La2dA z5?}xUh0tpfDN-Z>2@yi(p1JQ`_kO#TEszDV+>d&QAE$aCO2>A<{is^HqW8Zvb-#6s}rNIpWN;5XeL4|^~e2{TBk*G2f zzp2A#|6%q+xr5_MI^;bTSU7p3!N@UKvr~%B(sV!THG7{{!w$O4z8lVf(YBD1jL9yB zXwR1g;8kyaWCGNC>HUV;KH3Y zJcF_~BF8FrQkl0T3-=946pr5Pfp&|k_tVyG0Bhd)aQiF2C)__PwDE%(*?0}**lXWl zRgHD5pm2u(Ts?uUAVf}E0{Iv2Z1o%kAqQ@D%S@cj!EhqjQcO2`0Xg)Kj=kZKhT|^k zXfojgPaiC8Nx%?R;cCgM@jy8<3*w`!Pp!A+yG-p%F3#$BkLTOjOH~4f{B@sZ5;sZEC)!UUUVZrb&G!HSkk(@NnkN!2>YN9 zA`u)3$hPLJX#%ddJiM)#JE?>x=*+^F1lE<%XvStg>=$D>_@dqwd;&g@b`hzHI=2ba zPo)bg_dDi$yzz}*wDH6^6RWFI`r;f$p4#Bt4Oe7MES8P?z?3rye&R-$w z-5c*+;pmVC#xTQo>LrwhE;;nxRjSsZCz$DEMz|2N=~LebE}*fOJLMqO}!P zW99s8xy$a}(AKCOdod|RAAO$PP8KOIqLh)~-D>?~pBkf9Y`Z16!jmo`E}u&!M`AJxCeEEO7G$4d2GY;G>#E>bvCEbr(>W|8 zLwDPSt||1*bt+jKbuy4^$j1B?&^jB#F1KOSOvCfd@Nwev!dv(^eIYKLWg!ZIf7WytGRu!Yb?l=R5=Z&1#$azsgl16{v@> zm#|+50qB|CktLR82Vi;uhCyYprtUY@-;kPSPP@Rv|htwbYfyy9=8|u^R zOl+7E+Y*dhtlya!bSiGZSb5W61jF2XAZHUW|rqLV)pvX@$3H&oH^b z3^)bGhg4y!2>d62B`3!2Vwlj(Qn`X0r_VovADi(`;*ETmrvP{rOkh*!O!Hys@3X<% z6BrC-+?8}B?va6gz1%oGYxRRER_>KkrD4@O%;ST(-NWU&NlAqta?RGTK<dmEjcz=Pl@bV5njqx7YuSxzoJ%6X=6(;i|tumrBXi`i2F1&h6Im?kfnB!m;s>V1dYsqGaR^fZE|<;n0pB=NMJ6 zpZ9Qu#&m{54(yno@3D(;6j8j+UzA-=ezxmpAk{r#Q^%85$P~29u33d2>N#yyJJ_JL zfgM9yE>?+nJ(BtzCuRRNe$CI+%Bp{ov2-dNCcZcN>i|=7LwnN>5La(2c`+DO5Fcy{ zc>*I{+NV=RsjsYVDz~!9rS9CeE@q;DJ86rEMO!kvftBRx7t9fCH1@g$6)cVTjXiv% z2qd|eI?O*4X4nYxKOb2op6Y}Z}2R)>H_IPQ!+ut6Il z#7=EY0BSs0&zC#?Va2^Ea>ZuO(p%MazSZo<^Yd^S8cN76A*ei)F(bdWW5JV9Q)t0g zlAot!Uv?+s$ymCt6xHjZ`m-Y6TrLsZWX%yjwS4d*lmj}7n+FbyPmrqY=kA%Rs)W;k zK(d_RCE#?YajX_G1jL)Ow`oFir|gcaUukR;t#yEDIUpe9NKwk8rO9SSn6CGzwXGqE zoJWC2_dn!YCWhyPmtGNgz30(PJIfV)c5pm;Y$=|&x2!C3ZxGT`t*B6O587(Xq z^&*W>39t*sI-G|DDocq8P#~@BK?>GIO zGqB8}0Q*mIm@pUOvh5%q8bugjgL3Z3_x!a63#B@XZD zMJPzWE{qge13*ld*LD_kK1VI zpB5%veb1O9asiJ=;M1hbU~PYfyUPsu_v@y6)gcm>oWAMRf1!oI=Vq+=EqFna>m_^- zYP0=!XD153xTwk_{yA}SJW-Lzd%IPIeV*l#`*mU7JC*D-)b3N>xmsrYY%ZsO{2gVL zw_1GZ|0Lu7|ILz_C_qyz`78SpgXGREmR4U%6Y|3gb8WD#p`24A7J}@1#o%OI@rkJ~&<#kyNp-fl|E9RU(TwZ$od?+)0oN z$g3oVS9#_tnu=l#QtKd(*cOa&mS8jcIfkuEpW=w8?of>yQhucbH*l^nT85}oTV2aV zJHqhxeUI4QsZ+G9Z7;?+4b=~p+jOm4;MP?KphPveO6vx|FI7jh3O;Uw8`q5D!Hsh} zuhVx#uH`yPocz=2?++7FeF+Nrlp4F4;dWh>y`<(m*VK?G`4wBc;uRfLTi7 zT>lioyQ#TzvpB zA(oDilRAFA51xhCFjmlsKT1R`IsxT6cs7Yl5EAJ(w^Sq@p6@V1PjewEG=!s5k=@9R z^iIXPR4iYB*q+j(aJ|3B-?cxiT;6c3Wqj8%A1^LX2*sFr|G2-CwC?L-rKpI_{Ipvr zS&H(9U1>OfRw3491mg*1yql<|6tB77%&uI~h@@aptx>2MEUTX#O*OjWa9lwM7-e5Y zZ=r-(am_IpRx1ygkXj0E%3qw-?kq4TFh|KtGuOY=E&AkaP3GihStQHbdT#!5L!N+j zJp9iS&=pA^#0{%*8|XeJxoGu!74>sxL_v+(oB`RIAFAaaF%HCbsht&ayE~E~ExX-UT#S}?Y6@^wOyHhi zLwdlH+>_jin}n9oEro_nt_<6^0iNT~#*T|-dIJb0xh_;F6?Mv-E?`Yp&CzwX9S%xyy(G>8xsG$Wuz>C+AVtA7)-^nQW#=Xd{DsmY151SJIY_BpIUiN}K zB((2jRRQ>CK~=cZG)iQ47pAr_h5bCunCEfcb@xy)hKF>nR@*&?e)`kHs7-p>#p2CEwu~hFj;grx83d5j;Voq#}1v4Bw#7| zftz*_aB(vv5{xfxLQWF^o&U5MeW@36f&*b=soO#pOz}=1Mr*&ZDlAn_a18KdXV^4v z%K%S<-&mC+$V9zpMuFfk_qMppdwr#nz?!qjJb%2;_{^6mBQQgDGeP;uM1(9>%JS*w zzR9pEWu=i~6-r5v5i~@%pvyG;xs!SO-A*j%_+?J`L{OrXu85arGHI>-Djz&u;)cD7 z_q9k*kF1y3wiyO(K|{RB;gva6TRvjNWqO02QAfhS<>DH)BIuF?@6eR|e6+N&G#pEY zNExdD8rA&I_=~g*%?B+6CN>3UohqlCMT^{9U>6Wms@Z9MKx*>i52VV?S*PU41vkgf z&BuKG{YYtiCzB_kX`oTE_N@9>HvXc^!>}KZ8Ltm*9*{;Zgxg>=+|11t2kZR*Wf``r z#xjvW7jo8xi(84#Q_~2wjl4EfdN&=2-w;hV%EI;N+oxCG;Vbr0ly@$J96bL?Vd|?r8LGSN#q%@2j2XP?F)}sCfgg!|8(mBM*vqeHFI-#i$P`5Js z&p?CxJesq1h7dFLXXij09h8RQOO;e3@h10LDVvI9UdFl0R@EttEXswk_I*O`8|n4l z)ls%STsxILMr+`2Y`?0Q*RM^DfjdL}bu5Hscn$$jqskA)&A^w|jcoi{D3RGRf|7>t7vrU=xwm zL?BHFtDs~BWC^u|=i29Zj9cE|tdc+1C6FIon@)X-feE?R@lk-3+NjE5V%^Qs>Ia4X z?~pL$H2S^M_DLp~E||pJVFfTpNtXOHjX&t2GfOl=f+D-bn1BH$KX^9jNOKc;i_$I4 zp1MnE4&{Y&$9s`tl;))rImIuAfs7imu|(5&)bEqC^+mKg@$bP_s!Iv9?-y#wk?)(m z)C{Y<*S)?uVv~W0TCCx9GO@(fp>n)-Mal%EQa20!ROfl|u-(}APbegmke@hZFI z$O_eS2PuM3U}p8AQ(%k-X#zq}cJy)`KnGPt2_lEkr_>|Mk5e$_u@T-C4av>h&$zx_ z?a9u5teqQ6utoP-H#7eEd9zShF%7{_RXfYqqA8KluaiU?#Q91MDjz9DP@qM$Kca?&_`%=ra>k@uhlzEQQO)s9DF=|16ra)Oih=sb|_GH z9*_4`w#e7L%=TfHbNMD{;6$(>-W+hf&2`>kG?0ZZz-5T8YZ-X;O61>5XL0{p_|+yN zFB%__J>{C>jMs?In_T^7@l%CBOvc|DKKFD7O>Ry^B7UK6OuHMI)0mN}6J^jSf1G}` zgYUV)FemcWpYkikV4v@!rDSEexx%bgOJw~MI~ehalAA}bKpoR_yT?3 z;LFQ8s8%(_eF~o)6Sy?Pi2`0eEq-Hh@BY>2zvehU`dL117<$CF@nB}*+BeX`!3#(L zz&9i(r4IyOK=`gGp7yp|-_IG)Ilm?Ws%|P1?{G77jZuGY{bj=gjJfNEfxVy()vZ}4 z%dhw}*)QJ9TiWf&cWl+QD`p&UKzp>>QX}@n(Y1e9XDIKiM6fhcjBQO^JU5Am17aPA zNXD0$BL%e_ZFZ7ZHNUkKJBek+{>w0s2EZnCo0y7;91AKMv;bG_CkXHVb3!N}M$|HV z*~8>sdzRD7z1qzl{H7|Ie(4o$Qsdn(+TpVKd1@wQt~#<>Vh)mnmUcDJ$ai#}A*Gx1 zAz9OUu|UY^$cK3>IGy#zuql;24?6c~?Jkx6dfCUE^3lF;5a9FmI*_Ky(nxoj%B6o) zW2{0d0*L56bq3vYtcdmQH~|s_Nm8%!N1yruJmB&N0E*>rcEaPz)&q?_mhH}47WFqbMkMyuW6I{2 z!xnyFMSZ8-jW4<191E+rM|n(fpifh}h8{oM-~V*K8+1D2yCL<{Maf>;^}(MMWjhR? zSQRmH-4P3ZlIz+#bmQZbJe8WK22n~=SY{F(oEo%op(DmAxM zRPucvR#)>rc@zfv&w!fsi4*2V%21nlAAKE3qK0j5Nx5XN$DrkUwrk6edzHN-Ht}{( zb8~G|Lo5eogxQyvsw@_}%KONiy~BD7>`#ROW-*hhIg>;z9PJrBxyT9V zVs>XxfqHd7E4W@I?i#9jFLebZXC|TgnnqA^XKx<`7%s*dLS3D?6u`k zeoj~p5pb8D-#L{+=T*BZjzbvp2qY&c7=&DR$-G)_Zi6+Sv0p*p^YrVaTH(fSgn789 z3+k8UONI-W!qw)LOtLL2EMn;TmOAfbm7#+_R0Lz1Cuv{f0@Vr#FZSZgj?Y8`dzdDt ze!?7zw$r-7M%1zCD{Taj*#cEk8<-{l~ub1vbsYiDs6jV=WmdjZNg}|Hv7EUm+HXwZ+u) zwL}#zX5Nx9&;YkJ@LQ$(*xC`aU4v(}R$F&|&Gohd^PI0C3rSYA)$kPe|G|FJBBM3* zG)R;*bglo1%M+ar$xqKzimSc+$DKFqtL(~^hTH70ib-E>^AKir9Kh}RA_6&$)L_41 zyrfTU2Qw5|mzbkl^dr6XCBVZ*gZu$R*uaE2I#g>gyMSCpwFp-9VAs?memhRY%PeOE z_IL`7{qP9k?FMfaE+$b4Aa{7mHphb|v&46|25v`&UFq{wH%n_|BgEY-t_`?*z&moQ zNHVtgK+|G(5v*edG&H~XE#{1FK(-^k0o=wI>e&J(MSR+v`sDB1R@<{2mj|6bx9t7G zSuv$DPcJU;;&e~y*V0>1`(b_t9dGp?{L7O zm44s9c>U=kC+XvSZ&lXjHJ!;mEGYi4(VWLyvl;y$s;i>>>OLz|v~#s7Jr`ZoJB z>@?`(DGPs-)DJA2*W}b`-yGKLY7&S(6sF$k28L;-uCN8~;CwA%`cmw1{;Tycb|?Lx z6TM3*=reO%nN}|EzkX^y_D_Zo5iE(|X8^&@e{j{!7^C#ojAlr3Ou-8rkhcf4brhCC z0SN}?1b=P@CmCqG{A)HqPKNz#b~NenL_NZz&M%`OkgL)0v-ASZUGelP`_l@eJ}}`U zy`pi?VMXQ7k7jSoJ0eOH?20^1H`$PR8pb{(Xs@%a|_IQCfvKmzx%^ zuU;>^Q>$d?DOY-Vlh*)u@%fgIL3m-py*_MHywDByz|m#yFpOafK4a2wZ%G8nA9x5$ z!x7GNd;up>^Cl!=Nu(ZO_ja`6HZ3b2);t;?qCNAK39!%vQ17M}{9;1WQ7v2eTd`p} zz@ggWUqg)Ub$HUD@>hgvzxK6gu82+U+Bv9RE#!lP?Lo!*)XNNKmG`;(g`Qt32+;Q`}2y_Qh9yvO4v{73plZbR0fs;T{knSh6>3P!1oR4{w{3yDTs z1Akd9AOY%6XS7V6~_ce{w(uYU^ z$2{$gnUMnAkdg)XPVw6n-Z4xv@j+4Kib{Y(JN;^nD)$dZ)D#^x3bQL1!u|~UpQs3M zf-B_XIwy+J#L8ed`RgVGb>CbE9Ip?o=W1AEjHPr$K!-fu7y@~q~^&$ zQN*uPmt8OhsI+bnJk6>kKkzB;Sd02Da?k1_=}Uvsam0!421f~e@g-%u^w#GY27lHh zrY%xLpRd{$Ff}td*FSjPAg{K?xWCr;wZ#2?yWI+=@PU2Rs+jcA^%`EUh`ZpgpMvp< zpZ#WS|CO;?O7j;{dSsSu zW^YUSAvK~+R~~_0c=0s1Vl4d;?rF|5bA_7F$4FJH5@-{U>$B!qXKpI?Z9Kl(zDoa= z>4kXF+_kH~CyRnBUa?{Sw#Y-Q(BoR}jc*+q7^dmS8q1ljPMgNx1^>*#NTW!4sV4Xqwyzcuhn%*q<7rL)VI4e*iBZ=#nba}#k<+Tc6%Jt zIKZjeYvueJU&CWF@Su$Eb**V|GFDM?(AnL{V8XlLb8$4);C*_yLz#~RR2cB?NB4vY zi7*n)orKNQih=1_&jiWv*$v_Np{I*tgYP3t)GT$gKGjge^5AI~6KiaXzl{O^^x+yv zWwBwBX*>u<&2i_R#k?=#3IjBM)(lfD9KA5CyR}^hKYJ@d@hhM&UaVt$rw0lZiQYb+ zdQRlBoa*{y43;BXV^AmKVeYg07iRr^)U~}M8vej+t>F)>C8RDKc4~Q{VZiuGd0Kv# z{?kJJ+{jt(*l1K#%L01an~ddu0AUo!dvM}Ohmpk&Vbs`>)(Q0^s4F>5+s z{nC|_ygGsUl?MY&uj_Y&5(*Z}GIGYpb}%EM`xb%|RZR3*d-Od#GVnG;$I#I-sa(^{ zmH%iU01}0;#gMYbvT1yew z=bW6?NE##b^QKO(ef0BT#kPa+wA1exk^q>oRW!BN>zeb%b+S)%f-A+}G*=5Av+tU5 z_A#o*Rs%0o4;&Ux7+>WWQ<~2*G%}bfnyHJRNyK$^+7}Hxgo=7W0Cns5AGV}jEq(8% zfSd0={ho5EP~m}3w(tg)&B(Sg)~>@TgqT>MR`Pq1+4{p+@on~nh?>24OV zn4|J0qT=g^dQ-YRs}IN~a*XC(j*qN6cK@|w4f^p z<(Vzuvea^}C6 zD<^t%AE5DzMeI}8=u0J=3D_=hp%&G)Z?Y8T28d!B)4jbYz z7P&dh)5pqL@_)4Q7SDjun}PGcvgMrTc3>5);E zwPN3>#;3;Dv(5p|9nC6OXohpUvO{+G%Xj5Fv3}-zU&3v}t0V_Z9pAH4mQ%Pw?3X0Z zi%jd6cqbtuYTAwU5YM#20o1qyvPGBZed}2_)+?rE$y!nrcos{(u)%T_e^m>I^c=WO zww80iEjOPb<(P!zeNrv_)^A@BSE%5`7NH--s@YUVu6S@ti6KG#<5*=Q=)K5;Rq~)n ze3MkHr}OSOzFl^XweM>%JEKd7Cy-rAb)}4@NYv`JVh8jD34d@hzYha_^UMZX0T@VX za=A6qdH%HU@G_wWJ)-8xm+4AYwspy5TouD@8A6KVp@t^nMNy0cE+6E`^;?U#^F)K8 zTOD!)-Lii`ToT>%RGNws0M7(i5n%u6#`y-lVO2^l^EJm(x@~Yeb$F=Ma@XKOYH*+S^8BM_ zi)XRyEr~Hj{m4b9{BEHEKO2mR`aqa|qV-E`Jkd5agO3l}QtG2@haD1($tjb$J11bN zBidukha3mL*Zf%1xxKMdV0owE$Z9#|?;%~~X|u(YuID#N&3w$P7*mC3cI zEh_en|NZ`_ph@;*-B3LFPKyM;%5-Gc)BtoMDs3g>DpkW*QOVf%%0cZ--}GfJ-(Vo~ ztPEsyulTCdOYS(PfEu`_pAa2)!gU8lOjToK%6`5K*rm_epVlheK~2%jpnz1>o~TDAg76<`m&$1Ug0bj3~uq4 z`1UP{AykS(+>Mu))t5s`IUxHt+6WR8ri$Qm~0@lnk0v<9?z^OIhjDl$5-~>T?6Us;w6H zux26~lvLY;Dt&W`qb2lE&O8_}>NZi=w(`V_mNiAWf1?==OEaz1M6`Gp)7thpXa5_J z&?!A?o4Nsv%dW5&FlU1?pjNPf&9Mwt%prKPCRvCLV2=wMc39YCrb5Exu^C|;83in?_m4F+EUaU2_}1< zdtx&jF6-2T@W>i$d!cU4lhk09VR-slbGbC!y@uaOfDd9f)Yz;%Mzkrj6UwM)q)?&N zol&p?=#oe?OEg()>C?rgvOtsn6}!? zX75+tbVEz&Yvhr)xvDw_Vw2L5xyrF}G1)AFbMe<=|5%j(%_2sFDB?e8krn5ltmNIS z8fLzkWB#d&E-TYPkO`)wYhL;5Da>oTzR4=jQe%qiQ28GuuSzF)>XLh(n}A;I5=Tt4 zS9ek1ID@Mf=;~1v&{5j~PU76ESm*bx3{a=lx%GMKFs5Gq7(FYXYo18AqY$V!x~GCU z>c>T1r>A1FScK`nGQI-och(|Phu!8`l?B>e#h1=K9rPTFQnia$uI$mbnAKNuRoN*r zSw`r6?AM~Zr|}z<_Ms-bR$DAA~WAKE0*(FmaK#*CQ@>mhA>CYy>wyKA&BwXq67ZHnFQ@VA1QW@KaSrZ49^EHUw;KS!LIAT7y5AVo+qf!Jrf8CeE>S+!L`n`Ko| z?CReh7Y9N^Ds0+LO zNi+%V61^uPWXH0L`hf-aQL+KR*8;G=dI(uEfK{o~{I>!Y zy${wT0j$9U0oTYdbB>r3aO1XmekW~b`Xzm>_gIFNRN8ORO+gc39|+sLe|;1GaM?K^ zeD*jr!O&!DW3ryQ^=*NsGG^Pg`#st#T*uwMxbF5?Syoaz&;t6K>eh&J`TIsd(UWIO z&Y4~>h2-bM^t&C*QW~3U90&dOAkQw0Hillzw$BMY?$(!R*F7@?oa{slb*q7)vbCWD zeJ8;Yd2@<$@rakB#k>L_^?<5CTCn#oy?R{5RfHoC7p*~TMJV%HOGlO!8@z0hyvmqL zZTJy3)qRs0vo!4=lh>8_duZT+tfc|o!L?gNC*bqnVNH?Yps>BKHE(EtjaQlG{e}sW z1K*=mi67&94Z>UBuNLfCxuuj*pYfk8vObg4$6O7(?R}kd(+g@>Mr?P0n|r-)OIOX) zH{7}C0~3IjhZDU#^oPxX?--X4~m8`Ui9&AlsQUII zNO|NzG1!c^x9V=q`nV-{1jP|MqP7D1q{pz|k^1A2GLpER>7hR9wTviDA@-9o3pWoZ zRsev2(xsw$VM$|fCz5oa+J!{~h@DZ-xvOhnS`ets&ln<4=}v~-DHWM~XsNhorA%}j zXaspd1>ae?)|v5zwKflh>lNQr6#O=B*=i_v)nVan_94!tQ`zXt(H#lW?t5bU@Lhn%^#WoF7vO@WAhg}C;&iyH@KwqzSJrOrUt#-Y0Rj(OE>(~4|hm~hK^CxHKd%j^#{e=oh* zLE-qy;l2`B&k};4?OECXw2q4NH%b>TW1ls-NS-=#TftGb@nkM~lwj66+P~4m^V_ppmV^%`kv8A_KG8-8|LPu7 zHv3^->BS{TL1!VSA-*Z7|74*TgMHrts;w1eA1)TmJ67cf9VS-zN)Eed`k#@STUc#L z+T{4=_`J!tNg>n2A~zphv-dI7i5)3%wH(xiVw8!tFS{1>+wE2l+M{t0NWHLkTge44 zTYno7Df#TM6JN9AEK&EyLhQc{bhh6S=-%$V`C}Z}zq{aEIZ-89W2&Pl*80KL zUp;EBUBKn_gMaO}$jd;vu+!NN?1eQ05Vua&!>K5@Bf{@!IgU58evfWOx>xVh_?fGC z7nnm!`=;P8zGV*v>(}Xc1QH!x=j&pt*%~_!Q0Lg#pqq=TUvxSx;Og`#b&RzHdIc_f zKdxS+%WS*yCPk%ktWH5{x2^pSGc7DM+p#&vRSp+3@wD_b-RjcN%6`zATG=0ouuQ0q z%0q5@N|}kUZM>>VuK!e?N>02MA9_+L0&1^fm$PaN#2Vp2R3Q;mk4a>#5sD-&{vM0q zIZor4Fm;!|zpC_q_S_Xr8ci-BfFjX6U>SI*Nxt})8pj&Tw!5E1nic;LRME{?d=*ve z%ti)Z7eIMfno$j(4c|ET#5t%?vO0IS?bvi$1<}0D-4$K!h_|okqP)di{VV&y%Duy# z@@Gzf?8iZsdA{*;RmrM;qCw(~>ov-gy^ffqnqfe9;iF@zKTN6H%9Xp^pzdx`V|yVN zRbtInli)~LbNQ+Ov!7QN1JYwX`(fuJQc6yd=~%25WGsXnoy{Q5d@FdXs$}Olg%k@Y z9E{e=e)k(i+@)h=S1xe*y4p+S-X6TE=&W9)IZQa!6*pnpZ0BjU`8PMIBp}rm>MCD2 zX4GYvHM}z;!R3oSdXAidHHW^`7Mg8kB{9L<{L7ud_>@Ej*e?JVoO6Z_dwJmb>$qm5 z>h={6KqMaMDcZqytKD=}SSYshGpMhl^3NUfR^X-Y_GWKLY({LZMr*hfEGsyjO2`zc zt$x};QE|k&{fAQw(qt-h&z# zdn>x)1&GntS^i4+oVopfx;^jatl+{mq8c0P6!css^PsaM=H|1tt3}U4wmpm-N-%BVuO1Z*g6inml~%#@=bASFW#NwtcPAZy+X1e-Ux;mg!f+ zrf0h66?Gie6(NT815p1#<67QeIPz>Sdc$leHSx_mHb3hRHiSBWH)9;ofLM4 ziwkwzFOA=X*UgxK`jZV6s^$HIX^>yoxtnr)Ov~&vArU|6x<8MM;zDH~N1OT+f0o=w zdL)qT%m1hXMg?{cYOHD>&inG^{!|n%92>J3azyGc1Kq+JTTqMo>8hx1|5(pz^gA$b zW)J?ijfYGzRTE+5J~*@<9(8LxNx{!9BOt)AdE<^c_ABJQZgNyI!5>hj!iaE<-d0jp z0vd-+zRHeR-gFDJ@Q~>7XUgr7fxDWKl~lLAocwLpxQaGx_0I{XmnI2)S>@(Y>h($9 z@1|b`7^8Z&94`|D?8;qn&}PPb?z-vIr>qBvgLpT5d)(j6MgF&NzRJ2Ru(^Bd$#_~i z`eGt+tSoK#n&g{RP!(3{(b`LwC|T`I)!o6!$`SiqihZ%Zx1z#1CEyhLqMg0dixMC_ z$`WA@^|&_qmCAoM)4)g{@GonRsONq1(IN0#k9MnZ**X| zPuzJ;Z&YZ6S432>?hG>{Aose;1fXXK?_JrxWeO8Ch|kZqgv2P%)EJeF`*DC0Ixi@p zMXwbXmAUIgnjE@u7^U29C6N%61HSXt4y$CPJ_Z2l9_0G+X!t>I*km67X(e$9)!aVV z354^2JohR<1QL*-^N>AazSC$2j!Zx-n9}l|-PA9qIk{86Qb^mhn~GX6U0vyk!oA0d zcQ_V=dRI(4JI^7I_JnCAi)e?ema40Bxf>G)8&;MZE6R}UW{0=gu-HDk9NPV{q)ur` zSu@JDNUw8tn53R%`c~L<%!7DuNn#%4*-fY5LE8}9T=Z&pd@Jlrs$$=;k`7)hQts%= zU)x<2?4@1PM+*({JB&p!rI6wupf@t^8}4pQU`@lTr0xb3y{g%A&3}T!h(8h>UDHQGBE` z+heOX_KLC#4C24^^YtGm5%aO}ebk4!VQjS_P$F^M+%@l9+lcl!yCN5RwSB&@E9Zkb z3hk+aJklR%g4R*`*AS|tpY{GJIU#U7N%#*e-}IY4&Y!t-Xkl2nbYy`#{q%g%v2;Tv zMC-p!?!O^y^*7hKf6IxDfBjjz4{*4bjq=NQ?snj;Mdp`kHAsRNJZ4;ncdx&{R-OIe zLn{fMq->JZAQ4D!Oj$4VhuSt-YEO*C)Qv#`7$Pd}(bbds;-N~N&EqV4dgMeQ;zRb& zrO3kL{Nq3Czx%R%81#`+bL0dg=cCi}GjrjEYh2+4iG%O`YLAT(?LnNmk%&HHJGp|1 zu!ibpyN$QmW5>-#9K)64y4R*V`OfJU+3WKGqXlCN>cMI)_YM#7IaB|uGc*u7@8Y^) zFj0c}>KTRqa3^GddNGp8u~3Jrxzu4j4-d^$k@WmyX^3gFx+s*vEed_-H+jvUr6n+Q`ee7itibNj zm8K!X(LcKVE3zH=%8C;txeq^Su|Exg>?AVD_GH@CtquFYd%fMxceHF0^ngnjqf4r` yysaPIbZ^!8xZ-T!Y)BBW=1+XlfdxWf<=e6P1A|d2(4j(%IrQlVe952x%=`~XN*==i literal 0 HcmV?d00001 diff --git a/public/shoes.jpg:Zone.Identifier b/public/shoes.jpg:Zone.Identifier new file mode 100644 index 00000000..e69de29b diff --git a/public/tennis.jpg b/public/tennis.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f27932b4d610f39834048c34d7ca081e91400e47 GIT binary patch literal 358703 zcmcdT1zZ$c_p_vefV3!O03xMygCZgzARt{53ld9riHVAU0)l{qbS>R2sECx*(xK#% z((DrcXF=ZcDbMfw-qZj2!Q3-vPTiOr=ib>b-CsTe3ev9TrU0Oz0Gt5;-~a%*{T#po zF&6OuDEJRtvWG%#%`F+FY+$yA)^3cdoL4v*IT&4BTsTd4A8{Jnz%ZP^msvpa>J1x5 z8;2V;cC=TKxxlEYrOk-n47zy`zyrFV-UX!;#Mw>wixfVCEpc4&oFrsG$P@;2grx9ihfIK>RF-AF{uuA_d~2U_Bl(`vy1q26u$If_?&k zl#Q*My}8*9N5<2}tc>S`gajEcLtU((j*c8x4UH`g?M?P-8~}FnjFAG!FlEaK7Bc@i zA%1=iZcecH|A3!9{DbS~2&Qg#IhK@n>I_2F_$Td8**|GEaR4B=0+!8_KWRqc08n%f z0FLzjNjnt_03>$-ps?ke{7_-q%MC|ITVXCPOp`W;8gpU_^bh!t41aL`J@Sn`PK>=j z%8v0O)YQ<)%8?OMsKz!{Hcs}84z`BIQ1Au&t`YxZ!EfC9#t(KCs43JQY7LrF2V0rB zwHa95)+XkT<~G)h=GK2#!~an18y_&}Zo38%@`P=G!hjPv+(H3h&o%-$t8Ndf#5BcgSiv8Aw;u(h#GvF)+Fu^(ZFV#i@;VwYmqVYg!sW6xltaPV-*aTswpa71t} z}EUqT58LkWNecVvoB-{er zH@Ka+W4Nn$cz9HJEO-KVm+`dlEbu(=9^*yfW#Luhwc?H7t>EM1)8Mn=i{UHb8{#|S z-^UNf&%m$3Z^IwMUq3*2fZ+i5flCLp4_F_#eIWEe+JVXgZ3iX}Y#cm%km;cCL8XHx z2i*<^9!xk`da&i-*uf0~QUVqNF@kFZ76i8lo)cseydmf(SRy1OJV7W#s7z>1=tKCN zFq`ll;YUK$A+kef4oMx-J>+yK;860R>O(z;mWYUmn298bw22&v0*F$HYKaDk)``i9 zIf-S7O^9z2M-mqjw-L{g93){PIZvWb;!YAul1I`)GIRLgVdle9hYb&VAC5d+a=7d8 z3Mo11IZ`E380lluG}3y~NiuvgW-@6q6SBKx@np4RBjniRC&{JAjmhtjCy>7(AEUsd zV4;wuu%PgxfKxP6e5NF$te_mG!lq)TlBKeu3Z%-VLQtWp>8Q_BL#ZE9 zXHvIOuN^sdMDhsq$fF}!M>>z7X&7mwX)I};(iG7Q9K|_$=BV;fm!r`~-yEGeMsZB! znDMbk$8wML(qhq`p;e*vppB<(q+Ow-r<0+xr3LTCvKm}Ix%pP;H2P5(~}`5 zYfgSX#c)dDl;^4RQ@u*6Q*LOL8g;tVrIc+$Qu$jLT}8NOPNQQFIZf*h_P6+RI*IA{9>hH zl?6KhyACU{CbPD*er-c<<7(4t%VvAucGynX?wQ?ZdwKgL2Z)27L$M7%o_bENaSi@HmmE2*osYops4w});M?w8yXJ#ajXJ!(9Ud*1T==yl%fr8mUe$h+p| z$(wg?j`_&=q}(F7WqGUV_SxG(x0ml|+$p_Fch~3c$UT{R>Gz56+u!f<74eOEfb+oo zLGweNhv5&mADKLQ?|0TO)Nk{#@#FXY=lq}he+e)RXb$8LjDCXm#QF*1sl?NiAkrZB zppjsO;KC5bkVhfQ&kUZ`hw_HTgb{=}g$+Ny^1L|wRQQwd&4?QjoskzJvtH1?c=%#1 z$|R~SS~5B_hAzf01|4f2+x=4JWnmn1TxdLAymS0`f_g$-qF`cb($OTpq^)G@Osi|qSX@Tij=}zg$4BdX1 z{)+xJt}-V44jYT$1uY~*V! zXyR)sXy$J&Y!PTF{vhWI6H@^23zQ)Y!D`^v2BnS<=}TbEoI>=OyPGKWly-Td-gFviNw3W+{1@ce!Te z>dN3MY;|Mp(K^j~3Q7=Fht@z(Y`ARVZ$95*-74Ld-|qhc`|{<>9B}-+iH#8yFp&i3 z0uXHAFg6zU?$QJ^IRN2HA8;4I!UD%$Y#b~s99$f199%qH5bzFwV;MgF0m6ej01i4k zaA-e(U}IzB!Cfshk%Y@;~c~y0I3jMaO$!51e^;)K>zXZ4;(xUfXgmy2p*Ul zEC>$B1wg>u;o^~!;gcU`JS%zpz}0iy6xVG}@KE}kcmEerkbiDJGU9%%m7* ztOK}*hz{c6VB-UXpeR6w3pqi`eL=;Z{3PDt<3_hBKrQELcvKzkoT9|PdS2Pk?p9D- zZkv>G@O9hI@pea~I#e6<#HK2a)=uUaL~f%lRg(zjBdx- z^W330g}W#f-~LH8Z;A3r?Fg@NaCWuBmtNoySXx-5*rZ^o^n1?7{8>1EVqAWYZ?UCz z_F81LotKu|p^xR}4M~UPM_p1_M43BD{>l6QfeCKrx$a{J;&~xQ*3xL2UNK$YJoO`d zhvgI;me`g%i?7W2%29;AdLOahNFtVCAKX_x!O#`X=MnMD0W6lC$?tSAJlNdL!B(Y@ zQyt8OWzAud`-=T0B6eVdfX{xqv5K_e>OG_d=otQBQlrgG3=c$GnTe?>^HR?W4a(c3 zdOxw>MT69hMgEOJI*;M5M;1;=3euTRHwQ2aAprZCp5M@@)r4wxsjPjk%9Ia=`2PfU zDAUjTo5JrzDC^LjTd_;<8She-#4ur{8Jr5cfzGI3ifh<-yua9Qq5h;i!2p-+t*YkCsBnvnIUA2p3UqN4;H@K2Zg6S+G(}F#jhWf{_T4NauW1i5LASDr|~}T+%0k) zY03(ISng_8YUJt0hD6C9wEZr^&x#YkS}!#%Hb_RijZfBm)Vk9^=_2%Uz3A27JJGBW zn#*G1ivK@=&k$j0p>A-B+Xh^o_~ zzgO2w5~Bm+WohI(I65n#9CkDMI)?K90Ds%Xf3;0~_jzfnf_mvd+OWz1y*JLlBBFn_ zNx<5ZqHt425&+l}-)hg)X+6u?X!12GPzfoG{eN&8H1YQx>5hGfjV3zL zT5p#5mVdBVi3M;P^mRPOKkLk(UoL?TvdKfm-s<-{_6WVL(bk1i6iWU~)vtQ?pPC2> zZ%$bjQ}j~{cw&J*0D(C)ELT1@^<44F3>%LH8+u{NsI0_1Q?FvAp-U6{lV9c5PxXu} zHVyxT0j_WIY5+xP6OZ9xibTyzC8O$czzr90(4FPzljwlXh_8tR^{UAEU^sp={JcK{ z@JgggH&@@xipkGn98q(wk$q(&ZgATRGm(WH&DG#-47Nhglo&umf3u@I>VMvXac{7q zHtJTRG&8$*+Br@G3rlv#67s&c1aoHmr_0r#4szl_g{*03n)}zLR6_nAy5pahFGP)R zJTkDkk-l38e8s>Lb@Tf41T7!7Bo5^g#}MGlqlJ2bNYkExK+XxzY7FW3!ha}XOS90c z?hGOP=mP-3d3RTe5?Ci#)QRQ{eBsf-W1g*yql?2B2MG*v=X$Lpgviw3%3b@t zUW3~IX8rZmE&)PRC5>8o*%1rTGDV+tzvd6;dPCLh*^G*4WE5ClS>bV9;73 z7o8Xj2u?#|BqHv3F^t&)l%@Up#icpkq2!jGyDKqlriLm@;m7q=mfWbz4^wygiC>(J zZ`A#KZbPYaSCwap1;1>i>0Q@MmBI^rk0noc%lytc&UEwMjDlPrKrlV<_VS?45odZb z0IR4s@!BPrcZxz{;PdMkD_9MdUM5WmeHtAz+>J9071u|9bI%t@TSU^;J8*(4WoiJ*DMx+gNp#3M2s|ep6I!i`Q|a z^Bu1O_oxEvSkUd98Mo6St=`&+m^?6OXi38y>k!WA`pg|pAs{8KTr1qUa-(9TxtsIp zW${!-6g=!e=3t|>`gL=p7Rd1X;BV>)tMF3B!xN8DN(twhlwuvT*H+8Dwu;D|Is#*- z3};Gbo(NHtnmPz|$$Z+HslYdU7-a3)b+*q<)VBp){_L$s(Lla>=L(zlH2}Y{aI@xt zM@(dn!Wy>RPLGGj%8ZwyDodi^yBs*)R}C=N=b<&?JV#A^0IV@>_w#cB9W7n#-`D?FR^v28Y-)A^x6a)yX%eDF7cCliy;x~0Pu9nNZEYaua z_cPR)D=>mOjJ8)@v1l6x7|2v{roPary6-w;U^Kw|M&N-UE<2 zrigjJLF8&#=Z+7oCMz*DbN5}IA)cWFKH3yMWzqWNId!DTc1yiqP=EIzPm2wsVhJ%#NoT(u1D47u{&2Of3UV>{Lx-fKPKo* z0FB-9oL8s^GKLKIhO#VGk6izrlLSMgYBqkTib1ZWqDlIgt%e0L-}nhh0J7vHQeJg# zXvFmcu5lt$LVeNuKH_-8XXE;NlD|CNckH3-w?dY+h^Ll(vId=c!|uxNp(N_Ky}4uk z5W-6)wu}M4q%Ho@Qwx5s#Fhl_xEN1z*gc<>N}@9pHI76r775Hr^kxt2zL=fk`0kAE4@_|=;!wA^K?q=v9O6oQ&nwoE#2js*FU+O58&H8{xnBB zBqRs68G<4C&7fHsrEsD7T-2VPU!Lw0zrZSLJ3q1&bY;vdAF?3L^|sbsg8walzjUxf za1nHJee{Co&5j&{m@UU$XPAUg{^?DNgM7V__onR1=@?&#v;;5__l?WRFn)EH;L$5r z#0rlR_VR>j(|z*f9+^^(jQKu$geZH3*wP^46`ps@)~kg8fwsj*)XGlpPR=cgn%#_; zz=#vFo|sK9^iubHn%$tIM)8|w`TJEoo>cNwk~Imk(u2F2*2U=cR?O{>1JvOhb=(Ky zw;1v*ie7jvG?;{8ArI_ilOW_tfo4asG7f6efZ}qLSS26jlR_9aB7arpS#T2vxN z4dIQrB81K07|cwDUp72U@~i4!ob1!FVdXoY47FTpNuNI=Vv}}7Ff(rbQ$R!Y**V_^ zR@paJxh?og$=h0J8JpMLh_Im(&RsrVeWHCVc4xWeo%;x6bk*;UEHXEhXap2fvtbc*D5 znF@kcadJQS|zZ&QxBzwzj{PKIZ^+rJLd8_A=e=4`Y!PuU&Y11cN?ZMDYHnAxq5R= zKBe1p+5VR%%qz%mxA1&6cVh3O7baO&dJbTAL9Xcer8!s}zaQu4gONW2XA3c@FYt2K z?JB^mQ+@;dIF=KnWC)4JR6ZBvN+`*A;W@e_kUT(mo;H!4GPe^^tDD?@bgg#l z*&6KjEaln(`RYBtj?avb%)}&myNyQ12qzX`$m;USS*~Ixe)S%TI`Q+8v>Jx2k%;?) zxka?;?u(W=@G46B2IY~C@)sZT`lpUR?z_p}Z7jz`8jirHij~XgHN!V_RX(3QTExEQL+4a2 zLe9eJ)0P>Tu=+5DNJy;}DbzV;CB9_X4ZoJix!V-Jvj3W7pU&SzxViAg(ib2JW&Doe zT%B>h!{<7eC42)GtdL>|twUvJ`nKI#a_1`XnOs-PdT8|@j^O4xYwA4h^YpTw6Ne=t ze9i)q$5;u8O^jkKPe{AsT@6_JCa3x9Q()JFULYiwY+pj#y@>m>57m))p z>{jNQ+N;>MSaPP_1JkqU(rqd)>}DM+Oe06n4CffrinEY8Dc&}2kM{X#k_ zuw~1$9FKObQ8DIho4cZ6Gg__gm<516M%H7uHAHgQ`KHKn?#l39A!3~hR!ie;Gi))Lt?Ko*#aS!70Yk~Kc+y2!|bv&^qRSs3N$ zz80K}xRlhfv*N`yDXPS?KYMu1N`cxdEF-PdjLJKYriSA=Y`d zN^UfpcNo6gsy^$f0!a+7U{*42H>nwPxHwR1f;SdJ+67#j#GvO9Rm`E-mg`foJ26n) zDV@T=)b}xKsLjx}XTQ7;`0+K6^}JbP)<2QHSSMIp6zxR1W+2>_4<56#V=%a&>)UQ% z`G(zvuwTPx$79^jqh;dc&@G*%$e@15Ab2j#r^>o#fP>5liJn&$B|0>;RUw(4v# z+=R@vp$|OfqdDAkr+QV2b~Ws%fv={h6dyB4T{1UX-RS@Te=W8bX7Ytw-q&Jce)*o; z58WQFahAPk&wQhI(I^z2+ZUB~rviISu~MIoRT9@6nnmrE%C#*Xf3RC?3RrsZbH~u5E&5nOQYqZaa(uod~WM7n}-Y>YScS z$d4%}>wS7*C3k8k<9io%v=l|hRFvcT>+T``ovFa2BkSz^0 z=)7$3kX2TaGBG_v%N-3*@@R7J53Ad->0_Jn0Yfr+uq-Yas#ODt5syj^XxziUxKCNy zRv~h(pjl5nZzu)1+q5ZW4fFz#_N&J6@8=QM|HA(7Z@!=7VioF$pt=x6Rz#Dp*TkJj zT)qGTZ9zW3q|q#IOMR7MX`!i)IIQY4_(>KBkfl>%WoHXxy1xLtoHXvjnAej_P>l)ZILsM`_!=AwD(ZRevK!>OOyE>c1!-_YnWv#Q%2KhzS6}$*bp}RM9w|1H z8GpK_G~!&|bRt-#(C0gU*=_^~MB-mNdU>EF4$L>^ zUj{Nl9-tWF3R-S$NNaRj0L6V?h{HSX;tUOKx}07aI@^}JbB~o@;dJZru*(5ZCLEWA&3xUTL}+5DnElBr_P%rNO*vb{ zb=hATe@*iJOALQL@Mxxx`h8^`16lic&dC76<(to7TD@m+&8=flHb{D&j5!}b4^}y{ zTf_P#qf34A(^cVO591O!{^FDR(=-F!B#xwZW3+A+iGs9~j$IN0j!16}5J`W}>MX#? zoYyjO_3jI^BMH|ss=tb|ITc6QIjL;1^LKT^&g`z(xnGp6R;4sX@T1Hr3S<9bj8jd(RaExNrOBvVAbt zNg|S>Cq`w>3Q*8P`JsEYxZ@YD@>);iar{^-TCpnkhEMG8L{sKm{n@4*EoYuMq4ZO1 z#X?t?qNw>0GK&^`HY|H>5)e;~eLt1X6#8;U@`KjyaDlKQ@R ziM#qMek!`iwheWORCwU<$ZHP zY*+FD&$gxq?Q>$L!y>Tf?X%*~?y`(J-8tF3(BouzI?-HbFQ=XccvbDn8Dy5Thm<0A z1Ksv)*~d2hW2c;{-?v%>?SDf3TQ~k|{QH)nMtiS*gEs8F$AbqVUw{`2bTN^utYP7k zTQb;_ehYdW#oyY79G9->eNb^m zI?rK2dvbe8W=tSMOujM{93!9VxDkzxxpQ4xx2}!p;ME?&=c~l0 zt}-Ng26ihves)Z*A+lT<=d32Oy`4wHqs?SFzwrw9 zntH}B?tYXV2S}u&BZCtJ->D;A(n3b$%l`|@m z-+1H9=3G7EBEn)8t7jZ79z?=f7A=3?eOn{T=?ieV8f0YPE%9O!Gqp*lzu7Z480MLH z(gNwE!`ASbZ6_SIqY9pX(s#UTDqhCdV5e&)NWG8%mO!6)^2xJ}5zorMvG=dg9~wg+ zy>iMNbnqDRfnOOao~mzw5jfjqlQ3oQY}?Q4BxsAaRfCZVGfJ~MF-K32)*IxauKno( zuDN8IW?)LM?oGMIjPBmqq88%3@TFtLW9M{dgm<=~0pOTO%k0*TVUeiY)h)wt#*6?7 zEz_lRCZ{O_Y00mexco9L-=Mv2Sa3K!fKy_KkS6&;w)pow&GDQ__mC%F`TlM4eQX=6 zP#a$Km^id0s!0XhUa=e^Too01=f$#uIU|jGW|V8aYZ0``K$&N;<+7wdpFQ%82WohF z3U4vvV;;5q8m#wWSu2Wf&@Q`jNWZd^ZAEUElO&|V&v+aPGyU4L%IX1a;L> zwtfGj`;anvXTFl?_tN3fXYgkvA{BYe#Eh5t!**WgUE}cOk~dFtmE8|*k=P6*en6N? zgwRcpCwobVtiY=G{6m!l50AThyk7D4wU6RMgc%l17r2~kGLjX#&BrFU*Uw`Wy}Fgd zcP{Di_-lBf=e-?io`J`GW*yM?G$>itKibBg+JBaQU*i}p2O2b{-5bWf0G?Yqg5W(? zDE@%W9Q6S`AAl*Kb_^N+L0l{`*9XIj0mwVWZ0ATGl9vWrnr~K7VcquLj?U%JGL6E# zRL<_QV0PToK4dhcbfe!?JL}v@81&S$Qsd%F7oxYh-=%cX=PMhVSEBMuAt&Kv?|3>R z&&(ZaZYnGPoPA+dN<;l((pSEJnSB42W7M4p2+}j2sH~lHt!i_uSUa*~f-WWfoim%u z@m%ll&zuhB3-9$Lcj(|n&8X<|lX?CmE~O_%eYSnh4;)KL*hL08C7NsZSils&sTEeo z)9PMZz1r?fZ=+pU?XVEh&hFpW9+l8{dyM}g-LDI~F;O_7#T4-@Ep$!P0U1!|yQSJh zF}!00mB^$RQ|+wuK^!xfVF03;$|W3?=+|cdUi?^S)pBK4z@WIKWcZTXZ@Yb82L z?WUtN(A|aPp2mNc{ur19aE$|o!o(kV1XM$$-GlspKEw;Z3C=r&6pfoj9q@BWM(=)K_pOf` z0!pEiV%I);2-#5cBqddh+G-C8Kt5zJb?j_NV_4PEI^FKA-g$aQGfUsA?e^Nb(9C8h zArI=RmKiNMy{q49{Ac)&Tao~q=4Y{TwA;)v0GB$hz$5tCoCv+aGM8DyR!o>qs}H!g zi-b;(O`V&+yg>I=Rt1=s&ua;cLQ2rf!zp??fsds-AujSDZV`B$zyq2O2Sh$AlZi$ zGr`d1%!sHfndyX)R6FZxNE6+1>7bAaoIPY!02X7A-OOz!E2s6Z+r~cQJ654g#&&S{ zA!n`Y;Mg8gK>HxWq&Gl?%&4&BoN<|5n=$<9Rfu|{9Z~r(?LADX9TevDvpBJwF*uN= zYRN)EHhhwedAW-zE&_I{B#da<#>ZGB)vHIq0T9BE*HDMfcj^iS8wZ zi^E@e*_;wxXM7FDI;L^amfSud)%3Gt<>OE2)h7yLw%#sha_Qxv-9(#xG9A!?iRWLX z{(18K0teItFEk&5&)6z##_p)aCNunW!%q@`2-?H@mSmhyq+J8hD$nvx`NHy_qEEHp zYZnga_f2nxE)!GX3|Lg}2z`HH&=5#}j1*HD@nAhkexl1M0x5u>#r;`K)(&anv&Wn- z>z6^%Hoe(9fA=PTKakejR;Au0=m(p;FHxvBGP^Qv!`3F|8`#!;&nmHtb2c8C$4}xG zT(9*D_ICFfASf%FNLIZ9rFP=f;0Qo>b{10%K*ebX_~*ry5mI>{;xX&)44aGHWg^y_ z4wq;&D^=HMO`opl4$-Y)f+YI^$+HG{)rb-@hP(^SSHD~|ne>{g%VM+AgQ%r$j~}Zr zCGb!rx$05Dw9T{lovcHd`imdYS+S(CPGCtYU^3T$J${|2lzJQ^9m2Y=Y#44VmJ-!p+4&pu5qP6Y3dO1ED zH7}gBVR3GYUd}HTU68Ov?E7AP$imN0Rp&kcaVY~7%n$RZYag^*;Db4(tV~8I5d5umN8!8I+HsZ2{>MLyP_FE9RFn{ z_1s3?*kITTr)?WHt3{D>2%PTe&9HevxDGO3LRtUsU4V3p0VD1)SBtHSM2gO|I3E2d z5Iw!w&!uNaN$s;EMvwxJdbc$0T0v&wm)Ke26zW&vWn1-p*^IomV2Q1{U{x%-SGsRX zcTguGd|PNq9u&e|JE4#~#hvUwXEu;%@%P66izoYZ5Jz7jdk%v^({QcbDIhUZP9#a@ z15nw?Fy7jRwVUIC38r*!ZzG>6-QztOJ5lbo+)SPM&6tpWUfgBur<0P% zwj+iS-3L%X_3`q>E5UcCou|*2!Pj25JCwo&!ak`?A(W-r7(og6Y0}!~!UOl;E|(?r zZfQq0*EorghRLeq3geJxumffJq ztbuY^5L7Xd^M|8mK%8cTY8CFA(7IZ*xO%ZgbTyDF`QQ zKalQrZvRv$pVbpBbXklOJWqK(t^JR_6%>c)aLm=~1tYmvmEs#_>(B1l{RioOji=C^ z`65dXH1yGcEvOND>_)&5{?FM!;b{X!1X`rQNuYuA(V|^>^1N%)X=F*I$UORwrN(|9(oIG`v>R|q+O*LLJMS&TOkXhO zHbZSjQ^$v?e)z)LiRQ55%Lg+#>r%b>qoC_%cmgTz_|(Q!vW?fzEo)jEgepFdjtSL+ zx6ibknj7A@givKWR(aZpeSL$g*)g82?&F!MsoZBfrdfl)(6pDLN7xq0L7i~;$@ppjV#05u~X$sLN ze)fvqaEKx?cgFTkS07u_e6Q~a;P`=4+s|w39p!^b3U!Lb+gV}ldR|2icUvZGn_kTH zFcg@zAsyj~ebdhB76wdx6^O@G$9)&d%&qB@>0*4}EN&urES>n`t4((z2@ti@?6Q%b z@cb#3C;VED`G4osf2Qx#eFL`o{%d6^^In}bTggmyo^0&u7jrrpu^z>xZI}>SlAY`s z8TL@A>1ERkoe*Zw5^ZTM6j3Xi?o&95%%{J$Mr-AiUxUWD#2*&Zhi&#akjj?!H7Mk>TFNX33rc8j~`t?Rpv)`VJ|b-e_h~au=f^HAw6KiKpUL z0c#YMQMOTqYl{OC9Gp$3TWQwojiQKktYSz_UTf*A-b3j5)~#@AxkZWP5@o`>(ya4t z6r#vVQsFb4~FyD^Blkf*Jx;rq%Z)KH%jt#uqo5{8omcT-OThgt{P8pDqHmkV+drYNWKmy$^R780 zE#7Q(edk~dZk_J}xF=vua<0|A;+1pzC3;v|C~6+zKyTzCdjEK^|BANH9^dz=xN({V zd#P>Ptk;EM5ziq)0e!ThPNVfm*osTN7njLwX2obv4!Xauq8Z*1$So*lWPc12I1@C+ znpN=T{lur4!trK1=g;FB5mOg6+{w+{hExf2T~7+U6VLIYX7`P&<#v6cZ^M&V4gQ8Z z<}iY42DioR<<#BEr%juo{{oye7xur`CLf|Q{Jn4g-Te<0eb9rW?B1s2lfkZi+EbMPv#5-7{6R(Yh5RT-C^q< zlt^wIj+vtI)L)ShieC1}QZBZByClw>cm7$PiqXh~^Sk8S;0 z-Zv18J~^N1V!pz__1;EPyrICcsoEx2)R*mW{ihtE@@DWDBpCh-QE$0i0E@rHjIi6C z;Ht^L4w_|93(uybGU&(T`yasfP4rAzi9c^ly~iMUfLy5)Gam*&ou$wepfz(TUVw)M ze&Fh8s7DwmdRH@X z2PcO7vWKEgM+@(qGgbZBzVs}CI>rK8coGi_gs3GhB1i1zxhnZY4(5KXGUb@QDnv#L z-JOvcmUr$m7q)rG8<%#&R5honJ9^EHklCkqyGpEZM9pk2a+N!2P%Y>*rWyb5@O`ut z`*gbtSr+Lsi+7X1rI*o;!o-YVyQF7mZ~5a5Z%6#&#FRwF%-rg(M;R%*EjpZ%TdwKlssMNQc2n3LEc-uJ9+&QEH3KG@w_ zHrRJ!bzUpawTB96)L-clyLj`1pqPE5UoQ#Qd=GjZ54iwC_&T`-gfSj%v5^BKWRQ~3ld z)~hkTQ8LDPBq?O{8Fq}0g@-%tj7C@g=P~K8!6kw$bsVyK(UyYCFOqlnk5TZr5Zzom zrhw$&7XH$#2);m@v_-S>PX+Tgf7ox?5YPcPTQtGV7F81NdM444=@J{BGV4pPg0cF* zlSLS(zXMca`uuY~5iUhR@pd!bNQom`5-n)YuJcosVbEvOd1V^%!#A_stk-P^T;g@R z&QFlQ>da`fl-+tQR@yFWqP>+HLrNJ(iKT9A|o~)s{QB(hANJDH}s?eqYbvui!tCbQ@BT^FM7Vd&mlVgockPu;bK^)Pjb#9ukh#ryGygrtE@Vl^E!`@()xOQ_ ze9P)+0`#f>n1RdN$sx7og~9VK9XUQ2u0H@(IX%d+{d6HpBT>{w>q(!dO<3TV4fO3~ zmRZwg?;mV`B9LcBV`zrjRgdIG>&?{}H`txAQaza&l#)zwW*$-Rw5R*B_%VbM!!pX3 zSn_dWPa{f7AKzVsrsZdz4|Z-}p;3*V7kToh^Zz~em+2|wnq0kY*PN;NNhBMhED56p zvfyZ7uNMyEwXaiZ9AtTuYhd%jONnFL#iL#`argM(pT;0d7lYH9Rtz4^2>3=!x^;FD zWfs*3Y&=2?j3;`fSgtVr$@&!ok59Ch-D93zs*s7_)KGgcQa=uUcV&CT(ZPLXoNn`G zS%*3OCH|&&Ew((X0!q1`)4R&cDw-U{dlu;Ko-As=zFy+)*Jsxk^UldZTy#*_-7LC^ z*1!-+90>Dmq0BwD8M8cx-Nqm>$D(Q7HBgz(I$o*}88o={m|0QhYT}}`NT%AYo(`P_ zF>lwZyMGonc#spv`E>^ZoOM&es*Ym<8o)tnVOZXD?&#yqgpkB%KV;-T6aLa=U=<|J ztF||K%CzZ~dlh~CoS@Q*FQ`kY9*SC*pKbFW^m{LHe&mFIG(kgU`i<}OV~_VH#~mxw zkuF$?yfwSZqmeVrtC}>inK`@OJ#Be!<$He2feouvDT){8liM`G{xl%cDLvA`@9uG;6=c?U-aoN`xv?JTDIg2S)6 zM+GglxY(O65V=Cpe752eo1@#kO>vg+amU!*tbxB&8J~MNOfAi2D&vsSvuX^L0InFh z8I>}{y(l!k%k@89|5D;F0oN$gCmcdk2%%q4za zKQ}FIm{V>5o$2DJLR2K>HE>CP`UuaAw--_j>=+~|7_O_YGYKp@R16J2Qr=rG!PW$G z8ojaCU*KQ3%m+{HA}r7|*^QhMPnDf(8=bi+lRc-P_D_D%?JsjTHf?D6+Do}jmsZ+P z`37h;SVjZ`R(Dz*f|8}0*0}r*mU3}zc+0nBwmd-&u>5hP{*R&rXU*@&5TnoA(Z)4S z+y09c(t{5I*~s5VPd{$kPL5gsh7m-;*)JZwS*)&-QiX1j^rIe$Cxb=fWL11sE5Q$D zoNgvfywp83vu1fOPZTl29x!xJ%(A(V;mK5m@2I<;=;U%qkwEcMSbMR-mGUn@=A4q* z&MoVDc%;XyXbl>#d78dl zF2xOH^%gKyt2%0Mp@iPATUGt9MAa z7Vp8sLX|PxR{hYn&mai`)400xO{V<1viy1NvYQgq;q9+Ag}@$D(|H>^64H%11PXrF-I=mAu$SdN~hN@!aYkTEe%#i4b_-oz*@Wl5H|xA7N&A^U>X0B7n5uOS*_R|NW0 zFsDGMSl#g|Z;t^77~hh0n0b;|3`2q*b6{8CndP}=>#FA2!5Di!4{`S5)!N8@)UnA; z3XZ2rrsZX=>}4F{#qye5X=4ta90AMr74#3CMZ;p~0=aCWDcQ^(S=o?qe&iKsn0@mx z>}*Z_vftAwG0`zJ{V^nb4H@s|+0GDiF){z^UJQ6Jutvc;MOEgO?Bm@48+cS&!Y-^Z zinnLHmNQKArIpXOx%@Bizf=RvPke04UVcoh-c*SR21-+*_@ZE60Q|Gd!boj}z*8<$ zg-c4KEgo;GH~i($sRn8LSGi}sMZ;=d^q_mw#J~&WEpUTi77qz7201n=c?kbz(06hahPAg_*$&+2TwC;#i4YqiO+F@OlQ(FFq+wPR#n)VkEFT%2yXjEo zIk?dzAvwZ0U}})*xhCs=Tkcc+$E;kG{t{~5tx8xgE25(6Skz(^@6*UTdG2(tU9zh` z43k>!mU?5 zXz5y~vZA!^HE5A0Tm4&Af;#gT1&hEE;8+$;ZF5!~=gnc1Rz*GdyRQ7G zaJjGhbbIXoIsJC4Lj6f*mBiRq(B;vJqS!I_Ree3Q7lNV!($gq zo)2DI-L!tTQa;fX`!^PdKThJ)bfUd#S4#S|1g)}Be!ceM?#}%cmFpo{oquEp5H~LI z%EiNzN!Vm@%5_)B>abr|njTaud10nEC3C#}hLYZUhe>zN%4zwM{+9Fp<3{T@r|2Cj z={*L~O7VS@Mba(rO6d@BYr0|anD%bKNA3Erb*}SwnEWUKrzmB4~pGWg!1kx+~zA3YW|5N|kv+tOF zvyE+=93vV$Ip!t=%4X|U@|I}??j9`@AY^E$wtLALH~cmCl$D`{^f^N*UH9?ntiFDe zi?EoPP!7x9*xY^-lGyn-#q@XNZw3ggf?SzVuO!KFG4P9Xp%Wq{-c7KD|FyAjZRw0pMARDnCM^yC@K$HI_v>IkyNnnmBL zPX&ZY6W;JY2Wh=je$?j*n>bGwjZ8WQfl-#Yh01Ezq7-?zLc?=?Wb=I5ZXFKWv8XDq zhp^>sGbeB~NEY|#9o2G0=@;=d4K6+O=gASfv2^p|qat@Yme7GW2|a^VC+xed%1^J{ z7lg4D@V9OlJJ|o_`!?#$oUJ9u+*Dh>(8wVdC+ga;|=}5@+?(? z=j;(0FdmLJ$CdlKKdJbi{e}Fgck+bs=FR&_#rF+SrOrBQfWJ8Bhi> zu|WnR`{q#^8q(Q-m6`H5YaH1)aos40Eh)d(I(6iFYO6Q}?UXvYgI+SW=eFL$4m)v{ zvlR{~55h09EpptO*)Wpmcvh}(&kJ@k+<6R~5zE;$+@`j^-S0!_Cd#aC70~jvbdcVR zanYkQ@eHP=BZA)J&*TEhA*}sSKJrRKLu(fzC!F-Ea>iaV+W@j0!RoJ#+WdeWvofq0 z@tx8RVU=F1y%x(=7G%oiuOcQHkWx39l%I~u8{FNicPklBvW30DkQUtLppr%Ho!Pg& zzBK{A?`4UsCl_-S>XxWq^Ti{(pc!tt~p){NY=pzkwpQm;)C( z?Vf{VoK2K`=|k!d{N6a6l;?ZqR6`$L_S|_5gCYxE(c7-J*z(o-@_)a}r>Ex^bXW&W z9`Xfk9YHJ9?~C=^^y!TDt+*a!WirrpoRU)AQgXL~{2S=yip%%Tc7qR1PaP^F=*uB(BPW0L`^pEPK&x;S$jTv&4t;EBfM%INp z+%KwDE;@h%V$4GJUwS$R1^K|3!Q92`?^HsY___TdDYj78Sbk%%s_(kGnl43~vnah) z<>EXW)toh?&NVX3C7RQ=wk37WDNn@Nv2@(8H?usl@@uo4bSNz_Zg$%+(kX(bmp!Lq zPd))$Gyl41Im{F&G%NR!iu%X!$NpMp)Qutny|fauExc?P)kgz3R0-RM>fznyhDY!| z?Ex#4aUW*W(OgZPv5Q8|KgH+yMPQMQHpYARu$}*@nfm7fRNaN%tsJlD)sW3=eOh}W zid#q)Fh!C9Op#oZ?mwqe`b-%1((`v?S&GN8W+`1vIN&QUnDY%=Cq9YFYC`6hGZUmM zk^J1fP{mboNcOBNyZvhdGk4!y<+l4|>jq1|+^|y5s{EZV-hx^L>G!hq67HR!2Ul%< z;kgLrU1IEV!I{B5_7<|2Qn$;HWgL92ARSIj!SLA&3~!)oC(A0}@1ML5{e%i_5Z}PIwMN=L{0^96&=r}RBz%>4J#yWKBUH%1pPn8!p%Cvrj6 zg;q93CakKMDlWg=Ik6y|UHN@Vz1v(<#?@~PaWY)Z=xJsIbPnGSn3Nr1uY2Lp*1K{s zM0nv$_=o?^3HTqUO*DF$5mjLO4oasXrC7+O4MeGKvz1I32*J;J)_Kgmi<0TK{j}w6 z$(M6q4BbU*z9NtrM|8zL+TJ(6RsMg;LyyV_oZ#=d?4J&OA|=%8T{Rw2bq_ml3#eM{ z*qbhhQz>XB(%?I*1>GT{dA(d&vA=FYR3fYk2921;bw0JOk@_%1nK>_R8(Uo*xbfRVAi!M2W>Cwfk(VMsM?U}P&|JCGdL=F3o0 z`thxsH>cW)G+0&!YlWZSArJWzFcYhu3Fnq5iLyi;f-yTQQnW~1#u5Kh6uU2M5fwOD zRHtadCh;gD6egT2hZPlWu3Ocq^wH;V>l>UWIA*BtMCdba-h_FCX}Rw z()tpie%BflI3;p)EJ&3h#=o<<=gRJQULA~0?ry+OKBrb(+u)JCOB=<#^8@ak1m%Cz z8u&KiPTHSwBZi+L5zAn5#2lDVU9+_5JDLGBcX;WmT|Z{LLeqRm{NQs2W9|}&u)M*$ zO1o1F*ZI#s?#M5QB=MnVgaeWx9{pQK<)N18Z$N@UwUlZkkdV-4XYDqu()CO(i_9b< zF!&`Gy;S}jMA5$Lt%7q^NOAPdKZOuSUY{kVtYJ}GPS&8aw6e~6)|dBokf7L!w+ zG47t0P)mI=iH*+Fc-7pp2JxOfK}!`edC$zIX^aJ1^!6PoV+E+jDR0zBw8iA~n)%4W zj5NdREr5Td$j9&+bJV>b@~WCYh?-gS(AK$@l-S=QH}XT=z4YJNE1J_P>HQCEis0XD z|IcNVC`^OxymI4{_=Hf$M{j@Ao_~Y-w%XA=i=bt&O`Q-wplPH)Jy+XdsqA2ywwxeP z$&8J-E|y{}Hb#lv(=h~F%j&G=A zO@mrs+4-=}8J~oVFsq)B^uj{gjkm*#RKEwEvV|lp)+Tt!Lf((UB^MI?KJ1-_0^8A^ zbZIA(z?>}KZT7fl?uZx836e=;_;Vk+W_Kr(C(L(rw@h(saYH_7ECFvI1=!pf^R41;tYw`t}76luqnrYME zkQ(2!`H}%)W^W8%>Y-Vb0;ViBv?@-S;P{a2O)W*AM4q{vN+C2MB+rfoE>DA5luX~) zwhuU+Z-z~)zBQj3pGBVj)ImrHT<#DR7F@$2C+Ccuoi^Yp%k38Q6IORyt*Uj-M!47e{G=?<-M5=cwl>0DsFW3DHZv1nX;*h#N*V~A)zFNFI3Dw zgs(g%zv|h%5TE;pv2qSZR?ydbX7pdMpBeaLJ3CSPFkPQM-Rg@yFldkouP;)tFrrVHdZ+7JFOwe6#V(asUTdise`PBqHu zaxlnSt*}HL#mIyS&NN?L*(N=0)V0RAu0wGCSiWW&DW`n87y-DdBVWvGo0W0MaNNJW z=_fnJ#9Top#f@422D+8r?iv^T9hph8M}Z-)bmfMe8`=0uU((Oym;o_uF+GJQqxZg= z(u=61ZKuY0%{g7ocCX-%?nC6V`Oh6Bbhq5L(N>rDsToA@=-?#WZ9z^W7gj2MU#mS- z0_edvGTP=9`j!fU*af|XWm*ATebLnH;FlP0u{cKGXdmfU#TkcoJ_t56J*T0oQ$lO; zDU-&@*oo6)K{+BVj;mULVx-3cnKgLnKz4F>bbK_BXRx|cG3jQ{+Nf>w`)^teCmkxd z^MyW$75*~3YjC``qf-~4h3}nj^nt|rr4bsfXcoRpMg{buRNTH zKgf8$Ut4&RtRy~iMOUt~e#|=fM>j6j0dnZ8KEY(r9}_SL6v=$^?4X6$LMbx2oAPLQ zy(o&n@YQzj?~6gn`_L7ofuHp%`?!ThcfxEf+>)GfHjvfRJdBogJqU0K-Y1@20cVuT zi4Q?KHpJyS=C&2>8EfVff_ z--=%mDRb_@?oGq13>AS}29!U1ay^s`h9UJBR2@$t~|%HbF$TBjDEB+TAKRVo8y45H@kW z+e64C+-B3#Pcm?I?%MDD2`hV$dvAlVsc<0RUU$@LXGZk-FE3k-IAr~-G<0mB^!Kg# z7wqv$dM-m4?)K=HQM{hk{+xVmt|zy~V%DW)E)OT@Euhoowvt*7)$-2>egw&^ZA$oP zdJ?9I=YTDZ#Qlj4RpD8zox5RH>==sEyrty7hCiZjw;$^8gA>3s!#IQeeXlZN|I|bl zW#8xpY6YLPl^}l+{;V?K(J-;=Qv@JD~()w*_dz zwrqcP=f-^Hbh-DhE9(i35il|IuY9)eH&nYTYad}sdfZW*^Dvdpwrcf`!Y#Rqw0LE+ z{Es(~x+Q#ynir5v_x;CiA)HCOxcppt>A-wr$WTrLhwXN{J3gtSq zD!2N)Dj2KIs=?-E#UX0W7VQzZ{ArCOwd}!{X&w363J`*wB8oJ;n>BN$wk-{bCn7Pz ziJ(X`Xm5#fGe}viN-$_9sTmj$4&2GEv8DrKt6I}$O4AqjZ)X27@2V=%R!z|P~)X+5q_ zjs)8$cDaYky5z$5am31Y`9d zx5>CF-vrUCvHTn&Bg+`-c9HyaC+7A-{w)+T_)|oavN3KoLa7<(?yHHoIb-hrwj&U6y+UQ}M2 z-4QD>WYhoP9|!L|nlS0>qt|>eD2>ABKb#%4gBp$-YCiq-Mn&Rn3Jf1LI1i#};Z=Yw z140{)Dhx19{_tbA6^FcF68o@>XF@Dsc1R=4^$Uwdl$!(kPPKwx>*03L$CAR2-^%*e zJ8hx;wqVaLtj-;NRd z{Ex~cGr0Dm4>&`?c0$9cWflqlOiYT~J}bn?VPhRs zCp$#e1w1JdQWi7Vj>*9&cDcvqtV6akYq%yI6;z-ju;dlFV%zFOS-6{;8^6R|isj$$ z+5mXb-wh=w8Mu|Vg(3%9U(oU^^A)3|)e5zbKJ-x1-GrWhYl?H_zc?B07^J9kF(PhI zkw0YLGJQBQyV9g9;S}?a4eE|KQd)MD?vE;MKLfq=U{||f_dEhw)-UAI<k1B2N1qges^E+V}w; zu8PeM`c~L~ztgvur(->P><{jd@~74XjGt^9>ZXp{E;u1o(#8;wlzuEaY6D+1EAPGm zeiR2rDtR%wPcOIwrke+K0ulH3*B8VhG+y~e&6?OYY}w+iS}na25_eqW`QpY3&gGqJ z*^-T1$lvL4IvcS5S7K;j%Y)34I1KTR93Fhz6u;q$t*fKt? z!B*KZy9MkWeV3m9UPE@q^kJ{wj~)>I_k%r4pG7we8u${XOKi^;2YjQ^dAklwrV2TF z7jxvFrXDG5fn4-e_EK=e8d*Z?KBd*k-$?)K{rHr}WMgUil=SPHAcg|R*nyWo>l)am ztZGT8=)kiJ97CCEIpNz0_ySiyTQ#>Nm= zuT#uQl|6~m@5m9q5*+gqlNvkkP5R1iBxy!l1xD$~6#!GF-`J9lL597PYG6YQUMXJn zhi8TRa#)P02Op9roWtvS<;S8H(U3+JF{yD0O|_YtSal@6cwd17E6e{@lX1$&$M`y2 zpf(cX#$ChJRjUA6(_=S(ujlbrxV^;{`+n`5i8{P{$VTFPUfo#T%faczk6m1fH7W)jV<&q98#g>D=) zlg79Eu`rjskpv^0Zo=Gr+8Q>DLUfBZH`y6mz;LG~nk|awg+B~*1j+$W+J z?EqJ45lkZ_-_v1&c167^-a?NbR>b;2_Itb5jIe2)`xyK3C|M2{d!|6!d2Y8xYeh(h zkFtSIf|o8!J#ISZY81N>YG^Vp1h)~?CY!Nt;tBV4JE*(S_Ni$yw$uDW&!Sr@-k$PZ zAwUx}?QfSR%2JrgdbXJttI6~zEFiEBW%gz{T(4Ll_vvx<02P$HGyMiU0cTtF!ihOI zftWbO2d`rm{aE{e6>-y}wIvW&&`;SPXG2A3&6=jJeQg#%fnTVyI=TBU%TvK`!NJ9W z;NZJK*=Dvflz$i;{HRNR7?463YjQ{Y3vhg!--s~pFD&(`l%2)UiIAM z7Ma$PE-+H;jM2UUDtx6KEdRlDW_x%=M zt2`K8Jn+olQlidcYTa~pRRifX-ITHRa8+)+pF*^K*4_}99H&-8A25_?mOMOmegZT^ zSWA!?v4Pco@t;S2E->1t86_R|0$)lpsiJ6BZgK?<;Z^%yXgYk?DYud$@X6on@tzy#>zImpkIk6?MQ@K27y zQkHtvYAw8t%c`uut5|4Bh$54mTV4wG*?-}BoL_g(dC=N%V~``znb3yMwVOI+EGft=J57`(6xHXk*@iP58(8=(j?pJ z1b=AE(fawVE&s3k(Y}HPvS@3nwBei}odyURP9Aaq-0-^Zu0vpMnLc0KzGUr^mGqLO z39BiD)KX;~YSr3|eZB6Uy&`uF$oA`?O*nNk@Ke-}G^4=4ZMM&@nS1tB_Y>fs$*Gw_ z8Fa3ZP2auqA7x;Uv&m!adDdg^t2ilZSI4E-dODbm%tdcX$&c`Yx6dbxb+WTBRw%qA zl%(&=1**Y*s6n+!CUwdds8UusW95-NA{z-h=eiauY-1F z5D8@TgjeUMt&&5uY)IKlt7-8lm`t(iYgO>KmZCqoX4@bx(}Ktx51cz*jyZD5!F~!I zZn6xS>dpVmlkyQOd(xrIU}*6b3l29z1UMMl1fi9ud*>%_Ey=%m%=Jo?J;b)bu7&60 zUbrSYJJW@t5jO8R2oxh=?I2&OZd2yR7p%|SPk(7=x(NcY*1;K@K1|+WjVsuIbV>Q@ zE{J{kR^s39l(ZXlZDi=LgbLl5g{St3X^o-Uq$CYFWWOX>7 z$UD9$m%L1YL3|2&d1Q+w;bw1S^4;m$>dDi;tZdGwbio&E2E0=0U5EBjy3n{;@CP_n zIeU0F<&(P%u9svm7LWj*B~^O(sH(jeGNoCPk2~AFm7M_<)jDlOL zjTSM{6+b+tuWy-F2Y8(wW zePhK@JzO=^C-#T-XTNi^^<{C)iaz*mr=aVPb2y%ZuKT*=wh8W&Yh`OKpB_8``ge%+ z)?hk%yJ?dv&GEq9`|MWEx?8m|Gt_EQ>g=~>qHZ(?7ejM`uhL6Yzd6F5)1q8OEB9M! z#x2(texv&@_hZdSeqR|osg7y^V|&k&fFI}dl7K#kC&pE>b%WcBaKEv4!E?P!2<2!S zgl4Q$GLYLD1=h;O9c*-l#R)Lz#FzVY4*}%;`Q&>ouO3v$Fkd^M4GNGL=h_^bxkEAp?EOm??6nBANZwisdzj_0Aqo!H`LB&W(?Q zdKU&2l$v1=NfY-mowZ|Q2w04K6Z?m_6>v5O*s5l~@i$PmuWNxBAWg5HaU)uNScO`A zwiVv7!l<9DzMi9Oh=rb;vSbYgbBG%9B5$+-a=2mv$2Jj_lxYFScF$OLIZ;FKn{m`n zv0R@5rq!E`!6jGQ>gL{mttx%H-ICc1Wp>Uu^u?098@3CW))JT3O54zY_CgHNj4pSF^og&*pxTuc7eUN=tN5WgLJzr*e#gAEl&V<9?LHUjIh zGjA`=F@L1`{2Sr_c|Vrh9jS$IMq{dXR_z7z{2zi&tb4s9HXv-(CoCj{9nfqjt?F4p zDl>Ok4(t@N?koJD)uQj$j%W}Y&1Ke`z;HLwyxF2KV%J~Mp-~b=QmmONS~U5~OWDOc z$y{lGB*cPip0Fp=UK@>#o0lbi-ikAOKLmfY;3F5`UW)q@jLvhu&+=k3JAyEIt$FgI(rn=R~(lR~3u2UXDc^l7!r81{eCw;5Ty8wX!yT3`4`u7chgu%y1tm*{2 zk)cz2l*Q!s)#B1ThvcsnW{xp%n)h9;a!$Bdnn&e3&t{-6^^wrQ6Keno?VQM-rM+e6 z0JFk!`JQ&oZh6>~_`@6vxId@*)2}%Ikt4pJlrD?S><1jgJ*OfecTWk$xtFX!ABVlO zwCG8u;{GdqQ_RWht0%nwNbDUN%x=*6cA9qLO5OGaB1`X+2fuuDZ4Obt15>Z%koXat z%=Y3Z&gUQy=PM`mIT0Hzspf_abmfezYR2OMAIv{ zJl`$87G>1LLnsK_^=}+OL@jR)&AxkCQ5~uT7s^ueLfCeU$0coX;|_RLP+aGt4xSJy zJ65W&z#5?Q#%(`84hk#eAl`lVw52(&&QEXSplHTxLJh9*O37>WF?TN!;o-$tGrwyn z;R6$r%@?{nwn*T3mnXQT5;!@#b+zQDD9+@$YOu1DajobpUVSuo$2dBEqatVCj$FNt z3Vf>)8d#@jjH@K5&JK)(zFafgf)3I>LIuDA!R&8LM~n4@P<6;UMUCqs0j4z;X5VTF z`o2!3l0<6ry)s3(2_R|TlD+%)YlS=Oj^{2$^xQ79ZY5W%Lw(1RHcjVe+dJcacKH`k z-P9?M3Jg<=u~R*^5bfS@kbk4GuhehzRSHe_aM;$pMz zo>l;e?vCM(Ct{j&%F8C;VKfcCg(Lt2x0}i-TGg-1if@5r={zl;13RVruwd&73G{hg zL-*lMKJR>f1222UzMEgOpx$W0%-R=pnTNbsajuExTcbL;kQjo*E9(RTX=8_H4c)gt zY~4+)ai5Y|QCgrZ>}eMh0HyyIIN~bn*yKbmrF?)wv{)KI`o2fEOF%M*D3cTG3gM0i zp%OZL!H1!rclBqD1B!o~U={pGa`YJ{b8+`Ei;}aerF@FWOrno>jolt(8`o5rdB#NT z5T~^kd1?YoiatfgLLIi8Ir&lyQI9^^)lh^nL#v)dxow$z*+tJ-jx;`Q);e6tkY_6| zGE;vUyQaScu*NypqPVK}9j;TZWNbWhK9w>P1^$y_j2wBR_F=GF72w+n0J?@v!>t*Q zeb)YD;2(WE%1{8^g;mTV&m##XKeU@gFdOiHyrpl*ckXu$66__t^hUtICL-&Xi?Kq~ zOhBpS_^T}uHbB_>TBoQZ%zwH3p)vx9HKIo=FQAQr$MP3bpg-vVD**ui)}u*nyWY%9 z+Q=ynVFhrR{?u50%I(yJ`*imK!UyxomY+Di1-tVjk~Ru3(`M@af)1(g@{V$$UI6ot z{45jq1*ZhX3?C2eT-m%QfypD3h{bs3v_rqKb~j{G=k3Xg+75XpXe|HM)wPa^NAtRF z&AWbc<1gY=Lgys)+lWmpgT5AK9R_3mFWpCVvS8wgSh#Y=n!Wfq!p_mXb=&)*QAxLh zk1d%f`8*BKJnlsMq(bEO32;9}w1RS$+lTJ&cJ{TVJ$pTPt=OcZyoBY{QhZ_=UIb@F ziuZa6H@iWaI>;9i`hq14CPel$l%H&0BzqX~1PZh^QcqXh)$&A7V~neUr_4RBYha=# zuKIVVIxYQ9F)KtsRXz zgmfaZ)?!egIzcz7eVPsKtR?e}C8mL-1rzf7aO6SS^N}fn=cx%n;S!?uSw^VKmKIkt zz6D`AdhmCbuVWRk9t0fy|5`~b??AFgJPs`qaGrE}PEGKgGICXToGD(H|M zNwkzxp;fA(|8+3YBV|m(+ilJdUf1LmJdtG}m}z7;us~dE8j!0)0J^MIWNu*oW3HIu z?GP;rs6K@GN^=DoZ12K^(H-D_wY;!jG%1_1m|D|xjAd_Fn_8Q58q#=x2Tq`;Z|uu; z`=Gcea(aop8ud2iSp~CGcG1${l0pl%!6-R39EaBFUVerm z9qv~NO#;&QG~|2qj*c>^tp)(C|1f27jw^+8$>k>XKh6E|0I!O;`*FwaBdJEvXA{NZ zUAez4S*1Pw`EcUl7dh4{#ljsk{4;niFfkDSUipMez~J zFYzfA@n7JWA3i3KBED=w1C-SZF0i(R%4OkSLavlQU{ztaweHA#@YpB>&)P6r*<(2W?i@;s8-)2^r_b3{fu>K?pP~8HQg_=!0hi+5E*m#Y(z^{r% zL!hZ-v#^D7O?KXEQHtWbib6{dSlAi=qtI}FHUpr6oF~6> z%bf?Sx3YZu%ioRSXCNbOTeF5mQ#nn$hRLOmw1xNSo&p81nA>O9HH&m8urC7~2GcX1 zSS_QX0bq{H#hT2)<~e(bwfue7iprfW7v;;NJPbqAeOT>#aQzh4MGn6Y2$e-=wXP}Q zF6HGbd#l z%k_7z@=6J4Pjv4B81Us69@6%d7eFfw>}TubVejxld=fj-9TZXnk&R%@iZqHIPYt91JL5fy!# zE?+q@*du*Z*Jx3br*9@qGYI-3H=HuVqsZBKL;_sSm49B=*jLwlHc0`-4*=jx8McNc z3hD)mCA{j5|G!Y>e;&Nl)OnYt1vi>trjP;1VC?qm67J zHV%A0fBYZg}@#NX+F#b4+cIa9(DTR#r8oqWgh?`d04}$;Xg9Az$x0QsC@4 zo_PcJxv_{O*G(>v9q(W*8{B8ZM3NOQo6dN(4}5IJ-f}+~#vGm)`N>OV-e{|(2^M)! z!Gp%SP1sIYw8HQ_y$ipA%$g~^{TtZBzvzCrf}Qj<#_}ym73_?6Q%FW9Hn=EAQLE zjXMh~xK~_jDW1Lh6SbOOfp%^d#Vn~W&6Nq7^)f_U9?5aLnL$RcnxMOU6Jbg zO8O%gTD0GRxn$hf1>n>NmsTY5EGW4ih}WvmzNw^u&fJO3dzcx)5OMKMkRPH!j<&#Am^Unk=uBwkE zK|7g}Z1oktQmX1>!A+aLf|CR+p=Uf=a15 z(|FW%kog;HR2_tBTRR_rggOpRy{JFf3(2II{3`bwh2z@U8o7$NK)@y zL>91Z4q!_{KNs6BX(nu6-0ND9t0sD4=oK%1xUTA|24xXck(s*{#;lQJ$UlSQcI2zwTJn45X5TjS)swD>+t;FcNKYgS9yZi5a*6$B5W(P06HT3=b4q&X< zEcWlb_-Zk%^VVzyTQs#RCdsN-{mbjLw;iXy%uu^g(sk_iZNo@4S0WSjc( z+9R(jLW6L0;50S^8wJfU!m}+Xv-cBFDxH91f0yxUimvbV&ik3DC3>?a1BxWV34f`@2#qpUhCN`8X50CFI2eYte%rJCt=JG~+4@789eFGQD0yGuD}zcatpXtsuP z6rAlUD`@5ou=5;Ou;8~;5|gIWP+&!(dW#R0#M(ZU^w@G;J$Mza>JY9J`Y9}2l{I5D z>+TXW>%iPw^_T73(ef4C^YbP+*O}De1EZV2Hyxn%-|bW1wv{x;oKC!90Y`N`^SQ88 z1?}Zy7*!S4q}(Kf70Q(!G=pfg{qBv{YUUzlrygOqHL81NEP8T+a$E0|*J>ZhwrB<= zBf=MJ9!~DD@pE4u(R1s(@)958>5%aBN(Rr@_W|btRwjVQV|%}+P6O|LIKrY;-McrX zA@rEeneunx$$u)@Uw{4&9sk;1C}e6u9LC;L=)PP^GkTR)0LV>r+V9#>e_y%aZNRa4 z;%e13DB##U1enxm-0Rv$p`4q7TX{}K|y<%$8i|k2T8emidw;n{_cG zgw=^3wsYGzCc1VM@9%^RE8m?)r8%eNxK_9DBvVmdyz8nKI2c#N#9R;5ghNWsj8hqZ{c0NnL75-{;Ln>245{UB#VkqZw znA#y`!%`Km)>w7a2$K|cZEnp$^*bD_xChMk)E)4PlCf+<>t4cr*1n+|V2xTUTk;iH zV4-k>O=R`{_+CrsoiE~Z72c2LIp@zKI4;-T_oe+M!qwaF?#_6QYW28TJ7O=aWbAuN zp8dKiRWj_>-^}|GP{kElcZ-tBT!vb)y)!o(nL=?RuLQM;-az|v2cYm7(tWMYUz)ze zg@oLVw+^IJ5tF!=Q{>qXc#G?tfV z$QC~gn9Mo;(V7fVa)+OM#>jFBX$yiVeb?g2`OFFRFHIKB%B&6gmotPoqiq+@=Xek$ z+52Y5Z5h^PxO$S`qF=nD!>goCbgR6i4aMj;kibW}+PN>!xQ*HtJRY?TisTyEL>~L% zI=f(ApUnv|@@N=)aFqYOIUn}y-q9-@?jn2)l1v!U(J0>oZ&6~qws+D|%Qc zC?Pm+v}G?oxc=}f*?->t;`4<{(60tldpW&&HvPRC2nU|JditwVA0W`^nUTfFd?$}J zE=fN;h*sb#Z6$SeA4&5faG9y55!Ux>Rw#lemMIPZ-l&k|!P?}j>RV8KEB%c2I-Ihw zuh!JLx=n~)@Y!9JdT;f(imVGs;xn1^F!N*~U`^16e#2f)DdUv7VW%Eep8jcHI;4km zVw7|z-qU*tVOxtZSxgKhh?I4@z2CssPMMwFzl-u!ff+V9xd=L`h8vv+#u8xUG&C7) z$rkOtLo8|#|GXz-@p(_siFz#5E8y565`=*?=qYe18%dh(xSYnQ`LSFchzqlFCAKrk zpT!TEwD7#<`Jj;PNIMsPcE+gMr<~NU!Cs0I7FjM0>_F5-lO#)Lh1*6Ib6|foCJo8A z2iP^%ZuZV6B|BVz`#oWfo0`TBYI&NTO8IQnH1pW{MoC7l;RMJ>K|bnee;c z;Tmo49KtO#&+-5CwFEzmSsT|}!b{}n&-IM-9U=LBWhHb?ckOE87K+guYJU{gi}rGEn-kzMnDpua>%dBxtVNfT z3apd7WX{+xOcf@M1G|1=@o&yh$;N(j+BcseHx;Th-65!9D z3K@GsE18SM^TBgX;pN#6z7F!ENB@5LpE^|ArU+0btFA>ZNqJj>SWny$xd|*Cs`4i# z&W~8zyO#K+Z$xxS4Hj7B{V|-a`7Ltatw|W`?y@G_)n|t8*LJPd%*AO5kH9!prK^~_Q47oXk#g~jVX{n)mF>)W4q-pNOMy0Rxpdxxk3M-dRJspRXZ)A7dF zy~P9HTrWPAQW9_Rv1G*0^!3&(%Plh`Z|CWjOYJH zZzgzOalLWK;P8JWCaIsIRaX5RXbK=sfM8f*iLW-GyEs3;%Vm2#U)Bf~0Zg%sd2#K3 znh2RAN3`b;Iy1)ES2&xU32uN?QxNVMyNP%97XQ2znepYcZY^o0p#{HvG|;9Yo2tp9 z%bHi^XD%yZv~?L>FVtT zATvAt1)6J7EFB7U??|HMGj?n@1glA}QI(1EOOO#aF-VuEYN&Mgs)IndJDodiM8LH2 zd-#0XxZ8w-d&w1CJ|S!*k+wRx+MaIKd1M8)=$d%TOOc)+8NBO{zpD@j*eJ)06$l1d zP7VNpx)5#n_?<`HG9Xosdjm3o`0Kox2*Hy}QMdtc?ACKFD@hzZoV(~>bIIM4Z2bLcK z0}eg;fn8tF#u{pje6)u=BBYVoFw)F2W?j{fLYtO1yxw@a=c|kwCrwJRLYj8%N%$_v z$eg2uWy9a0UjZJA_@Mrk#@0A}g?}cwwPSD8ONE#)BVM3j{Hn5dRgPWr6&R z&0m_I5F&Hv{=Hv8pnv@mtFD)s!~Sh|O`~TYw<}PSyCmYQy0Ivjd{nIeynM5)`{N1S z2Qx2oR&GbCu!K(E@61n@@Puo}kI(5l!bE~J)hh4yA4p%h8JK?U0$fiRqv?b27bm=h%)-&=g4JhvGFCtXLjKhhgA>jTo2t)`YsD>IV2YDOg)aI&nv#{~Tq%Ps9) z_hr1rDJq$o+*DEKuxhruu?b3k4`PmC$wvVuAW3d}kF!P(dcw?`=~{fY;n zo~b%BWGK%e$>X?rmgPLtr$n}7p#1OHXY7lH%JLwbx>52;f^ih0Z%u#6sRgkc1LyrD z=2gn$x0Ryq`uQK0%(-lz8S>z^;%rCN4*^{nnwguCS1xcz!e^Ek1AxkjuQKe zL*r}#6Gj*}U(o}n35Q!^60+bK*^~KfXx5=-U;&IC=QYY_tKvn9wNQ6Kyaw;8RqZF4 zB)K%5^#E16L76Qm^2b=bu+Ax3^wt1~YUTA8! zQ(5XTb`vrcUn!Tp3b>bFf{)8C0lf3kG)N@{Cc{TzvxL=fGqq7G$P!=sZy;5j(w&T5 zW-{|DTfYnn@x!6!0=l4O6Z&9-`dvunm0y{c@q}uZbpvZLNnL>4DOJ&q+|;LU7iwEC z_EnnnX1)p6h$6T!im!bJM3Q8YT@8yQkKO%eN^CJ4*ln59Z32h*Uk%Q>=c**Znko@D2-Snr_rctmp%|JaEZb#;F@Yz-y9ugp{8fWy0QIEkpApBPY#!6r7B$*NmzGK+K(lQDNyg?9A0 zK2umTmXj1~XQQ42Z@Vi3&RjF1prNqQWav|Rj= ziuw=uANu%*p^FtzBZM+?(a8Vl`C|6RwA%LI9~WKPYHwh~Y%Q)d5a^1k2Md_{s~6v4 zXu^Lya%L#uIV#$g=EL|}yjsnkhPV?mau+i`?vhNhs+>#-V(d(=rtqv-;*31JI&a9X zf|+r3+~O5e*Ng1z0`=diGge>E4I39>SZ;P+zme+`5-;j(+#z~n*|TSQ4PWGYP*>#} zC1r^N{dHlFI8zLEDd{Cka ze&g%?lC(#xeTM}eQGr{ep>)6LE*DK7H5wD9710HwgMQh_$vp$uF#Q zOu=Z&dO!>H=Yjou!vCQc8G_NvY0N#Vj4e(YRjgt9cv%6t3BHcv0MCvG#<_Z<(HGd2 zLvg=CV0Nh(MXQhN@@GNPr@K0sfKoDjddt3G-<=uNQsiQ`NVlhiT5`ua?@H1yN+x<# zrSBj#cez==TPX_^*v+fsY-nkkLKV5CQpBXlk3Ad;T~}(9o%ftok{g7JS6a8gRxBpN z%e7yP9vx6afq-{_Kz%?$IrS{xU+`@0Sr2f#U`l_%f1PDe$)(rFv>_{#sl^nh`Z10RlPggsN^I?7#=a?Z0zZd$-pKbQBf}n zS`#8=_!h^{(m$9>_dLJOm<^5<^M~ZZfX~^P?7td5jJZR0QQG1fWDxpqrRVGtB6xkrPcH!U7mr5)8+gAdQLl*i*=Hwwjym94XOOP z$ry|6mK2QodGP5RFkt}I;2q>3M=XtB&j?{UcA~PtsLE6DW;~>Mo z>u7v?#f4v@FQ%yrC`mBt^o%^GV$Zg@@RuDJw>}+dEx!Br%FF+lm8BQ7eQW9^aZ6)j zmE+CC)23#_`cH4AeMqA14y;R+i@bci6|^ox2RPm&^5e*#Vd27fR)R$x{aGf zGz7O7p%iT~WwsOJ?hR&z3*-V897%u%_*s3qcWwg~EJ`gFJ3gWeGi$SK7k02*M!|?% zV$wWo8G+PI000#19mfNmFGs(Di%*j&g?Gi+FPF=2)V?FoF|RrR-A9pLh!+$7V>O{~ z3%%)?m{n3Vun5y{zRKiXfH~@^lUJ&EVmflnsz!AmRbu=e-I%mX=4?!A?$r3=0jaME z_xvJDL_Y)3PQ6~Al1H-Jjx2#V-O=nVq&N;tEQ0a3kcC;B3?dX-;Kd{4zv zHjb3Y<9y*1XO zdw3t|2r~EIzc^?A!t_#vms&><-xXHeYG(vV_d~bo7No^e+0+nH^|aXbm#)pp+91M^ z@6B z>*jwX0sVhE==0$fxuXvHfO`dhXX>T?S?Go9YpH=oa}C#y&m6s?9mP1QeCfi%oXx>I z)k3j1@~H1Pd3#~SadisgXZ2}qZw)jf`btWgCY*iEiZ0+^ABE=D*srDQx?RRBGhSG! zJWyJ6l`>{>V+dZGiMShB_f~4Twn|Li>l zj*FxZ3#I++H(}-cmlVL?{|_h8#yjcKg6THkzq{dnxuaFMhHH(W^W?OEe_v6Wj#{yU zq*z?%k4uH#(n}KII~O&UBo(s z4_z(Pk~f&J5o0Z%nOf<{q5s%EEkvge7+g=!jC9nXCU}v-zSwgc5MjW4lzPOW9*S2D zG?_V#;$@gK=Hd%L+4|e1dV^y;{dAuHXRWx!fFM+fS&j$(6cQ)1yKJ(2Cb|Vd4DH7T z-mB$QIn2I!l*VTOY~$0^y^Xw8TPVDLajW*HAQ!hlLZk6&ZHd@s_3<~aGMc2c0Q-Nm zJ#|1-&GvUe--B-s+)ZFR)9D! zn49R1!tpGF%Wb;lN*EwE*XJOE<DliEncH$*$7-zZC)q6|G3>Sj-E;4cWvxlrB+K%JBuJdL>_#3 z>D$o<>HBY~>x2hiZ4u}=5W>h|`ELIM%l2_M%l6!4ZX&RiNFOt4OYoqErrZ(_PMwJK zO=${GsDdpUer?@!`Ka9BGWA4qHll*3+w!8lF?R+|Q+Y+SvtK9?90^ z&|(vwnNcoZ#ZEBbO2v2b^bhV-pU?3On++v@Jl{L11w>!q4iv~^@Z5l3D}&u6&JJD*SIrD{s~D2`VIr5w$3aoDp!mAs2dO% zOg`h-Z{lUSLUskshmODN8+vCO5o+1~QbF1_@Md-T1`2ejlV)XYW+K~wFnk$LF7Kl^ z?9hTUXK&bdi0Aja(&I{ru+_Y4Y8_#kb018{6a!HPSY3-QZ*h91ZW7Ud?3c}3|3yQu zr5U1qCTfywb2md+i%$_XeUVi(L-CDjX!o?9sja2H;rY88rEFZX-hW)oZjK~sGg-91 z2;On~!|RMXBm!D|z-*RLDo`Gtgz4cypg&ld?p(AMbe|{a z>ykfYk(8QX9krTlT-}J+fbYFvr8O&ib$PrWqakHa*#Hseh3xYk6P66)o=DpM)3<4U zScz}vK=Cq|`LbHnOgIAjJLUNK z6r()53ylc9{D1FqjQ+%0@FpfJ{gPSi7^Q$_PuCXnaeN-I_ zc4R(r0A)sX$Idw9gH49AW8u9ImYZC0=t)qvq#wt-T|~E$#j{cZ8`_U1o0I!f?T-KRp)L#`oc}NVE0_=~FSZo2<95e-Kl|A153T2*H;p z^jTyMy3ZVv$Lm#7*gX8$*F_AmO^%64Mebl1%#MOniDQLSLV}O)7Z7p5^!v^FV{KS% z;&#^Z9~}8v2lGuUyMfk`bEN$2lQIu}nlF_)Wn)!a`@`(!x07~gyDvVkDVz*82jup6 ziZZY<%oem`!VOrPAf+5NDF74a$_d5QiR8{sVPuv6a^S-@EhjR2LjO;SV}Bu=I){P+ zlMoxs@D$H;F5s7Ej}=cjn+|zhGVP-Nnk2l&|GYFj@|o1-O{5LX9~ZpVGY_XN?GnE9 zRjXlg@%5t9o6I{0428vme03zm1u&UAVYg-MW+v=?aAyckSv$QbP^i$tGma>PTjsi5 zSn;zx8_!+CWN;O+L%f+t2YZ7AQ`JzHd}}xDgvee-Y`Pm6dIVg=30Bde3Yez|47OAn zC-w>{Giw;8zc4Po9Vd`Ce!#Lr{cm#)Fwat&VvyT9KJ(!)k+)< zj!#)^@7eU_9oNrYiY0G1#q$4ksKJoQERKD%Oj^5{!KQq_ROT51lQ&+a9Qm7SE z>HTvXys+LkWD4B~lSOIQ*efOMq58v{W2bteY9s=4SAB~j$lvcdohf+!SFsFFnMz~X zU(jU?R3_`_DR031C@e##i}KsMXi8z;0WZtqvTOq5jrHz51@F3{=8$I|=Ac4OQ5p@I zujFUPeU)g6t%w+Mf3T3{`(Ad$pPDm$l$ztqa>-17-AU*|{*@W8GkJ(fryTER&6(xn zs@shXD|o&?*rR#M!*B-Mp2g%lBx#*s#eYwTGJB@nD|@MMXP4n!g=3O9Mz2-A+}8@t zIpsdHDNIdQPuFI)>VSPk%Iynybkcqey08r~0r!Tell*AT!>P9nxcHdL1jkDvw{a~=URciy!Fwcub?T4r**$n+Ci$YwJx#-g*Uu31g2GTDV zaAeF>8^Qjs_xoG*Sup)Jg!Nvk#R}J%y?&0&I&*M0!5^Ag^W`D6wjwjI!|B6tD;mM)>`su*)P_6@(RWUVT+~O1P&&$v!oMH)77A)!{pS zjq7-X)Iz&X$ecq17oY!6JoemLy`3d`j?U%pyPPvb;&9%<`J#P;-X+&pqt2wQ zO<)VztneGTPK2E%HtRan!A@O$yy9nG2R>`ht{j!$ZgtrFL(%PoXHc|(J+6tti}1JO z&D?O{sB!e-sDt9c&Lve<29>nA24s>uVo&kgHzZY)sh*+XwvmdZUW1!TH^vwgb2e9_ zwgKO-?iGKq>j=dEL>M@8fg@tY>ex9F6m^hj+>FhvY)HYe?XtGwoxk>~0NoW?iX0W{ zkiL2<>a;$SIcUeE)7)9&W#Vl5UH0WjT1V0+kLH7a;UOWc&Q>#er!dv!QFfNmR;iRXt=AM;i>ux?m2(%<$^06Cn;CP_c;S~)PuhF} z3>d5R98y12w<3*_Pb)pWYF8KZix7xo_>wY0FM)#_x!76zK*LVZ2*@zNi#IFdbC`DE zXClSi#|X&t+XTmR6pt5C@n9Vi3xO$OCmhS-DVaOxj^FwiannWL`q&G$eBGIXPgA@k zbVc*-j@g2m=W)7y@Vh}X<)CsQI%UAKGHe?Ux6flGs4i1<{yM+IX*;o$CFt`(=~2ko z1Vy}gd0Eudx|#2q!lE9Vh?_s zygBn2J<$DJk^{Ti*>K8;8v$!(&OEy2pY>`O^JifNHfi-vv73LM3SiEfdexes4v+IJWNP-yplYrpYfJNgc`EK@0?@^80Qc)N%gSd8XsY!L@yOOO6U$6x2#Sc^NS1R zD4Nr&C2CqkA@<9O;DQInJ(VW3MCO>*!`d=1aSyDQwoLOXAh!7IL=Fv%`48sr376!> zWSjHGe{J$}C?h>odxyfVw&pe}!C`8KmJ=XTJPvsMjUCr@B#prfJ)|Q3A*0AoaZH)? z3sF-y04Ez=Iv%NB_QAw!?2X5Ae6X;iBr{kcv3GSot#WPi?fYaOLD}(W%9<22C(3KB z!#m95%)fHcpTiy;k@8-RN!FdYHDo_SEeSvBzd5Pdsp3`wrf7^#WSgLq{^%k2P7RZZ zhrC^3u|il^mAocnSVyyk2SI!LUc81QVye=nwyBGh7BXBW1&2Fvv(;=Oyf;3;&~&y_ zQK@t?cG2wHNWzxOmd%65(rphu&8x#fB2f;tR8OZJ+B{tZc6fut@4o@Wl$xH%m)>?E zBU}6Yt+yKrM}VwS)6Ky%Q6$Hp`*GSiw{H#}T_5iT_6+Xc%@NFTUdx^knyP&hLrt>m zo7N7&ECSaiT=l<0U%DtPhsr{@R9-pe#D0m-uuXJAUn8A8Vbf(B{fXnU+pF+zv2hIX z5ld9*mzoR;FkE3%jya^7J(Oif%0gT{yffXqNa%7J(fP=wqcKLndG~$R0 z?Q>{<eC^k0Avx z1^gOhmgVW)K3Fys_^C;?-a3atz?x$WllU@F8@Bpc{GQmCZJM9I4HYYCkm7?>c3YG3 zuQ{-T-S%m?Zo~M#J&f3%&J5|JJX&swS+mv8rg%fSi)Ir!ffx5ti1_6V=5+Zj31RWcf_~bud44z4x{8hj<7|%M@}Kq+Bkm zIn3X{&ttDYJ=Dl0Lt^*!Y^HYP(Y6H-zZnN-v4+K^)0;yviNv5E_M;H)qbFH?2D`%TOlNq zxv-y~Q20o%eISSXm-+K;?qS}_@Dvzf&0y<7P~W_*rI^TWIqq-%76?o4J4Dpbo5Qa% zoO~(1t^bw-|XRlD&mxxWMuzp<@geX=6U`-$H9WGen7NuP%<~^5Jx=%xbB_s zuu}g#P09b-$zt}}gYhW|84K0-9Tpb`)5>UzEZYORXbS*e$cs$JadiAhpQ37qMP94^vdu43Q#wKu+FS4AFVMmMy_BW4jll>gaEMK+wGLjSOpzS`hxkL@SG@fLYA6r$) zs;ek=eiMK1l$bazn5Xq==eq4B%pOboI3A2QQ_;O<2IKP~uGP4%gsA{ch+dr;*JJoL zA6>%iX!F36X;q_AFc#S#!mgMWk%U(*V&2SlfQi4VR+W01ko#6--#3|bQ_&*Dd1oE~ zjZU{5t9GB_eZpNdcjyAdip|4~0Num>?yy=#vkyj|w58LH8GR|j34?as+srm%t5kc+ zXG`$e$PtDDz^2EY;6dS3w*4@bdF0q!2J;7Qg$%y7qs6Tk(HT@921CYmFz+Wi$Gq2K z=EAbAjn$ebp`?1;a4jP6gHhqwM-EFyH3-(+YGUU)`r?GZMiHR@7(;;3+Sw&VCheHd z6185f?Sv{S{^sH&Org>5#L}zB%U0~@oIB*LQ)*ijKSx;U3bL^`49)MSMi>f92yB33 z!QKjy!a+%nB(hGTh)s$;T@qG`Cs9=&QV*c-=OC0N?6nW~B8?7WaA#yWI-|_fg@+!% z>s*vo#SFH)*2b`&qDjB@-hk@@F`gLN zE@jfR7Fmla8lQ)IF_Nfta*>-&>@LRm?Lj$c-ZUI3ZGBn#o<)lNwJ)bm)Mk8%Pu{z@ zgr63c+Dzz^FVN5ldi!$G2=l_BY(t%HJN`&~K34IZ#zx!tNBX?juGMJ@B|&SIFI%$k zQ<}TDf}4fzQu5^RMd;9}7&zsr9Eb494hG9XIO4_!*=<7xP*1$BtvRz2HUqXB0d{|h zsE&}lxSw84=Des9{CNN=}Q|s`Rx*)^fDnSnQjjPgT56G zH61c4b?{i$dU63^)7UPYAzq`LQGK5yt6L#9)pb8eCQW8VQ@PZWd(6gT8f9S4#zpgt z!ngb?dRc>8?1MBOV%Ud^?1dV1XyC%k^DeeZ3OnC;SNWBXHP&PB?LuCiLvb`#By!=& z5yy~TO^Xf)hAGrZ1#E+ViD8P@O>-A7he^=b^KA^dn0;tP+6D|`#d+M4w#5IR`j)Kb z&o?#k{bcTLe3uQD3=evi?@GFjhO?J3#$=ZpXwM@qf9uYvJ@a7N;X}NLbkt74$_~cy zb9#}aE!TI;{1`A+C%cmMqv6CCeA$g&Op5*~1m52GfDo2c7De++b11aK^~_+tVTC-c zn_-u1>kdbZ+#c&3!A8!M1+eXxN8k=rKnik*-l`zC`( zHlO+6NesbeAPnoTT=bF%bJAJCd||;(^fUo5{^jeuXl|Wev8G5{Q0cM^j<{orji!jb z;*@7_KLFK+^b&v|0wtGf0|?5i_Nf{of@bd5ivtL4zr@De89yDhCe_Hm|#CHe>Skn$rNs zPLI?hxfX$$iQ)(hcq1HN<-Ni0HZHdg7jFJw$ZVu;kyp3Rnu9XV*6E^KRW&ktYrP71 zU;S+>g&d_X^8677>0o+dn)jE5*Ar*jrN_Hyy+TpGRUDDN!@PHTR=6%xWSio8 ze<}sPMbou@CkT&}3E7~`Y#THvTgH7I0YMFfGJ*W9m0Q+mFfChQpS80uY~angrP&6& z@zW?DV$zL={=)^B^SYr(r4=}h4DAY*kOCM~?M&-2)!QMLj95_b3_;Fb$qq9ddX}5m zT3%djrNTV*X24-Q>ot|j2bwE$c&4p-4ryBwgqKlQXv=pGHn2FB`+N%zW;vCY|25h{ zRr}{*4183ZT*?a>_T}-)WAj$U5c6YiRX}y%=`0nRb}?>PS>nhr@Lpi#_T+$lE?WN4 z^}uFCSv=_)wZ22gmLpFM@)A=<2g=lZnM{mNUafdyhwJwBT(co9s>zFg+)D9IVqadO z^sS5fpghzW7P`yb(9ux$LCFxYqceE772kp%@WiLCn)o#X_xGE1W+gnl4A$eFW1FXm z#&8qX_4~=397VOa9_Vi)9L$LpNen@%?@5PEp1>=kFqkBYis2;5YnJt*tG2U^;4ZVG6=|+GJQ3%keFTj7(BU$vFV2FSlZGRHqV4q-WM#Gd zdR?57Dv$_edNnt!)!~8Yxt)UlHnEs@(D}_PIhrQxzwcIMN1OKBjn^j(6oyD|*_7#-CyQ3{8nYM=d zl~WW9@L=TD==rC&i=%aeZ`q)9-o02+8gFZ#=@4tPPD@CWA@x^Y zAdk)E;QR4tOKH!_v!G`d>B^_P>ThyhQ* z{vu4wY!ldyNFRnT+rz&A*i0sESeO;aPFp-1T z+VAs(%^sp6YSkxEo;!)*z7aMKhw%<^*}ljMaXpJNu6{pNct~1Dg_MlMG&A=NQk>r;c76x?^6|NL5?{N6t4~ls43i zI}tHBTx`d?@NoXacL)bv%~JqjapW@0b@7gQMLCE)Ij{O}v}FR88wYQ_@uUqS8U|+o zf+_&{GIW%=jW1G{(Qr^+`dDV!Kv)4LdpqFV`-?fX%AKs{Wm)rMwe4K!rS;8_dKK!l zvc-tUwC-bFSl6*qz^3rQwc zpXex`|G9exx?0Bz^U>UXqK#q1+66nD2%MVq0FKE~eseA8dzowsf>3(eq$B{41i`L}VmGI_TOd|;6 zgeI50D9i#$AMETtU6DJest>CunZZu#UtJsJ0{iU+=HHFltQhv-a{pqIoqeHY=TkFf z?cR~zCwajD1atGw^g`eS2GJyY8nX|NI+%OJF=I$b7KlW=XUQHb?n^Ina-63SE_2-J zr!30jY1NsHRj;W3*&10q$QQ#bE9=_e zqwfwF(IT$MYv4O;vc=92;+_@Ko9#JKo%mxd0yrs5?t?v+weaG^rPL^Z ziGwO#{tn5wO*#7iq@I9iZb)7YyRa5LWz-?(j_el_);%%K?iHUjMU|6tHR(tI&eaix zp3duw>y0iw3nyXCtdA~n0gkE%hd!7Z#yYhMv=LC#uHirb3Or!B=R^en41`hgfwI}o z7?U-Bw?l&O(>}RJ6M=S*^TM^70D=;yg39NTa%AJ-?8st40f4^m@mZF?tax5nqfELY z9iu?bMj*IVn52VuEhi#usUv*cp?o|44>8!v&$5Y~8CmllSYmETYz)%$P8Hep9nSZE zCQOl4C98UsSn>F}$_@zM&hWWp+`PddY7t?1Uw!M+VsEKQdX)Mn+jVv9s(weiW;vxl zyiu6g2c>ALXp^FOgF>o|LoBSP&0`gx-^|nXvY1}Y!TkKhC6g34L zZvcSyktYo|!E%vKm5`O>D80Po022V&Aov*duRkf_$)A>?`F^Yv zx{yT9sD>U`idSVV%NYMke+tuUFv0sgR}WF&dN%23{JKS2ZO1wJ;&To0Zi}WHP7Ye%OxEZ7GAAqFaA>H9?Y zEpHkMUEbQPpDO%Q8{%gY8AtBy`)dB%Zg5g&ujWbxPZ zu>lwVM6S%#^oNMQ``PiuSB_LMUK?Q_&p3ei_{%*{5$rfn5JB{!?as-!xY ztZ;jr4}@5;Hl2a@_lAAe-lt0o52OU!6?C|=q4K^%?{5La6DhD2-1FI>XXsp}zO2zF z>3u1$_X&ZA+0S=%kQO+%GL&&df|f7tX}HnFg9pj?Qf%v?l30FJ;+iETu=QlvZv>Y( zOdlf%X0!+GD@Igb_#?ZwK!1)dn_WSA+{{pZKl~~NQvzkkJ ztG>BpfMJV6oE>ZAAn7_5OhxzdfG@DK@P!hD%V;j-bQ;DlbqX459E1Kw9+0_SG%;9h ztd%2}t$a0{O(O};S=>4vq3UKiG&6^Xz;K7KM&2j(&YJSkCHI=ltAW0==n}|fdE_9G zESss#R-})dHV5Y@$J@RKHjI{Gu@$os$jPg^o0u@{)JE8NZskum$>a zgxRpqXjS6wy;Jn5-2m0j8rSGo3eJ94f_r@{vyQg$^2c|;*yOJ9Pbb%ssUJo6BdrQL zu%;ZN@D&x~mLhlw`$Upub?l&Et8fU=1t%Q7rCLbMwn`LDcaa{uVPi zZ;P0>`R}Lp>MUM#s@3(fyRL*&=R<%1kU+vKZj0TQ6u}www>zgyo2-tC2g+Z*H{Y2& z$?N%bI9&-9?YoZ=U~-mMyMYbR&&QD7&$4ymM^(?L0dh>hkJs$)igPT_KkA4~)yo&B~bpCLCF|U#a z%Ys2M<8=>mg+Dyb<9U7D{JqoEBK@8Xg0m&%N~MJ_Y+n#co+;%V{DOS`?$&mdnd49B zO<;fNU6oWqCjlim&DCxIGN}Isi;y>bsE=`zr^Fq}>=L($D5~R=jmm5?xSXgzXIv-% z=B_+0Rp5iW#s>{3JJizmseb^O8)08_e9-zM1un^Gw7jg`RwksT!^T#a4)!5ayj7MH z5x>+CVc?JybYmO*=NPX|_b4ZoqfT7oZH>Icza4Kd4377QzU?$5j$1Wj3qovj#0qCG zq-$Ey!6ki3Z&3bbQPsj5+Q-lF0^O&4P9l24E@Tys!dN)ubP@k^}OY_YafjseC@; zpM03>7=;=HG4`{obwe+u^~>NyjV(4_Ks?>58BCN&P-Eshlsr|-zjD!WD;I)2kg#Hx zSpv6d=s{zye5#jAe(hDoF-+SC{~{*N3rwR*QT>Q|@&T!E>)dZUK)`}Q%(RLM*C`BJ zZ*d}Ohb0rO6onC0CpF4m+M{k-m8zLMN(Ca$euL6qSM?iFx>IbER}9)3-r&=DEI)=L z)?~!Mk5%mc<)u#H#<1$6DndJ)fOzajPr^?s4b&@qa5oejY$0Kz1Hk+Bj1yCe1+K&j zfIdsftvsg>Snen-h->$D*xCf>oH@VEBCV@xjp)fz&^O($zFR5<2v)|z&nWI<>IR`TSt>CC^$RPbu!u>sw`Q*ycXRzUR%8cI;GFYZ9_m*1L^_lBe z;cb@=regY<;Aa7obmMrXYTq_6;<}GP2QOcWt^y`Gh#Jw=<79+^cCD9}_%u<~Q=Qxi z1$&qi7f!Bx1FKJC26HTUB<`P1lL9!lP6ehf@hpFyihz&=Te4x@;~h!{AD6}25n*BF zZ})5F4icwYc5i@Snn)JzJhZ$b*b)&7%}g?4O;pc!#P2ekItIQ&`>zr>#;+wMZoZY3 zcByd}zxTIq!|}beHs+LxPQ!z_Pq!N|=r993yNsHE@ey!>%qPN`pLjqE-CKHXr3Bi@ z{`=zn%o=KaVb6yL7K5l{+^&NDZ+DRTYTWlaF@ic?$Oaq&Q_Toz?|W(uUWbP03kbSs zMt;!*NVEe>K|s2*8UG};skqu;5NpQd*BjU}$ffqK2zX$UHTu>43;r=^VcBp_g`0L^Zc%~{T`W<#tU0-(teJ| z{CdIj%+hiX_A8 zwhCQZ_vFGrr2_7$7i6Exq5Z{voDj)0^_c{SINFnI@iUMqrfM)tc3S~fVbEp_+}ji? z6$o!Z8l?T7v3+F_+vff+Vw~v3@%e30<0o8XG`CW)&xvQ@E*Ys07Yc$*!BWS-Vx)=_nHYn>4_b28BFBrIW_e#LtVFN}Q{R8i z++X$;eJH;nA2lHtQohxmPZzG%W+t;*BS`PcJm~M7^TCk10 z6Ys}$A5Nr#r&{*CfZ&gxs=yLyJ_AodFka&fU%WhHODf4-RlPCRZ;{~j-)J8~8uG*D zFyFE}EA%_$h8l_Bc-x|0dl!J_cVkIWkGYV55K6*nuQNgrUE1u3HbxSH_Su?;!fb!pMPZ$or31C0o(qa#E zP4i&!59pywb?ez37dUwjYdu*cKjIigV6=89ePHp0F+bHyMS&lPTd8Pl)EeC5Q=|JQ zu)~+P{{aLkhBzr|7sr26YSw!XkjfnN zPYf6H(sbSA!CKUf5{I_gLusPk3teQL+>!wVEIp69mxV+|;AEZrrA_g1@^6P17(VCK zWoiyhzuD%Fi_;veDmd5-7w&IzjKAdhURiJ(^p9d>(}%lO>SiOF6`A8dx@|1^K1b_V zFsZ16Ucl4s4?y^aM_#ncWDYC_adC{j)NB1Q?k8DeS!{9~F2Q4hWB@~KPbSJ~(>E%KiS zSYtK`kDst>#fLLHG6UAmtb(OLLszZskr{pr#%i8|G;;8;Qr_*x-&oDVuH(ip+mkG6831a9GpF`cl-|JS-7KBi9t{CV-olxK47t>K(XFPIDdpJSqOm-jP;0zu8%@MrnaTCBiMDM)Vo_u9VgxGT zz~c0(W<1AW6xzPh5lU7j~|hlsb-^Y;JYp_u!V@DWk~(Xudbg3gx@PuA_@Nyw(~kR^9Cnzrjy=^@^+C%c)hJ$$8RQd~R>)I49QP zm+d~`3eYujkYp(m{?%PMgNPx{2oRCpi#X1r4JM|67kID12ea`PxEq0d%hR^>Idqx7 zOuS$Vm&M&mipKuqBhr^OOI#Z4HY&8eo#`0`ih}fpJU4|M7YYS`TSw@K1wL^M!UkW0neF744?NPKv0fi z1*O*0+|znZD{S=%sz$P9^FS#+3N!(M)~8;r$4nhf-K4;i6ZMu4KP{M(+o%S#kTFGs z#umk$3#OOx^Qd&~iC$)C7&Dt1#&Nb$2PeO?ptgAL$?zg2zQkxSsT;#!qbWsuWl5g+ zvG!_fwL9iub?3|E7dS3AMj9Z1N*xTkcOP`>_pM8cK21G6wHv2w(>&4u2sBqXTb)wfomO`SWkI>nquubJc)}d;0(0gHCn1bMpMfi8clg>SeYUpMMj7v-Y0pq5TdSwfUplWn`Q})P?IzzY!FEmD!TZJ zc#O*)>fT{uZ930!Lt>x}-`=utB;KxOtd9serfI;}V_HkvV4TeyP5oXBYy@7CZhLC> zJ5-s`sdDCYg=Tnhdnd7m{;=o{pMQ{GICd|-1pU@ypuTMafuYCpN25-|i{_tB5H@J- zYkW}VR|Hh@ik=c+e!%!%37@&DZQ+=k{j3(yCU{0JwtSvKV+Ne^T)3Axn0CFtb&c!RE6WjS-Y?v8oR2+t~N%d0m`HTB9ZCtc}D6+t#{j1;d+{$~w zlG%I7gv~~QV+AGU$~O$9@0G!E8!M+g)~6#gSFE(bcRSy?r1EN+qe9;R6pueF$jvVC z;#%70;hcVwy|M&$GKrAny9t(c>jtxMVbeKLnJm9+gSvH*+$G`soY34tO)k0NEcqBi z#q`q%BaKaiVZigB1gu3DO=N_UT&IyeHCP`3f%MpEsrQ{Af&cWFAGPbdr<0Cl-wQR>X@9a22O2Q>ir>Wt_Q5k+)af|9i)5=Do zEpl+^P4-a!r#CXo>SNcfX{6PH|V0ZiG2};Oq(43KZqdb6g;y;vVT|lf2L>G7pIpZQ zuga@j&Wi%Jp%W5|`Pi+K_wPb5qg!p|-s8+Z+BA77u{G&GSZ<{nYDJrS6zM;RBd`;k z5DwNTGbM*e9+uS;^_TAMh*-Z+{d*aV0jSdHZ==>|_kbS+7Z>gHyolNpb5z0-Wtx>b zu!bF@{#rM>23)ZuiGm_;-P%U|V{Z&|eEbv*ES2sErMJW%Ow=nYHz-02QkYMHc^Oe( z*i{Hiu6{YLc?s3T<0b%^R2VC?^B$P{4n153N2c8+cu4u!P2%fxh(D&={wcuTM7Smv zEU+?VKzY33L)Pn+OQ_e^8}u%v8K3?M^*_DEO5_~$BFtB&M1`X_vF9#`6|tQii}vpGxR)h`fwi&8JKUGs>;-N;MTY=*yk_wr^Rd7bULVLqVqU<5wm{ zF&2-|5f~d*of`3f9xLG>Bs6q9>~>?-6kpCNi@yv4qPwZtK7Z%QvSJ|k3A*zVOWUd} zu^afVoxe+*olGNVEl;Dk@1cLv&PUiT7y9v5VCDAL2J&7eW_82`iTBqt=G5&V{lkRJ zvPH9Lu0_U+tN}xu9Ud@aiNt4fc@@+p!*BaSfP0KVk_f#GsY2_Rb?sESlPbHYsYbyj z_MgTh*wtssHikOS`E`9Sa!*f{3iS(Fpk5cFYx_xsz)lo2*p#}uY`2HmmcI+XvFk0`fb;ESGC z9=#}#KmWTx_yHMn-@~ga{`p|NLNgdIw*u^{G!t-QiRK|R#5l2Vl%zfx?##jw3G8sG zszIyBy7tIBlo-6-#Qx)(F;)*@)UfmabEtzsTzs zqm&cfvS~wdq-e>>5*%zd7omiMku^a0L+^rv_u4^KAk<_nZOW(^pX*@!r+NkzE?c7r zS@)@dX$EEtxe-U0qt~gC>~V2gu)=A`vm&v^(U;RpnP=0sR>q0J_&G4hP4Nt;cs0y- z;~36US3AP>FSV7IDwFs~^kD@A|BU?~-(xm(GWI*f5hU#1h5SLicc@ z=FcpLAvfj^SgY{Sm~97t%D%HL4lC|+RN~FnbQ(2sxi99IwZiivRbal;%q*I7whyJwX0PZw9u`b^kX$t*xo4^#Bt567eolnouPF`|hMT{Pm%G&Pgu5%9}oBZK-jcN2x^sn2T9 zVwbIdhlaF)?rSmc5Zg&ru_dC|5LfXH=086hUdM?8QS0vwbw_88WhyWz12mP^xK>pI%#dyNzEUSTm{gbLj zl@QZQ16995G+5WuT+kQ5;Qp;Ni=E&rS3H;bi12In0skCLEoP1GzA!hiMyg9CguJpr zi(^K>J2-Ev+A$XcjQ!9T4f78iTKEpJ;Ym$mSpOVk5`m$1N^QNBl6BI@8!a;u=`BdA zA=AupFUHdHr#eHIIweo{g)VO^@_r`&&+dt{+LTQ-?Y^02rVi}dX$z|}Op_R$8_Mt6 zaHK&ibZt_e20DgLJPFpR7#<8vN8}nXodX5^-Cu)W@~zM3)C6sfb(#vfMs(-3eyej@ zdcZvAEGo=>vx0cSr|&zSF>^qTnn2We*B!e)FFu+1{M*Xo7(TJG+i&aBG$>~)#dv4B z!8kMnZIs_pet%vv)N+@n#&4zm?@PHuw|=fGWeYS(zMzeGH> z>)ZZNrUVXw92~5ci%Xef=0RoAtDpD11&FufTfalG9}in#IkKAS$0SU862x!xgYY-E z-5Nh1&ua-5Y<_p-CY#1I-Q^xPRMk{xgmLgYY0b^*;mH^bImYYRP{$TP7PMak@?K3# z9xd2}?Y+VjjVkpcQy14mPPgQZ%8W{79PxiKN~{9M4HJq}dAK#gX?sKZ|UO*G= zUJ9oLVm!tMo;loX+Fh~00O(+jG;nWPCz{%(=<9)*_20Y);EETMSrU1v&z>>F^_xq# zT0e)j!M6s^ff=K~sxrP4(@`5$g^3?9A`wqsm2EUzfRCMo&UA*AY2GX=IhXK{pXA>p z#A|cB-SYYq(5h%IbpN2i1B&tX#Yn=o3p|onH!UJy+Wih@f(L2_>Zq*2p))Rj+c%^q zR0m#g`{R%7)(4-8u%epKcEDYgF;Z76q`aO3s6nECZ)fO!;sEw+gm^6H&fA*i~nc*<1q z*TVxgU8-;drqcj{wBebRK^Uj2VR)l$xeWKv#HHn#e77{r7Nooh{p!ZomJl0w|F0LU z6t7rD)791+OmDZUg(>cqIAx!mma6NhGPl|EHS39V9f8fgG8BNBD?Tu!-8B+qigh$L z+feUYw*rgGuCXsJtbMrPjyxA*Q$FhYIaqyeCg(#eN6^_~slx7!CxKOHg}gF6DW5hf z7$ACvl;U9V#9)`wjN(b`-j&l}tznckdgj6g=Kt@7!NH21MpwnImYrT;rzF_TFm)ny zZY;KIolnID35lsBUv=?w`(jp@K}g@xZac z=ltrv7kSTkV-uZ9CP#`*)eLoD9Ja!?v>tfJ;MJ$vM2@w!lldn_5tIpjlS;>(Rpmt? zm|7GTsT=tOdUuI!JC*vMCy-ObeI732?+SE=vI=&%Q5?Bsl zrOAc*)rPE@nijP?ww>(ty?l-0$nbZFPH~0}PY&P3FyR(8J|_a|$2~oDORD=k$z9;k zw6T}yVY z(>s~2>}!K*!Yf^uP|gBN*6)NRJW!WMoifWD9L+sQkAufOB$(q0c6&Ufk8mSM$I zH5UE_wO`fD{SnJ=r{F)T{$Hi=8mL%tgG3+HyhFd-wG%KH22e$dPA!^`UIDZ3M2Rn8 zvVa@-SXsMB{YDPa%aah0cC$%^kTwIoz*K^$PtP5(Q4IzB@xucm{_WZxxr}dB4}X*; zR;4>Z?hxFRC8+C%<<#R8=(iNF2$?q2aLvYh_SKYyZ_;fLQ@9jXj1y$X_$iYGJxz*p z%O<@^qCjt1umSv^Uw*d?3<|-MFH-_DM*PO;97%Qbn~H<&c^xlyKRU_unKQ{Armuke z*tK|$qaPn@3vAR)v0c0T@Hp#VY3)IsQi1KHB`C&#!m{Q-?$k63W&6I<<#TK7<4d)z zx$Vl{*m$j`t&+peN0@VVJs1ASZOQ^KAGU^yc!KPK%oc3sA*!w4Y8Tf3C@Hh7F?QXU z*0+oO{4Ui!PTG7a!?uZa#+yZ&x~t6l3qx$^u6AA@x)}pJX!1lGtENHQ#srvS?o+ML zj2%NB`AkU-sfy~B&u-i>jVm2M$u+xRrQR-8ccd0hSk=uOLj~Jg%F3iHC5d%NXpHlz zJ_eni@LwBDeq6@ofzxzdPlpdw1{F2A4y3Sd)!U3g(UqU%W4loGUJz zKxr8A<}H>7cpt+tb`{hte?=ST)!VoK0mm5t*dD%Uvpr zE?>#a0ti`N;XXX7z*k5m169KL;F*Go;sM<&QSMwb>ajdv{w*%4A=0JZe!S7`9zz9c7p*9L%bcBVKbUooB^ZHj_|nw%Pt8y z-DvNt82V5_3>*^CcAKcS#xxEhpmweUyC~jn47Ko;X%-|x0A#qSe8LMIoL7=VQ5&Rt zE;#c8hsU&SE+h8j{_k#p`*d0~zu&dS(6c*5&^zU#*CP@?fT{t%M=J)uUz#InsJV`LG_B;(N4w6zbWF-9)E4AajU zbFxWUIf|=%QkQ&7sT`0lel}jT>32rj7HM21r*j$wr&qV8*W1N!#QS9rRZ6?Y#-R4( z{ts_(e6tomD^o_SUS$*5WQzkw<${H9PL5Z5+pVe?eM^!-FJ+pw#L!91ijxApEB?S# zNdXpN-Kl?&FY%aPynH;Z!SZ>Bc5;mX-7?&rHKD z?acasTKOL3o8UC}NrUpl(2V)qYd)0}rWUPrCB`UfKQ|{Qo>lX4#V7 zja>O<@gNETst*E=CXb}L`{bIc2XkS4P+d@D`ltiGC)gqFmqmE6vuCsS>Wf$vy{11E zjHehOnC;#74e=+W{|d(7_?|=&Y@q8g*wDJYqDG92q_zZ0uPt6!<;-f02vb zD{{dqnm=E(?2`VLvUdONCrW!~o*M;W_9RU3Gz7xnEKr6sVY3MQ;DXR$v$8{~-xhesU7Kt-noLz4Bby;7_tZ zX10&}c_CB!*#-ZY^qn%nZfkG;kG=PdYI5t^g#`lAf`EXMfYi`?Z(;(Wx6pfUp@kw? zP*8de9i#|`9(wOhdQmh$=tY`J7Z6ks+$VeQ=Nspo@t&XOe81ideuR6h-1o@JT613W zn%A65>yDk5f9HNfRm&qXNH4*9{nr`WDb)BseE7dF{r3#~_YC~^4E+B+0}uXMxJ8ZhMUg|T`TnSxb94J3FxU`67WLKenzHOow~18rh5ETmJnpwt11NfzWWsi9(1=bzj+i z7+Sqop$EWRvViu}0k|CRB$r=0;5}u5&tG7@addf{()}gySKW&H*Akx6r^4@yXjm69 zDJ4oQMmc}7TR<0gm|!ib(U4k>w;eje*Aja`J9W~cY#E*+LwZf0e@C$BY%~iOf)?id z3)bvs?)AJ8bH{wbtO0|8UmOKE0d;^_?lU@(aoDZ&Vz=VmKiSeCwE7{84;)S5{6s5< z*go79Bgx9;qR}cvE*Tsa+BZXnnZ-P~kqpiBRCfNnUWbF_)oZjsl2Vme?AAY(pS8Ow z+fkZgxhM>opI@;Nz6Hk?a?>_fm1^bI%%zni~y4SWu3JQ^h-%lKDDvF(qAn8c5R zq7xP)J948%+Cx3J<*tNFL$TW56D#G{^hl_L;S+xSu;xQi<|%q}U3eP=#Gs!wsWEfS zd-uVcrz6dZvX>so@*^LlPmSz|jjRe4p8RzKu?qyI43A@A`Q4)Pm-=FLZ=5n`Z}MdW zH6f(IQG|+8;o_!wPy1QQH^V38CusGYp_exw)QKadat_VUpG7nlQ!`0g5!Q?w`_1?b=^`` zR=UiW){-0H`bo6>o|peG5Miy}v7rMKOLw&T+y5^5ll%i%K$S!|@W4$NubzJY)`0oX zS0??X_jro!Z|$<$s`A-EqRNI!<4@O^%l?sGBS}*~>27uvcfUd(Ix&+LIYQX<$J+v-<7|$EVzxq&DLS zo0|R?RbBVSmgN>O0$RxLU;RM5QGA-}p?-oR&ej(95*`zKV@ur5^b zru+!=PTRWRIjNKa*Y2N${Ce&fQ403cdzBCc{kqE34ifAJamEHs*2^Bnt~7^5E-<+_ zyQZ}U)1=2uzB%ex;C`ee!^-U4Q%hQGQ5;4Cv`C(wvs-+tNFbi3P|~4NTj*Op9HM z^H4K=o9psbfIm{OI0&#O=@M7U{hQt)!O+&saPZyPX)gL1Vr|QI%TF)!h|1TV^pl#N z{`LVLL>(b2Lf7BNOLfV0fzG7@6C+C%f8PA`Y}6c+)PSFFzYLCwAH~gHhHoBGjs{VV z#LA-SX;?VjCu{1CPH+A6dg3dix~nqhd3@)4(__zPDQ?#dO`Zm+NUBSAjY7Sg8Jcl< zBL1D9WB0e(!FFMScwT%Ly|uBm56*lnD3DcEydoO!MI#kTXaKGFCHRV`bmstzkWx5S3=J{wOmEcj4+@yvdNV ztYgtot!jwQN1u>+2Q0ZZX}sX9mzh+<8@z0z;Hc1{6`sVssO~Gwnw=8tc=o#!Nxz7d zPNE~j#>PpPq(sxF%s|*{kF*AH9@~gNVQpi=r!)`he56mf$J3JREJtO@-of0(a`+{B z*QclG3|je$7=NcTeM#mV5a(y>@7!E?eeL|~5q$XUff1`JM`8AY<0+i}O$sP^$Q%

(L{~=eQn{Z{D}w%X1aaFtyz$_Wz#yq+nDFUr>HY8Ey@KWI}Br8@csu z)5s8|O`e;1(`TIHASLBqK?ji_&z1e(R(R$gD@@-O@h6IQEo^?A*rWjC-s0XYkv~vG z)Eb~{n;_Cz!<$a=O7Mw0o{uf3s*|6rwT;jjNdU@|G8Vj(!$0%q;3MwHS{l+O8&!oI zDq+6ew<445zf%L&meu%YaW2@%$qX1Mjfd86NyF=xymEi*tjql*;LM<$YfWH0W4+d z_E7&`NId0tp0%)7t(40}X}(cC{&b(J=% zxqtk?3chdsvc5rip}}bKUHP*zcOF|Szbx5q`_d|~M(D9KB6qNTH$_h<2wbzJU^%*$01U#v31*T>O+?Q0T|T2<=tr%Rdcy9@x@+y9=(< zXra2jvxvQXfk}9(NbwUmcwl)sn1H7qb(UV`{W+!i7XVjpv*~e{GiJ)I-=-jnibZ6eb2fQ{H7N#9ort zAs@^se}cY`!n_bGiF$7|kk$f>OvP(G9&2L_kyipCi*MfByXaBx)u_yj@Q(1Xc^H#= z8=grlx6byF*$WeD^0-abQZ#?qa^}H#p=uxjH5fPv@~UH&d|{M@Oe~ zbaVcgl>i%J>2<}W{q;$U>_tD$-#3*$^|>Eyd*i)i#@&Q^wxDmO`Wbq>?G9J3U*Iaq zZ<5|0=`*yQ&iiVPPFG*`=PsMg0d#t^MZUlUwE*i;ECR-c&)E|pcIv>zX76$MfR7uC z<)08P{HYe%;vf|gupbr0?O#P~WPRR?3I3k(8?5iz2Dd zCG95FdliegYqS4>%)9)ci0cOhbG6x;-7-|PA~{H)4XDWyQxlKu5O3*pmGmkxk*oba8AwJk=OSTY|rQw?RqK~?1f#h z*b&KCU&d^cCk7`qU;`)ZEIvZLz~Lqo&_v$%d(x*or)E;@Gw)nB>`NgRo6UbJP~HZP zt*S=Q2emz?R*DJAX+qoI?4Lrf0`A|oW>__(<@zO$1%*{1rK3_)!jfyByotMf!0PwD znO&0$aI~&gmxuQxzlwDKgWp_EkLoTV_A0$taorF2GJOyS)VXEKH=uL2H4SuM=}K>C zeZTtmor5l!AhfR~+1-yHB8RJ>~gW`t*`Je#<=wIwz_ zW7K-5pSr&as(}@^OcMScW3|F5ta;nh{ITCojYBri#OPh!rgVlS3P8Q~_h9t%_%lt9 z+4$enPcFwTLj#Myre9^N57p<749G;BAMNjFj6+_%bht7Lp`S>cMGyXdgtNB!b#u&@ z4C6%xUt~(46L_5w6iAU|$K9^=q`JXYHP%|)N{H)A6maY7mqfyvTcv{p4ta%JaPh|I zAY9wN=R8n)v)v{oz_)7buc#W@gJ=73SdzPPOwAVmslv2>>UigFO+#Faoi{HDuCM zGkhN;CB@>sc4Fl{FwJAqCRV+3ho!$Dj0(?1SUUs@^a2|g#@xtd1A=RXK)=;}l~8_M z-&qp-dzkxv=~`QwrVsD+M=Dr(w0ngU-DL4EqO6x|I22j9*oUu4T@11l)SNE)XQz*{ zH|_X?s$xBbRgB;i4jHn^Z*mA8*(yYjMR5xzg$$J2Xu2S1p>|B7zUeRmQc!`47w~l0 z{_X}+>Uil|-&A9_?d$t9%EyQz{QGgIE|vg9jP^1#S7y{4cK%e#6Bk7O#L_8xTr;*T z*$)E9Hu(GQHX%G<+@QoO>h(3q=G9?uybr%fQ2G{9>f4;;tUqaSsJ}K@{nk=s9U_=d zBf5C-nQK|!osfx4wWQ_e~9 z40Hz+!a$Mm`_HHDa-9llAf$HdxvW7S1b@H#Ue3xD!<$~8?laVZg`1R*?MQ)uWIR*# z(SP00z8WR035WNBa6oPryYv2&{q+paUpJRaU0stPTj_SK(Iqc4krX&>3iDh-{QvZ> z`N&2q@<}T*Nr>jvm;OBMVohYJ?3jh`@xBz_%=X_m4r}cs`eY!{2W>$zP!Id4Y`>=D zDWXf&Ap2&$exH;*IF7oFyIP#YZw)yOX4e7KN&ao(P6dMasmCp2Wg~ZtcMU@WHfwz1 z-z*!U^}eh;4@`o4S5p~Dp58ny_X_B4Ek<~eH5Ag~)g!l?YKM)&f2lzAOL+vYp$lMDZWw-R9CzSkzYhq3dA-4}fGEE$&NpuAF^2g__J_U}Mm z{ue(CFfBFRgk+tnbQE-#V6?dyQ%<&7+ZxaP@sf𓼇^qm}GlN?EF{`3M@tb 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 z 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 z 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%0AnS7i6=nbd+87JKfg5eP@I-wK?hw2yc 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 xY7D=IhlYHMKDrw-FI5@;^tQ} { const formatDate = (string) => { @@ -28,38 +32,72 @@ const EventPreview = (props) => { return date.toLocaleTimeString("en-US", options); }; + const priceText = props.data.price === 0 ? "Free" : `$${props.data.price}`; + return ( - - {/* */} + <> + + + + + - - {props.data.title} - - {/* - {props.data.admin.name} - */} - + {formatDate(props.data.start)}-{formatHour(props.data.end)} - - ${props.data.price} +

+ + {/* */} + {props.data.admin.name} - - - ); }; diff --git a/src/components/EventPreviewList.js b/src/components/EventPreviewList.js index 393f2fc9..9610be21 100644 --- a/src/components/EventPreviewList.js +++ b/src/components/EventPreviewList.js @@ -22,7 +22,7 @@ const EventPreviewList = () => { }, []); const eventPreviews = events.map((event) => ); - return
{eventPreviews}
; + return <>{eventPreviews}; }; export default EventPreviewList; diff --git a/src/components/navbar.js b/src/components/navbar.js index bf1cb70b..536f681b 100644 --- a/src/components/navbar.js +++ b/src/components/navbar.js @@ -6,35 +6,43 @@ import ExploreIcon from "@mui/icons-material/Explore"; import BookmarkIcon from "@mui/icons-material/Bookmark"; import EventIcon from "@mui/icons-material/Event"; import PersonIcon from "@mui/icons-material/Person"; +import { ThemeProvider } from "@mui/material/styles"; //-----------Components-----------// +import theme from "../theme"; //-----------Styling-----------// import "../App.css"; export default function NavBar() { return ( - - + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + ); } diff --git a/src/components/searchBar.js b/src/components/searchBar.js index 4769dfc7..92cac871 100644 --- a/src/components/searchBar.js +++ b/src/components/searchBar.js @@ -8,6 +8,7 @@ import { Input, IconButton } from "@mui/material"; import Box from "@mui/material/Box"; import Drawer from "@mui/material/Drawer"; import Button from "@mui/material/Button"; +import { Chip, Stack } from "@mui/material"; import List from "@mui/material/List"; import Divider from "@mui/material/Divider"; import ListItem from "@mui/material/ListItem"; @@ -17,13 +18,14 @@ import Checkbox from "@mui/material/Checkbox"; import FormGroup from "@mui/material/FormGroup"; import FormControlLabel from "@mui/material/FormControlLabel"; import axios from "axios"; +import Container from "@mui/material/Container"; //-----------Components-----------// import "./searchBar.css"; import { BACKEND_URL } from "../constant.js"; export default function SearchBar() { - const [keyword, setKeyword] = useState(""); + const [keyword, setKeyword] = useState("all"); const [open, setOpen] = useState(false); const navigate = useNavigate(); const [categories, setCategories] = useState([]); @@ -35,7 +37,7 @@ export default function SearchBar() { const response = await axios.get(`${BACKEND_URL}/categories`); const initialCheckedCategories = {}; response.data.forEach((category) => { - initialCheckedCategories[category.id] = true; + initialCheckedCategories[category.id] = false; }); setCheckedCategories(initialCheckedCategories); setCategories(response.data); @@ -55,6 +57,7 @@ export default function SearchBar() { const selectedCategories = Object.keys(checkedCategories).filter( (categoryId) => checkedCategories[categoryId] ); + navigate(`/search/${keyword}`, { state: { categories: selectedCategories }, }); @@ -71,6 +74,16 @@ export default function SearchBar() { })); }; + const chips = categories.map((category) => ( + handleCategoryToggle(category.id)} + /> + )); + const handleResetCategory = () => { const resetCategories = {}; Object.keys(checkedCategories).forEach((categoryId) => { @@ -139,16 +152,58 @@ export default function SearchBar() { ); return ( -
- setKeyword(e.target.value)} - /> - - +
+ + setKeyword(e.target.value)} + defaultValue="all" + /> + + + + +
+ + } + label="Filter" + /> + {chips} + +
+
+ {FilterList} diff --git a/src/pages/userPages/eventDetailPage.js b/src/pages/userPages/eventDetailPage.js index ca07eb4d..fbf72127 100644 --- a/src/pages/userPages/eventDetailPage.js +++ b/src/pages/userPages/eventDetailPage.js @@ -1,6 +1,6 @@ //-----------Libraries-----------// import { useState, useEffect } from "react"; -import { useParams } from "react-router-dom"; +import { useParams, Link } from "react-router-dom"; import axios from "axios"; import Button from "@mui/material/Button"; import Dialog from "@mui/material/Dialog"; @@ -8,11 +8,22 @@ import { Box } from "@mui/material"; import DialogTitle from "@mui/material/DialogTitle"; import { useAuth0 } from "@auth0/auth0-react"; import { Typography, Grid } from "@mui/material"; +import { createRoot } from "react-dom/client"; +import ArrowBackIcon from "@mui/icons-material/ArrowBack"; +import { + APIProvider, + Map, + Marker, + AdvancedMarker, + Pin, +} from "@vis.gl/react-google-maps"; //-----------Components-----------// import EventBookingPage from "./eventBookingPage"; import { BACKEND_URL } from "../../constant.js"; +const API_KEY = String(process.env.GOOGLE_MAPS_API_KEY); + export default function EventDetailPage() { const [event, setEvent] = useState(); const [eventId, setEventId] = useState(); @@ -71,7 +82,6 @@ export default function EventDetailPage() { Price: ${event.price} - @@ -80,6 +90,33 @@ export default function EventDetailPage() { + + + + + + + Language: {event.language.name} @@ -107,6 +144,9 @@ export default function EventDetailPage() { return (
+ + + {eventInfo} {showRegistration && ( diff --git a/src/pages/userPages/homePage.js b/src/pages/userPages/homePage.js index 74edb0d9..aaa9889d 100644 --- a/src/pages/userPages/homePage.js +++ b/src/pages/userPages/homePage.js @@ -1,7 +1,8 @@ //-----------Libraries-----------// import { useState, useEffect } from "react"; -import SearchIcon from "@mui/icons-material/Search"; -import TextField from "@mui/material/TextField"; +import { ThemeProvider } from "@mui/material/styles"; +import theme from "../../theme"; +import Typography from "@mui/material/Typography"; //-----------Components-----------// import EventPreviewList from "../../components/EventPreviewList"; @@ -9,11 +10,25 @@ import SearchBar from "../../components/searchBar"; export default function HomePage() { return ( -
-
- - + +
+
+ + +
+ {" "} + +
+
-
+ ); } diff --git a/src/pages/userPages/searchPage.js b/src/pages/userPages/searchPage.js index 07545f80..1b9f113e 100644 --- a/src/pages/userPages/searchPage.js +++ b/src/pages/userPages/searchPage.js @@ -3,6 +3,15 @@ import { useState, useEffect } from "react"; import { useOutletContext, useParams } from "react-router-dom"; import { useLocation } from "react-router-dom"; import axios from "axios"; +import { ThemeProvider } from "@mui/material/styles"; +import theme from "../../theme"; +import { + Card, + Button, + Switch, + Backdrop, + CircularProgress, +} from "@mui/material"; //-----------Components-----------// import { BACKEND_URL } from "../../constant.js"; @@ -15,6 +24,7 @@ export default function SearchPage() { const { state } = useLocation(); const selectedCategories = state && state.categories ? state.categories : []; const [events, setEvents] = useState([]); + const [loading, setLoading] = useState(true); useEffect(() => { const fetchData = async () => { @@ -27,8 +37,10 @@ export default function SearchPage() { ); setEvents(response.data); + setLoading(false); } catch (error) { console.error("Error fetching data:", error); + setLoading(false); } }; @@ -49,9 +61,29 @@ export default function SearchPage() { ); return ( -
- - {eventPreviews} -
+ +
+
+ + + {" "} + {/* Conditionally render Backdrop based on loading state */} +

Searching for events...

+ +
+
+ {eventPreviews} +
+
+
+
); } diff --git a/src/theme.js b/src/theme.js new file mode 100644 index 00000000..2ffd4665 --- /dev/null +++ b/src/theme.js @@ -0,0 +1,20 @@ +import { createTheme } from "@mui/material/styles"; + +const theme = createTheme({ + palette: { + primary: { + main: "#5A5A5A", + }, + secondary: { + main: "#0DCDAA", + }, + error: { + main: "#F0635A", + }, + info: { + main: "#81AC80", + }, + }, +}); + +export default theme; From cb893ec535011e41922b613ff722dff7b7ec4c39 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Sat, 6 Apr 2024 01:15:43 +0800 Subject: [PATCH 23/69] updated --- src/pages/userPages/eventDetailPage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/userPages/eventDetailPage.js b/src/pages/userPages/eventDetailPage.js index fbf72127..230547a0 100644 --- a/src/pages/userPages/eventDetailPage.js +++ b/src/pages/userPages/eventDetailPage.js @@ -90,7 +90,7 @@ export default function EventDetailPage() { - + Date: Sat, 6 Apr 2024 10:27:25 +0800 Subject: [PATCH 24/69] updated --- src/components/navbar.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/navbar.js b/src/components/navbar.js index 536f681b..cdf24b00 100644 --- a/src/components/navbar.js +++ b/src/components/navbar.js @@ -32,9 +32,9 @@ export default function NavBar() { - + {/* - + */} From d111afc76a94e068527cccc961f5a95c58991410 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Sat, 6 Apr 2024 10:51:58 +0800 Subject: [PATCH 25/69] fixed search filter category bug by clearing events --- src/pages/userPages/eventDetailPage.js | 4 +--- src/pages/userPages/searchPage.js | 4 +++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pages/userPages/eventDetailPage.js b/src/pages/userPages/eventDetailPage.js index 230547a0..8a6078d9 100644 --- a/src/pages/userPages/eventDetailPage.js +++ b/src/pages/userPages/eventDetailPage.js @@ -22,8 +22,6 @@ import { import EventBookingPage from "./eventBookingPage"; import { BACKEND_URL } from "../../constant.js"; -const API_KEY = String(process.env.GOOGLE_MAPS_API_KEY); - export default function EventDetailPage() { const [event, setEvent] = useState(); const [eventId, setEventId] = useState(); @@ -90,7 +88,7 @@ export default function EventDetailPage() { - + { const fetchData = async () => { try { + setEvents([]); + setLoading(true); const response = await axios.get( `${BACKEND_URL}/events/search/${keyword}`, { @@ -45,7 +47,7 @@ export default function SearchPage() { }; fetchData(); - }, [keyword]); + }, [keyword, selectedCategories]); console.log(events); From b3f7c2d9ed6a1f1b2fd885fc52b9683b086ed554 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Sat, 6 Apr 2024 10:56:56 +0800 Subject: [PATCH 26/69] amended --- src/pages/userPages/eventDetailPage.js | 2 +- src/pages/userPages/searchPage.js | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/pages/userPages/eventDetailPage.js b/src/pages/userPages/eventDetailPage.js index 8a6078d9..aa04b47a 100644 --- a/src/pages/userPages/eventDetailPage.js +++ b/src/pages/userPages/eventDetailPage.js @@ -88,7 +88,7 @@ export default function EventDetailPage() { - + 0 ? (
From cf1bda8c86fa30155b664baa81bc3539dc2b1ed0 Mon Sep 17 00:00:00 2001 From: kendigm Date: Sat, 6 Apr 2024 21:11:10 +0500 Subject: [PATCH 27/69] Auth0 Login Signup Forgetpassword signin with google email verfication --- package-lock.json | 31 +++++++ package.json | 1 + src/App.js | 49 ++++++---- src/index.js | 15 ++- src/pages/registerPage.js | 58 ++++++------ src/pages/signInPage.js | 131 +++++++++++++++------------ src/pages/userPages/homePage.js | 73 ++++++++++++++- src/pages/userPages/myProfilePage.js | 80 +++++++--------- src/slices/AuthSlices.js | 25 ----- src/slices/apiSlices.js | 11 --- src/slices/usersApiSlices.js | 30 ------ 11 files changed, 280 insertions(+), 224 deletions(-) delete mode 100644 src/slices/AuthSlices.js delete mode 100644 src/slices/apiSlices.js delete mode 100644 src/slices/usersApiSlices.js diff --git a/package-lock.json b/package-lock.json index b46d72e5..f0b11473 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "project-3-frontend-bootcamp", "version": "0.1.0", "dependencies": { + "@auth0/auth0-react": "^2.2.4", "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.0", "@mui/icons-material": "^5.15.14", @@ -37,6 +38,23 @@ "node": ">=6.0.0" } }, + "node_modules/@auth0/auth0-react": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@auth0/auth0-react/-/auth0-react-2.2.4.tgz", + "integrity": "sha512-l29PQC0WdgkCoOc6WeMAY26gsy/yXJICW0jHfj0nz8rZZphYKrLNqTRWFFCMJY+sagza9tSgB1kG/UvQYgGh9A==", + "dependencies": { + "@auth0/auth0-spa-js": "^2.1.3" + }, + "peerDependencies": { + "react": "^16.11.0 || ^17 || ^18", + "react-dom": "^16.11.0 || ^17 || ^18" + } + }, + "node_modules/@auth0/auth0-spa-js": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@auth0/auth0-spa-js/-/auth0-spa-js-2.1.3.tgz", + "integrity": "sha512-NMTBNuuG4g3rame1aCnNS5qFYIzsTUV5qTFPRfTyYFS1feS6jsCBR+eTq9YkxCp1yuoM2UIcjunPaoPl77U9xQ==" + }, "node_modules/@babel/code-frame": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", @@ -16637,6 +16655,19 @@ "@jridgewell/trace-mapping": "^0.3.9" } }, + "@auth0/auth0-react": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@auth0/auth0-react/-/auth0-react-2.2.4.tgz", + "integrity": "sha512-l29PQC0WdgkCoOc6WeMAY26gsy/yXJICW0jHfj0nz8rZZphYKrLNqTRWFFCMJY+sagza9tSgB1kG/UvQYgGh9A==", + "requires": { + "@auth0/auth0-spa-js": "^2.1.3" + } + }, + "@auth0/auth0-spa-js": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@auth0/auth0-spa-js/-/auth0-spa-js-2.1.3.tgz", + "integrity": "sha512-NMTBNuuG4g3rame1aCnNS5qFYIzsTUV5qTFPRfTyYFS1feS6jsCBR+eTq9YkxCp1yuoM2UIcjunPaoPl77U9xQ==" + }, "@babel/code-frame": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", diff --git a/package.json b/package.json index a47b3cff..185126f9 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "private": true, "proxy": "http://localhost:5000", "dependencies": { + "@auth0/auth0-react": "^2.2.4", "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.0", "@mui/icons-material": "^5.15.14", diff --git a/src/App.js b/src/App.js index e16ab3a5..d6a4101f 100644 --- a/src/App.js +++ b/src/App.js @@ -1,6 +1,6 @@ //-----------Libraries-----------// -import React from "react"; -import { BrowserRouter, Routes, Route } from "react-router-dom"; +import React, { useEffect, useState } from "react"; +import { BrowserRouter, Routes, Route, Navigate } from "react-router-dom"; //-----------Components-----------// import NavBar from "./components/navbar.js"; @@ -30,7 +30,11 @@ import AdminProfilePage from "./pages/adminPages/adminProfilePage.js"; import AdminEventPage from "./pages/adminPages/adminEventPage.js"; import AdminEventAttendancePage from "./pages/adminPages/adminEventAttendancePage.js"; import AdminAnalyticsPage from "./pages/adminPages/adminAnalyticsPage.js"; -import { Toaster } from "react-hot-toast"; +import { Toaster } from "react-hot-toast"; + +// Auth0 +import { useAuth0 } from "@auth0/auth0-react"; +import axios from "axios"; const AdminRoutes = () => ( @@ -44,23 +48,36 @@ const AdminRoutes = () => ( ); const App = () => { + const { + loginWithRedirect, + loginWithPopup, + isAuthenticated, + logout, + isLoading, + getAccessTokenSilently, + user, + } = useAuth0(); + return ( - + {isAuthenticated && } } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> + {!isAuthenticated ? ( + } /> // Show SignInPage if not authenticated + ) : ( + <> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + )} diff --git a/src/index.js b/src/index.js index dd8aa367..5b9e4693 100644 --- a/src/index.js +++ b/src/index.js @@ -1,17 +1,22 @@ //-----------Libraries-----------// import React from "react"; import ReactDOM from "react-dom/client"; -import store from "./Store.jsx"; -import { Provider } from "react-redux"; //-----------Components-----------// import App from "./App"; //-----------Styling-----------// import "./index.css"; +import { Auth0Provider } from "@auth0/auth0-react"; +const domain = process.env.REACT_APP_AUTH0_DOMAIN; +const clientId = process.env.REACT_APP_AUTH0_CLIENT_ID; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( - - - + + + ); diff --git a/src/pages/registerPage.js b/src/pages/registerPage.js index 43413ca1..e426d13a 100644 --- a/src/pages/registerPage.js +++ b/src/pages/registerPage.js @@ -10,10 +10,10 @@ import LockOutlinedIcon from "@mui/icons-material/LockOutlined"; import ArrowForwardIcon from "@mui/icons-material/ArrowForward"; import ArrowBackIcon from "@mui/icons-material/ArrowBack"; import PersonOutlineOutlinedIcon from "@mui/icons-material/PersonOutlineOutlined"; -import { useRegisterMutation } from "../slices/usersApiSlices"; -import { useDispatch, useSelector } from "react-redux"; +// import { useRegisterMutation } from "../slices/usersApiSlices"; +// import { useDispatch, useSelector } from "react-redux"; import { useEffect, useState } from "react"; -import { setCredentials } from "../slices/AuthSlices"; +// import { setCredentials } from "../slices/AuthSlices"; import toast from "react-hot-toast"; @@ -22,32 +22,32 @@ export default function RegisterPage() { const [email, setEmail] = useState(); const [password, setPassword] = useState(); const [confirmPassword, setConfirmPassword] = useState(); - const dispatch = useDispatch(); - const navigate = useNavigate(); - const { userInfo } = useSelector((state) => state.auth); - const [register, { isLoading }] = useRegisterMutation(); + // const dispatch = useDispatch(); + // const navigate = useNavigate(); + // const { userInfo } = useSelector((state) => state.auth); + // const [register, { isLoading }] = useRegisterMutation(); - useEffect(() => { - if (userInfo) { - navigate("/profile"); - } - }, [navigate, userInfo]); - async function handleRegister(e) { - e.preventDefault(); - if (password !== confirmPassword) - return toast.error(`Password not matched 😶`); - try { - const res = await register({ email, password, name }).unwrap(); - setName(""); - setEmail(""); - setPassword(""); - setConfirmPassword(""); - toast.success(res.message); - navigate("/signin"); - } catch (err) { - console.log(err?.data?.message || err.error); - } - } + // useEffect(() => { + // if (userInfo) { + // navigate("/profile"); + // } + // }, [navigate, userInfo]); + // async function handleRegister(e) { + // e.preventDefault(); + // if (password !== confirmPassword) + // return toast.error(`Password not matched 😶`); + // try { + // const res = await register({ email, password, name }).unwrap(); + // setName(""); + // setEmail(""); + // setPassword(""); + // setConfirmPassword(""); + // toast.success(res.message); + // navigate("/signin"); + // } catch (err) { + // console.log(err?.data?.message || err.error); + // } + // } return (
@@ -145,7 +145,7 @@ export default function RegisterPage() { -
-
- - + Sign In + +
+ +
+ + )} + + {/* { > Sign Up - +
*/} diff --git a/src/pages/userPages/homePage.js b/src/pages/userPages/homePage.js index 5580d4dc..44353391 100644 --- a/src/pages/userPages/homePage.js +++ b/src/pages/userPages/homePage.js @@ -1,13 +1,80 @@ //-----------Libraries-----------// import { useState, useEffect } from "react"; - +import Grid from "@mui/material/Grid"; +import Paper from "@mui/material/Paper"; +import Button from "@mui/material/Button"; //-----------Components-----------// import EventPreviewList from "../../components/EventPreviewList"; - +import ArrowForwardIcon from "@mui/icons-material/ArrowForward"; +import { useAuth0 } from "@auth0/auth0-react"; export default function HomePage() { + const { + loginWithRedirect, + loginWithPopup, + isAuthenticated, + logout, + isLoading, + user, + } = useAuth0(); return (
- + {!isAuthenticated ? ( +
+ + + + + + + +
+ ) : ( + + )}
); } diff --git a/src/pages/userPages/myProfilePage.js b/src/pages/userPages/myProfilePage.js index 9b5cbd41..4fd2b98f 100644 --- a/src/pages/userPages/myProfilePage.js +++ b/src/pages/userPages/myProfilePage.js @@ -1,4 +1,4 @@ -import React, { useEffect } from "react"; +import React, { useEffect, useState } from "react"; import Avatar from "@mui/material/Avatar"; import Typography from "@mui/material/Typography"; import List from "@mui/material/List"; @@ -12,59 +12,47 @@ import ContactSupportIcon from "@mui/icons-material/ContactSupport"; import SettingsIcon from "@mui/icons-material/Settings"; import HelpIcon from "@mui/icons-material/Help"; import ExitToAppIcon from "@mui/icons-material/ExitToApp"; +import { useAuth0 } from "@auth0/auth0-react"; +import axios from "axios"; import { Link, useNavigate } from "react-router-dom"; -import { useDispatch, useSelector } from "react-redux"; -import toast from "react-hot-toast"; -import { useLogoutMutation } from "../../slices/usersApiSlices"; -import { logoutt } from "../../slices/AuthSlices"; // Refactor the component to start with an uppercase letter const MyProfilePage = () => { - const user = { - name: "Glory Kendi", - profileImg: "/logo192.png", - unreadMessages: 3, // Number of unread messages - }; - const { userInfo } = useSelector((state) => state.auth); - const [logout] = useLogoutMutation(); // destructuring - const dispatch = useDispatch(); + const { isAuthenticated, logout, isLoading, getAccessTokenSilently, user } = + useAuth0(); + const domain = process.env.REACT_APP_AUTH0_DOMAIN; const navigate = useNavigate(); useEffect(() => { - if (!userInfo) { - navigate("/signin"); + if (!isAuthenticated) { + navigate("/"); } - }, [navigate, userInfo]); - const handleLogout = async (e) => { - try { - const res = await logout(); - dispatch(logoutt()); - // navigate("/signin"); - // window.location.href = "/signin"; - toast.success(res?.data?.message); - } catch (error) { - toast.error(error.message); - } - }; + }, [isAuthenticated, navigate]); return (
-
+ {isLoading ? ( +

loading...

+ ) : (
- +
+ +
+ + {user && user?.nickname} + + {/* {user && !user?.email_verified &&

Please verify your email

} */}
- - {userInfo?.name} - -
+ )} + @@ -77,11 +65,11 @@ const MyProfilePage = () => { - {user.unreadMessages > 0 && ( - - {user.unreadMessages} - - )} + {/* {user.unreadMessages > 0 && ( */} + + {/* {user.unreadMessages} */} + + {/* )} */} @@ -115,9 +103,9 @@ const MyProfilePage = () => { logout()} > diff --git a/src/slices/AuthSlices.js b/src/slices/AuthSlices.js deleted file mode 100644 index 18e3d2bc..00000000 --- a/src/slices/AuthSlices.js +++ /dev/null @@ -1,25 +0,0 @@ -import { createSlice } from "@reduxjs/toolkit"; - -const initialState = { - userInfo: localStorage.getItem("userInfo") - ? JSON.parse(localStorage.getItem("userInfo")) - : null, -}; - -const authSlice = createSlice({ - name: "auth", - initialState, - reducers: { - setCredentials: (state, action) => { - state.userInfo = action.payload; - localStorage.setItem("userInfo", JSON.stringify(action.payload)); - }, - logoutt: (state, action) => { - state.userInfo = null; - localStorage.removeItem("userInfo"); - }, - }, -}); - -export const { setCredentials, logoutt } = authSlice.actions; -export default authSlice.reducer; diff --git a/src/slices/apiSlices.js b/src/slices/apiSlices.js deleted file mode 100644 index cb84b46f..00000000 --- a/src/slices/apiSlices.js +++ /dev/null @@ -1,11 +0,0 @@ -import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; - -const baseQuery = fetchBaseQuery({ - // baseUrl: "http://localhost:5000", - credentials: "include", -}); -export const apiSlice = createApi({ - baseQuery, - tagTypes: ["User"], - endpoints: (builder) => ({}), -}); diff --git a/src/slices/usersApiSlices.js b/src/slices/usersApiSlices.js deleted file mode 100644 index 23c9e03d..00000000 --- a/src/slices/usersApiSlices.js +++ /dev/null @@ -1,30 +0,0 @@ -import { apiSlice } from "./apiSlices"; - -const USERS_URL = "/api/auth"; -export const userApiSlice = apiSlice.injectEndpoints({ - endpoints: (builder) => ({ - login: builder.mutation({ - query: (data) => ({ - url: `${USERS_URL}/signin`, - method: "POST", - body: data, - }), - }), - register: builder.mutation({ - query: (data) => ({ - url: `${USERS_URL}/signup`, - method: "POST", - body: data, - }), - }), - logout: builder.mutation({ - query: () => ({ - url: `${USERS_URL}/logout`, - method: "POST", - }), - }), - }), -}); - -export const { useLoginMutation, useRegisterMutation, useLogoutMutation } = - userApiSlice; From 07f073edd9351b97124c15bc968b99901a87ef4b Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Sun, 7 Apr 2024 01:17:22 +0800 Subject: [PATCH 28/69] added maps in search and scroll function, added maps in booking --- src/App.css | 5 ++ src/components/BookingPreview.js | 55 +++++++++---- src/components/navbar.js | 14 ++-- src/components/searchBar.js | 11 ++- src/pages/userPages/eventDetailPage.js | 5 +- src/pages/userPages/homePage.js | 28 +++---- src/pages/userPages/myBookingPage.js | 54 ++++++------- src/pages/userPages/searchPage.js | 108 ++++++++++++++++++------- src/theme.js | 7 +- 9 files changed, 183 insertions(+), 104 deletions(-) diff --git a/src/App.css b/src/App.css index 97b7c578..38083432 100644 --- a/src/App.css +++ b/src/App.css @@ -17,3 +17,8 @@ font-size: calc(10px + 2vmin); color: white; } + +a:visited { + color: inherit; + text-decoration: none; +} diff --git a/src/components/BookingPreview.js b/src/components/BookingPreview.js index e34592ef..5ab29ca7 100644 --- a/src/components/BookingPreview.js +++ b/src/components/BookingPreview.js @@ -1,12 +1,16 @@ //-----------Libraries-----------// import Card from "@mui/material/Card"; import CardContent from "@mui/material/CardContent"; -import CardActions from "@mui/material/CardActions"; -import Button from "@mui/material/Button"; import Typography from "@mui/material/Typography"; import { Link } from "react-router-dom"; +import { + APIProvider, + Map, + AdvancedMarker, + Pin, +} from "@vis.gl/react-google-maps"; -const EventPreview = (props) => { +const BookingPreview = (props) => { const formatDate = (string) => { const date = new Date(string); const options = { @@ -29,26 +33,49 @@ const EventPreview = (props) => { }; return ( - - {/* */} + + + + + + + + - - {props.data.event.title} - - {formatDate(props.data.event.start)}- {formatHour(props.data.event.end)} + + + {props.data.event.title} + + BookingId :${props.data.id} @@ -61,4 +88,4 @@ const EventPreview = (props) => { ); }; -export default EventPreview; +export default BookingPreview; diff --git a/src/components/navbar.js b/src/components/navbar.js index cdf24b00..c8090e52 100644 --- a/src/components/navbar.js +++ b/src/components/navbar.js @@ -6,7 +6,7 @@ import ExploreIcon from "@mui/icons-material/Explore"; import BookmarkIcon from "@mui/icons-material/Bookmark"; import EventIcon from "@mui/icons-material/Event"; import PersonIcon from "@mui/icons-material/Person"; -import { ThemeProvider } from "@mui/material/styles"; +import { ThemeProvider, styled } from "@mui/material/styles"; //-----------Components-----------// import theme from "../theme"; @@ -15,13 +15,11 @@ import theme from "../theme"; import "../App.css"; export default function NavBar() { + const Offset = styled("div")(({ theme }) => theme.mixins.toolbar); + return ( - + - {/* - - */} + diff --git a/src/components/searchBar.js b/src/components/searchBar.js index 92cac871..f14d8d0e 100644 --- a/src/components/searchBar.js +++ b/src/components/searchBar.js @@ -19,6 +19,8 @@ import FormGroup from "@mui/material/FormGroup"; import FormControlLabel from "@mui/material/FormControlLabel"; import axios from "axios"; import Container from "@mui/material/Container"; +import AppBar from "@mui/material/AppBar"; +import Toolbar from "@mui/material/Toolbar"; //-----------Components-----------// import "./searchBar.css"; @@ -94,6 +96,7 @@ export default function SearchBar() { const categoriesList = categories.map((category) => ( diff --git a/src/pages/userPages/eventDetailPage.js b/src/pages/userPages/eventDetailPage.js index aa04b47a..bba9b441 100644 --- a/src/pages/userPages/eventDetailPage.js +++ b/src/pages/userPages/eventDetailPage.js @@ -13,7 +13,6 @@ import ArrowBackIcon from "@mui/icons-material/ArrowBack"; import { APIProvider, Map, - Marker, AdvancedMarker, Pin, } from "@vis.gl/react-google-maps"; @@ -90,7 +89,7 @@ export default function EventDetailPage() { -
-
- + -
- {" "} - -
-
+
+
); diff --git a/src/pages/userPages/myBookingPage.js b/src/pages/userPages/myBookingPage.js index 468fa009..3c223765 100644 --- a/src/pages/userPages/myBookingPage.js +++ b/src/pages/userPages/myBookingPage.js @@ -6,10 +6,12 @@ import Typography from "@mui/material/Typography"; import Box from "@mui/material/Box"; import PropTypes from "prop-types"; import axios from "axios"; +import { ThemeProvider } from "@mui/material/styles"; //-----------Components-----------// import { BACKEND_URL } from "../../constant.js"; import BookingPreview from "../../components/BookingPreview.js"; +import theme from "../../theme"; function CustomTabPanel(props) { const { children, value, index, ...other } = props; @@ -22,11 +24,7 @@ function CustomTabPanel(props) { aria-labelledby={`simple-tab-${index}`} {...other} > - {value === index && ( - - {children} - - )} + {value === index && {children}}
); } @@ -88,28 +86,30 @@ export default function MyBookingPage() { : null; return ( -
- - - - - - - - - {currentPreviews} - - - {pastPreviews} - + + + + + + -
+ + {currentPreviews} + + + {pastPreviews} + +
); } diff --git a/src/pages/userPages/searchPage.js b/src/pages/userPages/searchPage.js index 816e4b56..36362875 100644 --- a/src/pages/userPages/searchPage.js +++ b/src/pages/userPages/searchPage.js @@ -1,17 +1,17 @@ //-----------Libraries-----------// -import { useState, useEffect } from "react"; +import { useState, useEffect, useRef } from "react"; import { useOutletContext, useParams } from "react-router-dom"; import { useLocation } from "react-router-dom"; import axios from "axios"; +import { Grid, Box } from "@mui/material"; import { ThemeProvider } from "@mui/material/styles"; import theme from "../../theme"; import { - Card, - Button, - Switch, - Backdrop, - CircularProgress, -} from "@mui/material"; + APIProvider, + Map, + AdvancedMarker, + Pin, +} from "@vis.gl/react-google-maps"; //-----------Components-----------// import { BACKEND_URL } from "../../constant.js"; @@ -25,6 +25,7 @@ export default function SearchPage() { const selectedCategories = state && state.categories ? state.categories : []; const [events, setEvents] = useState([]); const [loading, setLoading] = useState(true); + const eventPreviewRefs = useRef([]); useEffect(() => { const fetchData = async () => { @@ -52,37 +53,86 @@ export default function SearchPage() { const eventPreviews = events && events.length > 0 ? (
- {events.map((event) => ( - + {events.map((event, index) => ( +
(eventPreviewRefs.current[index] = ref)} + > + +
))}
) : (
No events found
); + const markers = + events.length > 0 && + events.map((event, index) => ( + handleMarkerClick(index)} + > + + + )); + + const handleMarkerClick = (index) => { + if (eventPreviewRefs.current[index]) { + eventPreviewRefs.current[index].scrollIntoView({ + behavior: "smooth", + block: "start", + }); + } + }; + + console.log(markers); + console.log(events); + return (
-
- - - {" "} - {/* Conditionally render Backdrop based on loading state */} -

Searching for events...

- -
-
- {eventPreviews} -
-
+ +
+ +
+ {events.length > 0 && ( // Only render the map if events are loaded + + + {markers} + + + )} + + {eventPreviews}
); diff --git a/src/theme.js b/src/theme.js index 2ffd4665..13905123 100644 --- a/src/theme.js +++ b/src/theme.js @@ -3,10 +3,10 @@ import { createTheme } from "@mui/material/styles"; const theme = createTheme({ palette: { primary: { - main: "#5A5A5A", + main: "#32AD80", }, secondary: { - main: "#0DCDAA", + main: "#FCA56D", }, error: { main: "#F0635A", @@ -14,6 +14,9 @@ const theme = createTheme({ info: { main: "#81AC80", }, + success: { + main: "#FFFFFF", + }, }, }); From cf7e2445624128a0908e32fc73a144dc329c8c1c Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Sun, 7 Apr 2024 10:33:44 +0800 Subject: [PATCH 29/69] updated checkout page ui --- src/pages/userPages/eventBookingPage.js | 113 +++++++++++++++++++----- 1 file changed, 92 insertions(+), 21 deletions(-) diff --git a/src/pages/userPages/eventBookingPage.js b/src/pages/userPages/eventBookingPage.js index 952cc74c..b333e5d4 100644 --- a/src/pages/userPages/eventBookingPage.js +++ b/src/pages/userPages/eventBookingPage.js @@ -9,15 +9,18 @@ import Button from "@mui/material/Button"; import Select from "@mui/material/Select"; import axios from "axios"; import { Box } from "@mui/material"; +import Typography from "@mui/material/Typography"; +import { ThemeProvider } from "@mui/material/styles"; //-----------Components-----------// import { BACKEND_URL } from "../../constant.js"; +import theme from "../../theme"; export default function EventBookingPage({ eventId, isFree }) { - const [quantity, setQuantity] = useState(""); - const [capacity, setCapacity] = useState(""); + const [quantity, setQuantity] = useState(1); + const [capacity, setCapacity] = useState(); + const [event, setEvent] = useState(); - //will add condition if price is free, don't need to go through stripe payment checkout useEffect(() => { const fetchData = async () => { try { @@ -34,16 +37,61 @@ export default function EventBookingPage({ eventId, isFree }) { fetchData(); }, [eventId]); - const handleQuantityChange = (event) => { - setQuantity(event.target.value); + useEffect(() => { + const fetchData = async () => { + try { + const response = await axios.get(`${BACKEND_URL}/events/${eventId}`); + setEvent(response.data); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + fetchData(); + }, [eventId]); + + // const handleQuantityChange = (event) => { + // setQuantity(event.target.value); + // }; + + // const arrayTickets = Array.from({ length: capacity }, (_, i) => i + 1); + + const handleIncrement = () => { + if (quantity < capacity) { + setQuantity(quantity + 1); + } + }; + + const handleDecrement = () => { + if (quantity > 1) { + setQuantity(quantity - 1); + } }; - const arrayTickets = Array.from({ length: capacity }, (_, i) => i + 1); + const totalPrice = event && event.price * quantity; + const displayPrice = totalPrice === 0 ? "Free" : `$ ${totalPrice}`; return ( -
- - + + + + Number of Tickets + + + {/* Tickets - {arrayTickets.map((quantity) => ( - - {quantity} - - ))} - - Quantity - */} - {quantity} diff --git a/src/pages/userPages/eventDetailPage.js b/src/pages/userPages/eventDetailPage.js index bba9b441..27c2e948 100644 --- a/src/pages/userPages/eventDetailPage.js +++ b/src/pages/userPages/eventDetailPage.js @@ -1,14 +1,9 @@ //-----------Libraries-----------// import { useState, useEffect } from "react"; import { useParams, Link } from "react-router-dom"; -import axios from "axios"; -import Button from "@mui/material/Button"; -import Dialog from "@mui/material/Dialog"; -import { Box } from "@mui/material"; -import DialogTitle from "@mui/material/DialogTitle"; import { useAuth0 } from "@auth0/auth0-react"; -import { Typography, Grid } from "@mui/material"; -import { createRoot } from "react-dom/client"; +import axios from "axios"; +import { Button, Dialog, Box, Typography, Grid } from "@mui/material"; import ArrowBackIcon from "@mui/icons-material/ArrowBack"; import { APIProvider, diff --git a/src/pages/userPages/searchPage.js b/src/pages/userPages/searchPage.js index 36362875..9037a3f0 100644 --- a/src/pages/userPages/searchPage.js +++ b/src/pages/userPages/searchPage.js @@ -1,11 +1,9 @@ //-----------Libraries-----------// import { useState, useEffect, useRef } from "react"; -import { useOutletContext, useParams } from "react-router-dom"; -import { useLocation } from "react-router-dom"; +import { useOutletContext, useParams, useLocation } from "react-router-dom"; import axios from "axios"; -import { Grid, Box } from "@mui/material"; -import { ThemeProvider } from "@mui/material/styles"; -import theme from "../../theme"; +import { Box, Grid, ThemeProvider } from "@mui/material"; + import { APIProvider, Map, @@ -18,6 +16,7 @@ import { BACKEND_URL } from "../../constant.js"; import EventPreview from "../../components/EventPreview.js"; import SearchBar from "../../components/searchBar"; import "./userPages.css"; +import theme from "../../theme"; export default function SearchPage() { const { keyword } = useParams(); From 92694a8f593f4c472cf663a9f0dae2c81a92597b Mon Sep 17 00:00:00 2001 From: kendigm Date: Sun, 7 Apr 2024 13:13:43 +0500 Subject: [PATCH 31/69] Auth0 api --- src/components/EventPreviewList.js | 3 ++- src/index.js | 5 ++++- src/pages/userPages/myProfilePage.js | 26 ++++++++++++++++++++------ 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/components/EventPreviewList.js b/src/components/EventPreviewList.js index 393f2fc9..432b6a2d 100644 --- a/src/components/EventPreviewList.js +++ b/src/components/EventPreviewList.js @@ -21,7 +21,8 @@ const EventPreviewList = () => { fetchData(); }, []); - const eventPreviews = events.map((event) => ); + const eventPreviews = + events && events?.map((event) => ); return
{eventPreviews}
; }; diff --git a/src/index.js b/src/index.js index 5b9e4693..ff0b4ef9 100644 --- a/src/index.js +++ b/src/index.js @@ -10,13 +10,16 @@ import { Auth0Provider } from "@auth0/auth0-react"; const domain = process.env.REACT_APP_AUTH0_DOMAIN; const clientId = process.env.REACT_APP_AUTH0_CLIENT_ID; +const AUDIENCE = process.env.REACT_APP_AUTH0_AUDIENCE; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( - + ); diff --git a/src/pages/userPages/myProfilePage.js b/src/pages/userPages/myProfilePage.js index 4fd2b98f..08a78676 100644 --- a/src/pages/userPages/myProfilePage.js +++ b/src/pages/userPages/myProfilePage.js @@ -18,15 +18,29 @@ import { Link, useNavigate } from "react-router-dom"; // Refactor the component to start with an uppercase letter const MyProfilePage = () => { - const { isAuthenticated, logout, isLoading, getAccessTokenSilently, user } = - useAuth0(); + const { + isAuthenticated, + loginWithRedirect, + logout, + isLoading, + getAccessTokenSilently, + user, + } = useAuth0(); const domain = process.env.REACT_APP_AUTH0_DOMAIN; const navigate = useNavigate(); - useEffect(() => { - if (!isAuthenticated) { - navigate("/"); + const [accessToken, setAccessToken] = useState(); + const checkUser = async () => { + if (isAuthenticated) { + let token = await getAccessTokenSilently(); + setAccessToken(token); + console.log("🚀 ~ useEffect ~ token:", token); + } else { + loginWithRedirect(); } - }, [isAuthenticated, navigate]); + }; + useEffect(() => { + checkUser(); + }, []); return (
{isLoading ? ( From 79c474721b2e559734b67a0a863154910eeeb98d Mon Sep 17 00:00:00 2001 From: kendigm Date: Sun, 7 Apr 2024 20:33:56 +0500 Subject: [PATCH 32/69] Auth0 tokens send to api --- src/App.js | 1 + src/components/EventPreviewList.js | 23 ++++++++++---- src/index.js | 2 +- src/pages/signInPage.js | 14 ++++++-- src/pages/userPages/eventDetailPage.js | 31 +++++++++++------- src/pages/userPages/homePage.js | 44 ++++++++++++++++++++++++++ src/pages/userPages/myProfilePage.js | 2 +- 7 files changed, 95 insertions(+), 22 deletions(-) diff --git a/src/App.js b/src/App.js index d6a4101f..0c25a934 100644 --- a/src/App.js +++ b/src/App.js @@ -58,6 +58,7 @@ const App = () => { user, } = useAuth0(); + return ( {isAuthenticated && } diff --git a/src/components/EventPreviewList.js b/src/components/EventPreviewList.js index 432b6a2d..2327450d 100644 --- a/src/components/EventPreviewList.js +++ b/src/components/EventPreviewList.js @@ -1,6 +1,7 @@ //-----------Libraries-----------// import { useState, useEffect } from "react"; import axios from "axios"; +import { useAuth0 } from "@auth0/auth0-react"; //-----------Components-----------// import EventPreview from "./EventPreview"; @@ -9,20 +10,30 @@ import { BACKEND_URL } from "../constant.js"; const EventPreviewList = () => { const [events, setEvents] = useState([]); - useEffect(() => { - const fetchData = async () => { + const { isAuthenticated, getAccessTokenSilently, user } = useAuth0(); + const [accessToken, setAccessToken] = useState(); + + const fetchData = async () => { + if (isAuthenticated) { + let token = await getAccessTokenSilently(); + setAccessToken(token); try { - const response = await axios.get(`${BACKEND_URL}/events`); + const response = await axios.get(`${BACKEND_URL}/events`, { + headers: { + authorization: `Bearer ${accessToken}`, + }, + }); setEvents(response.data); } catch (error) { console.error("Error fetching data:", error); } - }; + } + }; + useEffect(() => { fetchData(); }, []); - const eventPreviews = - events && events?.map((event) => ); + const eventPreviews = events.map((event) => ); return
{eventPreviews}
; }; diff --git a/src/index.js b/src/index.js index ff0b4ef9..7eeb5d5b 100644 --- a/src/index.js +++ b/src/index.js @@ -18,7 +18,7 @@ root.render( clientId={clientId} redirectUri={window.location.origin} audience={AUDIENCE} - scope="read:current_user update:current_user_metadata" + scope="openid email profile" > diff --git a/src/pages/signInPage.js b/src/pages/signInPage.js index f427c718..7739ea07 100644 --- a/src/pages/signInPage.js +++ b/src/pages/signInPage.js @@ -34,17 +34,25 @@ const SignIn = () => { loginWithRedirect, loginWithPopup, isAuthenticated, - + getAccessTokenSilently, logout, isLoading, user, } = useAuth0(); const navigate = useNavigate(); - useEffect(() => { + const [accessToken, setAccessToken] = useState(); + const checkUser = async () => { if (isAuthenticated) { + let token = await getAccessTokenSilently(); + setAccessToken(token); navigate("/profile"); + } else { + loginWithRedirect(); } - }, [navigate]); + }; + useEffect(() => { + checkUser(); + }, []); // const handleLogin = async (e) => { // e.preventDefault(); diff --git a/src/pages/userPages/eventDetailPage.js b/src/pages/userPages/eventDetailPage.js index 210e2770..692b7dfc 100644 --- a/src/pages/userPages/eventDetailPage.js +++ b/src/pages/userPages/eventDetailPage.js @@ -5,6 +5,7 @@ import axios from "axios"; import Button from "@mui/material/Button"; import Dialog from "@mui/material/Dialog"; import DialogTitle from "@mui/material/DialogTitle"; +import { useAuth0 } from "@auth0/auth0-react"; //-----------Components-----------// import EventBookingPage from "./eventBookingPage"; @@ -15,18 +16,26 @@ export default function EventDetailPage() { const [eventId, setEventId] = useState(); const [showRegistration, setShowRegistraton] = useState(null); const [isFree, setIsFree] = useState(null); - + const { isAuthenticated, getAccessTokenSilently, user } = useAuth0(); + const [accessToken, setAccessToken] = useState(); + const fetchData = async () => { + if (isAuthenticated) { + let token = await getAccessTokenSilently(); + setAccessToken(token); + } + try { + const response = await axios.get(`${BACKEND_URL}/events/${eventId}`, { + headers: { + authorization: `Bearer ${accessToken}`, + }, + }); + setEvent(response.data); + setIsFree(response.data.price === 0); + } catch (error) { + console.error("Error fetching data:", error); + } + }; useEffect(() => { - const fetchData = async () => { - try { - const response = await axios.get(`${BACKEND_URL}/events/${eventId}`); - setEvent(response.data); - setIsFree(response.data.price === 0); - } catch (error) { - console.error("Error fetching data:", error); - } - }; - fetchData(); }, [eventId]); diff --git a/src/pages/userPages/homePage.js b/src/pages/userPages/homePage.js index 44353391..227174e4 100644 --- a/src/pages/userPages/homePage.js +++ b/src/pages/userPages/homePage.js @@ -16,6 +16,50 @@ export default function HomePage() { isLoading, user, } = useAuth0(); + if (isLoading) { + return ( +
+ + + + + + + +
+ ); + } return (
{!isAuthenticated ? ( diff --git a/src/pages/userPages/myProfilePage.js b/src/pages/userPages/myProfilePage.js index 08a78676..56b68503 100644 --- a/src/pages/userPages/myProfilePage.js +++ b/src/pages/userPages/myProfilePage.js @@ -33,7 +33,7 @@ const MyProfilePage = () => { if (isAuthenticated) { let token = await getAccessTokenSilently(); setAccessToken(token); - console.log("🚀 ~ useEffect ~ token:", token); + console.log(token); } else { loginWithRedirect(); } From cf5ac4d153e94073c7a2a12d9846e1a8e9b8a402 Mon Sep 17 00:00:00 2001 From: kendigm Date: Mon, 8 Apr 2024 14:07:36 +0500 Subject: [PATCH 33/69] Admin Event Page --- src/App.js | 7 +- src/pages/adminPages/AdminCreateEvent.jsx | 253 ++++++++++++++++++++++ src/pages/adminPages/adminEventPage.js | 247 ++++++++++++++++++++- 3 files changed, 497 insertions(+), 10 deletions(-) create mode 100644 src/pages/adminPages/AdminCreateEvent.jsx diff --git a/src/App.js b/src/App.js index 0c25a934..ab834329 100644 --- a/src/App.js +++ b/src/App.js @@ -27,7 +27,6 @@ import ReturnPage from "./pages/userPages/returnPage.js"; //-----------AdminPages-----------// import AdminHomePage from "./pages/adminPages/adminHomePage.js"; import AdminProfilePage from "./pages/adminPages/adminProfilePage.js"; -import AdminEventPage from "./pages/adminPages/adminEventPage.js"; import AdminEventAttendancePage from "./pages/adminPages/adminEventAttendancePage.js"; import AdminAnalyticsPage from "./pages/adminPages/adminAnalyticsPage.js"; import { Toaster } from "react-hot-toast"; @@ -35,13 +34,14 @@ import { Toaster } from "react-hot-toast"; // Auth0 import { useAuth0 } from "@auth0/auth0-react"; import axios from "axios"; +import AdminCreateEvent from "./pages/adminPages/AdminCreateEvent.jsx"; const AdminRoutes = () => ( } /> } /> - } /> - } /> + } /> + } /> } /> } /> @@ -58,7 +58,6 @@ const App = () => { user, } = useAuth0(); - return ( {isAuthenticated && } diff --git a/src/pages/adminPages/AdminCreateEvent.jsx b/src/pages/adminPages/AdminCreateEvent.jsx new file mode 100644 index 00000000..5ff9ac52 --- /dev/null +++ b/src/pages/adminPages/AdminCreateEvent.jsx @@ -0,0 +1,253 @@ +import Grid from "@mui/material/Grid"; +import Paper from "@mui/material/Paper"; +import Typography from "@mui/material/Typography"; +import TextField from "@mui/material/TextField"; +import Button from "@mui/material/Button"; +import { Link, useNavigate } from "react-router-dom"; +import MailOutlinedIcon from "@mui/icons-material/MailOutlined"; +import InputAdornment from "@mui/material/InputAdornment"; +import LockOutlinedIcon from "@mui/icons-material/LockOutlined"; +import ArrowForwardIcon from "@mui/icons-material/ArrowForward"; +import ArrowBackIcon from "@mui/icons-material/ArrowBack"; +import PersonOutlineOutlinedIcon from "@mui/icons-material/PersonOutlineOutlined"; +import MenuItem from "@mui/material/MenuItem"; +import Select from "@mui/material/Select"; +import TextareaAutosize from '@mui/material/TextareaAutosize'; +import React, { useState } from 'react'; +import RadioGroup from '@mui/material/RadioGroup'; +import FormControlLabel from '@mui/material/FormControlLabel'; +import Radio from '@mui/material/Radio'; +import MonetizationOnIcon from '@mui/icons-material/MonetizationOn'; +import CloudUploadIcon from '@mui/icons-material/CloudUpload'; +import Box from '@mui/material/Box'; + + +export default function AdminCreateEvent() { + const [ticketPrice, setTicketPrice] = useState('free'); + const [paidAmount, setPaidAmount] = useState(''); + + const handlePriceChange = (event) => { + setTicketPrice(event.target.value); + }; + + const handleAmountChange = (event) => { + setPaidAmount(event.target.value); + }; + return ( +
+ + + + {/*
+ + + Events + +
*/} + + Event + +
+ + {" "} + Date + + {" "} +
+ + +
+ Category + + {" "} + +
+ + } label="Free" /> + } label="Paid" /> + + {ticketPrice === 'paid' && ( + + + + ), + }} + /> + )} +
+ + {/* Image upload button */} + + + + {/* Video upload button */} + + + +
+ + + + +
+ +
+
+
+
+ ); +} diff --git a/src/pages/adminPages/adminEventPage.js b/src/pages/adminPages/adminEventPage.js index ed2c57d7..2c7dcdc7 100644 --- a/src/pages/adminPages/adminEventPage.js +++ b/src/pages/adminPages/adminEventPage.js @@ -1,8 +1,243 @@ -//-----------Libraries-----------// -import { useState, useEffect } from "react"; +// import Grid from "@mui/material/Grid"; +// import Paper from "@mui/material/Paper"; +// import Typography from "@mui/material/Typography"; +// import TextField from "@mui/material/TextField"; +// import Button from "@mui/material/Button"; +// import { Link, useNavigate } from "react-router-dom"; +// import MailOutlinedIcon from "@mui/icons-material/MailOutlined"; +// import InputAdornment from "@mui/material/InputAdornment"; +// import LockOutlinedIcon from "@mui/icons-material/LockOutlined"; +// import ArrowForwardIcon from "@mui/icons-material/ArrowForward"; +// import ArrowBackIcon from "@mui/icons-material/ArrowBack"; +// import PersonOutlineOutlinedIcon from "@mui/icons-material/PersonOutlineOutlined"; +// import MenuItem from "@mui/material/MenuItem"; +// import Select from "@mui/material/Select"; +// import TextareaAutosize from '@mui/material/TextareaAutosize'; +// import React, { useState } from 'react'; +// import RadioGroup from '@mui/material/RadioGroup'; +// import FormControlLabel from '@mui/material/FormControlLabel'; +// import Radio from '@mui/material/Radio'; +// import MonetizationOnIcon from '@mui/icons-material/MonetizationOn'; -//-----------Components-----------// -export default function AdminEventPage() { - return
Create and edit event page
; -} +// export default function AdminEventPage() { +// const [ticketPrice, setTicketPrice] = useState('free'); +// const [paidAmount, setPaidAmount] = useState(''); + +// const handlePriceChange = (event) => { +// setTicketPrice(event.target.value); +// }; + +// const handleAmountChange = (event) => { +// setPaidAmount(event.target.value); +// }; +// return ( +//
+// +// +// +// {/*
+// +// +// Events +// +//
*/} +// +// Event +// +//
+// {" "} +// {" "} +//
+// +// +//
+ +// +// {" "} +// +//
+// +// } label="Free" /> +// } label="Paid" /> +// +// {ticketPrice === 'paid' && ( +// +// +// +// ), +// }} +// /> +// )} +//
+//
+// +//
+// +// +// Already have an account?{" "} +// +// Sign in +// +// +// +//
+//
+//
+//
+// ); +// } From 5775d66afad65a80622c3feb282dc00e85b6b9a5 Mon Sep 17 00:00:00 2001 From: kendigm Date: Mon, 8 Apr 2024 14:12:26 +0500 Subject: [PATCH 34/69] Admin Event Page --- src/pages/adminPages/AdminCreateEvent.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/adminPages/AdminCreateEvent.jsx b/src/pages/adminPages/AdminCreateEvent.jsx index 5ff9ac52..9f279f50 100644 --- a/src/pages/adminPages/AdminCreateEvent.jsx +++ b/src/pages/adminPages/AdminCreateEvent.jsx @@ -21,7 +21,7 @@ import MonetizationOnIcon from '@mui/icons-material/MonetizationOn'; import CloudUploadIcon from '@mui/icons-material/CloudUpload'; import Box from '@mui/material/Box'; - +git export default function AdminCreateEvent() { const [ticketPrice, setTicketPrice] = useState('free'); const [paidAmount, setPaidAmount] = useState(''); From 366cffc350228324de50b1ba08949f45f19f17d8 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Mon, 8 Apr 2024 22:01:33 +0800 Subject: [PATCH 35/69] deleted shoes file --- public/shoes.jpg:Zone.Identifier | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 public/shoes.jpg:Zone.Identifier diff --git a/public/shoes.jpg:Zone.Identifier b/public/shoes.jpg:Zone.Identifier deleted file mode 100644 index e69de29b..00000000 From 89fbf9b95e947dd15e8936fb587fbd95e2ff52dd Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Fri, 12 Apr 2024 22:10:53 +0800 Subject: [PATCH 36/69] compiled --- src/index.js | 14 +- src/pages/adminPages/AdminCreateEvent.jsx | 257 ++++++++++++++++++++++ src/pages/registerPage.js | 32 +-- src/pages/signInPage.js | 230 +++++-------------- src/pages/userPages/homePage.js | 2 - src/pages/userPages/myProfilePage.js | 94 ++++---- 6 files changed, 364 insertions(+), 265 deletions(-) create mode 100644 src/pages/adminPages/AdminCreateEvent.jsx diff --git a/src/index.js b/src/index.js index 55a0a591..3b1bf727 100644 --- a/src/index.js +++ b/src/index.js @@ -31,9 +31,7 @@ import SearchPage from "./pages/userPages/searchPage.js"; //-----------AdminPages-----------// import AdminHomePage from "./pages/adminPages/adminHomePage.js"; import AdminProfilePage from "./pages/adminPages/adminProfilePage.js"; -import AdminEventPage from "./pages/adminPages/adminEventPage.js"; -import AdminEventAttendancePage from "./pages/adminPages/adminEventAttendancePage.js"; -import AdminAnalyticsPage from "./pages/adminPages/adminAnalyticsPage.js"; +import AdminCreateEvent from "./pages/adminPages/AdminCreateEvent.jsx"; import { Toaster } from "react-hot-toast"; const root = ReactDOM.createRoot(document.getElementById("root")); @@ -41,11 +39,9 @@ const root = ReactDOM.createRoot(document.getElementById("root")); const AdminRoutes = () => ( } /> - } /> - } /> - } /> + } /> + } /> } /> - } /> ); @@ -53,8 +49,8 @@ const AdminRoutes = () => ( root.render( { + setTicketPrice(event.target.value); + }; + + const handleAmountChange = (event) => { + setPaidAmount(event.target.value); + }; + return ( +
+ + + + {/*
+ + + Events + +
*/} + + Event + +
+ {" "} + Date + {" "} +
+ + +
+ Category + + {" "} + +
+ + } + label="Free" + /> + } + label="Paid" + /> + + {ticketPrice === "paid" && ( + + + + ), + }} + /> + )} +
+ + {/* Image upload button */} + + + + {/* Video upload button */} + + + +
+ + +
+ +
+
+
+
+ ); +} diff --git a/src/pages/registerPage.js b/src/pages/registerPage.js index 43413ca1..2feed410 100644 --- a/src/pages/registerPage.js +++ b/src/pages/registerPage.js @@ -10,44 +10,14 @@ import LockOutlinedIcon from "@mui/icons-material/LockOutlined"; import ArrowForwardIcon from "@mui/icons-material/ArrowForward"; import ArrowBackIcon from "@mui/icons-material/ArrowBack"; import PersonOutlineOutlinedIcon from "@mui/icons-material/PersonOutlineOutlined"; -import { useRegisterMutation } from "../slices/usersApiSlices"; -import { useDispatch, useSelector } from "react-redux"; import { useEffect, useState } from "react"; -import { setCredentials } from "../slices/AuthSlices"; - -import toast from "react-hot-toast"; export default function RegisterPage() { const [name, setName] = useState(); const [email, setEmail] = useState(); const [password, setPassword] = useState(); const [confirmPassword, setConfirmPassword] = useState(); - const dispatch = useDispatch(); - const navigate = useNavigate(); - const { userInfo } = useSelector((state) => state.auth); - const [register, { isLoading }] = useRegisterMutation(); - useEffect(() => { - if (userInfo) { - navigate("/profile"); - } - }, [navigate, userInfo]); - async function handleRegister(e) { - e.preventDefault(); - if (password !== confirmPassword) - return toast.error(`Password not matched 😶`); - try { - const res = await register({ email, password, name }).unwrap(); - setName(""); - setEmail(""); - setPassword(""); - setConfirmPassword(""); - toast.success(res.message); - navigate("/signin"); - } catch (err) { - console.log(err?.data?.message || err.error); - } - } return (
@@ -145,7 +115,7 @@ export default function RegisterPage() { -
- - - Don’t have any account?{" "} - - Sign Up - - + + Sign In + +
+ +
+ + )} diff --git a/src/pages/userPages/homePage.js b/src/pages/userPages/homePage.js index 0488ba36..d49ae497 100644 --- a/src/pages/userPages/homePage.js +++ b/src/pages/userPages/homePage.js @@ -1,8 +1,6 @@ //-----------Libraries-----------// -import { useState, useEffect } from "react"; import { ThemeProvider } from "@mui/material/styles"; import theme from "../../theme"; -import Typography from "@mui/material/Typography"; //-----------Components-----------// import EventPreviewList from "../../components/EventPreviewList"; diff --git a/src/pages/userPages/myProfilePage.js b/src/pages/userPages/myProfilePage.js index 9b5cbd41..56b68503 100644 --- a/src/pages/userPages/myProfilePage.js +++ b/src/pages/userPages/myProfilePage.js @@ -1,4 +1,4 @@ -import React, { useEffect } from "react"; +import React, { useEffect, useState } from "react"; import Avatar from "@mui/material/Avatar"; import Typography from "@mui/material/Typography"; import List from "@mui/material/List"; @@ -12,59 +12,61 @@ import ContactSupportIcon from "@mui/icons-material/ContactSupport"; import SettingsIcon from "@mui/icons-material/Settings"; import HelpIcon from "@mui/icons-material/Help"; import ExitToAppIcon from "@mui/icons-material/ExitToApp"; +import { useAuth0 } from "@auth0/auth0-react"; +import axios from "axios"; import { Link, useNavigate } from "react-router-dom"; -import { useDispatch, useSelector } from "react-redux"; -import toast from "react-hot-toast"; -import { useLogoutMutation } from "../../slices/usersApiSlices"; -import { logoutt } from "../../slices/AuthSlices"; // Refactor the component to start with an uppercase letter const MyProfilePage = () => { - const user = { - name: "Glory Kendi", - profileImg: "/logo192.png", - unreadMessages: 3, // Number of unread messages - }; - const { userInfo } = useSelector((state) => state.auth); - const [logout] = useLogoutMutation(); // destructuring - const dispatch = useDispatch(); + const { + isAuthenticated, + loginWithRedirect, + logout, + isLoading, + getAccessTokenSilently, + user, + } = useAuth0(); + const domain = process.env.REACT_APP_AUTH0_DOMAIN; const navigate = useNavigate(); - useEffect(() => { - if (!userInfo) { - navigate("/signin"); - } - }, [navigate, userInfo]); - const handleLogout = async (e) => { - try { - const res = await logout(); - dispatch(logoutt()); - // navigate("/signin"); - // window.location.href = "/signin"; - toast.success(res?.data?.message); - } catch (error) { - toast.error(error.message); + const [accessToken, setAccessToken] = useState(); + const checkUser = async () => { + if (isAuthenticated) { + let token = await getAccessTokenSilently(); + setAccessToken(token); + console.log(token); + } else { + loginWithRedirect(); } }; + useEffect(() => { + checkUser(); + }, []); return (
-
+ {isLoading ? ( +

loading...

+ ) : (
- +
+ +
+ + {user && user?.nickname} + + {/* {user && !user?.email_verified &&

Please verify your email

} */}
- - {userInfo?.name} - -
+ )} + @@ -77,11 +79,11 @@ const MyProfilePage = () => { - {user.unreadMessages > 0 && ( - - {user.unreadMessages} - - )} + {/* {user.unreadMessages > 0 && ( */} + + {/* {user.unreadMessages} */} + + {/* )} */} @@ -115,9 +117,9 @@ const MyProfilePage = () => { logout()} > From f98a1e7e022817a6b0d556d0293094aa6797a841 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Sat, 13 Apr 2024 01:47:25 +0800 Subject: [PATCH 37/69] updated bookings with auth0 --- src/components/EventPreview.js | 4 +- src/components/searchBar.js | 4 +- src/pages/userPages/checkOutPage.js | 6 +- src/pages/userPages/eventBookingPage.js | 47 +++++++++- src/pages/userPages/eventDetailPage.js | 5 +- src/pages/userPages/myBookingPage.js | 110 +++++++++++++++++------- src/pages/userPages/myProfilePage.js | 59 +++++++++---- src/pages/userPages/returnPage.js | 3 +- src/pages/userPages/searchPage.js | 2 +- 9 files changed, 182 insertions(+), 58 deletions(-) diff --git a/src/components/EventPreview.js b/src/components/EventPreview.js index 38192103..758d157b 100644 --- a/src/components/EventPreview.js +++ b/src/components/EventPreview.js @@ -43,7 +43,7 @@ const EventPreview = (props) => { image={`${process.env.PUBLIC_URL}/shoes.jpg`} title="shoes" > - + {/* - + */} {categoriesList} - + {/* } @@ -146,7 +146,7 @@ export default function SearchBar() { onClick={(e) => e.stopPropagation()} /> - + */} - + { + try { + if (user && user.email) { + const response = await axios.post(`${BACKEND_URL}/users/`, { + email: user.email, + }); + const output = response.data; + setUserDb(output); + } else { + console.log("User email is undefined."); + } + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const checkUser = async () => { + if (isAuthenticated) { + let token = await getAccessTokenSilently(); + setAccessToken(token); + fetchData(); + } else { + loginWithRedirect(); + } + }; + + useEffect(() => { + checkUser(); + }, []); useEffect(() => { const fetchData = async () => { try { const response = await axios.get(`${BACKEND_URL}/bookings/current`, { - params: { userId: "0a750c6d-758e-4113-806d-4061f49edd13" }, + params: { + userId: userDb && userDb.length > 0 ? userDb[0].id : null, + }, }); console.log(response.data); const output = response.data; @@ -54,13 +100,13 @@ export default function MyBookingPage() { } }; fetchData(); - }, []); + }, [userDb]); useEffect(() => { const fetchData = async () => { try { const response = await axios.get(`${BACKEND_URL}/bookings/past`, { - params: { userId: "0a750c6d-758e-4113-806d-4061f49edd13" }, + params: { userId: userDb && userDb.length > 0 ? userDb[0].id : null }, }); const output = response.data; setPast(output.event); @@ -69,7 +115,7 @@ export default function MyBookingPage() { } }; fetchData(); - }, []); + }, [userDb]); const handleChange = (event, newValue) => { setValue(newValue); @@ -86,30 +132,36 @@ export default function MyBookingPage() { : null; return ( - - - - - - - - - {currentPreviews} - - - {pastPreviews} - - + <> + {isLoading ? ( +

loading...

+ ) : ( + + + + + + + + + {currentPreviews} + + + {pastPreviews} + + + )} + ); } diff --git a/src/pages/userPages/myProfilePage.js b/src/pages/userPages/myProfilePage.js index 56b68503..216e8aaf 100644 --- a/src/pages/userPages/myProfilePage.js +++ b/src/pages/userPages/myProfilePage.js @@ -15,6 +15,7 @@ import ExitToAppIcon from "@mui/icons-material/ExitToApp"; import { useAuth0 } from "@auth0/auth0-react"; import axios from "axios"; import { Link, useNavigate } from "react-router-dom"; +import { BACKEND_URL } from "../../constant.js"; // Refactor the component to start with an uppercase letter const MyProfilePage = () => { @@ -29,18 +30,38 @@ const MyProfilePage = () => { const domain = process.env.REACT_APP_AUTH0_DOMAIN; const navigate = useNavigate(); const [accessToken, setAccessToken] = useState(); + const [userDb, setUserDb] = useState(); + + const fetchData = async () => { + try { + if (user && user.email) { + const response = await axios.post(`${BACKEND_URL}/users/`, { + email: user.email, + }); + const output = response.data; + setUserDb(output); + } else { + console.log("User email is undefined."); + } + } catch (error) { + console.error("Error fetching data:", error); + } + }; + const checkUser = async () => { if (isAuthenticated) { let token = await getAccessTokenSilently(); setAccessToken(token); - console.log(token); + fetchData(); } else { loginWithRedirect(); } }; + useEffect(() => { checkUser(); }, []); + return (
{isLoading ? ( @@ -74,47 +95,47 @@ const MyProfilePage = () => { {" "} - + {/* - - {/* {user.unreadMessages > 0 && ( */} - - {/* {user.unreadMessages} */} - - {/* )} */} - - + */} + {/* {user.unreadMessages > 0 && ( */} + {/* */} + {/* {user.unreadMessages} */} + {/* */} + {/* )} */} + {/* */} + {/* - - + */} + {/* - + */} - + {/* - - + */} + {/* - + */} { - + {/* - + */}
); diff --git a/src/pages/userPages/returnPage.js b/src/pages/userPages/returnPage.js index 27cfeebb..b0b944c4 100644 --- a/src/pages/userPages/returnPage.js +++ b/src/pages/userPages/returnPage.js @@ -25,10 +25,11 @@ export default function ReturnPage() { const sessionId = urlParams.get("session_id"); const eventId = urlParams.get("eventId"); const quantity = urlParams.get("quantity"); + const user = urlParams.get("user"); axios .get( - `http://localhost:3000/bookings/session-status?session_id=${sessionId}&eventId=${eventId}&quantity=${quantity}` + `http://localhost:3000/bookings/session-status?session_id=${sessionId}&eventId=${eventId}&quantity=${quantity}&user=${user}` ) .then((response) => { setStatus(response.data.status); diff --git a/src/pages/userPages/searchPage.js b/src/pages/userPages/searchPage.js index 9037a3f0..d88a8061 100644 --- a/src/pages/userPages/searchPage.js +++ b/src/pages/userPages/searchPage.js @@ -114,7 +114,7 @@ export default function SearchPage() { }} > {events.length > 0 && ( // Only render the map if events are loaded - + Date: Sat, 13 Apr 2024 01:59:50 +0800 Subject: [PATCH 38/69] removed navbar for admin routes --- src/index.js | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/src/index.js b/src/index.js index 3b1bf727..d642bdfc 100644 --- a/src/index.js +++ b/src/index.js @@ -45,6 +45,28 @@ const AdminRoutes = () => ( ); +const NonAdminRoutes = () => ( + <> + + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + +); + //testing with simple basic auth0 root.render( @@ -56,23 +78,9 @@ root.render( }} > - - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> } /> - } /> - } /> - } /> + } /> From f621f8ea21d3ea5c1cd340b98d48570c18e8ddaf Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Sat, 13 Apr 2024 03:15:44 +0800 Subject: [PATCH 39/69] edited return page --- src/pages/userPages/returnPage.js | 57 +++++++++++++++++++------------ 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/src/pages/userPages/returnPage.js b/src/pages/userPages/returnPage.js index b0b944c4..58ea1d20 100644 --- a/src/pages/userPages/returnPage.js +++ b/src/pages/userPages/returnPage.js @@ -18,33 +18,44 @@ const stripePromise = loadStripe( export default function ReturnPage() { const [status, setStatus] = useState(null); const [customerEmail, setCustomerEmail] = useState(""); + const [loading, setLoading] = useState(true); useEffect(() => { - const queryString = window.location.search; - const urlParams = new URLSearchParams(queryString); - const sessionId = urlParams.get("session_id"); - const eventId = urlParams.get("eventId"); - const quantity = urlParams.get("quantity"); - const user = urlParams.get("user"); + const fetchData = async () => { + try { + const queryString = window.location.search; + const urlParams = new URLSearchParams(queryString); + const sessionId = urlParams.get("session_id"); + const eventId = urlParams.get("eventId"); + const quantity = urlParams.get("quantity"); + const user = urlParams.get("user"); + + const response = await axios.get( + `http://localhost:3000/bookings/session-status?session_id=${sessionId}&eventId=${eventId}&quantity=${quantity}&user=${user}` + ); - axios - .get( - `http://localhost:3000/bookings/session-status?session_id=${sessionId}&eventId=${eventId}&quantity=${quantity}&user=${user}` - ) - .then((response) => { setStatus(response.data.status); + console.log("Setstatus:", status); setCustomerEmail(response.data.customer_email); - }) - .catch((error) => { + setLoading(false); + } catch (error) { console.error("Error fetching client secret:", error); - }); + setLoading(false); + } + }; + + fetchData(); }, []); - if (status === "open") { - return ; + useEffect(() => { + console.log("Status updated:", status); + }, [status]); + + if (loading) { + return

Loading...

; } - console.log(status); + // Display confirmation message or redirect based on status if (status === "complete") { return (
@@ -52,13 +63,15 @@ export default function ReturnPage() { We appreciate your business! A confirmation email will be sent to{" "} {customerEmail}. If you have any questions, please email{" "} orders@example.com. -

+
); + } else if (status === "open") { + return ; + } else { + return

Status: {status}

; // Handle other statuses if needed } - - // return null; } From 462a0646cc77cd70fbea5a5f3a3892b16ab44333 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Sat, 13 Apr 2024 08:41:03 +0800 Subject: [PATCH 40/69] fixed free events --- src/pages/userPages/freeReturnPage.js | 2 ++ src/pages/userPages/myBookingPage.js | 26 ++++++++++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/pages/userPages/freeReturnPage.js b/src/pages/userPages/freeReturnPage.js index fc357776..2709c573 100644 --- a/src/pages/userPages/freeReturnPage.js +++ b/src/pages/userPages/freeReturnPage.js @@ -16,6 +16,7 @@ export default function FreeReturnPage() { const [status, setStatus] = useState(null); const location = useLocation(); const eventId = location.state.eventId; + const user_id = location.state.user_id; const quantity_bought = location.state.quantity; console.log(eventId); @@ -26,6 +27,7 @@ export default function FreeReturnPage() { .post(`${BACKEND_URL}/bookings/${eventId}`, { eventId: eventId, quantity_bought: quantity_bought, + user_id: user_id, }) .then((response) => { setStatus("complete"); diff --git a/src/pages/userPages/myBookingPage.js b/src/pages/userPages/myBookingPage.js index bebafa6b..73d9708a 100644 --- a/src/pages/userPages/myBookingPage.js +++ b/src/pages/userPages/myBookingPage.js @@ -155,10 +155,32 @@ export default function MyBookingPage() { - {currentPreviews} +
+ {currentPreviews} +
- {pastPreviews} +
+ {pastPreviews} +
)} From c47fe1da3b22a1831a0b7cfa8ec5161a11c5c7d4 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Sat, 13 Apr 2024 09:26:56 +0800 Subject: [PATCH 41/69] removed navbar in admin --- src/index.js | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/src/index.js b/src/index.js index 404e1744..a1d14117 100644 --- a/src/index.js +++ b/src/index.js @@ -44,6 +44,28 @@ const AdminRoutes = () => ( ); +const NonAdminRoutes = () => ( + <> + + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + +); + //testing with simple basic auth0 root.render( - - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> } /> - } /> - } /> - } /> + } /> From f9310d0f86bd7e98968ac758d9a55ea2774d3126 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Sat, 13 Apr 2024 09:53:29 +0800 Subject: [PATCH 42/69] updated navbar only on specific pages --- src/index.js | 89 ++++++++++++++++++++------ src/pages/userPages/eventDetailPage.js | 52 +++++++++------ 2 files changed, 102 insertions(+), 39 deletions(-) diff --git a/src/index.js b/src/index.js index a1d14117..93ccc69b 100644 --- a/src/index.js +++ b/src/index.js @@ -44,26 +44,77 @@ const AdminRoutes = () => ( ); +// const NonAdminRoutes = () => ( +// <> +// +// +// } /> +// } /> +// } /> +// } /> +// } /> +// } /> +// } /> +// } /> +// } /> +// } /> +// } /> +// } /> +// } /> +// } /> +// +// +// ); + const NonAdminRoutes = () => ( - <> - - - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - - + + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + } /> + } /> + } /> + } /> + } /> + ); //testing with simple basic auth0 diff --git a/src/pages/userPages/eventDetailPage.js b/src/pages/userPages/eventDetailPage.js index 97d96d34..b595cca1 100644 --- a/src/pages/userPages/eventDetailPage.js +++ b/src/pages/userPages/eventDetailPage.js @@ -2,7 +2,10 @@ import { useState, useEffect } from "react"; import { useParams, Link } from "react-router-dom"; import axios from "axios"; +import AppBar from "@mui/material/AppBar"; +import Toolbar from "@mui/material/Toolbar"; import { Button, Dialog, Box, Typography, Grid } from "@mui/material"; +import { ThemeProvider } from "@mui/material"; import ArrowBackIcon from "@mui/icons-material/ArrowBack"; import { APIProvider, @@ -15,6 +18,7 @@ import { useAuth0 } from "@auth0/auth0-react"; //-----------Components-----------// import EventBookingPage from "./eventBookingPage"; import { BACKEND_URL } from "../../constant.js"; +import theme from "../../theme"; export default function EventDetailPage() { const [event, setEvent] = useState(); @@ -80,17 +84,10 @@ export default function EventDetailPage() { - - Price: ${event.price} + + ${event.price} - - - - - - - {eventInfo} + + + + + + + +
+ + + + {eventInfo} - {showRegistration && ( - - - - )} -
+ {showRegistration && ( + + + + )} +
+ ); } From a89787d89f73fcdd685ff6b76d87135acfa63e24 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Sat, 13 Apr 2024 11:08:41 +0800 Subject: [PATCH 43/69] fixed bug of booking preview --- src/components/MyBookingBlank.js | 0 src/pages/userPages/myBookingPage.js | 78 ++++++++++++++++------------ 2 files changed, 44 insertions(+), 34 deletions(-) create mode 100644 src/components/MyBookingBlank.js diff --git a/src/components/MyBookingBlank.js b/src/components/MyBookingBlank.js new file mode 100644 index 00000000..e69de29b diff --git a/src/pages/userPages/myBookingPage.js b/src/pages/userPages/myBookingPage.js index 73d9708a..53882f02 100644 --- a/src/pages/userPages/myBookingPage.js +++ b/src/pages/userPages/myBookingPage.js @@ -26,7 +26,7 @@ function CustomTabPanel(props) { aria-labelledby={`simple-tab-${index}`} {...other} > - {value === index && {children}} + {value === index && {children}}
); } @@ -85,51 +85,61 @@ export default function MyBookingPage() { }, []); useEffect(() => { - const fetchData = async () => { - try { - const response = await axios.get(`${BACKEND_URL}/bookings/current`, { - params: { - userId: userDb && userDb.length > 0 ? userDb[0].id : null, - }, - }); - console.log(response.data); - const output = response.data; - setCurrent(output); - } catch (error) { - console.error("Error fetching data:", error); - } - }; - fetchData(); + if (userDb && userDb.length > 0) { + const fetchData = async () => { + try { + const response = await axios.get(`${BACKEND_URL}/bookings/current`, { + params: { userId: userDb[0].id }, + }); + console.log(response.data); + const output = response.data; + setCurrent(output); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + fetchData(); + } }, [userDb]); useEffect(() => { - const fetchData = async () => { - try { - const response = await axios.get(`${BACKEND_URL}/bookings/past`, { - params: { userId: userDb && userDb.length > 0 ? userDb[0].id : null }, - }); - const output = response.data; - setPast(output.event); - } catch (error) { - console.error("Error fetching data:", error); - } - }; - fetchData(); + if (userDb && userDb.length > 0) { + const fetchData = async () => { + try { + const response = await axios.get(`${BACKEND_URL}/bookings/past`, { + params: { userId: userDb[0].id }, + }); + console.log(response.data); + const output = response.data; + setPast(output); + console.log(past); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + fetchData(); + } }, [userDb]); const handleChange = (event, newValue) => { setValue(newValue); }; - const currentPreviews = current - ? current.map((booking) => ( + const currentPreviews = + current.length > 0 ? ( + current.map((booking) => ( )) - : null; + ) : ( +

You don't have any upcoming events.

+ ); - const pastPreviews = past - ? past.map((booking) => ) - : null; + const pastPreviews = + past.length > 0 ? ( + past.map((booking) => ) + ) : ( +

You don't have any past events.

+ ); return ( <> From 5b2531e8bd9a744bd9b03b3d8a135a11fd9caea7 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Sat, 13 Apr 2024 11:45:36 +0800 Subject: [PATCH 44/69] added empty state for myBooking --- public/blank/blank.png | Bin 0 -> 45513 bytes public/blank/blank.png:Zone.Identifier | 0 public/blank/blank.svg | 685 ++++++++++++++++++ ...-drawn-no-data-concept.zip:Zone.Identifier | 0 src/pages/userPages/myBookingPage.js | 68 +- 5 files changed, 751 insertions(+), 2 deletions(-) create mode 100644 public/blank/blank.png create mode 100644 public/blank/blank.png:Zone.Identifier create mode 100644 public/blank/blank.svg create mode 100644 public/hand-drawn-no-data-concept.zip:Zone.Identifier diff --git a/public/blank/blank.png b/public/blank/blank.png new file mode 100644 index 0000000000000000000000000000000000000000..cfb6faf392e4895109f7290d989dd5717563c7bc GIT binary patch literal 45513 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

SP#lw8-oqGwDW!5dlkug7f+K+ohiVfH@p4b~%F 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 literal 0 HcmV?d00001 diff --git a/public/blank/blank.png:Zone.Identifier b/public/blank/blank.png:Zone.Identifier new file mode 100644 index 00000000..e69de29b diff --git a/public/blank/blank.svg b/public/blank/blank.svg new file mode 100644 index 00000000..7009ab22 --- /dev/null +++ b/public/blank/blank.svg @@ -0,0 +1,685 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/hand-drawn-no-data-concept.zip:Zone.Identifier b/public/hand-drawn-no-data-concept.zip:Zone.Identifier new file mode 100644 index 00000000..e69de29b diff --git a/src/pages/userPages/myBookingPage.js b/src/pages/userPages/myBookingPage.js index 53882f02..fee0525b 100644 --- a/src/pages/userPages/myBookingPage.js +++ b/src/pages/userPages/myBookingPage.js @@ -9,6 +9,10 @@ import axios from "axios"; import { useAuth0 } from "@auth0/auth0-react"; import { ThemeProvider } from "@mui/material/styles"; import { Link, useNavigate } from "react-router-dom"; +import Card from "@mui/material/Card"; +import CardContent from "@mui/material/CardContent"; +import CardActions from "@mui/material/CardActions"; +import { CardMedia } from "@mui/material"; //-----------Components-----------// import { BACKEND_URL } from "../../constant.js"; @@ -131,14 +135,74 @@ export default function MyBookingPage() { )) ) : ( -

You don't have any upcoming events.

+ <> + + + + You don't have any upcoming events. + + + ); const pastPreviews = past.length > 0 ? ( past.map((booking) => ) ) : ( -

You don't have any past events.

+ <> + + + + You don't have any past events. + + + ); return ( From 96a54bb444bf0c55a1efed8dad14e65a187077d9 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Sat, 13 Apr 2024 11:46:07 +0800 Subject: [PATCH 45/69] removed zone identifier --- public/blank/blank.png:Zone.Identifier | 0 public/hand-drawn-no-data-concept.zip:Zone.Identifier | 0 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 public/blank/blank.png:Zone.Identifier delete mode 100644 public/hand-drawn-no-data-concept.zip:Zone.Identifier diff --git a/public/blank/blank.png:Zone.Identifier b/public/blank/blank.png:Zone.Identifier deleted file mode 100644 index e69de29b..00000000 diff --git a/public/hand-drawn-no-data-concept.zip:Zone.Identifier b/public/hand-drawn-no-data-concept.zip:Zone.Identifier deleted file mode 100644 index e69de29b..00000000 From d10a7d8d73663ae87340c7f38a494f7f27c29776 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Sat, 13 Apr 2024 11:55:36 +0800 Subject: [PATCH 46/69] added key in eventPreviewList --- src/components/EventPreviewList.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/EventPreviewList.js b/src/components/EventPreviewList.js index 9610be21..0ab13021 100644 --- a/src/components/EventPreviewList.js +++ b/src/components/EventPreviewList.js @@ -21,7 +21,9 @@ const EventPreviewList = () => { fetchData(); }, []); - const eventPreviews = events.map((event) => ); + const eventPreviews = events.map((event) => ( + + )); return <>{eventPreviews}; }; From a729d5f3e4cbb4d0d723137d7103b3bdcc26b5f2 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Sat, 13 Apr 2024 12:12:04 +0800 Subject: [PATCH 47/69] fixed process env --- src/components/BookingPreview.js | 2 +- src/pages/userPages/eventDetailPage.js | 2 +- src/pages/userPages/searchPage.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/BookingPreview.js b/src/components/BookingPreview.js index 5ab29ca7..9daeca21 100644 --- a/src/components/BookingPreview.js +++ b/src/components/BookingPreview.js @@ -35,7 +35,7 @@ const BookingPreview = (props) => { return ( - + - + {events.length > 0 && ( // Only render the map if events are loaded - + Date: Sat, 13 Apr 2024 22:14:01 +0800 Subject: [PATCH 48/69] updated event detail page and contactuspage --- public/cover.png | Bin 0 -> 12222 bytes .../cover.png:Zone.Identifier | 0 src/App.js | 88 ------- src/components/Redirect.js | 34 +++ src/components/navbar.js | 2 +- src/index.js | 37 +-- src/pages/contactUsPage.js | 40 ++++ src/pages/introPage.js | 46 ++++ src/pages/userPages/eventDetailPage.js | 216 ++++++++++++------ src/pages/userPages/favPage.js | 8 - src/pages/userPages/homePage.js | 8 +- src/pages/userPages/myBookingPage.js | 62 +++-- src/pages/userPages/myProfilePage.js | 117 +++++----- 13 files changed, 381 insertions(+), 277 deletions(-) create mode 100644 public/cover.png rename src/components/MyBookingBlank.js => public/cover.png:Zone.Identifier (100%) create mode 100644 src/components/Redirect.js create mode 100644 src/pages/contactUsPage.js create mode 100644 src/pages/introPage.js delete mode 100644 src/pages/userPages/favPage.js diff --git a/public/cover.png b/public/cover.png new file mode 100644 index 0000000000000000000000000000000000000000..c58f9c3677943afc3a0ea15f4ad62bb8ac372461 GIT binary patch literal 12222 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 ( - - } /> - } /> - } /> - } /> - } /> - } /> - -); - -const App = () => { - const { - loginWithRedirect, - loginWithPopup, - isAuthenticated, - logout, - isLoading, - getAccessTokenSilently, - user, - } = useAuth0(); - - return ( - - {isAuthenticated && } - - } /> - {!isAuthenticated ? ( - } /> // Show SignInPage if not authenticated - ) : ( - <> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - - )} - - - - ); -}; - -export default App; diff --git a/src/components/Redirect.js b/src/components/Redirect.js new file mode 100644 index 00000000..38a39fd6 --- /dev/null +++ b/src/components/Redirect.js @@ -0,0 +1,34 @@ +//-----------Libraries-----------// +import { ThemeProvider } from "@mui/material/styles"; +import theme from "../theme"; +import Typography from "@mui/material/Typography"; +import { Link } from "react-router-dom"; +import Box from "@mui/material/Box"; + +//-----------Components-----------// + +export default function Redirect({ title }) { + return ( + + + + Looking for your {title}? + + + Log into your account + + + + ); +} diff --git a/src/components/navbar.js b/src/components/navbar.js index c8090e52..e36ebb4e 100644 --- a/src/components/navbar.js +++ b/src/components/navbar.js @@ -27,7 +27,7 @@ export default function NavBar() { margin: "0 30px", }} > - + diff --git a/src/index.js b/src/index.js index 93ccc69b..23182f37 100644 --- a/src/index.js +++ b/src/index.js @@ -15,11 +15,12 @@ import RegisterPage from "./pages/registerPage.js"; import SignInPage from "./pages/signInPage.js"; import ResetPasswordPage from "./pages/resetPasswordPage.js"; import ErrorPage from "./pages/errorPage.js"; +import IntroPage from "./pages/introPage.js"; +import ContactUsPage from "./pages/contactUsPage.js"; //-----------UserPages-----------// import HomePage from "./pages/userPages/homePage.js"; import EventDetailPage from "./pages/userPages/eventDetailPage.js"; -import FavPage from "./pages/userPages/favPage.js"; import MyBookingPage from "./pages/userPages/myBookingPage.js"; import MyProfilePage from "./pages/userPages/myProfilePage.js"; import CheckoutForm from "./pages/userPages/checkOutPage.js"; @@ -44,32 +45,10 @@ const AdminRoutes = () => ( ); -// const NonAdminRoutes = () => ( -// <> -// -// -// } /> -// } /> -// } /> -// } /> -// } /> -// } /> -// } /> -// } /> -// } /> -// } /> -// } /> -// } /> -// } /> -// } /> -// -// -// ); - const NonAdminRoutes = () => ( @@ -92,6 +71,14 @@ const NonAdminRoutes = () => ( } /> + + + + } + /> ( } /> - + } /> } /> } /> } /> diff --git a/src/pages/contactUsPage.js b/src/pages/contactUsPage.js new file mode 100644 index 00000000..bba9d61f --- /dev/null +++ b/src/pages/contactUsPage.js @@ -0,0 +1,40 @@ +//-----------Libraries-----------// +import { Box, Button, Typography, ThemeProvider } from "@mui/material"; +import { Link } from "react-router-dom"; + +//-----------Components-----------// +import theme from "../theme"; + +export default function ContactUsPage() { + return ( + + + Coverpage + + + Contact Us + + + Email us at eventlink@gmail.com + + + + ); +} diff --git a/src/pages/introPage.js b/src/pages/introPage.js new file mode 100644 index 00000000..e5f54b31 --- /dev/null +++ b/src/pages/introPage.js @@ -0,0 +1,46 @@ +//-----------Libraries-----------// +import { Box, Button, Typography, ThemeProvider } from "@mui/material"; +import { Link } from "react-router-dom"; + +//-----------Components-----------// +import theme from "../theme"; + +export default function IntroPage() { + return ( + + + Coverpage + + + Find Your Community Events Anywhere + + + + + ); +} diff --git a/src/pages/userPages/eventDetailPage.js b/src/pages/userPages/eventDetailPage.js index 95df3c3b..1b32a592 100644 --- a/src/pages/userPages/eventDetailPage.js +++ b/src/pages/userPages/eventDetailPage.js @@ -6,7 +6,6 @@ import AppBar from "@mui/material/AppBar"; import Toolbar from "@mui/material/Toolbar"; import { Button, Dialog, Box, Typography, Grid } from "@mui/material"; import { ThemeProvider } from "@mui/material"; -import ArrowBackIcon from "@mui/icons-material/ArrowBack"; import { APIProvider, Map, @@ -14,6 +13,10 @@ import { Pin, } from "@vis.gl/react-google-maps"; import { useAuth0 } from "@auth0/auth0-react"; +import ArrowBackIcon from "@mui/icons-material/ArrowBack"; +import LocationOnIcon from "@mui/icons-material/LocationOn"; +import PersonIcon from "@mui/icons-material/Person"; +import LanguageIcon from "@mui/icons-material/Language"; //-----------Components-----------// import EventBookingPage from "./eventBookingPage"; @@ -71,73 +74,123 @@ export default function EventDetailPage() { //add image const eventInfo = event ? ( - - - - - {event.title} - - - - - {event.description} - - - - - ${event.price} - - + + shoes + + + + + {new Date(event.start).toLocaleString("en-US", { + weekday: "long", + day: "numeric", + month: "long", + hour: "numeric", + minute: "numeric", + })} + - + {new Date(event.end).toLocaleString("en-US", { + hour: "numeric", + minute: "numeric", + })} + + + + + {event.title} + + - - - - - - - - - - Language: {event.language.name} - - - {new Date(event.start).toLocaleString("en-US", { - weekday: "long", - day: "numeric", - month: "long", - hour: "numeric", - minute: "numeric", - })} - - - {new Date(event.end).toLocaleString("en-US", { - hour: "numeric", - minute: "numeric", - })} - - {event.admin.name} - {event.venue.address} + + + {event.description} + + + {/* + + ${event.price} + + */} + + + + Language: {event.language.name} + + + + + + {event.admin.name} + + + + + + {event.venue.address} + + + + + + + + + + + + - + ) : null; @@ -150,16 +203,31 @@ export default function EventDetailPage() { justifyContent: "center", }} > - + + {event && ${event.price}} + + -
- - - + + + + + + {eventInfo} {showRegistration && ( @@ -167,7 +235,7 @@ export default function EventDetailPage() {
)} -
+ ); } diff --git a/src/pages/userPages/favPage.js b/src/pages/userPages/favPage.js deleted file mode 100644 index f7611b6a..00000000 --- a/src/pages/userPages/favPage.js +++ /dev/null @@ -1,8 +0,0 @@ -//-----------Libraries-----------// -import { useState, useEffect } from "react"; - -//-----------Components-----------// - -export default function FavPage() { - return
Favorites page
; -} diff --git a/src/pages/userPages/homePage.js b/src/pages/userPages/homePage.js index d49ae497..3989ba43 100644 --- a/src/pages/userPages/homePage.js +++ b/src/pages/userPages/homePage.js @@ -1,5 +1,5 @@ //-----------Libraries-----------// -import { ThemeProvider } from "@mui/material/styles"; +import { Typography, ThemeProvider } from "@mui/material"; import theme from "../../theme"; //-----------Components-----------// @@ -21,6 +21,12 @@ export default function HomePage() { marginBottom: "20vw", }} > + + Ongoing Events +
diff --git a/src/pages/userPages/myBookingPage.js b/src/pages/userPages/myBookingPage.js index fee0525b..c6fe273e 100644 --- a/src/pages/userPages/myBookingPage.js +++ b/src/pages/userPages/myBookingPage.js @@ -1,23 +1,27 @@ //-----------Libraries-----------// import { useState, useEffect } from "react"; -import Tabs from "@mui/material/Tabs"; -import Tab from "@mui/material/Tab"; -import Typography from "@mui/material/Typography"; -import Box from "@mui/material/Box"; -import PropTypes from "prop-types"; -import axios from "axios"; +import { useNavigate } from "react-router-dom"; import { useAuth0 } from "@auth0/auth0-react"; -import { ThemeProvider } from "@mui/material/styles"; -import { Link, useNavigate } from "react-router-dom"; -import Card from "@mui/material/Card"; -import CardContent from "@mui/material/CardContent"; -import CardActions from "@mui/material/CardActions"; -import { CardMedia } from "@mui/material"; +import axios from "axios"; +import PropTypes from "prop-types"; +import { + Tabs, + ThemeProvider, + Tab, + Typography, + Box, + Button, + Card, + CardContent, + CardActions, + CardMedia, +} from "@mui/material"; //-----------Components-----------// import { BACKEND_URL } from "../../constant.js"; import BookingPreview from "../../components/BookingPreview.js"; import theme from "../../theme"; +import Redirect from "../../components/Redirect.js"; function CustomTabPanel(props) { const { children, value, index, ...other } = props; @@ -74,13 +78,34 @@ export default function MyBookingPage() { } }; + const RedirectTab = () => { + return ( +
+ + + + +
+ ); + }; + const checkUser = async () => { if (isAuthenticated) { let token = await getAccessTokenSilently(); setAccessToken(token); fetchData(); - } else { - loginWithRedirect(); } }; @@ -95,7 +120,6 @@ export default function MyBookingPage() { const response = await axios.get(`${BACKEND_URL}/bookings/current`, { params: { userId: userDb[0].id }, }); - console.log(response.data); const output = response.data; setCurrent(output); } catch (error) { @@ -205,6 +229,14 @@ export default function MyBookingPage() { ); + if (!isAuthenticated) { + return ( + + + + ); + } + return ( <> {isLoading ? ( diff --git a/src/pages/userPages/myProfilePage.js b/src/pages/userPages/myProfilePage.js index 216e8aaf..90b691f6 100644 --- a/src/pages/userPages/myProfilePage.js +++ b/src/pages/userPages/myProfilePage.js @@ -1,23 +1,27 @@ -import React, { useEffect, useState } from "react"; -import Avatar from "@mui/material/Avatar"; -import Typography from "@mui/material/Typography"; -import List from "@mui/material/List"; -import ListItem from "@mui/material/ListItem"; -import ListItemIcon from "@mui/material/ListItemIcon"; -import ListItemText from "@mui/material/ListItemText"; -import MessageIcon from "@mui/icons-material/Message"; -import CalendarTodayIcon from "@mui/icons-material/CalendarToday"; -import BookmarkIcon from "@mui/icons-material/Bookmark"; -import ContactSupportIcon from "@mui/icons-material/ContactSupport"; -import SettingsIcon from "@mui/icons-material/Settings"; -import HelpIcon from "@mui/icons-material/Help"; -import ExitToAppIcon from "@mui/icons-material/ExitToApp"; +//-----------Libraries-----------// +import { useEffect, useState } from "react"; +import { + Avatar, + ThemeProvider, + Typography, + List, + ListItem, + ListItemIcon, + ListItemText, +} from "@mui/material"; +import { + CalendarToday as CalendarTodayIcon, + ContactSupport as ContactSupportIcon, + ExitToApp as ExitToAppIcon, +} from "@mui/icons-material"; import { useAuth0 } from "@auth0/auth0-react"; import axios from "axios"; import { Link, useNavigate } from "react-router-dom"; + +//-----------Components-----------// import { BACKEND_URL } from "../../constant.js"; +import theme from "../../theme"; -// Refactor the component to start with an uppercase letter const MyProfilePage = () => { const { isAuthenticated, @@ -53,8 +57,6 @@ const MyProfilePage = () => { let token = await getAccessTokenSilently(); setAccessToken(token); fetchData(); - } else { - loginWithRedirect(); } }; @@ -62,6 +64,35 @@ const MyProfilePage = () => { checkUser(); }, []); + if (!isAuthenticated) { + return ( + +
+ + + + + + + + + loginWithRedirect()()}> + + + + + + +
+ ); + } + return (
{isLoading ? ( @@ -84,72 +115,28 @@ const MyProfilePage = () => { {user && user?.nickname} - {/* {user && !user?.email_verified &&

Please verify your email

} */}
)} - + - {" "} - {/* - - - - */} - {/* {user.unreadMessages > 0 && ( */} - {/* */} - {/* {user.unreadMessages} */} - {/* */} - {/* )} */} - {/* */} - {/* - - - - - */} - {/* - - - - - */} - + + - {/* - - - - - */} - {/* - - - - - */} - logout()} - > + logout()}> - {/* - - */} ); From f5715b81d60ca7365b4fb787eac4e9666967a5b5 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Sat, 13 Apr 2024 23:08:15 +0800 Subject: [PATCH 49/69] updated redirect url --- src/index.js | 4 +++- src/pages/contactUsPage.js | 6 ------ src/pages/userPages/eventBookingPage.js | 2 +- src/pages/userPages/eventDetailPage.js | 12 ++++++++++-- src/pages/userPages/freeReturnPage.js | 6 ++---- src/pages/userPages/returnPage.js | 2 +- 6 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/index.js b/src/index.js index 23182f37..89fb1665 100644 --- a/src/index.js +++ b/src/index.js @@ -104,13 +104,15 @@ const NonAdminRoutes = () => ( ); +const newUrl = window.location.origin + "/home"; + //testing with simple basic auth0 root.render( diff --git a/src/pages/contactUsPage.js b/src/pages/contactUsPage.js index bba9d61f..1b868db2 100644 --- a/src/pages/contactUsPage.js +++ b/src/pages/contactUsPage.js @@ -19,12 +19,6 @@ export default function ContactUsPage() { backgroundColor: "#E5F3E8", }} > - Coverpage - { if (!isAuthenticated) { - return loginWithRedirect(); + return loginWithRedirect({ + appState: { + returnTo: window.location.pathname, + }, + }); } setShowRegistraton(true); // let token = await getAccessTokenSilently(); @@ -210,7 +214,11 @@ export default function EventDetailPage() { justifyContent: "space-between", }} > - {event && ${event.price}} + {event && ( + + {event.price === 0 ? "Free" : `$${event.price}`} + + )}

diff --git a/src/pages/userPages/returnPage.js b/src/pages/userPages/returnPage.js index 58ea1d20..138a4455 100644 --- a/src/pages/userPages/returnPage.js +++ b/src/pages/userPages/returnPage.js @@ -64,7 +64,7 @@ export default function ReturnPage() { {customerEmail}. If you have any questions, please email{" "} orders@example.com.

- From 1455956355d84c0d81ef631c2797fb3f1bb60ca3 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Sat, 13 Apr 2024 23:14:51 +0800 Subject: [PATCH 50/69] saved auth0 cache to prevent logout after refresh --- src/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/index.js b/src/index.js index 89fb1665..a833c470 100644 --- a/src/index.js +++ b/src/index.js @@ -114,6 +114,8 @@ root.render( authorizationParams={{ redirect_uri: newUrl, }} + useRefreshTokens + cacheLocation="localstorage" > From 64e16bcb5dda0b5b41b41a634ddba0aad629999d Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Sat, 13 Apr 2024 23:45:16 +0800 Subject: [PATCH 51/69] updated return page --- package-lock.json | 519 ++++++++++++++++++++++++++ package.json | 1 + src/index.js | 4 - src/pages/userPages/freeReturnPage.js | 68 ++-- src/pages/userPages/returnPage.js | 66 ++-- 5 files changed, 612 insertions(+), 46 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4ea88abb..1563b892 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "@vis.gl/react-google-maps": "^0.8.3", "axios": "^1.6.8", "react": "^18.1.0", + "react-confetti-explosion": "^2.1.2", "react-dom": "^18.1.0", "react-hot-toast": "^2.4.1", "react-redux": "^9.1.0", @@ -5881,6 +5882,16 @@ "postcss": "^8.4" } }, + "node_modules/css-jss": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/css-jss/-/css-jss-10.10.0.tgz", + "integrity": "sha512-YyMIS/LsSKEGXEaVJdjonWe18p4vXLo8CMA4FrW/kcaEyqdIGKCFXao31gbJddXEdIxSXFFURWrenBJPlKTgAA==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "^10.10.0", + "jss-preset-default": "^10.10.0" + } + }, "node_modules/css-loader": { "version": "6.7.1", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.1.tgz", @@ -6054,6 +6065,15 @@ "node": ">=0.10.0" } }, + "node_modules/css-vendor": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz", + "integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==", + "dependencies": { + "@babel/runtime": "^7.8.3", + "is-in-browser": "^1.0.2" + } + }, "node_modules/css-what": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", @@ -8590,6 +8610,11 @@ "node": ">=10.17.0" } }, + "node_modules/hyphenate-style-name": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz", + "integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==" + }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -8861,6 +8886,11 @@ "node": ">=0.10.0" } }, + "node_modules/is-in-browser": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz", + "integrity": "sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g==" + }, "node_modules/is-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", @@ -11228,6 +11258,158 @@ "node": ">=0.10.0" } }, + "node_modules/jss": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss/-/jss-10.10.0.tgz", + "integrity": "sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "csstype": "^3.0.2", + "is-in-browser": "^1.1.3", + "tiny-warning": "^1.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/jss" + } + }, + "node_modules/jss-plugin-camel-case": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.10.0.tgz", + "integrity": "sha512-z+HETfj5IYgFxh1wJnUAU8jByI48ED+v0fuTuhKrPR+pRBYS2EDwbusU8aFOpCdYhtRc9zhN+PJ7iNE8pAWyPw==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "hyphenate-style-name": "^1.0.3", + "jss": "10.10.0" + } + }, + "node_modules/jss-plugin-compose": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-compose/-/jss-plugin-compose-10.10.0.tgz", + "integrity": "sha512-F5kgtWpI2XfZ3Z8eP78tZEYFdgTIbpA/TMuX3a8vwrNolYtN1N4qJR/Ob0LAsqIwCMLojtxN7c7Oo/+Vz6THow==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "tiny-warning": "^1.0.2" + } + }, + "node_modules/jss-plugin-default-unit": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.10.0.tgz", + "integrity": "sha512-SvpajxIECi4JDUbGLefvNckmI+c2VWmP43qnEy/0eiwzRUsafg5DVSIWSzZe4d2vFX1u9nRDP46WCFV/PXVBGQ==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0" + } + }, + "node_modules/jss-plugin-expand": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-expand/-/jss-plugin-expand-10.10.0.tgz", + "integrity": "sha512-ymT62W2OyDxBxr7A6JR87vVX9vTq2ep5jZLIdUSusfBIEENLdkkc0lL/Xaq8W9s3opUq7R0sZQpzRWELrfVYzA==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0" + } + }, + "node_modules/jss-plugin-extend": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-extend/-/jss-plugin-extend-10.10.0.tgz", + "integrity": "sha512-sKYrcMfr4xxigmIwqTjxNcHwXJIfvhvjTNxF+Tbc1NmNdyspGW47Ey6sGH8BcQ4FFQhLXctpWCQSpDwdNmXSwg==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "tiny-warning": "^1.0.2" + } + }, + "node_modules/jss-plugin-global": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.10.0.tgz", + "integrity": "sha512-icXEYbMufiNuWfuazLeN+BNJO16Ge88OcXU5ZDC2vLqElmMybA31Wi7lZ3lf+vgufRocvPj8443irhYRgWxP+A==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0" + } + }, + "node_modules/jss-plugin-nested": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.10.0.tgz", + "integrity": "sha512-9R4JHxxGgiZhurDo3q7LdIiDEgtA1bTGzAbhSPyIOWb7ZubrjQe8acwhEQ6OEKydzpl8XHMtTnEwHXCARLYqYA==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "tiny-warning": "^1.0.2" + } + }, + "node_modules/jss-plugin-props-sort": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.10.0.tgz", + "integrity": "sha512-5VNJvQJbnq/vRfje6uZLe/FyaOpzP/IH1LP+0fr88QamVrGJa0hpRRyAa0ea4U/3LcorJfBFVyC4yN2QC73lJg==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0" + } + }, + "node_modules/jss-plugin-rule-value-function": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.10.0.tgz", + "integrity": "sha512-uEFJFgaCtkXeIPgki8ICw3Y7VMkL9GEan6SqmT9tqpwM+/t+hxfMUdU4wQ0MtOiMNWhwnckBV0IebrKcZM9C0g==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "tiny-warning": "^1.0.2" + } + }, + "node_modules/jss-plugin-rule-value-observable": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-observable/-/jss-plugin-rule-value-observable-10.10.0.tgz", + "integrity": "sha512-ZLMaYrR3QE+vD7nl3oNXuj79VZl9Kp8/u6A1IbTPDcuOu8b56cFdWRZNZ0vNr8jHewooEeq2doy8Oxtymr2ZPA==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "symbol-observable": "^1.2.0" + } + }, + "node_modules/jss-plugin-template": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-template/-/jss-plugin-template-10.10.0.tgz", + "integrity": "sha512-ocXZBIOJOA+jISPdsgkTs8wwpK6UbsvtZK5JI7VUggTD6LWKbtoxUzadd2TpfF+lEtlhUmMsCkTRNkITdPKa6w==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "tiny-warning": "^1.0.2" + } + }, + "node_modules/jss-plugin-vendor-prefixer": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.10.0.tgz", + "integrity": "sha512-UY/41WumgjW8r1qMCO8l1ARg7NHnfRVWRhZ2E2m0DMYsr2DD91qIXLyNhiX83hHswR7Wm4D+oDYNC1zWCJWtqg==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "css-vendor": "^2.0.8", + "jss": "10.10.0" + } + }, + "node_modules/jss-preset-default": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-preset-default/-/jss-preset-default-10.10.0.tgz", + "integrity": "sha512-GL175Wt2FGhjE+f+Y3aWh+JioL06/QWFgZp53CbNNq6ZkVU0TDplD8Bxm9KnkotAYn3FlplNqoW5CjyLXcoJ7Q==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "jss-plugin-camel-case": "10.10.0", + "jss-plugin-compose": "10.10.0", + "jss-plugin-default-unit": "10.10.0", + "jss-plugin-expand": "10.10.0", + "jss-plugin-extend": "10.10.0", + "jss-plugin-global": "10.10.0", + "jss-plugin-nested": "10.10.0", + "jss-plugin-props-sort": "10.10.0", + "jss-plugin-rule-value-function": "10.10.0", + "jss-plugin-rule-value-observable": "10.10.0", + "jss-plugin-template": "10.10.0", + "jss-plugin-vendor-prefixer": "10.10.0" + } + }, "node_modules/jsx-ast-utils": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.0.tgz", @@ -13639,6 +13821,19 @@ "node": ">=14" } }, + "node_modules/react-confetti-explosion": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/react-confetti-explosion/-/react-confetti-explosion-2.1.2.tgz", + "integrity": "sha512-4UzDFBajAGXmF9TSJoRMO2QOBCIXc66idTxH8l7Mkul48HLGtk+tMzK9HYDYsy7Zmw5sEGchi2fbn4AJUuLrZw==", + "dependencies": { + "lodash": "^4.17.21", + "react-jss": "^10.9.2" + }, + "peerDependencies": { + "react": "^18.x", + "react-dom": "^18.x" + } + }, "node_modules/react-dev-utils": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", @@ -13756,6 +13951,11 @@ "node": ">=8" } }, + "node_modules/react-display-name": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/react-display-name/-/react-display-name-0.2.5.tgz", + "integrity": "sha512-I+vcaK9t4+kypiSgaiVWAipqHRXYmZIuAiS8vzFvXHHXVigg/sMKwlRgLy6LH2i3rmP+0Vzfl5lFsFRwF1r3pg==" + }, "node_modules/react-dom": { "version": "18.1.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.1.0.tgz", @@ -13793,6 +13993,40 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, + "node_modules/react-jss": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/react-jss/-/react-jss-10.10.0.tgz", + "integrity": "sha512-WLiq84UYWqNBF6579/uprcIUnM1TSywYq6AIjKTTTG5ziJl9Uy+pwuvpN3apuyVwflMbD60PraeTKT7uWH9XEQ==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "@emotion/is-prop-valid": "^0.7.3", + "css-jss": "10.10.0", + "hoist-non-react-statics": "^3.2.0", + "is-in-browser": "^1.1.3", + "jss": "10.10.0", + "jss-preset-default": "10.10.0", + "prop-types": "^15.6.0", + "shallow-equal": "^1.2.0", + "theming": "^3.3.0", + "tiny-warning": "^1.0.2" + }, + "peerDependencies": { + "react": ">=16.8.6" + } + }, + "node_modules/react-jss/node_modules/@emotion/is-prop-valid": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.7.3.tgz", + "integrity": "sha512-uxJqm/sqwXw3YPA5GXX365OBcJGFtxUVkB6WyezqFHlNe9jqUWH5ur2O2M8dGBz61kn1g3ZBlzUunFQXQIClhA==", + "dependencies": { + "@emotion/memoize": "0.7.1" + } + }, + "node_modules/react-jss/node_modules/@emotion/memoize": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.1.tgz", + "integrity": "sha512-Qv4LTqO11jepd5Qmlp3M1YEjBumoTHcHFdgPTQ+sFlIL5myi/7xu/POwP7IRu6odBdmLXdtIs1D6TuW6kbwbbg==" + }, "node_modules/react-redux": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.1.0.tgz", @@ -14631,6 +14865,11 @@ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, + "node_modules/shallow-equal": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz", + "integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -15167,6 +15406,14 @@ "boolbase": "~1.0.0" } }, + "node_modules/symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -15389,6 +15636,23 @@ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" }, + "node_modules/theming": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/theming/-/theming-3.3.0.tgz", + "integrity": "sha512-u6l4qTJRDaWZsqa8JugaNt7Xd8PPl9+gonZaIe28vAhqgHMIG/DOyFPqiKN/gQLQYj05tHv+YQdNILL4zoiAVA==", + "dependencies": { + "hoist-non-react-statics": "^3.3.0", + "prop-types": "^15.5.8", + "react-display-name": "^0.2.4", + "tiny-warning": "^1.0.2" + }, + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "react": ">=16.3" + } + }, "node_modules/throat": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", @@ -15399,6 +15663,11 @@ "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -20779,6 +21048,16 @@ "postcss-selector-parser": "^6.0.9" } }, + "css-jss": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/css-jss/-/css-jss-10.10.0.tgz", + "integrity": "sha512-YyMIS/LsSKEGXEaVJdjonWe18p4vXLo8CMA4FrW/kcaEyqdIGKCFXao31gbJddXEdIxSXFFURWrenBJPlKTgAA==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "^10.10.0", + "jss-preset-default": "^10.10.0" + } + }, "css-loader": { "version": "6.7.1", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.1.tgz", @@ -20888,6 +21167,15 @@ } } }, + "css-vendor": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz", + "integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==", + "requires": { + "@babel/runtime": "^7.8.3", + "is-in-browser": "^1.0.2" + } + }, "css-what": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", @@ -22739,6 +23027,11 @@ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==" }, + "hyphenate-style-name": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz", + "integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==" + }, "iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -22919,6 +23212,11 @@ "is-extglob": "^2.1.1" } }, + "is-in-browser": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz", + "integrity": "sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g==" + }, "is-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", @@ -24640,6 +24938,154 @@ "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.0.tgz", "integrity": "sha512-PNYZIdMjVIvVgDSYKTT63Y+KZ6IZvGRNNWcxwD+GNnUz1MKPfv30J8ueCjdwcN0nDx2SlshgyB7Oy0epAzVRRg==" }, + "jss": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss/-/jss-10.10.0.tgz", + "integrity": "sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw==", + "requires": { + "@babel/runtime": "^7.3.1", + "csstype": "^3.0.2", + "is-in-browser": "^1.1.3", + "tiny-warning": "^1.0.2" + } + }, + "jss-plugin-camel-case": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.10.0.tgz", + "integrity": "sha512-z+HETfj5IYgFxh1wJnUAU8jByI48ED+v0fuTuhKrPR+pRBYS2EDwbusU8aFOpCdYhtRc9zhN+PJ7iNE8pAWyPw==", + "requires": { + "@babel/runtime": "^7.3.1", + "hyphenate-style-name": "^1.0.3", + "jss": "10.10.0" + } + }, + "jss-plugin-compose": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-compose/-/jss-plugin-compose-10.10.0.tgz", + "integrity": "sha512-F5kgtWpI2XfZ3Z8eP78tZEYFdgTIbpA/TMuX3a8vwrNolYtN1N4qJR/Ob0LAsqIwCMLojtxN7c7Oo/+Vz6THow==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "tiny-warning": "^1.0.2" + } + }, + "jss-plugin-default-unit": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.10.0.tgz", + "integrity": "sha512-SvpajxIECi4JDUbGLefvNckmI+c2VWmP43qnEy/0eiwzRUsafg5DVSIWSzZe4d2vFX1u9nRDP46WCFV/PXVBGQ==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0" + } + }, + "jss-plugin-expand": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-expand/-/jss-plugin-expand-10.10.0.tgz", + "integrity": "sha512-ymT62W2OyDxBxr7A6JR87vVX9vTq2ep5jZLIdUSusfBIEENLdkkc0lL/Xaq8W9s3opUq7R0sZQpzRWELrfVYzA==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0" + } + }, + "jss-plugin-extend": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-extend/-/jss-plugin-extend-10.10.0.tgz", + "integrity": "sha512-sKYrcMfr4xxigmIwqTjxNcHwXJIfvhvjTNxF+Tbc1NmNdyspGW47Ey6sGH8BcQ4FFQhLXctpWCQSpDwdNmXSwg==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "tiny-warning": "^1.0.2" + } + }, + "jss-plugin-global": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.10.0.tgz", + "integrity": "sha512-icXEYbMufiNuWfuazLeN+BNJO16Ge88OcXU5ZDC2vLqElmMybA31Wi7lZ3lf+vgufRocvPj8443irhYRgWxP+A==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0" + } + }, + "jss-plugin-nested": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.10.0.tgz", + "integrity": "sha512-9R4JHxxGgiZhurDo3q7LdIiDEgtA1bTGzAbhSPyIOWb7ZubrjQe8acwhEQ6OEKydzpl8XHMtTnEwHXCARLYqYA==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "tiny-warning": "^1.0.2" + } + }, + "jss-plugin-props-sort": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.10.0.tgz", + "integrity": "sha512-5VNJvQJbnq/vRfje6uZLe/FyaOpzP/IH1LP+0fr88QamVrGJa0hpRRyAa0ea4U/3LcorJfBFVyC4yN2QC73lJg==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0" + } + }, + "jss-plugin-rule-value-function": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.10.0.tgz", + "integrity": "sha512-uEFJFgaCtkXeIPgki8ICw3Y7VMkL9GEan6SqmT9tqpwM+/t+hxfMUdU4wQ0MtOiMNWhwnckBV0IebrKcZM9C0g==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "tiny-warning": "^1.0.2" + } + }, + "jss-plugin-rule-value-observable": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-observable/-/jss-plugin-rule-value-observable-10.10.0.tgz", + "integrity": "sha512-ZLMaYrR3QE+vD7nl3oNXuj79VZl9Kp8/u6A1IbTPDcuOu8b56cFdWRZNZ0vNr8jHewooEeq2doy8Oxtymr2ZPA==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "symbol-observable": "^1.2.0" + } + }, + "jss-plugin-template": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-template/-/jss-plugin-template-10.10.0.tgz", + "integrity": "sha512-ocXZBIOJOA+jISPdsgkTs8wwpK6UbsvtZK5JI7VUggTD6LWKbtoxUzadd2TpfF+lEtlhUmMsCkTRNkITdPKa6w==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "tiny-warning": "^1.0.2" + } + }, + "jss-plugin-vendor-prefixer": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.10.0.tgz", + "integrity": "sha512-UY/41WumgjW8r1qMCO8l1ARg7NHnfRVWRhZ2E2m0DMYsr2DD91qIXLyNhiX83hHswR7Wm4D+oDYNC1zWCJWtqg==", + "requires": { + "@babel/runtime": "^7.3.1", + "css-vendor": "^2.0.8", + "jss": "10.10.0" + } + }, + "jss-preset-default": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-preset-default/-/jss-preset-default-10.10.0.tgz", + "integrity": "sha512-GL175Wt2FGhjE+f+Y3aWh+JioL06/QWFgZp53CbNNq6ZkVU0TDplD8Bxm9KnkotAYn3FlplNqoW5CjyLXcoJ7Q==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "jss-plugin-camel-case": "10.10.0", + "jss-plugin-compose": "10.10.0", + "jss-plugin-default-unit": "10.10.0", + "jss-plugin-expand": "10.10.0", + "jss-plugin-extend": "10.10.0", + "jss-plugin-global": "10.10.0", + "jss-plugin-nested": "10.10.0", + "jss-plugin-props-sort": "10.10.0", + "jss-plugin-rule-value-function": "10.10.0", + "jss-plugin-rule-value-observable": "10.10.0", + "jss-plugin-template": "10.10.0", + "jss-plugin-vendor-prefixer": "10.10.0" + } + }, "jsx-ast-utils": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.0.tgz", @@ -26249,6 +26695,15 @@ "whatwg-fetch": "^3.6.2" } }, + "react-confetti-explosion": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/react-confetti-explosion/-/react-confetti-explosion-2.1.2.tgz", + "integrity": "sha512-4UzDFBajAGXmF9TSJoRMO2QOBCIXc66idTxH8l7Mkul48HLGtk+tMzK9HYDYsy7Zmw5sEGchi2fbn4AJUuLrZw==", + "requires": { + "lodash": "^4.17.21", + "react-jss": "^10.9.2" + } + }, "react-dev-utils": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", @@ -26335,6 +26790,11 @@ } } }, + "react-display-name": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/react-display-name/-/react-display-name-0.2.5.tgz", + "integrity": "sha512-I+vcaK9t4+kypiSgaiVWAipqHRXYmZIuAiS8vzFvXHHXVigg/sMKwlRgLy6LH2i3rmP+0Vzfl5lFsFRwF1r3pg==" + }, "react-dom": { "version": "18.1.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.1.0.tgz", @@ -26362,6 +26822,39 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, + "react-jss": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/react-jss/-/react-jss-10.10.0.tgz", + "integrity": "sha512-WLiq84UYWqNBF6579/uprcIUnM1TSywYq6AIjKTTTG5ziJl9Uy+pwuvpN3apuyVwflMbD60PraeTKT7uWH9XEQ==", + "requires": { + "@babel/runtime": "^7.3.1", + "@emotion/is-prop-valid": "^0.7.3", + "css-jss": "10.10.0", + "hoist-non-react-statics": "^3.2.0", + "is-in-browser": "^1.1.3", + "jss": "10.10.0", + "jss-preset-default": "10.10.0", + "prop-types": "^15.6.0", + "shallow-equal": "^1.2.0", + "theming": "^3.3.0", + "tiny-warning": "^1.0.2" + }, + "dependencies": { + "@emotion/is-prop-valid": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.7.3.tgz", + "integrity": "sha512-uxJqm/sqwXw3YPA5GXX365OBcJGFtxUVkB6WyezqFHlNe9jqUWH5ur2O2M8dGBz61kn1g3ZBlzUunFQXQIClhA==", + "requires": { + "@emotion/memoize": "0.7.1" + } + }, + "@emotion/memoize": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.1.tgz", + "integrity": "sha512-Qv4LTqO11jepd5Qmlp3M1YEjBumoTHcHFdgPTQ+sFlIL5myi/7xu/POwP7IRu6odBdmLXdtIs1D6TuW6kbwbbg==" + } + } + }, "react-redux": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.1.0.tgz", @@ -26963,6 +27456,11 @@ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, + "shallow-equal": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz", + "integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==" + }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -27374,6 +27872,11 @@ } } }, + "symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" + }, "symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -27534,6 +28037,17 @@ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" }, + "theming": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/theming/-/theming-3.3.0.tgz", + "integrity": "sha512-u6l4qTJRDaWZsqa8JugaNt7Xd8PPl9+gonZaIe28vAhqgHMIG/DOyFPqiKN/gQLQYj05tHv+YQdNILL4zoiAVA==", + "requires": { + "hoist-non-react-statics": "^3.3.0", + "prop-types": "^15.5.8", + "react-display-name": "^0.2.4", + "tiny-warning": "^1.0.2" + } + }, "throat": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", @@ -27544,6 +28058,11 @@ "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" }, + "tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, "tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", diff --git a/package.json b/package.json index a3fd3a27..49f37853 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "@vis.gl/react-google-maps": "^0.8.3", "axios": "^1.6.8", "react": "^18.1.0", + "react-confetti-explosion": "^2.1.2", "react-dom": "^18.1.0", "react-hot-toast": "^2.4.1", "react-redux": "^9.1.0", diff --git a/src/index.js b/src/index.js index a833c470..235dc053 100644 --- a/src/index.js +++ b/src/index.js @@ -11,9 +11,6 @@ import NavBar from "./components/navbar.js"; import "./index.css"; //-----------Pages-----------// -import RegisterPage from "./pages/registerPage.js"; -import SignInPage from "./pages/signInPage.js"; -import ResetPasswordPage from "./pages/resetPasswordPage.js"; import ErrorPage from "./pages/errorPage.js"; import IntroPage from "./pages/introPage.js"; import ContactUsPage from "./pages/contactUsPage.js"; @@ -106,7 +103,6 @@ const NonAdminRoutes = () => ( const newUrl = window.location.origin + "/home"; -//testing with simple basic auth0 root.render( { axios @@ -31,6 +31,7 @@ export default function FreeReturnPage() { }) .then((response) => { setStatus("complete"); + setIsExploding("true"); }) .catch((error) => { console.error("Error inserting data", error); @@ -38,15 +39,40 @@ export default function FreeReturnPage() { }, []); return ( -
-

- Hooray! You're in. Your event reservation is complete - -

-
+ + {status === "complete" ? ( + <> + + + Hooray! You're in. + + + Your event reservation is complete + + {isExploding && } + + + + ) : ( +

Loading...

+ )} +
); - - // return null; } diff --git a/src/pages/userPages/returnPage.js b/src/pages/userPages/returnPage.js index 138a4455..205fcf1d 100644 --- a/src/pages/userPages/returnPage.js +++ b/src/pages/userPages/returnPage.js @@ -1,15 +1,12 @@ -import React, { useState, useEffect } from "react"; -import { Link } from "react-router-dom"; +import { useState, useEffect } from "react"; import { loadStripe } from "@stripe/stripe-js"; import axios from "axios"; -import { - BrowserRouter as Router, - Route, - Routes, - Navigate, -} from "react-router-dom"; -import Button from "@mui/material/Button"; +import { BrowserRouter as Router, Navigate, Link } from "react-router-dom"; +import { Box, Button, Typography, ThemeProvider } from "@mui/material"; +import ConfettiExplosion from "react-confetti-explosion"; + import { BACKEND_URL } from "../../constant.js"; +import theme from "../../theme"; const stripePromise = loadStripe( "pk_test_51OyC8VEkRpzvMxvMLDTzSAtzYuI8Aj98G0UQ3IkjB4ERSxgMQKMb9RNDz0LUq30pttvyJo0TsbnZVVZDxdP8SnIy000n2nrCq9" @@ -19,6 +16,14 @@ export default function ReturnPage() { const [status, setStatus] = useState(null); const [customerEmail, setCustomerEmail] = useState(""); const [loading, setLoading] = useState(true); + const [isExploding, setIsExploding] = useState(false); + + const mediumProps = { + force: 0.6, + duration: 2500, + particleCount: 200, + width: 1600, + }; useEffect(() => { const fetchData = async () => { @@ -35,9 +40,9 @@ export default function ReturnPage() { ); setStatus(response.data.status); - console.log("Setstatus:", status); setCustomerEmail(response.data.customer_email); setLoading(false); + setIsExploding("true"); } catch (error) { console.error("Error fetching client secret:", error); setLoading(false); @@ -58,20 +63,39 @@ export default function ReturnPage() { // Display confirmation message or redirect based on status if (status === "complete") { return ( -
-

- We appreciate your business! A confirmation email will be sent to{" "} - {customerEmail}. If you have any questions, please email{" "} - orders@example.com. -

- -
+ + + + Hooray! You're in. + + + Your event reservation is complete + + {isExploding && } + + + ); } else if (status === "open") { return ; } else { - return

Status: {status}

; // Handle other statuses if needed + return

Status: {status}

; } } From 110d8d3d70c030f078e18955858447164cccebcb Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Sun, 14 Apr 2024 00:04:44 +0800 Subject: [PATCH 52/69] updated myprofile page contact us button and refactoring code --- src/pages/contactUsPage.js | 3 +- src/pages/userPages/myProfilePage.js | 103 +++++++++++---------------- 2 files changed, 41 insertions(+), 65 deletions(-) diff --git a/src/pages/contactUsPage.js b/src/pages/contactUsPage.js index 1b868db2..ccfbb8f9 100644 --- a/src/pages/contactUsPage.js +++ b/src/pages/contactUsPage.js @@ -1,6 +1,5 @@ //-----------Libraries-----------// -import { Box, Button, Typography, ThemeProvider } from "@mui/material"; -import { Link } from "react-router-dom"; +import { Box, Typography, ThemeProvider } from "@mui/material"; //-----------Components-----------// import theme from "../theme"; diff --git a/src/pages/userPages/myProfilePage.js b/src/pages/userPages/myProfilePage.js index 90b691f6..434286d8 100644 --- a/src/pages/userPages/myProfilePage.js +++ b/src/pages/userPages/myProfilePage.js @@ -64,81 +64,58 @@ const MyProfilePage = () => { checkUser(); }, []); - if (!isAuthenticated) { - return ( - -
+ const handleContactUsClick = () => { + navigate("/contactus"); + }; + + const handleLoginOrLogout = () => { + if (isAuthenticated) { + logout(); + } else { + loginWithRedirect(); + } + }; + + return ( + +
+ {isLoading ? ( +

loading...

+ ) : ( +
+ {isAuthenticated && ( +
+ +
+ )} + + {user?.nickname} + +
+ )} - + - loginWithRedirect()()}> + - + - - ); - } - - return ( -
- {isLoading ? ( -

loading...

- ) : ( -
-
- -
- - {user && user?.nickname} - -
- )} - - - - - - - - - - - - - - - logout()}> - - - - - - -
+
+
); }; From ce4d0317abdf0647112c0fd75c24d0777b6f680f Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Sun, 14 Apr 2024 00:26:59 +0800 Subject: [PATCH 53/69] removed zone identifier --- public/blank/blank.svg | 685 ------------------------------- public/cover.png:Zone.Identifier | 0 2 files changed, 685 deletions(-) delete mode 100644 public/blank/blank.svg delete mode 100644 public/cover.png:Zone.Identifier diff --git a/public/blank/blank.svg b/public/blank/blank.svg deleted file mode 100644 index 7009ab22..00000000 --- a/public/blank/blank.svg +++ /dev/null @@ -1,685 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/cover.png:Zone.Identifier b/public/cover.png:Zone.Identifier deleted file mode 100644 index e69de29b..00000000 From f6d1826ca6243d62ab454128030ad40a63a143c2 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Sun, 14 Apr 2024 00:34:24 +0800 Subject: [PATCH 54/69] removed console log and comments --- src/components/EventPreview.js | 18 +------------ src/components/Redirect.js | 1 - src/components/navbar.js | 1 - src/components/searchBar.js | 30 ++++++++++----------- src/pages/errorPage.js | 36 +++++++++++++++++++++++-- src/pages/userPages/checkOutPage.js | 2 +- src/pages/userPages/eventBookingPage.js | 1 - src/pages/userPages/eventDetailPage.js | 8 ------ src/pages/userPages/myBookingPage.js | 6 ----- 9 files changed, 50 insertions(+), 53 deletions(-) diff --git a/src/components/EventPreview.js b/src/components/EventPreview.js index 758d157b..f365a293 100644 --- a/src/components/EventPreview.js +++ b/src/components/EventPreview.js @@ -1,14 +1,9 @@ //-----------Libraries-----------// import Card from "@mui/material/Card"; import CardContent from "@mui/material/CardContent"; -import CardActions from "@mui/material/CardActions"; import { CardMedia } from "@mui/material"; -import Button from "@mui/material/Button"; import Typography from "@mui/material/Typography"; import { Link } from "react-router-dom"; -import BookmarkIcon from "@mui/icons-material/Bookmark"; -import TurnedInTwoToneIcon from "@mui/icons-material/TurnedInTwoTone"; -import PlaceIcon from "@mui/icons-material/Place"; const EventPreview = (props) => { const formatDate = (string) => { @@ -42,17 +37,7 @@ const EventPreview = (props) => { sx={{ height: 120, position: "relative", borderRadius: 3 }} image={`${process.env.PUBLIC_URL}/shoes.jpg`} title="shoes" - > - {/* - - */} - + > { color="text.secondary" sx={{ padding: "0px", margin: "0px" }} > - {/* */} {props.data.admin.name} diff --git a/src/components/Redirect.js b/src/components/Redirect.js index 38a39fd6..bcf62d40 100644 --- a/src/components/Redirect.js +++ b/src/components/Redirect.js @@ -2,7 +2,6 @@ import { ThemeProvider } from "@mui/material/styles"; import theme from "../theme"; import Typography from "@mui/material/Typography"; -import { Link } from "react-router-dom"; import Box from "@mui/material/Box"; //-----------Components-----------// diff --git a/src/components/navbar.js b/src/components/navbar.js index e36ebb4e..90f2dd0a 100644 --- a/src/components/navbar.js +++ b/src/components/navbar.js @@ -3,7 +3,6 @@ import AppBar from "@mui/material/AppBar"; import Toolbar from "@mui/material/Toolbar"; import { Link } from "react-router-dom"; import ExploreIcon from "@mui/icons-material/Explore"; -import BookmarkIcon from "@mui/icons-material/Bookmark"; import EventIcon from "@mui/icons-material/Event"; import PersonIcon from "@mui/icons-material/Person"; import { ThemeProvider, styled } from "@mui/material/styles"; diff --git a/src/components/searchBar.js b/src/components/searchBar.js index 73c868c2..3fefb6ee 100644 --- a/src/components/searchBar.js +++ b/src/components/searchBar.js @@ -1,26 +1,24 @@ //-----------Libraries-----------// import { useState, useEffect } from "react"; -import { Link, useNavigate } from "react-router-dom"; -import SearchIcon from "@mui/icons-material/Search"; -import { styled, alpha } from "@mui/material/styles"; -import InputBase from "@mui/material/InputBase"; -import { Input, IconButton } from "@mui/material"; -import Box from "@mui/material/Box"; -import Drawer from "@mui/material/Drawer"; -import Button from "@mui/material/Button"; -import { Chip, Stack } from "@mui/material"; -import List from "@mui/material/List"; -import Divider from "@mui/material/Divider"; -import ListItem from "@mui/material/ListItem"; -import ListItemText from "@mui/material/ListItemText"; +import { useNavigate } from "react-router-dom"; +import { + Search as SearchIcon, + Input, + Box, + Drawer, + Button, + Chip, + Stack, + List, + Divider, + ListItem, + ListItemText, +} from "@mui/material"; import TuneIcon from "@mui/icons-material/Tune"; import Checkbox from "@mui/material/Checkbox"; import FormGroup from "@mui/material/FormGroup"; import FormControlLabel from "@mui/material/FormControlLabel"; import axios from "axios"; -import Container from "@mui/material/Container"; -import AppBar from "@mui/material/AppBar"; -import Toolbar from "@mui/material/Toolbar"; //-----------Components-----------// import "./searchBar.css"; diff --git a/src/pages/errorPage.js b/src/pages/errorPage.js index 14668c8b..2d37c9c8 100644 --- a/src/pages/errorPage.js +++ b/src/pages/errorPage.js @@ -1,8 +1,40 @@ //-----------Libraries-----------// -import { useState, useEffect } from "react"; +import { Box, Button, Typography, ThemeProvider } from "@mui/material"; +import { Link } from "react-router-dom"; //-----------Components-----------// +import theme from "../theme"; export default function ErrorPage() { - return
Error page
; + return ( + + + + Error + + + + + ); } diff --git a/src/pages/userPages/checkOutPage.js b/src/pages/userPages/checkOutPage.js index 98e8c789..24432de8 100644 --- a/src/pages/userPages/checkOutPage.js +++ b/src/pages/userPages/checkOutPage.js @@ -56,7 +56,7 @@ const CheckoutForm = () => { .then((response) => response.data.clientSecret) .catch((error) => { console.error("Error fetching client secret:", error); - throw error; // rethrow the error to handle it elsewhere if needed + throw error; }); }, [accessToken, eventId, quantity_bought, user_id]); diff --git a/src/pages/userPages/eventBookingPage.js b/src/pages/userPages/eventBookingPage.js index 5c3e1c02..2eb456d7 100644 --- a/src/pages/userPages/eventBookingPage.js +++ b/src/pages/userPages/eventBookingPage.js @@ -3,7 +3,6 @@ import { useState, useEffect } from "react"; import { Link } from "react-router-dom"; import axios from "axios"; import { Box, Button, Typography, ThemeProvider } from "@mui/material"; -import { styles } from "@mui/system"; import { useAuth0 } from "@auth0/auth0-react"; //-----------Components-----------// diff --git a/src/pages/userPages/eventDetailPage.js b/src/pages/userPages/eventDetailPage.js index 5519dabd..0f8f4584 100644 --- a/src/pages/userPages/eventDetailPage.js +++ b/src/pages/userPages/eventDetailPage.js @@ -28,7 +28,6 @@ export default function EventDetailPage() { const [eventId, setEventId] = useState(); const [showRegistration, setShowRegistraton] = useState(null); const [isFree, setIsFree] = useState(null); - // const [accessToken, setAccessToken] = useState(); const { user, loginWithRedirect, isAuthenticated, getAccessTokenSilently } = useAuth0(); const [accessToken, setAccessToken] = useState(); @@ -68,8 +67,6 @@ export default function EventDetailPage() { }); } setShowRegistraton(true); - // let token = await getAccessTokenSilently(); - // setAccessToken(token); }; const handleClose = () => { @@ -119,11 +116,6 @@ export default function EventDetailPage() { {event.description} - {/* - - ${event.price} - - */} Date: Sun, 14 Apr 2024 00:35:38 +0800 Subject: [PATCH 55/69] removed unused pages --- src/App.js | 0 src/pages/registerPage.js | 172 --------------------------------- src/pages/resetPasswordPage.js | 104 -------------------- src/pages/signInPage.js | 102 ------------------- 4 files changed, 378 deletions(-) delete mode 100644 src/App.js delete mode 100644 src/pages/registerPage.js delete mode 100644 src/pages/resetPasswordPage.js delete mode 100644 src/pages/signInPage.js diff --git a/src/App.js b/src/App.js deleted file mode 100644 index e69de29b..00000000 diff --git a/src/pages/registerPage.js b/src/pages/registerPage.js deleted file mode 100644 index 2feed410..00000000 --- a/src/pages/registerPage.js +++ /dev/null @@ -1,172 +0,0 @@ -import Grid from "@mui/material/Grid"; -import Paper from "@mui/material/Paper"; -import Typography from "@mui/material/Typography"; -import TextField from "@mui/material/TextField"; -import Button from "@mui/material/Button"; -import { Link, useNavigate } from "react-router-dom"; -import MailOutlinedIcon from "@mui/icons-material/MailOutlined"; -import InputAdornment from "@mui/material/InputAdornment"; -import LockOutlinedIcon from "@mui/icons-material/LockOutlined"; -import ArrowForwardIcon from "@mui/icons-material/ArrowForward"; -import ArrowBackIcon from "@mui/icons-material/ArrowBack"; -import PersonOutlineOutlinedIcon from "@mui/icons-material/PersonOutlineOutlined"; -import { useEffect, useState } from "react"; - -export default function RegisterPage() { - const [name, setName] = useState(); - const [email, setEmail] = useState(); - const [password, setPassword] = useState(); - const [confirmPassword, setConfirmPassword] = useState(); - - return ( -
- - - -
- - - -
- - Sign up - -
- setName(e.target.value)} - fullWidth - style={{ marginBottom: "1.5rem" }} - InputProps={{ - startAdornment: ( - - - - ), - }} - />{" "} - setEmail(e.target.value)} - fullWidth - style={{ marginBottom: "1.5rem" }} - InputProps={{ - startAdornment: ( - - - - ), - }} - />{" "} - setPassword(e.target.value)} - style={{ marginBottom: "1.5rem" }} - InputProps={{ - startAdornment: ( - - - - ), - }} - /> - setConfirmPassword(e.target.value)} - fullWidth - style={{ marginBottom: ".5rem" }} - InputProps={{ - startAdornment: ( - - - - ), - }} - /> - - - Already have an account?{" "} - - Sign in - - - -
-
-
-
- ); -} diff --git a/src/pages/resetPasswordPage.js b/src/pages/resetPasswordPage.js deleted file mode 100644 index dfe431f8..00000000 --- a/src/pages/resetPasswordPage.js +++ /dev/null @@ -1,104 +0,0 @@ -import Grid from "@mui/material/Grid"; -import Paper from "@mui/material/Paper"; -import Typography from "@mui/material/Typography"; -import TextField from "@mui/material/TextField"; -import Button from "@mui/material/Button"; -import { Link } from "react-router-dom"; -import MailOutlinedIcon from "@mui/icons-material/MailOutlined"; -import InputAdornment from "@mui/material/InputAdornment"; -import ArrowForwardIcon from "@mui/icons-material/ArrowForward"; -import ArrowBackIcon from "@mui/icons-material/ArrowBack"; - -export default function ResetPasswordPage() { - return ( -
- - - -
- - - -
- - Reset Password - - - Please enter your email address to request a password reset - -
- - - - ), - }} - />{" "} - - -
-
-
-
- ); -} diff --git a/src/pages/signInPage.js b/src/pages/signInPage.js deleted file mode 100644 index 3b523678..00000000 --- a/src/pages/signInPage.js +++ /dev/null @@ -1,102 +0,0 @@ -import React, { useEffect, useState } from "react"; -import Grid from "@mui/material/Grid"; -import Paper from "@mui/material/Paper"; -import Button from "@mui/material/Button"; -import { Link, useNavigate } from "react-router-dom"; -import ArrowForwardIcon from "@mui/icons-material/ArrowForward"; -import { useAuth0 } from "@auth0/auth0-react"; - -const SignIn = () => { - const [rememberMe, setRememberMe] = useState(false); - const handleRememberMe = () => { - setRememberMe(!rememberMe); - }; - - const [email, setEmail] = useState(""); - const [password, setPassword] = useState(""); - const { - loginWithRedirect, - loginWithPopup, - isAuthenticated, - getAccessTokenSilently, - logout, - isLoading, - user, - } = useAuth0(); - const navigate = useNavigate(); - const [accessToken, setAccessToken] = useState(); - const checkUser = async () => { - if (isAuthenticated) { - let token = await getAccessTokenSilently(); - setAccessToken(token); - navigate("/profile"); - } else { - loginWithRedirect(); - } - }; - useEffect(() => { - checkUser(); - }, []); - - return ( -
- - - -
- {!isAuthenticated && ( - - )} -
-
-
-
-
- ); -}; - -export default SignIn; From 44e7a6108fed587f5579a51fe0aed2f45de4e59e Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Sun, 14 Apr 2024 00:38:47 +0800 Subject: [PATCH 56/69] fixed import --- src/components/searchBar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/searchBar.js b/src/components/searchBar.js index 3fefb6ee..c0f62c24 100644 --- a/src/components/searchBar.js +++ b/src/components/searchBar.js @@ -2,7 +2,6 @@ import { useState, useEffect } from "react"; import { useNavigate } from "react-router-dom"; import { - Search as SearchIcon, Input, Box, Drawer, @@ -17,6 +16,7 @@ import { import TuneIcon from "@mui/icons-material/Tune"; import Checkbox from "@mui/material/Checkbox"; import FormGroup from "@mui/material/FormGroup"; +import SearchIcon from "@mui/icons-material/Search"; import FormControlLabel from "@mui/material/FormControlLabel"; import axios from "axios"; From 62ca82c3527c5e0dd46f27fbcd1af06873f1e86d Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Sun, 14 Apr 2024 16:48:48 +0800 Subject: [PATCH 57/69] base --- src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index 235dc053..61738f30 100644 --- a/src/index.js +++ b/src/index.js @@ -10,7 +10,7 @@ import NavBar from "./components/navbar.js"; //-----------Styling-----------// import "./index.css"; -//-----------Pages-----------// +//-----------Pages-----------/// import ErrorPage from "./pages/errorPage.js"; import IntroPage from "./pages/introPage.js"; import ContactUsPage from "./pages/contactUsPage.js"; From ad5100d4301c762a4b7e700270c2530ef5bc8e18 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Mon, 15 Apr 2024 00:50:02 +0800 Subject: [PATCH 58/69] added admin --- src/components/AdminEventPreview.js | 89 ++++ src/components/AdminEventPreviewList.js | 66 +++ src/components/AdminNavBar.js | 44 ++ src/index.js | 112 ++++- src/pages/adminPages/AdminCreateEvent.jsx | 533 ++++++++++++---------- src/pages/adminPages/adminCreateEvent.js | 378 +++++++++++++++ src/pages/adminPages/adminHomePage.js | 92 +++- src/pages/adminPages/adminIntroPage.js | 59 +++ src/pages/adminPages/adminProfilePage.js | 128 +++++- src/pages/adminPages/adminSettingsPage.js | 126 +++++ src/pages/errorPage.js | 2 +- 11 files changed, 1343 insertions(+), 286 deletions(-) create mode 100644 src/components/AdminEventPreview.js create mode 100644 src/components/AdminEventPreviewList.js create mode 100644 src/components/AdminNavBar.js create mode 100644 src/pages/adminPages/adminCreateEvent.js create mode 100644 src/pages/adminPages/adminIntroPage.js create mode 100644 src/pages/adminPages/adminSettingsPage.js diff --git a/src/components/AdminEventPreview.js b/src/components/AdminEventPreview.js new file mode 100644 index 00000000..aca39044 --- /dev/null +++ b/src/components/AdminEventPreview.js @@ -0,0 +1,89 @@ +//-----------Libraries-----------// +import Card from "@mui/material/Card"; +import CardContent from "@mui/material/CardContent"; +import { CardMedia } from "@mui/material"; +import Typography from "@mui/material/Typography"; +import { Link } from "react-router-dom"; + +const EventPreview = (props) => { + const formatDate = (string) => { + const date = new Date(string); + const options = { + day: "numeric", + month: "long", + hour: "2-digit", + minute: "2-digit", + }; + return date.toLocaleDateString("en-US", options); + }; + + //add logic to see whether start and end date is the same. + const formatHour = (string) => { + const date = new Date(string); + const options = { + hour: "2-digit", + minute: "2-digit", + }; + return date.toLocaleTimeString("en-US", options); + }; + + const priceText = props.data.price === 0 ? "Free" : `$${props.data.price}`; + + return ( + + + <> + + {/* */} + + {formatDate(props.data.start)}-{formatHour(props.data.end)} + +
+
+ + {props.data.title} + +
+
+ + {priceText} + +
+
+ + {props.data.status.name} + + {/* */} + +
+
+ ); +}; + +export default EventPreview; diff --git a/src/components/AdminEventPreviewList.js b/src/components/AdminEventPreviewList.js new file mode 100644 index 00000000..bba0dacd --- /dev/null +++ b/src/components/AdminEventPreviewList.js @@ -0,0 +1,66 @@ +//-----------Libraries-----------// +import { useState, useEffect } from "react"; +import axios from "axios"; +import { Box, Card, CardMedia, Typography } from "@mui/material"; + +//-----------Components-----------// +import AdminEventPreview from "./AdminEventPreview"; +import { BACKEND_URL } from "../constant.js"; + +const AdminEventPreviewList = ({ adminId }) => { + const [events, setEvents] = useState([]); + + useEffect(() => { + const fetchData = async () => { + try { + const response = await axios.post(`${BACKEND_URL}/events/admin`, { + adminId: adminId, + }); + setEvents(response.data); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + fetchData(); + }, []); + + if (events.length === 0) { + return ( + + + + You don't have any events. + + + ); + } + + const eventPreviews = events.map((event) => ( + + )); + return <>{eventPreviews}; +}; + +export default AdminEventPreviewList; diff --git a/src/components/AdminNavBar.js b/src/components/AdminNavBar.js new file mode 100644 index 00000000..ca1ab83d --- /dev/null +++ b/src/components/AdminNavBar.js @@ -0,0 +1,44 @@ +//-----------Libraries-----------// +import AppBar from "@mui/material/AppBar"; +import Toolbar from "@mui/material/Toolbar"; +import { Link } from "react-router-dom"; +import ExploreIcon from "@mui/icons-material/Explore"; +import EventIcon from "@mui/icons-material/Event"; +import PersonIcon from "@mui/icons-material/Person"; +import { ThemeProvider, styled } from "@mui/material/styles"; +import AddCircleOutlineIcon from "@mui/icons-material/AddCircleOutline"; + +//-----------Components-----------// +import theme from "../theme"; + +//-----------Styling-----------// +import "../App.css"; + +export default function AdminNavBar() { + const Offset = styled("div")(({ theme }) => theme.mixins.toolbar); + + return ( + + + + + + + + + + + + + + + + + ); +} diff --git a/src/index.js b/src/index.js index 61738f30..c643ceb7 100644 --- a/src/index.js +++ b/src/index.js @@ -6,6 +6,7 @@ import ReactDOM from "react-dom/client"; //-----------Components-----------// import NavBar from "./components/navbar.js"; +import AdminNavBar from "./components/AdminNavBar.js"; //-----------Styling-----------// import "./index.css"; @@ -26,19 +27,48 @@ import ReturnPage from "./pages/userPages/returnPage.js"; import SearchPage from "./pages/userPages/searchPage.js"; //-----------AdminPages-----------// +import AdminIntroPage from "./pages/adminPages/adminIntroPage.js"; import AdminHomePage from "./pages/adminPages/adminHomePage.js"; import AdminProfilePage from "./pages/adminPages/adminProfilePage.js"; -import AdminCreateEvent from "./pages/adminPages/AdminCreateEvent.jsx"; +import AdminCreateEvent from "./pages/adminPages/adminCreateEvent.js"; import { Toaster } from "react-hot-toast"; +import AdminSettingsPage from "./pages/adminPages/adminSettingsPage.js"; const root = ReactDOM.createRoot(document.getElementById("root")); const AdminRoutes = () => ( - } /> + } /> + + + + + } + /> + } /> } /> - } /> - } /> + + + + + } + /> + + + + + } + /> + {/* } /> */} ); @@ -97,28 +127,66 @@ const NonAdminRoutes = () => ( } /> } /> } /> - } /> + {/* } /> */}
); const newUrl = window.location.origin + "/home"; +const newUrlAdmin = window.location.origin + "/admin/home"; root.render( - - - - } /> - } /> - - - - + <> + + + + } /> + + + + + + + + } /> + + + + + ); + +// root.render( +// <> +// +// +// +// } /> +// } /> +// +// +// +// +// +// ); diff --git a/src/pages/adminPages/AdminCreateEvent.jsx b/src/pages/adminPages/AdminCreateEvent.jsx index c0a3aed3..1de459ea 100644 --- a/src/pages/adminPages/AdminCreateEvent.jsx +++ b/src/pages/adminPages/AdminCreateEvent.jsx @@ -1,257 +1,286 @@ -import Grid from "@mui/material/Grid"; -import Paper from "@mui/material/Paper"; -import Typography from "@mui/material/Typography"; -import TextField from "@mui/material/TextField"; -import Button from "@mui/material/Button"; -import { Link, useNavigate } from "react-router-dom"; -import MailOutlinedIcon from "@mui/icons-material/MailOutlined"; -import InputAdornment from "@mui/material/InputAdornment"; -import LockOutlinedIcon from "@mui/icons-material/LockOutlined"; -import ArrowForwardIcon from "@mui/icons-material/ArrowForward"; -import ArrowBackIcon from "@mui/icons-material/ArrowBack"; -import PersonOutlineOutlinedIcon from "@mui/icons-material/PersonOutlineOutlined"; -import MenuItem from "@mui/material/MenuItem"; -import Select from "@mui/material/Select"; -import TextareaAutosize from "@mui/material/TextareaAutosize"; -import React, { useState } from "react"; -import RadioGroup from "@mui/material/RadioGroup"; -import FormControlLabel from "@mui/material/FormControlLabel"; -import Radio from "@mui/material/Radio"; -import MonetizationOnIcon from "@mui/icons-material/MonetizationOn"; -import CloudUploadIcon from "@mui/icons-material/CloudUpload"; -import Box from "@mui/material/Box"; +// import Grid from "@mui/material/Grid"; +// import Paper from "@mui/material/Paper"; +// import Typography from "@mui/material/Typography"; +// import TextField from "@mui/material/TextField"; +// import Button from "@mui/material/Button"; +// import axios from "axios"; +// import { Link, useNavigate } from "react-router-dom"; +// import MailOutlinedIcon from "@mui/icons-material/MailOutlined"; +// import InputAdornment from "@mui/material/InputAdornment"; +// import MenuItem from "@mui/material/MenuItem"; +// import Select from "@mui/material/Select"; +// import TextareaAutosize from "@mui/material/TextareaAutosize"; +// import React, { useState } from "react"; +// import RadioGroup from "@mui/material/RadioGroup"; +// import FormControlLabel from "@mui/material/FormControlLabel"; +// import Radio from "@mui/material/Radio"; +// import MonetizationOnIcon from "@mui/icons-material/MonetizationOn"; +// import CloudUploadIcon from "@mui/icons-material/CloudUpload"; +// import Box from "@mui/material/Box"; +// import { BACKEND_URL } from "../../constant.js"; -export default function AdminCreateEvent() { - const [ticketPrice, setTicketPrice] = useState("free"); - const [paidAmount, setPaidAmount] = useState(""); +// export default function AdminCreateEvent() { +// const [ticketPrice, setTicketPrice] = useState("free"); +// const [paidAmount, setPaidAmount] = useState(""); +// const [title, setTitle] = useState(""); +// const [description, setDescription] = useState(""); +// const [languageId, setLanguageId] = useState(""); +// const [categoryId, setCategoryId] = useState(""); +// const [venueId, setVenueId] = useState(""); +// const [adminId, setAdminId] = useState(""); +// const [price, setPrice] = useState(""); +// const [start, setStart] = useState(""); +// const [end, setEnd] = useState(""); +// const [statusId, setStatusId] = useState(""); +// const [capacity, setCapacity] = useState(""); - const handlePriceChange = (event) => { - setTicketPrice(event.target.value); - }; +// const handlePriceChange = (event) => { +// setTicketPrice(event.target.value); +// }; - const handleAmountChange = (event) => { - setPaidAmount(event.target.value); - }; - return ( -
- - - - {/*
- - - Events - -
*/} - - Event - -
- {" "} - Date - {" "} -
- - { +// setPaidAmount(event.target.value); +// }; - variant="outlined" - type="time" - fullWidth - style={{ marginBottom: ".5rem" }} - /> -
- Category - - {" "} - -
- - } - label="Free" - /> - } - label="Paid" - /> - - {ticketPrice === "paid" && ( - - - - ), - }} - /> - )} -
- - {/* Image upload button */} - - +// const handleSubmit = (event) => { +// event.preventDefault(); - {/* Video upload button */} - - - -
- - -
- -
-
-
-
- ); -} +// axios +// .post(`${BACKEND_URL}/events`, { +// title, +// description, +// languageId, +// categoryId, +// venueId, +// adminId, +// price, +// start, +// end, +// statusId, +// capacity, +// }) +// .then((res) => { +// setTitle(""); +// setDescription(""); +// setLanguageId(""); +// setCategoryId(""); +// setVenueId(""); +// setAdminId(""); +// setPrice(""); +// setStart(""); +// setEnd(""); +// setStatusId(""); +// setCapacity(""); + +// // Navigate to event-specific page after submitting form +// }); +// }; + +// return ( +//
+// +// +// +// +// Event +// +//
+// {" "} +// Date +// {" "} +//
+// +// +//
+// Category +// +// {" "} +// +//
+// +// } +// label="Free" +// /> +// } +// label="Paid" +// /> +// +// {ticketPrice === "paid" && ( +// +// +// +// ), +// }} +// /> +// )} +//
+// +// {/* Image upload button */} +// +// + +// {/* Video upload button */} +// +// +// +//
+// +// +//
+// +//
+//
+//
+//
+// ); +// } diff --git a/src/pages/adminPages/adminCreateEvent.js b/src/pages/adminPages/adminCreateEvent.js new file mode 100644 index 00000000..1b5a2dba --- /dev/null +++ b/src/pages/adminPages/adminCreateEvent.js @@ -0,0 +1,378 @@ +//-----------Libraries-----------// +import { useState, useEffect } from "react"; +import { useAuth0 } from "@auth0/auth0-react"; +import { Link, useNavigate } from "react-router-dom"; +import axios from "axios"; +import { + Box, + Grid, + InputAdornment, + InputLabel, + OutlinedInput, + Paper, + Typography, + TextField, + Button, + MenuItem, + Select, +} from "@mui/material"; +import { APIProvider, Map, AdvancedMarker } from "@vis.gl/react-google-maps"; +import ArrowBackIcon from "@mui/icons-material/ArrowBack"; + +//-----------Components-----------// +import { BACKEND_URL } from "../../constant.js"; + +export default function AdminCreateEvent() { + const [title, setTitle] = useState(""); + const [description, setDescription] = useState(""); + const [venueId, setVenueId] = useState(""); + const [adminId, setAdminId] = useState(""); + const [price, setPrice] = useState(""); + const [start, setStart] = useState(""); + const [end, setEnd] = useState(""); + const [capacity, setCapacity] = useState(""); + const [languages, setLanguages] = useState([]); + const [selectedLanguageId, setSelectedLanguageId] = useState(); + const [categories, setCategories] = useState([]); + const [selectedCategoryId, setSelectedCategoryId] = useState(""); + const [statuses, setStatuses] = useState([]); + const [selectedStatusId, setSelectedStatusId] = useState(""); + const [marker, setMarker] = useState(); + const [address, setAddress] = useState(); + const [postalCode, setPostalCode] = useState(); + const [errorMessage, setErrorMessage] = useState(false); + const { + isAuthenticated, + loginWithRedirect, + logout, + isLoading, + getAccessTokenSilently, + user, + } = useAuth0(); + const [accessToken, setAccessToken] = useState(); + const navigate = useNavigate(); + + useEffect(() => { + const fetchData = async () => { + try { + const [categoriesResponse, languagesResponse, statusesResponse] = + await Promise.all([ + axios.get(`${BACKEND_URL}/categories`), + axios.get(`${BACKEND_URL}/categories/languages`), + axios.get(`${BACKEND_URL}/categories/statuses`), + ]); + + setCategories(categoriesResponse.data); + setLanguages(languagesResponse.data); + setStatuses(statusesResponse.data); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + fetchData(); + }, []); + + const onMapClick = (e) => { + setMarker({ + lat: e.detail.latLng.lat, + lng: e.detail.latLng.lng, + }); + }; + + const fetchData = async () => { + try { + if (user && user.email) { + const response = await axios.post(`${BACKEND_URL}/admins/`, { + email: user.email, + name: "CC", + }); + + const output = response.data; + + setAdminId(output[0].id); + } + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const checkUser = async () => { + if (isAuthenticated) { + let token = await getAccessTokenSilently(); + setAccessToken(token); + fetchData(); + } + }; + + useEffect(() => { + checkUser(); + }, []); + + useEffect(() => { + if (!isAuthenticated && !isLoading) { + navigate("/admin"); + } + }, [isAuthenticated, isLoading, navigate]); + + const handleSubmit = async (event) => { + event.preventDefault(); + + if ( + !title || + !description || + !selectedLanguageId || + !selectedCategoryId || + !selectedStatusId || + !price || + !start || + !end || + !capacity || + !address || + !postalCode || + !marker + ) { + setErrorMessage(true); + return; // Prevent form submission + } + + try { + const venueResponse = await axios.post(`${BACKEND_URL}/venues`, { + lat: marker.lat, + lng: marker.lng, + postal_code: postalCode, + address: address, + country: "Singapore", + }); + + const venueId = venueResponse.data.id; + + await axios.post(`${BACKEND_URL}/events`, { + title: title, + description: description, + languageId: selectedLanguageId, + categoryId: selectedCategoryId, + venueId: venueId, + adminId: adminId, + price: price, + start: start, + end: end, + statusId: selectedStatusId, + capacity: capacity, + }); + + setTitle(""); + setDescription(""); + setSelectedLanguageId(""); + setSelectedCategoryId(""); + setVenueId(""); + setAdminId(""); + setPrice(""); + setStart(""); + setEnd(""); + setAddress(""); + setPostalCode(""); + setSelectedStatusId(""); + setCapacity(""); + + navigate("../home", { replace: true }); + } catch (error) { + console.error("Error handling form submission:", error); + } + }; + + return ( + + + + + + + + + Create Event + +
+ + + Title + setTitle(e.target.value)} + /> + + + + Description + setDescription(e.target.value)} + /> + + + + Language + + + + + Category + + + + Status + + + + Amount + $ + } + value={price} + onChange={(e) => setPrice(e.target.value)} + /> + + + Start + setStart(e.target.value)} + InputLabelProps={{ + shrink: true, + }} + /> + + + End + setEnd(e.target.value)} + InputLabelProps={{ + shrink: true, + }} + /> + + + + Capacity + setCapacity(e.target.value)} + /> + + + Address + setAddress(e.target.value)} + /> + + + Postal Code + setPostalCode(e.target.value)} + /> + + + + + + + {marker && ( + + )} + + + + + {errorMessage &&

Please fill in all the details

} +
+
+ ); +} diff --git a/src/pages/adminPages/adminHomePage.js b/src/pages/adminPages/adminHomePage.js index 3dfe7389..a5e966ae 100644 --- a/src/pages/adminPages/adminHomePage.js +++ b/src/pages/adminPages/adminHomePage.js @@ -1,14 +1,92 @@ //-----------Libraries-----------// -import { useState, useEffect } from "react"; -import { Outlet } from "react-router-dom"; +import { Typography, ThemeProvider } from "@mui/material"; +import { Link, useNavigate } from "react-router-dom"; +import { useAuth0 } from "@auth0/auth0-react"; +import axios from "axios"; +import { useEffect, useState } from "react"; //-----------Components-----------// +import AdminEventPreviewList from "../../components/AdminEventPreviewList"; +import theme from "../../theme"; +import { BACKEND_URL } from "../../constant.js"; + +export default function AdminHomePage() { + const { + isAuthenticated, + loginWithRedirect, + logout, + isLoading, + getAccessTokenSilently, + user, + } = useAuth0(); + const domain = process.env.REACT_APP_AUTH0_DOMAIN; + const navigate = useNavigate(); + const [accessToken, setAccessToken] = useState(); + const [adminId, setAdminId] = useState(); + + const handleLogin = () => { + navigate("/admin/home"); + }; + + useEffect(() => { + const fetchAdminId = async () => { + try { + if (user && user.email) { + const token = await getAccessTokenSilently(); + const response = await axios.post( + `${BACKEND_URL}/admins/`, + { + email: user.email, + }, + { + headers: { + Authorization: `Bearer ${token}`, + }, + } + ); + console.log("success"); + const output = response.data; + console.log(output); + setAdminId(output[0].id); + } else { + console.log("User email is undefined."); + } + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + if (isAuthenticated) { + fetchAdminId(); + } + }, [getAccessTokenSilently, isAuthenticated, user]); + + console.log(isAuthenticated); + console.log(adminId); + + useEffect(() => { + if (!isAuthenticated && !isLoading) { + navigate("/admin"); + } + }, [isAuthenticated, isLoading, navigate]); -export default function adminHomePage() { return ( -
- - Admin homepage -
+ +
+ + Your Events + + {adminId && } +
+
); } diff --git a/src/pages/adminPages/adminIntroPage.js b/src/pages/adminPages/adminIntroPage.js new file mode 100644 index 00000000..98f8106d --- /dev/null +++ b/src/pages/adminPages/adminIntroPage.js @@ -0,0 +1,59 @@ +//-----------Libraries-----------// +import { Box, Button, Typography, ThemeProvider } from "@mui/material"; +import { useEffect, useState } from "react"; +import { Link, useNavigate } from "react-router-dom"; +import { useAuth0 } from "@auth0/auth0-react"; + +//-----------Components-----------// +import theme from "../../theme"; + +export default function AdminIntroPage() { + const { isAuthenticated, loginWithRedirect } = useAuth0(); + + const navigate = useNavigate(); + + const handleLogin = () => { + if (isAuthenticated) { + navigate("/admin/home"); + } else { + loginWithRedirect(); + } + }; + + return ( + + + Coverpage + + + Create Your Community Events Anywhere + + + + + ); +} diff --git a/src/pages/adminPages/adminProfilePage.js b/src/pages/adminPages/adminProfilePage.js index 379bc45b..ccee8eb3 100644 --- a/src/pages/adminPages/adminProfilePage.js +++ b/src/pages/adminPages/adminProfilePage.js @@ -1,8 +1,128 @@ //-----------Libraries-----------// -import { useState, useEffect } from "react"; +import { useEffect, useState } from "react"; +import { + Avatar, + ThemeProvider, + Typography, + List, + ListItem, + ListItemIcon, + ListItemText, +} from "@mui/material"; +import { + CalendarToday as CalendarTodayIcon, + ContactSupport as ContactSupportIcon, + ExitToApp as ExitToAppIcon, +} from "@mui/icons-material"; +import { useAuth0 } from "@auth0/auth0-react"; +import axios from "axios"; +import { Link, useNavigate } from "react-router-dom"; //-----------Components-----------// +import { BACKEND_URL } from "../../constant.js"; +import theme from "../../theme"; -export default function AdminProfilePage() { - return
Admin profile page
; -} +const AdminProfilePage = () => { + const { + isAuthenticated, + loginWithRedirect, + logout, + isLoading, + getAccessTokenSilently, + user, + } = useAuth0(); + const domain = process.env.REACT_APP_AUTH0_DOMAIN; + const navigate = useNavigate(); + const [accessToken, setAccessToken] = useState(); + const [adminDb, setAdminDb] = useState(); + + const fetchData = async () => { + try { + if (user && user.email) { + const response = await axios.post(`${BACKEND_URL}/admins/`, { + email: user.email, + }); + const output = response.data; + setAdminDb(output[0]); + } else { + console.log("User email is undefined."); + } + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const checkUser = async () => { + if (isAuthenticated) { + let token = await getAccessTokenSilently(); + setAccessToken(token); + fetchData(); + } + }; + + useEffect(() => { + checkUser(); + }, []); + + useEffect(() => { + if (!isAuthenticated && !isLoading) { + navigate("/admin"); + } + }, [isAuthenticated, isLoading, navigate]); + + const handleSettingClick = () => { + navigate("/admin/settings"); + }; + + const handleLoginOrLogout = () => { + if (isAuthenticated) { + logout(); + } else { + loginWithRedirect(); + } + }; + + return ( + +
+ {isLoading ? ( +

loading...

+ ) : ( +
+ {isAuthenticated && ( +
+ +
+ )} + + {adminDb && adminDb.name} + +
+ )} + + + + + + + + + + + + + + + +
+
+ ); +}; + +export default AdminProfilePage; diff --git a/src/pages/adminPages/adminSettingsPage.js b/src/pages/adminPages/adminSettingsPage.js new file mode 100644 index 00000000..3f84d597 --- /dev/null +++ b/src/pages/adminPages/adminSettingsPage.js @@ -0,0 +1,126 @@ +//-----------Libraries-----------// +import { useState, useEffect } from "react"; +import { useParams, Link, useNavigate } from "react-router-dom"; +import axios from "axios"; +import { + Button, + Dialog, + Box, + TextField, + Typography, + Grid, +} from "@mui/material"; +import { ThemeProvider } from "@mui/material"; +import { useAuth0 } from "@auth0/auth0-react"; + +//-----------Components-----------// +import { BACKEND_URL } from "../../constant.js"; +import theme from "../../theme.js"; + +export default function AdminSettingsPage() { + const [admin, setAdmin] = useState(); + const { + user, + loginWithRedirect, + isLoading, + isAuthenticated, + getAccessTokenSilently, + } = useAuth0(); + const [accessToken, setAccessToken] = useState(); + const [editName, setEditName] = useState(""); + const navigate = useNavigate(); + + useEffect(() => { + const fetchAdmin = async () => { + try { + if (user && user.email) { + console.log(user.email); + const token = await getAccessTokenSilently(); + const response = await axios.post( + `${BACKEND_URL}/admins/`, + { + email: user.email, + }, + { + headers: { + Authorization: `Bearer ${token}`, + }, + } + ); + console.log("success"); + const output = response.data; + setAdmin(output[0]); + if (output && output[0].name) { + setEditName(output[0].name); + } + } else { + console.log("User email is undefined."); + } + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + if (isAuthenticated) { + fetchAdmin(); + } + }, [getAccessTokenSilently, isAuthenticated, user]); + + useEffect(() => { + if (!isAuthenticated && !isLoading) { + navigate("/admin"); + } + }, [isAuthenticated, isLoading, navigate]); + + const handleFormSubmit = async (e) => { + e.preventDefault(); + try { + const token = await getAccessTokenSilently(); + const response = await axios.put( + `${BACKEND_URL}/admins/${admin.id}`, + { + newName: editName, + }, + { + headers: { + Authorization: `Bearer ${token}`, + }, + } + ); + console.log("Update success"); + setAdmin({ ...admin, name: editName }); + navigate("../profile", { replace: true }); + } catch (error) { + console.error("Error updating name:", error); + } + }; + + const handleNameChange = (e) => { + setEditName(e.target.value); + }; + + const adminInfo = admin ? ( + +
+ + + + + + + + +
+
+ ) : null; + + return {adminInfo}; +} diff --git a/src/pages/errorPage.js b/src/pages/errorPage.js index 2d37c9c8..ec439ff7 100644 --- a/src/pages/errorPage.js +++ b/src/pages/errorPage.js @@ -27,7 +27,7 @@ export default function ErrorPage() { diff --git a/src/pages/userPages/eventDetailPage.js b/src/pages/userPages/eventDetailPage.js index 0f8f4584..fe5e0eed 100644 --- a/src/pages/userPages/eventDetailPage.js +++ b/src/pages/userPages/eventDetailPage.js @@ -77,8 +77,8 @@ export default function EventDetailPage() { const eventInfo = event ? ( shoes Date: Mon, 15 Apr 2024 02:47:44 +0800 Subject: [PATCH 60/69] added admin can see who book their events --- src/components/AdminEventPreview.js | 76 +++--- src/index.js | 4 +- src/pages/adminPages/adminEventPage.js | 324 +++++++------------------ 3 files changed, 130 insertions(+), 274 deletions(-) diff --git a/src/components/AdminEventPreview.js b/src/components/AdminEventPreview.js index 390a6ae5..b2ddcf0a 100644 --- a/src/components/AdminEventPreview.js +++ b/src/components/AdminEventPreview.js @@ -45,48 +45,48 @@ const EventPreview = (props) => { image={props.data.image_link} title={props.data.id} > - {/* */} - - {formatDate(props.data.start)}-{formatHour(props.data.end)} - -
-
- - {props.data.title} - + + {formatDate(props.data.start)}-{formatHour(props.data.end)} + +
+
+ + {props.data.title} + +
+
+ + {priceText} + +
-
- - {priceText} - -
-
- - {props.data.status.name} - - {/* */} + + {props.data.status.name} + + diff --git a/src/index.js b/src/index.js index c643ceb7..c7ca5272 100644 --- a/src/index.js +++ b/src/index.js @@ -33,6 +33,7 @@ import AdminProfilePage from "./pages/adminPages/adminProfilePage.js"; import AdminCreateEvent from "./pages/adminPages/adminCreateEvent.js"; import { Toaster } from "react-hot-toast"; import AdminSettingsPage from "./pages/adminPages/adminSettingsPage.js"; +import AdminEventPage from "./pages/adminPages/adminEventPage.js"; const root = ReactDOM.createRoot(document.getElementById("root")); @@ -48,6 +49,7 @@ const AdminRoutes = () => ( } /> + } /> } /> } /> ( } /> } /> } /> - } /> + } /> {/* } /> */} ); diff --git a/src/pages/adminPages/adminEventPage.js b/src/pages/adminPages/adminEventPage.js index 2c7dcdc7..c09f9c74 100644 --- a/src/pages/adminPages/adminEventPage.js +++ b/src/pages/adminPages/adminEventPage.js @@ -1,243 +1,97 @@ -// import Grid from "@mui/material/Grid"; -// import Paper from "@mui/material/Paper"; -// import Typography from "@mui/material/Typography"; -// import TextField from "@mui/material/TextField"; -// import Button from "@mui/material/Button"; -// import { Link, useNavigate } from "react-router-dom"; -// import MailOutlinedIcon from "@mui/icons-material/MailOutlined"; -// import InputAdornment from "@mui/material/InputAdornment"; -// import LockOutlinedIcon from "@mui/icons-material/LockOutlined"; -// import ArrowForwardIcon from "@mui/icons-material/ArrowForward"; -// import ArrowBackIcon from "@mui/icons-material/ArrowBack"; -// import PersonOutlineOutlinedIcon from "@mui/icons-material/PersonOutlineOutlined"; -// import MenuItem from "@mui/material/MenuItem"; -// import Select from "@mui/material/Select"; -// import TextareaAutosize from '@mui/material/TextareaAutosize'; -// import React, { useState } from 'react'; -// import RadioGroup from '@mui/material/RadioGroup'; -// import FormControlLabel from '@mui/material/FormControlLabel'; -// import Radio from '@mui/material/Radio'; -// import MonetizationOnIcon from '@mui/icons-material/MonetizationOn'; +import axios from "axios"; +import { useState, useEffect } from "react"; +import { Box, Card, CardMedia, Typography, ThemeProvider } from "@mui/material"; +import { useParams, Link } from "react-router-dom"; +import theme from "../../theme"; +import { BACKEND_URL } from "../../constant.js"; +import ArrowBackIcon from "@mui/icons-material/ArrowBack"; +export default function AdminEventPage() { + const [bookings, setBookings] = useState([]); + const [eventId, setEventId] = useState(); -// export default function AdminEventPage() { -// const [ticketPrice, setTicketPrice] = useState('free'); -// const [paidAmount, setPaidAmount] = useState(''); + const fetchBookingsForEvent = async () => { + try { + const response = await axios.get(`${BACKEND_URL}/bookings/${eventId}`); + const { bookings } = response.data; -// const handlePriceChange = (event) => { -// setTicketPrice(event.target.value); -// }; + setBookings(bookings); + } catch (error) { + console.error("Error fetching bookings:", error); + } + }; -// const handleAmountChange = (event) => { -// setPaidAmount(event.target.value); -// }; -// return ( -//
-// -// -// -// {/*
-// -// -// Events -// -//
*/} -// -// Event -// -//
-// {" "} -// { + if (eventId) { + fetchBookingsForEvent(); + } + }, [eventId]); -// />{" "} -//
-// 0 ? ( + + {bookings.map((booking) => ( + + User: {booking.user.email} + + Quantity Bought: {booking.quantity_bought} + + + ))} + + ) : ( + + + -// + No one has booked yet. + + + ); -// variant="outlined" -// type="time" -// fullWidth -// style={{ marginBottom: ".5rem" }} - -// /> -//
- -// -// {" "} -// -//
-// -// } label="Free" /> -// } label="Paid" /> -// -// {ticketPrice === 'paid' && ( -// -// -// -// ), -// }} -// /> -// )} -//
-//
-// -//
-// -// -// Already have an account?{" "} -// -// Sign in -// -// -// -//
-//
-//
-//
-// ); -// } + return ( + + + + + + + {bookingList} + + ); +} From bb9138644a7ae34e3ab954c96df18c0df2a4c2ce Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Mon, 15 Apr 2024 21:36:52 +0800 Subject: [PATCH 61/69] updated ui and fixed routing bug --- package-lock.json | 115 ++++++++++++++++++++++++++ package.json | 2 + src/components/BookingPreview.js | 101 +++++++++++++--------- src/index.js | 2 +- src/pages/userPages/freeReturnPage.js | 73 +++++++++++++++- 5 files changed, 253 insertions(+), 40 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1563b892..edfd6a11 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,8 +16,10 @@ "@reduxjs/toolkit": "^2.2.3", "@stripe/react-stripe-js": "^2.6.2", "@stripe/stripe-js": "^3.0.10", + "@syncfusion/ej2-react-barcode-generator": "^25.1.39", "@vis.gl/react-google-maps": "^0.8.3", "axios": "^1.6.8", + "qrcode.react": "^3.1.0", "react": "^18.1.0", "react-confetti-explosion": "^2.1.2", "react-dom": "^18.1.0", @@ -3732,6 +3734,57 @@ "url": "https://github.com/sponsors/gregberge" } }, + "node_modules/@syncfusion/ej2-barcode-generator": { + "version": "25.1.39", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-barcode-generator/-/ej2-barcode-generator-25.1.39.tgz", + "integrity": "sha512-UwOoEArL4o6q/ILsHVmV3FTH4jIt02MlvKL2WbCAsjp/QjWs+tZ/NtJlJResjrpDvMGN5rDsfp5DeBDGicGCpQ==", + "dependencies": { + "@syncfusion/ej2-base": "~25.1.35", + "@syncfusion/ej2-data": "~25.1.35" + } + }, + "node_modules/@syncfusion/ej2-base": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-base/-/ej2-base-25.1.35.tgz", + "integrity": "sha512-eH/zLft7j5jhbNquVNcKoDmlx+ZU/77mHAJwpG9Ad4+C/+7UcWlIi/RDORJ0QreosZM4gMyCYzxDAZ5QOI3txw==", + "dependencies": { + "@syncfusion/ej2-icons": "~25.1.35" + }, + "bin": { + "syncfusion-license": "bin/syncfusion-license.js" + } + }, + "node_modules/@syncfusion/ej2-data": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-data/-/ej2-data-25.1.35.tgz", + "integrity": "sha512-eHWkoQcokKFiLUMpcw2IM1ul9v8HeRgIrUzowyWPpamuZASX8luczDy3VLR5AX0YeiE9aNv3QKsr04t4F1GRcQ==", + "dependencies": { + "@syncfusion/ej2-base": "~25.1.35" + } + }, + "node_modules/@syncfusion/ej2-icons": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-icons/-/ej2-icons-25.1.35.tgz", + "integrity": "sha512-E8ypbeB9ISTsaj8Q29w3Ysh6HG35GOdTjfaU6JTCaZ9wP30q04B4WfN9lqcd42Q198qhynFAXd3lJyYev68aGw==" + }, + "node_modules/@syncfusion/ej2-react-barcode-generator": { + "version": "25.1.39", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-react-barcode-generator/-/ej2-react-barcode-generator-25.1.39.tgz", + "integrity": "sha512-aO32bvDq/E29yVesFjmmGqpas/ciUU0JAfQzPxvhK1g7+M7COtoTkXdgRcU0IqqF3HdxroEjYXsECaJ3bygi7A==", + "dependencies": { + "@syncfusion/ej2-barcode-generator": "25.1.39", + "@syncfusion/ej2-base": "~25.1.35", + "@syncfusion/ej2-react-base": "~25.1.35" + } + }, + "node_modules/@syncfusion/ej2-react-base": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-react-base/-/ej2-react-base-25.1.35.tgz", + "integrity": "sha512-chjK/THRwbRcQTKUL7NyP2VBjtS65uw6e0kieTsQvJ37c3ZZZ3/FpHt9jcqJisStrZ/xp4/y9uSPe6kqBGQBCg==", + "dependencies": { + "@syncfusion/ej2-base": "~25.1.35" + } + }, "node_modules/@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", @@ -13693,6 +13746,14 @@ "teleport": ">=0.2.0" } }, + "node_modules/qrcode.react": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-3.1.0.tgz", + "integrity": "sha512-oyF+Urr3oAMUG/OiOuONL3HXM+53wvuH3mtIWQrYmsXoAq0DkvZp2RYUWFSMFtbdOpuS++9v+WAkzNVkMlNW6Q==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/qs": { "version": "6.10.3", "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", @@ -19394,6 +19455,54 @@ "loader-utils": "^2.0.0" } }, + "@syncfusion/ej2-barcode-generator": { + "version": "25.1.39", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-barcode-generator/-/ej2-barcode-generator-25.1.39.tgz", + "integrity": "sha512-UwOoEArL4o6q/ILsHVmV3FTH4jIt02MlvKL2WbCAsjp/QjWs+tZ/NtJlJResjrpDvMGN5rDsfp5DeBDGicGCpQ==", + "requires": { + "@syncfusion/ej2-base": "~25.1.35", + "@syncfusion/ej2-data": "~25.1.35" + } + }, + "@syncfusion/ej2-base": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-base/-/ej2-base-25.1.35.tgz", + "integrity": "sha512-eH/zLft7j5jhbNquVNcKoDmlx+ZU/77mHAJwpG9Ad4+C/+7UcWlIi/RDORJ0QreosZM4gMyCYzxDAZ5QOI3txw==", + "requires": { + "@syncfusion/ej2-icons": "~25.1.35" + } + }, + "@syncfusion/ej2-data": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-data/-/ej2-data-25.1.35.tgz", + "integrity": "sha512-eHWkoQcokKFiLUMpcw2IM1ul9v8HeRgIrUzowyWPpamuZASX8luczDy3VLR5AX0YeiE9aNv3QKsr04t4F1GRcQ==", + "requires": { + "@syncfusion/ej2-base": "~25.1.35" + } + }, + "@syncfusion/ej2-icons": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-icons/-/ej2-icons-25.1.35.tgz", + "integrity": "sha512-E8ypbeB9ISTsaj8Q29w3Ysh6HG35GOdTjfaU6JTCaZ9wP30q04B4WfN9lqcd42Q198qhynFAXd3lJyYev68aGw==" + }, + "@syncfusion/ej2-react-barcode-generator": { + "version": "25.1.39", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-react-barcode-generator/-/ej2-react-barcode-generator-25.1.39.tgz", + "integrity": "sha512-aO32bvDq/E29yVesFjmmGqpas/ciUU0JAfQzPxvhK1g7+M7COtoTkXdgRcU0IqqF3HdxroEjYXsECaJ3bygi7A==", + "requires": { + "@syncfusion/ej2-barcode-generator": "25.1.39", + "@syncfusion/ej2-base": "~25.1.35", + "@syncfusion/ej2-react-base": "~25.1.35" + } + }, + "@syncfusion/ej2-react-base": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-react-base/-/ej2-react-base-25.1.35.tgz", + "integrity": "sha512-chjK/THRwbRcQTKUL7NyP2VBjtS65uw6e0kieTsQvJ37c3ZZZ3/FpHt9jcqJisStrZ/xp4/y9uSPe6kqBGQBCg==", + "requires": { + "@syncfusion/ej2-base": "~25.1.35" + } + }, "@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", @@ -26609,6 +26718,12 @@ "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" }, + "qrcode.react": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-3.1.0.tgz", + "integrity": "sha512-oyF+Urr3oAMUG/OiOuONL3HXM+53wvuH3mtIWQrYmsXoAq0DkvZp2RYUWFSMFtbdOpuS++9v+WAkzNVkMlNW6Q==", + "requires": {} + }, "qs": { "version": "6.10.3", "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", diff --git a/package.json b/package.json index 49f37853..9342e644 100644 --- a/package.json +++ b/package.json @@ -12,8 +12,10 @@ "@reduxjs/toolkit": "^2.2.3", "@stripe/react-stripe-js": "^2.6.2", "@stripe/stripe-js": "^3.0.10", + "@syncfusion/ej2-react-barcode-generator": "^25.1.39", "@vis.gl/react-google-maps": "^0.8.3", "axios": "^1.6.8", + "qrcode.react": "^3.1.0", "react": "^18.1.0", "react-confetti-explosion": "^2.1.2", "react-dom": "^18.1.0", diff --git a/src/components/BookingPreview.js b/src/components/BookingPreview.js index 9daeca21..5fbae547 100644 --- a/src/components/BookingPreview.js +++ b/src/components/BookingPreview.js @@ -1,7 +1,15 @@ //-----------Libraries-----------// import Card from "@mui/material/Card"; import CardContent from "@mui/material/CardContent"; -import Typography from "@mui/material/Typography"; +import { + Tabs, + ThemeProvider, + Tab, + Typography, + Box, + Button, + CardMedia, +} from "@mui/material"; import { Link } from "react-router-dom"; import { APIProvider, @@ -9,6 +17,12 @@ import { AdvancedMarker, Pin, } from "@vis.gl/react-google-maps"; +import { QRCodeCanvas } from "qrcode.react"; +import Accordion from "@mui/material/Accordion"; +import AccordionActions from "@mui/material/AccordionActions"; +import AccordionSummary from "@mui/material/AccordionSummary"; +import AccordionDetails from "@mui/material/AccordionDetails"; +import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; const BookingPreview = (props) => { const formatDate = (string) => { @@ -33,57 +47,68 @@ const BookingPreview = (props) => { }; return ( - - - - + + + - - - - - + + + + + - + {formatDate(props.data.event.start)}- {formatHour(props.data.event.end)} - - {props.data.event.title} - - - - BookingId :${props.data.id} - - - Quantity :{props.data.quantity_bought} - + {props.data.event.title} - + + {props.data.event.venue.address} + + + {/* BookingId :{props.data.id} */} + + Quantity :{props.data.quantity_bought} + + + {/* + } + aria-controls="panel1-content" + id="panel1-header" + > + Ticket + + + + + */} ); }; diff --git a/src/index.js b/src/index.js index c7ca5272..2ada4c32 100644 --- a/src/index.js +++ b/src/index.js @@ -128,7 +128,7 @@ const NonAdminRoutes = () => ( } /> } /> } /> - } /> + } /> {/* } /> */} ); diff --git a/src/pages/userPages/freeReturnPage.js b/src/pages/userPages/freeReturnPage.js index 5a268901..2e011e68 100644 --- a/src/pages/userPages/freeReturnPage.js +++ b/src/pages/userPages/freeReturnPage.js @@ -2,7 +2,14 @@ import React, { useState, useEffect } from "react"; import { Link, useLocation } from "react-router-dom"; import axios from "axios"; import ConfettiExplosion from "react-confetti-explosion"; -import { Box, Button, Typography, ThemeProvider } from "@mui/material"; +import { + Box, + Grid, + Button, + Card, + Typography, + ThemeProvider, +} from "@mui/material"; import { BACKEND_URL } from "../../constant.js"; import theme from "../../theme"; @@ -14,6 +21,28 @@ export default function FreeReturnPage() { const user_id = location.state.user_id; const quantity_bought = location.state.quantity; const [isExploding, setIsExploding] = useState(false); + const [event, setEvent] = useState(); + + const formatDate = (string) => { + const date = new Date(string); + const options = { + day: "numeric", + month: "long", + hour: "2-digit", + minute: "2-digit", + }; + return date.toLocaleDateString("en-US", options); + }; + + //add logic to see whether start and end date is the same. + const formatHour = (string) => { + const date = new Date(string); + const options = { + hour: "2-digit", + minute: "2-digit", + }; + return date.toLocaleTimeString("en-US", options); + }; const mediumProps = { force: 0.6, @@ -36,6 +65,18 @@ export default function FreeReturnPage() { .catch((error) => { console.error("Error inserting data", error); }); + }, [eventId, quantity_bought, user_id]); + + useEffect(() => { + axios + .get(`${BACKEND_URL}/events/${eventId}`) + + .then((response) => { + setEvent(response.data); + }) + .catch((error) => { + console.error("Error fetching data", error); + }); }, []); return ( @@ -59,6 +100,36 @@ export default function FreeReturnPage() { Your event reservation is complete + + + + + {event.title} + + + + + {new Date(event.start).toLocaleString("en-US", { + weekday: "long", + day: "numeric", + month: "long", + hour: "numeric", + minute: "numeric", + })} + - + {new Date(event.end).toLocaleString("en-US", { + hour: "numeric", + minute: "numeric", + })} + + + + + {isExploding && }
- - {props.data.status.name} - + + {props.data.status.name} + From af357ba0817a22174d9625599553a1d086f5c7e9 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Mon, 15 Apr 2024 23:40:51 +0800 Subject: [PATCH 64/69] updated return page to add event information --- src/pages/userPages/returnPage.js | 78 ++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) diff --git a/src/pages/userPages/returnPage.js b/src/pages/userPages/returnPage.js index 205fcf1d..2a4fd4d7 100644 --- a/src/pages/userPages/returnPage.js +++ b/src/pages/userPages/returnPage.js @@ -2,7 +2,14 @@ import { useState, useEffect } from "react"; import { loadStripe } from "@stripe/stripe-js"; import axios from "axios"; import { BrowserRouter as Router, Navigate, Link } from "react-router-dom"; -import { Box, Button, Typography, ThemeProvider } from "@mui/material"; +import { + Box, + Button, + Card, + Grid, + Typography, + ThemeProvider, +} from "@mui/material"; import ConfettiExplosion from "react-confetti-explosion"; import { BACKEND_URL } from "../../constant.js"; @@ -14,10 +21,32 @@ const stripePromise = loadStripe( export default function ReturnPage() { const [status, setStatus] = useState(null); + const [event, setEvent] = useState(); const [customerEmail, setCustomerEmail] = useState(""); const [loading, setLoading] = useState(true); const [isExploding, setIsExploding] = useState(false); + const formatDate = (string) => { + const date = new Date(string); + const options = { + day: "numeric", + month: "long", + hour: "2-digit", + minute: "2-digit", + }; + return date.toLocaleDateString("en-US", options); + }; + + //add logic to see whether start and end date is the same. + const formatHour = (string) => { + const date = new Date(string); + const options = { + hour: "2-digit", + minute: "2-digit", + }; + return date.toLocaleTimeString("en-US", options); + }; + const mediumProps = { force: 0.6, duration: 2500, @@ -43,6 +72,8 @@ export default function ReturnPage() { setCustomerEmail(response.data.customer_email); setLoading(false); setIsExploding("true"); + + const eventResponse = await axios.get(); } catch (error) { console.error("Error fetching client secret:", error); setLoading(false); @@ -56,6 +87,21 @@ export default function ReturnPage() { console.log("Status updated:", status); }, [status]); + useEffect(() => { + const queryString = window.location.search; + const urlParams = new URLSearchParams(queryString); + const eventId = urlParams.get("eventId"); + axios + .get(`${BACKEND_URL}/events/${eventId}`) + + .then((response) => { + setEvent(response.data); + }) + .catch((error) => { + console.error("Error fetching data", error); + }); + }, []); + if (loading) { return

Loading...

; } @@ -81,6 +127,36 @@ export default function ReturnPage() { Your event reservation is complete + + + + + {event.title} + + + + + {new Date(event.start).toLocaleString("en-US", { + weekday: "long", + day: "numeric", + month: "long", + hour: "numeric", + minute: "numeric", + })} + - + {new Date(event.end).toLocaleString("en-US", { + hour: "numeric", + minute: "numeric", + })} + + + + + {isExploding && } -// - -// {/* Video upload button */} -// -// -//
-//
-// -// -//
-// -// -// -// -// -// ); -// } diff --git a/src/pages/adminPages/adminAnalyticsPage.js b/src/pages/adminPages/adminAnalyticsPage.js deleted file mode 100644 index f44524c5..00000000 --- a/src/pages/adminPages/adminAnalyticsPage.js +++ /dev/null @@ -1,8 +0,0 @@ -//-----------Libraries-----------// -import { useState, useEffect } from "react"; - -//-----------Components-----------// - -export default function AdminAnalyticsPage() { - return
Admin Analytics page
; -} diff --git a/src/pages/adminPages/adminCreateEvent.js b/src/pages/adminPages/adminCreateEvent.js index 0e1a0133..433ce065 100644 --- a/src/pages/adminPages/adminCreateEvent.js +++ b/src/pages/adminPages/adminCreateEvent.js @@ -11,7 +11,6 @@ import { InputAdornment, InputLabel, OutlinedInput, - Paper, Typography, TextField, Button, @@ -27,7 +26,6 @@ import { BACKEND_URL } from "../../constant.js"; export default function AdminCreateEvent() { const [title, setTitle] = useState(""); const [description, setDescription] = useState(""); - const [venueId, setVenueId] = useState(""); const [adminId, setAdminId] = useState(""); const [price, setPrice] = useState(""); const [start, setStart] = useState(""); @@ -45,19 +43,13 @@ export default function AdminCreateEvent() { const [errorMessage, setErrorMessage] = useState(false); const [file, setFile] = useState(null); const [previewUrl, setPreviewUrl] = useState(null); - const { - isAuthenticated, - loginWithRedirect, - logout, - isLoading, - getAccessTokenSilently, - user, - } = useAuth0(); + const { isAuthenticated, isLoading, getAccessTokenSilently, user } = + useAuth0(); const [accessToken, setAccessToken] = useState(); const navigate = useNavigate(); useEffect(() => { - const fetchData = async () => { + const fetchCategories = async () => { try { const [categoriesResponse, languagesResponse, statusesResponse] = await Promise.all([ @@ -73,9 +65,46 @@ export default function AdminCreateEvent() { console.error("Error fetching data:", error); } }; - fetchData(); + fetchCategories(); }, []); + const checkUser = async () => { + if (isAuthenticated) { + try { + let token = await getAccessTokenSilently(); + setAccessToken(token); + if (user && user.email) { + const response = await axios.post( + `${BACKEND_URL}/admins/`, + { + email: user.email, + name: "CC", + }, + { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + } + ); + const output = response.data; + setAdminId(output[0].id); + } + } catch (error) { + console.error("Error fetching data:", error); + } + } + }; + + useEffect(() => { + checkUser(); + }, [isAuthenticated]); + + useEffect(() => { + if (!isAuthenticated && !isLoading) { + navigate("/admin"); + } + }, [isAuthenticated, isLoading, navigate]); + useEffect(() => { if (!file) { return; @@ -92,41 +121,6 @@ export default function AdminCreateEvent() { }); }; - const fetchData = async () => { - try { - if (user && user.email) { - const response = await axios.post(`${BACKEND_URL}/admins/`, { - email: user.email, - name: "CC", - }); - - const output = response.data; - - setAdminId(output[0].id); - } - } catch (error) { - console.error("Error fetching data:", error); - } - }; - - const checkUser = async () => { - if (isAuthenticated) { - let token = await getAccessTokenSilently(); - setAccessToken(token); - fetchData(); - } - }; - - useEffect(() => { - checkUser(); - }, []); - - useEffect(() => { - if (!isAuthenticated && !isLoading) { - navigate("/admin"); - } - }, [isAuthenticated, isLoading, navigate]); - const handleSubmit = async (event) => { event.preventDefault(); @@ -145,40 +139,57 @@ export default function AdminCreateEvent() { !marker ) { setErrorMessage(true); - return; // Prevent form submission + return; } + //get venueId based on lat and lng google maps marker try { - const venueResponse = await axios.post(`${BACKEND_URL}/venues`, { - lat: marker.lat, - lng: marker.lng, - postal_code: postalCode, - address: address, - country: "Singapore", - }); + const venueResponse = await axios.post( + `${BACKEND_URL}/venues`, + { + lat: marker.lat, + lng: marker.lng, + postal_code: postalCode, + address: address, + country: "Singapore", + }, + { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + } + ); const venueId = venueResponse.data.id; - await axios.post(`${BACKEND_URL}/events`, { - title: title, - description: description, - languageId: selectedLanguageId, - categoryId: selectedCategoryId, - venueId: venueId, - adminId: adminId, - price: price, - start: start, - end: end, - statusId: selectedStatusId, - capacity: capacity, - image_link: previewUrl, - }); + //create event in database + await axios.post( + `${BACKEND_URL}/events`, + { + title: title, + description: description, + languageId: selectedLanguageId, + categoryId: selectedCategoryId, + venueId: venueId, + adminId: adminId, + price: price, + start: start, + end: end, + statusId: selectedStatusId, + capacity: capacity, + image_link: previewUrl, + }, + { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + } + ); setTitle(""); setDescription(""); setSelectedLanguageId(""); setSelectedCategoryId(""); - setVenueId(""); setAdminId(""); setPrice(""); setStart(""); @@ -195,8 +206,6 @@ export default function AdminCreateEvent() { } }; - console.log(previewUrl); - return ( Event attendance page; -} diff --git a/src/pages/adminPages/adminEventPage.js b/src/pages/adminPages/adminEventPage.js index 9f66cdfe..4cee4a4d 100644 --- a/src/pages/adminPages/adminEventPage.js +++ b/src/pages/adminPages/adminEventPage.js @@ -1,67 +1,81 @@ +//-----------Libraries-----------// import axios from "axios"; import { useState, useEffect } from "react"; import { Box, Card, CardMedia, Typography, ThemeProvider } from "@mui/material"; -import { useParams, Link } from "react-router-dom"; -import theme from "../../theme"; -import { BACKEND_URL } from "../../constant.js"; +import { useParams, Link, useNavigate } from "react-router-dom"; import ArrowBackIcon from "@mui/icons-material/ArrowBack"; +import { useAuth0 } from "@auth0/auth0-react"; + +import { BACKEND_URL } from "../../constant.js"; +import theme from "../../theme"; export default function AdminEventPage() { const [bookings, setBookings] = useState([]); const [eventId, setEventId] = useState(); const [capacity, setCapacity] = useState(); const [event, setEvent] = useState(); - - const fetchBookingsForEvent = async () => { - try { - const response = await axios.get(`${BACKEND_URL}/bookings/${eventId}`); - const { bookings } = response.data; - - setBookings(bookings); - } catch (error) { - console.error("Error fetching bookings:", error); - } - }; + const [accessToken, setAccessToken] = useState(); + const { isAuthenticated, isLoading, getAccessTokenSilently } = useAuth0(); + const navigate = useNavigate(); const params = useParams(); if (eventId !== params.eventId) { setEventId(params.eventId); } - useEffect(() => { - if (eventId) { - fetchBookingsForEvent(); - } - }, [eventId]); - - useEffect(() => { - const fetchData = async () => { + const checkUser = async () => { + if (isAuthenticated) { try { - const response = await axios.get( - `${BACKEND_URL}/bookings/capacity/${eventId}` - ); - - setCapacity(response.data.availableCapacity); + let token = await getAccessTokenSilently(); + setAccessToken(token); } catch (error) { console.error("Error fetching data:", error); } - }; + } + }; - fetchData(); - }, [eventId]); + useEffect(() => { + checkUser(); + }, [isAuthenticated]); + + useEffect(() => { + if (!isAuthenticated && !isLoading) { + navigate("/admin"); + } + }, [isAuthenticated, isLoading, navigate]); useEffect(() => { const fetchData = async () => { try { - const response = await axios.get(`${BACKEND_URL}/events/${eventId}`); + const eventResponse = await axios.get( + `${BACKEND_URL}/events/${eventId}` + ); + setEvent(eventResponse.data); + + // Fetch available capacity + const capacityResponse = await axios.get( + `${BACKEND_URL}/bookings/capacity/${eventId}` + ); + setCapacity(capacityResponse.data.availableCapacity); - setEvent(response.data); + // Fetch all bookings for the event + const bookingsResponse = await axios.get( + `${BACKEND_URL}/bookings/${eventId}`, + { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + } + ); + setBookings(bookingsResponse.data.bookings); } catch (error) { console.error("Error fetching data:", error); } }; - fetchData(); + if (eventId) { + fetchData(); + } }, [eventId]); const bookingList = diff --git a/src/pages/adminPages/adminHomePage.js b/src/pages/adminPages/adminHomePage.js index a5e966ae..80eae613 100644 --- a/src/pages/adminPages/adminHomePage.js +++ b/src/pages/adminPages/adminHomePage.js @@ -1,6 +1,6 @@ //-----------Libraries-----------// import { Typography, ThemeProvider } from "@mui/material"; -import { Link, useNavigate } from "react-router-dom"; +import { useNavigate } from "react-router-dom"; import { useAuth0 } from "@auth0/auth0-react"; import axios from "axios"; import { useEffect, useState } from "react"; @@ -11,28 +11,18 @@ import theme from "../../theme"; import { BACKEND_URL } from "../../constant.js"; export default function AdminHomePage() { - const { - isAuthenticated, - loginWithRedirect, - logout, - isLoading, - getAccessTokenSilently, - user, - } = useAuth0(); - const domain = process.env.REACT_APP_AUTH0_DOMAIN; + const { isAuthenticated, isLoading, getAccessTokenSilently, user } = + useAuth0(); const navigate = useNavigate(); const [accessToken, setAccessToken] = useState(); const [adminId, setAdminId] = useState(); - const handleLogin = () => { - navigate("/admin/home"); - }; - useEffect(() => { const fetchAdminId = async () => { try { if (user && user.email) { const token = await getAccessTokenSilently(); + setAccessToken(token); const response = await axios.post( `${BACKEND_URL}/admins/`, { @@ -44,9 +34,7 @@ export default function AdminHomePage() { }, } ); - console.log("success"); const output = response.data; - console.log(output); setAdminId(output[0].id); } else { console.log("User email is undefined."); @@ -61,9 +49,6 @@ export default function AdminHomePage() { } }, [getAccessTokenSilently, isAuthenticated, user]); - console.log(isAuthenticated); - console.log(adminId); - useEffect(() => { if (!isAuthenticated && !isLoading) { navigate("/admin"); @@ -85,7 +70,9 @@ export default function AdminHomePage() { > Your Events - {adminId && } + {adminId && ( + + )} ); diff --git a/src/pages/adminPages/adminIntroPage.js b/src/pages/adminPages/adminIntroPage.js index 98f8106d..a8e8de64 100644 --- a/src/pages/adminPages/adminIntroPage.js +++ b/src/pages/adminPages/adminIntroPage.js @@ -1,7 +1,6 @@ //-----------Libraries-----------// import { Box, Button, Typography, ThemeProvider } from "@mui/material"; -import { useEffect, useState } from "react"; -import { Link, useNavigate } from "react-router-dom"; +import { useNavigate } from "react-router-dom"; import { useAuth0 } from "@auth0/auth0-react"; //-----------Components-----------// diff --git a/src/pages/adminPages/adminProfilePage.js b/src/pages/adminPages/adminProfilePage.js index ccee8eb3..5fdf1470 100644 --- a/src/pages/adminPages/adminProfilePage.js +++ b/src/pages/adminPages/adminProfilePage.js @@ -10,13 +10,12 @@ import { ListItemText, } from "@mui/material"; import { - CalendarToday as CalendarTodayIcon, ContactSupport as ContactSupportIcon, ExitToApp as ExitToAppIcon, } from "@mui/icons-material"; import { useAuth0 } from "@auth0/auth0-react"; import axios from "axios"; -import { Link, useNavigate } from "react-router-dom"; +import { useNavigate } from "react-router-dom"; //-----------Components-----------// import { BACKEND_URL } from "../../constant.js"; @@ -31,7 +30,6 @@ const AdminProfilePage = () => { getAccessTokenSilently, user, } = useAuth0(); - const domain = process.env.REACT_APP_AUTH0_DOMAIN; const navigate = useNavigate(); const [accessToken, setAccessToken] = useState(); const [adminDb, setAdminDb] = useState(); @@ -39,9 +37,17 @@ const AdminProfilePage = () => { const fetchData = async () => { try { if (user && user.email) { - const response = await axios.post(`${BACKEND_URL}/admins/`, { - email: user.email, - }); + const response = await axios.post( + `${BACKEND_URL}/admins/`, + { + email: user.email, + }, + { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + } + ); const output = response.data; setAdminDb(output[0]); } else { diff --git a/src/pages/adminPages/adminSettingsPage.js b/src/pages/adminPages/adminSettingsPage.js index 3f84d597..fdb92924 100644 --- a/src/pages/adminPages/adminSettingsPage.js +++ b/src/pages/adminPages/adminSettingsPage.js @@ -1,15 +1,8 @@ //-----------Libraries-----------// import { useState, useEffect } from "react"; -import { useParams, Link, useNavigate } from "react-router-dom"; +import { useNavigate } from "react-router-dom"; import axios from "axios"; -import { - Button, - Dialog, - Box, - TextField, - Typography, - Grid, -} from "@mui/material"; +import { Button, Box, TextField, Grid } from "@mui/material"; import { ThemeProvider } from "@mui/material"; import { useAuth0 } from "@auth0/auth0-react"; @@ -19,14 +12,8 @@ import theme from "../../theme.js"; export default function AdminSettingsPage() { const [admin, setAdmin] = useState(); - const { - user, - loginWithRedirect, - isLoading, - isAuthenticated, - getAccessTokenSilently, - } = useAuth0(); - const [accessToken, setAccessToken] = useState(); + const { user, isLoading, isAuthenticated, getAccessTokenSilently } = + useAuth0(); const [editName, setEditName] = useState(""); const navigate = useNavigate(); @@ -47,7 +34,6 @@ export default function AdminSettingsPage() { }, } ); - console.log("success"); const output = response.data; setAdmin(output[0]); if (output && output[0].name) { @@ -87,7 +73,6 @@ export default function AdminSettingsPage() { }, } ); - console.log("Update success"); setAdmin({ ...admin, name: editName }); navigate("../profile", { replace: true }); } catch (error) { diff --git a/src/pages/errorPage.js b/src/pages/errorPage.js deleted file mode 100644 index ec439ff7..00000000 --- a/src/pages/errorPage.js +++ /dev/null @@ -1,40 +0,0 @@ -//-----------Libraries-----------// -import { Box, Button, Typography, ThemeProvider } from "@mui/material"; -import { Link } from "react-router-dom"; - -//-----------Components-----------// -import theme from "../theme"; - -export default function ErrorPage() { - return ( - - - - Error - - - - - ); -} From c579b3a0f7d1e205bf4b3ba9783c7c03f8948c86 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Tue, 16 Apr 2024 23:59:31 +0800 Subject: [PATCH 67/69] updated users tokens --- src/pages/userPages/eventBookingPage.js | 24 +++++++------ src/pages/userPages/eventDetailPage.js | 15 ++------ src/pages/userPages/freeReturnPage.js | 39 ++++++++++++++++---- src/pages/userPages/myBookingPage.js | 32 +++++++++++------ src/pages/userPages/myProfilePage.js | 47 ++----------------------- src/pages/userPages/returnPage.js | 32 +++++++++++++---- 6 files changed, 100 insertions(+), 89 deletions(-) diff --git a/src/pages/userPages/eventBookingPage.js b/src/pages/userPages/eventBookingPage.js index 2eb456d7..411a908e 100644 --- a/src/pages/userPages/eventBookingPage.js +++ b/src/pages/userPages/eventBookingPage.js @@ -15,14 +15,8 @@ export default function EventBookingPage({ eventId, isFree }) { const [event, setEvent] = useState(); const [userDb, setUserDb] = useState(); const [accessToken, setAccessToken] = useState(); - const { - isAuthenticated, - loginWithRedirect, - logout, - isLoading, - getAccessTokenSilently, - user, - } = useAuth0(); + const { isAuthenticated, loginWithRedirect, getAccessTokenSilently, user } = + useAuth0(); useEffect(() => { const fetchData = async () => { @@ -56,9 +50,17 @@ export default function EventBookingPage({ eventId, isFree }) { const fetchData = async () => { try { if (user && user.email) { - const response = await axios.post(`${BACKEND_URL}/users/`, { - email: user.email, - }); + const response = await axios.post( + `${BACKEND_URL}/users/`, + { + email: user.email, + }, + { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + } + ); const output = response.data; setUserDb(output); } else { diff --git a/src/pages/userPages/eventDetailPage.js b/src/pages/userPages/eventDetailPage.js index fe5e0eed..b193e1b0 100644 --- a/src/pages/userPages/eventDetailPage.js +++ b/src/pages/userPages/eventDetailPage.js @@ -28,20 +28,11 @@ export default function EventDetailPage() { const [eventId, setEventId] = useState(); const [showRegistration, setShowRegistraton] = useState(null); const [isFree, setIsFree] = useState(null); - const { user, loginWithRedirect, isAuthenticated, getAccessTokenSilently } = - useAuth0(); - const [accessToken, setAccessToken] = useState(); + const { loginWithRedirect, isAuthenticated } = useAuth0(); + const fetchData = async () => { - if (isAuthenticated) { - let token = await getAccessTokenSilently(); - setAccessToken(token); - } try { - const response = await axios.get(`${BACKEND_URL}/events/${eventId}`, { - headers: { - authorization: `Bearer ${accessToken}`, - }, - }); + const response = await axios.get(`${BACKEND_URL}/events/${eventId}`); setEvent(response.data); setIsFree(response.data.price === 0); } catch (error) { diff --git a/src/pages/userPages/freeReturnPage.js b/src/pages/userPages/freeReturnPage.js index 2e011e68..93ca84cb 100644 --- a/src/pages/userPages/freeReturnPage.js +++ b/src/pages/userPages/freeReturnPage.js @@ -1,3 +1,4 @@ +//-----------Libraries-----------// import React, { useState, useEffect } from "react"; import { Link, useLocation } from "react-router-dom"; import axios from "axios"; @@ -10,7 +11,9 @@ import { Typography, ThemeProvider, } from "@mui/material"; +import { useAuth0 } from "@auth0/auth0-react"; +//-----------Components-----------// import { BACKEND_URL } from "../../constant.js"; import theme from "../../theme"; @@ -22,6 +25,8 @@ export default function FreeReturnPage() { const quantity_bought = location.state.quantity; const [isExploding, setIsExploding] = useState(false); const [event, setEvent] = useState(); + const { isAuthenticated, getAccessTokenSilently } = useAuth0(); + const [accessToken, setAccessToken] = useState(); const formatDate = (string) => { const date = new Date(string); @@ -34,7 +39,6 @@ export default function FreeReturnPage() { return date.toLocaleDateString("en-US", options); }; - //add logic to see whether start and end date is the same. const formatHour = (string) => { const date = new Date(string); const options = { @@ -51,13 +55,36 @@ export default function FreeReturnPage() { width: 1600, }; + const checkUser = async () => { + if (isAuthenticated) { + try { + let token = await getAccessTokenSilently(); + setAccessToken(token); + } catch (error) { + console.error("Error fetching data:", error); + } + } + }; + + useEffect(() => { + checkUser(); + }, [isAuthenticated]); + useEffect(() => { axios - .post(`${BACKEND_URL}/bookings/${eventId}`, { - eventId: eventId, - quantity_bought: quantity_bought, - user_id: user_id, - }) + .post( + `${BACKEND_URL}/bookings/${eventId}`, + { + eventId: eventId, + quantity_bought: quantity_bought, + user_id: user_id, + }, + { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + } + ) .then((response) => { setStatus("complete"); setIsExploding("true"); diff --git a/src/pages/userPages/myBookingPage.js b/src/pages/userPages/myBookingPage.js index 08c598f7..f0c3ec88 100644 --- a/src/pages/userPages/myBookingPage.js +++ b/src/pages/userPages/myBookingPage.js @@ -1,6 +1,5 @@ //-----------Libraries-----------// import { useState, useEffect } from "react"; -import { useNavigate } from "react-router-dom"; import { useAuth0 } from "@auth0/auth0-react"; import axios from "axios"; import PropTypes from "prop-types"; @@ -51,13 +50,10 @@ export default function MyBookingPage() { const { isAuthenticated, loginWithRedirect, - logout, isLoading, getAccessTokenSilently, user, } = useAuth0(); - const domain = process.env.REACT_APP_AUTH0_DOMAIN; - const navigate = useNavigate(); const [accessToken, setAccessToken] = useState(); const fetchData = async () => { @@ -113,9 +109,17 @@ export default function MyBookingPage() { if (userDb && userDb.length > 0) { const fetchData = async () => { try { - const response = await axios.get(`${BACKEND_URL}/bookings/current`, { - params: { userId: userDb[0].id }, - }); + const response = await axios.get( + `${BACKEND_URL}/bookings/current`, + { + params: { userId: userDb[0].id }, + }, + { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + } + ); const output = response.data; setCurrent(output); } catch (error) { @@ -130,9 +134,17 @@ export default function MyBookingPage() { if (userDb && userDb.length > 0) { const fetchData = async () => { try { - const response = await axios.get(`${BACKEND_URL}/bookings/past`, { - params: { userId: userDb[0].id }, - }); + const response = await axios.get( + `${BACKEND_URL}/bookings/past`, + { + params: { userId: userDb[0].id }, + }, + { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + } + ); const output = response.data; setPast(output); } catch (error) { diff --git a/src/pages/userPages/myProfilePage.js b/src/pages/userPages/myProfilePage.js index 434286d8..9cc6824c 100644 --- a/src/pages/userPages/myProfilePage.js +++ b/src/pages/userPages/myProfilePage.js @@ -1,5 +1,4 @@ //-----------Libraries-----------// -import { useEffect, useState } from "react"; import { Avatar, ThemeProvider, @@ -10,59 +9,19 @@ import { ListItemText, } from "@mui/material"; import { - CalendarToday as CalendarTodayIcon, ContactSupport as ContactSupportIcon, ExitToApp as ExitToAppIcon, } from "@mui/icons-material"; import { useAuth0 } from "@auth0/auth0-react"; -import axios from "axios"; -import { Link, useNavigate } from "react-router-dom"; +import { useNavigate } from "react-router-dom"; //-----------Components-----------// -import { BACKEND_URL } from "../../constant.js"; import theme from "../../theme"; const MyProfilePage = () => { - const { - isAuthenticated, - loginWithRedirect, - logout, - isLoading, - getAccessTokenSilently, - user, - } = useAuth0(); - const domain = process.env.REACT_APP_AUTH0_DOMAIN; + const { isAuthenticated, loginWithRedirect, logout, isLoading, user } = + useAuth0(); const navigate = useNavigate(); - const [accessToken, setAccessToken] = useState(); - const [userDb, setUserDb] = useState(); - - const fetchData = async () => { - try { - if (user && user.email) { - const response = await axios.post(`${BACKEND_URL}/users/`, { - email: user.email, - }); - const output = response.data; - setUserDb(output); - } else { - console.log("User email is undefined."); - } - } catch (error) { - console.error("Error fetching data:", error); - } - }; - - const checkUser = async () => { - if (isAuthenticated) { - let token = await getAccessTokenSilently(); - setAccessToken(token); - fetchData(); - } - }; - - useEffect(() => { - checkUser(); - }, []); const handleContactUsClick = () => { navigate("/contactus"); diff --git a/src/pages/userPages/returnPage.js b/src/pages/userPages/returnPage.js index 2a4fd4d7..71e523ca 100644 --- a/src/pages/userPages/returnPage.js +++ b/src/pages/userPages/returnPage.js @@ -1,3 +1,4 @@ +//-----------Libraries-----------// import { useState, useEffect } from "react"; import { loadStripe } from "@stripe/stripe-js"; import axios from "axios"; @@ -11,7 +12,9 @@ import { ThemeProvider, } from "@mui/material"; import ConfettiExplosion from "react-confetti-explosion"; +import { useAuth0 } from "@auth0/auth0-react"; +//-----------Components-----------// import { BACKEND_URL } from "../../constant.js"; import theme from "../../theme"; @@ -22,9 +25,10 @@ const stripePromise = loadStripe( export default function ReturnPage() { const [status, setStatus] = useState(null); const [event, setEvent] = useState(); - const [customerEmail, setCustomerEmail] = useState(""); const [loading, setLoading] = useState(true); const [isExploding, setIsExploding] = useState(false); + const { isAuthenticated, getAccessTokenSilently } = useAuth0(); + const [accessToken, setAccessToken] = useState(); const formatDate = (string) => { const date = new Date(string); @@ -37,7 +41,6 @@ export default function ReturnPage() { return date.toLocaleDateString("en-US", options); }; - //add logic to see whether start and end date is the same. const formatHour = (string) => { const date = new Date(string); const options = { @@ -54,6 +57,21 @@ export default function ReturnPage() { width: 1600, }; + const checkUser = async () => { + if (isAuthenticated) { + try { + let token = await getAccessTokenSilently(); + setAccessToken(token); + } catch (error) { + console.error("Error fetching data:", error); + } + } + }; + + useEffect(() => { + checkUser(); + }, [isAuthenticated]); + useEffect(() => { const fetchData = async () => { try { @@ -65,15 +83,17 @@ export default function ReturnPage() { const user = urlParams.get("user"); const response = await axios.get( - `http://localhost:3000/bookings/session-status?session_id=${sessionId}&eventId=${eventId}&quantity=${quantity}&user=${user}` + `http://localhost:3000/bookings/session-status?session_id=${sessionId}&eventId=${eventId}&quantity=${quantity}&user=${user}`, + { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + } ); setStatus(response.data.status); - setCustomerEmail(response.data.customer_email); setLoading(false); setIsExploding("true"); - - const eventResponse = await axios.get(); } catch (error) { console.error("Error fetching client secret:", error); setLoading(false); From 205a4cdd4f8db7881fd108a8386b059ab420a860 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Sat, 20 Apr 2024 00:36:31 +0800 Subject: [PATCH 68/69] updated --- README.md | 16 ++++++++++++---- src/components/AdminEventPreview.js | 10 +--------- src/components/AdminNavBar.js | 1 - src/components/searchBar.js | 2 -- src/constant.js | 2 +- 5 files changed, 14 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 85445030..086368f1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Rocket Academy Coding Bootcamp: Project 3 Frontend -## Event Link +# Event Link Event Link is a mobile-oriented platform designed to facilitate event management for both users and administrators. With its intuitive user interface and robust administrative tools, Event Link simplifies the process of organizing and participating in events. @@ -21,11 +21,19 @@ User Insights: Administrators can view the email addresses of users who have boo Usage To utilize Event Link, simply access the platform from your mobile device's browser. Users can start exploring events immediately, while administrators can log in to access the administrative dashboard. +## ERD + +https://drawsql.app/teams/l-67/diagrams/event + +## UI Wireframes + +https://www.figma.com/file/HHel7Q8qyt8eSzQyMVlJDj/Kendi-x-Lili-Project?type=design&node-id=1%3A2&mode=design&t=e8HLvaPKKFWyRDky-1 + ## Technologies Used -Frontend: MUI -Backend: Node.js, Express.js, Nodemailer, -Database: Sequelize +Frontend: MUI (Material-UI) +Backend: Node.js, Express.js, Nodemailer +Database: Sequelize (ORM for PostgreSQL) Payment Processing: Stripe API Mapping: Google Maps API diff --git a/src/components/AdminEventPreview.js b/src/components/AdminEventPreview.js index 12ffd598..69d24e64 100644 --- a/src/components/AdminEventPreview.js +++ b/src/components/AdminEventPreview.js @@ -1,12 +1,6 @@ //-----------Libraries-----------// import React, { useState } from "react"; -import { - Card, - CardContent, - CardMedia, - Button, - Typography, -} from "@mui/material"; +import { Card, CardContent, CardMedia, Typography } from "@mui/material"; import { Link } from "react-router-dom"; const EventPreview = (props) => { @@ -33,8 +27,6 @@ const EventPreview = (props) => { const priceText = props.data.price === 0 ? "Free" : `$${props.data.price}`; - console.log(props); - return ( diff --git a/src/components/AdminNavBar.js b/src/components/AdminNavBar.js index ca1ab83d..91afe2d2 100644 --- a/src/components/AdminNavBar.js +++ b/src/components/AdminNavBar.js @@ -3,7 +3,6 @@ import AppBar from "@mui/material/AppBar"; import Toolbar from "@mui/material/Toolbar"; import { Link } from "react-router-dom"; import ExploreIcon from "@mui/icons-material/Explore"; -import EventIcon from "@mui/icons-material/Event"; import PersonIcon from "@mui/icons-material/Person"; import { ThemeProvider, styled } from "@mui/material/styles"; import AddCircleOutlineIcon from "@mui/icons-material/AddCircleOutline"; diff --git a/src/components/searchBar.js b/src/components/searchBar.js index d2091dc9..795fd97f 100644 --- a/src/components/searchBar.js +++ b/src/components/searchBar.js @@ -123,9 +123,7 @@ export default function SearchBar() { X - - {categoriesList} diff --git a/src/constant.js b/src/constant.js index 3c6be070..1cc46964 100644 --- a/src/constant.js +++ b/src/constant.js @@ -1 +1 @@ -export const BACKEND_URL = "http://localhost:5000"; +export const BACKEND_URL = "http://localhost:3000"; From eb64c7c6883d6a2115a7959330d86dce630f1ba3 Mon Sep 17 00:00:00 2001 From: Lili00ani Date: Sat, 20 Apr 2024 10:27:56 +0800 Subject: [PATCH 69/69] added frontend url --- src/constant.js | 3 ++- src/pages/userPages/returnPage.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/constant.js b/src/constant.js index 1cc46964..ff20f1d0 100644 --- a/src/constant.js +++ b/src/constant.js @@ -1 +1,2 @@ -export const BACKEND_URL = "http://localhost:3000"; +export const BACKEND_URL = "http://localhost:5000"; +export const FRONTEND_URL = "http://localhost:3000"; diff --git a/src/pages/userPages/returnPage.js b/src/pages/userPages/returnPage.js index 71e523ca..c68d3cb8 100644 --- a/src/pages/userPages/returnPage.js +++ b/src/pages/userPages/returnPage.js @@ -16,6 +16,7 @@ import { useAuth0 } from "@auth0/auth0-react"; //-----------Components-----------// import { BACKEND_URL } from "../../constant.js"; +import { FRONTEND_URL } from "../../constant.js"; import theme from "../../theme"; const stripePromise = loadStripe( @@ -83,7 +84,7 @@ export default function ReturnPage() { const user = urlParams.get("user"); const response = await axios.get( - `http://localhost:3000/bookings/session-status?session_id=${sessionId}&eventId=${eventId}&quantity=${quantity}&user=${user}`, + `${FRONTEND_URL}/bookings/session-status?session_id=${sessionId}&eventId=${eventId}&quantity=${quantity}&user=${user}`, { headers: { Authorization: `Bearer ${accessToken}`,