diff --git a/.env.example b/.env.example index 7334213..2abc8d2 100644 --- a/.env.example +++ b/.env.example @@ -3,4 +3,6 @@ # DEVELOPMENT TOOLS # Ideally, don't add them to production deployment envs # !STARTERCONF Change to true if you want to log data -NEXT_PUBLIC_SHOW_LOGGER="false" \ No newline at end of file +NEXT_PUBLIC_SHOW_LOGGER="false" +PORT= +NEXT_PUBLIC_MARKETPLACE_BACKEND_URL='http://localhost:4020' diff --git a/.vscode/settings.json b/.vscode/settings.json index 737af3d..23e2aa6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,7 +3,7 @@ "editor.formatOnSave": true, "editor.tabSize": 2, "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" }, // Tailwind CSS Autocomplete, add more if used in projects "tailwindCSS.classAttributes": [ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..366a841 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,40 @@ +# Stage 1: Build Stage +FROM node:18-alpine AS build + +# Set the working directory inside the container +WORKDIR /app + +# Copy package.json and package-lock.json to the working directory +COPY package*.json ./ + +# Install dependencies +RUN npm install + +# Copy the rest of the application code to the container +COPY . . +COPY .env.example ./env.local + +# Build the Next.js app +RUN npm run build + +# Stage 2: Runtime Stage +FROM node:18-alpine + +# Set the working directory inside the container +WORKDIR /app + +# Copy only necessary files from the build stage +ENV NODE_ENV production + +COPY --from=build /app/next.config.js ./next.config.js +COPY --from=build /app/public ./public +COPY --from=build /app/package.json ./package.json +COPY --from=build /app/.next/standalone ./ +COPY --from=build /app/.next/static ./.next/static +COPY .env.example ./env.local + +# Expose the desired port +EXPOSE 3400 + +# Start the Next.js app +CMD ["node", "server.js"] diff --git a/config.js b/config.js new file mode 100644 index 0000000..3656c30 --- /dev/null +++ b/config.js @@ -0,0 +1,6 @@ +const marketBackendUrl = + process.env.NEXT_PUBLIC_MARKETPLACE_BACKEND_URL || 'http://localhost:4020'; + +module.exports = { + marketBackendUrl, +}; diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..8645dce --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,15 @@ +version: '3' + +services: + marketplace-ui: + build: + context: . + dockerfile: Dockerfile + ports: + - "3400:3000" + networks: + - samagra_compass + +networks: + samagra_compass: + external: true diff --git a/next.config.js b/next.config.js index caecedc..4285e83 100644 --- a/next.config.js +++ b/next.config.js @@ -6,13 +6,16 @@ const nextConfig = { reactStrictMode: true, swcMinify: true, - + output: 'standalone', // Uncoment to add domain whitelist - // images: { - // domains: [ - // 'res.cloudinary.com', - // ], - // }, + images: { + remotePatterns: [ + { + protocol: 'https', + hostname: '**', + }, + ], + }, webpack(config) { // Grab the existing rule that handles SVG imports diff --git a/package-lock.json b/package-lock.json index cdb1338..2067ee3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,12 +8,25 @@ "name": "ts-nextjs-tailwind-starter", "version": "0.1.0", "dependencies": { + "@reduxjs/toolkit": "^1.9.7", + "@types/swiper": "^6.0.0", + "axios": "^1.6.0", "clsx": "^1.2.1", "lucide-react": "^0.260.0", "next": "^13.4.10", "react": "^18.2.0", + "react-detect-offline": "^2.4.5", "react-dom": "^18.2.0", "react-icons": "^4.10.1", + "react-redux": "^8.1.3", + "react-select": "^5.7.7", + "react-simple-pull-to-refresh": "^1.3.3", + "react-slick": "^0.29.0", + "react-toastify": "^9.1.3", + "redux": "^4.2.1", + "redux-persist": "^6.0.0", + "redux-thunk": "^2.4.2", + "swiper": "^11.0.2", "tailwind-merge": "^1.13.2" }, "devDependencies": { @@ -24,6 +37,8 @@ "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@types/react": "^18.2.15", + "@types/react-detect-offline": "^2.4.4", + "@types/react-slick": "^0.23.11", "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.62.0", "autoprefixer": "^10.4.14", @@ -88,7 +103,6 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", - "dev": true, "dependencies": { "@babel/highlight": "^7.22.5" }, @@ -335,7 +349,6 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", - "dev": true, "dependencies": { "@babel/types": "^7.22.5" }, @@ -457,7 +470,6 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -466,7 +478,6 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -512,7 +523,6 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", - "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.22.5", "chalk": "^2.0.0", @@ -526,7 +536,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "dependencies": { "color-convert": "^1.9.0" }, @@ -538,7 +547,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -552,7 +560,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "dependencies": { "color-name": "1.1.3" } @@ -560,14 +567,12 @@ "node_modules/@babel/highlight/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, "engines": { "node": ">=0.8.0" } @@ -576,7 +581,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0= sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, "engines": { "node": ">=4" } @@ -585,7 +589,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -1978,12 +1981,11 @@ "dev": true }, "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==", - "dev": true, + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz", + "integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==", "dependencies": { - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" @@ -2002,6 +2004,11 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/runtime/node_modules/regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" + }, "node_modules/@babel/template": { "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", @@ -2041,7 +2048,6 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", - "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.22.5", "@babel/helper-validator-identifier": "^7.22.5", @@ -2321,6 +2327,117 @@ "node": ">=12" } }, + "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/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/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.1", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz", + "integrity": "sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.2", + "@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.2", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.2.tgz", + "integrity": "sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==", + "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/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-community/eslint-utils": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.2.0.tgz", @@ -2404,6 +2521,28 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@floating-ui/core": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.5.0.tgz", + "integrity": "sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg==", + "dependencies": { + "@floating-ui/utils": "^0.1.3" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.3.tgz", + "integrity": "sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==", + "dependencies": { + "@floating-ui/core": "^1.4.2", + "@floating-ui/utils": "^0.1.3" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.6.tgz", + "integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==" + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", @@ -3046,6 +3185,29 @@ "url": "https://opencollective.com/unts" } }, + "node_modules/@reduxjs/toolkit": { + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.7.tgz", + "integrity": "sha512-t7v8ZPxhhKgOKtU+uyJT13lu4vL7az5aFi4IdoDs/eS548edn2M8Ik9h8fxgvMjGoAUVFSt6ZC1P5cWmQ014QQ==", + "dependencies": { + "immer": "^9.0.21", + "redux": "^4.2.1", + "redux-thunk": "^2.4.2", + "reselect": "^4.1.8" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18", + "react-redux": "^7.2.1 || ^8.0.2" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, "node_modules/@rushstack/eslint-patch": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.3.tgz", @@ -3553,6 +3715,15 @@ "@types/node": "*" } }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz", + "integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", @@ -3620,8 +3791,7 @@ "node_modules/@types/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", - "dev": true + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" }, "node_modules/@types/prettier": { "version": "2.4.1", @@ -3632,34 +3802,57 @@ "node_modules/@types/prop-types": { "version": "15.7.4", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz", - "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==", - "dev": true + "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==" }, "node_modules/@types/react": { "version": "18.2.15", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.15.tgz", "integrity": "sha512-oEjE7TQt1fFTFSbf8kkNuc798ahTUzn3Le67/PWjE8MAfYAD/qB7O8hSTcromLFqHCt9bcdOg5GXMokzTjJ5SA==", - "dev": true, "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", "csstype": "^3.0.2" } }, + "node_modules/@types/react-detect-offline": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/react-detect-offline/-/react-detect-offline-2.4.4.tgz", + "integrity": "sha512-iUqEWeiN63YfNMho8SdltKR0q7WbFXJM5cQXWLKo9rluuYn7kcyzUz2lJnG57MSmESHPC1esRICt2Ve1TlVDAA==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/react-dom": { "version": "18.0.2", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.2.tgz", "integrity": "sha512-UxeS+Wtj5bvLRREz9tIgsK4ntCuLDo0EcAcACgw3E+9wE8ePDr9uQpq53MfcyxyIS55xJ+0B6mDS8c4qkkHLBg==", + "devOptional": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-slick": { + "version": "0.23.11", + "resolved": "https://registry.npmjs.org/@types/react-slick/-/react-slick-0.23.11.tgz", + "integrity": "sha512-52AbNhYN7u0ATqAUvap2MXNG3znUsJslAWgebUHrovvnJ6EG6oic+TZyC82XiwwvijRMyL2V0C2wPJbzsSwllw==", "dev": true, "dependencies": { "@types/react": "*" } }, + "node_modules/@types/react-transition-group": { + "version": "4.4.8", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.8.tgz", + "integrity": "sha512-QmQ22q+Pb+HQSn04NL3HtrqHwYMf4h3QKArOy5F8U5nEVMaihBs3SR10WiOM1iwPz5jIo8x/u11al+iEGZZrvg==", + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/scheduler": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", - "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", - "dev": true + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" }, "node_modules/@types/semver": { "version": "7.3.13", @@ -3673,6 +3866,15 @@ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, + "node_modules/@types/swiper": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@types/swiper/-/swiper-6.0.0.tgz", + "integrity": "sha512-QPZRgxZ+ivXXtzV43B3LxpXUIC7FE/EoKM+rtxngmgt2M7eeUYypZhyqZD8UxJtlBcUDw/ATGoVeSNpvBBrz2w==", + "deprecated": "This is a stub types definition. swiper provides its own type definitions, so you do not need this installed.", + "dependencies": { + "swiper": "*" + } + }, "node_modules/@types/testing-library__jest-dom": { "version": "5.14.1", "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.1.tgz", @@ -3682,6 +3884,11 @@ "@types/jest": "*" } }, + "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/yargs": { "version": "16.0.4", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", @@ -4160,8 +4367,7 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k= sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k= sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/autoprefixer": { "version": "10.4.14", @@ -4205,6 +4411,29 @@ "node": ">=4" } }, + "node_modules/axios": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.0.tgz", + "integrity": "sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/axios/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", @@ -4264,6 +4493,20 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, "node_modules/babel-plugin-polyfill-corejs2": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.4.tgz", @@ -4466,7 +4709,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, "engines": { "node": ">=6" } @@ -4613,6 +4855,11 @@ "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", "dev": true }, + "node_modules/classnames": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + }, "node_modules/clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -4747,7 +4994,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -4831,7 +5077,6 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dev": true, "dependencies": { "safe-buffer": "~5.1.1" } @@ -4865,7 +5110,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", - "dev": true, "dependencies": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", @@ -5035,8 +5279,7 @@ "node_modules/csstype": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz", - "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==", - "dev": true + "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==" }, "node_modules/damerau-levenshtein": { "version": "1.0.8", @@ -5171,7 +5414,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk= sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, "engines": { "node": ">=0.4.0" } @@ -5245,6 +5487,15 @@ "integrity": "sha512-Xu9mD0UjrJisTmv7lmVSDMagQcU9R5hwAbxsaAE/35XPnPLJobbuREfV/rraiSaEj/UOvgrzQs66zyTWTlyd+g==", "dev": true }, + "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": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", @@ -5386,6 +5637,11 @@ "node": ">=10.13.0" } }, + "node_modules/enquire.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/enquire.js/-/enquire.js-2.1.6.tgz", + "integrity": "sha512-/KujNpO+PT63F7Hlpu4h3pE3TokKRHN26JYmQpPyjkRD/N57R7bPDNojMXdi7uveAKjYB7yQnartCxZnFWr0Xw==" + }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -5402,7 +5658,6 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, "dependencies": { "is-arrayish": "^0.2.1" } @@ -5484,7 +5739,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, "engines": { "node": ">=10" }, @@ -6311,6 +6565,11 @@ "node": ">=8" } }, + "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", @@ -6346,6 +6605,25 @@ "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", "dev": true }, + "node_modules/follow-redirects": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/form-data": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", @@ -6410,8 +6688,7 @@ "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "node_modules/function.prototype.name": { "version": "1.1.5", @@ -6651,7 +6928,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, "dependencies": { "function-bind": "^1.1.1" }, @@ -6716,6 +6992,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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/hosted-git-info": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", @@ -6836,11 +7125,19 @@ "node": ">= 4" } }, + "node_modules/immer": { + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -6856,7 +7153,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, "engines": { "node": ">=4" } @@ -6934,8 +7230,7 @@ "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, "node_modules/is-bigint": { "version": "1.0.2", @@ -6989,7 +7284,6 @@ "version": "2.12.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.0.tgz", "integrity": "sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==", - "dev": true, "dependencies": { "has": "^1.0.3" }, @@ -8057,8 +8351,7 @@ "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, "node_modules/json-schema-traverse": { "version": "0.4.1", @@ -8072,6 +8365,14 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, + "node_modules/json2mq": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz", + "integrity": "sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==", + "dependencies": { + "string-convert": "^0.2.0" + } + }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -8201,8 +8502,7 @@ "node_modules/lines-and-columns": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= sha512-8ZmlJFVK9iCmtLz19HpSsR8HaAMWBT284VMNednLwlIMDP2hJDCIhUp0IZ2xUcZ+Ob6BM0VvCSJwzASDM45NLQ==", - "dev": true + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= sha512-8ZmlJFVK9iCmtLz19HpSsR8HaAMWBT284VMNednLwlIMDP2hJDCIhUp0IZ2xUcZ+Ob6BM0VvCSJwzASDM45NLQ==" }, "node_modules/lint-staged": { "version": "12.5.0", @@ -8357,8 +8657,7 @@ "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" }, "node_modules/lodash.merge": { "version": "4.6.2", @@ -8547,6 +8846,11 @@ "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", "dev": true }, + "node_modules/memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" + }, "node_modules/meow": { "version": "8.1.2", "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", @@ -8616,7 +8920,6 @@ "version": "1.51.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -8625,7 +8928,6 @@ "version": "2.1.34", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", - "dev": true, "dependencies": { "mime-db": "1.51.0" }, @@ -8930,7 +9232,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -9157,7 +9458,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, "dependencies": { "callsites": "^3.0.0" }, @@ -9169,7 +9469,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -9219,14 +9518,12 @@ "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, "engines": { "node": ">=8" } @@ -9561,7 +9858,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -9571,8 +9867,12 @@ "node_modules/prop-types/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==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "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", @@ -9639,6 +9939,11 @@ "node": ">=0.10.0" } }, + "node_modules/react-detect-offline": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/react-detect-offline/-/react-detect-offline-2.4.5.tgz", + "integrity": "sha512-sI13NPEKl3uQp95FT5CwrYzH3DnXCwNP6TnY6NRF5gFDM4NU9KDlbtA6HG2dwhDVS0RYQGXwZW/mHbdf8fCnaw==" + }, "node_modules/react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -9665,6 +9970,121 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, + "node_modules/react-redux": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.1.3.tgz", + "integrity": "sha512-n0ZrutD7DaX/j9VscF+uTALI3oUPa/pO4Z3soOBIjuRn/FzVu6aehhysxZCLi6y7duMf52WNZGMl7CtuK5EnRw==", + "dependencies": { + "@babel/runtime": "^7.12.1", + "@types/hoist-non-react-statics": "^3.3.1", + "@types/use-sync-external-store": "^0.0.3", + "hoist-non-react-statics": "^3.3.2", + "react-is": "^18.0.0", + "use-sync-external-store": "^1.0.0" + }, + "peerDependencies": { + "@types/react": "^16.8 || ^17.0 || ^18.0", + "@types/react-dom": "^16.8 || ^17.0 || ^18.0", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0", + "react-native": ">=0.59", + "redux": "^4 || ^5.0.0-beta.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, + "node_modules/react-redux/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/react-select": { + "version": "5.7.7", + "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.7.7.tgz", + "integrity": "sha512-HhashZZJDRlfF/AKj0a0Lnfs3sRdw/46VJIRd8IbB9/Ovr74+ZIwkAdSBjSPXsFMG+u72c5xShqwLSKIJllzqw==", + "dependencies": { + "@babel/runtime": "^7.12.0", + "@emotion/cache": "^11.4.0", + "@emotion/react": "^11.8.1", + "@floating-ui/dom": "^1.0.1", + "@types/react-transition-group": "^4.4.0", + "memoize-one": "^6.0.0", + "prop-types": "^15.6.0", + "react-transition-group": "^4.3.0", + "use-isomorphic-layout-effect": "^1.1.2" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-simple-pull-to-refresh": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/react-simple-pull-to-refresh/-/react-simple-pull-to-refresh-1.3.3.tgz", + "integrity": "sha512-6qXsa5RtNVmKJhLWvDLIX8UK51HFtCEGjdqQGf+M1Qjrcc4qH4fki97sgVpGEFBRwbY7DiVDA5N5p97kF16DTw==", + "peerDependencies": { + "react": "^16.10.2 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.10.2 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-slick": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/react-slick/-/react-slick-0.29.0.tgz", + "integrity": "sha512-TGdOKE+ZkJHHeC4aaoH85m8RnFyWqdqRfAGkhd6dirmATXMZWAxOpTLmw2Ll/jPTQ3eEG7ercFr/sbzdeYCJXA==", + "dependencies": { + "classnames": "^2.2.5", + "enquire.js": "^2.1.6", + "json2mq": "^0.2.0", + "lodash.debounce": "^4.0.8", + "resize-observer-polyfill": "^1.5.0" + }, + "peerDependencies": { + "react": "^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-toastify": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.1.3.tgz", + "integrity": "sha512-fPfb8ghtn/XMxw3LkxQBk3IyagNpF/LIKjOBflbexr2AWxAH1MJgvnESwEwBn9liLFXgTKWgBSdZpw9m4OTHTg==", + "dependencies": { + "clsx": "^1.1.1" + }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + } + }, + "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/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -9842,6 +10262,30 @@ "node": ">=8" } }, + "node_modules/redux": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "dependencies": { + "@babel/runtime": "^7.9.2" + } + }, + "node_modules/redux-persist": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/redux-persist/-/redux-persist-6.0.0.tgz", + "integrity": "sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ==", + "peerDependencies": { + "redux": ">4.0.0" + } + }, + "node_modules/redux-thunk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz", + "integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==", + "peerDependencies": { + "redux": "^4" + } + }, "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -9939,11 +10383,20 @@ "node": ">=0.10.0" } }, + "node_modules/reselect": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz", + "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==" + }, + "node_modules/resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + }, "node_modules/resolve": { "version": "1.22.2", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", - "dev": true, "dependencies": { "is-core-module": "^2.11.0", "path-parse": "^1.0.7", @@ -10077,8 +10530,7 @@ "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "node_modules/safe-regex-test": { "version": "1.0.0", @@ -10388,6 +10840,11 @@ "node": ">=0.6.19" } }, + "node_modules/string-convert": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz", + "integrity": "sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==" + }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -10568,6 +11025,11 @@ } } }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, "node_modules/sucrase": { "version": "3.32.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.32.0.tgz", @@ -10648,7 +11110,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -10695,6 +11156,24 @@ "node": ">= 10" } }, + "node_modules/swiper": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/swiper/-/swiper-11.0.2.tgz", + "integrity": "sha512-JMHZYdUDG0V5ZdzWJkQicW4F7u4edmS4vlOhciTDhcZokDL2N8EE2uP4INxqIgpiJMoeHlwATqZk2yEAW7F6Dw==", + "funding": [ + { + "type": "patreon", + "url": "https://www.patreon.com/swiperjs" + }, + { + "type": "open_collective", + "url": "http://opencollective.com/swiper" + } + ], + "engines": { + "node": ">= 4.7.0" + } + }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -10888,7 +11367,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, "engines": { "node": ">=4" } @@ -11230,6 +11708,27 @@ "punycode": "^2.1.0" } }, + "node_modules/use-isomorphic-layout-effect": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", + "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "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", @@ -11512,7 +12011,6 @@ "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true, "engines": { "node": ">= 6" } @@ -11636,7 +12134,6 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", - "dev": true, "requires": { "@babel/highlight": "^7.22.5" } @@ -11824,7 +12321,6 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", - "dev": true, "requires": { "@babel/types": "^7.22.5" } @@ -11909,14 +12405,12 @@ "@babel/helper-string-parser": { "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", - "dev": true + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==" }, "@babel/helper-validator-identifier": { "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", - "dev": true + "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==" }, "@babel/helper-validator-option": { "version": "7.22.5", @@ -11950,7 +12444,6 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.22.5", "chalk": "^2.0.0", @@ -11961,7 +12454,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -11970,7 +12462,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -11981,7 +12472,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "requires": { "color-name": "1.1.3" } @@ -11989,26 +12479,22 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0= sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0= sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -12937,12 +13423,18 @@ "dev": true }, "@babel/runtime": { - "version": "7.17.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.9.tgz", - "integrity": "sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==", - "dev": true, + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz", + "integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==", "requires": { - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.14.0" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" + } } }, "@babel/runtime-corejs3": { @@ -12988,7 +13480,6 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", - "dev": true, "requires": { "@babel/helper-string-parser": "^7.22.5", "@babel/helper-validator-identifier": "^7.22.5", @@ -13205,6 +13696,106 @@ "@cspotcode/source-map-consumer": "0.8.0" } }, + "@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": { + "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/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.1", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz", + "integrity": "sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==", + "requires": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "hoist-non-react-statics": "^3.3.1" + } + }, + "@emotion/serialize": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.2.tgz", + "integrity": "sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==", + "requires": { + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", + "csstype": "^3.0.2" + } + }, + "@emotion/sheet": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" + }, + "@emotion/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-community/eslint-utils": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.2.0.tgz", @@ -13260,6 +13851,28 @@ "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==", "dev": true }, + "@floating-ui/core": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.5.0.tgz", + "integrity": "sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg==", + "requires": { + "@floating-ui/utils": "^0.1.3" + } + }, + "@floating-ui/dom": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.3.tgz", + "integrity": "sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==", + "requires": { + "@floating-ui/core": "^1.4.2", + "@floating-ui/utils": "^0.1.3" + } + }, + "@floating-ui/utils": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.6.tgz", + "integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==" + }, "@humanwhocodes/config-array": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", @@ -13710,6 +14323,17 @@ "tslib": "^2.4.0" } }, + "@reduxjs/toolkit": { + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.7.tgz", + "integrity": "sha512-t7v8ZPxhhKgOKtU+uyJT13lu4vL7az5aFi4IdoDs/eS548edn2M8Ik9h8fxgvMjGoAUVFSt6ZC1P5cWmQ014QQ==", + "requires": { + "immer": "^9.0.21", + "redux": "^4.2.1", + "redux-thunk": "^2.4.2", + "reselect": "^4.1.8" + } + }, "@rushstack/eslint-patch": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.3.tgz", @@ -14061,6 +14685,15 @@ "@types/node": "*" } }, + "@types/hoist-non-react-statics": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz", + "integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==", + "requires": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "@types/istanbul-lib-coverage": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", @@ -14128,8 +14761,7 @@ "@types/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", - "dev": true + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" }, "@types/prettier": { "version": "2.4.1", @@ -14140,34 +14772,57 @@ "@types/prop-types": { "version": "15.7.4", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz", - "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==", - "dev": true + "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==" }, "@types/react": { "version": "18.2.15", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.15.tgz", "integrity": "sha512-oEjE7TQt1fFTFSbf8kkNuc798ahTUzn3Le67/PWjE8MAfYAD/qB7O8hSTcromLFqHCt9bcdOg5GXMokzTjJ5SA==", - "dev": true, "requires": { "@types/prop-types": "*", "@types/scheduler": "*", "csstype": "^3.0.2" } }, + "@types/react-detect-offline": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/react-detect-offline/-/react-detect-offline-2.4.4.tgz", + "integrity": "sha512-iUqEWeiN63YfNMho8SdltKR0q7WbFXJM5cQXWLKo9rluuYn7kcyzUz2lJnG57MSmESHPC1esRICt2Ve1TlVDAA==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, "@types/react-dom": { "version": "18.0.2", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.2.tgz", "integrity": "sha512-UxeS+Wtj5bvLRREz9tIgsK4ntCuLDo0EcAcACgw3E+9wE8ePDr9uQpq53MfcyxyIS55xJ+0B6mDS8c4qkkHLBg==", + "devOptional": true, + "requires": { + "@types/react": "*" + } + }, + "@types/react-slick": { + "version": "0.23.11", + "resolved": "https://registry.npmjs.org/@types/react-slick/-/react-slick-0.23.11.tgz", + "integrity": "sha512-52AbNhYN7u0ATqAUvap2MXNG3znUsJslAWgebUHrovvnJ6EG6oic+TZyC82XiwwvijRMyL2V0C2wPJbzsSwllw==", "dev": true, "requires": { "@types/react": "*" } }, + "@types/react-transition-group": { + "version": "4.4.8", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.8.tgz", + "integrity": "sha512-QmQ22q+Pb+HQSn04NL3HtrqHwYMf4h3QKArOy5F8U5nEVMaihBs3SR10WiOM1iwPz5jIo8x/u11al+iEGZZrvg==", + "requires": { + "@types/react": "*" + } + }, "@types/scheduler": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", - "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", - "dev": true + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" }, "@types/semver": { "version": "7.3.13", @@ -14181,6 +14836,14 @@ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, + "@types/swiper": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@types/swiper/-/swiper-6.0.0.tgz", + "integrity": "sha512-QPZRgxZ+ivXXtzV43B3LxpXUIC7FE/EoKM+rtxngmgt2M7eeUYypZhyqZD8UxJtlBcUDw/ATGoVeSNpvBBrz2w==", + "requires": { + "swiper": "*" + } + }, "@types/testing-library__jest-dom": { "version": "5.14.1", "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.1.tgz", @@ -14190,6 +14853,11 @@ "@types/jest": "*" } }, + "@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/yargs": { "version": "16.0.4", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", @@ -14506,8 +15174,7 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k= sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k= sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "autoprefixer": { "version": "10.4.14", @@ -14529,6 +15196,28 @@ "integrity": "sha512-gd1kmb21kwNuWr6BQz8fv6GNECPBnUasepcoLbekws23NVBLODdsClRZ+bQ8+9Uomf3Sm3+Vwn0oYG9NvwnJCw==", "dev": true }, + "axios": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.0.tgz", + "integrity": "sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==", + "requires": { + "follow-redirects": "^1.15.0", + "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", @@ -14576,6 +15265,16 @@ "@types/babel__traverse": "^7.0.6" } }, + "babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "requires": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + } + }, "babel-plugin-polyfill-corejs2": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.4.tgz", @@ -14727,8 +15426,7 @@ "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" }, "camelcase": { "version": "6.2.0", @@ -14821,6 +15519,11 @@ "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", "dev": true }, + "classnames": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + }, "clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -14929,7 +15632,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -14995,7 +15697,6 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dev": true, "requires": { "safe-buffer": "~5.1.1" } @@ -15019,7 +15720,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", - "dev": true, "requires": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", @@ -15149,8 +15849,7 @@ "csstype": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz", - "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==", - "dev": true + "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==" }, "damerau-levenshtein": { "version": "1.0.8", @@ -15251,8 +15950,7 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk= sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk= sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, "detect-newline": { "version": "3.1.0", @@ -15308,6 +16006,15 @@ "integrity": "sha512-Xu9mD0UjrJisTmv7lmVSDMagQcU9R5hwAbxsaAE/35XPnPLJobbuREfV/rraiSaEj/UOvgrzQs66zyTWTlyd+g==", "dev": true }, + "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": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", @@ -15415,6 +16122,11 @@ "tapable": "^2.2.0" } }, + "enquire.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/enquire.js/-/enquire.js-2.1.6.tgz", + "integrity": "sha512-/KujNpO+PT63F7Hlpu4h3pE3TokKRHN26JYmQpPyjkRD/N57R7bPDNojMXdi7uveAKjYB7yQnartCxZnFWr0Xw==" + }, "entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -15425,7 +16137,6 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, "requires": { "is-arrayish": "^0.2.1" } @@ -15491,8 +16202,7 @@ "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==", - "dev": true + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" }, "escodegen": { "version": "2.0.0", @@ -16112,6 +16822,11 @@ "to-regex-range": "^5.0.1" } }, + "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", @@ -16138,6 +16853,11 @@ "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", "dev": true }, + "follow-redirects": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==" + }, "form-data": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", @@ -16182,8 +16902,7 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "function.prototype.name": { "version": "1.1.5", @@ -16357,7 +17076,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -16398,6 +17116,21 @@ "has-symbols": "^1.0.2" } }, + "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==" + } + } + }, "hosted-git-info": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", @@ -16487,11 +17220,15 @@ "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true }, + "immer": { + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==" + }, "import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -16500,8 +17237,7 @@ "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" } } }, @@ -16563,8 +17299,7 @@ "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, "is-bigint": { "version": "1.0.2", @@ -16600,7 +17335,6 @@ "version": "2.12.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.0.tgz", "integrity": "sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==", - "dev": true, "requires": { "has": "^1.0.3" } @@ -17402,8 +18136,7 @@ "json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, "json-schema-traverse": { "version": "0.4.1", @@ -17417,6 +18150,14 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, + "json2mq": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz", + "integrity": "sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==", + "requires": { + "string-convert": "^0.2.0" + } + }, "json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -17511,8 +18252,7 @@ "lines-and-columns": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= sha512-8ZmlJFVK9iCmtLz19HpSsR8HaAMWBT284VMNednLwlIMDP2hJDCIhUp0IZ2xUcZ+Ob6BM0VvCSJwzASDM45NLQ==", - "dev": true + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= sha512-8ZmlJFVK9iCmtLz19HpSsR8HaAMWBT284VMNednLwlIMDP2hJDCIhUp0IZ2xUcZ+Ob6BM0VvCSJwzASDM45NLQ==" }, "lint-staged": { "version": "12.5.0", @@ -17624,8 +18364,7 @@ "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" }, "lodash.merge": { "version": "4.6.2", @@ -17774,6 +18513,11 @@ "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", "dev": true }, + "memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" + }, "meow": { "version": "8.1.2", "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", @@ -17826,14 +18570,12 @@ "mime-db": { "version": "1.51.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", - "dev": true + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==" }, "mime-types": { "version": "2.1.34", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", - "dev": true, "requires": { "mime-db": "1.51.0" } @@ -18042,8 +18784,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, "object-hash": { "version": "3.0.0", @@ -18198,7 +18939,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, "requires": { "callsites": "^3.0.0" } @@ -18207,7 +18947,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -18242,14 +18981,12 @@ "path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" }, "picocolors": { "version": "1.0.0", @@ -18454,7 +19191,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "requires": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -18464,11 +19200,15 @@ "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==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" } } }, + "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", @@ -18507,6 +19247,11 @@ "loose-envify": "^1.1.0" } }, + "react-detect-offline": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/react-detect-offline/-/react-detect-offline-2.4.5.tgz", + "integrity": "sha512-sI13NPEKl3uQp95FT5CwrYzH3DnXCwNP6TnY6NRF5gFDM4NU9KDlbtA6HG2dwhDVS0RYQGXwZW/mHbdf8fCnaw==" + }, "react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -18528,6 +19273,79 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, + "react-redux": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.1.3.tgz", + "integrity": "sha512-n0ZrutD7DaX/j9VscF+uTALI3oUPa/pO4Z3soOBIjuRn/FzVu6aehhysxZCLi6y7duMf52WNZGMl7CtuK5EnRw==", + "requires": { + "@babel/runtime": "^7.12.1", + "@types/hoist-non-react-statics": "^3.3.1", + "@types/use-sync-external-store": "^0.0.3", + "hoist-non-react-statics": "^3.3.2", + "react-is": "^18.0.0", + "use-sync-external-store": "^1.0.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==" + } + } + }, + "react-select": { + "version": "5.7.7", + "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.7.7.tgz", + "integrity": "sha512-HhashZZJDRlfF/AKj0a0Lnfs3sRdw/46VJIRd8IbB9/Ovr74+ZIwkAdSBjSPXsFMG+u72c5xShqwLSKIJllzqw==", + "requires": { + "@babel/runtime": "^7.12.0", + "@emotion/cache": "^11.4.0", + "@emotion/react": "^11.8.1", + "@floating-ui/dom": "^1.0.1", + "@types/react-transition-group": "^4.4.0", + "memoize-one": "^6.0.0", + "prop-types": "^15.6.0", + "react-transition-group": "^4.3.0", + "use-isomorphic-layout-effect": "^1.1.2" + } + }, + "react-simple-pull-to-refresh": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/react-simple-pull-to-refresh/-/react-simple-pull-to-refresh-1.3.3.tgz", + "integrity": "sha512-6qXsa5RtNVmKJhLWvDLIX8UK51HFtCEGjdqQGf+M1Qjrcc4qH4fki97sgVpGEFBRwbY7DiVDA5N5p97kF16DTw==", + "requires": {} + }, + "react-slick": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/react-slick/-/react-slick-0.29.0.tgz", + "integrity": "sha512-TGdOKE+ZkJHHeC4aaoH85m8RnFyWqdqRfAGkhd6dirmATXMZWAxOpTLmw2Ll/jPTQ3eEG7ercFr/sbzdeYCJXA==", + "requires": { + "classnames": "^2.2.5", + "enquire.js": "^2.1.6", + "json2mq": "^0.2.0", + "lodash.debounce": "^4.0.8", + "resize-observer-polyfill": "^1.5.0" + } + }, + "react-toastify": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.1.3.tgz", + "integrity": "sha512-fPfb8ghtn/XMxw3LkxQBk3IyagNpF/LIKjOBflbexr2AWxAH1MJgvnESwEwBn9liLFXgTKWgBSdZpw9m4OTHTg==", + "requires": { + "clsx": "^1.1.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" + } + }, "read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -18667,6 +19485,26 @@ "strip-indent": "^3.0.0" } }, + "redux": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "requires": { + "@babel/runtime": "^7.9.2" + } + }, + "redux-persist": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/redux-persist/-/redux-persist-6.0.0.tgz", + "integrity": "sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ==", + "requires": {} + }, + "redux-thunk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz", + "integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==", + "requires": {} + }, "regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -18745,11 +19583,20 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I= sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true }, + "reselect": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz", + "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==" + }, + "resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + }, "resolve": { "version": "1.22.2", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", - "dev": true, "requires": { "is-core-module": "^2.11.0", "path-parse": "^1.0.7", @@ -18838,8 +19685,7 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "safe-regex-test": { "version": "1.0.0", @@ -19086,6 +19932,11 @@ "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", "dev": true }, + "string-convert": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz", + "integrity": "sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==" + }, "string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -19206,6 +20057,11 @@ "client-only": "0.0.1" } }, + "stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, "sucrase": { "version": "3.32.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.32.0.tgz", @@ -19265,8 +20121,7 @@ "supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" }, "svg-parser": { "version": "2.0.4", @@ -19296,6 +20151,11 @@ } } }, + "swiper": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/swiper/-/swiper-11.0.2.tgz", + "integrity": "sha512-JMHZYdUDG0V5ZdzWJkQicW4F7u4edmS4vlOhciTDhcZokDL2N8EE2uP4INxqIgpiJMoeHlwATqZk2yEAW7F6Dw==" + }, "symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -19452,8 +20312,7 @@ "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" }, "to-regex-range": { "version": "5.0.1", @@ -19691,6 +20550,18 @@ "punycode": "^2.1.0" } }, + "use-isomorphic-layout-effect": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", + "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==", + "requires": {} + }, + "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", @@ -19916,8 +20787,7 @@ "yaml": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" }, "yargs": { "version": "17.1.0", diff --git a/package.json b/package.json index e3e12d9..43ae8b4 100644 --- a/package.json +++ b/package.json @@ -18,22 +18,37 @@ "prepare": "husky install" }, "dependencies": { + "@reduxjs/toolkit": "^1.9.7", + "@types/swiper": "^6.0.0", + "axios": "^1.6.0", "clsx": "^1.2.1", "lucide-react": "^0.260.0", "next": "^13.4.10", "react": "^18.2.0", + "react-detect-offline": "^2.4.5", "react-dom": "^18.2.0", "react-icons": "^4.10.1", + "react-redux": "^8.1.3", + "react-select": "^5.7.7", + "react-simple-pull-to-refresh": "^1.3.3", + "react-slick": "^0.29.0", + "react-toastify": "^9.1.3", + "redux": "^4.2.1", + "redux-persist": "^6.0.0", + "redux-thunk": "^2.4.2", + "swiper": "^11.0.2", "tailwind-merge": "^1.13.2" }, "devDependencies": { "@commitlint/cli": "^16.3.0", "@commitlint/config-conventional": "^16.2.4", - "@tailwindcss/forms": "^0.5.4", "@svgr/webpack": "^8.0.1", + "@tailwindcss/forms": "^0.5.4", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@types/react": "^18.2.15", + "@types/react-detect-offline": "^2.4.4", + "@types/react-slick": "^0.23.11", "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.62.0", "autoprefixer": "^10.4.14", diff --git a/public/favicon.ico b/public/favicon.ico deleted file mode 100644 index 038704b..0000000 Binary files a/public/favicon.ico and /dev/null differ diff --git a/public/favicon/android-chrome-192x192.png b/public/favicon/android-chrome-192x192.png deleted file mode 100644 index 1826e12..0000000 Binary files a/public/favicon/android-chrome-192x192.png and /dev/null differ diff --git a/public/favicon/android-chrome-512x512.png b/public/favicon/android-chrome-512x512.png deleted file mode 100644 index 05cac45..0000000 Binary files a/public/favicon/android-chrome-512x512.png and /dev/null differ diff --git a/public/favicon/apple-touch-icon.png b/public/favicon/apple-touch-icon.png deleted file mode 100644 index 267bb7f..0000000 Binary files a/public/favicon/apple-touch-icon.png and /dev/null differ diff --git a/public/favicon/favicon-16x16.png b/public/favicon/favicon-16x16.png deleted file mode 100644 index abef5bf..0000000 Binary files a/public/favicon/favicon-16x16.png and /dev/null differ diff --git a/public/favicon/favicon-32x32.png b/public/favicon/favicon-32x32.png deleted file mode 100644 index cfe227c..0000000 Binary files a/public/favicon/favicon-32x32.png and /dev/null differ diff --git a/public/favicon/favicon.ico b/public/favicon/favicon.ico deleted file mode 100644 index 038704b..0000000 Binary files a/public/favicon/favicon.ico and /dev/null differ diff --git a/public/favicon/samagra_logo.jpg b/public/favicon/samagra_logo.jpg new file mode 100644 index 0000000..de89980 Binary files /dev/null and b/public/favicon/samagra_logo.jpg differ diff --git a/public/favicon/site.webmanifest b/public/favicon/site.webmanifest index 8cf9748..84503e8 100644 --- a/public/favicon/site.webmanifest +++ b/public/favicon/site.webmanifest @@ -3,12 +3,12 @@ "short_name": "", "icons": [ { - "src": "/favicon/android-chrome-192x192.png", + "src": "/favicon/samagra_logo.jpg", "sizes": "192x192", "type": "image/png" }, { - "src": "/favicon/android-chrome-512x512.png", + "src": "/favicon/samagra_logo.jpg", "sizes": "512x512", "type": "image/png" } diff --git a/public/images/SearchBox.png b/public/images/SearchBox.png new file mode 100644 index 0000000..6cdadf4 Binary files /dev/null and b/public/images/SearchBox.png differ diff --git a/public/images/courseFullImage.png b/public/images/courseFullImage.png new file mode 100644 index 0000000..be734b3 Binary files /dev/null and b/public/images/courseFullImage.png differ diff --git a/public/images/courseImage.png b/public/images/courseImage.png new file mode 100644 index 0000000..7bf5421 Binary files /dev/null and b/public/images/courseImage.png differ diff --git a/public/svg/MarketPlace.svg b/public/svg/MarketPlace.svg new file mode 100644 index 0000000..d224d6b --- /dev/null +++ b/public/svg/MarketPlace.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/public/svg/NoInternetErrorIcon.svg b/public/svg/NoInternetErrorIcon.svg new file mode 100644 index 0000000..d67191f --- /dev/null +++ b/public/svg/NoInternetErrorIcon.svg @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/svg/NotFoundIcon.svg b/public/svg/NotFoundIcon.svg new file mode 100644 index 0000000..853060b --- /dev/null +++ b/public/svg/NotFoundIcon.svg @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/svg/editIcon.svg b/public/svg/editIcon.svg new file mode 100644 index 0000000..5d08214 --- /dev/null +++ b/public/svg/editIcon.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/public/svg/emptyBox.svg b/public/svg/emptyBox.svg new file mode 100644 index 0000000..ef893e0 --- /dev/null +++ b/public/svg/emptyBox.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/svg/errorLogo.svg b/public/svg/errorLogo.svg new file mode 100644 index 0000000..507ea0b --- /dev/null +++ b/public/svg/errorLogo.svg @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/svg/filter.svg b/public/svg/filter.svg new file mode 100644 index 0000000..b2aa927 --- /dev/null +++ b/public/svg/filter.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/public/svg/index.tsx b/public/svg/index.tsx new file mode 100644 index 0000000..1230d9b --- /dev/null +++ b/public/svg/index.tsx @@ -0,0 +1,19 @@ +import EditIcon from './editIcon.svg'; +import Filter from './filter.svg'; +import LeftArrow from './leftArrow.svg'; +import MarketPlaceIcon from './MarketPlace.svg'; +import NotFound from './notFound.svg'; +import NotificationBell from './notificationBell.svg'; +import Star from './star.svg'; +import Wallet from './wallet.svg'; + +export { + EditIcon, + Filter, + LeftArrow, + MarketPlaceIcon, + NotFound, + NotificationBell, + Star, + Wallet, +}; diff --git a/public/svg/leftArrow.svg b/public/svg/leftArrow.svg new file mode 100644 index 0000000..7a44f8a --- /dev/null +++ b/public/svg/leftArrow.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/public/svg/notFound.svg b/public/svg/notFound.svg new file mode 100644 index 0000000..182e6fb --- /dev/null +++ b/public/svg/notFound.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/svg/notificationBell.svg b/public/svg/notificationBell.svg new file mode 100644 index 0000000..eec9629 --- /dev/null +++ b/public/svg/notificationBell.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/public/svg/star.svg b/public/svg/star.svg new file mode 100644 index 0000000..d3305ad --- /dev/null +++ b/public/svg/star.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/public/svg/wallet.svg b/public/svg/wallet.svg new file mode 100644 index 0000000..3f077bd --- /dev/null +++ b/public/svg/wallet.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/app/all-courses/layout.tsx b/src/app/all-courses/layout.tsx new file mode 100644 index 0000000..6a36c98 --- /dev/null +++ b/src/app/all-courses/layout.tsx @@ -0,0 +1,12 @@ +'use client'; +import * as React from 'react'; + +import PullRefresh from '@/components/PullToRefresh'; + +export default function Layout({ children }: { children: React.ReactNode }) { + return ( + + <>{children} + + ); +} diff --git a/src/app/all-courses/page.tsx b/src/app/all-courses/page.tsx new file mode 100644 index 0000000..48d6e59 --- /dev/null +++ b/src/app/all-courses/page.tsx @@ -0,0 +1,88 @@ +'use client'; + +import { useSearchParams } from 'next/navigation'; +import { useEffect, useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; + +import CourseCard from '@/components/Course/CourseCard'; +import NoCoursesFound from '@/components/Course/NoCoursesFound'; +import TitleNavbar from '@/components/navbar/TitleNavbar'; + +import Spinner from '@/app/components/Spinner'; +import { getMarketplaceCourses } from '@/redux/marketplace/action'; +import { CourseType } from '@/redux/marketplace/marketplaceReducer'; +import { AppDispatch, RootState } from '@/redux/store'; + +const Courses = () => { + const dispatch: AppDispatch = useDispatch(); + const { + isLoading, + isError, + savedCourses, + mostPopularCourses, + recommendedCourses, + } = useSelector((state: RootState) => state?.marketplace); + const useParam = useSearchParams(); + + const [currentCourses, setCurrentCourses] = useState([]); + const [currentTitle, setCurrentTitle] = useState(''); + + useEffect(() => { + const userId = localStorage.getItem('userId') ?? ''; + const type = useParam.get('type'); + if (!savedCourses || !mostPopularCourses || !recommendedCourses) { + dispatch(getMarketplaceCourses(userId)); + } + if (type === 'popular') { + setCurrentCourses(mostPopularCourses); + setCurrentTitle('Most Popular Courses'); + } else if (type === 'saved') { + setCurrentCourses(savedCourses); + setCurrentTitle('Saved Courses'); + } else { + setCurrentCourses(recommendedCourses); + setCurrentTitle('Recommended Courses'); + } + }, [ + dispatch, + recommendedCourses, + mostPopularCourses, + savedCourses, + useParam, + ]); + + return ( +
+ {isLoading && ( +
+ +
+ )} + {isError && ( +
+ Error... +
+ )} + + {!isLoading && !isError && ( +
+ +
+ {currentCourses?.length > 0 ? ( + currentCourses?.map((course) => { + return ( + + ); + }) + ) : ( +
+ +
+ )} +
+
+ )} +
+ ); +}; +export default Courses; diff --git a/src/app/completed-course/layout.tsx b/src/app/completed-course/layout.tsx new file mode 100644 index 0000000..c6ee683 --- /dev/null +++ b/src/app/completed-course/layout.tsx @@ -0,0 +1,16 @@ +'use client'; +import * as React from 'react'; + +import TitleNavbar from '@/components/navbar/TitleNavbar'; +import PullRefresh from '@/components/PullToRefresh'; + +export default function Layout({ children }: { children: React.ReactNode }) { + return ( + + <> + + {children} + + + ); +} diff --git a/src/app/completed-course/page.tsx b/src/app/completed-course/page.tsx new file mode 100644 index 0000000..f4a9975 --- /dev/null +++ b/src/app/completed-course/page.tsx @@ -0,0 +1,34 @@ +'use client'; +import { useEffect } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; + +import SingleCompletedCourse from '@/components/Course/SingleCompletedCourse'; +import { outfit } from '@/components/FontFamily'; + +import { + CompletedCourseType, + getCompletedCourse, +} from '@/redux/completedCourse/action'; +import { AppDispatch, RootState } from '@/redux/store'; + +const CompletedCourse = () => { + const dispatch: AppDispatch = useDispatch(); + const { courses } = useSelector((state: RootState) => state?.completedCourse); + + const courseList = (courses ?? []).filter( + (item: CompletedCourseType) => item?.status == 'COMPLETED' + ); + + useEffect(() => { + const userId = localStorage.getItem('userId') || ''; + dispatch(getCompletedCourse(userId)); + }, [dispatch]); + return ( +
+ {courseList?.map((course: CompletedCourseType, index: number) => ( + + ))} +
+ ); +}; +export default CompletedCourse; diff --git a/src/app/components/Spinner.tsx b/src/app/components/Spinner.tsx new file mode 100644 index 0000000..d04d3e3 --- /dev/null +++ b/src/app/components/Spinner.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +const Spinner = ({ classes = 'h-12 w-12' }: { classes?: string }) => { + { + return ( +
+ + Loading... +
+ ); + } +}; +export default Spinner; diff --git a/src/app/course-description/[id]/page.tsx b/src/app/course-description/[id]/page.tsx new file mode 100644 index 0000000..e4c2900 --- /dev/null +++ b/src/app/course-description/[id]/page.tsx @@ -0,0 +1,321 @@ +'use client'; +import Image from 'next/image'; +import { useRouter } from 'next/navigation'; +import { useState } from 'react'; +import { BsBookmark, BsFillBookmarkFill, BsShare } from 'react-icons/bs'; +import { GoPeople } from 'react-icons/go'; +import { MdOutlineKeyboardArrowLeft } from 'react-icons/md'; +import { useDispatch, useSelector } from 'react-redux'; +import { toast } from 'react-toastify'; + +import ButtonFill from '@/components/buttons/ButtonFill'; +import Competencies from '@/components/Competencies'; +import { outfit } from '@/components/FontFamily'; +import ColoredText from '@/components/heading/ColoredText'; +import Overview from '@/components/Overview'; +import BasicPopup from '@/components/popUp/BasicPopup'; +import ButtonPopup from '@/components/popUp/ButtonPopup'; + +import { + getPurchaseCourseStatus, + purchasesACourse, + removeCourse, + saveACourse, +} from '@/redux/coursesDescription/action'; +import { + PURCHASE_COURSE_SUCCESS, + SAVE_COURSE_SUCCESS, + UNSAVE_COURSE_SUCCESS, +} from '@/redux/coursesDescription/type'; +import { getMarketplaceCourses } from '@/redux/marketplace/action'; +import { AppDispatch, RootState } from '@/redux/store'; + +import { EditIcon, Star } from '~/svg'; + +export type SingleCourseType = { + id: number; + title: string; + description: string; + courseLink: string; + imgLink: string; + credits: number; + language: string[]; + duration: number; + competency: { + [key: string]: string[]; + }; + author: string; + avgRating: number; + updatedAt: string; + providerName: string; + numOfUsers: number; + providerId: string; +}; + +const CourseDescription = () => { + const userId = localStorage.getItem('userId') ?? ''; + const dispatch: AppDispatch = useDispatch(); + const router = useRouter(); + const [showPopUp, setShowPopUp] = useState(false); + const [DetailsPopUp, setDetailsPopUp] = useState(false); + const [option, setOption] = useState('overview'); + + const { saveCourseStatus, purchaseCourseStatus, singleCourse, courseLink } = + useSelector((state: RootState) => state?.singleCourse); + + const purchaseCourse = async () => { + const payload = { + courseId: singleCourse?.courseId, + title: singleCourse?.title, + description: singleCourse?.description, + credits: singleCourse?.credits, + imageLink: singleCourse?.imageLink + ? singleCourse?.imageLink + : singleCourse?.imgLink, + language: singleCourse?.language, + courseLink: singleCourse?.courseLink, + providerName: singleCourse?.providerName, + avgRating: singleCourse?.avgRating, + competency: singleCourse?.competency, + providerId: singleCourse?.providerId, + author: singleCourse?.author, + bppId: singleCourse?.bppId, + bppUri: singleCourse?.bppUri, + }; + + dispatch(purchasesACourse(userId, payload)).then((res: unknown) => { + if ((res as { type?: string })?.type === PURCHASE_COURSE_SUCCESS) { + toast.success('course purchase successfully', { + draggable: false, + }); + dispatch(getMarketplaceCourses(userId)); + setShowPopUp(false); + } + }); + }; + + const handleCourseContinue = () => { + if (courseLink) { + window.open(courseLink, '_blank'); + } else { + // if course link is null + dispatch(getPurchaseCourseStatus(userId, singleCourse?.courseId)); + toast.warn('updating your course please wait', { + draggable: false, + }); + } + }; + + const handleSavedIconClick = async () => { + if (saveCourseStatus) { + dispatch(removeCourse(userId, singleCourse?.courseId)).then( + (res: unknown) => { + if ((res as { type?: string })?.type === UNSAVE_COURSE_SUCCESS) { + toast.success('course unsaved successfully', { + draggable: false, + }); + dispatch(getMarketplaceCourses(userId)); + } + } + ); + } else { + const payload = { + courseId: singleCourse?.courseId, + title: singleCourse?.title, + description: singleCourse?.description, + credits: singleCourse?.credits, + imageLink: singleCourse?.imageLink + ? singleCourse?.imageLink + : singleCourse?.imgLink, + language: singleCourse?.language, + courseLink: singleCourse?.courseLink, + providerName: singleCourse?.providerName, + author: singleCourse?.author, + avgRating: singleCourse?.avgRating, + competency: singleCourse?.competency, + bppId: singleCourse?.bppId, + bppUri: singleCourse?.bppUri, + }; + + dispatch(saveACourse(userId, payload)).then((res: unknown) => { + if ((res as { type?: string })?.type === SAVE_COURSE_SUCCESS) { + toast.success('course saved successfully', { + draggable: false, + }); + dispatch(getMarketplaceCourses(userId)); + } + }); + } + }; + + return ( +
+ {/* buy course popup */} + {showPopUp && ( + + )} + {/* author Details popup */} + {DetailsPopUp && ( + + )} + {/* header */} +
+
router.push('/marketplace')} + > + +
+
+
+ {saveCourseStatus ? ( + + ) : ( + + )} + {/* or */} +
+
+ +
+
+
+ {/* description */} +
+ course-description-image +

+ {singleCourse?.title} +

+
setDetailsPopUp(true)} + > + + + {singleCourse?.providerName || 'DUMMY PROVIDER'} + +
+
+ {singleCourse?.language?.map((item: string, index: number) => ( + + ))} +
+
+

+ Cr. {singleCourse?.credits} +

+

+ {singleCourse?.avgRating !== null && + singleCourse?.avgRating !== undefined && ( + <> + {singleCourse?.avgRating}{' '} + + + + + )} +

+
+
+ {/* member tab */} +
+ +

+ {singleCourse?.numberOfPurchases + ? singleCourse?.numberOfPurchases + : singleCourse?.numOfUsers + ? singleCourse?.numOfUsers + : 0}{' '} + Members +

+
+
+ {/* Overview and competency */} + +
+
+
setOption('overview')} + > +

+ Overview +

+
+
setOption('competencies')} + > +

+ Competencies +

+
+
+ {/* two component */} +
+ {option === 'overview' && ( + + )} + {option === 'competencies' && ( + + )} +
+ {/* bottom button */} +
+ + purchaseCourseStatus ? handleCourseContinue() : setShowPopUp(true) + } + classes='flex-grow h-[45px] bg-[#385B8B] text-[#fff] mt-5' + > + {purchaseCourseStatus + ? 'Continue' + : `Buy Now Cr. ${singleCourse?.credits}`} + +
+
+
+ ); +}; +export default CourseDescription; diff --git a/src/app/course-description/layout.tsx b/src/app/course-description/layout.tsx new file mode 100644 index 0000000..bdb9a2e --- /dev/null +++ b/src/app/course-description/layout.tsx @@ -0,0 +1,14 @@ +'use client'; +import * as React from 'react'; + +import PullRefresh from '@/components/PullToRefresh'; + +export default function Layout({ children }: { children: React.ReactNode }) { + return ( +
+ + <>{children} + +
+ ); +} diff --git a/src/app/error/DataNotFound/layout.tsx b/src/app/error/DataNotFound/layout.tsx new file mode 100644 index 0000000..bb9e3d8 --- /dev/null +++ b/src/app/error/DataNotFound/layout.tsx @@ -0,0 +1,17 @@ +import { Metadata } from 'next'; +import * as React from 'react'; + +import '@/styles/colors.css'; + +export const metadata: Metadata = { + title: 'error Screen', + description: 'error Screen if the user is not able to fetch the data', +}; + +export default function ComponentsLayout({ + children, +}: { + children: React.ReactNode; +}) { + return <>{children}; +} diff --git a/src/app/error/DataNotFound/page.tsx b/src/app/error/DataNotFound/page.tsx new file mode 100644 index 0000000..735425d --- /dev/null +++ b/src/app/error/DataNotFound/page.tsx @@ -0,0 +1,34 @@ +'use client'; +import React from 'react'; + +import TextButton from '@/components/buttons/TextButton'; +import { outfit } from '@/components/FontFamily'; + +import NotFoundIcon from '~/svg/NotFoundIcon.svg'; + +const Page = () => { + const handleRefresh = () => { + window.location.href = '/'; + }; + return ( +
+

Oops!

+
+ +
+

+ Not able to fetch data +
+ Some connection Error Happened! +

+ + Try again + + <> +
+ ); +}; + +export default Page; diff --git a/src/app/layout.tsx b/src/app/layout.tsx index c0dba01..8bc8f61 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,45 +1,48 @@ import { Metadata } from 'next'; import * as React from 'react'; +import { ToastContainer } from 'react-toastify'; import '@/styles/globals.css'; // !STARTERCONF This is for demo purposes, remove @/styles/colors.css import immediately import '@/styles/colors.css'; +import 'react-toastify/dist/ReactToastify.css'; -import { siteConfig } from '@/constant/config'; +import ConnectionCheckWrapper from '@/components/ErrorScreen/ConnectionCheckWrapper'; + +import ReduxProvider from '@/redux/Provider'; // !STARTERCONF Change these default meta // !STARTERCONF Look at @/constant/config to change them export const metadata: Metadata = { - title: { - default: siteConfig.title, - template: `%s | ${siteConfig.title}`, - }, - description: siteConfig.description, + title: 'Compass Marketplace demo', + + description: + 'Marketplace portal to upskill themselves according to their competency.', robots: { index: true, follow: true }, // !STARTERCONF this is the default favicon, you can generate your own from https://realfavicongenerator.net/ // ! copy to /favicon folder icons: { - icon: '/favicon/favicon.ico', - shortcut: '/favicon/favicon-16x16.png', - apple: '/favicon/apple-touch-icon.png', - }, - manifest: `/favicon/site.webmanifest`, - openGraph: { - url: siteConfig.url, - title: siteConfig.title, - description: siteConfig.description, - siteName: siteConfig.title, - images: [`${siteConfig.url}/images/og.jpg`], - type: 'website', - locale: 'en_US', - }, - twitter: { - card: 'summary_large_image', - title: siteConfig.title, - description: siteConfig.description, - images: [`${siteConfig.url}/images/og.jpg`], - // creator: '@th_clarence', + icon: '/favicon/samagra_logo.jpg', + shortcut: '/favicon/samagra_logo.jpg', + apple: '/favicon/samagra_logo.jpg', }, + // manifest: `/favicon/site.webmanifest`, + // openGraph: { + // url: siteConfig.url, + // title: siteConfig.title, + // description: siteConfig.description, + // siteName: siteConfig.title, + // images: [`${siteConfig.url}/images/og.jpg`], + // type: 'website', + // locale: 'en_US', + // }, + // twitter: { + // card: 'summary_large_image', + // title: siteConfig.title, + // description: siteConfig.description, + // images: [`${siteConfig.url}/images/og.jpg`], + // // creator: '@th_clarence', + // }, // authors: [ // { // name: 'Theodorus Clarence', @@ -55,7 +58,28 @@ export default function RootLayout({ }) { return ( - {children} + + + + <> + {children} + + + + + ); } diff --git a/src/app/marketplace/layout.tsx b/src/app/marketplace/layout.tsx new file mode 100644 index 0000000..d09da22 --- /dev/null +++ b/src/app/marketplace/layout.tsx @@ -0,0 +1,22 @@ +'use client'; +import * as React from 'react'; + +// import Footer from '@/components/navbar/Footer'; +import TopNavbar from '@/components/navbar/TopNavbar'; +import PullRefresh from '@/components/PullToRefresh'; + +export default function Layout({ children }: { children: React.ReactNode }) { + return ( +
+ + <> + + {children} + {/*
*/} + + +
+ ); +} diff --git a/src/app/marketplace/page.tsx b/src/app/marketplace/page.tsx new file mode 100644 index 0000000..d96152c --- /dev/null +++ b/src/app/marketplace/page.tsx @@ -0,0 +1,66 @@ +'use client'; +import Link from 'next/link'; +import { useSelector } from 'react-redux'; +import 'swiper/css'; + +import CourseBox from '@/components/Course/CourseBox'; +import { outfit } from '@/components/FontFamily'; +import Heading from '@/components/heading/Heading'; +import SeeAll from '@/components/heading/SeeAll'; +import UnclickableSearchInput from '@/components/Input/UnclickableSearchInput'; +import SwiperDiv from '@/components/SwiperDiv'; + +import { RootState } from '@/redux/store'; + +const MarketPlace = () => { + const { savedCourses, mostPopularCourses, recommendedCourses } = useSelector( + (state: RootState) => state?.marketplace + ); + const { userDetails } = useSelector((state: RootState) => state?.userDetails); + + return ( +
+
+ +

+ Let’s Improve Your{' '} + Competency! +

+ {/* serach bar */} +
+ + + +
+
+ + +
+
+ +
+
+ {/* Recommended course */} + + {/* most popular course */} + + {/* saved course */} + +
+ ); +}; +export default MarketPlace; diff --git a/src/app/not-found.tsx b/src/app/not-found.tsx index 9598fe5..6aea5a7 100644 --- a/src/app/not-found.tsx +++ b/src/app/not-found.tsx @@ -1,6 +1,9 @@ import { Metadata } from 'next'; import * as React from 'react'; -import { RiAlarmWarningFill } from 'react-icons/ri'; + +import { outfit } from '@/components/FontFamily'; + +import ErrorLogo from '~/svg/errorLogo.svg'; export const metadata: Metadata = { title: 'Not Found', @@ -10,13 +13,22 @@ export default function NotFound() { return (
-
- -

Page Not Found

- Back to home +
+ + +

Something went wrong!

+

+ We encountered an error while trying to connect with our server. + Please try after sometime. +

+ + Back to home +
diff --git a/src/app/notifications/layout.tsx b/src/app/notifications/layout.tsx new file mode 100644 index 0000000..a18d9a2 --- /dev/null +++ b/src/app/notifications/layout.tsx @@ -0,0 +1,16 @@ +'use client'; +import * as React from 'react'; + +import TitleNavbar from '@/components/navbar/TitleNavbar'; +import PullRefresh from '@/components/PullToRefresh'; + +export default function Layout({ children }: { children: React.ReactNode }) { + return ( + + <> + + {children} + + + ); +} diff --git a/src/app/notifications/page.tsx b/src/app/notifications/page.tsx new file mode 100644 index 0000000..c53dd3e --- /dev/null +++ b/src/app/notifications/page.tsx @@ -0,0 +1,109 @@ +'use client'; +import { useEffect } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; + +import { outfit } from '@/components/FontFamily'; + +import Spinner from '@/app/components/Spinner'; +import { getAllNotifications } from '@/redux/notification/action'; +import { AppDispatch, RootState } from '@/redux/store'; + +export type NotificationType = { + id: number; + link: string; + status: string; + text: string; + createdAt: string; +}; + +const Notifications = () => { + const dispatch: AppDispatch = useDispatch(); + const { + notificationData, + isLoading, + isError, + }: { + notificationData: NotificationType[]; + isLoading: boolean; + isError: boolean; + } = useSelector((state: RootState) => state.notification); + + const viewedNotifications: NotificationType[] = notificationData?.filter( + (notification: NotificationType) => notification.status === 'VIEWED' + ); + const unviewedNotifications: NotificationType[] = notificationData?.filter( + (notification: NotificationType) => notification.status !== 'VIEWED' + ); + + useEffect(() => { + const userId = localStorage.getItem('userId') ?? ''; + dispatch(getAllNotifications(userId)); + }, [dispatch]); + + return ( +
+ {isLoading && ( +
+ +
+ )} + {isError && ( +
+ Error... +
+ )} + {!isLoading && !isError && ( +
+ {/* unviewed */} + {unviewedNotifications?.length > 0 && + unviewedNotifications?.map((notification) => { + const createdAtDate = new Date(notification?.createdAt); + + const formattedDate = new Intl.DateTimeFormat('en-US', { + day: 'numeric', + month: 'short', + year: 'numeric', + }).format(createdAtDate); + + return ( +
+

+ {notification?.text} +

+

+ {formattedDate} +

+
+
+ ); + })} + + {/* viewed */} + {viewedNotifications?.map((notification) => { + const createdAtDate = new Date(notification?.createdAt); + + const formattedDate = new Intl.DateTimeFormat('en-US', { + day: 'numeric', + month: 'short', + year: 'numeric', + }).format(createdAtDate); + + return ( +
+

+ {notification?.text} +

+

+ {formattedDate} +

+
+
+ ); + })} +
+ )} +
+ ); +}; + +export default Notifications; diff --git a/src/app/ongoing-courses/layout.tsx b/src/app/ongoing-courses/layout.tsx new file mode 100644 index 0000000..efd0776 --- /dev/null +++ b/src/app/ongoing-courses/layout.tsx @@ -0,0 +1,17 @@ +'use client'; +import * as React from 'react'; + +import TitleNavbar from '@/components/navbar/TitleNavbar'; +import PullRefresh from '@/components/PullToRefresh'; + +export default function Layout({ children }: { children: React.ReactNode }) { + return ( + + <> + {' '} + + {children} + + + ); +} diff --git a/src/app/ongoing-courses/page.tsx b/src/app/ongoing-courses/page.tsx new file mode 100644 index 0000000..c54226d --- /dev/null +++ b/src/app/ongoing-courses/page.tsx @@ -0,0 +1,59 @@ +'use client'; +import { useSelector } from 'react-redux'; +import 'swiper/css'; + +import NoCoursesFound from '@/components/Course/NoCoursesFound'; +import SwipeSlide from '@/components/SwipeSlide'; + +import { CompetencyType } from '@/redux/marketplace/marketplaceReducer'; +import { RootState } from '@/redux/store'; + +export type OnGoingCoursesType = { + id: number; + courseId: number; + becknTransactionId: string; + consumerId: string; + feedback: string; + purchasedAt: Date | undefined | string; + rating: number | null; + status: string; + walletTransactionId: number; + CourseInfo: { + title: string; + description: string; + credits: number; + imageLink: string; + language: string[]; + courseLink: string; + providerName: string; + author: string; + avgRating: number; + bppUrl: string; + competency: CompetencyType[]; + courseId: number; + numberOfPurchases: number; + }; +}; + +const OnGoingCourses = () => { + const { ongoingCourses } = useSelector( + (state: RootState) => state?.marketplace + ); + + return ( +
+ {ongoingCourses && ongoingCourses?.length > 0 ? ( + ongoingCourses?.map((course: OnGoingCoursesType) => ( +
+ +
+ )) + ) : ( +
+ +
+ )} +
+ ); +}; +export default OnGoingCourses; diff --git a/src/app/page.tsx b/src/app/page.tsx index 46c0560..b7b86a0 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,12 +1,14 @@ 'use client'; import Head from 'next/head'; +import { useRouter, useSearchParams } from 'next/navigation'; import * as React from 'react'; +import { useDispatch } from 'react-redux'; -import ArrowLink from '@/components/links/ArrowLink'; -import ButtonLink from '@/components/links/ButtonLink'; -import UnderlineLink from '@/components/links/UnderlineLink'; -import UnstyledLink from '@/components/links/UnstyledLink'; +import { getMarketplaceCourses } from '@/redux/marketplace/action'; +import { MARKETPLACE_SUCCESS } from '@/redux/marketplace/type'; +import { AppDispatch } from '@/redux/store'; +import { getUserDetails } from '@/redux/userDetails/action'; /** * SVGR Support @@ -15,55 +17,50 @@ import UnstyledLink from '@/components/links/UnstyledLink'; * You can override the next-env if the type is important to you * @see https://stackoverflow.com/questions/68103844/how-to-override-next-js-svg-module-declaration */ -import Logo from '~/svg/Logo.svg'; // !STARTERCONF -> Select !STARTERCONF and CMD + SHIFT + F // Before you begin editing, follow all comments with `STARTERCONF`, // to customize the default configuration. export default function HomePage() { + const searchParams = useSearchParams(); + const router = useRouter(); + const dispatch: AppDispatch = useDispatch(); + + React.useEffect(() => { + let userId = localStorage.getItem('userId') || ''; + const queryId = searchParams.get('userId') || ''; + if (queryId.trim() !== '') { + userId = queryId; + localStorage.setItem('userId', queryId); + } + dispatch(getUserDetails(userId)); + dispatch(getMarketplaceCourses(userId)).then((res: unknown) => { + if ((res as { type?: string })?.type === MARKETPLACE_SUCCESS) { + router.push('/marketplace'); + } + }); + }, [dispatch, searchParams, router]); return (
- Hi + Compass Marketplace demo + + +
-
- -

Next.js + Tailwind CSS + TypeScript Starter

-

- A starter for Next.js, Tailwind CSS, and TypeScript with Absolute - Import, Seo, Link component, pre-configured with Husky{' '} -

-

- - See the repository - +

+
+

+ Loading MarketPlace...

- - - See all components - - - - {/* eslint-disable-next-line @next/next/no-img-element */} - Deploy with Vercel - - -
- © {new Date().getFullYear()} By{' '} - - Theodorus Clarence - -
diff --git a/src/app/purchase-history/layout.tsx b/src/app/purchase-history/layout.tsx new file mode 100644 index 0000000..13a249d --- /dev/null +++ b/src/app/purchase-history/layout.tsx @@ -0,0 +1,14 @@ +'use client'; +import * as React from 'react'; + +import PullRefresh from '@/components/PullToRefresh'; + +export default function Layout({ children }: { children: React.ReactNode }) { + return ( +
+ + <>{children} + +
+ ); +} diff --git a/src/app/purchase-history/page.tsx b/src/app/purchase-history/page.tsx new file mode 100644 index 0000000..0df0f55 --- /dev/null +++ b/src/app/purchase-history/page.tsx @@ -0,0 +1,126 @@ +'use client'; +import Link from 'next/link'; +import { useEffect } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; + +import { outfit } from '@/components/FontFamily'; +import Heading from '@/components/heading/Heading'; + +import Spinner from '@/app/components/Spinner'; +import { getPurchaseHistory } from '@/redux/purchaseHistory/action'; +import { AppDispatch, RootState } from '@/redux/store'; + +import { LeftArrow, Wallet } from '~/svg'; + +export type TransectionType = { + id: number; + credits: number; + title: string; + author: string; + purchasedAt: string; +}; + +export type ConsumerCourse = { + id: number; + purchasedAt?: string; + CourseInfo: { + title: string; + credits: number; + providerName?: string; + }; +}; + +const PurchaseHistory = () => { + const userId = localStorage.getItem('userId') ?? ''; + const { walletBalance, purchaseHistory, isLoading, isError } = useSelector( + (state: RootState) => state.purchaseHistory + ); + const dispatch: AppDispatch = useDispatch(); + + useEffect(() => { + dispatch(getPurchaseHistory(userId)); + }, [dispatch, userId]); + + return ( +
+ {isLoading && ( +
+ +
+ )} + {isError && ( +
+ Error... +
+ )} + {!isLoading && !isError && ( +
+ {/* top balance section */} +
+
+
+ + + + +

+ Wallet Balance +

+
+ +

+ {walletBalance} +

+
+
+ +
+
+ {/* heading */} +
+ +
+ {/* transection details */} + +
+ {purchaseHistory?.map((transection: TransectionType) => { + const purchasedDate = new Date(transection?.purchasedAt); + const formattedDate = purchasedDate.toLocaleDateString('en-US', { + month: 'short', + day: 'numeric', + year: 'numeric', + }); + + return ( +
+
+

+ {transection?.title} +

+

+ - {transection?.credits} +

+
+
+

+ {transection?.author} +

+

+ {formattedDate} +

+
+ +
+
+ ); + })} +
+
+ )} +
+ ); +}; +export default PurchaseHistory; diff --git a/src/app/search/layout.tsx b/src/app/search/layout.tsx new file mode 100644 index 0000000..6a36c98 --- /dev/null +++ b/src/app/search/layout.tsx @@ -0,0 +1,12 @@ +'use client'; +import * as React from 'react'; + +import PullRefresh from '@/components/PullToRefresh'; + +export default function Layout({ children }: { children: React.ReactNode }) { + return ( + + <>{children} + + ); +} diff --git a/src/app/search/page.tsx b/src/app/search/page.tsx new file mode 100644 index 0000000..aa2adf8 --- /dev/null +++ b/src/app/search/page.tsx @@ -0,0 +1,275 @@ +'use client'; +import { useState } from 'react'; +import { RxCross1 } from 'react-icons/rx'; +import { useDispatch, useSelector } from 'react-redux'; +import { toast } from 'react-toastify'; + +import CourseBox from '@/components/Course/CourseBox'; +import CourseCard from '@/components/Course/CourseCard'; +import FilterPage from '@/components/FilterPage'; +import Heading from '@/components/heading/Heading'; +import SearchInput from '@/components/Input/SearchInput'; +import SearchTopbar from '@/components/navbar/SearchTopbar'; + +import { CourseType } from '@/redux/marketplace/marketplaceReducer'; +import { getSearchCourses } from '@/redux/searchCourses/action'; +import { AppDispatch, RootState } from '@/redux/store'; + +import { NotFound } from '~/svg'; + +const getInitialValue2 = () => { + return { + competencies: '', + courseProviders: null, + language: null, + sortBy: '', + }; +}; + +export type filterObjType = { + competencies: string; + courseProviders: string[] | null; + language: string[] | null; + sortBy: string; +}; + +export type optionType = { + competency: { label: string; value: string }[]; + language: { label: string; value: string }[]; + courseProvider: { label: string; value: string }[]; +}; + +// will filter data +const filterData = (data: CourseType[], filterObj: filterObjType) => { + // if there is no filter applied + if ( + Object.values(filterObj)?.every( + (element) => element === null || element === '' + ) + ) { + return data; + } + const { competencies, courseProviders, language, sortBy } = filterObj; + + let filteredResponse = data?.filter((course: CourseType) => { + const competencyMatch = + !competencies || + course?.competency?.some( + (item) => item?.name?.toLowerCase() == competencies?.toLowerCase() + ); + const languageMatch = + language?.length === 0 || + !language || + language?.some((lang: string) => + course?.language + ?.map((item) => item?.toLowerCase()) + ?.includes(lang?.toLowerCase()) + ); + + const courseProviderMatch = + courseProviders?.length === 0 || + !courseProviders || + courseProviders?.some( + (provider: string) => + course?.providerName?.toLowerCase() === provider?.toLowerCase() + ); + + return competencyMatch && languageMatch && courseProviderMatch; + }); + if (sortBy === 'Low Price') { + filteredResponse = filteredResponse.sort((a, b) => a.credits - b.credits); + } + if (sortBy === 'High Price') { + filteredResponse = filteredResponse.sort((a, b) => b.credits - a.credits); + } + return filteredResponse; +}; + +const SearchPage = () => { + // will set text to search courses + const [searchText, setSearchText] = useState(''); + + // will set data to filter courses + const [filterObj, setFilterObj] = useState(getInitialValue2()); + + // to dispatch action for api call + const dispatch: AppDispatch = useDispatch(); + + // will get most popular course data + const { mostPopularCourses } = useSelector( + (state: RootState) => state?.marketplace + ); + + // will get searched courses data + const { searchCourses } = useSelector( + (state: RootState) => state?.searchCourses + ); + + // this method will apply filter to fetched data + const coursesList = filterData(searchCourses, filterObj); + + // will show popular courses initial when true + const [showMostPopularCourses, setShowMostPopularCourses] = + useState(true); + + // will show filter input fields if true + const [isFilterOpen, setFilterOpen] = useState(false); + + // will show filters list in ui + const [selectedOption, setSelectedOption] = useState([]); + + // will set all filters applied eg '1 language' '2 course provider' etc + const SearchFilterOptions = () => { + const { competencies, courseProviders, language, sortBy } = filterObj; + setSelectedOption([]); + if (competencies) setSelectedOption((prev) => [...prev, competencies]); + if (courseProviders?.length) + setSelectedOption((prev) => [ + ...prev, + `${courseProviders?.length} course provider`, + ]); + if (language?.length) + setSelectedOption((prev) => [...prev, `${language.length} language`]); + if (sortBy) { + setSelectedOption((prev) => [...prev, sortBy]); + } + }; + + // will fetch data and hide popular courses + const handleSearchCourse = async () => { + if (searchText) { + dispatch(getSearchCourses(searchText)); + setShowMostPopularCourses(false); + } else { + toast.error('please enter course name', { + draggable: false, + }); + } + }; + + // will remove search field + const handleCrossIcon = () => { + setShowMostPopularCourses(true); + setSearchText(''); + }; + + // will remove filters and set the filters to null + const handleDeleteSelectedOption = (indexToRemove: number) => { + const updatedOptions = [...selectedOption]; + const removeFilter = updatedOptions.splice(indexToRemove, 1); + if (removeFilter?.join()?.includes('High Price' || 'Low Price')) { + setFilterObj((pre) => { + return { + ...pre, + sortBy: '', + }; + }); + } else if (removeFilter?.join()?.includes('language')) { + setFilterObj((pre) => { + return { + ...pre, + language: null, + }; + }); + } else if (removeFilter?.join()?.includes('provider')) { + setFilterObj((pre) => { + return { + ...pre, + courseProviders: null, + }; + }); + } else { + setFilterObj((pre) => { + return { + ...pre, + competencies: '', + }; + }); + } + setSelectedOption(updatedOptions); + }; + + // filter input fields + if (isFilterOpen) { + return ( + + ); + } + + return ( +
+ + setFilterOpen(true)} + /> + {selectedOption?.length != 0 && ( +
+

Filtered by:

+ {selectedOption?.map((option, index) => { + return ( +
+

{option}

+ handleDeleteSelectedOption(index)} + style={{ cursor: 'pointer' }} + /> +
+ ); + })} +
+ )} + + {/* either */} + {showMostPopularCourses ? ( + + ) : coursesList?.length != 0 ? ( +
+
+ +
+
+ {coursesList?.map((course: CourseType, index: number) => { + return ; + })} +
+
+ ) : ( +
+
+ +
+
+

+ Search not found +

+

+ Please activate the property name search service that is available + correctly +

+
+
+ )} +
+ ); +}; +export default SearchPage; diff --git a/src/components/Competencies.tsx b/src/components/Competencies.tsx new file mode 100644 index 0000000..8f0c6c5 --- /dev/null +++ b/src/components/Competencies.tsx @@ -0,0 +1,19 @@ +import SingleCompetency from '@/components/course-description/SingleCompetency'; + +import { CompetencyType } from '@/redux/marketplace/marketplaceReducer'; + +const Competencies = ({ competency }: { competency: CompetencyType[] }) => { + return ( +
+ {competency?.map((item) => { + return ( + + ); + })} +
+ ); +}; +export default Competencies; diff --git a/src/components/Course/CourseBox.tsx b/src/components/Course/CourseBox.tsx new file mode 100644 index 0000000..904dca2 --- /dev/null +++ b/src/components/Course/CourseBox.tsx @@ -0,0 +1,26 @@ +import CourseSlides from '@/components/Course/CourseSlides'; +import Heading from '@/components/heading/Heading'; +import SeeAll from '@/components/heading/SeeAll'; + +import { CourseType } from '@/redux/marketplace/marketplaceReducer'; + +const CourseBox = ({ + heading, + CoursesList, + handleSeeAllButtonClick, +}: { + heading: string; + CoursesList: CourseType[]; + handleSeeAllButtonClick: string; +}) => { + return ( +
+
+ + +
+ +
+ ); +}; +export default CourseBox; diff --git a/src/components/Course/CourseCard.tsx b/src/components/Course/CourseCard.tsx new file mode 100644 index 0000000..18640c0 --- /dev/null +++ b/src/components/Course/CourseCard.tsx @@ -0,0 +1,122 @@ +'use client'; +import Image from 'next/image'; +import { useRouter } from 'next/navigation'; +import { useDispatch } from 'react-redux'; + +import { outfit } from '@/components/FontFamily'; + +import { getSaveCourseAndStatus } from '@/redux/coursesDescription/action'; +import { GET_SAVE_COURSE_AND_STATUS_SUCCESS } from '@/redux/coursesDescription/type'; +import { CourseType } from '@/redux/marketplace/marketplaceReducer'; +import { AppDispatch } from '@/redux/store'; + +import ColoredText from '../heading/ColoredText'; + +import { EditIcon, Star } from '~/svg'; + +const CourseCard = ({ courseDetails }: { courseDetails: CourseType }) => { + const router = useRouter(); + + const dispatch: AppDispatch = useDispatch(); + + const handleRoute = () => { + const userId = localStorage.getItem('userId') ?? ''; + dispatch( + getSaveCourseAndStatus(userId, courseDetails?.courseId, courseDetails) + ).then((res: unknown) => { + if ( + (res as { type?: string })?.type === GET_SAVE_COURSE_AND_STATUS_SUCCESS + ) { + router.push(`/course-description/${courseDetails?.courseId}`); + } + }); + }; + + return ( +
+
+
+
+ courseImage +
+
+

+ {courseDetails?.title} +

+
+ {courseDetails?.competency?.map((item, index) => { + if (index < 2) { + return ( +
  • + {item.name} ( + {item?.levels + .map((level) => `L${level.levelNumber}`) + .join(', ')} + ){index == 1 && '....'} +
  • + ); + } + return null; // Skip rendering for keys beyond the first two and the ellipsis + })} +
    +
    + {/* Icon and language list */} +
    +
    +
    + + + {courseDetails?.providerName} + + {courseDetails?.language?.map((item: string, index: number) => ( + + ))} +
    +
    +
    +

    + Cr. {courseDetails?.credits} +

    +

    + {courseDetails?.avgRating !== null && + courseDetails?.avgRating !== undefined && ( + <> + {courseDetails?.avgRating}{' '} + + {' '} + + + )} +

    +
    +
    +
    + ); +}; +export default CourseCard; diff --git a/src/components/Course/CourseSlides.tsx b/src/components/Course/CourseSlides.tsx new file mode 100644 index 0000000..c9dc35a --- /dev/null +++ b/src/components/Course/CourseSlides.tsx @@ -0,0 +1,39 @@ +import { Swiper, SwiperSlide } from 'swiper/react'; +import 'swiper/css'; + +import CourseCard from '@/components/Course/CourseCard'; + +import { CourseType } from '@/redux/marketplace/marketplaceReducer'; + +import NoCoursesFound from './NoCoursesFound'; + +const CourseSlides = ({ CoursesList }: { CoursesList: CourseType[] }) => { + const spaceBetween = CoursesList?.length > 1 ? -10 : 0; + + return ( + <> + {CoursesList?.length > 0 ? ( +
    + + {CoursesList?.map((course) => { + return ( + + + + ); + })} + +
    + ) : ( +
    + +
    + )} + + ); +}; +export default CourseSlides; diff --git a/src/components/Course/NoCoursesFound.tsx b/src/components/Course/NoCoursesFound.tsx new file mode 100644 index 0000000..0bd7c97 --- /dev/null +++ b/src/components/Course/NoCoursesFound.tsx @@ -0,0 +1,18 @@ +import React from 'react'; + +import EmptyBox from '~/svg/emptyBox.svg'; + +const NoCoursesFound = () => { + return ( +
    +
    + +
    +

    + No courses found. +

    +
    + ); +}; + +export default NoCoursesFound; diff --git a/src/components/Course/SingleCompletedCourse.tsx b/src/components/Course/SingleCompletedCourse.tsx new file mode 100644 index 0000000..4eac770 --- /dev/null +++ b/src/components/Course/SingleCompletedCourse.tsx @@ -0,0 +1,68 @@ +'use client'; +import Image from 'next/image'; +import { useState } from 'react'; +import { FaRegStar, FaStar } from 'react-icons/fa'; +import { useDispatch } from 'react-redux'; + +import { + CompletedCourseType, + giveFeedbackRating, +} from '@/redux/completedCourse/action'; +import { AppDispatch } from '@/redux/store'; + +const SingleCompletedCourse = ({ + courseDetail, +}: { + courseDetail: CompletedCourseType; +}) => { + const [start, setStar] = useState(parseInt(courseDetail?.rating ?? 0)); + const dispatch: AppDispatch = useDispatch(); + const handleClick = (index: number) => { + const payload = { + courseInfoId: courseDetail.courseInfoId, + rating: index, + }; + dispatch(giveFeedbackRating(courseDetail.consumerId, payload)); + setStar(index); + }; + return ( +
    + course image +
    +
    +

    + {courseDetail?.CourseInfo?.title} +

    +

    + {courseDetail?.CourseInfo?.author} +

    +
    +
    + {Array.from({ length: start })?.map((_, index) => ( + handleClick(index + 1)} + /> + ))} + {Array.from({ length: 5 - start }).map((_, index) => ( + handleClick(start + index + 1)} + /> + ))} +
    +
    +
    + ); +}; +export default SingleCompletedCourse; diff --git a/src/components/ErrorScreen/ConnectionCheckWrapper.tsx b/src/components/ErrorScreen/ConnectionCheckWrapper.tsx new file mode 100644 index 0000000..4dd957a --- /dev/null +++ b/src/components/ErrorScreen/ConnectionCheckWrapper.tsx @@ -0,0 +1,23 @@ +'use client'; +import React from 'react'; +import { Detector } from 'react-detect-offline'; + +import NoInternetConnectionError from '@/components/ErrorScreen/NoInternetConnectionError'; + +const ConnectionCheckWrapper = ({ + children, +}: { + children: React.ReactNode; +}) => { + return ( +
    + ( + <> {online ? <>{children} : } + )} + /> +
    + ); +}; + +export default ConnectionCheckWrapper; diff --git a/src/components/ErrorScreen/NoInternetConnectionError.tsx b/src/components/ErrorScreen/NoInternetConnectionError.tsx new file mode 100644 index 0000000..602b88a --- /dev/null +++ b/src/components/ErrorScreen/NoInternetConnectionError.tsx @@ -0,0 +1,37 @@ +import React from 'react'; + +import { outfit } from '@/components/FontFamily'; + +import NoInternetErrorIcon from '~/svg/NoInternetErrorIcon.svg'; +const NoInternetConnectionError = () => { + const handleRetry = () => { + window.location.reload(); + }; + + return ( +
    +
    +
    + +

    Oops! no connection

    +

    + There seems to be a problem with your network connection. Please + check your internet connection. +

    + +
    +
    +
    + ); +}; + +export default NoInternetConnectionError; diff --git a/src/components/FilterPage.tsx b/src/components/FilterPage.tsx new file mode 100644 index 0000000..7bd228d --- /dev/null +++ b/src/components/FilterPage.tsx @@ -0,0 +1,114 @@ +'use client'; +import { RxCross2 } from 'react-icons/rx'; + +import ButtonFill from '@/components/buttons/ButtonFill'; +import { outfit } from '@/components/FontFamily'; +import MultipleButton from '@/components/Input/MultipleButton'; +import MultiSelectTag from '@/components/Input/MultiSelectTag'; + +import MultiSelectCreatable from './Input/MultiSelectCreatable'; +import SelectTag from './Input/SelectTag'; +import { + COMPETENCY_OPTIONS, + LANGUAGE_OPTIONS, + PROVIDER_OPTIONS, +} from './options'; +import { filterObjType } from '../app/search/page'; + +const FilterCourse = ({ + filterObj, + setFilterObj, + setFilterOpen, + SearchFilterOptions, + handleFilterCourse, +}: { + filterObj: filterObjType; + setFilterObj: (value: filterObjType) => void; + setFilterOpen: (value: boolean) => void; + SearchFilterOptions: () => void; + handleFilterCourse: () => void; +}) => { + const handleChange = (name: string, value: string[] | string) => { + setFilterObj({ ...filterObj, [name]: value }); + }; + + const handleApplyFilter = () => { + SearchFilterOptions(); + setFilterOpen(false); + handleFilterCourse(); + }; + + return ( +
    + {/* heading */} +
    +

    Filter

    + setFilterOpen(false)} + className='cursor-pointer' + /> +
    + {/* Competencies*/} +
    + + handleChange('competencies', value)} + value={filterObj?.competencies ?? ''} + options={COMPETENCY_OPTIONS} + placeholder='--Select--' + /> +
    + + {/* third party provider*/} + +
    + + handleChange('courseProviders', value)} + value={filterObj?.courseProviders ?? []} + options={PROVIDER_OPTIONS} + placeholder='--Select--' + /> +
    + {/*language*/} + +
    + + handleChange('language', value)} + value={filterObj?.language ?? []} + options={LANGUAGE_OPTIONS} + placeholder='--Select--' + /> +
    + {/*sort by*/} +
    + + handleChange('sortBy', val)} + value={filterObj.sortBy} + /> +
    + +
    + + Apply Filters + +
    +
    + ); +}; +export default FilterCourse; diff --git a/src/components/FontFamily.ts b/src/components/FontFamily.ts new file mode 100644 index 0000000..f38c1f4 --- /dev/null +++ b/src/components/FontFamily.ts @@ -0,0 +1,18 @@ +import { Outfit, Oxanium, Poppins } from 'next/font/google'; + +const oxanium = Oxanium({ + subsets: ['latin'], + weight: ['600'], +}); + +const outfit = Outfit({ + subsets: ['latin'], + weight: ['600', '500', '400'], +}); + +const poppins = Poppins({ + subsets: ['latin'], + weight: ['600'], +}); + +export { outfit, oxanium, poppins }; diff --git a/src/components/Input/MultiSelectCreatable.tsx b/src/components/Input/MultiSelectCreatable.tsx new file mode 100644 index 0000000..45d3d71 --- /dev/null +++ b/src/components/Input/MultiSelectCreatable.tsx @@ -0,0 +1,92 @@ +'use client'; +import React from 'react'; +import { ActionMeta, MultiValue } from 'react-select'; +import CreatableSelect from 'react-select/creatable'; + +export type OptionType = { + label: string; + value: string; +}; + +export type PropsType = { + onChange: (value: string[]) => void; + value: string[]; + options: OptionType[]; + placeholder: string; + errorMessage?: string; + paddingY?: string; + isDisabled?: boolean; +}; + +const MultiSelectCreatable = ({ + options, + onChange, + value, + placeholder, + errorMessage = '', + paddingY = '', + isDisabled = false, +}: PropsType) => { + const handleOption = ( + evt: MultiValue, + action: ActionMeta + ) => { + if ( + action.action === 'select-option' || + action.action === 'create-option' + ) { + onChange(evt?.map((item: OptionType) => item?.value)); + } else if (action.action === 'remove-value') { + if (Array.isArray(value)) { + onChange( + value?.filter((option) => option !== action?.removedValue?.value) + ); + } + } + }; + + return ( +
    + ({ + label: item, + value: item, + }))} + className='basic-multi-select' + classNamePrefix='select' + placeholder={placeholder} + onChange={(evt, action) => { + if (Array.isArray(evt)) { + handleOption(evt, action); + } + }} + styles={{ + input: (base) => ({ + ...base, + 'input:focus': { + boxShadow: 'none', + }, + }), + control: (baseStyles) => ({ + ...baseStyles, + borderColor: errorMessage ? 'red' : '#E3E7EF', + paddingTop: paddingY, + paddingBottom: paddingY, + borderRadius: '8px', + }), + }} + /> + {errorMessage && ( +

    + {errorMessage} +

    + )} +
    + ); +}; + +export default MultiSelectCreatable; diff --git a/src/components/Input/MultiSelectTag.tsx b/src/components/Input/MultiSelectTag.tsx new file mode 100644 index 0000000..7dd582f --- /dev/null +++ b/src/components/Input/MultiSelectTag.tsx @@ -0,0 +1,83 @@ +'use client'; +import React from 'react'; +import Select, { ActionMeta, MultiValue } from 'react-select'; +export type OptionType = { + label: string; + value: string; +}; +export type PropsType = { + onChange: (value: string[]) => void; + value: string[]; + options: OptionType[]; + placeholder: string; + errorMessage?: string; + paddingY?: string; + isDisabled?: boolean; +}; +const MultiSelectTag = ({ + options, + onChange, + value, + placeholder, + errorMessage = '', + paddingY = '', + isDisabled = false, +}: PropsType) => { + const handleOption = ( + evt: MultiValue, + action: ActionMeta + ) => { + if (action.action === 'select-option') { + onChange(evt?.map((item: OptionType) => item?.value)); + } else if (action.action === 'remove-value') { + if (Array.isArray(value)) { + onChange( + value?.filter((option) => option !== action?.removedValue?.value) + ); + } + } + }; + return ( +
    + { + onChange(e?.target?.value), setShowCross(true); + }} + onKeyDown={handleKeyDown} + /> +
    +
    +
    + {value != '' && showCross ? ( +
    handleCrossIcon()} + className='relative inline-block' + > + +
    + ) : ( +
    handleFilterIcon()} + className='relative inline-block cursor-pointer' + > + {selectedOptionCount != 0 && ( +

    + {selectedOptionCount} +

    + )} +
    + +
    +
    + )} +
    +
    + ); +}; + +export default SearchInput; diff --git a/src/components/Input/SelectTag.tsx b/src/components/Input/SelectTag.tsx new file mode 100644 index 0000000..c9c90df --- /dev/null +++ b/src/components/Input/SelectTag.tsx @@ -0,0 +1,69 @@ +'use client'; +import React from 'react'; +import Select, { SingleValue } from 'react-select'; + +export type OptionType = { + label: string; + value: string; +}; + +export type PropsType = { + onChange: (value: string) => void; + value: string; + width?: string; + options: OptionType[]; + placeholder: string; + errorMessage?: string; + paddingY?: string; + isDisabled?: boolean; +}; + +const SelectTag = ({ + options, + onChange, + width = '100%', + value, + placeholder, + errorMessage = '', + paddingY = '', + isDisabled = false, +}: PropsType) => { + return ( +
    + +
    +
    +
    + +
    +
    + + ); +}; + +export default UnclickableSearchInput; diff --git a/src/components/Overview.tsx b/src/components/Overview.tsx new file mode 100644 index 0000000..fc95534 --- /dev/null +++ b/src/components/Overview.tsx @@ -0,0 +1,12 @@ +const Overview = ({ about }: { about: string }) => { + return ( +
    +

    + About Course +

    + +

    {about}

    +
    + ); +}; +export default Overview; diff --git a/src/components/PullToRefresh.tsx b/src/components/PullToRefresh.tsx new file mode 100644 index 0000000..5b89ad7 --- /dev/null +++ b/src/components/PullToRefresh.tsx @@ -0,0 +1,31 @@ +'use client'; +import React from 'react'; +import PullToRefresh from 'react-simple-pull-to-refresh'; +type PropsType = { + children: React.ReactElement; +}; + +const PullRefresh = ({ children }: PropsType) => { + const refreshHandler = async () => { + await new Promise((resolve) => { + setTimeout(() => { + window.location.href = '/'; + resolve; + }, 2000); + }); + }; + + return ( +
    + + {children} + +
    + ); +}; + +export default PullRefresh; diff --git a/src/components/SwipeSlide.tsx b/src/components/SwipeSlide.tsx new file mode 100644 index 0000000..8223fe3 --- /dev/null +++ b/src/components/SwipeSlide.tsx @@ -0,0 +1,56 @@ +import { outfit, poppins } from '@/components/FontFamily'; + +import { OnGoingCoursesType } from '@/app/ongoing-courses/page'; + +const SwipeSlide = ({ course }: { course: OnGoingCoursesType }) => { + return ( +
    +

    + Ongoing +

    +

    + {course?.CourseInfo?.title} +

    +

    + {course?.CourseInfo?.competency?.length > 0 && + course?.CourseInfo?.competency?.map((item, index) => { + if (index < 2) { + return ( +

  • + {item?.name} ( + {item?.levels + .map((level) => `L${level?.levelNumber}`) + .join(', ')} + ),{index == 1 && '....'} +
  • + ); + } + return null; // Skip rendering for keys beyond the first two and the ellipsis + })} +

    +
    +

    + Created by + + {course?.CourseInfo?.providerName} + +

    + + Continue + +
    +
    + ); +}; + +export default SwipeSlide; diff --git a/src/components/SwiperDiv.tsx b/src/components/SwiperDiv.tsx new file mode 100644 index 0000000..67dff87 --- /dev/null +++ b/src/components/SwiperDiv.tsx @@ -0,0 +1,41 @@ +import { useSelector } from 'react-redux'; +import { Pagination } from 'swiper/modules'; +import { Swiper, SwiperSlide } from 'swiper/react'; +import 'swiper/css'; +import 'swiper/css/pagination'; + +import SwipeSlide from '@/components/SwipeSlide'; + +import { OnGoingCoursesType } from '@/app/ongoing-courses/page'; +import { RootState } from '@/redux/store'; + +import NoCoursesFound from './Course/NoCoursesFound'; + +const SwiperDiv = () => { + const { ongoingCourses } = useSelector( + (state: RootState) => state?.marketplace + ); + return ( +
    + {ongoingCourses && ongoingCourses.length > 0 ? ( + + {ongoingCourses?.map((course: OnGoingCoursesType) => ( + + + + ))} + + ) : ( +
    + +
    + )} +
    + ); +}; +export default SwiperDiv; diff --git a/src/components/buttons/ButtonFill.tsx b/src/components/buttons/ButtonFill.tsx new file mode 100644 index 0000000..64580bf --- /dev/null +++ b/src/components/buttons/ButtonFill.tsx @@ -0,0 +1,28 @@ +'use client'; +import React from 'react'; + +export type ButtonType = { + onClick: () => void; + children: React.ReactNode; + classes: string; + disabled?: boolean; +}; + +const ButtonFill = ({ + onClick, + children, + classes, + disabled = false, +}: ButtonType) => { + return ( + + ); +}; + +export default ButtonFill; diff --git a/src/components/buttons/ButtonOutline.tsx b/src/components/buttons/ButtonOutline.tsx new file mode 100644 index 0000000..76018fe --- /dev/null +++ b/src/components/buttons/ButtonOutline.tsx @@ -0,0 +1,17 @@ +'use client'; +import React from 'react'; + +import { ButtonType } from '@/components/buttons/ButtonFill'; + +const ButtonOutline = ({ onClick, children, classes }: ButtonType) => { + return ( + + ); +}; + +export default ButtonOutline; diff --git a/src/components/course-description/SingleCompetency.tsx b/src/components/course-description/SingleCompetency.tsx new file mode 100644 index 0000000..bfcea80 --- /dev/null +++ b/src/components/course-description/SingleCompetency.tsx @@ -0,0 +1,57 @@ +import { useState } from 'react'; +import { BiSolidBarChartAlt2 } from 'react-icons/bi'; +import { MdKeyboardArrowDown, MdKeyboardArrowUp } from 'react-icons/md'; + +import { outfit, poppins } from '@/components/FontFamily'; + +import { LevelsType } from '@/redux/marketplace/marketplaceReducer'; + +type propType = { + name: string; + levels: LevelsType[]; +}; + +const SingleCompetency = ({ competency }: { competency: propType }) => { + const [open, setOpen] = useState(false); + const { name, levels } = competency; + return ( +
    +
    +
    +

    {name}

    +
    setOpen(!open)} + className='cursor-pointer rounded-sm hover:bg-slate-200' + > + {open ? ( + + ) : ( + + )} +
    +
    + {open && ( +
    +
    + + +

    + Level +

    +
    +
      + {levels?.map((level) => { + return ( +
    • + • {level?.name} +
    • + ); + })} +
    +
    + )} +
    +
    + ); +}; +export default SingleCompetency; diff --git a/src/components/heading/ColoredText.tsx b/src/components/heading/ColoredText.tsx new file mode 100644 index 0000000..1e6f75b --- /dev/null +++ b/src/components/heading/ColoredText.tsx @@ -0,0 +1,4 @@ +const ColoredText = ({ text, classes }: { text: string; classes: string }) => { + return
    {text}
    ; +}; +export default ColoredText; diff --git a/src/components/heading/Heading.tsx b/src/components/heading/Heading.tsx new file mode 100644 index 0000000..74a2b66 --- /dev/null +++ b/src/components/heading/Heading.tsx @@ -0,0 +1,10 @@ +import { outfit } from '@/components/FontFamily'; + +const Heading = ({ heading }: { heading: string }) => { + return ( +

    + {heading} +

    + ); +}; +export default Heading; diff --git a/src/components/heading/SeeAll.tsx b/src/components/heading/SeeAll.tsx new file mode 100644 index 0000000..0496082 --- /dev/null +++ b/src/components/heading/SeeAll.tsx @@ -0,0 +1,22 @@ +import Link from 'next/link'; + +import { outfit } from '@/components/FontFamily'; + +const SeeAll = ({ + heading, + redirectTo, +}: { + heading: string; + redirectTo: string; +}) => { + return ( + +

    + {heading} +

    + + ); +}; +export default SeeAll; diff --git a/src/components/navbar/Footer.tsx b/src/components/navbar/Footer.tsx new file mode 100644 index 0000000..f7bdd2f --- /dev/null +++ b/src/components/navbar/Footer.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import { AiFillSetting } from 'react-icons/ai'; +import { HiOutlineUserCircle } from 'react-icons/hi'; + +import { MarketPlaceIcon } from '~/svg'; + +const Footer = () => { + return ( +
    +
    +
    +
    + +
    +
    Marketplace
    +
    +
    +
    + +
    +
    Competency
    +
    +
    +
    + +
    +
    Account
    +
    +
    +
    + ); +}; + +export default Footer; diff --git a/src/components/navbar/SearchTopbar.tsx b/src/components/navbar/SearchTopbar.tsx new file mode 100644 index 0000000..34be599 --- /dev/null +++ b/src/components/navbar/SearchTopbar.tsx @@ -0,0 +1,30 @@ +import Link from 'next/link'; +import React from 'react'; +import { RxCross1 } from 'react-icons/rx'; + +import Heading from '@/components/heading/Heading'; + +const SearchTopbar = ({ + title, + redirectTo, +}: { + title: string; + redirectTo: string; +}) => { + return ( +
    + + +
    + ); +}; + +export default SearchTopbar; diff --git a/src/components/navbar/TitleNavbar.tsx b/src/components/navbar/TitleNavbar.tsx new file mode 100644 index 0000000..58edb32 --- /dev/null +++ b/src/components/navbar/TitleNavbar.tsx @@ -0,0 +1,24 @@ +import { useRouter } from 'next/navigation'; +import React from 'react'; +import { MdOutlineKeyboardArrowLeft } from 'react-icons/md'; + +import Heading from '@/components/heading/Heading'; + +const TitleNavbar = ({ title }: { title: string }) => { + const router = useRouter(); + + return ( +
    + + +
    + ); +}; + +export default TitleNavbar; diff --git a/src/components/navbar/TopNavbar.tsx b/src/components/navbar/TopNavbar.tsx new file mode 100644 index 0000000..9fbcd94 --- /dev/null +++ b/src/components/navbar/TopNavbar.tsx @@ -0,0 +1,31 @@ +import Link from 'next/link'; +import React from 'react'; + +import { oxanium } from '../FontFamily'; + +import { NotificationBell, Wallet } from '~/svg'; + +const TopNavbar = () => { + return ( +
    +
    COMPASS
    +
    + +
    + +
    + + +
    + +
    + +
    +
    + ); +}; + +export default TopNavbar; diff --git a/src/components/options.ts b/src/components/options.ts new file mode 100644 index 0000000..2ca1ecd --- /dev/null +++ b/src/components/options.ts @@ -0,0 +1,72 @@ +export const COMPETENCY_OPTIONS = [ + { + label: 'competency1', + value: 'competency1', + }, + { + label: 'competency2', + value: 'competency2', + }, + { + label: 'competency3', + value: 'competency3', + }, + { + label: 'competency4', + value: 'competency4', + }, + { + label: 'competency5', + value: 'competency5', + }, + { + label: 'Backend Engineering', + value: 'Backend Engineering', + }, + { + label: 'API Development', + value: 'API Development', + }, + { + label: 'Typescript', + value: 'Typescript', + }, +]; + +export const PROVIDER_OPTIONS = [ + { + label: 'my code', + value: 'my code', + }, + { + label: 'Code', + value: 'Code', + }, + { + label: 'Udemy', + value: 'Udemy', + }, + { + label: 'sdf', + value: 'sdf', + }, +]; + +export const LANGUAGE_OPTIONS = [ + { + label: 'en', + value: 'en', + }, + { + label: 'english', + value: 'english', + }, + { + label: 'hindi', + value: 'hindi', + }, + { + label: 'marathi', + value: 'marathi', + }, +]; diff --git a/src/components/popUp/BasicPopup.tsx b/src/components/popUp/BasicPopup.tsx new file mode 100644 index 0000000..ee385e1 --- /dev/null +++ b/src/components/popUp/BasicPopup.tsx @@ -0,0 +1,51 @@ +import { RxCross1 } from 'react-icons/rx'; + +import { SingleCourseType } from '@/app/course-description/[id]/page'; + +const BasicPopup = ({ + setDetailsPopUp, + courseDetails, +}: { + setDetailsPopUp: (value: boolean) => void; + courseDetails: SingleCourseType; +}) => { + const purchasedDate = new Date(courseDetails?.updatedAt); + const formattedDate = purchasedDate.toLocaleDateString('en-US', { + month: 'short', + day: 'numeric', + year: 'numeric', + }); + return ( +
    +
    + {/* pop up height and width and position */} +
    + {/* popUp inside thing */} +
    +
    setDetailsPopUp(false)} + > + +
    +

    + {courseDetails?.title} +

    + +

    + Created by:{' '} + {courseDetails?.providerName} +

    +

    + Author: {courseDetails?.author} +

    +

    + Last Updated On:{' '} + {formattedDate} +

    +
    +
    +
    + ); +}; +export default BasicPopup; diff --git a/src/components/popUp/ButtonPopup.tsx b/src/components/popUp/ButtonPopup.tsx new file mode 100644 index 0000000..3b2971c --- /dev/null +++ b/src/components/popUp/ButtonPopup.tsx @@ -0,0 +1,47 @@ +import ButtonFill from '@/components/buttons/ButtonFill'; + +const ButtonPopup = ({ + setShowPopUp, + purchaseCourse, + credit, +}: { + setShowPopUp: (value: boolean) => void; + purchaseCourse: () => void; + credit: number; +}) => { + return ( +
    +
    + {/* pop up height and width and position */} +
    + {/* popUp inside thing */} +
    +

    + Confirm Your Purchase +

    + +

    + Thank you for choosing us for your learning journey! Cr. {credit}{' '} + will be debited from your wallet for this purchase. +

    +
    + setShowPopUp(false)} + classes='w-[140px] h-[36px] bg-[#EEF5FF] text-[#385B8B]' + > + Close + + purchaseCourse()} + classes='w-[140px] h-[36px] bg-[#385B8B] text-[#fff]' + > + Confirm + +
    +
    +
    +
    + ); +}; + +export default ButtonPopup; diff --git a/src/redux/Provider.tsx b/src/redux/Provider.tsx new file mode 100644 index 0000000..a7e7c20 --- /dev/null +++ b/src/redux/Provider.tsx @@ -0,0 +1,15 @@ +'use client'; +import { Provider } from 'react-redux'; +import { PersistGate } from 'redux-persist/integration/react'; + +import { persistor, store } from './store'; + +const ReduxProvider = ({ children }: { children: React.ReactNode }) => { + return ( + + {children} + + ); +}; + +export default ReduxProvider; diff --git a/src/redux/completedCourse/action.ts b/src/redux/completedCourse/action.ts new file mode 100644 index 0000000..681b6aa --- /dev/null +++ b/src/redux/completedCourse/action.ts @@ -0,0 +1,98 @@ +import { marketBackendUrl } from '@root/config'; +import axios from 'axios'; +import { Dispatch } from 'react'; +import { toast } from 'react-toastify'; + +import { + FEEDBACK_COURSE_REQUEST, + FEEDBACK_COURSE_SUCCESS, + FEEDBACK_FAILURE, + GET_COMPLETED_COURSE_REQUEST, + GET_COMPLETED_COURSE_SUCCESS, + GET_COMPLETED_FAILURE, +} from '@/redux/completedCourse/type'; + +export type CompletedCourseType = { + id: string; + courseInfoId: number; + becknTransactionId: string; + consumerId: string; + feedback: string; + purchasedAt: string; + rating: string; + status: string; + becknMessageId: string; + completedAt: string; + CourseInfo: { + title: string; + description: string; + credits: number; + imageLink: string; + language: string[]; + courseLink: string; + providerName: string; + author: string; + avgRating: number; + bppId: string; + bppUri: string; + providerId: string; + competency: { + [key: string]: string[]; + }; + courseId: string; + numberOfPurchases: number; + }; +}; + +type CompletedCourseActionTypes = { + type: string; + payload?: CompletedCourseType[]; +}; + +type FeedbackActionTypes = { + type: string; +}; + +type FeedbackPayloadType = { + rating: number; + courseInfoId: number; +}; + +export const giveFeedbackRating = + (userId: string, payload: FeedbackPayloadType) => + (dispatch: Dispatch) => { + dispatch({ type: FEEDBACK_COURSE_REQUEST }); + return axios + .patch( + `${marketBackendUrl}/api/consumer/${userId}/course/feedback`, + payload + ) + .then((res) => { + toast.success(res.data.message, { + draggable: false, + }); + dispatch({ + type: FEEDBACK_COURSE_SUCCESS, + }); + }) + .catch(() => { + toast.error('something went wrong', { + draggable: false, + }); + dispatch({ type: FEEDBACK_FAILURE }); + }); + }; + +export const getCompletedCourse = + (userId: string) => (dispatch: Dispatch) => { + dispatch({ type: GET_COMPLETED_COURSE_REQUEST }); + return axios + .get(`${marketBackendUrl}/api/consumer/${userId}/course/purchases`) + .then((res) => { + dispatch({ + type: GET_COMPLETED_COURSE_SUCCESS, + payload: res?.data?.data.consumerCourses, + }); + }) + .catch(() => dispatch({ type: GET_COMPLETED_FAILURE })); + }; diff --git a/src/redux/completedCourse/completedCourseReducer.ts b/src/redux/completedCourse/completedCourseReducer.ts new file mode 100644 index 0000000..c5c8034 --- /dev/null +++ b/src/redux/completedCourse/completedCourseReducer.ts @@ -0,0 +1,48 @@ +import { CompletedCourseType } from '@/redux/completedCourse/action'; +import { + GET_COMPLETED_COURSE_REQUEST, + GET_COMPLETED_COURSE_SUCCESS, + GET_COMPLETED_FAILURE, +} from '@/redux/completedCourse/type'; + +const init = { + courses: [], + isLoading: false, + isError: false, +}; + +type actionType = { + type: string; + payload: CompletedCourseType[]; +}; + +export const completedCourseReducer = ( + state = init, + { type, payload }: actionType +) => { + switch (type) { + case GET_COMPLETED_COURSE_REQUEST: { + return { + ...state, + isLoading: true, + }; + } + case GET_COMPLETED_COURSE_SUCCESS: { + return { + ...state, + isLoading: false, + courses: payload, + }; + } + case GET_COMPLETED_FAILURE: { + return { + ...state, + isLoading: false, + isError: true, + }; + } + default: { + return state; + } + } +}; diff --git a/src/redux/completedCourse/type.ts b/src/redux/completedCourse/type.ts new file mode 100644 index 0000000..90207a9 --- /dev/null +++ b/src/redux/completedCourse/type.ts @@ -0,0 +1,7 @@ +export const GET_COMPLETED_COURSE_REQUEST = 'getCompletedCourseRequest'; +export const GET_COMPLETED_COURSE_SUCCESS = 'getCompletedCourseSuccess'; +export const GET_COMPLETED_FAILURE = ' getCompletedCourseFailure'; + +export const FEEDBACK_COURSE_REQUEST = 'feedbackCourseRequest'; +export const FEEDBACK_COURSE_SUCCESS = 'feedbackCourseSuccess'; +export const FEEDBACK_FAILURE = ' feedbackCourseFailure'; diff --git a/src/redux/coursesDescription/action.ts b/src/redux/coursesDescription/action.ts new file mode 100644 index 0000000..75803bc --- /dev/null +++ b/src/redux/coursesDescription/action.ts @@ -0,0 +1,208 @@ +import { marketBackendUrl } from '@root/config'; +import axios from 'axios'; +import { Dispatch } from 'react'; +import { toast } from 'react-toastify'; + +import { + GET_SAVE_COURSE_AND_STATUS_FAILURE, + GET_SAVE_COURSE_AND_STATUS_REQUEST, + GET_SAVE_COURSE_AND_STATUS_SUCCESS, + PURCHASE_COURSE_FAILURE, + PURCHASE_COURSE_REQUEST, + PURCHASE_COURSE_SUCCESS, + SAVE_COURSE_FAILURE, + SAVE_COURSE_REQUEST, + SAVE_COURSE_SUCCESS, + UNSAVE_COURSE_FAILURE, + UNSAVE_COURSE_REQUEST, + UNSAVE_COURSE_SUCCESS, +} from './type'; +import { CourseType } from '../marketplace/marketplaceReducer'; + +export type requestCourseType = { + courseId: string; + bppId?: string; + title: string; + description: string; + credits: number; + imageLink: string; + language: string[]; + courseLink: string; + providerName: string; + providerId?: string; + avgRating: number; + author: string; + competency: { + [key: string]: string[]; + }; +}; + +type CourseDescriptionActionTypes = { + type: string; + payload?: { + saveCourseStatus?: boolean; + purchaseCourseStatus?: boolean; + courseLink?: string; + }; +}; + +type SingleCourseActionTypes = { + type: string; + payload?: { + saveCourseStatus: boolean; + purchaseCourseStatus: boolean; + courseLink: string; + singleCourse: CourseType; + }; +}; + +export const removeCourse = + (userId: string, courseId: string) => + (dispatch: Dispatch) => { + dispatch({ type: UNSAVE_COURSE_REQUEST }); + return axios + .patch(`${marketBackendUrl}/api/consumer/${userId}/course/unsave`, { + courseId: courseId, + }) + .then(() => + dispatch({ + type: UNSAVE_COURSE_SUCCESS, + payload: { saveCourseStatus: false }, + }) + ) + .catch(() => { + dispatch({ type: UNSAVE_COURSE_FAILURE }); + toast.error('something went wrong', { + draggable: false, + }); + }); + }; + +export const saveACourse = + (userId: string, payload: requestCourseType) => + (dispatch: Dispatch) => { + dispatch({ type: SAVE_COURSE_REQUEST }); + return axios + .post(`${marketBackendUrl}/api/consumer/${userId}/course/save`, { + ...payload, + providerId: userId, + }) + .then(() => + dispatch({ + type: SAVE_COURSE_SUCCESS, + payload: { saveCourseStatus: true }, + }) + ) + .catch(() => { + dispatch({ type: SAVE_COURSE_FAILURE }); + toast.error('something went wrong', { + draggable: false, + }); + }); + }; + +// to check course is purchased or not +const handlePurchaseCourseStatus = async (userId: string, courseId: string) => { + const res = await axios.post( + `${marketBackendUrl}/api/consumer/${userId}/course/purchase/status`, + { courseId: courseId } + ); + return res.data.data; +}; + +export const getPurchaseCourseStatus = (userId: string, courseId: string) => { + return async (dispatch: Dispatch) => { + dispatch({ type: PURCHASE_COURSE_REQUEST }); + try { + const status = await handlePurchaseCourseStatus(userId, courseId); + + return dispatch({ + type: PURCHASE_COURSE_SUCCESS, + payload: { + purchaseCourseStatus: status?.purchased, + courseLink: status?.courseLink, + }, + }); + } catch (error) { + if (axios.isAxiosError(error)) { + dispatch({ type: PURCHASE_COURSE_FAILURE }); + toast.error(error?.response?.data?.message, { + draggable: false, + }); + } + } + }; +}; + +export const purchasesACourse = ( + userId: string, + payload: requestCourseType +) => { + return async (dispatch: Dispatch) => { + dispatch({ type: PURCHASE_COURSE_REQUEST }); + try { + await axios.post( + `${marketBackendUrl}/api/consumer/${userId}/course/purchase`, + payload + ); + const status = await handlePurchaseCourseStatus( + userId, + payload?.courseId + ); + return dispatch({ + type: PURCHASE_COURSE_SUCCESS, + payload: { + purchaseCourseStatus: status.purchased, + courseLink: status.courseLink, + }, + }); + } catch (error: unknown) { + if (axios.isAxiosError(error)) { + dispatch({ type: PURCHASE_COURSE_FAILURE }); + toast.error(error?.response?.data?.message, { + draggable: false, + }); + } + } + }; +}; + +// to check course is save or not +const getSaveCourseStatus = async (userId: string, courseId: string) => { + const res = await axios.post( + `${marketBackendUrl}/api/consumer/${userId}/course/save/status`, + { courseId: courseId } + ); + return res.data.saved; +}; + +export const getSaveCourseAndStatus = ( + userId: string, + courseId: string, + singleCourse: CourseType +) => { + return async (dispatch: Dispatch) => { + dispatch({ type: GET_SAVE_COURSE_AND_STATUS_REQUEST }); + + try { + const [savedCourseStatus, purchaseCourseStatus] = await Promise.all([ + getSaveCourseStatus(userId, courseId), + handlePurchaseCourseStatus(userId, courseId), + ]); + return dispatch({ + type: GET_SAVE_COURSE_AND_STATUS_SUCCESS, + payload: { + saveCourseStatus: savedCourseStatus, + purchaseCourseStatus: purchaseCourseStatus?.purchased, + courseLink: purchaseCourseStatus?.courseLink, + singleCourse: singleCourse, + }, + }); + } catch (error) { + setTimeout(() => { + dispatch({ type: GET_SAVE_COURSE_AND_STATUS_FAILURE }); + window.location.href = '/error/DataNotFound'; + }, 5000); + } + }; +}; diff --git a/src/redux/coursesDescription/courseDescriptionReducer.ts b/src/redux/coursesDescription/courseDescriptionReducer.ts new file mode 100644 index 0000000..0be35a0 --- /dev/null +++ b/src/redux/coursesDescription/courseDescriptionReducer.ts @@ -0,0 +1,129 @@ +import { + GET_SAVE_COURSE_AND_STATUS_FAILURE, + GET_SAVE_COURSE_AND_STATUS_REQUEST, + GET_SAVE_COURSE_AND_STATUS_SUCCESS, + PURCHASE_COURSE_FAILURE, + PURCHASE_COURSE_REQUEST, + PURCHASE_COURSE_SUCCESS, + SAVE_COURSE_FAILURE, + SAVE_COURSE_REQUEST, + SAVE_COURSE_SUCCESS, + UNSAVE_COURSE_FAILURE, + UNSAVE_COURSE_REQUEST, + UNSAVE_COURSE_SUCCESS, +} from './type'; +import { CourseType } from '../marketplace/marketplaceReducer'; + +const init = { + saveCourseStatus: null, + purchaseCourseStatus: null, + singleCourse: null, + courseLink: null, + isLoading: false, + isError: false, +}; + +type actionType = { + type: string; + payload: { + saveCourseStatus?: boolean; + purchaseCourseStatus?: boolean; + courseLink?: string; + singleCourse?: CourseType; + }; +}; + +export const courseDescriptionReducer = ( + state = init, + { type, payload }: actionType +) => { + switch (type) { + case GET_SAVE_COURSE_AND_STATUS_REQUEST: { + return { + ...state, + isLoading: true, + }; + } + case GET_SAVE_COURSE_AND_STATUS_SUCCESS: { + return { + ...state, + isLoading: false, + saveCourseStatus: payload?.saveCourseStatus, + purchaseCourseStatus: payload?.purchaseCourseStatus, + singleCourse: payload?.singleCourse, + courseLink: payload.courseLink, + }; + } + case GET_SAVE_COURSE_AND_STATUS_FAILURE: { + return { + ...state, + isLoading: false, + isError: true, + }; + } + case SAVE_COURSE_REQUEST: { + return { + ...state, + isLoading: true, + }; + } + case SAVE_COURSE_SUCCESS: { + return { + ...state, + isLoading: false, + saveCourseStatus: payload?.saveCourseStatus, + }; + } + case SAVE_COURSE_FAILURE: { + return { + ...state, + isLoading: false, + isError: true, + }; + } + case UNSAVE_COURSE_REQUEST: { + return { + ...state, + isLoading: true, + }; + } + case UNSAVE_COURSE_SUCCESS: { + return { + ...state, + isLoading: false, + saveCourseStatus: payload?.saveCourseStatus, + }; + } + case UNSAVE_COURSE_FAILURE: { + return { + ...state, + isLoading: false, + isError: true, + }; + } + case PURCHASE_COURSE_REQUEST: { + return { + ...state, + isLoading: true, + }; + } + case PURCHASE_COURSE_SUCCESS: { + return { + ...state, + isLoading: false, + purchaseCourseStatus: payload?.purchaseCourseStatus, + courseLink: payload?.courseLink, + }; + } + case PURCHASE_COURSE_FAILURE: { + return { + ...state, + isLoading: false, + isError: true, + }; + } + default: { + return state; + } + } +}; diff --git a/src/redux/coursesDescription/type.ts b/src/redux/coursesDescription/type.ts new file mode 100644 index 0000000..44c7bf1 --- /dev/null +++ b/src/redux/coursesDescription/type.ts @@ -0,0 +1,15 @@ +export const SAVE_COURSE_REQUEST = 'addCourseRequest'; +export const SAVE_COURSE_SUCCESS = 'addCourseSuccess'; +export const SAVE_COURSE_FAILURE = 'addCourseFailure'; + +export const UNSAVE_COURSE_REQUEST = 'unSaveCourseRequest'; +export const UNSAVE_COURSE_SUCCESS = 'unSaveCourseSuccess'; +export const UNSAVE_COURSE_FAILURE = 'unSaveCourseFailure'; + +export const PURCHASE_COURSE_REQUEST = 'purchaseCourseRequest'; +export const PURCHASE_COURSE_SUCCESS = 'purchaseCourseSuccess'; +export const PURCHASE_COURSE_FAILURE = 'purchaseCourseFailure'; + +export const GET_SAVE_COURSE_AND_STATUS_REQUEST = 'getSaveCourseStatusRequest'; +export const GET_SAVE_COURSE_AND_STATUS_SUCCESS = 'getSaveCourseStatusSuccess'; +export const GET_SAVE_COURSE_AND_STATUS_FAILURE = 'getSaveCourseStatusFailure'; diff --git a/src/redux/marketplace/action.ts b/src/redux/marketplace/action.ts new file mode 100644 index 0000000..f7755e9 --- /dev/null +++ b/src/redux/marketplace/action.ts @@ -0,0 +1,81 @@ +import { marketBackendUrl } from '@root/config'; +import axios from 'axios'; +import { Dispatch } from 'react'; + +import { CourseType } from './marketplaceReducer'; +import { + MARKETPLACE_FAILURE, + MARKETPLACE_REQUEST, + MARKETPLACE_SUCCESS, +} from './type'; + +type marketplaceActionTypes = { + type: string; + payload?: { + mostPopularCourses: CourseType[]; + recommendedCourses: CourseType[]; + savedCourses: CourseType[]; + ongoingCourses: CourseType[]; + }; +}; + +export const getSavedCourse = async (userId: string) => { + const data = await axios.get( + `${marketBackendUrl}/api/consumer/${userId}/course/saved` + ); + return data.data.data.consumerCourses; +}; +export const getOngoingCourses = async (userId: string) => { + const data = await axios.get( + `${marketBackendUrl}/api/consumer/${userId}/course/ongoing` + ); + return data.data.data.consumerCourses; +}; +export const getMostPopularCourses = async () => { + // api is not correct for now + const data = await axios.get( + `${marketBackendUrl}/api/consumer/course/popular?limit=10&offset=0` + ); + return data.data.data.response; +}; +export const getRecommendedCourses = async (userId: string) => { + // api is not correct for now + const data = await axios.get( + `${marketBackendUrl}/api/consumer/${userId}/course/recommended` + ); + return data.data.data.response; +}; + +export const getMarketplaceCourses = (userId: string) => { + return async (dispatch: Dispatch) => { + dispatch({ type: MARKETPLACE_REQUEST }); + + try { + const [ + recommendedCoursesResponse, + mostPopularCoursesResponse, + ongoingCoursesResponse, + savedCourseResponse, + ] = await Promise.all([ + getRecommendedCourses(userId), + getMostPopularCourses(), + getOngoingCourses(userId), + getSavedCourse(userId), + ]); + return dispatch({ + type: MARKETPLACE_SUCCESS, + payload: { + mostPopularCourses: mostPopularCoursesResponse, + recommendedCourses: recommendedCoursesResponse, + savedCourses: savedCourseResponse, + ongoingCourses: ongoingCoursesResponse, + }, + }); + } catch (error) { + setTimeout(() => { + dispatch({ type: MARKETPLACE_FAILURE }); + window.location.href = '/error/DataNotFound'; + }, 5000); + } + }; +}; diff --git a/src/redux/marketplace/marketplaceReducer.ts b/src/redux/marketplace/marketplaceReducer.ts new file mode 100644 index 0000000..514bc7f --- /dev/null +++ b/src/redux/marketplace/marketplaceReducer.ts @@ -0,0 +1,91 @@ +import { + MARKETPLACE_FAILURE, + MARKETPLACE_REQUEST, + MARKETPLACE_SUCCESS, +} from './type'; + +export type LevelsType = { + id: number | string; + levelNumber: number | string; + name: string; +}; + +export type CompetencyType = { + id: number | string; + name: string; + levels: LevelsType[]; +}; + +export type CourseType = { + courseId: string; + title: string; + competency: CompetencyType[]; + created_by: string; + lastUpdatedOn: string; + avgRating: number; + credits: number; + language: string[]; + imageLink: string; + imgLink: string; + description: string; + author?: string; + courseLink?: string; + bppId?: string; + bppUri?: string; + providerId?: string; + providerName?: string; + numberOfPurchases: number; +}; + +const init = { + mostPopularCourses: null, + recommendedCourses: null, + savedCourses: null, + ongoingCourses: null, + isLoading: false, + isError: false, +}; + +type actionType = { + type: string; + payload: { + mostPopularCourses: CourseType[]; + recommendedCourses: CourseType[]; + savedCourses: CourseType[]; + ongoingCourses: CourseType[]; + }; +}; + +export const marketplaceReducer = ( + state = init, + { type, payload }: actionType +) => { + switch (type) { + case MARKETPLACE_REQUEST: { + return { + ...state, + isLoading: true, + }; + } + case MARKETPLACE_SUCCESS: { + return { + ...state, + isLoading: false, + mostPopularCourses: payload.mostPopularCourses, + recommendedCourses: payload.recommendedCourses, + savedCourses: payload.savedCourses, + ongoingCourses: payload.ongoingCourses, + }; + } + case MARKETPLACE_FAILURE: { + return { + ...state, + isLoading: false, + isError: true, + }; + } + default: { + return state; + } + } +}; diff --git a/src/redux/marketplace/type.ts b/src/redux/marketplace/type.ts new file mode 100644 index 0000000..fa90fcd --- /dev/null +++ b/src/redux/marketplace/type.ts @@ -0,0 +1,3 @@ +export const MARKETPLACE_REQUEST = 'marketplaceRequest'; +export const MARKETPLACE_SUCCESS = 'marketplaceSuccess'; +export const MARKETPLACE_FAILURE = 'marketplaceFailure'; diff --git a/src/redux/notification/action.ts b/src/redux/notification/action.ts new file mode 100644 index 0000000..b6e9c4f --- /dev/null +++ b/src/redux/notification/action.ts @@ -0,0 +1,30 @@ +import { marketBackendUrl } from '@root/config'; +import axios from 'axios'; +import { Dispatch } from 'react'; + +import { NotificationType } from '@/app/notifications/page'; + +import { + GET_NOTIFICATION_FAILURE, + GET_NOTIFICATION_REQUEST, + GET_NOTIFICATION_SUCCESS, +} from './type'; + +type NotificationActionTypes = { + type: string; + payload?: NotificationType[]; +}; + +export const getAllNotifications = + (userId: string) => (dispatch: Dispatch) => { + dispatch({ type: GET_NOTIFICATION_REQUEST }); + axios + .get(`${marketBackendUrl}/api/consumer/${userId}/notifications`) + .then((res) => + dispatch({ + type: GET_NOTIFICATION_SUCCESS, + payload: res.data.data.notifications, + }) + ) + .catch(() => dispatch({ type: GET_NOTIFICATION_FAILURE })); + }; diff --git a/src/redux/notification/notificationReducer.ts b/src/redux/notification/notificationReducer.ts new file mode 100644 index 0000000..2f43002 --- /dev/null +++ b/src/redux/notification/notificationReducer.ts @@ -0,0 +1,44 @@ +import { NotificationType } from '@/app/notifications/page'; + +import { + GET_NOTIFICATION_FAILURE, + GET_NOTIFICATION_REQUEST, + GET_NOTIFICATION_SUCCESS, +} from './type'; + +const init = { + notificationData: [], + isLoading: false, + isError: false, +}; + +export const notificationReducer = ( + state = init, + { type, payload }: { type: string; payload: NotificationType[] } +) => { + switch (type) { + case GET_NOTIFICATION_REQUEST: { + return { + ...state, + isLoading: true, + }; + } + case GET_NOTIFICATION_SUCCESS: { + return { + ...state, + isLoading: false, + notificationData: payload, + }; + } + case GET_NOTIFICATION_FAILURE: { + return { + ...state, + isLoading: false, + isError: true, + }; + } + default: { + return state; + } + } +}; diff --git a/src/redux/notification/type.ts b/src/redux/notification/type.ts new file mode 100644 index 0000000..83460ad --- /dev/null +++ b/src/redux/notification/type.ts @@ -0,0 +1,3 @@ +export const GET_NOTIFICATION_REQUEST = 'getNotificationRequest'; +export const GET_NOTIFICATION_SUCCESS = 'getNotificationSuccess'; +export const GET_NOTIFICATION_FAILURE = 'getNotificationFailure'; diff --git a/src/redux/purchaseHistory/action.ts b/src/redux/purchaseHistory/action.ts new file mode 100644 index 0000000..d8bf47d --- /dev/null +++ b/src/redux/purchaseHistory/action.ts @@ -0,0 +1,66 @@ +import { marketBackendUrl } from '@root/config'; +import axios from 'axios'; +import { Dispatch } from 'react'; + +import { ConsumerCourse, TransectionType } from '@/app/purchase-history/page'; + +import { + GET_PURCHASE_HISTORY_FAILURE, + GET_PURCHASE_HISTORY_REQUEST, + GET_PURCHASE_HISTORY_SUCCESS, +} from './type'; + +type PurchaseActionTypes = { + type: string; + payload?: { + walletBalance: number | null; + purchaseHistory: TransectionType[]; + }; +}; + +export const fetchCredits = async (userId: string) => { + const data = await axios.get( + `${marketBackendUrl}/api/consumer/${userId}/wallet/credits` + ); + return data.data.data.credits; +}; + +export const fetchPurchaseHistory = async (userId: string) => { + const data = await axios.get( + `${marketBackendUrl}/api/consumer/${userId}/course/purchases` + ); + return data.data.data.consumerCourses; +}; + +export const getPurchaseHistory = (userId: string) => { + return async (dispatch: Dispatch) => { + dispatch({ type: GET_PURCHASE_HISTORY_REQUEST }); + + try { + const [creditsResponse, purchaseHistoryResponse] = await Promise.all([ + fetchCredits(userId), + fetchPurchaseHistory(userId), + ]); + const transactionObjArray = purchaseHistoryResponse?.map( + (item: ConsumerCourse) => { + return { + id: item?.id, + title: item?.CourseInfo?.title, + credits: item?.CourseInfo?.credits, + author: item?.CourseInfo?.providerName, + purchasedAt: item?.purchasedAt, + }; + } + ); + dispatch({ + type: GET_PURCHASE_HISTORY_SUCCESS, + payload: { + walletBalance: creditsResponse, + purchaseHistory: transactionObjArray, + }, + }); + } catch (error) { + dispatch({ type: GET_PURCHASE_HISTORY_FAILURE }); + } + }; +}; diff --git a/src/redux/purchaseHistory/purchaseHistoryReducer.ts b/src/redux/purchaseHistory/purchaseHistoryReducer.ts new file mode 100644 index 0000000..cd185e7 --- /dev/null +++ b/src/redux/purchaseHistory/purchaseHistoryReducer.ts @@ -0,0 +1,55 @@ +import { TransectionType } from '@/app/purchase-history/page'; + +import { + GET_PURCHASE_HISTORY_FAILURE, + GET_PURCHASE_HISTORY_REQUEST, + GET_PURCHASE_HISTORY_SUCCESS, +} from './type'; + +const init = { + walletBalance: null, + purchaseHistory: [], + isLoading: false, + isError: false, +}; + +type actionType = { + type: string; + payload: { + walletBalance: number; + purchaseHistory: TransectionType[]; + }; +}; + +export const purchaseHistoryReducer = ( + state = init, + { type, payload }: actionType +) => { + switch (type) { + case GET_PURCHASE_HISTORY_REQUEST: { + return { + ...state, + isLoading: true, + }; + } + case GET_PURCHASE_HISTORY_SUCCESS: { + return { + ...state, + isLoading: false, + isError: false, + purchaseHistory: payload?.purchaseHistory, + walletBalance: payload?.walletBalance, + }; + } + case GET_PURCHASE_HISTORY_FAILURE: { + return { + ...state, + isLoading: false, + isError: true, + }; + } + default: { + return state; + } + } +}; diff --git a/src/redux/purchaseHistory/type.ts b/src/redux/purchaseHistory/type.ts new file mode 100644 index 0000000..10cd161 --- /dev/null +++ b/src/redux/purchaseHistory/type.ts @@ -0,0 +1,3 @@ +export const GET_PURCHASE_HISTORY_REQUEST = 'getPurchaseHistoryRequest'; +export const GET_PURCHASE_HISTORY_SUCCESS = 'getPurchaseHistorySuccess'; +export const GET_PURCHASE_HISTORY_FAILURE = 'getPurchaseHistoryFailure'; diff --git a/src/redux/searchCourses/action.ts b/src/redux/searchCourses/action.ts new file mode 100644 index 0000000..b01d668 --- /dev/null +++ b/src/redux/searchCourses/action.ts @@ -0,0 +1,58 @@ +import { marketBackendUrl } from '@root/config'; +import axios from 'axios'; +import { Dispatch } from 'react'; + +import { + SEARCH_COURSES_FAILURE, + SEARCH_COURSES_REQUEST, + SEARCH_COURSES_RESET, + SEARCH_COURSES_SUCCESS, +} from './type'; +import { CourseType } from '../marketplace/marketplaceReducer'; + +type SearchCoursesActionTypes = { + type: string; + payload?: CourseType[]; +}; + +export const getSearchCourses = + (searchText: string) => + async (dispatch: Dispatch) => { + dispatch({ type: SEARCH_COURSES_REQUEST }); + + // when ever user search it will first reset initial value to empty + dispatch({ + type: SEARCH_COURSES_RESET, + }); + try { + const response = await axios.get( + `${marketBackendUrl}/api/consumer/course/search?searchInput=${searchText}` + ); + { + dispatch({ + type: SEARCH_COURSES_SUCCESS, + payload: response?.data?.data?.searchResponse?.courses, + }); + } + if (response?.data?.data?.searchResponse?.messageId) { + let counter = 0; + const intervalId = setInterval(async () => { + const res = await axios.get( + `${marketBackendUrl}/api/consumer/course/search/poll/${response?.data?.data?.searchResponse?.messageId}` + ); + if (Array.isArray(res.data.data.courses.data)) { + dispatch({ + type: SEARCH_COURSES_SUCCESS, + payload: res.data.data.courses.data, + }); + } + counter++; + if (counter >= 5) { + clearInterval(intervalId); // Stop the interval after 5 iterations + } + }, 5000); // 5-second interval + } + } catch (error) { + dispatch({ type: SEARCH_COURSES_FAILURE }); + } + }; diff --git a/src/redux/searchCourses/searchReducer.ts b/src/redux/searchCourses/searchReducer.ts new file mode 100644 index 0000000..cb724b9 --- /dev/null +++ b/src/redux/searchCourses/searchReducer.ts @@ -0,0 +1,56 @@ +import { + SEARCH_COURSES_FAILURE, + SEARCH_COURSES_REQUEST, + SEARCH_COURSES_RESET, + SEARCH_COURSES_SUCCESS, +} from './type'; +import { CourseType } from '../marketplace/marketplaceReducer'; + +const init = { + searchCourses: [], + isLoading: false, + isError: false, +}; + +type actionType = { + type: string; + payload: CourseType[]; +}; + +export const searchCoursesReducer = ( + state = init, + { type, payload }: actionType +) => { + switch (type) { + case SEARCH_COURSES_REQUEST: { + return { + ...state, + isLoading: true, + }; + } + case SEARCH_COURSES_RESET: { + return { + ...state, + isLoading: false, + searchCourses: [], + }; + } + case SEARCH_COURSES_SUCCESS: { + return { + ...state, + isLoading: false, + searchCourses: [...state.searchCourses, ...payload], + }; + } + case SEARCH_COURSES_FAILURE: { + return { + ...state, + isLoading: false, + isError: true, + }; + } + default: { + return state; + } + } +}; diff --git a/src/redux/searchCourses/type.ts b/src/redux/searchCourses/type.ts new file mode 100644 index 0000000..0dfc1b1 --- /dev/null +++ b/src/redux/searchCourses/type.ts @@ -0,0 +1,4 @@ +export const SEARCH_COURSES_REQUEST = 'searchCoursesRequest'; +export const SEARCH_COURSES_SUCCESS = 'searchCoursesSuccess'; +export const SEARCH_COURSES_FAILURE = 'searchCoursesFailure'; +export const SEARCH_COURSES_RESET = 'searchCoursesReset'; diff --git a/src/redux/store.ts b/src/redux/store.ts new file mode 100644 index 0000000..01b0e43 --- /dev/null +++ b/src/redux/store.ts @@ -0,0 +1,68 @@ +import { TypedUseSelectorHook, useSelector } from 'react-redux'; +import { + AnyAction, + applyMiddleware, + combineReducers, + legacy_createStore, + Store, +} from 'redux'; +import { persistReducer, persistStore } from 'redux-persist'; +import createWebStorage from 'redux-persist/lib/storage/createWebStorage'; +import thunk, { ThunkDispatch } from 'redux-thunk'; + +import { completedCourseReducer } from '@/redux/completedCourse/completedCourseReducer'; + +import { courseDescriptionReducer } from './coursesDescription/courseDescriptionReducer'; +import { marketplaceReducer } from './marketplace/marketplaceReducer'; +import { notificationReducer } from './notification/notificationReducer'; +import { purchaseHistoryReducer } from './purchaseHistory/purchaseHistoryReducer'; +import { searchCoursesReducer } from './searchCourses/searchReducer'; +import { userDetailsReducer } from './userDetails/userDetailsReducer'; + +const createNoopStorage = () => { + return { + getItem(_key: string) { + return Promise.resolve(null); + }, + setItem(_key: string, value: string) { + return Promise.resolve(value); + }, + removeItem(_key: string) { + return Promise.resolve(); + }, + }; +}; + +const storage = + typeof window !== 'undefined' + ? createWebStorage('local') + : createNoopStorage(); + +const persistConfig = { + key: 'marketplacePersistData', + storage, +}; + +const rootReducer = combineReducers({ + notification: notificationReducer, + purchaseHistory: purchaseHistoryReducer, + marketplace: marketplaceReducer, + singleCourse: courseDescriptionReducer, + searchCourses: searchCoursesReducer, + completedCourse: completedCourseReducer, + userDetails: userDetailsReducer, +}); + +const persistedReducer = persistReducer(persistConfig, rootReducer); + +export type RootState = ReturnType; +export type AppDispatch = ThunkDispatch; + +export const useAppSelector: TypedUseSelectorHook = useSelector; + +export const store: Store = legacy_createStore( + persistedReducer, + applyMiddleware(thunk) +); + +export const persistor = persistStore(store); diff --git a/src/redux/userDetails/action.ts b/src/redux/userDetails/action.ts new file mode 100644 index 0000000..c52ebc7 --- /dev/null +++ b/src/redux/userDetails/action.ts @@ -0,0 +1,39 @@ +import { marketBackendUrl } from '@root/config'; +import axios from 'axios'; +import { Dispatch } from 'react'; + +import { + USER_DETAILS_FAILURE, + USER_DETAILS_REQUEST, + USER_DETAILS_SUCCESS, +} from './type'; + +export type UserDetailsType = { + consumerId: string; + name: string; + emailId: string; + phoneNumber: string; + createdAt: string; + updatedAt: string; + credits: 4960; + numberOfPurchasedCourses: 2; +}; + +type UserDetailsActionTypes = { + type: string; + payload?: UserDetailsType; +}; + +export const getUserDetails = + (userId: string) => (dispatch: Dispatch) => { + dispatch({ type: USER_DETAILS_REQUEST }); + axios + .get(`${marketBackendUrl}/api/consumer/${userId}`) + .then((res) => + dispatch({ + type: USER_DETAILS_SUCCESS, + payload: res?.data?.data?.consumer, + }) + ) + .catch(() => dispatch({ type: USER_DETAILS_FAILURE })); + }; diff --git a/src/redux/userDetails/type.ts b/src/redux/userDetails/type.ts new file mode 100644 index 0000000..602fda7 --- /dev/null +++ b/src/redux/userDetails/type.ts @@ -0,0 +1,3 @@ +export const USER_DETAILS_REQUEST = 'userDetailsRequest'; +export const USER_DETAILS_SUCCESS = 'userDetailsSuccess'; +export const USER_DETAILS_FAILURE = 'userDetailsFailure'; diff --git a/src/redux/userDetails/userDetailsReducer.ts b/src/redux/userDetails/userDetailsReducer.ts new file mode 100644 index 0000000..0e4d171 --- /dev/null +++ b/src/redux/userDetails/userDetailsReducer.ts @@ -0,0 +1,48 @@ +import { UserDetailsType } from './action'; +import { + USER_DETAILS_FAILURE, + USER_DETAILS_REQUEST, + USER_DETAILS_SUCCESS, +} from './type'; + +const init = { + userDetails: {}, + isLoading: false, + isError: false, +}; + +type actionType = { + type: string; + payload: UserDetailsType; +}; + +export const userDetailsReducer = ( + state = init, + { type, payload }: actionType +) => { + switch (type) { + case USER_DETAILS_REQUEST: { + return { + ...state, + isLoading: true, + }; + } + case USER_DETAILS_SUCCESS: { + return { + ...state, + isLoading: false, + userDetails: payload, + }; + } + case USER_DETAILS_FAILURE: { + return { + ...state, + isLoading: false, + isError: true, + }; + } + default: { + return state; + } + } +}; diff --git a/tsconfig.json b/tsconfig.json index f3a4ec1..9028271 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,7 +16,8 @@ "baseUrl": ".", "paths": { "@/*": ["./src/*"], - "~/*": ["./public/*"] + "~/*": ["./public/*"], + "@root/*": ["./*"] }, "incremental": true, "plugins": [ @@ -25,7 +26,13 @@ } ] }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts", + "src/app/all-courses" + ], "exclude": ["node_modules"], "moduleResolution": ["node_modules", ".next", "node"] } diff --git a/yarn.lock b/yarn.lock index 673b38f..ea90eb2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -155,7 +155,7 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-module-imports@^7.22.5": +"@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.22.5": "integrity" "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==" "resolved" "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz" "version" "7.22.5" @@ -1019,12 +1019,12 @@ "core-js-pure" "^3.15.0" "regenerator-runtime" "^0.13.4" -"@babel/runtime@^7.10.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": - "integrity" "sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==" - "resolved" "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.9.tgz" - "version" "7.17.9" +"@babel/runtime@^7.10.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.18.3", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": + "integrity" "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==" + "resolved" "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz" + "version" "7.23.2" dependencies: - "regenerator-runtime" "^0.13.4" + "regenerator-runtime" "^0.14.0" "@babel/template@^7.22.5", "@babel/template@^7.3.3": "integrity" "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==" @@ -1234,6 +1234,94 @@ dependencies: "@cspotcode/source-map-consumer" "0.8.0" +"@emotion/babel-plugin@^11.11.0": + "integrity" "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==" + "resolved" "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz" + "version" "11.11.0" + 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" + +"@emotion/cache@^11.11.0", "@emotion/cache@^11.4.0": + "integrity" "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==" + "resolved" "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz" + "version" "11.11.0" + 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" + +"@emotion/hash@^0.9.1": + "integrity" "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" + "resolved" "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz" + "version" "0.9.1" + +"@emotion/memoize@^0.8.1": + "integrity" "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + "resolved" "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz" + "version" "0.8.1" + +"@emotion/react@^11.8.1": + "integrity" "sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==" + "resolved" "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz" + "version" "11.11.1" + dependencies: + "@babel/runtime" "^7.18.3" + "@emotion/babel-plugin" "^11.11.0" + "@emotion/cache" "^11.11.0" + "@emotion/serialize" "^1.1.2" + "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" + "@emotion/utils" "^1.2.1" + "@emotion/weak-memoize" "^0.3.1" + "hoist-non-react-statics" "^3.3.1" + +"@emotion/serialize@^1.1.2": + "integrity" "sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==" + "resolved" "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.2.tgz" + "version" "1.1.2" + 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" + +"@emotion/sheet@^1.2.2": + "integrity" "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" + "resolved" "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz" + "version" "1.2.2" + +"@emotion/unitless@^0.8.1": + "integrity" "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + "resolved" "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz" + "version" "0.8.1" + +"@emotion/use-insertion-effect-with-fallbacks@^1.0.1": + "integrity" "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==" + "resolved" "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz" + "version" "1.0.1" + +"@emotion/utils@^1.2.1": + "integrity" "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" + "resolved" "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz" + "version" "1.2.1" + +"@emotion/weak-memoize@^0.3.1": + "integrity" "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" + "resolved" "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz" + "version" "0.3.1" + "@eslint-community/eslint-utils@^4.2.0": "integrity" "sha512-gB8T4H4DEfX2IV9zGDJPOBgP1e/DbfCPDTtEqUMckpvzS1OYtva8JdFYBqMwYk7xAQ429WGF/UPqn8uQ//h2vQ==" "resolved" "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.2.0.tgz" @@ -1266,6 +1354,26 @@ "resolved" "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz" "version" "8.44.0" +"@floating-ui/core@^1.4.2": + "integrity" "sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg==" + "resolved" "https://registry.npmjs.org/@floating-ui/core/-/core-1.5.0.tgz" + "version" "1.5.0" + dependencies: + "@floating-ui/utils" "^0.1.3" + +"@floating-ui/dom@^1.0.1": + "integrity" "sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==" + "resolved" "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.3.tgz" + "version" "1.5.3" + dependencies: + "@floating-ui/core" "^1.4.2" + "@floating-ui/utils" "^0.1.3" + +"@floating-ui/utils@^0.1.3": + "integrity" "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==" + "resolved" "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.6.tgz" + "version" "0.1.6" + "@humanwhocodes/config-array@^0.11.10": "integrity" "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==" "resolved" "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz" @@ -1557,6 +1665,16 @@ "tiny-glob" "^0.2.9" "tslib" "^2.4.0" +"@reduxjs/toolkit@^1.9.7": + "integrity" "sha512-t7v8ZPxhhKgOKtU+uyJT13lu4vL7az5aFi4IdoDs/eS548edn2M8Ik9h8fxgvMjGoAUVFSt6ZC1P5cWmQ014QQ==" + "resolved" "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.7.tgz" + "version" "1.9.7" + dependencies: + "immer" "^9.0.21" + "redux" "^4.2.1" + "redux-thunk" "^2.4.2" + "reselect" "^4.1.8" + "@rushstack/eslint-patch@^1.1.3": "integrity" "sha512-WiBSI6JBIhC6LRIsB2Kwh8DsGTlbBU+mLRxJmAe3LjHTdkDpwIbEOZgoXBbZilk/vlfjK8i6nKRAvIRn1XaIMw==" "resolved" "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.3.tgz" @@ -1809,6 +1927,14 @@ dependencies: "@types/node" "*" +"@types/hoist-non-react-statics@^3.3.1": + "integrity" "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==" + "resolved" "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz" + "version" "3.3.5" + dependencies: + "@types/react" "*" + "hoist-non-react-statics" "^3.3.0" + "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": "integrity" "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==" "resolved" "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz" @@ -1876,14 +2002,35 @@ "resolved" "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz" "version" "15.7.4" -"@types/react-dom@^18.0.0": +"@types/react-detect-offline@^2.4.4": + "integrity" "sha512-iUqEWeiN63YfNMho8SdltKR0q7WbFXJM5cQXWLKo9rluuYn7kcyzUz2lJnG57MSmESHPC1esRICt2Ve1TlVDAA==" + "resolved" "https://registry.npmjs.org/@types/react-detect-offline/-/react-detect-offline-2.4.4.tgz" + "version" "2.4.4" + dependencies: + "@types/react" "*" + +"@types/react-dom@^16.8 || ^17.0 || ^18.0", "@types/react-dom@^18.0.0": "integrity" "sha512-UxeS+Wtj5bvLRREz9tIgsK4ntCuLDo0EcAcACgw3E+9wE8ePDr9uQpq53MfcyxyIS55xJ+0B6mDS8c4qkkHLBg==" "resolved" "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.2.tgz" "version" "18.0.2" dependencies: "@types/react" "*" -"@types/react@*", "@types/react@^18.2.15": +"@types/react-slick@^0.23.11": + "integrity" "sha512-52AbNhYN7u0ATqAUvap2MXNG3znUsJslAWgebUHrovvnJ6EG6oic+TZyC82XiwwvijRMyL2V0C2wPJbzsSwllw==" + "resolved" "https://registry.npmjs.org/@types/react-slick/-/react-slick-0.23.11.tgz" + "version" "0.23.11" + dependencies: + "@types/react" "*" + +"@types/react-transition-group@^4.4.0": + "integrity" "sha512-QmQ22q+Pb+HQSn04NL3HtrqHwYMf4h3QKArOy5F8U5nEVMaihBs3SR10WiOM1iwPz5jIo8x/u11al+iEGZZrvg==" + "resolved" "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.8.tgz" + "version" "4.4.8" + dependencies: + "@types/react" "*" + +"@types/react@*", "@types/react@^16.8 || ^17.0 || ^18.0", "@types/react@^18.2.15": "integrity" "sha512-oEjE7TQt1fFTFSbf8kkNuc798ahTUzn3Le67/PWjE8MAfYAD/qB7O8hSTcromLFqHCt9bcdOg5GXMokzTjJ5SA==" "resolved" "https://registry.npmjs.org/@types/react/-/react-18.2.15.tgz" "version" "18.2.15" @@ -1907,6 +2054,13 @@ "resolved" "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz" "version" "2.0.1" +"@types/swiper@^6.0.0": + "integrity" "sha512-QPZRgxZ+ivXXtzV43B3LxpXUIC7FE/EoKM+rtxngmgt2M7eeUYypZhyqZD8UxJtlBcUDw/ATGoVeSNpvBBrz2w==" + "resolved" "https://registry.npmjs.org/@types/swiper/-/swiper-6.0.0.tgz" + "version" "6.0.0" + dependencies: + "swiper" "*" + "@types/testing-library__jest-dom@^5.9.1": "integrity" "sha512-Gk9vaXfbzc5zCXI9eYE9BI5BNHEp4D3FWjgqBE/ePGYElLAP+KvxBcsdkwfIVvezs605oiyd/VrpiHe3Oeg+Aw==" "resolved" "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.1.tgz" @@ -1914,6 +2068,11 @@ dependencies: "@types/jest" "*" +"@types/use-sync-external-store@^0.0.3": + "integrity" "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" + "resolved" "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz" + "version" "0.0.3" + "@types/yargs-parser@*": "integrity" "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==" "resolved" "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz" @@ -2240,6 +2399,15 @@ "resolved" "https://registry.npmjs.org/axe-core/-/axe-core-4.4.1.tgz" "version" "4.4.1" +"axios@^1.6.0": + "integrity" "sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==" + "resolved" "https://registry.npmjs.org/axios/-/axios-1.6.0.tgz" + "version" "1.6.0" + dependencies: + "follow-redirects" "^1.15.0" + "form-data" "^4.0.0" + "proxy-from-env" "^1.1.0" + "axobject-query@^2.2.0": "integrity" "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==" "resolved" "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz" @@ -2280,6 +2448,15 @@ "@types/babel__core" "^7.0.0" "@types/babel__traverse" "^7.0.6" +"babel-plugin-macros@^3.1.0": + "integrity" "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==" + "resolved" "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz" + "version" "3.1.0" + dependencies: + "@babel/runtime" "^7.12.5" + "cosmiconfig" "^7.0.0" + "resolve" "^1.19.0" + "babel-plugin-polyfill-corejs2@^0.4.4": "integrity" "sha512-9WeK9snM1BfxB38goUEv2FLnA6ja07UMfazFHzCXUb3NyDZAwfXvQiURQ6guTTMeHcOsdknULm1PDhs4uWtKyA==" "resolved" "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.4.tgz" @@ -2491,6 +2668,11 @@ "resolved" "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz" "version" "1.2.2" +"classnames@^2.2.5": + "integrity" "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + "resolved" "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz" + "version" "2.3.2" + "clean-stack@^2.0.0": "integrity" "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" "resolved" "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz" @@ -2533,7 +2715,7 @@ "strip-ansi" "^6.0.0" "wrap-ansi" "^7.0.0" -"clsx@^1.2.1": +"clsx@^1.1.1", "clsx@^1.2.1": "integrity" "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==" "resolved" "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz" "version" "1.2.1" @@ -2641,7 +2823,7 @@ "split2" "^3.0.0" "through2" "^4.0.0" -"convert-source-map@^1.4.0", "convert-source-map@^1.6.0", "convert-source-map@^1.7.0": +"convert-source-map@^1.4.0", "convert-source-map@^1.5.0", "convert-source-map@^1.6.0", "convert-source-map@^1.7.0": "integrity" "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==" "resolved" "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz" "version" "1.8.0" @@ -2916,6 +3098,14 @@ "resolved" "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.10.tgz" "version" "0.5.10" +"dom-helpers@^5.0.1": + "integrity" "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==" + "resolved" "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz" + "version" "5.2.1" + dependencies: + "@babel/runtime" "^7.8.7" + "csstype" "^3.0.2" + "dom-serializer@^2.0.0": "integrity" "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==" "resolved" "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz" @@ -3001,6 +3191,11 @@ "graceful-fs" "^4.2.4" "tapable" "^2.2.0" +"enquire.js@^2.1.6": + "integrity" "sha512-/KujNpO+PT63F7Hlpu4h3pE3TokKRHN26JYmQpPyjkRD/N57R7bPDNojMXdi7uveAKjYB7yQnartCxZnFWr0Xw==" + "resolved" "https://registry.npmjs.org/enquire.js/-/enquire.js-2.1.6.tgz" + "version" "2.1.6" + "entities@^4.2.0", "entities@^4.4.0": "integrity" "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" "resolved" "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz" @@ -3410,6 +3605,11 @@ dependencies: "to-regex-range" "^5.0.1" +"find-root@^1.1.0": + "integrity" "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + "resolved" "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz" + "version" "1.1.0" + "find-up@^2.1.0": "integrity" "sha1-RdG35QbHF93UgndaK3eSCjwMV6c= sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==" "resolved" "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz" @@ -3454,6 +3654,11 @@ "resolved" "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz" "version" "3.1.1" +"follow-redirects@^1.15.0": + "integrity" "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==" + "resolved" "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz" + "version" "1.15.3" + "form-data@^3.0.0": "integrity" "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==" "resolved" "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz" @@ -3463,6 +3668,15 @@ "combined-stream" "^1.0.8" "mime-types" "^2.1.12" +"form-data@^4.0.0": + "integrity" "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==" + "resolved" "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz" + "version" "4.0.0" + dependencies: + "asynckit" "^0.4.0" + "combined-stream" "^1.0.8" + "mime-types" "^2.1.12" + "fraction.js@^4.2.0": "integrity" "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==" "resolved" "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz" @@ -3713,6 +3927,13 @@ dependencies: "function-bind" "^1.1.1" +"hoist-non-react-statics@^3.3.0", "hoist-non-react-statics@^3.3.1", "hoist-non-react-statics@^3.3.2": + "integrity" "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==" + "resolved" "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz" + "version" "3.3.2" + dependencies: + "react-is" "^16.7.0" + "hosted-git-info@^2.1.4": "integrity" "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" "resolved" "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz" @@ -3776,6 +3997,11 @@ "resolved" "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz" "version" "5.2.0" +"immer@^9.0.21": + "integrity" "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==" + "resolved" "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz" + "version" "9.0.21" + "import-fresh@^3.0.0", "import-fresh@^3.2.1": "integrity" "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==" "resolved" "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" @@ -4532,6 +4758,13 @@ "resolved" "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" "version" "1.0.1" +"json2mq@^0.2.0": + "integrity" "sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==" + "resolved" "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz" + "version" "0.2.0" + dependencies: + "string-convert" "^0.2.0" + "json5@^1.0.1": "integrity" "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==" "resolved" "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz" @@ -4790,6 +5023,11 @@ "resolved" "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz" "version" "2.0.30" +"memoize-one@^6.0.0": + "integrity" "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" + "resolved" "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz" + "version" "6.0.0" + "meow@^8.0.0": "integrity" "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==" "resolved" "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz" @@ -5365,7 +5603,7 @@ "kleur" "^3.0.3" "sisteransi" "^1.0.5" -"prop-types@^15.8.1": +"prop-types@^15.6.0", "prop-types@^15.6.2", "prop-types@^15.8.1": "integrity" "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==" "resolved" "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz" "version" "15.8.1" @@ -5374,6 +5612,11 @@ "object-assign" "^4.1.1" "react-is" "^16.13.1" +"proxy-from-env@^1.1.0": + "integrity" "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "resolved" "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz" + "version" "1.1.0" + "psl@^1.1.33": "integrity" "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" "resolved" "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz" @@ -5399,7 +5642,12 @@ "resolved" "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz" "version" "4.0.1" -"react-dom@^18.0.0", "react-dom@^18.2.0": +"react-detect-offline@^2.4.5": + "integrity" "sha512-sI13NPEKl3uQp95FT5CwrYzH3DnXCwNP6TnY6NRF5gFDM4NU9KDlbtA6HG2dwhDVS0RYQGXwZW/mHbdf8fCnaw==" + "resolved" "https://registry.npmjs.org/react-detect-offline/-/react-detect-offline-2.4.5.tgz" + "version" "2.4.5" + +"react-dom@^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.10.2 || ^17.0.0 || ^18.0.0", "react-dom@^16.8 || ^17.0 || ^18.0", "react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom@^18.0.0", "react-dom@^18.2.0", "react-dom@>=16", "react-dom@>=16.6.0": "integrity" "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==" "resolved" "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz" "version" "18.2.0" @@ -5417,12 +5665,82 @@ "resolved" "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" "version" "16.13.1" +"react-is@^16.7.0": + "integrity" "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + "resolved" "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" + "version" "16.13.1" + "react-is@^17.0.1": "integrity" "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" "resolved" "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz" "version" "17.0.2" -"react@*", "react@^16.5.1 || ^17.0.0 || ^18.0.0", "react@^18.0.0", "react@^18.2.0", "react@>= 16.8.0 || 17.x.x || ^18.0.0-0", "react@>=17.0.0": +"react-is@^18.0.0": + "integrity" "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + "resolved" "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz" + "version" "18.2.0" + +"react-redux@^7.2.1 || ^8.0.2", "react-redux@^8.1.3": + "integrity" "sha512-n0ZrutD7DaX/j9VscF+uTALI3oUPa/pO4Z3soOBIjuRn/FzVu6aehhysxZCLi6y7duMf52WNZGMl7CtuK5EnRw==" + "resolved" "https://registry.npmjs.org/react-redux/-/react-redux-8.1.3.tgz" + "version" "8.1.3" + dependencies: + "@babel/runtime" "^7.12.1" + "@types/hoist-non-react-statics" "^3.3.1" + "@types/use-sync-external-store" "^0.0.3" + "hoist-non-react-statics" "^3.3.2" + "react-is" "^18.0.0" + "use-sync-external-store" "^1.0.0" + +"react-select@^5.7.7": + "integrity" "sha512-HhashZZJDRlfF/AKj0a0Lnfs3sRdw/46VJIRd8IbB9/Ovr74+ZIwkAdSBjSPXsFMG+u72c5xShqwLSKIJllzqw==" + "resolved" "https://registry.npmjs.org/react-select/-/react-select-5.7.7.tgz" + "version" "5.7.7" + dependencies: + "@babel/runtime" "^7.12.0" + "@emotion/cache" "^11.4.0" + "@emotion/react" "^11.8.1" + "@floating-ui/dom" "^1.0.1" + "@types/react-transition-group" "^4.4.0" + "memoize-one" "^6.0.0" + "prop-types" "^15.6.0" + "react-transition-group" "^4.3.0" + "use-isomorphic-layout-effect" "^1.1.2" + +"react-simple-pull-to-refresh@^1.3.3": + "integrity" "sha512-6qXsa5RtNVmKJhLWvDLIX8UK51HFtCEGjdqQGf+M1Qjrcc4qH4fki97sgVpGEFBRwbY7DiVDA5N5p97kF16DTw==" + "resolved" "https://registry.npmjs.org/react-simple-pull-to-refresh/-/react-simple-pull-to-refresh-1.3.3.tgz" + "version" "1.3.3" + +"react-slick@^0.29.0": + "integrity" "sha512-TGdOKE+ZkJHHeC4aaoH85m8RnFyWqdqRfAGkhd6dirmATXMZWAxOpTLmw2Ll/jPTQ3eEG7ercFr/sbzdeYCJXA==" + "resolved" "https://registry.npmjs.org/react-slick/-/react-slick-0.29.0.tgz" + "version" "0.29.0" + dependencies: + "classnames" "^2.2.5" + "enquire.js" "^2.1.6" + "json2mq" "^0.2.0" + "lodash.debounce" "^4.0.8" + "resize-observer-polyfill" "^1.5.0" + +"react-toastify@^9.1.3": + "integrity" "sha512-fPfb8ghtn/XMxw3LkxQBk3IyagNpF/LIKjOBflbexr2AWxAH1MJgvnESwEwBn9liLFXgTKWgBSdZpw9m4OTHTg==" + "resolved" "https://registry.npmjs.org/react-toastify/-/react-toastify-9.1.3.tgz" + "version" "9.1.3" + dependencies: + "clsx" "^1.1.1" + +"react-transition-group@^4.3.0": + "integrity" "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==" + "resolved" "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz" + "version" "4.4.5" + dependencies: + "@babel/runtime" "^7.5.5" + "dom-helpers" "^5.0.1" + "loose-envify" "^1.4.0" + "prop-types" "^15.6.2" + +"react@*", "react@^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react@^16.10.2 || ^17.0.0 || ^18.0.0", "react@^16.5.1 || ^17.0.0 || ^18.0.0", "react@^16.8 || ^17.0 || ^18.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^16.9.0 || ^17.0.0 || ^18", "react@^18.0.0", "react@^18.2.0", "react@>= 16.8.0 || 17.x.x || ^18.0.0-0", "react@>=16", "react@>=16.6.0", "react@>=16.8.0", "react@>=17.0.0": "integrity" "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==" "resolved" "https://registry.npmjs.org/react/-/react-18.2.0.tgz" "version" "18.2.0" @@ -5479,6 +5797,23 @@ "indent-string" "^4.0.0" "strip-indent" "^3.0.0" +"redux-persist@^6.0.0": + "integrity" "sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ==" + "resolved" "https://registry.npmjs.org/redux-persist/-/redux-persist-6.0.0.tgz" + "version" "6.0.0" + +"redux-thunk@^2.4.2": + "integrity" "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==" + "resolved" "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz" + "version" "2.4.2" + +"redux@^4", "redux@^4 || ^5.0.0-beta.0", "redux@^4.2.1", "redux@>4.0.0": + "integrity" "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==" + "resolved" "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz" + "version" "4.2.1" + dependencies: + "@babel/runtime" "^7.9.2" + "regenerate-unicode-properties@^10.1.0": "integrity" "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==" "resolved" "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz" @@ -5496,6 +5831,11 @@ "resolved" "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz" "version" "0.13.7" +"regenerator-runtime@^0.14.0": + "integrity" "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" + "resolved" "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz" + "version" "0.14.0" + "regenerator-transform@^0.15.1": "integrity" "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==" "resolved" "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz" @@ -5536,6 +5876,16 @@ "resolved" "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" "version" "2.1.1" +"reselect@^4.1.8": + "integrity" "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==" + "resolved" "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz" + "version" "4.1.8" + +"resize-observer-polyfill@^1.5.0": + "integrity" "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + "resolved" "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz" + "version" "1.5.1" + "resolve-cwd@^3.0.0": "integrity" "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==" "resolved" "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz" @@ -5565,7 +5915,7 @@ "resolved" "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz" "version" "1.1.0" -"resolve@^1.1.7", "resolve@^1.10.0", "resolve@^1.14.2", "resolve@^1.20.0", "resolve@^1.22.0", "resolve@^1.22.2": +"resolve@^1.1.7", "resolve@^1.10.0", "resolve@^1.14.2", "resolve@^1.19.0", "resolve@^1.20.0", "resolve@^1.22.0", "resolve@^1.22.2": "integrity" "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==" "resolved" "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz" "version" "1.22.2" @@ -5774,6 +6124,11 @@ "buffer-from" "^1.0.0" "source-map" "^0.6.0" +"source-map@^0.5.7": + "integrity" "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==" + "resolved" "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz" + "version" "0.5.7" + "source-map@^0.6.0", "source-map@^0.6.1", "source-map@~0.6.1": "integrity" "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" "resolved" "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" @@ -5846,6 +6201,11 @@ "resolved" "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz" "version" "0.3.1" +"string-convert@^0.2.0": + "integrity" "sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==" + "resolved" "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz" + "version" "0.2.1" + "string-length@^4.0.1": "integrity" "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==" "resolved" "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz" @@ -5961,6 +6321,11 @@ dependencies: "client-only" "0.0.1" +"stylis@4.2.0": + "integrity" "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + "resolved" "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz" + "version" "4.2.0" + "sucrase@^3.32.0": "integrity" "sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ==" "resolved" "https://registry.npmjs.org/sucrase/-/sucrase-3.32.0.tgz" @@ -6030,6 +6395,11 @@ "csso" "^5.0.5" "picocolors" "^1.0.0" +"swiper@*", "swiper@^11.0.2": + "integrity" "sha512-JMHZYdUDG0V5ZdzWJkQicW4F7u4edmS4vlOhciTDhcZokDL2N8EE2uP4INxqIgpiJMoeHlwATqZk2yEAW7F6Dw==" + "resolved" "https://registry.npmjs.org/swiper/-/swiper-11.0.2.tgz" + "version" "11.0.2" + "symbol-tree@^3.2.4": "integrity" "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" "resolved" "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz" @@ -6350,6 +6720,16 @@ dependencies: "punycode" "^2.1.0" +"use-isomorphic-layout-effect@^1.1.2": + "integrity" "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==" + "resolved" "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz" + "version" "1.1.2" + +"use-sync-external-store@^1.0.0": + "integrity" "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==" + "resolved" "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz" + "version" "1.2.0" + "util-deprecate@^1.0.1", "util-deprecate@^1.0.2": "integrity" "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" "resolved" "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"