From 5bf2b006a04fc442115f57b217ae9938c5440187 Mon Sep 17 00:00:00 2001 From: Tatenda Munenge Date: Tue, 8 Apr 2025 08:32:05 +0200 Subject: [PATCH 1/4] Update UI adds configs --- .gitignore | 1 + package-lock.json | 1035 +++++++++++++++-- package.json | 45 +- src/app.config.ts | 13 +- src/app.routes.ts | 2 + src/app/layout/component/app.menu.ts | 4 + src/app/pages/crud/crud.ts | 4 +- src/app/pages/empty/run.js | 17 + src/app/pages/ledger/ledger.component.html | 87 ++ src/app/pages/ledger/ledger.component.scss | 0 src/app/pages/ledger/ledger.component.spec.ts | 23 + src/app/pages/ledger/ledger.component.ts | 139 +++ src/app/pages/service/ledger.service.ts | 137 +++ src/index.html | 2 +- 14 files changed, 1376 insertions(+), 133 deletions(-) create mode 100644 src/app/pages/empty/run.js create mode 100644 src/app/pages/ledger/ledger.component.html create mode 100644 src/app/pages/ledger/ledger.component.scss create mode 100644 src/app/pages/ledger/ledger.component.spec.ts create mode 100644 src/app/pages/ledger/ledger.component.ts create mode 100644 src/app/pages/service/ledger.service.ts diff --git a/.gitignore b/.gitignore index 4934ebf81..7ddedec17 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ # Node /node_modules +/node_modulesxxx npm-debug.log yarn-error.log diff --git a/package-lock.json b/package-lock.json index bf1fba25a..396f897ca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,51 +1,52 @@ { "name": "sakai-ng", - "version": "19.0.0", + "version": "19.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "sakai-ng", - "version": "19.0.0", + "version": "19.0.1", "dependencies": { - "@angular/animations": "^19.0.0", - "@angular/common": "^19.0.0", - "@angular/compiler": "^19.0.0", - "@angular/core": "^19.0.0", - "@angular/forms": "^19.0.0", - "@angular/platform-browser": "^19.0.0", - "@angular/platform-browser-dynamic": "^19.0.0", - "@angular/router": "^19.0.0", + "@angular/animations": "19.0.5", + "@angular/common": "19.0.5", + "@angular/compiler": "19.0.5", + "@angular/core": "19.0.5", + "@angular/fire": "^19.0.0", + "@angular/forms": "19.0.5", + "@angular/platform-browser": "19.0.5", + "@angular/platform-browser-dynamic": "19.0.5", + "@angular/router": "19.0.5", "@primeng/themes": "^19.0.5", "chart.js": "4.4.2", "primeclt": "^0.1.5", "primeicons": "^7.0.0", - "primeng": "^19.0.5", + "primeng": "^19.0.8", "rxjs": "~7.8.0", - "tailwindcss-primeui": "^0.3.2", - "tslib": "^2.3.0", + "tailwindcss-primeui": "0.5.1", + "tslib": "2.3.0", "zone.js": "~0.15.0" }, "devDependencies": { - "@angular-devkit/build-angular": "^19.0.6", - "@angular/cli": "^19.0.6", - "@angular/compiler-cli": "^19.0.0", + "@angular-devkit/build-angular": "19.0.6", + "@angular/cli": "19.0.6", + "@angular/compiler-cli": "19.0.0", "@types/jasmine": "~5.1.0", - "autoprefixer": "^10.4.20", - "eslint": "^9.14.0", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-import": "^2.31.0", - "eslint-plugin-prefer-arrow": "^1.2.3", - "eslint-plugin-prettier": "^4.2.1", + "autoprefixer": "10.4.20", + "eslint": "9.14.0", + "eslint-config-prettier": "9.1.0", + "eslint-plugin-import": "2.31.0", + "eslint-plugin-prefer-arrow": "1.2.3", + "eslint-plugin-prettier": "4.2.1", "jasmine-core": "~5.4.0", "karma": "~6.4.0", "karma-chrome-launcher": "~3.2.0", "karma-coverage": "~2.2.0", "karma-jasmine": "~5.1.0", "karma-jasmine-html-reporter": "~2.1.0", - "postcss": "^8.4.49", - "prettier": "^3.0.0", - "tailwindcss": "^3.4.17", + "postcss": "8.4.49", + "prettier": "3.0.0", + "tailwindcss": "3.4.17", "typescript": "~5.6.2" } }, @@ -213,6 +214,13 @@ } } }, + "node_modules/@angular-devkit/build-angular/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, "node_modules/@angular-devkit/build-webpack": { "version": "0.1900.6", "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1900.6.tgz", @@ -236,7 +244,6 @@ "version": "19.0.6", "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.0.6.tgz", "integrity": "sha512-WUWJhzQDsovfMY6jtb9Ktz/5sJszsaErj+XV2aXab85f1OweI/Iv2urPZnJwUSilvVN5Ok/fy3IJ6SuihK4Ceg==", - "dev": true, "dependencies": { "ajv": "8.17.1", "ajv-formats": "3.0.1", @@ -263,7 +270,6 @@ "version": "19.0.6", "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-19.0.6.tgz", "integrity": "sha512-R9hlHfAh1HKoIWgnYJlOEKhUezhTNl0fpUmHxG2252JSY5FLRxmYArTtJYYmbNdBbsBLNg3UHyM/GBPvJSA3NQ==", - "dev": true, "dependencies": { "@angular-devkit/core": "19.0.6", "jsonc-parser": "3.3.1", @@ -452,10 +458,11 @@ } }, "node_modules/@angular/compiler-cli": { - "version": "19.0.5", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-19.0.5.tgz", - "integrity": "sha512-KSzuWCTZlvJsoAenxM9cjTOzNM8mrFxDBInj0KVPz7QU83amGS4rcv1pWO/QGYQcErfskcN84TAdMegaRWWCmA==", + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-19.0.0.tgz", + "integrity": "sha512-2PxpsIeppoDLAx7A6i0GE10WjC+Fkz8tTQioa7r4y/+eYnniEjJFIQM/8lbkOnRVcuYoeXoNyYWr3fEQAyO4LA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "7.26.0", "@jridgewell/sourcemap-codec": "^1.4.14", @@ -475,7 +482,7 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/compiler": "19.0.5", + "@angular/compiler": "19.0.0", "typescript": ">=5.5 <5.7" } }, @@ -494,6 +501,36 @@ "zone.js": "~0.15.0" } }, + "node_modules/@angular/fire": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/@angular/fire/-/fire-19.0.0.tgz", + "integrity": "sha512-dVU9IdL9sGKe1fV7g2iGgkjUQIYrbnljHtHUgNpZaskyW+Vy6ndtsEbSUoRd6sLP8WpThWH7WvITKhu/8a6qfQ==", + "license": "MIT", + "dependencies": { + "@angular-devkit/schematics": "^19.0.0", + "@schematics/angular": "^19.0.0", + "firebase": "^11.2.0", + "rxfire": "^6.1.0", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/common": "^19.0.0", + "@angular/core": "^19.0.0", + "@angular/platform-browser": "^19.0.0", + "@angular/platform-browser-dynamic": "^19.0.0", + "@angular/platform-server": "^19.0.0", + "firebase-tools": "^13.0.0", + "rxjs": "~7.8.0" + }, + "peerDependenciesMeta": { + "@angular/platform-server": { + "optional": true + }, + "firebase-tools": { + "optional": true + } + } + }, "node_modules/@angular/forms": { "version": "19.0.5", "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-19.0.5.tgz", @@ -2525,12 +2562,13 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.1.tgz", - "integrity": "sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", + "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@eslint/object-schema": "^2.1.5", + "@eslint/object-schema": "^2.1.4", "debug": "^4.3.1", "minimatch": "^3.1.2" }, @@ -2539,13 +2577,11 @@ } }, "node_modules/@eslint/core": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.9.1.tgz", - "integrity": "sha512-GuUdqkyyzQI5RMIWkHhvTWLCyLo1jNK3vzkSyaExH5kHPDHcuL2VOpHjmMY+y3+NC69qAKToBqldTBgYeLSr9Q==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.7.0.tgz", + "integrity": "sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw==", "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.15" - }, + "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } @@ -2608,19 +2644,21 @@ "dev": true }, "node_modules/@eslint/js": { - "version": "9.17.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.17.0.tgz", - "integrity": "sha512-Sxc4hqcs1kTu0iID3kcZDW3JHq2a77HO9P8CP6YEA/FpH3Ll8UXE2r/86Rz9YJLKme39S9vU5OWNjC6Xl0Cr3w==", + "version": "9.14.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.14.0.tgz", + "integrity": "sha512-pFoEtFWCPyDOl+C6Ift+wC7Ro89otjigCf5vcuWqWgqNSQbRrpjSvdeE6ofLz4dHmyxD5f7gIdGT4+p36L6Twg==", "dev": true, + "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/object-schema": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.5.tgz", - "integrity": "sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==", + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } @@ -2637,6 +2675,645 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@firebase/analytics": { + "version": "0.10.12", + "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.12.tgz", + "integrity": "sha512-iDCGnw6qdFqwI5ywkgece99WADJNoymu+nLIQI4fZM/vCZ3bEo4wlpEetW71s1HqGpI0hQStiPhqVjFxDb2yyw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.13", + "@firebase/installations": "0.6.13", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.11.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/analytics-compat": { + "version": "0.2.18", + "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.18.tgz", + "integrity": "sha512-Hw9mzsSMZaQu6wrTbi3kYYwGw9nBqOHr47pVLxfr5v8CalsdrG5gfs9XUlPOZjHRVISp3oQrh1j7d3E+ulHPjQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/analytics": "0.10.12", + "@firebase/analytics-types": "0.8.3", + "@firebase/component": "0.6.13", + "@firebase/util": "1.11.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/analytics-types": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.3.tgz", + "integrity": "sha512-VrIp/d8iq2g501qO46uGz3hjbDb8xzYMrbu8Tp0ovzIzrvJZ2fvmj649gTjge/b7cCCcjT0H37g1gVtlNhnkbg==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/app": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.11.4.tgz", + "integrity": "sha512-GPREsZjfSaHzwyC6cI/Cqvzf6zxqMzya+25tSpUstdqC2w0IdfxEfOMjfdW7bDfVEf4Rb4Nb6gfoOAgVSp4c4g==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.13", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.11.0", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/app-check": { + "version": "0.8.13", + "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.8.13.tgz", + "integrity": "sha512-ONsgml8/dplUOAP42JQO6hhiWDEwR9+RUTLenxAN9S8N6gel/sDQ9Ci721Py1oASMGdDU8v9R7xAZxzvOX5lPg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.13", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.11.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/app-check-compat": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.20.tgz", + "integrity": "sha512-/twgmlnNAaZ/wbz3kcQrL/26b+X+zUX+lBmu5LwwEcWcpnb+mrVEAKhD7/ttm52dxYiSWtLDeuXy3FXBhqBC5A==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check": "0.8.13", + "@firebase/app-check-types": "0.5.3", + "@firebase/component": "0.6.13", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.11.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/app-check-interop-types": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.3.tgz", + "integrity": "sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/app-check-types": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.3.tgz", + "integrity": "sha512-hyl5rKSj0QmwPdsAxrI5x1otDlByQ7bvNvVt8G/XPO2CSwE++rmSVf3VEhaeOR4J8ZFaF0Z0NDSmLejPweZ3ng==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/app-compat": { + "version": "0.2.53", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.53.tgz", + "integrity": "sha512-vDeZSit0q4NyaDIVcaiJF3zhLgguP6yc0JwQAfpTyllgt8XMtkMFyY/MxJtFrK2ocpQX/yCbV2DXwvpY2NVuJw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app": "0.11.4", + "@firebase/component": "0.6.13", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.11.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/app-types": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.3.tgz", + "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/auth": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.10.0.tgz", + "integrity": "sha512-S7SqBsN7sIQsftNE3bitLlK+4bWrTHY+Rx2JFlNitgVYu2nK8W8ZQrkG8GCEwiFPq0B2vZ9pO5kVTFfq2sP96A==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.13", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.11.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@react-native-async-storage/async-storage": "^1.18.1" + }, + "peerDependenciesMeta": { + "@react-native-async-storage/async-storage": { + "optional": true + } + } + }, + "node_modules/@firebase/auth-compat": { + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.5.20.tgz", + "integrity": "sha512-8FwODTSBnaqGQbKfML7LcpzGGPyouB7YHg3dZq+CZMziVc7oBY1jJeNvpnM1hAQoVuTjWPXoRrCltdGeOlkKfQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/auth": "1.10.0", + "@firebase/auth-types": "0.13.0", + "@firebase/component": "0.6.13", + "@firebase/util": "1.11.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/auth-interop-types": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.4.tgz", + "integrity": "sha512-JPgcXKCuO+CWqGDnigBtvo09HeBs5u/Ktc2GaFj2m01hLarbxthLNm7Fk8iOP1aqAtXV+fnnGj7U28xmk7IwVA==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/auth-types": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.13.0.tgz", + "integrity": "sha512-S/PuIjni0AQRLF+l9ck0YpsMOdE8GO2KU6ubmBB7P+7TJUCQDa3R1dlgYm9UzGbbePMZsp0xzB93f2b/CgxMOg==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/component": { + "version": "0.6.13", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.13.tgz", + "integrity": "sha512-I/Eg1NpAtZ8AAfq8mpdfXnuUpcLxIDdCDtTzWSh+FXnp/9eCKJ3SNbOCKrUCyhLzNa2SiPJYruei0sxVjaOTeg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/util": "1.11.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/data-connect": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@firebase/data-connect/-/data-connect-0.3.3.tgz", + "integrity": "sha512-JsgppNX1wcQYP5bg4Sg6WTS7S0XazklSjr1fG3ox9DHtt4LOQwJ3X1/c81mKMIZxocV22ujiwLYQWG6Y9D1FiQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.13", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.11.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/database": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.14.tgz", + "integrity": "sha512-9nxYtkHAG02/Nh2Ssms1T4BbWPPjiwohCvkHDUl4hNxnki1kPgsLo5xe9kXNzbacOStmVys+RUXvwzynQSKmUQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.13", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.11.0", + "faye-websocket": "0.11.4", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database-compat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.0.5.tgz", + "integrity": "sha512-CNf1UbvWh6qIaSf4sn6sx2DTDz/em/D7QxULH1LTxxDQHr9+CeYGvlAqrKnk4ZH0P0eIHyQFQU7RwkUJI0B9gQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.13", + "@firebase/database": "1.0.14", + "@firebase/database-types": "1.0.10", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.11.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database-types": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.10.tgz", + "integrity": "sha512-mH6RC1E9/Pv8jf1/p+M8YFTX+iu+iHDN89hecvyO7wHrI4R1V0TXjxOHvX3nLJN1sfh0CWG6CHZ0VlrSmK/cwg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-types": "0.9.3", + "@firebase/util": "1.11.0" + } + }, + "node_modules/@firebase/firestore": { + "version": "4.7.10", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.7.10.tgz", + "integrity": "sha512-6nKsyo2U+jYSCcSE5sjMdDNA23DMUvYPUvsYGg09CNvcTO8GGKsPs7SpOhspsB91mbacq+u627CDAx3FUhPSSQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.13", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.11.0", + "@firebase/webchannel-wrapper": "1.0.3", + "@grpc/grpc-js": "~1.9.0", + "@grpc/proto-loader": "^0.7.8", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/firestore-compat": { + "version": "0.3.45", + "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.45.tgz", + "integrity": "sha512-uRvi7AYPmsDl7UZwPyV7jgDGYusEZ2+U2g7MndbQHKIA8fNHpYC6QrzMs58+/IjX+kF/lkUn67Vrr0AkVjlY+Q==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.13", + "@firebase/firestore": "4.7.10", + "@firebase/firestore-types": "3.0.3", + "@firebase/util": "1.11.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/firestore-types": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-3.0.3.tgz", + "integrity": "sha512-hD2jGdiWRxB/eZWF89xcK9gF8wvENDJkzpVFb4aGkzfEaKxVRD1kjz1t1Wj8VZEp2LCB53Yx1zD8mrhQu87R6Q==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/functions": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.12.3.tgz", + "integrity": "sha512-Wv7JZMUkKLb1goOWRtsu3t7m97uK6XQvjQLPvn8rncY91+VgdU72crqnaYCDI/ophNuBEmuK8mn0/pAnjUeA6A==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.13", + "@firebase/messaging-interop-types": "0.2.3", + "@firebase/util": "1.11.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/functions-compat": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.20.tgz", + "integrity": "sha512-iIudmYDAML6n3c7uXO2YTlzra2/J6lnMzmJTXNthvrKVMgNMaseNoQP1wKfchK84hMuSF8EkM4AvufwbJ+Juew==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.13", + "@firebase/functions": "0.12.3", + "@firebase/functions-types": "0.6.3", + "@firebase/util": "1.11.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/functions-types": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.3.tgz", + "integrity": "sha512-EZoDKQLUHFKNx6VLipQwrSMh01A1SaL3Wg6Hpi//x6/fJ6Ee4hrAeswK99I5Ht8roiniKHw4iO0B1Oxj5I4plg==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/installations": { + "version": "0.6.13", + "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.13.tgz", + "integrity": "sha512-6ZpkUiaygPFwgVneYxuuOuHnSPnTA4KefLEaw/sKk/rNYgC7X6twaGfYb0sYLpbi9xV4i5jXsqZ3WO+yaguNgg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.13", + "@firebase/util": "1.11.0", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/installations-compat": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.13.tgz", + "integrity": "sha512-f/o6MqCI7LD/ulY9gvgkv6w5k6diaReD8BFHd/y/fEdpsXmFWYS/g28GXCB72bRVBOgPpkOUNl+VsMvDwlRKmw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.13", + "@firebase/installations": "0.6.13", + "@firebase/installations-types": "0.5.3", + "@firebase/util": "1.11.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/installations-types": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.3.tgz", + "integrity": "sha512-2FJI7gkLqIE0iYsNQ1P751lO3hER+Umykel+TkLwHj6plzWVxqvfclPUZhcKFVQObqloEBTmpi2Ozn7EkCABAA==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/logger": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.4.tgz", + "integrity": "sha512-mH0PEh1zoXGnaR8gD1DeGeNZtWFKbnz9hDO91dIml3iou1gpOnLqXQ2dJfB71dj6dpmUjcQ6phY3ZZJbjErr9g==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/messaging": { + "version": "0.12.17", + "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.17.tgz", + "integrity": "sha512-W3CnGhTm6Nx8XGb6E5/+jZTuxX/EK8Vur4QXvO1DwZta/t0xqWMRgO9vNsZFMYBqFV4o3j4F9qK/iddGYwWS6g==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.13", + "@firebase/installations": "0.6.13", + "@firebase/messaging-interop-types": "0.2.3", + "@firebase/util": "1.11.0", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/messaging-compat": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.17.tgz", + "integrity": "sha512-5Q+9IG7FuedusdWHVQRjpA3OVD9KUWp/IPegcv0s5qSqRLBjib7FlAeWxN+VL0Ew43tuPJBY2HKhEecuizmO1Q==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.13", + "@firebase/messaging": "0.12.17", + "@firebase/util": "1.11.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/messaging-interop-types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.3.tgz", + "integrity": "sha512-xfzFaJpzcmtDjycpDeCUj0Ge10ATFi/VHVIvEEjDNc3hodVBQADZ7BWQU7CuFpjSHE+eLuBI13z5F/9xOoGX8Q==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/performance": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.7.2.tgz", + "integrity": "sha512-DXLLp0R0jdxH/yTmv+WTkOzsLl8YYecXh4lGZE0dzqC0IV8k+AxpLSSWvOTCkAETze8yEU/iF+PtgYVlGjfMMQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.13", + "@firebase/installations": "0.6.13", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.11.0", + "tslib": "^2.1.0", + "web-vitals": "^4.2.4" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/performance-compat": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.15.tgz", + "integrity": "sha512-wUxsw7hGBEMN6XfvYQqwPIQp5LcJXawWM5tmYp6L7ClCoTQuEiCKHWWVurJgN8Q1YHzoHVgjNfPQAOVu29iMVg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.13", + "@firebase/logger": "0.4.4", + "@firebase/performance": "0.7.2", + "@firebase/performance-types": "0.2.3", + "@firebase/util": "1.11.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/performance-types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.3.tgz", + "integrity": "sha512-IgkyTz6QZVPAq8GSkLYJvwSLr3LS9+V6vNPQr0x4YozZJiLF5jYixj0amDtATf1X0EtYHqoPO48a9ija8GocxQ==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/remote-config": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.6.0.tgz", + "integrity": "sha512-Yrk4l5+6FJLPHC6irNHMzgTtJ3NfHXlAXVChCBdNFtgmzyGmufNs/sr8oA0auEfIJ5VpXCaThRh3P4OdQxiAlQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.13", + "@firebase/installations": "0.6.13", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.11.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/remote-config-compat": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.13.tgz", + "integrity": "sha512-UmHoO7TxAEJPIZf8e1Hy6CeFGMeyjqSCpgoBkQZYXFI2JHhzxIyDpr8jVKJJN1dmAePKZ5EX7dC13CmcdTOl7Q==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.13", + "@firebase/logger": "0.4.4", + "@firebase/remote-config": "0.6.0", + "@firebase/remote-config-types": "0.4.0", + "@firebase/util": "1.11.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/remote-config-types": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.4.0.tgz", + "integrity": "sha512-7p3mRE/ldCNYt8fmWMQ/MSGRmXYlJ15Rvs9Rk17t8p0WwZDbeK7eRmoI1tvCPaDzn9Oqh+yD6Lw+sGLsLg4kKg==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/storage": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.13.7.tgz", + "integrity": "sha512-FkRyc24rK+Y6EaQ1tYFm3TevBnnfSNA0VyTfew2hrYyL/aYfatBg7HOgktUdB4kWMHNA9VoTotzZTGoLuK92wg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.13", + "@firebase/util": "1.11.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/storage-compat": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.17.tgz", + "integrity": "sha512-CBlODWEZ5b6MJWVh21VZioxwxNwVfPA9CAdsk+ZgVocJQQbE2oDW1XJoRcgthRY1HOitgbn4cVrM+NlQtuUYhw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.13", + "@firebase/storage": "0.13.7", + "@firebase/storage-types": "0.8.3", + "@firebase/util": "1.11.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/storage-types": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.3.tgz", + "integrity": "sha512-+Muk7g9uwngTpd8xn9OdF/D48uiQ7I1Fae7ULsWPuKoCH3HU7bfFPhxtJYzyhjdniowhuDpQcfPmuNRAqZEfvg==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/util": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.11.0.tgz", + "integrity": "sha512-PzSrhIr++KI6y4P6C/IdgBNMkEx0Ex6554/cYd0Hm+ovyFSJtJXqb/3OSIdnBoa2cpwZT1/GW56EmRc5qEc5fQ==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/vertexai": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@firebase/vertexai/-/vertexai-1.2.1.tgz", + "integrity": "sha512-cukZ5ne2RsOWB4PB1EO6nTXgOLxPMKDJfEn+XnSV5ZKWM0ID5o0DvbyS59XihFaBzmy2SwJldP5ap7/xUnW4jA==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/component": "0.6.13", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.11.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/webchannel-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-1.0.3.tgz", + "integrity": "sha512-2xCRM9q9FlzGZCdgDMJwc0gyUkWFtkosy7Xxr6sFgQwn+wMNIWd7xIvYNauU1r64B5L5rsGKy/n9TKJ0aAFeqQ==", + "license": "Apache-2.0" + }, + "node_modules/@grpc/grpc-js": { + "version": "1.9.15", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.15.tgz", + "integrity": "sha512-nqE7Hc0AzI+euzUwDAy0aY5hCp10r734gMGRdU+qOPX0XSceI2ULrcXB5U2xSc5VkWwalCj4M7GzCAygZl2KoQ==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/proto-loader": "^0.7.8", + "@types/node": ">=12.12.47" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.7.13", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz", + "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==", + "license": "Apache-2.0", + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.5", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", @@ -4299,6 +4976,70 @@ "node": ">=12.11.0" } }, + "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==", + "license": "BSD-3-Clause" + }, + "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==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" + }, + "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==", + "license": "BSD-3-Clause", + "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==", + "license": "BSD-3-Clause" + }, + "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==", + "license": "BSD-3-Clause" + }, + "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==", + "license": "BSD-3-Clause" + }, + "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==", + "license": "BSD-3-Clause" + }, + "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==", + "license": "BSD-3-Clause" + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.26.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.26.0.tgz", @@ -4543,7 +5284,6 @@ "version": "19.0.6", "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-19.0.6.tgz", "integrity": "sha512-HicclmbW/+mlljU7a4PzbyIWG+7tognoL5LsgMFJQUDzJXHNjRt1riL0vk57o8Pcprnz9FheeWZXO1KRhXkQuw==", - "dev": true, "dependencies": { "@angular-devkit/core": "19.0.6", "@angular-devkit/schematics": "19.0.6", @@ -5293,7 +6033,6 @@ "version": "8.17.1", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dev": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -5309,7 +6048,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", - "dev": true, "dependencies": { "ajv": "^8.0.0" }, @@ -6160,7 +6898,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "dev": true, + "devOptional": true, "dependencies": { "readdirp": "^4.0.1" }, @@ -6242,7 +6980,6 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -6255,14 +6992,12 @@ "node_modules/cliui/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/cliui/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "engines": { "node": ">=8" } @@ -6271,7 +7006,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -6285,7 +7019,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -7447,7 +8180,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, "engines": { "node": ">=6" } @@ -7471,26 +8203,27 @@ } }, "node_modules/eslint": { - "version": "9.17.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.17.0.tgz", - "integrity": "sha512-evtlNcpJg+cZLcnVKwsai8fExnqjGPicK7gnUtlNuzu+Fv9bI0aLpND5T44VLQtoMEnI57LoXO9XAkIXwohKrA==", + "version": "9.14.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.14.0.tgz", + "integrity": "sha512-c2FHsVBr87lnUtjP4Yhvk4yEhKrQavGafRA/Se1ouse8PfbfC/Qh9Mxa00yWsZRlqeUB9raXip0aiiUZkgnr9g==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.19.0", - "@eslint/core": "^0.9.0", - "@eslint/eslintrc": "^3.2.0", - "@eslint/js": "9.17.0", - "@eslint/plugin-kit": "^0.2.3", + "@eslint/config-array": "^0.18.0", + "@eslint/core": "^0.7.0", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "9.14.0", + "@eslint/plugin-kit": "^0.2.0", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.1", + "@humanwhocodes/retry": "^0.4.0", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", - "cross-spawn": "^7.0.6", + "cross-spawn": "^7.0.2", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.2.0", @@ -7509,7 +8242,8 @@ "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.3" + "optionator": "^0.9.3", + "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" @@ -8065,8 +8799,7 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-diff": { "version": "1.3.0", @@ -8115,8 +8848,7 @@ "node_modules/fast-uri": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz", - "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==", - "dev": true + "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==" }, "node_modules/fastq": { "version": "1.18.0", @@ -8130,7 +8862,6 @@ "version": "0.11.4", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "dev": true, "dependencies": { "websocket-driver": ">=0.5.1" }, @@ -8238,6 +8969,42 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/firebase": { + "version": "11.6.0", + "resolved": "https://registry.npmjs.org/firebase/-/firebase-11.6.0.tgz", + "integrity": "sha512-Xqm6j6zszIEmI5nW1MPR8yTafoRTSrW3mWG9Lk9elCJtQDQSiTEkKZiNtUm9y6XfOPl8xoF1TNpxZe8HjgA0Og==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/analytics": "0.10.12", + "@firebase/analytics-compat": "0.2.18", + "@firebase/app": "0.11.4", + "@firebase/app-check": "0.8.13", + "@firebase/app-check-compat": "0.3.20", + "@firebase/app-compat": "0.2.53", + "@firebase/app-types": "0.9.3", + "@firebase/auth": "1.10.0", + "@firebase/auth-compat": "0.5.20", + "@firebase/data-connect": "0.3.3", + "@firebase/database": "1.0.14", + "@firebase/database-compat": "2.0.5", + "@firebase/firestore": "4.7.10", + "@firebase/firestore-compat": "0.3.45", + "@firebase/functions": "0.12.3", + "@firebase/functions-compat": "0.3.20", + "@firebase/installations": "0.6.13", + "@firebase/installations-compat": "0.2.13", + "@firebase/messaging": "0.12.17", + "@firebase/messaging-compat": "0.2.17", + "@firebase/performance": "0.7.2", + "@firebase/performance-compat": "0.2.15", + "@firebase/remote-config": "0.6.0", + "@firebase/remote-config-compat": "0.2.13", + "@firebase/storage": "0.13.7", + "@firebase/storage-compat": "0.3.17", + "@firebase/util": "1.11.0", + "@firebase/vertexai": "1.2.1" + } + }, "node_modules/flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", @@ -8466,7 +9233,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -8867,8 +9633,7 @@ "node_modules/http-parser-js": { "version": "0.5.8", "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", - "dev": true + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" }, "node_modules/http-proxy": { "version": "1.18.1", @@ -8967,6 +9732,12 @@ "postcss": "^8.1.0" } }, + "node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", + "license": "ISC" + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -9888,8 +10659,7 @@ "node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -9912,8 +10682,7 @@ "node_modules/jsonc-parser": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", - "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", - "dev": true + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==" }, "node_modules/jsonfile": { "version": "4.0.0", @@ -10542,6 +11311,12 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "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==", + "license": "MIT" + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -10706,6 +11481,12 @@ "node": ">=8.0" } }, + "node_modules/long": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.1.tgz", + "integrity": "sha512-ka87Jz3gcx/I7Hal94xaN2tZEOPoUOEVftkQqZx2EeQRN7LGdfLlI3FvZ+7WDplm+vK2Urx9ULrvSowtdCieng==", + "license": "Apache-2.0" + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -10719,7 +11500,6 @@ "version": "0.30.12", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz", "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==", - "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } @@ -12280,7 +13060,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", - "dev": true, "engines": { "node": ">=12" }, @@ -12595,10 +13374,11 @@ } }, "node_modules/prettier": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz", - "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.0.tgz", + "integrity": "sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==", "dev": true, + "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" }, @@ -13145,9 +13925,10 @@ "integrity": "sha512-jK3Et9UzwzTsd6tzl2RmwrVY/b8raJ3QZLzoDACj+oTJ0oX7L9Hy+XnVwgo4QVKlKpnP/Ur13SXV/pVh4LzaDw==" }, "node_modules/primeng": { - "version": "19.0.5", - "resolved": "https://registry.npmjs.org/primeng/-/primeng-19.0.5.tgz", - "integrity": "sha512-3IMWTUykIyZpT7d+pD7KzB+68GcY8/xOV10V1Tf09cPkPuwXlFP+NAVGIqAOXBzkw+RmJksSBoa13bpS/fMo1g==", + "version": "19.0.10", + "resolved": "https://registry.npmjs.org/primeng/-/primeng-19.0.10.tgz", + "integrity": "sha512-pVvywU6WoDtS6cwyGm5wyHp/RPqsqtTL3Z6eNgwsP7wMRpNYxVQB2W5ewF64byP8bqFqRQMWY2ZPj0lDeTQ/sA==", + "license": "SEE LICENSE IN LICENSE.md", "dependencies": { "@primeuix/styled": "^0.3.2", "@primeuix/utils": "^0.3.2", @@ -13198,6 +13979,30 @@ "node": ">=10" } }, + "node_modules/protobufjs": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", + "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "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/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -13342,7 +14147,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", - "dev": true, + "devOptional": true, "engines": { "node": ">= 14.16.0" }, @@ -13487,7 +14292,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -13496,7 +14300,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -13713,6 +14516,16 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rxfire": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/rxfire/-/rxfire-6.1.0.tgz", + "integrity": "sha512-NezdjeY32VZcCuGO0bbb8H8seBsJSCaWdUwGsHNzUcAOHR0VGpzgPtzjuuLXr8R/iemkqSzbx/ioS7VwV43ynA==", + "license": "Apache-2.0", + "peerDependencies": { + "firebase": "^9.0.0 || ^10.0.0 || ^11.0.0", + "rxjs": "^6.0.0 || ^7.0.0" + } + }, "node_modules/rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", @@ -14471,7 +15284,6 @@ "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, "engines": { "node": ">= 8" } @@ -14964,9 +15776,10 @@ } }, "node_modules/tailwindcss-primeui": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/tailwindcss-primeui/-/tailwindcss-primeui-0.3.4.tgz", - "integrity": "sha512-5+Qfoe5Kpq2Iwrd6umBUb3rQH6b7+pL4jxJUId0Su5agUM6TwCyH5Pyl9R0y3QQB3IRuTxBNmeS11B41f+30zw==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/tailwindcss-primeui/-/tailwindcss-primeui-0.5.1.tgz", + "integrity": "sha512-zNqp62N4c+pwBVkVJd8ByvujepVKAMxZBdYy5MzIDi/Zb2p8wTGo4RrQaqLQazm3teOWVmttzZYPH/GlOB3lgw==", + "license": "MIT", "peerDependencies": { "tailwindcss": ">=3.1.0" } @@ -15193,6 +16006,13 @@ } } }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, + "license": "MIT" + }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", @@ -15330,9 +16150,10 @@ } }, "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", + "license": "0BSD" }, "node_modules/tsx": { "version": "4.19.2", @@ -16654,6 +17475,12 @@ "node": ">= 14" } }, + "node_modules/web-vitals": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-4.2.4.tgz", + "integrity": "sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==", + "license": "Apache-2.0" + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", @@ -16999,7 +17826,6 @@ "version": "0.7.4", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "dev": true, "dependencies": { "http-parser-js": ">=0.5.1", "safe-buffer": ">=5.1.0", @@ -17013,7 +17839,6 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "dev": true, "engines": { "node": ">=0.8.0" } @@ -17257,7 +18082,6 @@ "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, "engines": { "node": ">=10" } @@ -17283,7 +18107,6 @@ "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -17301,7 +18124,6 @@ "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, "engines": { "node": ">=12" } @@ -17309,14 +18131,12 @@ "node_modules/yargs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/yargs/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "engines": { "node": ">=8" } @@ -17325,7 +18145,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", diff --git a/package.json b/package.json index 89a019195..ae84218ee 100644 --- a/package.json +++ b/package.json @@ -11,44 +11,45 @@ }, "private": true, "dependencies": { - "@angular/animations": "^19.0.0", - "@angular/common": "^19.0.0", - "@angular/compiler": "^19.0.0", - "@angular/core": "^19.0.0", - "@angular/forms": "^19.0.0", - "@angular/platform-browser": "^19.0.0", - "@angular/platform-browser-dynamic": "^19.0.0", - "@angular/router": "^19.0.0", + "@angular/animations": "19.0.5", + "@angular/common": "19.0.5", + "@angular/compiler": "19.0.5", + "@angular/core": "19.0.5", + "@angular/fire": "^19.0.0", + "@angular/forms": "19.0.5", + "@angular/platform-browser": "19.0.5", + "@angular/platform-browser-dynamic": "19.0.5", + "@angular/router": "19.0.5", "@primeng/themes": "^19.0.5", "chart.js": "4.4.2", "primeclt": "^0.1.5", "primeicons": "^7.0.0", "primeng": "^19.0.8", "rxjs": "~7.8.0", - "tailwindcss-primeui": "^0.5.1", - "tslib": "^2.3.0", + "tailwindcss-primeui": "0.5.1", + "tslib": "2.3.0", "zone.js": "~0.15.0" }, "devDependencies": { - "@angular-devkit/build-angular": "^19.0.6", - "@angular/cli": "^19.0.6", - "@angular/compiler-cli": "^19.0.0", + "@angular-devkit/build-angular": "19.0.6", + "@angular/cli": "19.0.6", + "@angular/compiler-cli": "19.0.0", "@types/jasmine": "~5.1.0", - "autoprefixer": "^10.4.20", - "eslint": "^9.14.0", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-import": "^2.31.0", - "eslint-plugin-prefer-arrow": "^1.2.3", - "eslint-plugin-prettier": "^4.2.1", + "autoprefixer": "10.4.20", + "eslint": "9.14.0", + "eslint-config-prettier": "9.1.0", + "eslint-plugin-import": "2.31.0", + "eslint-plugin-prefer-arrow": "1.2.3", + "eslint-plugin-prettier": "4.2.1", "jasmine-core": "~5.4.0", "karma": "~6.4.0", "karma-chrome-launcher": "~3.2.0", "karma-coverage": "~2.2.0", "karma-jasmine": "~5.1.0", "karma-jasmine-html-reporter": "~2.1.0", - "postcss": "^8.4.49", - "prettier": "^3.0.0", - "tailwindcss": "^3.4.17", + "postcss": "8.4.49", + "prettier": "3.0.0", + "tailwindcss": "3.4.17", "typescript": "~5.6.2" } } diff --git a/src/app.config.ts b/src/app.config.ts index c66888171..0917ec9ac 100644 --- a/src/app.config.ts +++ b/src/app.config.ts @@ -5,12 +5,23 @@ import { provideRouter, withEnabledBlockingInitialNavigation, withInMemoryScroll import Aura from '@primeng/themes/aura'; import { providePrimeNG } from 'primeng/config'; import { appRoutes } from './app.routes'; +import { initializeApp, provideFirebaseApp } from '@angular/fire/app'; +import { provideFirestore, getFirestore } from '@angular/fire/firestore'; export const appConfig: ApplicationConfig = { providers: [ provideRouter(appRoutes, withInMemoryScrolling({ anchorScrolling: 'enabled', scrollPositionRestoration: 'enabled' }), withEnabledBlockingInitialNavigation()), provideHttpClient(withFetch()), provideAnimationsAsync(), - providePrimeNG({ theme: { preset: Aura, options: { darkModeSelector: '.app-dark' } } }) + providePrimeNG({ theme: { preset: Aura, options: { darkModeSelector: '.app-dark' } } }), + provideFirebaseApp(() => initializeApp({ + apiKey: "AIzaSyCp1ieMWDtGU2PhOBApy3p5O6gxgBTzcIo", + authDomain: "celebration-ledger.firebaseapp.com", + projectId: "celebration-ledger", + storageBucket: "celebration-ledger.firebasestorage.app", + messagingSenderId: "487837077137", + appId: "1:487837077137:web:8cd470e6bd0a3832da7930" + })), + provideFirestore(() => getFirestore()), ] }; diff --git a/src/app.routes.ts b/src/app.routes.ts index 96e5ba31e..fd8d09aba 100644 --- a/src/app.routes.ts +++ b/src/app.routes.ts @@ -4,6 +4,7 @@ import { Dashboard } from './app/pages/dashboard/dashboard'; import { Documentation } from './app/pages/documentation/documentation'; import { Landing } from './app/pages/landing/landing'; import { Notfound } from './app/pages/notfound/notfound'; +import { LedgerComponent } from './app/pages/ledger/ledger.component'; export const appRoutes: Routes = [ { @@ -13,6 +14,7 @@ export const appRoutes: Routes = [ { path: '', component: Dashboard }, { path: 'uikit', loadChildren: () => import('./app/pages/uikit/uikit.routes') }, { path: 'documentation', component: Documentation }, + { path: 'ledger', component: LedgerComponent }, { path: 'pages', loadChildren: () => import('./app/pages/pages.routes') } ] }, diff --git a/src/app/layout/component/app.menu.ts b/src/app/layout/component/app.menu.ts index ae77ce77a..9295a0e3c 100644 --- a/src/app/layout/component/app.menu.ts +++ b/src/app/layout/component/app.menu.ts @@ -24,6 +24,10 @@ export class AppMenu { label: 'Home', items: [{ label: 'Dashboard', icon: 'pi pi-fw pi-home', routerLink: ['/'] }] }, + { + label: 'Financials', + items: [{ label: 'Ledger', icon: 'pi pi-fw pi-home', routerLink: ['/ledger'] }] + }, { label: 'UI Components', items: [ diff --git a/src/app/pages/crud/crud.ts b/src/app/pages/crud/crud.ts index 0a14156f1..720142004 100644 --- a/src/app/pages/crud/crud.ts +++ b/src/app/pages/crud/crud.ts @@ -19,6 +19,7 @@ import { InputIconModule } from 'primeng/inputicon'; import { IconFieldModule } from 'primeng/iconfield'; import { ConfirmDialogModule } from 'primeng/confirmdialog'; import { Product, ProductService } from '../service/product.service'; +import { LedgerComponent } from '../ledger/ledger.component'; interface Column { field: string; @@ -52,7 +53,7 @@ interface ExportColumn { TagModule, InputIconModule, IconFieldModule, - ConfirmDialogModule + ConfirmDialogModule, LedgerComponent ], template: ` @@ -66,6 +67,7 @@ interface ExportColumn { + + + + + + + + + + + + + + +
+
+ + + Name is required. +
+
+ + + Province is required. +
+ +
+ +
+ + +
+
+ + +
+
+
+ +
+ + +
+
+ + +
+
+ + + +
+
+ + + + + +
+ + + + FOC + Province + Date + Adults + Children + Tithes + Offering + + + + + + {{ stat.location }} + {{ stat.province }} + {{ stat.date }} + {{ stat.attendanceAdults }} + {{ stat.attendanceChildren }} + {{ stat.tithe | currency }} + {{ stat.offeringSeed | currency }} + + + + + + \ No newline at end of file diff --git a/src/app/pages/ledger/ledger.component.scss b/src/app/pages/ledger/ledger.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/pages/ledger/ledger.component.spec.ts b/src/app/pages/ledger/ledger.component.spec.ts new file mode 100644 index 000000000..588821473 --- /dev/null +++ b/src/app/pages/ledger/ledger.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { LedgerComponent } from './ledger.component'; + +describe('LedgerComponent', () => { + let component: LedgerComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [LedgerComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(LedgerComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/ledger/ledger.component.ts b/src/app/pages/ledger/ledger.component.ts new file mode 100644 index 000000000..8c18d745a --- /dev/null +++ b/src/app/pages/ledger/ledger.component.ts @@ -0,0 +1,139 @@ +import { Component } from '@angular/core'; +import { GetDataService, Ledger } from '../service/ledger.service'; +import { CommonModule } from '@angular/common'; +import { FormControl, FormGroup, FormsModule } from '@angular/forms'; +import { ButtonModule } from 'primeng/button'; +import { ConfirmDialogModule } from 'primeng/confirmdialog'; +import { DialogModule } from 'primeng/dialog'; +import { IconFieldModule } from 'primeng/iconfield'; +import { InputIconModule } from 'primeng/inputicon'; +import { InputNumberModule } from 'primeng/inputnumber'; +import { InputTextModule } from 'primeng/inputtext'; +import { RadioButtonModule } from 'primeng/radiobutton'; +import { RatingModule } from 'primeng/rating'; +import { RippleModule } from 'primeng/ripple'; +import { SelectModule } from 'primeng/select'; +import { TableModule } from 'primeng/table'; +import { TagModule } from 'primeng/tag'; +import { TextareaModule } from 'primeng/textarea'; +import { ToastModule } from 'primeng/toast'; +import { ToolbarModule } from 'primeng/toolbar'; +import { collectionGroup, getDocs } from '@angular/fire/firestore'; +@Component({ + selector: 'app-ledger', + standalone: true, + imports: [ + CommonModule, + TableModule, + FormsModule, + ButtonModule, + RippleModule, + ToastModule, + ToolbarModule, + RatingModule, + InputTextModule, + TextareaModule, + SelectModule, + RadioButtonModule, + InputNumberModule, + DialogModule, + TagModule, + InputIconModule, + IconFieldModule, + ConfirmDialogModule + ], + providers: [GetDataService], + templateUrl: './ledger.component.html', + styleUrl: './ledger.component.scss' +}) +export class LedgerComponent { + stats!: any[]; + stat!: Ledger; + submitted: boolean = false; + statDialog: boolean=false; + givingForm!: FormGroup<{ attendanceChildren: FormControl; attendanceAdults: FormControl; tithe: FormControl; offeringSeed: FormControl; firstFruit: FormControl; missionsMinistry: FormControl; compassionSeed: FormControl; cafeOffering: FormControl; crossCulture: FormControl; businessTithe: FormControl; projectRelocate: FormControl; buildingFund: FormControl; youthOffering: FormControl; leviteTithe: FormControl; champions: FormControl; prisonsOfCompassion: FormControl; musicOfCompassion: FormControl; other: FormControl; }>; +focId: any; + constructor( private getData: GetDataService ) { } + hideDialog() { + this.statDialog = false; + this.submitted = false; +} + async saveStat() { + console.log(this.stat); + this.stat.location = this.focId + let docId = this.createCollectionId(new Date()) + this.stat.date = docId + try { await this.getData.submitReport(this.stat).then((data) => { + console.log(data); + + }) + this.getAllData() + } + catch (error) { + console.error("Error adding document: ", error); + } + + // try { + // await this.getData.addDataToCol(this.stat, `stats/${docId}`) + // // await this.getData.addDataToCol(this.stat, `offering/${docId}/logs/${this.focId}`) + // console.log('Data sent'); + + // } + // catch (error) { + // console.error("Error adding document: ", error); + // } + + +} +createCollectionId(date: Date): string { + const day = String(date.getDate()).padStart(2, '0'); // Ensure two digits + const month = String(date.getMonth() + 1).padStart(2, '0'); // Months are 0-based + const year = date.getFullYear(); + return `${day}-${month}-${year}`; // 23-march-2025 +} + openNew() { + this.stat = {} as Ledger; + this.submitted = false; + this.statDialog = true; + } + async ngOnInit() { + this.getData.getAll('offering').subscribe((data) => { + console.log(data); + // this.stats = data + }); + this.getAllData() + } + + async getAllData(){ + await this.getData.getAllReports().then((data) => { + console.log(data); + + this.stats=data + }); + } + + + + initForm() { + this.givingForm = new FormGroup({ + attendanceChildren: new FormControl('', ), + attendanceAdults: new FormControl('', ), + tithe: new FormControl('', ), + offeringSeed: new FormControl('', ), + firstFruit: new FormControl("", ), + missionsMinistry: new FormControl('', ), + compassionSeed: new FormControl('', ), + cafeOffering: new FormControl('', ), + crossCulture: new FormControl('', ), + businessTithe: new FormControl('', ), + projectRelocate: new FormControl('', ), + buildingFund: new FormControl('', ), + youthOffering: new FormControl('', ), + leviteTithe: new FormControl('', ), + champions: new FormControl('', ), + prisonsOfCompassion: new FormControl('', ), + musicOfCompassion: new FormControl('', ), + other: new FormControl('', ), + }); + } +} diff --git a/src/app/pages/service/ledger.service.ts b/src/app/pages/service/ledger.service.ts new file mode 100644 index 000000000..4158f4a23 --- /dev/null +++ b/src/app/pages/service/ledger.service.ts @@ -0,0 +1,137 @@ +import { HttpClient } from '@angular/common/http'; +import { inject, Injectable } from '@angular/core'; +import { addDoc, collection, collectionData, collectionGroup, doc, docData, DocumentReference, Firestore, getDocs, setDoc } from '@angular/fire/firestore'; +import { Observable } from 'rxjs'; + +interface InventoryStatus { + label: string; + value: string; +} +export interface Ledger { + attendanceChildren: number; + attendanceAdults: number; + tithe: number; + location: string; + province: string; + offeringSeed: number; + firstFruit: number; + missionsMinistry: string; + compassionSeed: number; + cafeOffering: number; + crossCulture: number; + businessTithe: number; + projectRelocate: string; + buildingFund: number; + youthOffering: number; + leviteTithe: number; + champions: number; + prisonsOfCompassion: number; + musicOfCompassion: number; + other: number; + focId: string; + date: string; +} +export interface Product { + id?: string; + code?: string; + name?: string; + description?: string; + price?: number; + quantity?: number; + inventoryStatus?: string; + category?: string; + image?: string; + rating?: number; +} + +@Injectable() + +export class GetDataService { + + item$!: Observable; + firestore = inject(Firestore); + + constructor(private http: HttpClient) {} + async submitReport(data: any) { + try { + // Reference to the 'provinces' collection + const provinceRef = doc(this.firestore, `provinces/${data.province}`); + + // Reference to the 'locations' subcollection within the province document + const locationRef = doc(provinceRef, `locations/${data.location}`); + + // Reference to the 'reports' subcollection within the location document + const reportsCollection = collection(locationRef, 'reports'); + + // Submit the report to the 'reports' subcollection + const reportDoc = { + date: data.date, + attendanceChildren: data.attendanceChildren, + attendanceAdults: data.attendanceAdults, + tithe: data.tithe, + location: data.location, + province: data.province, + offeringSeed: data.offeringSeed, + }; + await addDoc(reportsCollection, reportDoc); + + console.log('Report submitted successfully!'); + } catch (error) { + console.error('Error submitting report:', error); + } + } + async getAllReports() { + try { + // Use the `collectionGroup` query to fetch all documents from subcollections named 'reports' + const reportsSnapshot = await getDocs(collectionGroup(this.firestore, 'reports')); + + // Map through each document to extract data + const allReports = reportsSnapshot.docs.map(doc => ({ + id: doc.id, // The document ID + ...doc.data() // The report data + })); + + console.log('All Reports:', allReports); + return allReports; + } catch (error) { + console.error('Error retrieving reports:', error); + throw error; // Optionally rethrow the error for higher-level handling + } + } + getAll(str: string): Observable { + + const offeringCollection = collection(this.firestore, str); + return collectionData(offeringCollection); + } + + getDoc(str: string): any { + const oDoc = doc(this.firestore, str); + return docData(oDoc); + } + + async addDataToDoc(data: any, collectionPath: string) { + if (!data) return; + console.log("", data); + + const offeringCollection = collection(this.firestore, collectionPath ); + + await addDoc(offeringCollection, data ).then((documentReference: DocumentReference) => { + // the documentReference provides access to the newly created document + console.log(documentReference); + + }); + } + + async addDataToCol(data: any, collectionPath: string) { + try{ + if (!data) return; + console.log("", data); + + const offeringDoc = doc(this.firestore, collectionPath ); + + await setDoc(offeringDoc, data ); + }catch(e){ + console.log(e); + } + } + } \ No newline at end of file diff --git a/src/index.html b/src/index.html index d307198f1..696719832 100644 --- a/src/index.html +++ b/src/index.html @@ -2,7 +2,7 @@ - Sakai - PrimeNG + FOC - Ledger From 87a5d62759e3ec2bdfa1a33d71cd1b80a61cc506 Mon Sep 17 00:00:00 2001 From: Tatenda Munenge Date: Thu, 10 Apr 2025 08:44:41 +0200 Subject: [PATCH 2/4] Adds capture date to records form --- src/app/pages/ledger/ledger.component.html | 5 +++++ src/app/pages/service/ledger.service.ts | 2 ++ 2 files changed, 7 insertions(+) diff --git a/src/app/pages/ledger/ledger.component.html b/src/app/pages/ledger/ledger.component.html index 07f7030a1..ad61f7016 100644 --- a/src/app/pages/ledger/ledger.component.html +++ b/src/app/pages/ledger/ledger.component.html @@ -18,6 +18,11 @@ Name is required. +
+ + + Date is required. +
diff --git a/src/app/pages/service/ledger.service.ts b/src/app/pages/service/ledger.service.ts index 4158f4a23..78edbc46c 100644 --- a/src/app/pages/service/ledger.service.ts +++ b/src/app/pages/service/ledger.service.ts @@ -30,6 +30,7 @@ export interface Ledger { other: number; focId: string; date: string; + captureDate: string; } export interface Product { id?: string; @@ -66,6 +67,7 @@ export class GetDataService { // Submit the report to the 'reports' subcollection const reportDoc = { date: data.date, + captureDate: data.captureDate, attendanceChildren: data.attendanceChildren, attendanceAdults: data.attendanceAdults, tithe: data.tithe, From 63735bef7f3c486205e988606be856430f86a9ab Mon Sep 17 00:00:00 2001 From: Tatenda Munenge Date: Sat, 12 Apr 2025 07:55:12 +0200 Subject: [PATCH 3/4] Adds new Ap pages --- src/app.routes.ts | 4 +++ src/app/layout/component/app.menu.ts | 6 +++- src/app/pages/foc/foc.component.html | 1 + src/app/pages/foc/foc.component.scss | 0 src/app/pages/foc/foc.component.spec.ts | 23 ++++++++++++++ src/app/pages/foc/foc.component.ts | 11 +++++++ .../pages/provinces/provinces.component.html | 31 +++++++++++++++++++ .../pages/provinces/provinces.component.scss | 0 .../provinces/provinces.component.spec.ts | 23 ++++++++++++++ .../pages/provinces/provinces.component.ts | 28 +++++++++++++++++ 10 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 src/app/pages/foc/foc.component.html create mode 100644 src/app/pages/foc/foc.component.scss create mode 100644 src/app/pages/foc/foc.component.spec.ts create mode 100644 src/app/pages/foc/foc.component.ts create mode 100644 src/app/pages/provinces/provinces.component.html create mode 100644 src/app/pages/provinces/provinces.component.scss create mode 100644 src/app/pages/provinces/provinces.component.spec.ts create mode 100644 src/app/pages/provinces/provinces.component.ts diff --git a/src/app.routes.ts b/src/app.routes.ts index fd8d09aba..da4744086 100644 --- a/src/app.routes.ts +++ b/src/app.routes.ts @@ -5,6 +5,8 @@ import { Documentation } from './app/pages/documentation/documentation'; import { Landing } from './app/pages/landing/landing'; import { Notfound } from './app/pages/notfound/notfound'; import { LedgerComponent } from './app/pages/ledger/ledger.component'; +import { ProvincesComponent } from './app/pages/provinces/provinces.component'; +import { FocComponent } from './app/pages/foc/foc.component'; export const appRoutes: Routes = [ { @@ -15,6 +17,8 @@ export const appRoutes: Routes = [ { path: 'uikit', loadChildren: () => import('./app/pages/uikit/uikit.routes') }, { path: 'documentation', component: Documentation }, { path: 'ledger', component: LedgerComponent }, + { path: 'provinces', component: ProvincesComponent }, + { path: 'foc', component: FocComponent }, { path: 'pages', loadChildren: () => import('./app/pages/pages.routes') } ] }, diff --git a/src/app/layout/component/app.menu.ts b/src/app/layout/component/app.menu.ts index 9295a0e3c..9ea9c7bb6 100644 --- a/src/app/layout/component/app.menu.ts +++ b/src/app/layout/component/app.menu.ts @@ -26,7 +26,11 @@ export class AppMenu { }, { label: 'Financials', - items: [{ label: 'Ledger', icon: 'pi pi-fw pi-home', routerLink: ['/ledger'] }] + items: [ + { label: 'Ledger', icon: 'pi pi-fw pi-home', routerLink: ['/ledger'] }, + { label: 'Provinces', icon: 'pi pi-fw pi-home', routerLink: ['/provinces'] }, + { label: 'FOCs', icon: 'pi pi-fw pi-home', routerLink: ['/foc'] } + ] }, { label: 'UI Components', diff --git a/src/app/pages/foc/foc.component.html b/src/app/pages/foc/foc.component.html new file mode 100644 index 000000000..23ab4c58e --- /dev/null +++ b/src/app/pages/foc/foc.component.html @@ -0,0 +1 @@ +

foc works!

diff --git a/src/app/pages/foc/foc.component.scss b/src/app/pages/foc/foc.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/pages/foc/foc.component.spec.ts b/src/app/pages/foc/foc.component.spec.ts new file mode 100644 index 000000000..8c5674cf4 --- /dev/null +++ b/src/app/pages/foc/foc.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { FocComponent } from './foc.component'; + +describe('FocComponent', () => { + let component: FocComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [FocComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(FocComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/foc/foc.component.ts b/src/app/pages/foc/foc.component.ts new file mode 100644 index 000000000..21f48e50b --- /dev/null +++ b/src/app/pages/foc/foc.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-foc', + imports: [], + templateUrl: './foc.component.html', + styleUrl: './foc.component.scss' +}) +export class FocComponent { + +} diff --git a/src/app/pages/provinces/provinces.component.html b/src/app/pages/provinces/provinces.component.html new file mode 100644 index 000000000..b9dc827ae --- /dev/null +++ b/src/app/pages/provinces/provinces.component.html @@ -0,0 +1,31 @@ + + + + + + + + + + + + + +
+
+ +
+ +
+
+ +
+
+
+
+ + + + + +
\ No newline at end of file diff --git a/src/app/pages/provinces/provinces.component.scss b/src/app/pages/provinces/provinces.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/pages/provinces/provinces.component.spec.ts b/src/app/pages/provinces/provinces.component.spec.ts new file mode 100644 index 000000000..465d2cf01 --- /dev/null +++ b/src/app/pages/provinces/provinces.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ProvincesComponent } from './provinces.component'; + +describe('ProvincesComponent', () => { + let component: ProvincesComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ProvincesComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(ProvincesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/provinces/provinces.component.ts b/src/app/pages/provinces/provinces.component.ts new file mode 100644 index 000000000..c9ed26708 --- /dev/null +++ b/src/app/pages/provinces/provinces.component.ts @@ -0,0 +1,28 @@ +import { Component } from '@angular/core'; +import { ButtonModule } from 'primeng/button'; +import { DialogModule } from 'primeng/dialog'; +import { ToolbarModule } from 'primeng/toolbar'; + +@Component({ + selector: 'app-provinces', + imports: [ + ToolbarModule, + ButtonModule, + DialogModule, + ], + templateUrl: './provinces.component.html', + styleUrl: './provinces.component.scss' +}) +export class ProvincesComponent { + + statDialog: boolean=false; + submitted: boolean = false; + public saveStat() { + + } + + public hideDialog(){ + this.statDialog = false; + this.submitted = false; + } +} From 1c62abafefc44cdfe85e5c3e52f6012804eade77 Mon Sep 17 00:00:00 2001 From: Tatenda Munenge Date: Sat, 12 Apr 2025 09:40:39 +0200 Subject: [PATCH 4/4] adds filtering fui functionality --- src/app/pages/ledger/ledger.component.html | 20 +++++++ src/app/pages/ledger/ledger.component.ts | 27 ++++++++-- src/app/pages/service/ledger.service.ts | 61 +++++++++++++++------- 3 files changed, 86 insertions(+), 22 deletions(-) diff --git a/src/app/pages/ledger/ledger.component.html b/src/app/pages/ledger/ledger.component.html index ad61f7016..8c00b0e10 100644 --- a/src/app/pages/ledger/ledger.component.html +++ b/src/app/pages/ledger/ledger.component.html @@ -1,3 +1,23 @@ +
+
+
Filter Reports
+ +
+
+ + +
+
+ + +
+ +
+
+
+
+
+
diff --git a/src/app/pages/ledger/ledger.component.ts b/src/app/pages/ledger/ledger.component.ts index 8c18d745a..79fb2a1a8 100644 --- a/src/app/pages/ledger/ledger.component.ts +++ b/src/app/pages/ledger/ledger.component.ts @@ -18,6 +18,7 @@ import { TagModule } from 'primeng/tag'; import { TextareaModule } from 'primeng/textarea'; import { ToastModule } from 'primeng/toast'; import { ToolbarModule } from 'primeng/toolbar'; +import { ListboxModule } from 'primeng/listbox'; import { collectionGroup, getDocs } from '@angular/fire/firestore'; @Component({ selector: 'app-ledger', @@ -40,7 +41,8 @@ import { collectionGroup, getDocs } from '@angular/fire/firestore'; TagModule, InputIconModule, IconFieldModule, - ConfirmDialogModule + ConfirmDialogModule, + ListboxModule, ], providers: [GetDataService], templateUrl: './ledger.component.html', @@ -52,12 +54,23 @@ export class LedgerComponent { submitted: boolean = false; statDialog: boolean=false; givingForm!: FormGroup<{ attendanceChildren: FormControl; attendanceAdults: FormControl; tithe: FormControl; offeringSeed: FormControl; firstFruit: FormControl; missionsMinistry: FormControl; compassionSeed: FormControl; cafeOffering: FormControl; crossCulture: FormControl; businessTithe: FormControl; projectRelocate: FormControl; buildingFund: FormControl; youthOffering: FormControl; leviteTithe: FormControl; champions: FormControl; prisonsOfCompassion: FormControl; musicOfCompassion: FormControl; other: FormControl; }>; -focId: any; + focId: any; constructor( private getData: GetDataService ) { } + + + focValues: any[] = [ + { name: 'Marondera', id: 'MaronderaFocId' }, + { name: 'Mahusekwa', id: 'MahusekwaFocId' }, + { name: 'Murehwa', id: 'MurehwaFocId' } +]; + + focValue: any = null; + filterDate: string = ''; + hideDialog() { this.statDialog = false; this.submitted = false; -} + } async saveStat() { console.log(this.stat); this.stat.location = this.focId @@ -112,6 +125,14 @@ createCollectionId(date: Date): string { }); } + async getFilteredData(){ + await this.getData.getFilteredReports(this.focValue, this.filterDate).then((data) => { + console.log(this.focValue); + console.log(this.filterDate); + this.stats=data + }); + } + initForm() { diff --git a/src/app/pages/service/ledger.service.ts b/src/app/pages/service/ledger.service.ts index 78edbc46c..642f28d66 100644 --- a/src/app/pages/service/ledger.service.ts +++ b/src/app/pages/service/ledger.service.ts @@ -1,6 +1,6 @@ import { HttpClient } from '@angular/common/http'; import { inject, Injectable } from '@angular/core'; -import { addDoc, collection, collectionData, collectionGroup, doc, docData, DocumentReference, Firestore, getDocs, setDoc } from '@angular/fire/firestore'; +import { addDoc, collection, collectionData, collectionGroup, doc, docData, DocumentReference, Firestore, getDocs, query, setDoc, where } from '@angular/fire/firestore'; import { Observable } from 'rxjs'; interface InventoryStatus { @@ -82,26 +82,49 @@ export class GetDataService { console.error('Error submitting report:', error); } } - async getAllReports() { - try { - // Use the `collectionGroup` query to fetch all documents from subcollections named 'reports' - const reportsSnapshot = await getDocs(collectionGroup(this.firestore, 'reports')); - - // Map through each document to extract data - const allReports = reportsSnapshot.docs.map(doc => ({ - id: doc.id, // The document ID - ...doc.data() // The report data - })); - - console.log('All Reports:', allReports); - return allReports; - } catch (error) { - console.error('Error retrieving reports:', error); - throw error; // Optionally rethrow the error for higher-level handling - } + async getAllReports() { + try { + // Use the `collectionGroup` query to fetch all documents from subcollections named 'reports' + const reportsSnapshot = await getDocs(collectionGroup(this.firestore, 'reports')); + + // Map through each document to extract data + const allReports = reportsSnapshot.docs.map(doc => ({ + id: doc.id, // The document ID + ...doc.data() // The report data + })); + + console.log('All Reports:', allReports); + return allReports; + } catch (error) { + console.error('Error retrieving reports:', error); + throw error; // Optionally rethrow the error for higher-level handling } + } + + + async getFilteredReports(focId: string, date: string) { + try { + const filterDate = new Date(date); + const q = query( + collection(this.firestore, 'reports'), + // where("date", "==", filterDate), + where("MaronderaFocId", "==", focId), + ); + const reportsSnapshot = await getDocs(q); + const allReports = reportsSnapshot.docs.map(doc => ({ + id: doc.id, // The document ID + ...doc.data() // The report data + })); + return allReports; + } + catch (error) { + console.error('Error retrieving reports:', error); + throw error; // Optionally rethrow the error for higher-level handling + } + } + + getAll(str: string): Observable { - const offeringCollection = collection(this.firestore, str); return collectionData(offeringCollection); }