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/README.md b/README.md index f43f4285..086368f1 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,42 @@ # Rocket Academy Coding Bootcamp: Project 3 Frontend +# 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. + +# Features + +## User Side + +View and Search: Users can browse through a variety of events using keywords and filters based on categories. This feature is accessible even before logging in, allowing users to discover events effortlessly. +Interactive Maps: Integrated maps provide users with the location of event venues, helping them plan their attendance efficiently. +Booking Management: Users can make bookings for both free and paid events. Paid events utilize Stripe for secure transactions. Upon successful payment, users receive email notifications confirming their booking. +Booking History: Users have access to their booking history, allowing them to keep track of past and upcoming events they've registered for. + +## Admin Side + +Event Creation: Administrators have the capability to create new events, providing details such as event name, date, location, and ticket availability. +Booking Tracking: Admins can monitor who has booked their events and track the number of available slots in real-time. This feature helps ensure efficient management of event capacity. +User Insights: Administrators can view the email addresses of users who have booked their events, along with the number of tickets purchased by each user. +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 (Material-UI) +Backend: Node.js, Express.js, Nodemailer +Database: Sequelize (ORM for PostgreSQL) +Payment Processing: Stripe API +Mapping: Google Maps API + ## Available Scripts This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). In the project directory, you can run: diff --git a/package-lock.json b/package-lock.json index 35392e08..edfd6a11 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,9 +8,26 @@ "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", + "@mui/material": "^5.15.14", + "@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", - "react-scripts": "5.0.1" + "react-hot-toast": "^2.4.1", + "react-redux": "^9.1.0", + "react-router-dom": "^6.22.3", + "react-scripts": "5.0.1", + "redux": "^5.0.1" } }, "node_modules/@ampproject/remapping": { @@ -25,6 +42,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", @@ -1764,11 +1798,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 +1820,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 +2036,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 +2248,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 +3010,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 +3346,55 @@ } } }, + "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/@reduxjs/toolkit": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.2.3.tgz", + "integrity": "sha512-76dll9EnJXg4EVcI5YNxZA/9hSAmZsFqzMmNRHvIlzw2WS/twfcVX3ysYrWGJMClwEmChQFC4yRq74tn6fdzRA==", + "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", + "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", @@ -2966,6 +3495,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", @@ -3184,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", @@ -3315,6 +3916,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", @@ -3387,6 +3993,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 +4013,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 +4044,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", @@ -3450,6 +4084,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", @@ -3685,6 +4324,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", @@ -4214,16 +4866,39 @@ "engines": { "node": "^10 || ^12 || >=14" }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/axe-core": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.1.tgz", - "integrity": "sha512-gd1kmb21kwNuWr6BQz8fv6GNECPBnUasepcoLbekws23NVBLODdsClRZ+bQ8+9Uomf3Sm3+Vwn0oYG9NvwnJCw==", + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/axe-core": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.1.tgz", + "integrity": "sha512-gd1kmb21kwNuWr6BQz8fv6GNECPBnUasepcoLbekws23NVBLODdsClRZ+bQ8+9Uomf3Sm3+Vwn0oYG9NvwnJCw==", + "engines": { + "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": ">=4" + "node": ">= 6" } }, "node_modules/axobject-query": { @@ -4920,6 +5595,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", @@ -5252,6 +5935,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", @@ -5425,6 +6118,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", @@ -5586,6 +6288,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 +6536,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 +7854,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", @@ -7171,9 +7892,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", @@ -7605,6 +8326,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", @@ -7705,6 +8434,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", @@ -7921,6 +8663,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", @@ -8192,6 +8939,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", @@ -10559,6 +11311,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", @@ -12815,6 +13719,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", @@ -12837,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", @@ -12965,6 +13882,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", @@ -13082,6 +14012,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", @@ -13099,11 +14034,86 @@ "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-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", + "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", @@ -13112,6 +14122,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 +14224,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", @@ -13230,6 +14285,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", @@ -13372,6 +14440,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", @@ -13853,6 +14926,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", @@ -14246,6 +15324,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", @@ -14384,6 +15467,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", @@ -14606,6 +15697,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", @@ -14616,6 +15724,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", @@ -14901,6 +16014,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", @@ -15883,6 +17004,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", @@ -17044,11 +18178,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": { @@ -17156,37 +18297,163 @@ "postcss-value-parser": "^4.2.0" } }, - "@csstools/postcss-oklab-function": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.1.0.tgz", - "integrity": "sha512-e/Q5HopQzmnQgqimG9v3w2IG4VRABsBq3itOcn4bnm+j4enTgQZ0nWsaH/m9GV2otWGQ0nwccYL5vmLKyvP1ww==", + "@csstools/postcss-oklab-function": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.1.0.tgz", + "integrity": "sha512-e/Q5HopQzmnQgqimG9v3w2IG4VRABsBq3itOcn4bnm+j4enTgQZ0nWsaH/m9GV2otWGQ0nwccYL5vmLKyvP1ww==", + "requires": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + } + }, + "@csstools/postcss-progressive-custom-properties": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.3.0.tgz", + "integrity": "sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "@csstools/postcss-stepped-value-functions": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-1.0.0.tgz", + "integrity": "sha512-q8c4bs1GumAiRenmFjASBcWSLKrbzHzWl6C2HcaAxAXIiL2rUlUWbqQZUjwVG5tied0rld19j/Mm90K3qI26vw==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "@csstools/postcss-unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.0.tgz", + "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": { - "@csstools/postcss-progressive-custom-properties": "^1.1.0", - "postcss-value-parser": "^4.2.0" + "@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" } }, - "@csstools/postcss-progressive-custom-properties": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.3.0.tgz", - "integrity": "sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA==", + "@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": { - "postcss-value-parser": "^4.2.0" + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", + "csstype": "^3.0.2" } }, - "@csstools/postcss-stepped-value-functions": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-1.0.0.tgz", - "integrity": "sha512-q8c4bs1GumAiRenmFjASBcWSLKrbzHzWl6C2HcaAxAXIiL2rUlUWbqQZUjwVG5tied0rld19j/Mm90K3qI26vw==", + "@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": { - "postcss-value-parser": "^4.2.0" + "@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" } }, - "@csstools/postcss-unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.0.tgz", - "integrity": "sha512-T5ZyNSw9G0x0UDFiXV40a7VjKw2b+l4G+S0sctKqxhx8cg9QtMUAGwJBVU9mHPDPoZEmwm0tEoukjl4zb9MU7Q==", + "@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 +18498,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 +19068,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 +19220,34 @@ "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==" + }, + "@reduxjs/toolkit": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.2.3.tgz", + "integrity": "sha512-76dll9EnJXg4EVcI5YNxZA/9hSAmZsFqzMmNRHvIlzw2WS/twfcVX3ysYrWGJMClwEmChQFC4yRq74tn6fdzRA==", + "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", + "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", @@ -17884,6 +19322,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", @@ -18004,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", @@ -18129,6 +19628,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", @@ -18201,6 +19705,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 +19725,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 +19756,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", @@ -18264,6 +19796,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", @@ -18396,6 +19933,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", @@ -18818,6 +20364,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", @@ -19343,6 +20911,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", @@ -19584,6 +21157,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", @@ -19693,6 +21276,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", @@ -19809,6 +21401,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 +21587,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 +22567,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", @@ -20985,9 +22596,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", @@ -21274,6 +22885,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", @@ -21341,6 +22958,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", @@ -21504,6 +23136,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", @@ -21684,6 +23321,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", @@ -23405,6 +25047,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", @@ -24908,6 +26698,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", @@ -24923,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", @@ -25009,6 +26810,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", @@ -25095,6 +26905,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", @@ -25109,16 +26924,83 @@ "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-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", + "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", "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 +27056,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", @@ -25210,6 +27103,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", @@ -25321,6 +27225,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", @@ -25662,6 +27571,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", @@ -25955,6 +27869,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", @@ -26068,6 +27987,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", @@ -26228,6 +28152,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", @@ -26238,6 +28173,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", @@ -26449,6 +28389,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 6fd77e8c..9342e644 100644 --- a/package.json +++ b/package.json @@ -2,10 +2,28 @@ "name": "project-3-frontend-bootcamp", "version": "0.1.0", "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", + "@mui/material": "^5.15.14", + "@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", - "react-scripts": "5.0.1" + "react-hot-toast": "^2.4.1", + "react-redux": "^9.1.0", + "react-router-dom": "^6.22.3", + "react-scripts": "5.0.1", + "redux": "^5.0.1" }, "scripts": { "start": "react-scripts start", diff --git a/public/blank/blank.png b/public/blank/blank.png new file mode 100644 index 00000000..cfb6faf3 Binary files /dev/null and b/public/blank/blank.png differ diff --git a/public/cover.png b/public/cover.png new file mode 100644 index 00000000..c58f9c36 Binary files /dev/null and b/public/cover.png differ 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/App.js b/src/App.js deleted file mode 100644 index 4a6f800f..00000000 --- a/src/App.js +++ /dev/null @@ -1,20 +0,0 @@ -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. -

-
-
- ); - } -} - -export default App; diff --git a/src/components/AdminEventPreview.js b/src/components/AdminEventPreview.js new file mode 100644 index 00000000..69d24e64 --- /dev/null +++ b/src/components/AdminEventPreview.js @@ -0,0 +1,92 @@ +//-----------Libraries-----------// +import React, { useState } from "react"; +import { Card, CardContent, CardMedia, Typography } from "@mui/material"; +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..ba4978c6 --- /dev/null +++ b/src/components/AdminEventPreviewList.js @@ -0,0 +1,79 @@ +//-----------Libraries-----------// +import { useState, useEffect } from "react"; +import axios from "axios"; +import { Box, CardMedia, Typography } from "@mui/material"; + +//-----------Components-----------// +import AdminEventPreview from "./AdminEventPreview"; +import { BACKEND_URL } from "../constant.js"; + +const AdminEventPreviewList = ({ adminId, accessToken }) => { + const [events, setEvents] = useState([]); + + useEffect(() => { + const fetchData = async () => { + try { + const response = await axios.post( + `${BACKEND_URL}/events/admin`, + { + adminId: adminId, + }, + { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + } + ); + 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..91afe2d2 --- /dev/null +++ b/src/components/AdminNavBar.js @@ -0,0 +1,43 @@ +//-----------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 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/components/BookingPreview.js b/src/components/BookingPreview.js new file mode 100644 index 00000000..0b004ebb --- /dev/null +++ b/src/components/BookingPreview.js @@ -0,0 +1,87 @@ +//-----------Libraries-----------// +import { Card, Typography, Box } from "@mui/material"; +import { Link } from "react-router-dom"; +import { + APIProvider, + Map, + AdvancedMarker, + Pin, +} from "@vis.gl/react-google-maps"; + +const BookingPreview = (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 ( + + + + + + + + + + + + {formatDate(props.data.event.start)}- + {formatHour(props.data.event.end)} + + + {props.data.event.title} + + + {props.data.event.venue.address} + + + + Quantity :{props.data.quantity_bought} + + + + ); +}; + +export default BookingPreview; diff --git a/src/components/EventPreview.js b/src/components/EventPreview.js new file mode 100644 index 00000000..f893a03e --- /dev/null +++ b/src/components/EventPreview.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.admin.name} + + + +
+
+ ); +}; + +export default EventPreview; diff --git a/src/components/EventPreviewList.js b/src/components/EventPreviewList.js new file mode 100644 index 00000000..0ab13021 --- /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"; +import { BACKEND_URL } from "../constant.js"; + +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/components/Redirect.js b/src/components/Redirect.js new file mode 100644 index 00000000..bcf62d40 --- /dev/null +++ b/src/components/Redirect.js @@ -0,0 +1,33 @@ +//-----------Libraries-----------// +import { ThemeProvider } from "@mui/material/styles"; +import theme from "../theme"; +import Typography from "@mui/material/Typography"; +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 new file mode 100644 index 00000000..90f2dd0a --- /dev/null +++ b/src/components/navbar.js @@ -0,0 +1,43 @@ +//-----------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"; + +//-----------Components-----------// +import theme from "../theme"; + +//-----------Styling-----------// +import "../App.css"; + +export default function NavBar() { + const Offset = styled("div")(({ theme }) => theme.mixins.toolbar); + + return ( + + + + + + + + + + + + + + + + + ); +} 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..795fd97f --- /dev/null +++ b/src/components/searchBar.js @@ -0,0 +1,196 @@ +//-----------Libraries-----------// +import { useState, useEffect } from "react"; +import { useNavigate } from "react-router-dom"; +import { + 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 SearchIcon from "@mui/icons-material/Search"; +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("all"); + 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] = false; + }); + 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 }, + }); + } catch (error) { + console.error("Error searching", error); + } + }; + + const handleCategoryToggle = (categoryId) => { + setCheckedCategories((prevCheckedCategories) => ({ + ...prevCheckedCategories, + [categoryId]: !prevCheckedCategories[categoryId], + })); + }; + + const chips = categories.map((category) => ( + handleCategoryToggle(category.id)} + /> + )); + + 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()} + /> + )); + + const FilterList = ( + + + + + + + + + {categoriesList} + + + + + + ); + + return ( +
+ + setKeyword(e.target.value)} + defaultValue="all" + /> + + + + +
+ + } + label="Filter" + /> + {chips} + +
+
+ + + {FilterList} + +
+ ); +} diff --git a/src/constant.js b/src/constant.js new file mode 100644 index 00000000..ff20f1d0 --- /dev/null +++ b/src/constant.js @@ -0,0 +1,2 @@ +export const BACKEND_URL = "http://localhost:5000"; +export const FRONTEND_URL = "http://localhost:3000"; 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/index.js b/src/index.js index a64e7d56..aceed4af 100644 --- a/src/index.js +++ b/src/index.js @@ -1,7 +1,171 @@ +//-----------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 NavBar from "./components/navbar.js"; +import AdminNavBar from "./components/AdminNavBar.js"; + +//-----------Styling-----------// import "./index.css"; -import App from "./App"; + +//-----------Pages-----------/// +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 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 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.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")); -root.render(); + +const AdminRoutes = () => ( + + } /> + + + + + } + /> + } /> + } /> + } /> + + + + + } + /> + + + + + } + /> + +); + +const NonAdminRoutes = () => ( + + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + } /> + } /> + } /> + } /> + } /> + +); + +const newUrl = window.location.origin + "/home"; +const newUrlAdmin = window.location.origin + "/admin/home"; + +root.render( + <> + + + + } /> + + + + + + + + } /> + + + + + +); diff --git a/src/logo.png b/src/logo.png deleted file mode 100755 index a7e08590..00000000 Binary files a/src/logo.png and /dev/null differ diff --git a/src/pages/adminPages/adminCreateEvent.js b/src/pages/adminPages/adminCreateEvent.js new file mode 100644 index 00000000..433ce065 --- /dev/null +++ b/src/pages/adminPages/adminCreateEvent.js @@ -0,0 +1,415 @@ +//-----------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, + CardMedia, + Input, + InputAdornment, + InputLabel, + OutlinedInput, + 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 [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 [file, setFile] = useState(null); + const [previewUrl, setPreviewUrl] = useState(null); + const { isAuthenticated, isLoading, getAccessTokenSilently, user } = + useAuth0(); + const [accessToken, setAccessToken] = useState(); + const navigate = useNavigate(); + + useEffect(() => { + const fetchCategories = 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); + } + }; + 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; + } + const previewUrl = URL.createObjectURL(file); + setPreviewUrl(previewUrl); + localStorage.setItem("test", previewUrl); + }, [file]); + + const onMapClick = (e) => { + setMarker({ + lat: e.detail.latLng.lat, + lng: e.detail.latLng.lng, + }); + }; + + const handleSubmit = async (event) => { + event.preventDefault(); + + if ( + !title || + !description || + !selectedLanguageId || + !selectedCategoryId || + !selectedStatusId || + !price || + !start || + !end || + !capacity || + !address || + !postalCode || + !marker + ) { + setErrorMessage(true); + 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", + }, + { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + } + ); + + const venueId = venueResponse.data.id; + + //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(""); + setAdminId(""); + setPrice(""); + setStart(""); + setEnd(""); + setAddress(""); + setPostalCode(""); + setSelectedStatusId(""); + setCapacity(""); + setPreviewUrl(""); + + 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 && ( + + )} + + + + setFile(e.target.files[0])} /> + + {previewUrl && ( + + )} + + + + {errorMessage &&

Please fill in all the details

} +
+
+ ); +} diff --git a/src/pages/adminPages/adminEventPage.js b/src/pages/adminPages/adminEventPage.js new file mode 100644 index 00000000..4cee4a4d --- /dev/null +++ b/src/pages/adminPages/adminEventPage.js @@ -0,0 +1,150 @@ +//-----------Libraries-----------// +import axios from "axios"; +import { useState, useEffect } from "react"; +import { Box, Card, CardMedia, Typography, ThemeProvider } from "@mui/material"; +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 [accessToken, setAccessToken] = useState(); + const { isAuthenticated, isLoading, getAccessTokenSilently } = useAuth0(); + const navigate = useNavigate(); + + const params = useParams(); + if (eventId !== params.eventId) { + setEventId(params.eventId); + } + + const checkUser = async () => { + if (isAuthenticated) { + try { + let token = await getAccessTokenSilently(); + setAccessToken(token); + } catch (error) { + console.error("Error fetching data:", error); + } + } + }; + + useEffect(() => { + checkUser(); + }, [isAuthenticated]); + + useEffect(() => { + if (!isAuthenticated && !isLoading) { + navigate("/admin"); + } + }, [isAuthenticated, isLoading, navigate]); + + useEffect(() => { + const fetchData = async () => { + try { + 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); + + // 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); + } + }; + + if (eventId) { + fetchData(); + } + }, [eventId]); + + const bookingList = + bookings.length > 0 ? ( + + {bookings.map((booking) => ( + + User: {booking.user.email} + + Quantity Bought: {booking.quantity_bought} + + + BookingId: {booking.id} + + + ))} + + ) : ( + + + + No one has booked yet. + + + ); + + return ( + + + + + + + + + + {event && Total slots: {event.capacity}} + {capacity && Slots left: {capacity}} + + {bookingList} + + ); +} diff --git a/src/pages/adminPages/adminHomePage.js b/src/pages/adminPages/adminHomePage.js new file mode 100644 index 00000000..80eae613 --- /dev/null +++ b/src/pages/adminPages/adminHomePage.js @@ -0,0 +1,79 @@ +//-----------Libraries-----------// +import { Typography, ThemeProvider } from "@mui/material"; +import { 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, isLoading, getAccessTokenSilently, user } = + useAuth0(); + const navigate = useNavigate(); + const [accessToken, setAccessToken] = useState(); + const [adminId, setAdminId] = useState(); + + useEffect(() => { + const fetchAdminId = async () => { + try { + if (user && user.email) { + const token = await getAccessTokenSilently(); + setAccessToken(token); + const response = await axios.post( + `${BACKEND_URL}/admins/`, + { + email: user.email, + }, + { + headers: { + Authorization: `Bearer ${token}`, + }, + } + ); + const output = response.data; + 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]); + + useEffect(() => { + if (!isAuthenticated && !isLoading) { + navigate("/admin"); + } + }, [isAuthenticated, isLoading, navigate]); + + return ( + +
+ + Your Events + + {adminId && ( + + )} +
+
+ ); +} diff --git a/src/pages/adminPages/adminIntroPage.js b/src/pages/adminPages/adminIntroPage.js new file mode 100644 index 00000000..a8e8de64 --- /dev/null +++ b/src/pages/adminPages/adminIntroPage.js @@ -0,0 +1,58 @@ +//-----------Libraries-----------// +import { Box, Button, Typography, ThemeProvider } from "@mui/material"; +import { 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 new file mode 100644 index 00000000..5fdf1470 --- /dev/null +++ b/src/pages/adminPages/adminProfilePage.js @@ -0,0 +1,134 @@ +//-----------Libraries-----------// +import { useEffect, useState } from "react"; +import { + Avatar, + ThemeProvider, + Typography, + List, + ListItem, + ListItemIcon, + ListItemText, +} from "@mui/material"; +import { + ContactSupport as ContactSupportIcon, + ExitToApp as ExitToAppIcon, +} from "@mui/icons-material"; +import { useAuth0 } from "@auth0/auth0-react"; +import axios from "axios"; +import { useNavigate } from "react-router-dom"; + +//-----------Components-----------// +import { BACKEND_URL } from "../../constant.js"; +import theme from "../../theme"; + +const AdminProfilePage = () => { + const { + isAuthenticated, + loginWithRedirect, + logout, + isLoading, + getAccessTokenSilently, + user, + } = useAuth0(); + 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, + }, + { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + } + ); + 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..fdb92924 --- /dev/null +++ b/src/pages/adminPages/adminSettingsPage.js @@ -0,0 +1,111 @@ +//-----------Libraries-----------// +import { useState, useEffect } from "react"; +import { useNavigate } from "react-router-dom"; +import axios from "axios"; +import { Button, Box, TextField, 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, isLoading, isAuthenticated, getAccessTokenSilently } = + useAuth0(); + 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}`, + }, + } + ); + 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}`, + }, + } + ); + 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/contactUsPage.js b/src/pages/contactUsPage.js new file mode 100644 index 00000000..ccfbb8f9 --- /dev/null +++ b/src/pages/contactUsPage.js @@ -0,0 +1,33 @@ +//-----------Libraries-----------// +import { Box, Typography, ThemeProvider } from "@mui/material"; + +//-----------Components-----------// +import theme from "../theme"; + +export default function ContactUsPage() { + return ( + + + + 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/checkOutPage.js b/src/pages/userPages/checkOutPage.js new file mode 100644 index 00000000..24432de8 --- /dev/null +++ b/src/pages/userPages/checkOutPage.js @@ -0,0 +1,76 @@ +import React, { useCallback, useState, useEffect } from "react"; +import { useLocation } from "react-router-dom"; +import { loadStripe } from "@stripe/stripe-js"; +import axios from "axios"; +import { + EmbeddedCheckoutProvider, + EmbeddedCheckout, +} from "@stripe/react-stripe-js"; +import { BACKEND_URL } from "../../constant.js"; +import { useAuth0 } from "@auth0/auth0-react"; + +//public key +const stripePromise = loadStripe( + "pk_test_51OyC8VEkRpzvMxvMLDTzSAtzYuI8Aj98G0UQ3IkjB4ERSxgMQKMb9RNDz0LUq30pttvyJo0TsbnZVVZDxdP8SnIy000n2nrCq9" +); + +const CheckoutForm = () => { + const location = useLocation(); + const eventId = location.state.eventId; + const quantity_bought = location.state.quantity; + const user_id = location.state.user_id; + const { user, loginWithRedirect, isAuthenticated, getAccessTokenSilently } = + useAuth0(); + const [accessToken, setAccessToken] = useState(null); + + 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, + user_id: user_id, + }, + { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + } + ) + .then((response) => response.data.clientSecret) + .catch((error) => { + console.error("Error fetching client secret:", error); + throw error; + }); + }, [accessToken, eventId, quantity_bought, user_id]); + + const options = { fetchClientSecret }; + console.log(options); + + console.log("User ID:", user_id); + return ( +
+ + + +
+ ); +}; + +export default CheckoutForm; diff --git a/src/pages/userPages/eventBookingPage.js b/src/pages/userPages/eventBookingPage.js new file mode 100644 index 00000000..411a908e --- /dev/null +++ b/src/pages/userPages/eventBookingPage.js @@ -0,0 +1,163 @@ +//-----------Libraries-----------// +import { useState, useEffect } from "react"; +import { Link } from "react-router-dom"; +import axios from "axios"; +import { Box, Button, Typography, ThemeProvider } from "@mui/material"; +import { useAuth0 } from "@auth0/auth0-react"; + +//-----------Components-----------// +import { BACKEND_URL } from "../../constant.js"; +import theme from "../../theme"; + +export default function EventBookingPage({ eventId, isFree }) { + const [quantity, setQuantity] = useState(1); + const [capacity, setCapacity] = useState(); + const [event, setEvent] = useState(); + const [userDb, setUserDb] = useState(); + const [accessToken, setAccessToken] = useState(); + const { isAuthenticated, loginWithRedirect, getAccessTokenSilently, user } = + useAuth0(); + + 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]); + + 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 fetchData = async () => { + try { + if (user && user.email) { + const response = await axios.post( + `${BACKEND_URL}/users/`, + { + email: user.email, + }, + { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + } + ); + 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(); + }, []); + + const handleIncrement = () => { + if (quantity < capacity) { + setQuantity(quantity + 1); + } + }; + + const handleDecrement = () => { + if (quantity > 1) { + setQuantity(quantity - 1); + } + }; + + const totalPrice = event && event.price * quantity; + const displayPrice = totalPrice === 0 ? "Free" : `$ ${totalPrice}`; + + return ( + + + + Number of Tickets + + + + + {quantity} + + + + + + Total + + + {displayPrice} + + + + + + + + + ); +} diff --git a/src/pages/userPages/eventDetailPage.js b/src/pages/userPages/eventDetailPage.js new file mode 100644 index 00000000..b193e1b0 --- /dev/null +++ b/src/pages/userPages/eventDetailPage.js @@ -0,0 +1,232 @@ +//-----------Libraries-----------// +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 { + APIProvider, + Map, + AdvancedMarker, + 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"; +import { BACKEND_URL } from "../../constant.js"; +import theme from "../../theme"; + +export default function EventDetailPage() { + const [event, setEvent] = useState(); + const [eventId, setEventId] = useState(); + const [showRegistration, setShowRegistraton] = useState(null); + const [isFree, setIsFree] = useState(null); + const { loginWithRedirect, isAuthenticated } = useAuth0(); + + 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); + } + }; + useEffect(() => { + fetchData(); + }, [eventId]); + + // Update eventID in state if needed to trigger data retrieval + const params = useParams(); + if (eventId !== params.eventId) { + setEventId(params.eventId); + } + + const handleClickOpen = async () => { + if (!isAuthenticated) { + return loginWithRedirect({ + appState: { + returnTo: window.location.pathname, + }, + }); + } + setShowRegistraton(true); + }; + + const handleClose = () => { + setShowRegistraton(false); + }; + + //add image + const eventInfo = event ? ( + + {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", + })} + + + + + {event.title} + + + + + + {event.description} + + + + + + Language: {event.language.name} + + + + + + {event.admin.name} + + + + + + {event.venue.address} + + + + + + + + + + + + + + + + ) : null; + + return ( + + + + + {event && ( + + {event.price === 0 ? "Free" : `$${event.price}`} + + )} + + + + + + + + + + + + {eventInfo} + + {showRegistration && ( + + + + )} + + + ); +} diff --git a/src/pages/userPages/freeReturnPage.js b/src/pages/userPages/freeReturnPage.js new file mode 100644 index 00000000..93ca84cb --- /dev/null +++ b/src/pages/userPages/freeReturnPage.js @@ -0,0 +1,176 @@ +//-----------Libraries-----------// +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, + Grid, + Button, + Card, + Typography, + ThemeProvider, +} from "@mui/material"; +import { useAuth0 } from "@auth0/auth0-react"; + +//-----------Components-----------// +import { BACKEND_URL } from "../../constant.js"; +import theme from "../../theme"; + +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; + 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); + const options = { + day: "numeric", + month: "long", + hour: "2-digit", + minute: "2-digit", + }; + return date.toLocaleDateString("en-US", options); + }; + + 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, + particleCount: 200, + 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, + }, + { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + } + ) + .then((response) => { + setStatus("complete"); + setIsExploding("true"); + }) + .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 ( + + {status === "complete" ? ( + <> + + + Hooray! You're in. + + + 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 && } + + + + ) : ( +

Loading...

+ )} +
+ ); +} diff --git a/src/pages/userPages/homePage.js b/src/pages/userPages/homePage.js new file mode 100644 index 00000000..3989ba43 --- /dev/null +++ b/src/pages/userPages/homePage.js @@ -0,0 +1,34 @@ +//-----------Libraries-----------// +import { Typography, ThemeProvider } from "@mui/material"; +import theme from "../../theme"; + +//-----------Components-----------// +import EventPreviewList from "../../components/EventPreviewList"; +import SearchBar from "../../components/searchBar"; + +export default function HomePage() { + return ( + + + +
+ + Ongoing Events + + +
+
+ ); +} diff --git a/src/pages/userPages/myBookingPage.js b/src/pages/userPages/myBookingPage.js new file mode 100644 index 00000000..f0c3ec88 --- /dev/null +++ b/src/pages/userPages/myBookingPage.js @@ -0,0 +1,301 @@ +//-----------Libraries-----------// +import { useState, useEffect } from "react"; +import { useAuth0 } from "@auth0/auth0-react"; +import axios from "axios"; +import PropTypes from "prop-types"; +import { + Tabs, + ThemeProvider, + Tab, + Typography, + Box, + Button, + Card, + 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; + + 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([]); + const [userDb, setUserDb] = useState(); + const { + isAuthenticated, + loginWithRedirect, + isLoading, + getAccessTokenSilently, + user, + } = useAuth0(); + const [accessToken, setAccessToken] = 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); + } + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const RedirectTab = () => { + return ( +
+ + + + +
+ ); + }; + + const checkUser = async () => { + if (isAuthenticated) { + let token = await getAccessTokenSilently(); + setAccessToken(token); + fetchData(); + } + }; + + useEffect(() => { + checkUser(); + }, []); + + useEffect(() => { + if (userDb && userDb.length > 0) { + const fetchData = async () => { + try { + 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) { + console.error("Error fetching data:", error); + } + }; + fetchData(); + } + }, [userDb]); + + useEffect(() => { + if (userDb && userDb.length > 0) { + const fetchData = async () => { + try { + 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) { + console.error("Error fetching data:", error); + } + }; + fetchData(); + } + }, [userDb]); + + const handleChange = (event, newValue) => { + setValue(newValue); + }; + + const currentPreviews = + current.length > 0 ? ( + current.map((booking) => ( + + )) + ) : ( + <> + + + + You don't have any upcoming events. + + + + ); + + const pastPreviews = + past.length > 0 ? ( + past.map((booking) => ) + ) : ( + <> + + + + You don't have any past events. + + + + ); + + if (!isAuthenticated) { + return ( + + + + ); + } + + return ( + <> + {isLoading ? ( +

loading...

+ ) : ( + + + + + + + + +
+ {currentPreviews} +
+
+ +
+ {pastPreviews} +
+
+
+ )} + + ); +} diff --git a/src/pages/userPages/myProfilePage.js b/src/pages/userPages/myProfilePage.js new file mode 100644 index 00000000..9cc6824c --- /dev/null +++ b/src/pages/userPages/myProfilePage.js @@ -0,0 +1,81 @@ +//-----------Libraries-----------// +import { + Avatar, + ThemeProvider, + Typography, + List, + ListItem, + ListItemIcon, + ListItemText, +} from "@mui/material"; +import { + ContactSupport as ContactSupportIcon, + ExitToApp as ExitToAppIcon, +} from "@mui/icons-material"; +import { useAuth0 } from "@auth0/auth0-react"; +import { useNavigate } from "react-router-dom"; + +//-----------Components-----------// +import theme from "../../theme"; + +const MyProfilePage = () => { + const { isAuthenticated, loginWithRedirect, logout, isLoading, user } = + useAuth0(); + const navigate = useNavigate(); + + const handleContactUsClick = () => { + navigate("/contactus"); + }; + + const handleLoginOrLogout = () => { + if (isAuthenticated) { + logout(); + } else { + loginWithRedirect(); + } + }; + + return ( + +
+ {isLoading ? ( +

loading...

+ ) : ( +
+ {isAuthenticated && ( +
+ +
+ )} + + {user?.nickname} + +
+ )} + + + + + + + + + + + + + + + +
+
+ ); +}; + +export default MyProfilePage; diff --git a/src/pages/userPages/returnPage.js b/src/pages/userPages/returnPage.js new file mode 100644 index 00000000..c68d3cb8 --- /dev/null +++ b/src/pages/userPages/returnPage.js @@ -0,0 +1,198 @@ +//-----------Libraries-----------// +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, + Card, + Grid, + Typography, + ThemeProvider, +} from "@mui/material"; +import ConfettiExplosion from "react-confetti-explosion"; +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( + "pk_test_51OyC8VEkRpzvMxvMLDTzSAtzYuI8Aj98G0UQ3IkjB4ERSxgMQKMb9RNDz0LUq30pttvyJo0TsbnZVVZDxdP8SnIy000n2nrCq9" +); + +export default function ReturnPage() { + const [status, setStatus] = useState(null); + const [event, setEvent] = 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); + const options = { + day: "numeric", + month: "long", + hour: "2-digit", + minute: "2-digit", + }; + return date.toLocaleDateString("en-US", options); + }; + + 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, + particleCount: 200, + 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 { + 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( + `${FRONTEND_URL}/bookings/session-status?session_id=${sessionId}&eventId=${eventId}&quantity=${quantity}&user=${user}`, + { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + } + ); + + setStatus(response.data.status); + setLoading(false); + setIsExploding("true"); + } catch (error) { + console.error("Error fetching client secret:", error); + setLoading(false); + } + }; + + fetchData(); + }, []); + + useEffect(() => { + 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...

; + } + + // Display confirmation message or redirect based on status + if (status === "complete") { + return ( + + + + Hooray! You're in. + + + 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 && } + + + + ); + } else if (status === "open") { + return ; + } else { + return

Status: {status}

; + } +} diff --git a/src/pages/userPages/searchPage.js b/src/pages/userPages/searchPage.js new file mode 100644 index 00000000..86c4a3db --- /dev/null +++ b/src/pages/userPages/searchPage.js @@ -0,0 +1,138 @@ +//-----------Libraries-----------// +import { useState, useEffect, useRef } from "react"; +import { useOutletContext, useParams, useLocation } from "react-router-dom"; +import axios from "axios"; +import { Box, Grid, ThemeProvider } from "@mui/material"; + +import { + APIProvider, + Map, + AdvancedMarker, + Pin, +} from "@vis.gl/react-google-maps"; + +//-----------Components-----------// +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(); + const { state } = useLocation(); + const selectedCategories = state && state.categories ? state.categories : []; + const [events, setEvents] = useState([]); + const [loading, setLoading] = useState(true); + const eventPreviewRefs = useRef([]); + + useEffect(() => { + const fetchData = async () => { + try { + setEvents([]); + setLoading(true); + const response = await axios.get( + `${BACKEND_URL}/events/search/${keyword}`, + { + params: { categories: selectedCategories }, + } + ); + + setEvents(response.data); + setLoading(false); + } catch (error) { + console.error("Error fetching data:", error); + setLoading(false); + } + }; + + fetchData(); + }, [keyword, selectedCategories]); + + const eventPreviews = + events && events.length > 0 ? ( +
+ {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 ( + +
+ +
+ +
+ {events.length > 0 && ( // Only render the map if events are loaded + + + {markers} + + + )} + + {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; +} diff --git a/src/theme.js b/src/theme.js new file mode 100644 index 00000000..13905123 --- /dev/null +++ b/src/theme.js @@ -0,0 +1,23 @@ +import { createTheme } from "@mui/material/styles"; + +const theme = createTheme({ + palette: { + primary: { + main: "#32AD80", + }, + secondary: { + main: "#FCA56D", + }, + error: { + main: "#F0635A", + }, + info: { + main: "#81AC80", + }, + success: { + main: "#FFFFFF", + }, + }, +}); + +export default theme;