diff --git a/package-lock.json b/package-lock.json index 07f19d2..33765b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,8 +8,14 @@ "name": "project1-3.2", "version": "0.0.0", "dependencies": { + "animate.css": "^4.1.1", + "axios": "^1.6.2", + "bootstrap": "^5.3.2", "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-bootstrap": "^2.9.1", + "react-dom": "^18.2.0", + "react-router-dom": "^6.20.0", + "uuid": "^9.0.1" }, "devDependencies": { "@types/react": "^18.2.15", @@ -322,6 +328,17 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/runtime": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.5.tgz", + "integrity": "sha512-NdUTHcPe4C99WxPub+K9l9tK5/lV4UXIoaHSYgzco9BCyjKAAwzdBI+wWtYqHt7LJdbo74ZjRPJgzVweq1sz0w==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { "version": "7.22.15", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", @@ -910,6 +927,84 @@ "node": ">= 8" } }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@react-aria/ssr": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.0.tgz", + "integrity": "sha512-Bz6BqP6ZorCme9tSWHZVmmY+s7AU8l6Vl2NUYmBzezD//fVHHfFo4lFBn5tBuAaJEm3AuCLaJQ6H2qhxNSb7zg==", + "dependencies": { + "@swc/helpers": "^0.5.0" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + } + }, + "node_modules/@remix-run/router": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.13.0.tgz", + "integrity": "sha512-5dMOnVnefRsl4uRnAdoWjtVTdh8e6aZqgM4puy9nmEADH72ck+uXwzpJLEKE9Q6F8ZljNewLgmTfkxUrBdv4WA==", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@restart/hooks": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.11.tgz", + "integrity": "sha512-Ft/ncTULZN6ldGHiF/k5qt72O8JyRMOeg0tApvCni8LkoiEahO+z3TNxfXIVGy890YtWVDvJAl662dVJSJXvMw==", + "dependencies": { + "dequal": "^2.0.3" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@restart/ui": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.6.6.tgz", + "integrity": "sha512-eC3puKuWE1SRYbojWHXnvCNHGgf3uzHCb6JOhnF4OXPibOIPEkR1sqDSkL643ydigxwh+ruCa1CmYHlzk7ikKA==", + "dependencies": { + "@babel/runtime": "^7.21.0", + "@popperjs/core": "^2.11.6", + "@react-aria/ssr": "^3.5.0", + "@restart/hooks": "^0.4.9", + "@types/warning": "^3.0.0", + "dequal": "^2.0.3", + "dom-helpers": "^5.2.0", + "uncontrollable": "^8.0.1", + "warning": "^4.0.3" + }, + "peerDependencies": { + "react": ">=16.14.0", + "react-dom": ">=16.14.0" + } + }, + "node_modules/@restart/ui/node_modules/uncontrollable": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz", + "integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==", + "peerDependencies": { + "react": ">=16.14.0" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.3.tgz", + "integrity": "sha512-FaruWX6KdudYloq1AHD/4nU+UsMTdNE8CKyrseXWEcgjDAbvkwJg2QGPAnfIJLIWsjZOSPLOAykK6fuYp4vp4A==", + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@types/babel__core": { "version": "7.20.3", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.3.tgz", @@ -954,14 +1049,12 @@ "node_modules/@types/prop-types": { "version": "15.7.9", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.9.tgz", - "integrity": "sha512-n1yyPsugYNSmHgxDFjicaI2+gCNjsBck8UX9kuofAKlc0h1bL+20oSF72KeNaW2DUlesbEVCFgyV2dPGTiY42g==", - "dev": true + "integrity": "sha512-n1yyPsugYNSmHgxDFjicaI2+gCNjsBck8UX9kuofAKlc0h1bL+20oSF72KeNaW2DUlesbEVCFgyV2dPGTiY42g==" }, "node_modules/@types/react": { "version": "18.2.33", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.33.tgz", "integrity": "sha512-v+I7S+hu3PIBoVkKGpSYYpiBT1ijqEzWpzQD62/jm4K74hPpSP7FF9BnKG6+fg2+62weJYkkBWDJlZt5JO/9hg==", - "dev": true, "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -977,11 +1070,23 @@ "@types/react": "*" } }, + "node_modules/@types/react-transition-group": { + "version": "4.4.9", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.9.tgz", + "integrity": "sha512-ZVNmWumUIh5NhH8aMD9CR2hdW0fNuYInlocZHaZ+dgk/1K49j1w/HoAuK1ki+pgscQrOFRTlXeoURtuzEkV3dg==", + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/scheduler": { "version": "0.16.5", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.5.tgz", - "integrity": "sha512-s/FPdYRmZR8SjLWGMCuax7r3qCWQw9QKHzXVukAuuIJkXkDRwp+Pu5LMIVFi0Fxbav35WURicYr8u1QsoybnQw==", - "dev": true + "integrity": "sha512-s/FPdYRmZR8SjLWGMCuax7r3qCWQw9QKHzXVukAuuIJkXkDRwp+Pu5LMIVFi0Fxbav35WURicYr8u1QsoybnQw==" + }, + "node_modules/@types/warning": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.3.tgz", + "integrity": "sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q==" }, "node_modules/@ungap/structured-clone": { "version": "1.2.0", @@ -1045,6 +1150,11 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/animate.css": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/animate.css/-/animate.css-4.1.1.tgz", + "integrity": "sha512-+mRmCTv6SbCmtYJCN4faJMNFVNN5EuCTTprDTAo7YzIGji2KADmakjVA3+8mVDkZ2Bf09vayB35lSQIex2+QaQ==" + }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -1183,6 +1293,11 @@ "has-symbols": "^1.0.3" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, "node_modules/available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", @@ -1195,12 +1310,40 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/axios": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz", + "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/bootstrap": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.2.tgz", + "integrity": "sha512-D32nmNWiQHo94BKHLmOrdjlL05q1c8oxbtBphQFb9Z5to6eGRDCm0QgeaZ4zFBHzfg2++rqa2JkqCcxDy0sH0g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/twbs" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + } + ], + "peerDependencies": { + "@popperjs/core": "^2.11.8" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1300,6 +1443,11 @@ "node": ">=4" } }, + "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/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -1315,6 +1463,17 @@ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1344,8 +1503,7 @@ "node_modules/csstype": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", - "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==", - "dev": true + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" }, "node_modules/debug": { "version": "4.3.4", @@ -1401,6 +1559,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "engines": { + "node": ">=6" + } + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -1413,6 +1587,15 @@ "node": ">=6.0.0" } }, + "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/electron-to-chromium": { "version": "1.4.568", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.568.tgz", @@ -1966,6 +2149,25 @@ "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", "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/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -1975,6 +2177,19 @@ "is-callable": "^1.1.3" } }, + "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/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -2290,6 +2505,14 @@ "node": ">= 0.4" } }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, "node_modules/is-array-buffer": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", @@ -2757,6 +2980,25 @@ "yallist": "^3.0.2" } }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -2809,7 +3051,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -3059,13 +3300,29 @@ "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", "react-is": "^16.13.1" } }, + "node_modules/prop-types-extra": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz", + "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==", + "dependencies": { + "react-is": "^16.3.2", + "warning": "^4.0.0" + }, + "peerDependencies": { + "react": ">=0.14.0" + } + }, + "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/punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", @@ -3106,6 +3363,35 @@ "node": ">=0.10.0" } }, + "node_modules/react-bootstrap": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.9.1.tgz", + "integrity": "sha512-ezgmh/ARCYp18LbZEqPp0ppvy+ytCmycDORqc8vXSKYV3cer4VH7OReV8uMOoKXmYzivJTxgzGHalGrHamryHA==", + "dependencies": { + "@babel/runtime": "^7.22.5", + "@restart/hooks": "^0.4.9", + "@restart/ui": "^1.6.6", + "@types/react-transition-group": "^4.4.6", + "classnames": "^2.3.2", + "dom-helpers": "^5.2.1", + "invariant": "^2.2.4", + "prop-types": "^15.8.1", + "prop-types-extra": "^1.1.0", + "react-transition-group": "^4.4.5", + "uncontrollable": "^7.2.1", + "warning": "^4.0.3" + }, + "peerDependencies": { + "@types/react": ">=16.14.8", + "react": ">=16.14.0", + "react-dom": ">=16.14.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -3121,8 +3407,12 @@ "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/react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" }, "node_modules/react-refresh": { "version": "0.14.0", @@ -3133,6 +3423,51 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.20.0.tgz", + "integrity": "sha512-pVvzsSsgUxxtuNfTHC4IxjATs10UaAtvLGVSA1tbUE4GDaOSU1Esu2xF5nWLz7KPiMuW8BJWuPFdlGYJ7/rW0w==", + "dependencies": { + "@remix-run/router": "1.13.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.20.0.tgz", + "integrity": "sha512-CbcKjEyiSVpA6UtCHOIYLUYn/UJfwzp55va4yEfpk7JBN3GPqWfHrdLkAvNCcpXr8QoihcDMuk0dzWZxtlB/mQ==", + "dependencies": { + "@remix-run/router": "1.13.0", + "react-router": "6.20.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "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/reflect.getprototypeof": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz", @@ -3153,6 +3488,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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/regexp.prototype.flags": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", @@ -3510,6 +3850,11 @@ "node": ">=4" } }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -3614,6 +3959,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/uncontrollable": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz", + "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==", + "dependencies": { + "@babel/runtime": "^7.6.3", + "@types/react": ">=16.9.11", + "invariant": "^2.2.4", + "react-lifecycles-compat": "^3.0.4" + }, + "peerDependencies": { + "react": ">=15.0.0" + } + }, "node_modules/update-browserslist-db": { "version": "1.0.13", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", @@ -3653,6 +4012,18 @@ "punycode": "^2.1.0" } }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/vite": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.0.tgz", @@ -3708,6 +4079,14 @@ } } }, + "node_modules/warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -4040,6 +4419,14 @@ "@babel/helper-plugin-utils": "^7.22.5" } }, + "@babel/runtime": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.5.tgz", + "integrity": "sha512-NdUTHcPe4C99WxPub+K9l9tK5/lV4UXIoaHSYgzco9BCyjKAAwzdBI+wWtYqHt7LJdbo74ZjRPJgzVweq1sz0w==", + "requires": { + "regenerator-runtime": "^0.14.0" + } + }, "@babel/template": { "version": "7.22.15", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", @@ -4371,6 +4758,64 @@ "fastq": "^1.6.0" } }, + "@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==" + }, + "@react-aria/ssr": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.0.tgz", + "integrity": "sha512-Bz6BqP6ZorCme9tSWHZVmmY+s7AU8l6Vl2NUYmBzezD//fVHHfFo4lFBn5tBuAaJEm3AuCLaJQ6H2qhxNSb7zg==", + "requires": { + "@swc/helpers": "^0.5.0" + } + }, + "@remix-run/router": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.13.0.tgz", + "integrity": "sha512-5dMOnVnefRsl4uRnAdoWjtVTdh8e6aZqgM4puy9nmEADH72ck+uXwzpJLEKE9Q6F8ZljNewLgmTfkxUrBdv4WA==" + }, + "@restart/hooks": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.11.tgz", + "integrity": "sha512-Ft/ncTULZN6ldGHiF/k5qt72O8JyRMOeg0tApvCni8LkoiEahO+z3TNxfXIVGy890YtWVDvJAl662dVJSJXvMw==", + "requires": { + "dequal": "^2.0.3" + } + }, + "@restart/ui": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.6.6.tgz", + "integrity": "sha512-eC3puKuWE1SRYbojWHXnvCNHGgf3uzHCb6JOhnF4OXPibOIPEkR1sqDSkL643ydigxwh+ruCa1CmYHlzk7ikKA==", + "requires": { + "@babel/runtime": "^7.21.0", + "@popperjs/core": "^2.11.6", + "@react-aria/ssr": "^3.5.0", + "@restart/hooks": "^0.4.9", + "@types/warning": "^3.0.0", + "dequal": "^2.0.3", + "dom-helpers": "^5.2.0", + "uncontrollable": "^8.0.1", + "warning": "^4.0.3" + }, + "dependencies": { + "uncontrollable": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz", + "integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==", + "requires": {} + } + } + }, + "@swc/helpers": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.3.tgz", + "integrity": "sha512-FaruWX6KdudYloq1AHD/4nU+UsMTdNE8CKyrseXWEcgjDAbvkwJg2QGPAnfIJLIWsjZOSPLOAykK6fuYp4vp4A==", + "requires": { + "tslib": "^2.4.0" + } + }, "@types/babel__core": { "version": "7.20.3", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.3.tgz", @@ -4415,14 +4860,12 @@ "@types/prop-types": { "version": "15.7.9", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.9.tgz", - "integrity": "sha512-n1yyPsugYNSmHgxDFjicaI2+gCNjsBck8UX9kuofAKlc0h1bL+20oSF72KeNaW2DUlesbEVCFgyV2dPGTiY42g==", - "dev": true + "integrity": "sha512-n1yyPsugYNSmHgxDFjicaI2+gCNjsBck8UX9kuofAKlc0h1bL+20oSF72KeNaW2DUlesbEVCFgyV2dPGTiY42g==" }, "@types/react": { "version": "18.2.33", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.33.tgz", "integrity": "sha512-v+I7S+hu3PIBoVkKGpSYYpiBT1ijqEzWpzQD62/jm4K74hPpSP7FF9BnKG6+fg2+62weJYkkBWDJlZt5JO/9hg==", - "dev": true, "requires": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -4438,11 +4881,23 @@ "@types/react": "*" } }, + "@types/react-transition-group": { + "version": "4.4.9", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.9.tgz", + "integrity": "sha512-ZVNmWumUIh5NhH8aMD9CR2hdW0fNuYInlocZHaZ+dgk/1K49j1w/HoAuK1ki+pgscQrOFRTlXeoURtuzEkV3dg==", + "requires": { + "@types/react": "*" + } + }, "@types/scheduler": { "version": "0.16.5", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.5.tgz", - "integrity": "sha512-s/FPdYRmZR8SjLWGMCuax7r3qCWQw9QKHzXVukAuuIJkXkDRwp+Pu5LMIVFi0Fxbav35WURicYr8u1QsoybnQw==", - "dev": true + "integrity": "sha512-s/FPdYRmZR8SjLWGMCuax7r3qCWQw9QKHzXVukAuuIJkXkDRwp+Pu5LMIVFi0Fxbav35WURicYr8u1QsoybnQw==" + }, + "@types/warning": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.3.tgz", + "integrity": "sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q==" }, "@ungap/structured-clone": { "version": "1.2.0", @@ -4488,6 +4943,11 @@ "uri-js": "^4.2.2" } }, + "animate.css": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/animate.css/-/animate.css-4.1.1.tgz", + "integrity": "sha512-+mRmCTv6SbCmtYJCN4faJMNFVNN5EuCTTprDTAo7YzIGji2KADmakjVA3+8mVDkZ2Bf09vayB35lSQIex2+QaQ==" + }, "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -4593,18 +5053,39 @@ "has-symbols": "^1.0.3" } }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, "available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", "dev": true }, + "axios": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz", + "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==", + "requires": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "bootstrap": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.2.tgz", + "integrity": "sha512-D32nmNWiQHo94BKHLmOrdjlL05q1c8oxbtBphQFb9Z5to6eGRDCm0QgeaZ4zFBHzfg2++rqa2JkqCcxDy0sH0g==", + "requires": {} + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -4661,6 +5142,11 @@ "supports-color": "^5.3.0" } }, + "classnames": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -4676,6 +5162,14 @@ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -4702,8 +5196,7 @@ "csstype": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", - "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==", - "dev": true + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" }, "debug": { "version": "4.3.4", @@ -4742,6 +5235,16 @@ "object-keys": "^1.1.1" } }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, + "dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==" + }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -4751,6 +5254,15 @@ "esutils": "^2.0.2" } }, + "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" + } + }, "electron-to-chromium": { "version": "1.4.568", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.568.tgz", @@ -5180,6 +5692,11 @@ "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", "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==" + }, "for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -5189,6 +5706,16 @@ "is-callable": "^1.1.3" } }, + "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" + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -5407,6 +5934,14 @@ "side-channel": "^1.0.4" } }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "requires": { + "loose-envify": "^1.0.0" + } + }, "is-array-buffer": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", @@ -5739,6 +6274,19 @@ "yallist": "^3.0.2" } }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -5775,8 +6323,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, "object-inspect": { "version": "1.13.1", @@ -5946,13 +6493,26 @@ "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", "react-is": "^16.13.1" } }, + "prop-types-extra": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz", + "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==", + "requires": { + "react-is": "^16.3.2", + "warning": "^4.0.0" + } + }, + "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==" + }, "punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", @@ -5973,6 +6533,25 @@ "loose-envify": "^1.1.0" } }, + "react-bootstrap": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.9.1.tgz", + "integrity": "sha512-ezgmh/ARCYp18LbZEqPp0ppvy+ytCmycDORqc8vXSKYV3cer4VH7OReV8uMOoKXmYzivJTxgzGHalGrHamryHA==", + "requires": { + "@babel/runtime": "^7.22.5", + "@restart/hooks": "^0.4.9", + "@restart/ui": "^1.6.6", + "@types/react-transition-group": "^4.4.6", + "classnames": "^2.3.2", + "dom-helpers": "^5.2.1", + "invariant": "^2.2.4", + "prop-types": "^15.8.1", + "prop-types-extra": "^1.1.0", + "react-transition-group": "^4.4.5", + "uncontrollable": "^7.2.1", + "warning": "^4.0.3" + } + }, "react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -5985,8 +6564,12 @@ "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==" + }, + "react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" }, "react-refresh": { "version": "0.14.0", @@ -5994,6 +6577,34 @@ "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==", "dev": true }, + "react-router": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.20.0.tgz", + "integrity": "sha512-pVvzsSsgUxxtuNfTHC4IxjATs10UaAtvLGVSA1tbUE4GDaOSU1Esu2xF5nWLz7KPiMuW8BJWuPFdlGYJ7/rW0w==", + "requires": { + "@remix-run/router": "1.13.0" + } + }, + "react-router-dom": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.20.0.tgz", + "integrity": "sha512-CbcKjEyiSVpA6UtCHOIYLUYn/UJfwzp55va4yEfpk7JBN3GPqWfHrdLkAvNCcpXr8QoihcDMuk0dzWZxtlB/mQ==", + "requires": { + "@remix-run/router": "1.13.0", + "react-router": "6.20.0" + } + }, + "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" + } + }, "reflect.getprototypeof": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz", @@ -6008,6 +6619,11 @@ "which-builtin-type": "^1.1.3" } }, + "regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" + }, "regexp.prototype.flags": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", @@ -6253,6 +6869,11 @@ "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true }, + "tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -6327,6 +6948,17 @@ "which-boxed-primitive": "^1.0.2" } }, + "uncontrollable": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz", + "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==", + "requires": { + "@babel/runtime": "^7.6.3", + "@types/react": ">=16.9.11", + "invariant": "^2.2.4", + "react-lifecycles-compat": "^3.0.4" + } + }, "update-browserslist-db": { "version": "1.0.13", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", @@ -6346,6 +6978,11 @@ "punycode": "^2.1.0" } }, + "uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==" + }, "vite": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.0.tgz", @@ -6358,6 +6995,14 @@ "rollup": "^3.27.1" } }, + "warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "requires": { + "loose-envify": "^1.0.0" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index f46c43f..2d4660d 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,14 @@ "preview": "vite preview" }, "dependencies": { + "animate.css": "^4.1.1", + "axios": "^1.6.2", + "bootstrap": "^5.3.2", "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-bootstrap": "^2.9.1", + "react-dom": "^18.2.0", + "react-router-dom": "^6.20.0", + "uuid": "^9.0.1" }, "devDependencies": { "@types/react": "^18.2.15", diff --git a/src/App.css b/src/App.css index b9d355d..bede3be 100644 --- a/src/App.css +++ b/src/App.css @@ -1,42 +1,5 @@ -#root { - max-width: 1280px; - margin: 0 auto; - padding: 2rem; - text-align: center; -} - -.logo { - height: 6em; - padding: 1.5em; - will-change: filter; - transition: filter 300ms; -} -.logo:hover { - filter: drop-shadow(0 0 2em #646cffaa); -} -.logo.react:hover { - filter: drop-shadow(0 0 2em #61dafbaa); -} - -@keyframes logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} - -@media (prefers-reduced-motion: no-preference) { - a:nth-of-type(2) .logo { - animation: logo-spin infinite 20s linear; - } -} - -.card { - padding: 2em; -} +@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;600;700&display=swap'); -.read-the-docs { - color: #888; +body { + background-color: rgb(255, 255, 255) } diff --git a/src/App.jsx b/src/App.jsx index e033eca..c59fce2 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,17 +1,146 @@ -import logo from "/logo.png"; +import NavBar from "./components/Navbar/Navbar"; +import { Routes, Route } from "react-router-dom"; +import QuoteWrapper from "./components/RandomQuote/QuoteWrapper"; +import Home from "./components/Start/Home.jsx"; +import ChangeUser from "./components/ChangeUser/ChangeUser.jsx"; +import Create from "./components/Create/Create.jsx"; +import Saved from "./components/Saved/Saved.jsx"; +import Viewed from "./components/Viewed/Viewed.jsx"; +import { useState } from "react"; +import "bootstrap/dist/css/bootstrap.min.css"; import "./App.css"; +import QuoteX from "./components/Home/QuoteX.jsx"; function App() { + const [users, setUsers] = useState([ + { username: "Kelly", saved: [], created: [] }, + { username: "Jeremy", saved: [], created: [] } + ]); + const [currUser, setCurrUser] = useState("") + const [viewedQuotes, setViewedQuotes] = useState([]) + + const addUser = (name) => { + setUsers([...users, { + username: name, + saved: [], + created: [] + }]) + } + + const addViewedQuotes = (quote) => { + setViewedQuotes([...viewedQuotes, quote]) + } + + const changeCurrUser = (name) => { + setCurrUser(name); + } + + const handleSaved = (username, quote) => { + console.log(quote) + setUsers( + users.map((user) => + user.username === username + ? { ...user, saved: [...user.saved, quote] } + : user + ) + ); + } + + const handleCreate = (username, quote) => { + setUsers( + users.map((user) => + user.username === username + ? { ...user, created: [...user.created, quote] } + : user + ) + ); + } + + const handleDelete = (username, quote, saveOrcreated) => { + if (saveOrcreated == "saved") { + setUsers( + users.map((user) => + user.username === username + ? { ...user, saved: user.saved.filter((item) => item !== quote) } + : user + ) + ); + } else if (saveOrcreated == "created"){ + setUsers( + users.map((user) => + user.username === username + ? { + ...user, + created: user.created.filter((item) => item !== quote), + } + : user + ) + ); + } + + } + return ( <> -
- logo -
-

Project 1

-
-

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

+
+ + + + } + /> + + } + /> + + } + /> + } + /> + + } + /> + } + /> + + } + /> +
); diff --git a/src/components/ChangeUser/ChangeUser.css b/src/components/ChangeUser/ChangeUser.css new file mode 100644 index 0000000..c2149dc --- /dev/null +++ b/src/components/ChangeUser/ChangeUser.css @@ -0,0 +1,14 @@ +.changeuser-container { + margin-top: 2rem; + margin-left: auto; + margin-right: auto; + width: 40%; +} + +.changeuser-input { + margin: 1rem 0 1rem 0; +} + +.concluding { + margin: 1rem 0 1rem 0; +} \ No newline at end of file diff --git a/src/components/ChangeUser/ChangeUser.jsx b/src/components/ChangeUser/ChangeUser.jsx new file mode 100644 index 0000000..213cb41 --- /dev/null +++ b/src/components/ChangeUser/ChangeUser.jsx @@ -0,0 +1,54 @@ +import React, {useState} from 'react' +import "./ChangeUser.css" +import {Form, Button} from "react-bootstrap" +import ModalAlert from "../RandomQuote/Modal"; + +function ChangeUser({username, options, changeCurrUser}) { + const [selectedOption, setSelectedOption] = useState("") + const [modalShow, setModalShow] = useState(false); + + const handleChange = (event) => { + setSelectedOption(event.target.value); + }; + + const handleClick = () => { + setModalShow(true); + changeCurrUser(selectedOption) + } + + return ( +
+

Hello, {username}

+
+ + + + {options.map((option, index) => ( + + ))} + +
+ + +
To add new user, please go to "Get Started"
+ + setModalShow(false)} + text="Changed" + > + +
+ ); +} + +export default ChangeUser \ No newline at end of file diff --git a/src/components/Create/Create.css b/src/components/Create/Create.css new file mode 100644 index 0000000..21c3638 --- /dev/null +++ b/src/components/Create/Create.css @@ -0,0 +1,10 @@ +.create-container { + margin-top: 2rem; + margin-left: auto; + margin-right: auto; + width: 40%; +} + +.create-input { + +} \ No newline at end of file diff --git a/src/components/Create/Create.jsx b/src/components/Create/Create.jsx new file mode 100644 index 0000000..cd1cab6 --- /dev/null +++ b/src/components/Create/Create.jsx @@ -0,0 +1,63 @@ +import React, {useState} from 'react' +import ModalAlert from '../RandomQuote/Modal'; +import {Form, Button} from "react-bootstrap"; +import "./Create.css" + +function Create({username, handleCreate}) { + const [quote, setQuote] = useState(""); + const [category, setCategory] = useState("") + const [modalShow, setModalShow] = useState(false); + + const handleText = (event) => { + setQuote(event.target.value); + } + + const handleCategory = (event) => { + setCategory(event.target.value) + } + + const createQuote = () => { + event.preventDefault() + if(username == "") { + return + } else { + const newQuote = { + text: quote, + author: username, + category: category + }; + setModalShow(true); + handleCreate(username, newQuote); + } + }; + + return ( +
+

Hello, {username}

+
+ + Write Your Own Quote + + + + Category + + + +
+ setModalShow(false)} + text="Created" + > +
+ ); +} + +export default Create \ No newline at end of file diff --git a/src/components/Home/Inspire.jpg b/src/components/Home/Inspire.jpg new file mode 100644 index 0000000..6794161 Binary files /dev/null and b/src/components/Home/Inspire.jpg differ diff --git a/src/components/Home/QuoteX.css b/src/components/Home/QuoteX.css new file mode 100644 index 0000000..4aecd50 --- /dev/null +++ b/src/components/Home/QuoteX.css @@ -0,0 +1,16 @@ +.quotex-container { + margin-top: 2rem; + margin-left: auto; + margin-right: auto; + width: 60%; +} + +.first-row-second-col { + display: flex; + flex-direction: column; + justify-content: center; +} + +.first-row { + background-color: bisque; +} \ No newline at end of file diff --git a/src/components/Home/QuoteX.jsx b/src/components/Home/QuoteX.jsx new file mode 100644 index 0000000..8a161a8 --- /dev/null +++ b/src/components/Home/QuoteX.jsx @@ -0,0 +1,90 @@ +import React from 'react' +import { Container, Row, Col, Image, Button, Card } from 'react-bootstrap' +import { Link } from "react-router-dom" +import "./QuoteX.css" + +function QuoteX() { + return ( +
+ + + + + + +

Life's Tough.

+

Get Inspired.

+ + +
+ +

Recent Quotes Made By Our Users

+
+ + + + + Mahatma Gandhi + + You must be the change you wish to see in the world. + + + + + + + + Aristotle + + It is during our darkest moments that we must focus to see the + light. + + + + + + + + Confucius + + It does not matter how slowly you go, as long as you do not + stop. + + + + + + + + Today's Featured Quote + + Ralph Waldo Emerson + + The only person you are destined to become is the person you + decide to be. + + + + +
+
+ ); +} + +export default QuoteX \ No newline at end of file diff --git a/src/components/Navbar/Navbar.css b/src/components/Navbar/Navbar.css new file mode 100644 index 0000000..515e580 --- /dev/null +++ b/src/components/Navbar/Navbar.css @@ -0,0 +1,3 @@ +.navbar-container { +} + diff --git a/src/components/Navbar/Navbar.jsx b/src/components/Navbar/Navbar.jsx new file mode 100644 index 0000000..acee581 --- /dev/null +++ b/src/components/Navbar/Navbar.jsx @@ -0,0 +1,43 @@ +import React from 'react' +import { Link, NavLink } from 'react-router-dom'; +import { Navbar, Nav, Container, NavDropdown } from 'react-bootstrap'; +import './Navbar.css' + +function NavBar() { + return ( + <> + + + + + + + + + + ); +} + +export default NavBar \ No newline at end of file diff --git a/src/components/RandomQuote/ApiNinja.jsx b/src/components/RandomQuote/ApiNinja.jsx new file mode 100644 index 0000000..70429b9 --- /dev/null +++ b/src/components/RandomQuote/ApiNinja.jsx @@ -0,0 +1,46 @@ +import React, { useState, useEffect } from "react"; +import axios from "axios"; + +const ApiNinja = () => { + const [quotes, setQuotes] = useState([]); + const [error, setError] = useState(""); + + useEffect(() => { + const apiKey = "1naX24kV6w8xEHsS9W4vYw==gz8Kl5FF27xnEfjY"; + const category = "happiness"; + const url = `https://api.api-ninjas.com/v1/quotes?category=${category}`; + + axios + .get(url, { + headers: { + "X-Api-Key": apiKey, + }, + }) + .then((response) => { + setQuotes(response.data); + }) + .catch((error) => { + if (error.response) { + setError(`Error: ${error.response.status} - ${error.response.data}`); + } else if (error.request) { + setError("Error: No response received from server"); + } else { + setError("Error: " + error.message); + } + }); + }, []); + + return ( +
+

From API Ninja:

+ {error ?

{error}

: null} + +
+ ); +}; + +export default ApiNinja; diff --git a/src/components/RandomQuote/Modal.jsx b/src/components/RandomQuote/Modal.jsx new file mode 100644 index 0000000..f7d4f8c --- /dev/null +++ b/src/components/RandomQuote/Modal.jsx @@ -0,0 +1,27 @@ +import React from "react"; +import { Button, Modal } from "react-bootstrap"; + +const ModalAlert = (props) => { + return ( + + + + Alert! + + + +

{props.text}

+
+ + + +
+ ); +}; + +export default ModalAlert; diff --git a/src/components/RandomQuote/Quote.jsx b/src/components/RandomQuote/Quote.jsx new file mode 100644 index 0000000..a0c33a1 --- /dev/null +++ b/src/components/RandomQuote/Quote.jsx @@ -0,0 +1,42 @@ +import React, { useState } from 'react' +import Button from "react-bootstrap/Button"; +import Card from "react-bootstrap/Card"; +import "animate.css"; + +function Quote({quote, author, nextQuote, saveThis}) { + const [generate, setGenerate] = useState(false) + const [modalShow, setModalShow] = useState(false); + + const generateQuote = () => { + nextQuote(); + setGenerate(true) + } + + return ( + <> +
+ + +
+ {generate ? ( +
+ + Here's a nice quote for you... + +
+

{quote}

+
{author}
+
+
+
+
+ ) : null} + + ); +} + +export default Quote \ No newline at end of file diff --git a/src/components/RandomQuote/QuoteWrapper.css b/src/components/RandomQuote/QuoteWrapper.css new file mode 100644 index 0000000..78afb13 --- /dev/null +++ b/src/components/RandomQuote/QuoteWrapper.css @@ -0,0 +1,30 @@ +.quote-wrapper { + margin-top: 2rem; + margin-left: auto; + margin-right: auto; + width: 40%; +} + +.input-wrapper { + display: flex; + justify-content: left; + gap: 2rem; + width: 100%; + margin-top: 1rem; +} + +.quote-container { + margin-top: 1rem; +} + +.quote-buttons { + display: flex; + gap: 5px; + margin: 1rem 0 1rem 0; +} + +.input-field { + background-color: rgb(205, 249, 255); + padding: 0.5rem; + border-radius: 5%; +} \ No newline at end of file diff --git a/src/components/RandomQuote/QuoteWrapper.jsx b/src/components/RandomQuote/QuoteWrapper.jsx new file mode 100644 index 0000000..c7fca36 --- /dev/null +++ b/src/components/RandomQuote/QuoteWrapper.jsx @@ -0,0 +1,111 @@ +import React, {useState, useEffect} from 'react' +import Quote from './Quote' +import UserInput from './UserInput' +import ModalAlert from "./Modal.jsx"; +import { getCategory, getAuthors, getWord, getWordFromTF } from '../../utils'; +import "./QuoteWrapper.css" + +function QuoteWrapper({username, users, handleSaved, addViewedQuotes}) { + const [category, setCategory] = useState(""); + const [author, setAuthor] = useState(""); + const [quote, setQuote] = useState({}); + const [saveThisQuote, setSaveThisQuote] = useState(false) + const [modalShow, setModalShow] = useState(false); + + //Obtain quotes from TF + let quotesFromTF = [] + getWordFromTF() + .then((quotes) => + quotes.map((quote) => { + return { + ...quote, + author: quote.author.split(",")[0], + }; + }) + ) + .then(quotes => quotesFromTF = quotes); + + const handleCategoryChange = (value) => { + setCategory(value); + }; + + + const handleAuthorChange = (value) => { + setAuthor(value); + }; + + const nextQuote = () => { + let categories = [] + let searchedWord = "" + if(category == "" && author == "") { + searchedWord = "random" + } else { + categories = [category, author] + } + let newQuote = (searchedWord == "random") ? + quotesFromTF[Math.floor(Math.random() * quotesFromTF.length)]: + getWord(categories) + setQuote(newQuote) + }; + + const saveThis = () => { + setModalShow(true); + setSaveThisQuote(true) + } + + const closeSave = () => { + setModalShow(false) + setSaveThisQuote(false) + } + + useEffect(() => { + if (!(quote.text == null)) { + handleSaved(username, quote); + setQuote({}) + } else { + null; + } + }, [saveThisQuote]) + + useEffect(() => { + if(!(quote.text == null)) { + addViewedQuotes(quote); + } else { + null + } + },[quote]) + + return ( +
+

Hello, {username}

+
+ + +
+ + + closeSave()} + text="Saved" + > +
+ ); +} + +export default QuoteWrapper \ No newline at end of file diff --git a/src/components/RandomQuote/UserInput.jsx b/src/components/RandomQuote/UserInput.jsx new file mode 100644 index 0000000..c856b7d --- /dev/null +++ b/src/components/RandomQuote/UserInput.jsx @@ -0,0 +1,38 @@ +import React, { useEffect } from "react"; +import { useState } from "react" +import Form from "react-bootstrap/Form"; +import "./QuoteWrapper.css" + + +function UserInput({inputLabel, optionName, onDropdownChange, options}) { + const [selectedOption, setSelectedOption] = useState(""); + + const handleChange = (event) => { + setSelectedOption(event.target.value); + }; + + useEffect(() => { + onDropdownChange(selectedOption) + }, [selectedOption]) + + return ( + + {inputLabel} + + + {options.map((option, index) => ( + + ))} + + + ); +} + +export default UserInput; diff --git a/src/components/Saved/QuoteCard.jsx b/src/components/Saved/QuoteCard.jsx new file mode 100644 index 0000000..d295325 --- /dev/null +++ b/src/components/Saved/QuoteCard.jsx @@ -0,0 +1,22 @@ +import React from 'react' +import { Button, Card } from "react-bootstrap"; + +function QuoteCard({username, quote, handleDelete, saveOrCreated}) { + + const handleClick = () => { + handleDelete(username, quote, saveOrCreated) + } + return ( + <> + + + {quote.author} + {quote.text} + + + + + ); +} + +export default QuoteCard \ No newline at end of file diff --git a/src/components/Saved/Saved.css b/src/components/Saved/Saved.css new file mode 100644 index 0000000..785debb --- /dev/null +++ b/src/components/Saved/Saved.css @@ -0,0 +1,12 @@ +.saved-container { + margin-top: 2rem; + margin-left: auto; + margin-right: auto; + width: 50%; +} + +.saved-list { + display: flex; + flex-wrap: wrap; + gap: 5px; +} \ No newline at end of file diff --git a/src/components/Saved/Saved.jsx b/src/components/Saved/Saved.jsx new file mode 100644 index 0000000..2340976 --- /dev/null +++ b/src/components/Saved/Saved.jsx @@ -0,0 +1,48 @@ +import React from 'react' +import QuoteCard from './QuoteCard'; +import "./Saved.css" + +function Saved({username, users, handleDelete}) { + return ( +
+

Hello, {username}

+
+
Saved Quotes:
+
+ {users.map((user) => + user.username === username + ? user.saved.map((quote, index) => ( + + )) + : null + )} +
+
+ +
Created Quotes:
+
+ {users.map((user) => + user.username === username + ? user.created.map((quote, index) => ( + + )) + : null + )} +
+
+ ); +} + +export default Saved \ No newline at end of file diff --git a/src/components/Start/Home.css b/src/components/Start/Home.css new file mode 100644 index 0000000..5442e85 --- /dev/null +++ b/src/components/Start/Home.css @@ -0,0 +1,19 @@ +.home-container { + display: flex; + flex-direction: column; + align-items: center; +} + +.home-greet { + margin: 2rem; + font-size:2.5rem; +} + +.home-answer { + background-color:rgb(250, 255, 194); + padding: 1rem; + margin: 2rem; + border-radius: 5%; + text-align: center; + width: 30%; +} \ No newline at end of file diff --git a/src/components/Start/Home.jsx b/src/components/Start/Home.jsx new file mode 100644 index 0000000..35331dc --- /dev/null +++ b/src/components/Start/Home.jsx @@ -0,0 +1,41 @@ +import React, { useState } from 'react' +import './Home.css' +import "animate.css"; + +function Home({addUser, user, changeCurrUser}) { + const [tempUser, setTempUser] = useState(""); + const [showGreet, setShowGreet] = useState(false); + + const greetUser = () => { + addUser(tempUser); + setShowGreet(true); + changeCurrUser(tempUser); + } + + const handleChange = (event) => { + setTempUser(event.target.value) + } + + return ( + <> +
+
Hello, what is your name?
+
+ handleChange(e)}> + +
+ + {showGreet ? ( +
+

Hello, {user}

+

Ready to be inspired?

+
+
Click "Quote" to Begin!
+
+ ) : null} +
+ + ); +} + +export default Home \ No newline at end of file diff --git a/src/components/Viewed/Viewed.jsx b/src/components/Viewed/Viewed.jsx new file mode 100644 index 0000000..cda4d46 --- /dev/null +++ b/src/components/Viewed/Viewed.jsx @@ -0,0 +1,18 @@ +import React from 'react' + +function Viewed ({username, viewedQuotes}) { + return ( +
+

Viewed Quotes:

+ +
+ ); +} + +export default Viewed \ No newline at end of file diff --git a/src/index.css b/src/index.css deleted file mode 100644 index 2c3fac6..0000000 --- a/src/index.css +++ /dev/null @@ -1,69 +0,0 @@ -:root { - font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; - line-height: 1.5; - font-weight: 400; - - color-scheme: light dark; - color: rgba(255, 255, 255, 0.87); - background-color: #242424; - - font-synthesis: none; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - -webkit-text-size-adjust: 100%; -} - -a { - font-weight: 500; - color: #646cff; - text-decoration: inherit; -} -a:hover { - color: #535bf2; -} - -body { - margin: 0; - display: flex; - place-items: center; - min-width: 320px; - min-height: 100vh; -} - -h1 { - font-size: 3.2em; - line-height: 1.1; -} - -button { - border-radius: 8px; - border: 1px solid transparent; - padding: 0.6em 1.2em; - font-size: 1em; - font-weight: 500; - font-family: inherit; - background-color: #1a1a1a; - cursor: pointer; - transition: border-color 0.25s; -} -button:hover { - border-color: #646cff; -} -button:focus, -button:focus-visible { - outline: 4px auto -webkit-focus-ring-color; -} - -@media (prefers-color-scheme: light) { - :root { - color: #213547; - background-color: #ffffff; - } - a:hover { - color: #747bff; - } - button { - background-color: #f9f9f9; - } -} diff --git a/src/main.jsx b/src/main.jsx index 54b39dd..bbfa59c 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -1,10 +1,12 @@ import React from 'react' import ReactDOM from 'react-dom/client' import App from './App.jsx' -import './index.css' +import { BrowserRouter } from 'react-router-dom' ReactDOM.createRoot(document.getElementById('root')).render( - + + + , ) diff --git a/src/quotes.json b/src/quotes.json new file mode 100644 index 0000000..9403752 --- /dev/null +++ b/src/quotes.json @@ -0,0 +1,192 @@ +[ + { + "text": "Many of life's failures are people who did not realize how close they were to success when they gave up.", + "author": "Thomas Edison", + "category": ["Encouraging"] + }, + { + "text": "Believe you can and you're halfway there.", + "author": "Theodore Roosevelt", + "category": ["Encouraging"] + }, + { + "text": "Nothing is Possible. The word itself is 'I'm Possible'", + "author": "Unknown", + "category": ["Encouraging"] + }, + { + "text": "Even the darkest night will end and the sun will rise.", + "author": "Les Misérables", + "category": ["Encouraging"] + }, + { + "text": "If you're going through hell, keep going.", + "author": "Winston Churchill", + "category": ["Encouraging"] + }, + { + "text": "It does not matter how slowly you go as long as you do not stop.", + "author": "Confucius", + "category": ["Encouraging"] + }, + { + "text": "If Plan A doesn't work, there are 25 more letters in the alphabet.", + "author": "Confucius", + "category": ["Encouraging"] + }, + { + "text": "If you can dream it, you can do it.", + "author": "Walt Disney", + "category": ["Inspiring"] + }, + { + "text": "Don't count the days, make the days count.", + "author": "Muhammad Ali", + "category": ["Inspiring"] + }, + { + "text": "The best and most beautiful things in the world cannot be seen or even touched - they must be felt with the heart.", + "author": "Helen Keller", + "category": ["Inspiring"] + }, + { + "text": "Perfection is not attainable, but if we chase perfection we can catch excellence.", + "author": "Vince Lombardi", + "category": ["Inspiring"] + }, + { + "text": "Before you marry a person, you should first make them use a computer with slow Internet to see who they really are.", + "author": "Will Ferrell", + "category": ["Funny"] + }, + { + "text": "People say love is the best feeling, but I think finding a toilet when you are having diarrhea is better", + "author": "Unknown", + "category": ["Funny"] + }, + { + "text": "My advice to you is get married: If you find a good wife you'll be happy; if not, you'll become a philosopher", + "author": "Socrates", + "category": ["Funny"] + }, + { + "text": "Two things are infinite: the universe and human stupidity. And I'm not sure about the universe.", + "author": "Albert Einstein", + "category": ["Funny"] + }, + { + "text": "The best way to teach your kids about taxes is by eating 30 percent of their ice cream", + "author": "Albert Einstein", + "category": ["Funny"] + }, + { + "text": "If you think nobody cares if you’re alive, try missing a couple of car payments.", + "author": "Earl Wilson", + "category": ["Funny"] + }, + { + "text": "Always code as if the person who ends up maintaining your code will be a violent psychopath who knows where you live.", + "author": "Unknown", + "category": ["Coding"] + }, + { + "text": "Give someone a program; you frustrate them for a day; teach them how to program, and you frustrate them for a lifetime", + "author": "David Leinweber", + "category": ["Coding"] + }, + { + "text": "If the code doesn't bother you, don't bother it.", + "author": "Unknown", + "category": ["Coding"] + }, + { + "text": "You never finish a program, you just stop working on it.", + "author": "Unknown", + "category": ["Coding"] + }, + { + "text": "Programming today is a race between software engineers striving to build bigger and better idiot-proof programs and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.", + "author": "Rick Cook", + "category": ["Coding"] + }, + { + "text": "There is always one more bug to fix.", + "author": "Ellen Ullman", + "category": ["Coding"] + }, + { + "text": "Sometimes it pays to stay in bed on Monday, rather than spending the rest of the week debugging Monday's code.", + "author": "Dan Salomon", + "category": ["Coding"] + }, + { + "text": "Java is to Javascript what car is to Carpet.", + "author": "Chris Heilmann", + "category": ["Coding"] + }, + { + "text": "The best way to appreciate your job is to imagine yourself without one.", + "author": "Oscar Wilde", + "category": ["Work"] + }, + { + "text": "Every day I get up and look through the Forbes list of the richest people in America. If I'm not there, I go to work.", + "author": "Robert Orben", + "category": ["Work"] + }, + { + "text": "I always give 100% at Work: 10% Monday, 23% Tuesday, 40% Wednesday, 22% Thursday, and 5% Friday.", + "author": "Unknown", + "category": ["Work"] + }, + { + "text": "My boss told me to start every presentation with a joke. The first slide was my paycheck.", + "author": "Unknown", + "category": ["Work"] + }, + { + "text": "I love deadlines. I like the whooshing sound they make as they fly by.", + "author": "Douglas Adams", + "category": ["Work"] + }, + { + "text": "I always arrive late at the office, but I make up for it by leaving early.", + "author": "Charles Lamb", + "category": ["Work"] + }, + { + "text": "I always arrive late at the office, but I make up for it by leaving early.", + "author": "Charles Lamb", + "category": ["Work"] + }, + { + "text": "The best abs exercise is five sets of stop eating so much", + "author": "Lazar Angelov", + "category": ["Health"] + }, + { + "text": "It's no longer a question of staying healthy. It's a question of finding a sickness you like.", + "author": "Unknown", + "category": ["Health"] + }, + { + "text": "We do not stop exercising because we grow old - we grow old because we stop exercising.", + "author": "Kenneth Cooper", + "category": ["Health"] + }, + { + "text": "I don't have a favorite programming language, I just hate them all equally.", + "author": "Unknown", + "category": ["Coding"] + }, + { + "text": "I'm not a bug, I'm a feature in disguise.", + "author": "Unknown", + "category": ["Coding"] + }, + { + "text": "The best thing about a boolean is even if you are wrong, you are only off by a bit.", + "author": "Unknown", + "category": ["Coding"] + } +] diff --git a/src/utils.jsx b/src/utils.jsx new file mode 100644 index 0000000..9d46f1c --- /dev/null +++ b/src/utils.jsx @@ -0,0 +1,52 @@ +import quotes from "./quotes.json"; + +//From Own Database +export const getWord = (category) => { + let matchingQuotes = []; + if (category[1] != "") { + for (const quote of quotes) { + quote.author.includes(category[1]) ? + matchingQuotes.push(quote) : null + } + } else if (category[0] != ""){ + for (const quote of quotes) { + quote.category.includes(category[0]) ? + matchingQuotes.push(quote) : null + } + } + + const defaultQuote = { + text: "No Quote Found", + author: "NA" + } + let matchingQuote = matchingQuotes.length > 0? matchingQuotes[Math.floor(Math.random() * matchingQuotes.length)] : defaultQuote + return matchingQuote +}; + +export const getAuthors = () => { + let authors = new Set(); + for (const quote of quotes) { + authors.add(quote.author); + } + return [...authors]; +} + +export const getCategory = () => { + let category = new Set(); + for (const quote of quotes) { + category.add(quote.category[0]); + } + return [...category]; +}; + +//From https://type.fit/api/quotes +export const getWordFromTF = async () => { + let tfQuotes = [] + const response = await fetch("https://type.fit/api/quotes"); + tfQuotes = await response.json(); + return tfQuotes +} + +//From API Ninjia + +