From fcc309d570d1fe08d1b18ab80fdcaa26b9e2dbd1 Mon Sep 17 00:00:00 2001 From: normanlikescats Date: Thu, 9 Mar 2023 13:23:28 +0800 Subject: [PATCH 01/24] initial commit with axios, firebase and env set up --- .gitignore | 1 + package-lock.json | 1440 ++++++++++++++++++++++++++++++++++++++++++++- package.json | 4 +- 3 files changed, 1438 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 4d29575d..6e8f7461 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. # dependencies +.env /node_modules /.pnp .pnp.js diff --git a/package-lock.json b/package-lock.json index 147f7995..cfb56699 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,8 @@ "name": "project2-bootcamp", "version": "0.1.0", "dependencies": { + "axios": "^1.3.4", + "firebase": "^9.17.2", "react": "^18.1.0", "react-dom": "^18.1.0", "react-scripts": "5.0.1" @@ -2057,6 +2059,575 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@firebase/analytics": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.9.4.tgz", + "integrity": "sha512-Mb2UaD0cyJ9DrTk4Okz8wqpjZuVRVXHZOjhbQcmGb8VtibXY1+jm/k3eJ21r7NqUKnjWejYM2EX+hI9+dtXGkQ==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/installations": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/analytics-compat": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.4.tgz", + "integrity": "sha512-ZN4K49QwOR8EWIUTV03VBdcVkz8sVsfJmve4g2+FEIj0kyTK0MdoVTWNOwWj9TVi2p/7FvKRKkpWxkydmi9x7g==", + "dependencies": { + "@firebase/analytics": "0.9.4", + "@firebase/analytics-types": "0.8.0", + "@firebase/component": "0.6.4", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/analytics-types": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.0.tgz", + "integrity": "sha512-iRP+QKI2+oz3UAh4nPEq14CsEjrjD6a5+fuypjScisAh9kXKFvdJOZJDwk7kikLvWVLGEs9+kIUS4LPQV7VZVw==" + }, + "node_modules/@firebase/app": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.9.4.tgz", + "integrity": "sha512-xX8I6pNqUxhxhaghy9fbjOWOP9ndx5UeN5F0V/PWD2u7xRg88YkzZrDocTAIU17y82UPZ1x1E5n15CsXGcxaOg==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "idb": "7.0.1", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/app-check": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.6.4.tgz", + "integrity": "sha512-M9qyVTWkEkHXmgwGtObvXQqKcOe9iKAOPqm0pCe74mzgKVTNq157ff39+fxHPb4nFbipToY+GuvtabLUzkHehQ==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/app-check-compat": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.4.tgz", + "integrity": "sha512-s6ON0ixPKe99M1DNYMI2eR5aLwQZgy0z8fuW1tnEbzg5p/N/GKFmqiIHSV4gfp8+X7Fw5NLm7qMfh4xrcPgQCw==", + "dependencies": { + "@firebase/app-check": "0.6.4", + "@firebase/app-check-types": "0.5.0", + "@firebase/component": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/app-check-interop-types": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.2.0.tgz", + "integrity": "sha512-+3PQIeX6/eiVK+x/yg8r6xTNR97fN7MahFDm+jiQmDjcyvSefoGuTTNQuuMScGyx3vYUBeZn+Cp9kC0yY/9uxQ==" + }, + "node_modules/@firebase/app-check-types": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.0.tgz", + "integrity": "sha512-uwSUj32Mlubybw7tedRzR24RP8M8JUVR3NPiMk3/Z4bCmgEKTlQBwMXrehDAZ2wF+TsBq0SN1c6ema71U/JPyQ==" + }, + "node_modules/@firebase/app-compat": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.4.tgz", + "integrity": "sha512-eYKtxMrzi+icZ6dFeJEoEpxu3aq1jp2PeL5vPIOAavJpdgRWFmSGmw3a46Hkay+GGGX4fkJG3vCfuoQsf5ksjA==", + "dependencies": { + "@firebase/app": "0.9.4", + "@firebase/component": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/app-types": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.0.tgz", + "integrity": "sha512-AeweANOIo0Mb8GiYm3xhTEBVCmPwTYAu9Hcd2qSkLuga/6+j9b1Jskl5bpiSQWy9eJ/j5pavxj6eYogmnuzm+Q==" + }, + "node_modules/@firebase/app/node_modules/idb": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.0.1.tgz", + "integrity": "sha512-UUxlE7vGWK5RfB/fDwEGgRf84DY/ieqNha6msMV99UsEMQhJ1RwbCd8AYBj3QMgnE3VZnfQvm4oKVCJTYlqIgg==" + }, + "node_modules/@firebase/auth": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-0.21.4.tgz", + "integrity": "sha512-yZrs1F8sTt8IMCJl29gaxokDZSLjO08r2bL2PNKV1Duz2vJ67ZtVcgHAidyf8BFak9uS8mepd9KlYFDfwUO60Q==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/auth-compat": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.3.4.tgz", + "integrity": "sha512-AVNZ4pwLV063ngPKU+8tykQ6v+fRlKfBWEp1W+JU1pEJI+GK0thOPrCn22lWyI8LYiDrh3MLIiBJCv7fsyQajw==", + "dependencies": { + "@firebase/auth": "0.21.4", + "@firebase/auth-types": "0.12.0", + "@firebase/component": "0.6.4", + "@firebase/util": "1.9.3", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/auth-interop-types": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.1.tgz", + "integrity": "sha512-VOaGzKp65MY6P5FI84TfYKBXEPi6LmOCSMMzys6o2BN2LOsqy7pCuZCup7NYnfbk5OkkQKzvIfHOzTm0UDpkyg==" + }, + "node_modules/@firebase/auth-types": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.0.tgz", + "integrity": "sha512-pPwaZt+SPOshK8xNoiQlK5XIrS97kFYc3Rc7xmy373QsOJ9MmqXxLaYssP5Kcds4wd2qK//amx/c+A8O2fVeZA==", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/component": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.4.tgz", + "integrity": "sha512-rLMyrXuO9jcAUCaQXCMjCMUsWrba5fzHlNK24xz5j2W6A/SRmK8mZJ/hn7V0fViLbxC0lPMtrK1eYzk6Fg03jA==", + "dependencies": { + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/database": { + "version": "0.14.4", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.14.4.tgz", + "integrity": "sha512-+Ea/IKGwh42jwdjCyzTmeZeLM3oy1h0mFPsTy6OqCWzcu/KFqRAr5Tt1HRCOBlNOdbh84JPZC47WLU18n2VbxQ==", + "dependencies": { + "@firebase/auth-interop-types": "0.2.1", + "@firebase/component": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "faye-websocket": "0.11.4", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/database-compat": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-0.3.4.tgz", + "integrity": "sha512-kuAW+l+sLMUKBThnvxvUZ+Q1ZrF/vFJ58iUY9kAcbX48U03nVzIF6Tmkf0p3WVQwMqiXguSgtOPIB6ZCeF+5Gg==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/database": "0.14.4", + "@firebase/database-types": "0.10.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/database-types": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.10.4.tgz", + "integrity": "sha512-dPySn0vJ/89ZeBac70T+2tWWPiJXWbmRygYv0smT5TfE3hDrQ09eKMF3Y+vMlTdrMWq7mUdYW5REWPSGH4kAZQ==", + "dependencies": { + "@firebase/app-types": "0.9.0", + "@firebase/util": "1.9.3" + } + }, + "node_modules/@firebase/firestore": { + "version": "3.8.4", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-3.8.4.tgz", + "integrity": "sha512-sNLT4vGBSrx75Q2yLzCHL/1LDS7+UG8gaIohox/GpKYGxt4r8/AsUOmjN4llDqdnFSgY5ePYp2+nHArFXHyZjA==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "@firebase/webchannel-wrapper": "0.9.0", + "@grpc/grpc-js": "~1.7.0", + "@grpc/proto-loader": "^0.6.13", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=10.10.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/firestore-compat": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.4.tgz", + "integrity": "sha512-xUzz1V53vA1R8S5QQbQ33zqNv0bV+dZpeQKqMXt6HNWa1yiX7lUooGYRws825F+QBOadW1teav1ttXnGZAsgUw==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/firestore": "3.8.4", + "@firebase/firestore-types": "2.5.1", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/firestore-types": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-2.5.1.tgz", + "integrity": "sha512-xG0CA6EMfYo8YeUxC8FeDzf6W3FX1cLlcAGBYV6Cku12sZRI81oWcu61RSKM66K6kUENP+78Qm8mvroBcm1whw==", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/functions": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.9.4.tgz", + "integrity": "sha512-3H2qh6U+q+nepO5Hds+Ddl6J0pS+zisuBLqqQMRBHv9XpWfu0PnDHklNmE8rZ+ccTEXvBj6zjkPfdxt6NisvlQ==", + "dependencies": { + "@firebase/app-check-interop-types": "0.2.0", + "@firebase/auth-interop-types": "0.2.1", + "@firebase/component": "0.6.4", + "@firebase/messaging-interop-types": "0.2.0", + "@firebase/util": "1.9.3", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/functions-compat": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.4.tgz", + "integrity": "sha512-kxVxTGyLV1MBR3sp3mI+eQ6JBqz0G5bk310F8eX4HzDFk4xjk5xY0KdHktMH+edM2xs1BOg0vwvvsAHczIjB+w==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/functions": "0.9.4", + "@firebase/functions-types": "0.6.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/functions-types": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.0.tgz", + "integrity": "sha512-hfEw5VJtgWXIRf92ImLkgENqpL6IWpYaXVYiRkFY1jJ9+6tIhWM7IzzwbevwIIud/jaxKVdRzD7QBWfPmkwCYw==" + }, + "node_modules/@firebase/installations": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.4.tgz", + "integrity": "sha512-u5y88rtsp7NYkCHC3ElbFBrPtieUybZluXyzl7+4BsIz4sqb4vSAuwHEUgCgCeaQhvsnxDEU6icly8U9zsJigA==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/util": "1.9.3", + "idb": "7.0.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/installations-compat": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.4.tgz", + "integrity": "sha512-LI9dYjp0aT9Njkn9U4JRrDqQ6KXeAmFbRC0E7jI7+hxl5YmRWysq5qgQl22hcWpTk+cm3es66d/apoDU/A9n6Q==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/installations": "0.6.4", + "@firebase/installations-types": "0.5.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/installations-types": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.0.tgz", + "integrity": "sha512-9DP+RGfzoI2jH7gY4SlzqvZ+hr7gYzPODrbzVD82Y12kScZ6ZpRg/i3j6rleto8vTFC8n6Len4560FnV1w2IRg==", + "peerDependencies": { + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/installations/node_modules/idb": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.0.1.tgz", + "integrity": "sha512-UUxlE7vGWK5RfB/fDwEGgRf84DY/ieqNha6msMV99UsEMQhJ1RwbCd8AYBj3QMgnE3VZnfQvm4oKVCJTYlqIgg==" + }, + "node_modules/@firebase/logger": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.0.tgz", + "integrity": "sha512-eRKSeykumZ5+cJPdxxJRgAC3G5NknY2GwEbKfymdnXtnT0Ucm4pspfR6GT4MUQEDuJwRVbVcSx85kgJulMoFFA==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/messaging": { + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.4.tgz", + "integrity": "sha512-6JLZct6zUaex4g7HI3QbzeUrg9xcnmDAPTWpkoMpd/GoSVWH98zDoWXMGrcvHeCAIsLpFMe4MPoZkJbrPhaASw==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/installations": "0.6.4", + "@firebase/messaging-interop-types": "0.2.0", + "@firebase/util": "1.9.3", + "idb": "7.0.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/messaging-compat": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.4.tgz", + "integrity": "sha512-lyFjeUhIsPRYDPNIkYX1LcZMpoVbBWXX4rPl7c/rqc7G+EUea7IEtSt4MxTvh6fDfPuzLn7+FZADfscC+tNMfg==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/messaging": "0.12.4", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/messaging-interop-types": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.0.tgz", + "integrity": "sha512-ujA8dcRuVeBixGR9CtegfpU4YmZf3Lt7QYkcj693FFannwNuZgfAYaTmbJ40dtjB81SAu6tbFPL9YLNT15KmOQ==" + }, + "node_modules/@firebase/messaging/node_modules/idb": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.0.1.tgz", + "integrity": "sha512-UUxlE7vGWK5RfB/fDwEGgRf84DY/ieqNha6msMV99UsEMQhJ1RwbCd8AYBj3QMgnE3VZnfQvm4oKVCJTYlqIgg==" + }, + "node_modules/@firebase/performance": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.6.4.tgz", + "integrity": "sha512-HfTn/bd8mfy/61vEqaBelNiNnvAbUtME2S25A67Nb34zVuCSCRIX4SseXY6zBnOFj3oLisaEqhVcJmVPAej67g==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/installations": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/performance-compat": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.4.tgz", + "integrity": "sha512-nnHUb8uP9G8islzcld/k6Bg5RhX62VpbAb/Anj7IXs/hp32Eb2LqFPZK4sy3pKkBUO5wcrlRWQa6wKOxqlUqsg==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/performance": "0.6.4", + "@firebase/performance-types": "0.2.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/performance-types": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.0.tgz", + "integrity": "sha512-kYrbr8e/CYr1KLrLYZZt2noNnf+pRwDq2KK9Au9jHrBMnb0/C9X9yWSXmZkFt4UIdsQknBq8uBB7fsybZdOBTA==" + }, + "node_modules/@firebase/remote-config": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.4.4.tgz", + "integrity": "sha512-x1ioTHGX8ZwDSTOVp8PBLv2/wfwKzb4pxi0gFezS5GCJwbLlloUH4YYZHHS83IPxnua8b6l0IXUaWd0RgbWwzQ==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/installations": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/remote-config-compat": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.4.tgz", + "integrity": "sha512-FKiki53jZirrDFkBHglB3C07j5wBpitAaj8kLME6g8Mx+aq7u9P7qfmuSRytiOItADhWUj7O1JIv7n9q87SuwA==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/remote-config": "0.4.4", + "@firebase/remote-config-types": "0.3.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/remote-config-types": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.3.0.tgz", + "integrity": "sha512-RtEH4vdcbXZuZWRZbIRmQVBNsE7VDQpet2qFvq6vwKLBIQRQR5Kh58M4ok3A3US8Sr3rubYnaGqZSurCwI8uMA==" + }, + "node_modules/@firebase/storage": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.11.2.tgz", + "integrity": "sha512-CtvoFaBI4hGXlXbaCHf8humajkbXhs39Nbh6MbNxtwJiCqxPy9iH3D3CCfXAvP0QvAAwmJUTK3+z9a++Kc4nkA==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/util": "1.9.3", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/storage-compat": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.2.tgz", + "integrity": "sha512-wvsXlLa9DVOMQJckbDNhXKKxRNNewyUhhbXev3t8kSgoCotd1v3MmqhKKz93ePhDnhHnDs7bYHy+Qa8dRY6BXw==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/storage": "0.11.2", + "@firebase/storage-types": "0.8.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/storage-types": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.0.tgz", + "integrity": "sha512-isRHcGrTs9kITJC0AVehHfpraWFui39MPaU7Eo8QfWlqW7YPymBmRgjDrlOgFdURh6Cdeg07zmkLP5tzTKRSpg==", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/util": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.3.tgz", + "integrity": "sha512-DY02CRhOZwpzO36fHpuVysz6JZrscPiBXD0fXp6qSrL9oNOx5KWICKdR95C0lSITzxp0TZosVyHqzatE8JbcjA==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/webchannel-wrapper": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.9.0.tgz", + "integrity": "sha512-BpiZLBWdLFw+qFel9p3Zs1jD6QmH7Ii4aTDu6+vx8ShdidChZUXqDhYJly4ZjSgQh54miXbBgBrk0S+jTIh/Qg==" + }, + "node_modules/@grpc/grpc-js": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.7.3.tgz", + "integrity": "sha512-H9l79u4kJ2PVSxUNA08HMYAnUBLj9v6KjYQ7SQ71hOZcEXhShE/y5iQCesP8+6/Ik/7i2O0a10bPquIcYfufog==", + "dependencies": { + "@grpc/proto-loader": "^0.7.0", + "@types/node": ">=12.12.47" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + } + }, + "node_modules/@grpc/grpc-js/node_modules/@grpc/proto-loader": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.5.tgz", + "integrity": "sha512-mfcTuMbFowq1wh/Rn5KQl6qb95M21Prej3bewD9dUQMurYGVckGO/Pbe2Ocwto6sD05b/mxZLspvqwx60xO2Rg==", + "dependencies": { + "@types/long": "^4.0.1", + "lodash.camelcase": "^4.3.0", + "long": "^4.0.0", + "protobufjs": "^7.0.0", + "yargs": "^16.2.0" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@grpc/grpc-js/node_modules/protobufjs": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.2.tgz", + "integrity": "sha512-++PrQIjrom+bFDPpfmqXfAGSQs40116JRrqqyf53dymUMvvb5d/LMRyicRoF1AUKoXVS1/IgJXlEgcpr4gTF3Q==", + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@grpc/grpc-js/node_modules/protobufjs/node_modules/long": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.1.tgz", + "integrity": "sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A==" + }, + "node_modules/@grpc/proto-loader": { + "version": "0.6.13", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.13.tgz", + "integrity": "sha512-FjxPYDRTn6Ec3V0arm1FtSpmP6V50wuph2yILpyvTKzjc76oDdoihXqM1DzOW5ubvCC8GivfCnNtfaRE8myJ7g==", + "dependencies": { + "@types/long": "^4.0.1", + "lodash.camelcase": "^4.3.0", + "long": "^4.0.0", + "protobufjs": "^6.11.3", + "yargs": "^16.2.0" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.9.5", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", @@ -2866,6 +3437,60 @@ } } }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, "node_modules/@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -3367,6 +3992,11 @@ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=" }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" + }, "node_modules/@types/mime": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", @@ -4226,6 +4856,29 @@ "node": ">=4" } }, + "node_modules/axios": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.4.tgz", + "integrity": "sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ==", + "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", @@ -7153,6 +7806,39 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/firebase": { + "version": "9.17.2", + "resolved": "https://registry.npmjs.org/firebase/-/firebase-9.17.2.tgz", + "integrity": "sha512-2V95/evwB3zsi6RYHCvPXfkiQrSepFQJohv3YGoQVhS0bvXuYXmkLtrCVGShxneB/5t9HE5C9q9C8XPnK4APBw==", + "dependencies": { + "@firebase/analytics": "0.9.4", + "@firebase/analytics-compat": "0.2.4", + "@firebase/app": "0.9.4", + "@firebase/app-check": "0.6.4", + "@firebase/app-check-compat": "0.3.4", + "@firebase/app-compat": "0.2.4", + "@firebase/app-types": "0.9.0", + "@firebase/auth": "0.21.4", + "@firebase/auth-compat": "0.3.4", + "@firebase/database": "0.14.4", + "@firebase/database-compat": "0.3.4", + "@firebase/firestore": "3.8.4", + "@firebase/firestore-compat": "0.3.4", + "@firebase/functions": "0.9.4", + "@firebase/functions-compat": "0.3.4", + "@firebase/installations": "0.6.4", + "@firebase/installations-compat": "0.2.4", + "@firebase/messaging": "0.12.4", + "@firebase/messaging-compat": "0.2.4", + "@firebase/performance": "0.6.4", + "@firebase/performance-compat": "0.2.4", + "@firebase/remote-config": "0.4.4", + "@firebase/remote-config-compat": "0.2.4", + "@firebase/storage": "0.11.2", + "@firebase/storage-compat": "0.3.2", + "@firebase/util": "1.9.3" + } + }, "node_modules/flat-cache": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", @@ -7171,9 +7857,9 @@ "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==" }, "node_modules/follow-redirects": { - "version": "1.14.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", - "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==", + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", "funding": [ { "type": "individual", @@ -10681,6 +11367,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -10706,6 +11397,11 @@ "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" }, + "node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -11028,6 +11724,44 @@ "tslib": "^2.0.3" } }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/node-forge": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", @@ -12795,6 +13529,31 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/protobufjs": { + "version": "6.11.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", + "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==", + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -12815,6 +13574,11 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -17231,6 +17995,492 @@ } } }, + "@firebase/analytics": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.9.4.tgz", + "integrity": "sha512-Mb2UaD0cyJ9DrTk4Okz8wqpjZuVRVXHZOjhbQcmGb8VtibXY1+jm/k3eJ21r7NqUKnjWejYM2EX+hI9+dtXGkQ==", + "requires": { + "@firebase/component": "0.6.4", + "@firebase/installations": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + } + }, + "@firebase/analytics-compat": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.4.tgz", + "integrity": "sha512-ZN4K49QwOR8EWIUTV03VBdcVkz8sVsfJmve4g2+FEIj0kyTK0MdoVTWNOwWj9TVi2p/7FvKRKkpWxkydmi9x7g==", + "requires": { + "@firebase/analytics": "0.9.4", + "@firebase/analytics-types": "0.8.0", + "@firebase/component": "0.6.4", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + } + }, + "@firebase/analytics-types": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.0.tgz", + "integrity": "sha512-iRP+QKI2+oz3UAh4nPEq14CsEjrjD6a5+fuypjScisAh9kXKFvdJOZJDwk7kikLvWVLGEs9+kIUS4LPQV7VZVw==" + }, + "@firebase/app": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.9.4.tgz", + "integrity": "sha512-xX8I6pNqUxhxhaghy9fbjOWOP9ndx5UeN5F0V/PWD2u7xRg88YkzZrDocTAIU17y82UPZ1x1E5n15CsXGcxaOg==", + "requires": { + "@firebase/component": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "idb": "7.0.1", + "tslib": "^2.1.0" + }, + "dependencies": { + "idb": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.0.1.tgz", + "integrity": "sha512-UUxlE7vGWK5RfB/fDwEGgRf84DY/ieqNha6msMV99UsEMQhJ1RwbCd8AYBj3QMgnE3VZnfQvm4oKVCJTYlqIgg==" + } + } + }, + "@firebase/app-check": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.6.4.tgz", + "integrity": "sha512-M9qyVTWkEkHXmgwGtObvXQqKcOe9iKAOPqm0pCe74mzgKVTNq157ff39+fxHPb4nFbipToY+GuvtabLUzkHehQ==", + "requires": { + "@firebase/component": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + } + }, + "@firebase/app-check-compat": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.4.tgz", + "integrity": "sha512-s6ON0ixPKe99M1DNYMI2eR5aLwQZgy0z8fuW1tnEbzg5p/N/GKFmqiIHSV4gfp8+X7Fw5NLm7qMfh4xrcPgQCw==", + "requires": { + "@firebase/app-check": "0.6.4", + "@firebase/app-check-types": "0.5.0", + "@firebase/component": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + } + }, + "@firebase/app-check-interop-types": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.2.0.tgz", + "integrity": "sha512-+3PQIeX6/eiVK+x/yg8r6xTNR97fN7MahFDm+jiQmDjcyvSefoGuTTNQuuMScGyx3vYUBeZn+Cp9kC0yY/9uxQ==" + }, + "@firebase/app-check-types": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.0.tgz", + "integrity": "sha512-uwSUj32Mlubybw7tedRzR24RP8M8JUVR3NPiMk3/Z4bCmgEKTlQBwMXrehDAZ2wF+TsBq0SN1c6ema71U/JPyQ==" + }, + "@firebase/app-compat": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.4.tgz", + "integrity": "sha512-eYKtxMrzi+icZ6dFeJEoEpxu3aq1jp2PeL5vPIOAavJpdgRWFmSGmw3a46Hkay+GGGX4fkJG3vCfuoQsf5ksjA==", + "requires": { + "@firebase/app": "0.9.4", + "@firebase/component": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + } + }, + "@firebase/app-types": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.0.tgz", + "integrity": "sha512-AeweANOIo0Mb8GiYm3xhTEBVCmPwTYAu9Hcd2qSkLuga/6+j9b1Jskl5bpiSQWy9eJ/j5pavxj6eYogmnuzm+Q==" + }, + "@firebase/auth": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-0.21.4.tgz", + "integrity": "sha512-yZrs1F8sTt8IMCJl29gaxokDZSLjO08r2bL2PNKV1Duz2vJ67ZtVcgHAidyf8BFak9uS8mepd9KlYFDfwUO60Q==", + "requires": { + "@firebase/component": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + } + }, + "@firebase/auth-compat": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.3.4.tgz", + "integrity": "sha512-AVNZ4pwLV063ngPKU+8tykQ6v+fRlKfBWEp1W+JU1pEJI+GK0thOPrCn22lWyI8LYiDrh3MLIiBJCv7fsyQajw==", + "requires": { + "@firebase/auth": "0.21.4", + "@firebase/auth-types": "0.12.0", + "@firebase/component": "0.6.4", + "@firebase/util": "1.9.3", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + } + }, + "@firebase/auth-interop-types": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.1.tgz", + "integrity": "sha512-VOaGzKp65MY6P5FI84TfYKBXEPi6LmOCSMMzys6o2BN2LOsqy7pCuZCup7NYnfbk5OkkQKzvIfHOzTm0UDpkyg==" + }, + "@firebase/auth-types": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.0.tgz", + "integrity": "sha512-pPwaZt+SPOshK8xNoiQlK5XIrS97kFYc3Rc7xmy373QsOJ9MmqXxLaYssP5Kcds4wd2qK//amx/c+A8O2fVeZA==", + "requires": {} + }, + "@firebase/component": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.4.tgz", + "integrity": "sha512-rLMyrXuO9jcAUCaQXCMjCMUsWrba5fzHlNK24xz5j2W6A/SRmK8mZJ/hn7V0fViLbxC0lPMtrK1eYzk6Fg03jA==", + "requires": { + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + } + }, + "@firebase/database": { + "version": "0.14.4", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.14.4.tgz", + "integrity": "sha512-+Ea/IKGwh42jwdjCyzTmeZeLM3oy1h0mFPsTy6OqCWzcu/KFqRAr5Tt1HRCOBlNOdbh84JPZC47WLU18n2VbxQ==", + "requires": { + "@firebase/auth-interop-types": "0.2.1", + "@firebase/component": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "faye-websocket": "0.11.4", + "tslib": "^2.1.0" + } + }, + "@firebase/database-compat": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-0.3.4.tgz", + "integrity": "sha512-kuAW+l+sLMUKBThnvxvUZ+Q1ZrF/vFJ58iUY9kAcbX48U03nVzIF6Tmkf0p3WVQwMqiXguSgtOPIB6ZCeF+5Gg==", + "requires": { + "@firebase/component": "0.6.4", + "@firebase/database": "0.14.4", + "@firebase/database-types": "0.10.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + } + }, + "@firebase/database-types": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.10.4.tgz", + "integrity": "sha512-dPySn0vJ/89ZeBac70T+2tWWPiJXWbmRygYv0smT5TfE3hDrQ09eKMF3Y+vMlTdrMWq7mUdYW5REWPSGH4kAZQ==", + "requires": { + "@firebase/app-types": "0.9.0", + "@firebase/util": "1.9.3" + } + }, + "@firebase/firestore": { + "version": "3.8.4", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-3.8.4.tgz", + "integrity": "sha512-sNLT4vGBSrx75Q2yLzCHL/1LDS7+UG8gaIohox/GpKYGxt4r8/AsUOmjN4llDqdnFSgY5ePYp2+nHArFXHyZjA==", + "requires": { + "@firebase/component": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "@firebase/webchannel-wrapper": "0.9.0", + "@grpc/grpc-js": "~1.7.0", + "@grpc/proto-loader": "^0.6.13", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + } + }, + "@firebase/firestore-compat": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.4.tgz", + "integrity": "sha512-xUzz1V53vA1R8S5QQbQ33zqNv0bV+dZpeQKqMXt6HNWa1yiX7lUooGYRws825F+QBOadW1teav1ttXnGZAsgUw==", + "requires": { + "@firebase/component": "0.6.4", + "@firebase/firestore": "3.8.4", + "@firebase/firestore-types": "2.5.1", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + } + }, + "@firebase/firestore-types": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-2.5.1.tgz", + "integrity": "sha512-xG0CA6EMfYo8YeUxC8FeDzf6W3FX1cLlcAGBYV6Cku12sZRI81oWcu61RSKM66K6kUENP+78Qm8mvroBcm1whw==", + "requires": {} + }, + "@firebase/functions": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.9.4.tgz", + "integrity": "sha512-3H2qh6U+q+nepO5Hds+Ddl6J0pS+zisuBLqqQMRBHv9XpWfu0PnDHklNmE8rZ+ccTEXvBj6zjkPfdxt6NisvlQ==", + "requires": { + "@firebase/app-check-interop-types": "0.2.0", + "@firebase/auth-interop-types": "0.2.1", + "@firebase/component": "0.6.4", + "@firebase/messaging-interop-types": "0.2.0", + "@firebase/util": "1.9.3", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + } + }, + "@firebase/functions-compat": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.4.tgz", + "integrity": "sha512-kxVxTGyLV1MBR3sp3mI+eQ6JBqz0G5bk310F8eX4HzDFk4xjk5xY0KdHktMH+edM2xs1BOg0vwvvsAHczIjB+w==", + "requires": { + "@firebase/component": "0.6.4", + "@firebase/functions": "0.9.4", + "@firebase/functions-types": "0.6.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + } + }, + "@firebase/functions-types": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.0.tgz", + "integrity": "sha512-hfEw5VJtgWXIRf92ImLkgENqpL6IWpYaXVYiRkFY1jJ9+6tIhWM7IzzwbevwIIud/jaxKVdRzD7QBWfPmkwCYw==" + }, + "@firebase/installations": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.4.tgz", + "integrity": "sha512-u5y88rtsp7NYkCHC3ElbFBrPtieUybZluXyzl7+4BsIz4sqb4vSAuwHEUgCgCeaQhvsnxDEU6icly8U9zsJigA==", + "requires": { + "@firebase/component": "0.6.4", + "@firebase/util": "1.9.3", + "idb": "7.0.1", + "tslib": "^2.1.0" + }, + "dependencies": { + "idb": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.0.1.tgz", + "integrity": "sha512-UUxlE7vGWK5RfB/fDwEGgRf84DY/ieqNha6msMV99UsEMQhJ1RwbCd8AYBj3QMgnE3VZnfQvm4oKVCJTYlqIgg==" + } + } + }, + "@firebase/installations-compat": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.4.tgz", + "integrity": "sha512-LI9dYjp0aT9Njkn9U4JRrDqQ6KXeAmFbRC0E7jI7+hxl5YmRWysq5qgQl22hcWpTk+cm3es66d/apoDU/A9n6Q==", + "requires": { + "@firebase/component": "0.6.4", + "@firebase/installations": "0.6.4", + "@firebase/installations-types": "0.5.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + } + }, + "@firebase/installations-types": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.0.tgz", + "integrity": "sha512-9DP+RGfzoI2jH7gY4SlzqvZ+hr7gYzPODrbzVD82Y12kScZ6ZpRg/i3j6rleto8vTFC8n6Len4560FnV1w2IRg==", + "requires": {} + }, + "@firebase/logger": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.0.tgz", + "integrity": "sha512-eRKSeykumZ5+cJPdxxJRgAC3G5NknY2GwEbKfymdnXtnT0Ucm4pspfR6GT4MUQEDuJwRVbVcSx85kgJulMoFFA==", + "requires": { + "tslib": "^2.1.0" + } + }, + "@firebase/messaging": { + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.4.tgz", + "integrity": "sha512-6JLZct6zUaex4g7HI3QbzeUrg9xcnmDAPTWpkoMpd/GoSVWH98zDoWXMGrcvHeCAIsLpFMe4MPoZkJbrPhaASw==", + "requires": { + "@firebase/component": "0.6.4", + "@firebase/installations": "0.6.4", + "@firebase/messaging-interop-types": "0.2.0", + "@firebase/util": "1.9.3", + "idb": "7.0.1", + "tslib": "^2.1.0" + }, + "dependencies": { + "idb": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.0.1.tgz", + "integrity": "sha512-UUxlE7vGWK5RfB/fDwEGgRf84DY/ieqNha6msMV99UsEMQhJ1RwbCd8AYBj3QMgnE3VZnfQvm4oKVCJTYlqIgg==" + } + } + }, + "@firebase/messaging-compat": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.4.tgz", + "integrity": "sha512-lyFjeUhIsPRYDPNIkYX1LcZMpoVbBWXX4rPl7c/rqc7G+EUea7IEtSt4MxTvh6fDfPuzLn7+FZADfscC+tNMfg==", + "requires": { + "@firebase/component": "0.6.4", + "@firebase/messaging": "0.12.4", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + } + }, + "@firebase/messaging-interop-types": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.0.tgz", + "integrity": "sha512-ujA8dcRuVeBixGR9CtegfpU4YmZf3Lt7QYkcj693FFannwNuZgfAYaTmbJ40dtjB81SAu6tbFPL9YLNT15KmOQ==" + }, + "@firebase/performance": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.6.4.tgz", + "integrity": "sha512-HfTn/bd8mfy/61vEqaBelNiNnvAbUtME2S25A67Nb34zVuCSCRIX4SseXY6zBnOFj3oLisaEqhVcJmVPAej67g==", + "requires": { + "@firebase/component": "0.6.4", + "@firebase/installations": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + } + }, + "@firebase/performance-compat": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.4.tgz", + "integrity": "sha512-nnHUb8uP9G8islzcld/k6Bg5RhX62VpbAb/Anj7IXs/hp32Eb2LqFPZK4sy3pKkBUO5wcrlRWQa6wKOxqlUqsg==", + "requires": { + "@firebase/component": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/performance": "0.6.4", + "@firebase/performance-types": "0.2.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + } + }, + "@firebase/performance-types": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.0.tgz", + "integrity": "sha512-kYrbr8e/CYr1KLrLYZZt2noNnf+pRwDq2KK9Au9jHrBMnb0/C9X9yWSXmZkFt4UIdsQknBq8uBB7fsybZdOBTA==" + }, + "@firebase/remote-config": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.4.4.tgz", + "integrity": "sha512-x1ioTHGX8ZwDSTOVp8PBLv2/wfwKzb4pxi0gFezS5GCJwbLlloUH4YYZHHS83IPxnua8b6l0IXUaWd0RgbWwzQ==", + "requires": { + "@firebase/component": "0.6.4", + "@firebase/installations": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + } + }, + "@firebase/remote-config-compat": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.4.tgz", + "integrity": "sha512-FKiki53jZirrDFkBHglB3C07j5wBpitAaj8kLME6g8Mx+aq7u9P7qfmuSRytiOItADhWUj7O1JIv7n9q87SuwA==", + "requires": { + "@firebase/component": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/remote-config": "0.4.4", + "@firebase/remote-config-types": "0.3.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + } + }, + "@firebase/remote-config-types": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.3.0.tgz", + "integrity": "sha512-RtEH4vdcbXZuZWRZbIRmQVBNsE7VDQpet2qFvq6vwKLBIQRQR5Kh58M4ok3A3US8Sr3rubYnaGqZSurCwI8uMA==" + }, + "@firebase/storage": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.11.2.tgz", + "integrity": "sha512-CtvoFaBI4hGXlXbaCHf8humajkbXhs39Nbh6MbNxtwJiCqxPy9iH3D3CCfXAvP0QvAAwmJUTK3+z9a++Kc4nkA==", + "requires": { + "@firebase/component": "0.6.4", + "@firebase/util": "1.9.3", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + } + }, + "@firebase/storage-compat": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.2.tgz", + "integrity": "sha512-wvsXlLa9DVOMQJckbDNhXKKxRNNewyUhhbXev3t8kSgoCotd1v3MmqhKKz93ePhDnhHnDs7bYHy+Qa8dRY6BXw==", + "requires": { + "@firebase/component": "0.6.4", + "@firebase/storage": "0.11.2", + "@firebase/storage-types": "0.8.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + } + }, + "@firebase/storage-types": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.0.tgz", + "integrity": "sha512-isRHcGrTs9kITJC0AVehHfpraWFui39MPaU7Eo8QfWlqW7YPymBmRgjDrlOgFdURh6Cdeg07zmkLP5tzTKRSpg==", + "requires": {} + }, + "@firebase/util": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.3.tgz", + "integrity": "sha512-DY02CRhOZwpzO36fHpuVysz6JZrscPiBXD0fXp6qSrL9oNOx5KWICKdR95C0lSITzxp0TZosVyHqzatE8JbcjA==", + "requires": { + "tslib": "^2.1.0" + } + }, + "@firebase/webchannel-wrapper": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.9.0.tgz", + "integrity": "sha512-BpiZLBWdLFw+qFel9p3Zs1jD6QmH7Ii4aTDu6+vx8ShdidChZUXqDhYJly4ZjSgQh54miXbBgBrk0S+jTIh/Qg==" + }, + "@grpc/grpc-js": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.7.3.tgz", + "integrity": "sha512-H9l79u4kJ2PVSxUNA08HMYAnUBLj9v6KjYQ7SQ71hOZcEXhShE/y5iQCesP8+6/Ik/7i2O0a10bPquIcYfufog==", + "requires": { + "@grpc/proto-loader": "^0.7.0", + "@types/node": ">=12.12.47" + }, + "dependencies": { + "@grpc/proto-loader": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.5.tgz", + "integrity": "sha512-mfcTuMbFowq1wh/Rn5KQl6qb95M21Prej3bewD9dUQMurYGVckGO/Pbe2Ocwto6sD05b/mxZLspvqwx60xO2Rg==", + "requires": { + "@types/long": "^4.0.1", + "lodash.camelcase": "^4.3.0", + "long": "^4.0.0", + "protobufjs": "^7.0.0", + "yargs": "^16.2.0" + } + }, + "protobufjs": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.2.tgz", + "integrity": "sha512-++PrQIjrom+bFDPpfmqXfAGSQs40116JRrqqyf53dymUMvvb5d/LMRyicRoF1AUKoXVS1/IgJXlEgcpr4gTF3Q==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "dependencies": { + "long": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.1.tgz", + "integrity": "sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A==" + } + } + } + } + }, + "@grpc/proto-loader": { + "version": "0.6.13", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.13.tgz", + "integrity": "sha512-FjxPYDRTn6Ec3V0arm1FtSpmP6V50wuph2yILpyvTKzjc76oDdoihXqM1DzOW5ubvCC8GivfCnNtfaRE8myJ7g==", + "requires": { + "@types/long": "^4.0.1", + "lodash.camelcase": "^4.3.0", + "long": "^4.0.0", + "protobufjs": "^6.11.3", + "yargs": "^16.2.0" + } + }, "@humanwhocodes/config-array": { "version": "0.9.5", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", @@ -17810,6 +19060,60 @@ "source-map": "^0.7.3" } }, + "@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + }, + "@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + }, + "@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "requires": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, "@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -18181,6 +19485,11 @@ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=" }, + "@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" + }, "@types/mime": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", @@ -18818,6 +20127,28 @@ "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.1.tgz", "integrity": "sha512-gd1kmb21kwNuWr6BQz8fv6GNECPBnUasepcoLbekws23NVBLODdsClRZ+bQ8+9Uomf3Sm3+Vwn0oYG9NvwnJCw==" }, + "axios": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.4.tgz", + "integrity": "sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ==", + "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", @@ -20970,6 +22301,39 @@ "path-exists": "^4.0.0" } }, + "firebase": { + "version": "9.17.2", + "resolved": "https://registry.npmjs.org/firebase/-/firebase-9.17.2.tgz", + "integrity": "sha512-2V95/evwB3zsi6RYHCvPXfkiQrSepFQJohv3YGoQVhS0bvXuYXmkLtrCVGShxneB/5t9HE5C9q9C8XPnK4APBw==", + "requires": { + "@firebase/analytics": "0.9.4", + "@firebase/analytics-compat": "0.2.4", + "@firebase/app": "0.9.4", + "@firebase/app-check": "0.6.4", + "@firebase/app-check-compat": "0.3.4", + "@firebase/app-compat": "0.2.4", + "@firebase/app-types": "0.9.0", + "@firebase/auth": "0.21.4", + "@firebase/auth-compat": "0.3.4", + "@firebase/database": "0.14.4", + "@firebase/database-compat": "0.3.4", + "@firebase/firestore": "3.8.4", + "@firebase/firestore-compat": "0.3.4", + "@firebase/functions": "0.9.4", + "@firebase/functions-compat": "0.3.4", + "@firebase/installations": "0.6.4", + "@firebase/installations-compat": "0.2.4", + "@firebase/messaging": "0.12.4", + "@firebase/messaging-compat": "0.2.4", + "@firebase/performance": "0.6.4", + "@firebase/performance-compat": "0.2.4", + "@firebase/remote-config": "0.4.4", + "@firebase/remote-config-compat": "0.2.4", + "@firebase/storage": "0.11.2", + "@firebase/storage-compat": "0.3.2", + "@firebase/util": "1.9.3" + } + }, "flat-cache": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", @@ -20985,9 +22349,9 @@ "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==" }, "follow-redirects": { - "version": "1.14.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", - "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==" + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" }, "fork-ts-checker-webpack-plugin": { "version": "6.5.2", @@ -23494,6 +24858,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" + }, "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -23519,6 +24888,11 @@ "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -23758,6 +25132,35 @@ "tslib": "^2.0.3" } }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "requires": { + "whatwg-url": "^5.0.0" + }, + "dependencies": { + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } + } + }, "node-forge": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", @@ -24892,6 +26295,26 @@ } } }, + "protobufjs": { + "version": "6.11.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", + "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + } + }, "proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -24908,6 +26331,11 @@ } } }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", diff --git a/package.json b/package.json index e58f30a2..e590e30a 100644 --- a/package.json +++ b/package.json @@ -3,12 +3,14 @@ "version": "0.1.0", "private": true, "dependencies": { + "axios": "^1.3.4", + "firebase": "^9.17.2", "react": "^18.1.0", "react-dom": "^18.1.0", "react-scripts": "5.0.1" }, "scripts": { - "start": "react-scripts start", + "start": "WATCHPACK_POLLING=true react-scripts start", "build": "react-scripts build" }, "eslintConfig": { From f793a95d385b95f6f7858343fe42466ff02d0f71 Mon Sep 17 00:00:00 2001 From: normanlikescats Date: Thu, 9 Mar 2023 13:53:06 +0800 Subject: [PATCH 02/24] setup firebase stuff and movie API --- package-lock.json | 61 ++++++++++++++++++++++++++++++++++++ package.json | 1 + src/{ => Components}/App.css | 0 src/{ => Components}/App.js | 0 src/firebase.js | 23 ++++++++++++++ 5 files changed, 85 insertions(+) rename src/{ => Components}/App.css (100%) rename src/{ => Components}/App.js (100%) create mode 100644 src/firebase.js diff --git a/package-lock.json b/package-lock.json index cfb56699..10b1f464 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "firebase": "^9.17.2", "react": "^18.1.0", "react-dom": "^18.1.0", + "react-router-dom": "^6.8.2", "react-scripts": "5.0.1" } }, @@ -3491,6 +3492,14 @@ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" }, + "node_modules/@remix-run/router": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.3.3.tgz", + "integrity": "sha512-YRHie1yQEj0kqqCTCJEfHqYSSNlZQ696QJG+MMiW4mxSl9I0ojz/eRhJS4fs88Z5i6D1SmoF9d3K99/QOhI8/w==", + "engines": { + "node": ">=14" + } + }, "node_modules/@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -13876,6 +13885,36 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.8.2.tgz", + "integrity": "sha512-lF7S0UmXI5Pd8bmHvMdPKI4u4S5McxmHnzJhrYi9ZQ6wE+DA8JN5BzVC5EEBuduWWDaiJ8u6YhVOCmThBli+rw==", + "dependencies": { + "@remix-run/router": "1.3.3" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.8.2.tgz", + "integrity": "sha512-N/oAF1Shd7g4tWy+75IIufCGsHBqT74tnzHQhbiUTYILYF0Blk65cg+HPZqwC+6SqEyx033nKqU7by38v3lBZg==", + "dependencies": { + "@remix-run/router": "1.3.3", + "react-router": "6.8.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "node_modules/react-scripts": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", @@ -19114,6 +19153,11 @@ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" }, + "@remix-run/router": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.3.3.tgz", + "integrity": "sha512-YRHie1yQEj0kqqCTCJEfHqYSSNlZQ696QJG+MMiW4mxSl9I0ojz/eRhJS4fs88Z5i6D1SmoF9d3K99/QOhI8/w==" + }, "@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -26547,6 +26591,23 @@ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==" }, + "react-router": { + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.8.2.tgz", + "integrity": "sha512-lF7S0UmXI5Pd8bmHvMdPKI4u4S5McxmHnzJhrYi9ZQ6wE+DA8JN5BzVC5EEBuduWWDaiJ8u6YhVOCmThBli+rw==", + "requires": { + "@remix-run/router": "1.3.3" + } + }, + "react-router-dom": { + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.8.2.tgz", + "integrity": "sha512-N/oAF1Shd7g4tWy+75IIufCGsHBqT74tnzHQhbiUTYILYF0Blk65cg+HPZqwC+6SqEyx033nKqU7by38v3lBZg==", + "requires": { + "@remix-run/router": "1.3.3", + "react-router": "6.8.2" + } + }, "react-scripts": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", diff --git a/package.json b/package.json index e590e30a..38ca49a1 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "firebase": "^9.17.2", "react": "^18.1.0", "react-dom": "^18.1.0", + "react-router-dom": "^6.8.2", "react-scripts": "5.0.1" }, "scripts": { diff --git a/src/App.css b/src/Components/App.css similarity index 100% rename from src/App.css rename to src/Components/App.css diff --git a/src/App.js b/src/Components/App.js similarity index 100% rename from src/App.js rename to src/Components/App.js diff --git a/src/firebase.js b/src/firebase.js new file mode 100644 index 00000000..b2bdea46 --- /dev/null +++ b/src/firebase.js @@ -0,0 +1,23 @@ +// Import the functions you need from the SDKs you need +import { initializeApp } from "firebase/app"; +import { getDatabase } from "firebase/database"; +import { getStorage } from "firebase/storage"; +import { getAuth } from "firebase/auth"; + +const firebaseConfig = { + apiKey: process.env.REACT_APP_API_KEY, + authDomain: process.env.REACT_APP_AUTH_DOMAIN, + databaseURL: process.env.REACT_APP_REALTIME_DATABASE_URL, + projectId: process.env.REACT_APP_PROJECT_ID, + storageBucket: process.env.REACT_APP_STORAGE_BUCKET, + messagingSenderId: "SENDER_ID", + appId: "APP_ID", +}; + +// Initialize Firebase +const firebaseApp = initializeApp(firebaseConfig); + +// Get a reference to the database service and export the reference for other modules +export const database = getDatabase(firebaseApp); +export const storage = getStorage(firebaseApp); +export const auth = getAuth(firebaseApp); \ No newline at end of file From ef0ab71cdf964e9ca8436042e3bb056b9922b288 Mon Sep 17 00:00:00 2001 From: normanlikescats Date: Thu, 9 Mar 2023 14:50:34 +0800 Subject: [PATCH 03/24] set up router and basic components to build out --- src/Components/App.js | 44 ++++++++++++++++++++++++----------- src/Components/Error.js | 9 +++++++ src/Components/Feed.js | 9 +++++++ src/Components/LandingPage.js | 9 +++++++ src/Components/Login.js | 9 +++++++ src/Components/Movie.js | 9 +++++++ src/Components/Profile.js | 9 +++++++ src/Components/Register.js | 9 +++++++ 8 files changed, 93 insertions(+), 14 deletions(-) create mode 100644 src/Components/Error.js create mode 100644 src/Components/Feed.js create mode 100644 src/Components/LandingPage.js create mode 100644 src/Components/Login.js create mode 100644 src/Components/Movie.js create mode 100644 src/Components/Profile.js create mode 100644 src/Components/Register.js diff --git a/src/Components/App.js b/src/Components/App.js index 4a6f800f..2fa38a80 100644 --- a/src/Components/App.js +++ b/src/Components/App.js @@ -1,20 +1,36 @@ import React from "react"; -import logo from "./logo.png"; +import { + BrowserRouter, + Route, + Routes, +} from "react-router-dom"; +import LandingPage from "./LandingPage" +import Login from "./Login" +import Register from "./Register" +import Feed from "./Feed" +import Error from "./Error" +import Movie from "./Movie" +import Profile from "./Profile" import "./App.css"; -class App extends React.Component { - render() { - return ( -
-
- logo -

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

-
-
- ); - } +function App() { + return ( +
+
+ + + }/> + }/> + }/> + }/> + }/> + }/> + }/> + + +
+
+ ); } export default App; diff --git a/src/Components/Error.js b/src/Components/Error.js new file mode 100644 index 00000000..b74cd68c --- /dev/null +++ b/src/Components/Error.js @@ -0,0 +1,9 @@ +import React from 'react'; + +export default function Error (){ + return( +
+ test +
+ ) +} \ No newline at end of file diff --git a/src/Components/Feed.js b/src/Components/Feed.js new file mode 100644 index 00000000..5f90d5c5 --- /dev/null +++ b/src/Components/Feed.js @@ -0,0 +1,9 @@ +import React from 'react'; + +export default function Feed (){ + return( +
+ test +
+ ) +} \ No newline at end of file diff --git a/src/Components/LandingPage.js b/src/Components/LandingPage.js new file mode 100644 index 00000000..4a4cd909 --- /dev/null +++ b/src/Components/LandingPage.js @@ -0,0 +1,9 @@ +import React from 'react'; + +export default function LandingPage (){ + return( +
+ test +
+ ) +} \ No newline at end of file diff --git a/src/Components/Login.js b/src/Components/Login.js new file mode 100644 index 00000000..c2c4355e --- /dev/null +++ b/src/Components/Login.js @@ -0,0 +1,9 @@ +import React from 'react'; + +export default function Login (){ + return( +
+ test +
+ ) +} \ No newline at end of file diff --git a/src/Components/Movie.js b/src/Components/Movie.js new file mode 100644 index 00000000..b17909bc --- /dev/null +++ b/src/Components/Movie.js @@ -0,0 +1,9 @@ +import React from 'react'; + +export default function Movie (){ + return( +
+ test +
+ ) +} \ No newline at end of file diff --git a/src/Components/Profile.js b/src/Components/Profile.js new file mode 100644 index 00000000..460e11b6 --- /dev/null +++ b/src/Components/Profile.js @@ -0,0 +1,9 @@ +import React from 'react'; + +export default function Profile (){ + return( +
+ test +
+ ) +} \ No newline at end of file diff --git a/src/Components/Register.js b/src/Components/Register.js new file mode 100644 index 00000000..05daf9b5 --- /dev/null +++ b/src/Components/Register.js @@ -0,0 +1,9 @@ +import React from 'react'; + +export default function Register (){ + return( +
+ test +
+ ) +} \ No newline at end of file From db4da73d226111b6550f229ac6a4106fca575102 Mon Sep 17 00:00:00 2001 From: normanlikescats Date: Fri, 10 Mar 2023 12:00:31 +0800 Subject: [PATCH 04/24] built login/register page --- src/Components/App.js | 21 ++++++-- src/Components/Error.js | 2 +- src/Components/Feed.js | 5 +- src/Components/LandingPage.js | 3 +- src/Components/Login.js | 92 ++++++++++++++++++++++++++++++++++- src/Components/Movie.js | 2 +- src/Components/NavBar.js | 21 ++++++++ src/Components/Profile.js | 2 +- src/Components/Register.js | 9 ---- src/index.js | 2 +- 10 files changed, 140 insertions(+), 19 deletions(-) create mode 100644 src/Components/NavBar.js delete mode 100644 src/Components/Register.js diff --git a/src/Components/App.js b/src/Components/App.js index 2fa38a80..81d6ca54 100644 --- a/src/Components/App.js +++ b/src/Components/App.js @@ -3,25 +3,40 @@ import { BrowserRouter, Route, Routes, + Link } from "react-router-dom"; import LandingPage from "./LandingPage" import Login from "./Login" -import Register from "./Register" import Feed from "./Feed" import Error from "./Error" import Movie from "./Movie" import Profile from "./Profile" import "./App.css"; +function NavBar (){ + return( +
+ +
+ ) +} + + function App() { return (
- }/> + }/> }/> - }/> }/> }/> }/> diff --git a/src/Components/Error.js b/src/Components/Error.js index b74cd68c..22af4d6a 100644 --- a/src/Components/Error.js +++ b/src/Components/Error.js @@ -3,7 +3,7 @@ import React from 'react'; export default function Error (){ return(
- test + error
) } \ No newline at end of file diff --git a/src/Components/Feed.js b/src/Components/Feed.js index 5f90d5c5..d59f49dc 100644 --- a/src/Components/Feed.js +++ b/src/Components/Feed.js @@ -3,7 +3,10 @@ import React from 'react'; export default function Feed (){ return(
- test + + + +
) } \ No newline at end of file diff --git a/src/Components/LandingPage.js b/src/Components/LandingPage.js index 4a4cd909..b55286a7 100644 --- a/src/Components/LandingPage.js +++ b/src/Components/LandingPage.js @@ -1,9 +1,10 @@ import React from 'react'; +import Movie from './Movie'; export default function LandingPage (){ return(
- test +

LandingPage

) } \ No newline at end of file diff --git a/src/Components/Login.js b/src/Components/Login.js index c2c4355e..0200670b 100644 --- a/src/Components/Login.js +++ b/src/Components/Login.js @@ -1,9 +1,99 @@ import React from 'react'; +import { useState } from 'react'; +import { createUserWithEmailAndPassword, signInWithEmailAndPassword } from "firebase/auth"; +import { auth } from '../firebase'; +import { useNavigate } from 'react-router-dom'; export default function Login (){ + const navigate = useNavigate(); + const [email, setEmail] = useState('') + const [password, setPassword] = useState('') + const [user, setUser] = useState(null) + const [mode, setMode ] = useState('Login') + + function handleInput(e){ + if (e.target.name === 'email'){ + setEmail(e.target.value) + } else if (e.target.name === 'password'){ + setPassword(e.target.value) + } + console.log(`email: ${email} and password: ${password}`) + } + + function handleSubmit(e){ + e.preventDefault(); + if(e.name === 'login'){ + console.log('login') + if (email === '' || password === ''){ + alert('Please enter an email and passowrd') + } else{ + signInWithEmailAndPassword(auth, email, password) + .then((userCredential) => { + // Signed in + console.log('signed in!') + console.log(userCredential) + const user = userCredential.user; + setUser(user); + navigate('/feed') + }) + .catch((error) => { + const errorMessage = error.message; + console.log(errorMessage); + console.log(error.code) + if (error.code ==='auth/invalid-email'){ + alert('Invalid Email') + } else if (error.code ==='auth/wrong-password'){ + alert('Incorrect Password') + } else{ + alert(`Error: ${error.code}`) + } + }); + } + } else if (e.name === 'signup'){ + console.log('signup') + if (email === '' || password === ''){ + alert('Please enter an email and passowrd') + } else if(email.indexOf('@')===-1 || email.indexOf('@') === email.length-1){ + alert('Please use a valid email format') + } else { + createUserWithEmailAndPassword(auth, email, password) + .then((userCredential) => { + // Signed in + console.log(userCredential) + const user = userCredential.user; + setUser(user); + navigate('/feed') + }) + .catch((error) => { + console.log(error.message); + console.log(error.code) + }); + } + } + } + + function changeLogin(e){ + setMode('Login') + console.log(mode) + } + + function changeRegister(e){ + setMode('Register') + console.log(mode) + } + return(
- test + + +
+ + + { mode === 'Login' + ? + : + } +
) } \ No newline at end of file diff --git a/src/Components/Movie.js b/src/Components/Movie.js index b17909bc..2f1e0f18 100644 --- a/src/Components/Movie.js +++ b/src/Components/Movie.js @@ -3,7 +3,7 @@ import React from 'react'; export default function Movie (){ return(
- test + movie
) } \ No newline at end of file diff --git a/src/Components/NavBar.js b/src/Components/NavBar.js new file mode 100644 index 00000000..4410b220 --- /dev/null +++ b/src/Components/NavBar.js @@ -0,0 +1,21 @@ +import React from 'react'; +import { Link } from 'react-router-dom'; + +export default function NavBar (){ + return( +
+ +
+ ) +} + + + diff --git a/src/Components/Profile.js b/src/Components/Profile.js index 460e11b6..f4ddd1b2 100644 --- a/src/Components/Profile.js +++ b/src/Components/Profile.js @@ -3,7 +3,7 @@ import React from 'react'; export default function Profile (){ return(
- test + profile
) } \ No newline at end of file diff --git a/src/Components/Register.js b/src/Components/Register.js deleted file mode 100644 index 05daf9b5..00000000 --- a/src/Components/Register.js +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react'; - -export default function Register (){ - return( -
- test -
- ) -} \ No newline at end of file diff --git a/src/index.js b/src/index.js index 31508db1..08bd95e3 100644 --- a/src/index.js +++ b/src/index.js @@ -1,7 +1,7 @@ import React from "react"; import ReactDOM from "react-dom/client"; import "./index.css"; -import App from "./App"; +import App from "./Components/App"; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( From 3c0476b9bc3077fc0d07b0c4f467fd48d1188039 Mon Sep 17 00:00:00 2001 From: normanlikescats Date: Sat, 11 Mar 2023 17:33:45 +0800 Subject: [PATCH 05/24] set up create a review page, movie specific page and api calls --- package-lock.json | 15 +++++ package.json | 1 + src/Components/App.js | 21 ++----- src/Components/Feed.js | 19 +++++- src/Components/Login.js | 15 +++-- src/Components/Movie.css | 3 + src/Components/Movie.js | 80 +++++++++++++++++++++++- src/Components/ReviewCreator.css | 9 +++ src/Components/ReviewCreator.js | 102 +++++++++++++++++++++++++++++++ src/Components/SearchResult.css | 13 ++++ src/Components/SearchResult.js | 19 ++++++ src/Components/StarRating.css | 8 +++ src/Components/StarRating.js | 37 +++++++++++ src/index.js | 2 - 14 files changed, 317 insertions(+), 27 deletions(-) create mode 100644 src/Components/Movie.css create mode 100644 src/Components/ReviewCreator.css create mode 100644 src/Components/ReviewCreator.js create mode 100644 src/Components/SearchResult.css create mode 100644 src/Components/SearchResult.js create mode 100644 src/Components/StarRating.css create mode 100644 src/Components/StarRating.js diff --git a/package-lock.json b/package-lock.json index 10b1f464..ac1db14e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "firebase": "^9.17.2", "react": "^18.1.0", "react-dom": "^18.1.0", + "react-icons": "^4.8.0", "react-router-dom": "^6.8.2", "react-scripts": "5.0.1" } @@ -13872,6 +13873,14 @@ "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" }, + "node_modules/react-icons": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.8.0.tgz", + "integrity": "sha512-N6+kOLcihDiAnj5Czu637waJqSnwlMNROzVZMhfX68V/9bu9qHaMIJC4UdozWoOk57gahFCNHwVvWzm0MTzRjg==", + "peerDependencies": { + "react": "*" + } + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -26581,6 +26590,12 @@ "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" }, + "react-icons": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.8.0.tgz", + "integrity": "sha512-N6+kOLcihDiAnj5Czu637waJqSnwlMNROzVZMhfX68V/9bu9qHaMIJC4UdozWoOk57gahFCNHwVvWzm0MTzRjg==", + "requires": {} + }, "react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", diff --git a/package.json b/package.json index 38ca49a1..ccf76aa2 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "firebase": "^9.17.2", "react": "^18.1.0", "react-dom": "^18.1.0", + "react-icons": "^4.8.0", "react-router-dom": "^6.8.2", "react-scripts": "5.0.1" }, diff --git a/src/Components/App.js b/src/Components/App.js index 81d6ca54..3cffb8c1 100644 --- a/src/Components/App.js +++ b/src/Components/App.js @@ -11,23 +11,9 @@ import Feed from "./Feed" import Error from "./Error" import Movie from "./Movie" import Profile from "./Profile" +import ReviewCreator from "./ReviewCreator" import "./App.css"; -function NavBar (){ - return( -
- -
- ) -} - function App() { return ( @@ -39,8 +25,9 @@ function App() { }/> }/> }/> - }/> - }/> + }/> + }/> + }/>
diff --git a/src/Components/Feed.js b/src/Components/Feed.js index d59f49dc..044ee34a 100644 --- a/src/Components/Feed.js +++ b/src/Components/Feed.js @@ -1,12 +1,27 @@ import React from 'react'; +import { useNavigate } from 'react-router-dom'; +import { signOut } from "firebase/auth" +import { storage, database, auth } from "../firebase"; export default function Feed (){ + const navigate = useNavigate(); + + function handleSignOut(){ + console.log('signed out') + navigate('/login'); + } + + function handleCreateReview(){ + console.log('create review') + navigate('/create-review') + } + return(
- + - +
) } \ No newline at end of file diff --git a/src/Components/Login.js b/src/Components/Login.js index 0200670b..7b9df155 100644 --- a/src/Components/Login.js +++ b/src/Components/Login.js @@ -22,8 +22,8 @@ export default function Login (){ function handleSubmit(e){ e.preventDefault(); - if(e.name === 'login'){ - console.log('login') + if(mode === 'Login'){ + console.log('loginrun') if (email === '' || password === ''){ alert('Please enter an email and passowrd') } else{ @@ -49,8 +49,8 @@ export default function Login (){ } }); } - } else if (e.name === 'signup'){ - console.log('signup') + } else if (mode === 'Register'){ + console.log('signup run') if (email === '' || password === ''){ alert('Please enter an email and passowrd') } else if(email.indexOf('@')===-1 || email.indexOf('@') === email.length-1){ @@ -75,20 +75,25 @@ export default function Login (){ function changeLogin(e){ setMode('Login') console.log(mode) + setPassword('') + setEmail('') } function changeRegister(e){ setMode('Register') console.log(mode) + setPassword('') + setEmail('') } return(
+

{mode}

- + { mode === 'Login' ? : diff --git a/src/Components/Movie.css b/src/Components/Movie.css new file mode 100644 index 00000000..566c954f --- /dev/null +++ b/src/Components/Movie.css @@ -0,0 +1,3 @@ +.movie-poster{ + max-height: 50vh; +} \ No newline at end of file diff --git a/src/Components/Movie.js b/src/Components/Movie.js index 2f1e0f18..2301944d 100644 --- a/src/Components/Movie.js +++ b/src/Components/Movie.js @@ -1,9 +1,87 @@ import React from 'react'; +import { useState, useEffect } from 'react'; +import { onChildAdded, push, ref, set } from "firebase/database"; +import { storage, database, auth } from "../firebase"; +import { useLocation } from 'react-router-dom'; +import axios from 'axios'; +import "./Movie.css" +import StarRating from './StarRating'; + +const DB_REVIEWS_KEY = "reviews"; export default function Movie (){ + const [reviews, setReviews] = useState([]); + const [reviewInput, setReviewInput] = useState(''); + const [rating, setRating] = useState(null); + const location = useLocation(); + const [imgPath, setImgPath] = useState(`https://image.tmdb.org/t/p/w1280/`); + + const movieId = location.pathname.split("/")[2]; + const movieTitle = location.pathname.split("/")[3].split("%20").join(" "); + + useEffect(()=>{ + axios.get(`https://api.themoviedb.org/3/movie/${movieId}?api_key=${process.env.REACT_APP_MOVIES_API_KEY}&language=en-US`).then(function (response) { + console.log(response) + setImgPath(()=> imgPath + response.data.poster_path) + }).catch(function (error) { + console.error(error); + }); + },[]) + + useEffect(()=> { + const reviewsRef = ref(database, DB_REVIEWS_KEY + "/" + movieId); + // For Text Input + onChildAdded(reviewsRef, (data) => { + setReviews((prev)=> [...prev, {key: data.key, val: data.val()}]) + }) + },[]) + + function handleReviewInput(e){ + setReviewInput(e.target.value) + } + + function handleReviewSubmit(e){ + e.preventDefault(); + + if (rating === null || reviewInput === ''){ + alert('Please enter a rating or review') + } else { + const reiewsListRef = ref(database, DB_REVIEWS_KEY+ "/" + movieId); + const newReviewRef = push(reiewsListRef); + let currDate = new Date(); + set(newReviewRef, { + val: reviewInput, + dateTime: currDate.toLocaleDateString() + " " + currDate.toLocaleTimeString([], {hour: '2-digit', minute: '2-digit'}), + rating: rating + }); + setReviewInput(''); + } + } + + let reviewItems = reviews.map((review) => ( +
+ {review.val.val + " - " + [...Array(review.val.rating)].map((star)=>{return "★"}).join('')}
+ {review.val.dateTime} +
+ )); + + function changeStarRating(rating){ + setRating(rating); + } + return(
- movie +

{movieTitle}

+ + +
Write a Review:
+ + + + +
+ {reviewItems} +
) } \ No newline at end of file diff --git a/src/Components/ReviewCreator.css b/src/Components/ReviewCreator.css new file mode 100644 index 00000000..50f0f249 --- /dev/null +++ b/src/Components/ReviewCreator.css @@ -0,0 +1,9 @@ +.selected-movie-flex{ + display: flex; + flex-direction: column; +} + +.selected-movie-poster{ + max-height: 40vh; + align-self: center; +} \ No newline at end of file diff --git a/src/Components/ReviewCreator.js b/src/Components/ReviewCreator.js new file mode 100644 index 00000000..cf615d4d --- /dev/null +++ b/src/Components/ReviewCreator.js @@ -0,0 +1,102 @@ +import React from 'react'; +import { useState, useEffect } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { onChildAdded, push, ref, set } from "firebase/database"; +import { storage, database, auth } from "../firebase"; +import axios from 'axios'; +import SearchResult from './SearchResult'; +import "./ReviewCreator.css"; +import StarRating from './StarRating'; + +const DB_REVIEWS_KEY = "reviews"; + +export default function ReviewCreator (){ + const navigate = useNavigate(); + const [reviewInput, setReviewInput] = useState('') + const [searchInput, setSearchInput] = useState('') + const [searchResult, setSearchResult] = useState([]) + const [movie, setMovie] = useState(null) + const [rating, setRating] = useState(null) + + + function handleReviewInput(e){ + setReviewInput(e.target.value) + } + + function handleReviewSubmit(e){ + e.preventDefault(); + if (rating === null || reviewInput === ''){ + alert('Please enter a rating or review') + } else{ + const reiewsListRef = ref(database, DB_REVIEWS_KEY + "/" + movie.id); + const newReviewRef = push(reiewsListRef); + let currDate = new Date(); + set(newReviewRef, { + val: reviewInput, + rating: rating, + dateTime: currDate.toLocaleDateString() + " " + currDate.toLocaleTimeString([], {hour: '2-digit', minute: '2-digit'}), + }); + setReviewInput(''); + navigate("/movie/" + movie.id + "/" + movie.title) + } + } + + function handleSearchInput(e) { + setSearchInput(e.target.value); + fetchSearchResult(e); + } + + function fetchSearchResult(e){ + axios.get(`https://api.themoviedb.org/3/search/movie?api_key=${process.env.REACT_APP_MOVIES_API_KEY}&language=en-US&query=${e.target.value}`).then(function (response) { + const slicedArray = response.data.results.slice(0,5) + console.log(response.data.results) + setSearchResult(slicedArray); + console.log(searchResult); + }).catch(function (error) { + console.error(error); + }); + } + + function handleResultClick(imgPath, title, id){ + setMovie({ + id: id, + title: title, + imgPath: imgPath + }) + setSearchResult([]); + setSearchInput(''); + } + + function changeStarRating(rating){ + setRating(rating); + } + + let searchResultItems = searchResult.map((result, id) => ( + + )); + + console.log(rating) + console.log(reviewInput) + return( +
+

REVIEW CREATOOOOOOOOOR

+
+ + {searchResultItems} +
+ {movie === null + ? null + :
+

{movie.title}

+ +
Rating
+
} + +
+
Review:
+ + +
+
+ ) +} \ No newline at end of file diff --git a/src/Components/SearchResult.css b/src/Components/SearchResult.css new file mode 100644 index 00000000..e2ed09e9 --- /dev/null +++ b/src/Components/SearchResult.css @@ -0,0 +1,13 @@ +.search-flex-container{ + width: 100%; + display: flex; + flex-wrap: nowrap; +} + +.search-flex-container:hover{ + background-color: #000; +} + +.search-preview-image { + max-width: 40px; +} \ No newline at end of file diff --git a/src/Components/SearchResult.js b/src/Components/SearchResult.js new file mode 100644 index 00000000..aef38774 --- /dev/null +++ b/src/Components/SearchResult.js @@ -0,0 +1,19 @@ +import React from 'react'; +import "./SearchResult.css" + +export default function SearchResult (props){ + const imgPath = `https://image.tmdb.org/t/p/w1280/${props.movieDetails.poster_path}` + const title = props.movieDetails.title + const id = props.movieDetails.id + + function handleClick(){ + props.handleResultClick(imgPath, title, id) + } + + return( +
+ +

{props.movieDetails.title}

+
+ ) +} \ No newline at end of file diff --git a/src/Components/StarRating.css b/src/Components/StarRating.css new file mode 100644 index 00000000..5228f1cb --- /dev/null +++ b/src/Components/StarRating.css @@ -0,0 +1,8 @@ +input[type="radio"] { + display: none; +} + +.star{ + size: 150; + cursor: pointer; +} diff --git a/src/Components/StarRating.js b/src/Components/StarRating.js new file mode 100644 index 00000000..2c0d5274 --- /dev/null +++ b/src/Components/StarRating.js @@ -0,0 +1,37 @@ +import React from 'react'; +import { useState, useEffect } from 'react'; +import { FaStar} from 'react-icons/fa'; +import "./StarRating.css"; + +export default function StarRating (props){ + const [rating, setRating] = useState(null); + const [hover, setHover] = useState(null); + + useEffect(()=>{ + props.changeStarRating(rating) + }) + + return( +
+ {[...Array(5)].map((star, counter)=>{ + const ratingValue = counter + 1 + return( + + ) + })} +
+ ) +} \ No newline at end of file diff --git a/src/index.js b/src/index.js index 08bd95e3..efa55881 100644 --- a/src/index.js +++ b/src/index.js @@ -5,7 +5,5 @@ import App from "./Components/App"; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( - - ); From 8e2cffeae1bc842364d891265a7cbc0471df9433 Mon Sep 17 00:00:00 2001 From: normanlikescats Date: Sun, 12 Mar 2023 21:59:24 +0800 Subject: [PATCH 06/24] created movies database for movies with reviews and home feed to show posters of movies with reviews --- src/Components/Feed.js | 22 ++++++++++++++++++++++ src/Components/Movie.js | 23 +++++++++++++++++++---- src/Components/ReviewCreator.js | 32 ++++++++++++++++++++++++++++---- 3 files changed, 69 insertions(+), 8 deletions(-) diff --git a/src/Components/Feed.js b/src/Components/Feed.js index 044ee34a..fcc781d5 100644 --- a/src/Components/Feed.js +++ b/src/Components/Feed.js @@ -1,10 +1,25 @@ import React from 'react'; +import { useEffect,useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { signOut } from "firebase/auth" +import { ref, onChildAdded } from "firebase/database" +import axios from 'axios'; import { storage, database, auth } from "../firebase"; +const DB_MOVIES_KEY = "movies"; +const DB_REVIEWS_KEY = "reviews"; + export default function Feed (){ const navigate = useNavigate(); + const [movies, setMovies] = useState([]); + + useEffect(()=> { + const moviesRef = ref(database, DB_MOVIES_KEY); + // For Text Input + onChildAdded(moviesRef, (data) => { + setMovies((prev)=> [...prev, {key: data.key, val: data.val()}]) + }) + },[]) function handleSignOut(){ console.log('signed out') @@ -16,12 +31,19 @@ export default function Feed (){ navigate('/create-review') } + let moviesList = movies.map((movie)=>( + + )) + return(
+
+ {moviesList} +
) } \ No newline at end of file diff --git a/src/Components/Movie.js b/src/Components/Movie.js index 2301944d..f21bf0fe 100644 --- a/src/Components/Movie.js +++ b/src/Components/Movie.js @@ -1,13 +1,14 @@ import React from 'react'; import { useState, useEffect } from 'react'; -import { onChildAdded, push, ref, set } from "firebase/database"; -import { storage, database, auth } from "../firebase"; +import { onChildAdded, push, ref, set, get } from "firebase/database"; +import { storage, database, auth } from "../firebase"; import { useLocation } from 'react-router-dom'; import axios from 'axios'; import "./Movie.css" import StarRating from './StarRating'; const DB_REVIEWS_KEY = "reviews"; +const DB_MOVIES_KEY = "movies"; export default function Movie (){ const [reviews, setReviews] = useState([]); @@ -21,7 +22,6 @@ export default function Movie (){ useEffect(()=>{ axios.get(`https://api.themoviedb.org/3/movie/${movieId}?api_key=${process.env.REACT_APP_MOVIES_API_KEY}&language=en-US`).then(function (response) { - console.log(response) setImgPath(()=> imgPath + response.data.poster_path) }).catch(function (error) { console.error(error); @@ -54,10 +54,25 @@ export default function Movie (){ dateTime: currDate.toLocaleDateString() + " " + currDate.toLocaleTimeString([], {hour: '2-digit', minute: '2-digit'}), rating: rating }); + addMovieDatabase(); setReviewInput(''); } } + function addMovieDatabase(){ + if (reviews.length === 0){ + const moviesListRef = ref(database, DB_MOVIES_KEY); + const newMovieRef = push(moviesListRef); + set(newMovieRef, { + id: movieId, + title: movieTitle, + imgPath: imgPath + }); + } + console.log('reviews') + console.log(reviews) + } + let reviewItems = reviews.map((review) => (
{review.val.val + " - " + [...Array(review.val.rating)].map((star)=>{return "★"}).join('')}
@@ -68,7 +83,7 @@ export default function Movie (){ function changeStarRating(rating){ setRating(rating); } - + console.log(reviews) return(

{movieTitle}

diff --git a/src/Components/ReviewCreator.js b/src/Components/ReviewCreator.js index cf615d4d..1e543d0d 100644 --- a/src/Components/ReviewCreator.js +++ b/src/Components/ReviewCreator.js @@ -9,6 +9,7 @@ import "./ReviewCreator.css"; import StarRating from './StarRating'; const DB_REVIEWS_KEY = "reviews"; +const DB_MOVIES_KEY = "movies"; export default function ReviewCreator (){ const navigate = useNavigate(); @@ -17,6 +18,8 @@ export default function ReviewCreator (){ const [searchResult, setSearchResult] = useState([]) const [movie, setMovie] = useState(null) const [rating, setRating] = useState(null) + const [reviews, setReviews] = useState([]); + function handleReviewInput(e){ @@ -37,10 +40,24 @@ export default function ReviewCreator (){ dateTime: currDate.toLocaleDateString() + " " + currDate.toLocaleTimeString([], {hour: '2-digit', minute: '2-digit'}), }); setReviewInput(''); + addMovieDatabase(); navigate("/movie/" + movie.id + "/" + movie.title) } } + function addMovieDatabase(){ + if (reviews.length === 0){ + const moviesListRef = ref(database, DB_MOVIES_KEY); + const newMovieRef = push(moviesListRef); + set(newMovieRef, { + id: movie.id, + title: movie.title, + imgPath: movie.imgPath + }); + } + } + + function handleSearchInput(e) { setSearchInput(e.target.value); fetchSearchResult(e); @@ -49,9 +66,7 @@ export default function ReviewCreator (){ function fetchSearchResult(e){ axios.get(`https://api.themoviedb.org/3/search/movie?api_key=${process.env.REACT_APP_MOVIES_API_KEY}&language=en-US&query=${e.target.value}`).then(function (response) { const slicedArray = response.data.results.slice(0,5) - console.log(response.data.results) setSearchResult(slicedArray); - console.log(searchResult); }).catch(function (error) { console.error(error); }); @@ -63,10 +78,20 @@ export default function ReviewCreator (){ title: title, imgPath: imgPath }) + fetchReviews(id); + console.log(reviews); setSearchResult([]); setSearchInput(''); } + function fetchReviews (id){ + console.log('run') + const reviewsRef = ref(database, DB_REVIEWS_KEY + "/" + id); + onChildAdded(reviewsRef, (data) => { + setReviews((prev)=> [...prev, {key: data.key, val: data.val()}]) + }) + } + function changeStarRating(rating){ setRating(rating); } @@ -75,8 +100,7 @@ export default function ReviewCreator (){ )); - console.log(rating) - console.log(reviewInput) + console.log(reviews); return(

REVIEW CREATOOOOOOOOOR

From b88c37102a2a5b91288d4c2720183fb28b16f0a2 Mon Sep 17 00:00:00 2001 From: normanlikescats Date: Mon, 13 Mar 2023 16:35:20 +0800 Subject: [PATCH 07/24] add edit and delete buttons (v1, not final, not great) --- src/Components/Movie.js | 93 +++++++++++++++++++++++++++++++---- src/Components/ReviewBlock.js | 49 ++++++++++++++++++ 2 files changed, 132 insertions(+), 10 deletions(-) create mode 100644 src/Components/ReviewBlock.js diff --git a/src/Components/Movie.js b/src/Components/Movie.js index f21bf0fe..2dbada38 100644 --- a/src/Components/Movie.js +++ b/src/Components/Movie.js @@ -1,11 +1,12 @@ import React from 'react'; import { useState, useEffect } from 'react'; -import { onChildAdded, push, ref, set, get } from "firebase/database"; +import { onChildAdded, onChildRemoved, push, ref, set, get, update, remove } from "firebase/database"; import { storage, database, auth } from "../firebase"; import { useLocation } from 'react-router-dom'; import axios from 'axios'; import "./Movie.css" import StarRating from './StarRating'; +import ReviewBlock from './ReviewBlock'; const DB_REVIEWS_KEY = "reviews"; const DB_MOVIES_KEY = "movies"; @@ -34,7 +35,7 @@ export default function Movie (){ onChildAdded(reviewsRef, (data) => { setReviews((prev)=> [...prev, {key: data.key, val: data.val()}]) }) - },[]) + }, []) function handleReviewInput(e){ setReviewInput(e.target.value) @@ -69,21 +70,93 @@ export default function Movie (){ imgPath: imgPath }); } - console.log('reviews') - console.log(reviews) + } + + function handleReviewEdit(input, id){ + let index = -1; + for (let i = 0; i < reviews.length; i++){ + if(reviews[i].key === id){ + index = i; + } + } + + let updatedReview = {...reviews[index]}; + updatedReview.val.val = input; + + + console.log(updatedReview) + + let newReviewsArray = [...reviews]; + + newReviewsArray.splice(index, 1, updatedReview); + + setReviews(newReviewsArray); + } + + function handleStarsEdit( rating, id){ + let index = -1; + for (let i = 0; i < reviews.length; i++){ + if(reviews[i].key === id){ + index = i; + } + } + + let updatedReview = {...reviews[index]}; + updatedReview.val.rating = rating; + + let newReviewsArray = [...reviews]; + + newReviewsArray.splice(index, 1, updatedReview); + + setReviews(newReviewsArray); + } + + function confirmChanges(reviewText, id ){ + const reviewRef = ref(database, DB_REVIEWS_KEY+ "/" + movieId + "/" + id); + update(reviewRef, { + val: reviewText, + }) + } + + function handleDelete(id){ + const reviewRef = ref(database, DB_REVIEWS_KEY+ "/" + movieId + "/" + id); + let updatedArray = []; + if (reviews.length >1){ + let index = -1; + for (let i = 0; i < reviews.length; i++){ + if(reviews[i].key === id){ + console.log('true') + index = i; + updatedArray = [...reviews].splice(0, 1) + } + } + } + + + console.log(updatedArray); + setReviews(updatedArray); + remove(reviewRef); } let reviewItems = reviews.map((review) => ( -
- {review.val.val + " - " + [...Array(review.val.rating)].map((star)=>{return "★"}).join('')}
- {review.val.dateTime} -
- )); +
+ +
+ )); function changeStarRating(rating){ setRating(rating); } - console.log(reviews) + return(

{movieTitle}

diff --git a/src/Components/ReviewBlock.js b/src/Components/ReviewBlock.js new file mode 100644 index 00000000..437e67bd --- /dev/null +++ b/src/Components/ReviewBlock.js @@ -0,0 +1,49 @@ +import React from 'react'; +import { useState, useEffect } from 'react'; +import StarRating from './StarRating'; + +export default function ReviewBlock (props){ + const [editMode, setEditMode] = useState(false); + + function handleEditMode(){ + setEditMode(!editMode) + } + + function confirmChanges(){ + setEditMode(!editMode) + props.confirmChanges(props.reviewText, props.id); + } + + function handleReviewInput(e){ + props.handleReviewEdit(e.target.value, props.id) + } + + function handleDelete(){ + props.handleDelete(props.id) + } + + function changeStarRating(rating){ + props.handleStarsEdit(rating, props.id) + } + + return( +
+
+ {editMode===true + ? + : } + +
+ {editMode === true + ?
+ + +

{props.datetime}

+
+ :
+

{props.reviewText} - {[...Array(props.stars)].map((star)=>{return "★"}).join('')}

+

{props.datetime}

+
} +
+ ) +} \ No newline at end of file From 3e1572417fc5c0fce373c72cf62aa9471312078d Mon Sep 17 00:00:00 2001 From: normanlikescats Date: Tue, 14 Mar 2023 11:23:16 +0800 Subject: [PATCH 08/24] add context to signin and signup --- src/Components/App.js | 7 ++++-- src/Components/Login.js | 42 +++++++++++++++------------------- src/Context/AuthContext.js | 46 ++++++++++++++++++++++++++++++++++++++ src/firebase.js | 2 +- 4 files changed, 70 insertions(+), 27 deletions(-) create mode 100644 src/Context/AuthContext.js diff --git a/src/Components/App.js b/src/Components/App.js index 3cffb8c1..80db4f0f 100644 --- a/src/Components/App.js +++ b/src/Components/App.js @@ -13,13 +13,15 @@ import Movie from "./Movie" import Profile from "./Profile" import ReviewCreator from "./ReviewCreator" import "./App.css"; +import { AuthContextProvider } from "../Context/AuthContext"; function App() { return (
- + + }/> }/> @@ -28,8 +30,9 @@ function App() { }/> }/> }/> - + +
); diff --git a/src/Components/Login.js b/src/Components/Login.js index 7b9df155..5251b558 100644 --- a/src/Components/Login.js +++ b/src/Components/Login.js @@ -3,6 +3,7 @@ import { useState } from 'react'; import { createUserWithEmailAndPassword, signInWithEmailAndPassword } from "firebase/auth"; import { auth } from '../firebase'; import { useNavigate } from 'react-router-dom'; +import { UserAuth } from '../Context/AuthContext' export default function Login (){ const navigate = useNavigate(); @@ -10,6 +11,8 @@ export default function Login (){ const [password, setPassword] = useState('') const [user, setUser] = useState(null) const [mode, setMode ] = useState('Login') + + const { createUser, signIn } = UserAuth(); function handleInput(e){ if (e.target.name === 'email'){ @@ -20,23 +23,18 @@ export default function Login (){ console.log(`email: ${email} and password: ${password}`) } - function handleSubmit(e){ + function handleSubmit (e) { e.preventDefault(); + console.log('run') + if(mode === 'Login'){ console.log('loginrun') if (email === '' || password === ''){ alert('Please enter an email and passowrd') } else{ - signInWithEmailAndPassword(auth, email, password) - .then((userCredential) => { - // Signed in - console.log('signed in!') - console.log(userCredential) - const user = userCredential.user; - setUser(user); - navigate('/feed') - }) - .catch((error) => { + signIn(email, password).then(()=>{ + navigate('/profile') + }).catch((error) => { const errorMessage = error.message; console.log(errorMessage); console.log(error.code) @@ -56,21 +54,17 @@ export default function Login (){ } else if(email.indexOf('@')===-1 || email.indexOf('@') === email.length-1){ alert('Please use a valid email format') } else { - createUserWithEmailAndPassword(auth, email, password) - .then((userCredential) => { - // Signed in - console.log(userCredential) - const user = userCredential.user; - setUser(user); - navigate('/feed') - }) - .catch((error) => { - console.log(error.message); - console.log(error.code) - }); + createUser(email, password).then(()=>{ + navigate('/profile') + }).catch((error) => { + const errorMessage = error.message; + console.log(errorMessage); + console.log(error.code) + }) + }; } } - } + function changeLogin(e){ setMode('Login') diff --git a/src/Context/AuthContext.js b/src/Context/AuthContext.js new file mode 100644 index 00000000..070bc2bf --- /dev/null +++ b/src/Context/AuthContext.js @@ -0,0 +1,46 @@ +import { createContext, useContext, useEffect, useState } from 'react'; +import { + createUserWithEmailAndPassword, + signInWithEmailAndPassword, + signOut, + onAuthStateChanged, +} from 'firebase/auth'; +import { auth } from '../firebase'; + +const UserContext = createContext(); + +export const AuthContextProvider = ({ children }) => { + const [user, setUser] = useState({}); + + const createUser = (email, password) => { + return createUserWithEmailAndPassword(auth, email, password); + }; + + const signIn = (email, password) => { + return signInWithEmailAndPassword(auth, email, password) + } + + const logout = () => { + return signOut(auth) + } + + useEffect(() => { + const unsubscribe = onAuthStateChanged(auth, (currentUser) => { + console.log(currentUser); + setUser(currentUser); + }); + return () => { + unsubscribe(); + }; + }, []); + + return ( + + {children} + + ); +}; + +export const UserAuth = () => { + return useContext(UserContext); +}; diff --git a/src/firebase.js b/src/firebase.js index b2bdea46..8383abff 100644 --- a/src/firebase.js +++ b/src/firebase.js @@ -2,7 +2,7 @@ import { initializeApp } from "firebase/app"; import { getDatabase } from "firebase/database"; import { getStorage } from "firebase/storage"; -import { getAuth } from "firebase/auth"; +import { getAuth, setPersistence, browserSessionPersistence } from "firebase/auth"; const firebaseConfig = { apiKey: process.env.REACT_APP_API_KEY, From e02fd7bc6641274bf02a810c510617920df1d39b Mon Sep 17 00:00:00 2001 From: normanlikescats Date: Tue, 14 Mar 2023 15:06:48 +0800 Subject: [PATCH 09/24] insert create a profile page and allow profile picture upload --- src/Components/Login.js | 2 +- src/Components/Profile.css | 5 ++++ src/Components/Profile.js | 60 +++++++++++++++++++++++++++++++++++++- src/Context/AuthContext.js | 4 +-- src/firebase.js | 22 ++++++++++++-- 5 files changed, 86 insertions(+), 7 deletions(-) create mode 100644 src/Components/Profile.css diff --git a/src/Components/Login.js b/src/Components/Login.js index 5251b558..44e29be9 100644 --- a/src/Components/Login.js +++ b/src/Components/Login.js @@ -51,7 +51,7 @@ export default function Login (){ console.log('signup run') if (email === '' || password === ''){ alert('Please enter an email and passowrd') - } else if(email.indexOf('@')===-1 || email.indexOf('@') === email.length-1){ + } else if(email.indexOf('@')===-1 || email.indexOf('@') === email.length-1 || email.indexOf('@') === 0){ alert('Please use a valid email format') } else { createUser(email, password).then(()=>{ diff --git a/src/Components/Profile.css b/src/Components/Profile.css new file mode 100644 index 00000000..3c140bc8 --- /dev/null +++ b/src/Components/Profile.css @@ -0,0 +1,5 @@ +.profile-pic { + height: 30vw; + width: 30vw; + object-fit: cover; +} \ No newline at end of file diff --git a/src/Components/Profile.js b/src/Components/Profile.js index f4ddd1b2..52233334 100644 --- a/src/Components/Profile.js +++ b/src/Components/Profile.js @@ -1,9 +1,67 @@ import React from 'react'; +import { useState, useEffect } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { UserAuth } from '../Context/AuthContext' +import { upload } from '../firebase'; +import "./Profile.css" export default function Profile (){ + const navigate = useNavigate(); + const { user , logout } = UserAuth(); + const [ bio, setBio ] = useState(''); + const [ profilePic, setProfilePic] = useState(null); + const [ loading, setLoading ] = useState(false); + const [ photoURL, setPhotoURL] = useState('https://i.pinimg.com/564x/9b/47/a0/9b47a023caf29f113237d61170f34ad9.jpg') + + useEffect(()=>{ + if(user ?.photoURL){ + setPhotoURL(user.photoURL) + } + }, [user.photoURL]) + + function handleBioEdit (e){ + setBio(()=> e.target.value) + } + + function handleLogout(){ + logout(); + navigate("/login") + } + + function handleSubmit(e){ + e.preventDefault(); + } + + function handleFile(e){ + if(e.target.files[0]){ + setProfilePic(e.target.files[0]) + } + } + + function uploadProfilePic (){ + upload(profilePic, user, setLoading); + } + + return(
- profile +
+ Profile Picture +
+ + +
+ Email: +
+ Bio: