This commit is contained in:
Alexander Kacheryants 2024-04-07 06:45:30 +03:00
parent 234b560d1f
commit f9fdc50855
52 changed files with 767 additions and 583 deletions

View File

@ -5,12 +5,13 @@
{
"files": ["*.ts"],
"parserOptions": {
"project": ["tsconfig.json"],
"project": ["tsconfig.json", "tsconfig.spec.json", "tsconfig.app.json"],
"createDefaultProgram": true
},
"extends": [
"plugin:@angular-eslint/recommended",
"plugin:@angular-eslint/template/process-inline-templates"
"plugin:@angular-eslint/template/process-inline-templates",
"plugin:prettier/recommended"
],
"rules": {
"@angular-eslint/component-class-suffix": [

514
package-lock.json generated
View File

@ -16,36 +16,45 @@
"@angular/platform-browser": "^17.0.2",
"@angular/platform-browser-dynamic": "^17.0.2",
"@angular/router": "^17.0.2",
"@awesome-cordova-plugins/in-app-browser": "^6.6.0",
"@capacitor/android": "5.7.4",
"@capacitor/app": "5.0.7",
"@capacitor/core": "5.7.4",
"@capacitor/haptics": "5.0.7",
"@capacitor/ios": "5.7.4",
"@capacitor/keyboard": "5.0.8",
"@capacitor/status-bar": "5.0.7",
"@ionic/angular": "^7.0.0",
"@ionic/storage-angular": "^4.0.0",
"cordova-plugin-inappbrowser": "github:ihackfx/cordova-plugin-inappbrowser",
"ionicons": "^7.0.0",
"node-isbn": "^1.6.1",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.14.2"
},
"devDependencies": {
"@angular-devkit/build-angular": "^17.0.0",
"@angular-eslint/builder": "^17.0.0",
"@angular-eslint/eslint-plugin": "^17.0.0",
"@angular-eslint/eslint-plugin-template": "^17.0.0",
"@angular-eslint/schematics": "^17.0.0",
"@angular-eslint/template-parser": "^17.0.0",
"@angular-eslint/builder": "17.3.0",
"@angular-eslint/eslint-plugin": "17.3.0",
"@angular-eslint/eslint-plugin-template": "17.3.0",
"@angular-eslint/schematics": "17.3.0",
"@angular-eslint/template-parser": "17.3.0",
"@angular/cli": "^17.0.0",
"@angular/compiler-cli": "^17.0.2",
"@angular/language-service": "^17.0.2",
"@capacitor/cli": "5.7.4",
"@ionic/angular-toolkit": "^11.0.1",
"@types/jasmine": "~5.1.0",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"@types/node-isbn": "^1.6.4",
"@typescript-eslint/eslint-plugin": "7.2.0",
"@typescript-eslint/parser": "7.2.0",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-jsdoc": "^48.2.1",
"eslint-plugin-prefer-arrow": "1.2.2",
"eslint-plugin-prettier": "^5.1.3",
"jasmine-core": "~5.1.0",
"jasmine-spec-reporter": "~5.0.0",
"karma": "~6.4.0",
@ -53,6 +62,7 @@
"karma-coverage": "~2.2.0",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.1.0",
"prettier": "3.2.5",
"typescript": "~5.2.2"
}
},
@ -635,6 +645,30 @@
"rxjs": "^6.5.3 || ^7.4.0"
}
},
"node_modules/@awesome-cordova-plugins/core": {
"version": "6.6.0",
"resolved": "https://registry.npmjs.org/@awesome-cordova-plugins/core/-/core-6.6.0.tgz",
"integrity": "sha512-mr2oI+qIoxgoccG57VMkkQdedvulIFJ+kyDeXZvrA1CSkFu1RzTwRvM6QuyA01f9i9G9hSSONpAp4v94h45LNA==",
"peer": true,
"dependencies": {
"@types/cordova": "latest"
},
"peerDependencies": {
"rxjs": "^5.5.0 || ^6.5.0 || ^7.3.0"
}
},
"node_modules/@awesome-cordova-plugins/in-app-browser": {
"version": "6.6.0",
"resolved": "https://registry.npmjs.org/@awesome-cordova-plugins/in-app-browser/-/in-app-browser-6.6.0.tgz",
"integrity": "sha512-RC+t421VHEz5dyoWb9gKYQ16D0vvtCJWty8moGheN3YmfB8dr80NSyt6gOWW8QIa6+3wDTNfSSUN+h0zMp7pvQ==",
"dependencies": {
"@types/cordova": "latest"
},
"peerDependencies": {
"@awesome-cordova-plugins/core": "^6.0.1",
"rxjs": "^5.5.0 || ^6.5.0 || ^7.3.0"
}
},
"node_modules/@babel/code-frame": {
"version": "7.24.2",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz",
@ -2384,6 +2418,14 @@
"node": ">=6.9.0"
}
},
"node_modules/@capacitor/android": {
"version": "5.7.4",
"resolved": "https://registry.npmjs.org/@capacitor/android/-/android-5.7.4.tgz",
"integrity": "sha512-9ETwrCaLaimLHbwGpgfsPS9cHcPMFLmKFdlYsFsYIusMO6aOrcQTA9Q4xVAkr55ava4Wk+pVRniRYsekrbOLdw==",
"peerDependencies": {
"@capacitor/core": "^5.7.0"
}
},
"node_modules/@capacitor/app": {
"version": "5.0.7",
"resolved": "https://registry.npmjs.org/@capacitor/app/-/app-5.0.7.tgz",
@ -2509,6 +2551,14 @@
"@capacitor/core": "^5.0.0"
}
},
"node_modules/@capacitor/ios": {
"version": "5.7.4",
"resolved": "https://registry.npmjs.org/@capacitor/ios/-/ios-5.7.4.tgz",
"integrity": "sha512-tQH24WMSYVKYr/Jl1gFImooQmu8OdXUFHoDaPV1WpZIiwbwxbTdwOXeLlGes5U8B8t7xuxTWMWMDt3IwRlDbhQ==",
"peerDependencies": {
"@capacitor/core": "^5.7.0"
}
},
"node_modules/@capacitor/keyboard": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/@capacitor/keyboard/-/keyboard-5.0.8.tgz",
@ -3178,6 +3228,27 @@
"tslib": "^2.1.0"
}
},
"node_modules/@ionic/storage": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@ionic/storage/-/storage-4.0.0.tgz",
"integrity": "sha512-3N21P19Xk6cICLnSXZ3ilRqbSXAGSFeIF3HNqz+1kARcm0UFT/vwmZreaXtFyq437vvEWOfJ2enlj3JHLKS0FA==",
"dependencies": {
"localforage": "^1.9.0"
}
},
"node_modules/@ionic/storage-angular": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@ionic/storage-angular/-/storage-angular-4.0.0.tgz",
"integrity": "sha512-FeSmCMCm1bMRfu5TFSqLtjdfEo/dLLUhLIrPmbhSYomVZdV/dNn4mBZv9SabyxSqn4bF31hw40y+4buhG+durQ==",
"dependencies": {
"@ionic/storage": "^4.0.0",
"tslib": "^2.3.0"
},
"peerDependencies": {
"@angular/core": "*",
"rxjs": "*"
}
},
"node_modules/@ionic/utils-array": {
"version": "2.1.6",
"resolved": "https://registry.npmjs.org/@ionic/utils-array/-/utils-array-2.1.6.tgz",
@ -4203,6 +4274,18 @@
"node": ">=14"
}
},
"node_modules/@pkgr/core": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz",
"integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==",
"dev": true,
"engines": {
"node": "^12.20.0 || ^14.18.0 || >=16.0.0"
},
"funding": {
"url": "https://opencollective.com/unts"
}
},
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.14.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.0.tgz",
@ -4576,6 +4659,11 @@
"integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==",
"dev": true
},
"node_modules/@types/cordova": {
"version": "11.0.3",
"resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-11.0.3.tgz",
"integrity": "sha512-kyuRQ40/NWQVhqGIHq78Ehu2Bf9Mlg0LhmSmis6ZFJK7z933FRfYi8tHe/k/0fB+PGfCf95rJC6TO7dopaFvAg=="
},
"node_modules/@types/cors": {
"version": "2.8.17",
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz",
@ -4701,6 +4789,25 @@
"@types/node": "*"
}
},
"node_modules/@types/node-isbn": {
"version": "1.6.4",
"resolved": "https://registry.npmjs.org/@types/node-isbn/-/node-isbn-1.6.4.tgz",
"integrity": "sha512-SKqE4/fuLWQRHQUzbeKgVEy9Tnh8L6HHzFmTGUgP+c5vmW5us6UmT6I3o4nOnXOw9b249PRP5XMTTfdg6NcwqQ==",
"dev": true,
"dependencies": {
"@types/node": "*",
"axios": "^0.21.1"
}
},
"node_modules/@types/node-isbn/node_modules/axios": {
"version": "0.21.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
"dev": true,
"dependencies": {
"follow-redirects": "^1.14.0"
}
},
"node_modules/@types/qs": {
"version": "6.9.14",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.14.tgz",
@ -4780,16 +4887,16 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz",
"integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==",
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.2.0.tgz",
"integrity": "sha512-mdekAHOqS9UjlmyF/LSs6AIEvfceV749GFxoBAjwAv0nkevfKHWQFDMcBZWUiIC5ft6ePWivXoS36aKQ0Cy3sw==",
"dev": true,
"dependencies": {
"@eslint-community/regexpp": "^4.5.1",
"@typescript-eslint/scope-manager": "6.21.0",
"@typescript-eslint/type-utils": "6.21.0",
"@typescript-eslint/utils": "6.21.0",
"@typescript-eslint/visitor-keys": "6.21.0",
"@typescript-eslint/scope-manager": "7.2.0",
"@typescript-eslint/type-utils": "7.2.0",
"@typescript-eslint/utils": "7.2.0",
"@typescript-eslint/visitor-keys": "7.2.0",
"debug": "^4.3.4",
"graphemer": "^1.4.0",
"ignore": "^5.2.4",
@ -4805,8 +4912,8 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha",
"eslint": "^7.0.0 || ^8.0.0"
"@typescript-eslint/parser": "^7.0.0",
"eslint": "^8.56.0"
},
"peerDependenciesMeta": {
"typescript": {
@ -4814,68 +4921,16 @@
}
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/type-utils": {
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz",
"integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==",
"dev": true,
"dependencies": {
"@typescript-eslint/typescript-estree": "6.21.0",
"@typescript-eslint/utils": "6.21.0",
"debug": "^4.3.4",
"ts-api-utils": "^1.0.1"
},
"engines": {
"node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"eslint": "^7.0.0 || ^8.0.0"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": {
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz",
"integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
"@types/json-schema": "^7.0.12",
"@types/semver": "^7.5.0",
"@typescript-eslint/scope-manager": "6.21.0",
"@typescript-eslint/types": "6.21.0",
"@typescript-eslint/typescript-estree": "6.21.0",
"semver": "^7.5.4"
},
"engines": {
"node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"eslint": "^7.0.0 || ^8.0.0"
}
},
"node_modules/@typescript-eslint/parser": {
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz",
"integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==",
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.2.0.tgz",
"integrity": "sha512-5FKsVcHTk6TafQKQbuIVkXq58Fnbkd2wDL4LB7AURN7RUOu1utVP+G8+6u3ZhEroW3DF6hyo3ZEXxgKgp4KeCg==",
"dev": true,
"dependencies": {
"@typescript-eslint/scope-manager": "6.21.0",
"@typescript-eslint/types": "6.21.0",
"@typescript-eslint/typescript-estree": "6.21.0",
"@typescript-eslint/visitor-keys": "6.21.0",
"@typescript-eslint/scope-manager": "7.2.0",
"@typescript-eslint/types": "7.2.0",
"@typescript-eslint/typescript-estree": "7.2.0",
"@typescript-eslint/visitor-keys": "7.2.0",
"debug": "^4.3.4"
},
"engines": {
@ -4886,7 +4941,7 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"eslint": "^7.0.0 || ^8.0.0"
"eslint": "^8.56.0"
},
"peerDependenciesMeta": {
"typescript": {
@ -4895,13 +4950,13 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz",
"integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==",
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz",
"integrity": "sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "6.21.0",
"@typescript-eslint/visitor-keys": "6.21.0"
"@typescript-eslint/types": "7.2.0",
"@typescript-eslint/visitor-keys": "7.2.0"
},
"engines": {
"node": "^16.0.0 || >=18.0.0"
@ -4938,7 +4993,7 @@
}
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": {
"node_modules/@typescript-eslint/types": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.2.0.tgz",
"integrity": "sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==",
@ -4951,7 +5006,7 @@
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": {
"node_modules/@typescript-eslint/typescript-estree": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.2.0.tgz",
"integrity": "sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==",
@ -4979,64 +5034,6 @@
}
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.2.0.tgz",
"integrity": "sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "7.2.0",
"eslint-visitor-keys": "^3.4.1"
},
"engines": {
"node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@typescript-eslint/types": {
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz",
"integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==",
"dev": true,
"engines": {
"node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz",
"integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "6.21.0",
"@typescript-eslint/visitor-keys": "6.21.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
"minimatch": "9.0.3",
"semver": "^7.5.4",
"ts-api-utils": "^1.0.1"
},
"engines": {
"node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/@typescript-eslint/utils": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.2.0.tgz",
@ -5062,65 +5059,7 @@
"eslint": "^8.56.0"
}
},
"node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz",
"integrity": "sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "7.2.0",
"@typescript-eslint/visitor-keys": "7.2.0"
},
"engines": {
"node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.2.0.tgz",
"integrity": "sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==",
"dev": true,
"engines": {
"node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.2.0.tgz",
"integrity": "sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "7.2.0",
"@typescript-eslint/visitor-keys": "7.2.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
"minimatch": "9.0.3",
"semver": "^7.5.4",
"ts-api-utils": "^1.0.1"
},
"engines": {
"node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": {
"node_modules/@typescript-eslint/visitor-keys": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.2.0.tgz",
"integrity": "sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==",
@ -5137,23 +5076,6 @@
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz",
"integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "6.21.0",
"eslint-visitor-keys": "^3.4.1"
},
"engines": {
"node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@ungap/structured-clone": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
@ -6840,6 +6762,35 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/cordova-plugin-inappbrowser": {
"version": "6.0.1-dev",
"resolved": "git+ssh://git@github.com/ihackfx/cordova-plugin-inappbrowser.git#9f87eabf784614d2b800653462a4840088f0afc1",
"license": "Apache-2.0",
"engines": {
"cordovaDependencies": {
"0.2.3": {
"cordova": ">=3.1.0"
},
"4.0.0": {
"cordova": ">=3.1.0",
"cordova-ios": ">=4.0.0"
},
"5.0.0": {
"cordova": ">=9.0.0",
"cordova-android": ">=9.0.0",
"cordova-ios": ">=6.0.0"
},
"6.0.1-dev": {
"cordova": ">=9.0.0",
"cordova-android": ">=10.0.0",
"cordova-ios": ">=6.0.0"
},
"7.0.0": {
"cordova": ">100"
}
}
}
},
"node_modules/core-js-compat": {
"version": "3.36.1",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.1.tgz",
@ -7920,6 +7871,18 @@
"url": "https://opencollective.com/eslint"
}
},
"node_modules/eslint-config-prettier": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz",
"integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==",
"dev": true,
"bin": {
"eslint-config-prettier": "bin/cli.js"
},
"peerDependencies": {
"eslint": ">=7.0.0"
}
},
"node_modules/eslint-import-resolver-node": {
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz",
@ -8093,6 +8056,36 @@
"eslint": ">=2.0.0"
}
},
"node_modules/eslint-plugin-prettier": {
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz",
"integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==",
"dev": true,
"dependencies": {
"prettier-linter-helpers": "^1.0.0",
"synckit": "^0.8.6"
},
"engines": {
"node": "^14.18.0 || >=16.0.0"
},
"funding": {
"url": "https://opencollective.com/eslint-plugin-prettier"
},
"peerDependencies": {
"@types/eslint": ">=8.0.0",
"eslint": ">=8.0.0",
"eslint-config-prettier": "*",
"prettier": ">=3.0.0"
},
"peerDependenciesMeta": {
"@types/eslint": {
"optional": true
},
"eslint-config-prettier": {
"optional": true
}
}
},
"node_modules/eslint-scope": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.1.tgz",
@ -8637,6 +8630,12 @@
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true
},
"node_modules/fast-diff": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
"integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
"dev": true
},
"node_modules/fast-glob": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
@ -8862,7 +8861,6 @@
"version": "1.15.6",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
"dev": true,
"funding": [
{
"type": "individual",
@ -9648,6 +9646,11 @@
"node": ">=0.10.0"
}
},
"node_modules/immediate": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
"integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="
},
"node_modules/immutable": {
"version": "4.3.5",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.5.tgz",
@ -11160,6 +11163,14 @@
}
}
},
"node_modules/lie": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
"integrity": "sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==",
"dependencies": {
"immediate": "~3.0.5"
}
},
"node_modules/lines-and-columns": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.4.tgz",
@ -11187,6 +11198,14 @@
"node": ">= 12.13.0"
}
},
"node_modules/localforage": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz",
"integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==",
"dependencies": {
"lie": "3.1.1"
}
},
"node_modules/locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
@ -11988,6 +12007,22 @@
"node": "^16.13.0 || >=18.0.0"
}
},
"node_modules/node-isbn": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/node-isbn/-/node-isbn-1.6.1.tgz",
"integrity": "sha512-OHxpA5xfi7K0iTbqxPpeGlueRA3dasHDRwaKkCWkscLoaKvI8e4mn8yfHrYL0zCJhWq8A2cdrZNbAsHvm7ASwg==",
"dependencies": {
"axios": "^0.21.1"
}
},
"node_modules/node-isbn/node_modules/axios": {
"version": "0.21.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
"dependencies": {
"follow-redirects": "^1.14.0"
}
},
"node_modules/node-machine-id": {
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/node-machine-id/-/node-machine-id-1.1.12.tgz",
@ -13239,6 +13274,33 @@
"node": ">= 0.8.0"
}
},
"node_modules/prettier": {
"version": "3.2.5",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz",
"integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==",
"dev": true,
"bin": {
"prettier": "bin/prettier.cjs"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/prettier-linter-helpers": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
"integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
"dev": true,
"dependencies": {
"fast-diff": "^1.1.2"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/pretty-format": {
"version": "29.7.0",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
@ -14898,6 +14960,22 @@
"node": ">=0.10"
}
},
"node_modules/synckit": {
"version": "0.8.8",
"resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz",
"integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==",
"dev": true,
"dependencies": {
"@pkgr/core": "^0.1.0",
"tslib": "^2.6.2"
},
"engines": {
"node": "^14.18.0 || >=16.0.0"
},
"funding": {
"url": "https://opencollective.com/unts"
}
},
"node_modules/tapable": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",

View File

@ -21,36 +21,45 @@
"@angular/platform-browser": "^17.0.2",
"@angular/platform-browser-dynamic": "^17.0.2",
"@angular/router": "^17.0.2",
"@awesome-cordova-plugins/in-app-browser": "^6.6.0",
"@capacitor/android": "5.7.4",
"@capacitor/app": "5.0.7",
"@capacitor/core": "5.7.4",
"@capacitor/haptics": "5.0.7",
"@capacitor/ios": "5.7.4",
"@capacitor/keyboard": "5.0.8",
"@capacitor/status-bar": "5.0.7",
"@ionic/angular": "^7.0.0",
"@ionic/storage-angular": "^4.0.0",
"cordova-plugin-inappbrowser": "github:ihackfx/cordova-plugin-inappbrowser",
"ionicons": "^7.0.0",
"node-isbn": "^1.6.1",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.14.2"
},
"devDependencies": {
"@angular-devkit/build-angular": "^17.0.0",
"@angular-eslint/builder": "^17.0.0",
"@angular-eslint/eslint-plugin": "^17.0.0",
"@angular-eslint/eslint-plugin-template": "^17.0.0",
"@angular-eslint/schematics": "^17.0.0",
"@angular-eslint/template-parser": "^17.0.0",
"@angular-eslint/builder": "17.3.0",
"@angular-eslint/eslint-plugin": "17.3.0",
"@angular-eslint/eslint-plugin-template": "17.3.0",
"@angular-eslint/schematics": "17.3.0",
"@angular-eslint/template-parser": "17.3.0",
"@angular/cli": "^17.0.0",
"@angular/compiler-cli": "^17.0.2",
"@angular/language-service": "^17.0.2",
"@capacitor/cli": "5.7.4",
"@ionic/angular-toolkit": "^11.0.1",
"@types/jasmine": "~5.1.0",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"@types/node-isbn": "^1.6.4",
"@typescript-eslint/eslint-plugin": "7.2.0",
"@typescript-eslint/parser": "7.2.0",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-jsdoc": "^48.2.1",
"eslint-plugin-prefer-arrow": "1.2.2",
"eslint-plugin-prettier": "^5.1.3",
"jasmine-core": "~5.1.0",
"jasmine-spec-reporter": "~5.0.0",
"karma": "~6.4.0",
@ -58,6 +67,7 @@
"karma-coverage": "~2.2.0",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.1.0",
"prettier": "3.2.5",
"typescript": "~5.2.2"
},
"description": "An Ionic project"

View File

@ -1,16 +1,16 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { Tab3Page } from './tab3.page';
import { RentPage } from './rent.page';
const routes: Routes = [
{
path: '',
component: Tab3Page,
}
component: RentPage,
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
exports: [RouterModule],
})
export class Tab3PageRoutingModule {}
export class RentPageRoutingModule {}

View File

@ -0,0 +1,20 @@
import { IonicModule } from '@ionic/angular';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { RentPage } from './rent.page';
import { RentPageRoutingModule } from './rent-routing.module';
import { BookPageModule } from '../modals/book-page/book-page.module';
@NgModule({
imports: [
IonicModule,
CommonModule,
FormsModule,
RentPageRoutingModule,
BookPageModule,
],
declarations: [RentPage],
})
export class RentPageModule {}

View File

@ -0,0 +1,38 @@
<ion-header [translucent]="true">
<ion-toolbar>
<ion-title>
Аренда
</ion-title>
<ion-buttons slot="end">
<ion-button (click)="refresh()">
<ion-icon slot="icon-only" name="refresh"/>
</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content [fullscreen]="true">
<ion-header collapse="condense">
<ion-toolbar>
<ion-title size="large">Аренда</ion-title>
</ion-toolbar>
</ion-header>
<ion-list *ngFor="let item of booksName; index as i">
<ion-item [id]="'issue' + i" lines="none" button>
<ion-card>
<img class="itemImg" [alt]="item.book.volumeInfo.title" [src]="item.book.volumeInfo.imageLinks.thumbnail" />
<ion-card-header>
<ion-card-title>{{item.book.volumeInfo.title}}</ion-card-title>
<ion-card-subtitle>Выдан: {{item.user?.fio}}</ion-card-subtitle>
</ion-card-header>
<ion-card-content>
Книга выдана {{dateParse(item.issue.date)}}. До {{dateParse(item.issue.dateTo)}}
</ion-card-content>
</ion-card>
<app-book-page [trigger]="'issue' + i" [item]="item.book" />
</ion-item>
</ion-list>
</ion-content>

View File

@ -0,0 +1,6 @@
.itemImg{
margin-left: auto;
margin-right: auto;
margin-top: 2vh;
display: block;
}

View File

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { RentPage } from './rent.page';
describe('RentPage', () => {
let component: RentPage;
let fixture: ComponentFixture<RentPage>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [RentPage],
imports: [IonicModule.forRoot()],
}).compileComponents();
fixture = TestBed.createComponent(RentPage);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,58 @@
import { Component, OnInit } from '@angular/core';
import {
bookIssued,
readerUser,
StorageService,
} from '../services/storage/storage.service';
import { Book, GoogleBookApiService } from '../api/google-book-api.service';
interface issue {
issue: bookIssued;
book: Book;
user: readerUser | null;
}
@Component({
selector: 'app-rent-page',
templateUrl: 'rent.page.html',
styleUrls: ['rent.page.scss'],
})
export class RentPage implements OnInit {
constructor(
private storage: StorageService,
private ApiService: GoogleBookApiService,
) {}
protected booksName: Array<issue> = [];
protected refresh() {
this.ngOnInit();
}
ngOnInit() {
this.booksName = [];
this.storage.init().then(() => {
this.storage.getBooksIssued().then((issues) => {
this.storage.getReaderUsers().then((users) => {
issues.forEach((issue) => {
return this.ApiService.search(issue.bookId).subscribe({
next: (book) => {
this.booksName.push({
issue: issue,
book: book.items[0],
user:
users.find((user) => {
return user.id === issue.userId;
}) || null,
});
},
});
});
});
});
});
}
public dateParse(date: string) {
let _date = new Date(date);
return _date.toLocaleDateString();
}
}

View File

@ -1,16 +1,16 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { Tab2Page } from './tab2.page';
import { SearchPage } from './search.page';
const routes: Routes = [
{
path: '',
component: Tab2Page,
}
component: SearchPage,
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
exports: [RouterModule],
})
export class Tab2PageRoutingModule {}
export class SearchPageRoutingModule {}

View File

@ -0,0 +1,20 @@
import { IonicModule } from '@ionic/angular';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { SearchPage } from './search.page';
import { SearchPageRoutingModule } from './search-routing.module';
import { BookPageModule } from '../modals/book-page/book-page.module';
@NgModule({
imports: [
IonicModule,
CommonModule,
FormsModule,
SearchPageRoutingModule,
BookPageModule,
],
declarations: [SearchPage],
})
export class SearchPageModule {}

View File

@ -0,0 +1,27 @@
<ion-header [translucent]="true">
<ion-toolbar>
<ion-title>
Поиск книг
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content [fullscreen]="true">
<ion-header collapse="condense">
<ion-toolbar>
<ion-title size="large">Поиск книг</ion-title>
</ion-toolbar>
</ion-header>
<ion-searchbar (ionInput)="search($event)" placeholder="Найти книгу"></ion-searchbar>
<ion-list *ngFor="let item of searchResult; index as i">
<ion-item *ngIf="item.volumeInfo.imageLinks" [id]="'book' + i" lines="none">
<ion-thumbnail slot="start">
<img [alt]="item.volumeInfo.imageLinks.thumbnail" [src]="item.volumeInfo.imageLinks.thumbnail" />
</ion-thumbnail>
<ion-label>{{item.volumeInfo.title}}</ion-label>
<app-book-page [item]="item" [trigger]="'book'+i" />
</ion-item>
</ion-list>
</ion-content>

View File

@ -0,0 +1,10 @@
ion-thumbnail{
height: 15vh;
width: 10vh;
}
ion-thumbnail img{
height: 100%;
width: 100%;
object-fit: contain;
}

View File

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { SearchPage } from './search.page';
describe('SearchPage', () => {
let component: SearchPage;
let fixture: ComponentFixture<SearchPage>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [SearchPage],
imports: [IonicModule.forRoot()],
}).compileComponents();
fixture = TestBed.createComponent(SearchPage);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,32 @@
import { Component } from '@angular/core';
import { Subject, takeUntil } from 'rxjs';
import { Book, GoogleBookApiService } from '../api/google-book-api.service';
@Component({
selector: 'app-search-page',
templateUrl: 'search.page.html',
styleUrls: ['search.page.scss'],
})
export class SearchPage {
constructor(private api: GoogleBookApiService) {}
public searchResult: Array<Book> = [];
private destroy$: Subject<boolean> = new Subject<boolean>();
public search(e: any) {
this.destroy$.next(true);
this.api
.search(e.target.value)
.pipe(takeUntil(this.destroy$))
.subscribe({
next: (res) => {
console.log(res);
this.searchResult = res.items;
},
error: (error) => {
console.log(error);
},
});
}
}

View File

@ -1,16 +1,16 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { Tab1Page } from './tab1.page';
import { UsersPage } from './users.page';
const routes: Routes = [
{
path: '',
component: Tab1Page,
}
component: UsersPage,
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
exports: [RouterModule],
})
export class Tab1PageRoutingModule {}
export class UsersPageRoutingModule {}

View File

@ -2,19 +2,19 @@ import { IonicModule } from '@ionic/angular';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { Tab2Page } from './tab2.page';
import { ExploreContainerComponentModule } from '../explore-container/explore-container.module';
import { UsersPage } from './users.page';
import { Tab2PageRoutingModule } from './tab2-routing.module';
import { UsersPageRoutingModule } from './users-routing.module';
import { NewUserModalPageModule } from '../modals/new-user/new-user-modal.module';
@NgModule({
imports: [
IonicModule,
CommonModule,
FormsModule,
ExploreContainerComponentModule,
Tab2PageRoutingModule
UsersPageRoutingModule,
NewUserModalPageModule,
],
declarations: [Tab2Page]
declarations: [UsersPage],
})
export class Tab2PageModule {}

View File

@ -0,0 +1,37 @@
<ion-header>
<ion-toolbar>
<ion-title>
Читатели
</ion-title>
<ion-buttons slot="start">
</ion-buttons>
<ion-buttons slot="end">
<ion-button>
<ion-icon slot="icon-only" name="refresh" (click)="refresh()" />
</ion-button>
<ion-button id="addUser">
<ion-icon slot="icon-only" name="add"/>
</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content [fullscreen]="true">
<ion-header collapse="condense">
<ion-toolbar>
<ion-title size="large">Читатели</ion-title>
</ion-toolbar>
</ion-header>
<ion-list>
<ion-item lines="none">
<ion-label>ID и ФИО читателя</ion-label>
<ion-label slot="end">Дата регистрации</ion-label>
</ion-item>
<ion-item *ngFor="let user of users; index as i">
<ion-label>{{user.id}} {{user.fio}}</ion-label>
<ion-label slot="end">{{getDate(user.registrationDate)}}</ion-label>
</ion-item>
</ion-list>
<app-new-user-modal trigger="addUser" />
</ion-content>

View File

@ -0,0 +1,6 @@
.toolbar-btn{
--padding-start: unset;
--padding-end: unset;
--padding-top: unset;
--padding-bottom: unset;
}

View File

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { UsersPage } from './users.page';
describe('UsersPage', () => {
let component: UsersPage;
let fixture: ComponentFixture<UsersPage>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [UsersPage],
imports: [IonicModule.forRoot()],
}).compileComponents();
fixture = TestBed.createComponent(UsersPage);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,36 @@
import { Component, OnInit } from '@angular/core';
import {
readerUser,
StorageService,
} from '../services/storage/storage.service';
@Component({
selector: 'app-users-page',
templateUrl: 'users.page.html',
styleUrls: ['users.page.scss'],
})
export class UsersPage implements OnInit {
public users: Array<readerUser> = [];
constructor(private storage: StorageService) {}
ngOnInit() {
this.storage.init().then(() => {
this.storage.getReaderUsers().then((users) => {
console.log(users);
this.users = users;
});
});
}
refresh() {
this.ngOnInit();
}
getDate(dateNumber: number) {
const date = new Date(dateNumber);
return date.toLocaleDateString();
}
protected readonly Date = Date;
}

View File

@ -4,13 +4,28 @@ import { PreloadAllModules, RouterModule, Routes } from '@angular/router';
const routes: Routes = [
{
path: '',
loadChildren: () => import('./tabs/tabs.module').then(m => m.TabsPageModule)
}
loadChildren: () =>
import('./tabs/tabs.module').then((m) => m.TabsPageModule),
},
{
path: 'issue-book-modal',
loadChildren: () =>
import('./modals/issue-book-modal/issue-book-modal.module').then(
(m) => m.IssueBookModalPageModule,
),
},
{
path: 'new-user-modal',
loadChildren: () =>
import('./modals/new-user/new-user-modal.module').then(
(m) => m.NewUserModalPageModule,
),
},
];
@NgModule({
imports: [
RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })
RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules }),
],
exports: [RouterModule]
exports: [RouterModule],
})
export class AppRoutingModule {}

View File

@ -4,7 +4,6 @@ import { TestBed } from '@angular/core/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [AppComponent],
@ -17,5 +16,4 @@ describe('AppComponent', () => {
const app = fixture.componentInstance;
expect(app).toBeTruthy();
});
});

View File

@ -1,16 +1,29 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { IonicStorageModule } from '@ionic/storage-angular';
import { RouteReuseStrategy } from '@angular/router';
import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { Drivers } from '@ionic/storage';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { provideHttpClient } from '@angular/common/http';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule],
providers: [{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }],
imports: [
BrowserModule,
IonicStorageModule.forRoot({
name: '__libraryDB',
driverOrder: [Drivers.IndexedDB, Drivers.LocalStorage],
}),
IonicModule.forRoot(),
AppRoutingModule,
],
providers: [
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
provideHttpClient(),
],
bootstrap: [AppComponent],
})
export class AppModule {}

View File

@ -1,4 +0,0 @@
<div id="container">
<strong>{{ name }}</strong>
<p>Explore <a target="_blank" rel="noopener noreferrer" href="https://ionicframework.com/docs/components">UI Components</a></p>
</div>

View File

@ -1,27 +0,0 @@
#container {
text-align: center;
position: absolute;
left: 0;
right: 0;
top: 50%;
transform: translateY(-50%);
}
#container strong {
font-size: 20px;
line-height: 26px;
}
#container p {
font-size: 16px;
line-height: 22px;
color: #8c8c8c;
margin: 0;
}
#container a {
text-decoration: none;
}

View File

@ -1,24 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { ExploreContainerComponent } from './explore-container.component';
describe('ExploreContainerComponent', () => {
let component: ExploreContainerComponent;
let fixture: ComponentFixture<ExploreContainerComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ExploreContainerComponent],
imports: [IonicModule.forRoot()]
}).compileComponents();
fixture = TestBed.createComponent(ExploreContainerComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -1,12 +0,0 @@
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-explore-container',
templateUrl: './explore-container.component.html',
styleUrls: ['./explore-container.component.scss'],
})
export class ExploreContainerComponent {
@Input() name?: string;
}

View File

@ -1,14 +0,0 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { ExploreContainerComponent } from './explore-container.component';
@NgModule({
imports: [ CommonModule, FormsModule, IonicModule],
declarations: [ExploreContainerComponent],
exports: [ExploreContainerComponent]
})
export class ExploreContainerComponentModule {}

View File

@ -1,20 +0,0 @@
import { IonicModule } from '@ionic/angular';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { Tab1Page } from './tab1.page';
import { ExploreContainerComponentModule } from '../explore-container/explore-container.module';
import { Tab1PageRoutingModule } from './tab1-routing.module';
@NgModule({
imports: [
IonicModule,
CommonModule,
FormsModule,
ExploreContainerComponentModule,
Tab1PageRoutingModule
],
declarations: [Tab1Page]
})
export class Tab1PageModule {}

View File

@ -1,17 +0,0 @@
<ion-header [translucent]="true">
<ion-toolbar>
<ion-title>
Tab 1
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content [fullscreen]="true">
<ion-header collapse="condense">
<ion-toolbar>
<ion-title size="large">Tab 1</ion-title>
</ion-toolbar>
</ion-header>
<app-explore-container name="Tab 1 page"></app-explore-container>
</ion-content>

View File

@ -1,26 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { ExploreContainerComponentModule } from '../explore-container/explore-container.module';
import { Tab1Page } from './tab1.page';
describe('Tab1Page', () => {
let component: Tab1Page;
let fixture: ComponentFixture<Tab1Page>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [Tab1Page],
imports: [IonicModule.forRoot(), ExploreContainerComponentModule]
}).compileComponents();
fixture = TestBed.createComponent(Tab1Page);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -1,12 +0,0 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-tab1',
templateUrl: 'tab1.page.html',
styleUrls: ['tab1.page.scss']
})
export class Tab1Page {
constructor() {}
}

View File

@ -1,17 +0,0 @@
<ion-header [translucent]="true">
<ion-toolbar>
<ion-title>
Tab 2
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content [fullscreen]="true">
<ion-header collapse="condense">
<ion-toolbar>
<ion-title size="large">Tab 2</ion-title>
</ion-toolbar>
</ion-header>
<app-explore-container name="Tab 2 page"></app-explore-container>
</ion-content>

View File

@ -1,26 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { ExploreContainerComponentModule } from '../explore-container/explore-container.module';
import { Tab2Page } from './tab2.page';
describe('Tab2Page', () => {
let component: Tab2Page;
let fixture: ComponentFixture<Tab2Page>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [Tab2Page],
imports: [IonicModule.forRoot(), ExploreContainerComponentModule]
}).compileComponents();
fixture = TestBed.createComponent(Tab2Page);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -1,12 +0,0 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-tab2',
templateUrl: 'tab2.page.html',
styleUrls: ['tab2.page.scss']
})
export class Tab2Page {
constructor() {}
}

View File

@ -1,20 +0,0 @@
import { IonicModule } from '@ionic/angular';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { Tab3Page } from './tab3.page';
import { ExploreContainerComponentModule } from '../explore-container/explore-container.module';
import { Tab3PageRoutingModule } from './tab3-routing.module';
@NgModule({
imports: [
IonicModule,
CommonModule,
FormsModule,
ExploreContainerComponentModule,
Tab3PageRoutingModule
],
declarations: [Tab3Page]
})
export class Tab3PageModule {}

View File

@ -1,17 +0,0 @@
<ion-header [translucent]="true">
<ion-toolbar>
<ion-title>
Tab 3
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content [fullscreen]="true">
<ion-header collapse="condense">
<ion-toolbar>
<ion-title size="large">Tab 3</ion-title>
</ion-toolbar>
</ion-header>
<app-explore-container name="Tab 3 page"></app-explore-container>
</ion-content>

View File

@ -1,26 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { ExploreContainerComponentModule } from '../explore-container/explore-container.module';
import { Tab3Page } from './tab3.page';
describe('Tab3Page', () => {
let component: Tab3Page;
let fixture: ComponentFixture<Tab3Page>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [Tab3Page],
imports: [IonicModule.forRoot(), ExploreContainerComponentModule]
}).compileComponents();
fixture = TestBed.createComponent(Tab3Page);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -1,12 +0,0 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-tab3',
templateUrl: 'tab3.page.html',
styleUrls: ['tab3.page.scss']
})
export class Tab3Page {
constructor() {}
}

View File

@ -8,29 +8,32 @@ const routes: Routes = [
component: TabsPage,
children: [
{
path: 'tab1',
loadChildren: () => import('../tab1/tab1.module').then(m => m.Tab1PageModule)
path: 'search',
loadChildren: () =>
import('../SearchPage/search.module').then((m) => m.SearchPageModule),
},
{
path: 'tab2',
loadChildren: () => import('../tab2/tab2.module').then(m => m.Tab2PageModule)
path: 'users',
loadChildren: () =>
import('../UsersPage/users.module').then((m) => m.Tab2PageModule),
},
{
path: 'tab3',
loadChildren: () => import('../tab3/tab3.module').then(m => m.Tab3PageModule)
path: 'rent',
loadChildren: () =>
import('../RentPage/rent.module').then((m) => m.RentPageModule),
},
{
path: '',
redirectTo: '/tabs/tab1',
pathMatch: 'full'
}
]
redirectTo: '/tabs/search',
pathMatch: 'full',
},
],
},
{
path: '',
redirectTo: '/tabs/tab1',
pathMatch: 'full'
}
redirectTo: '/tabs/search',
pathMatch: 'full',
},
];
@NgModule({

View File

@ -8,12 +8,7 @@ import { TabsPageRoutingModule } from './tabs-routing.module';
import { TabsPage } from './tabs.page';
@NgModule({
imports: [
IonicModule,
CommonModule,
FormsModule,
TabsPageRoutingModule
],
declarations: [TabsPage]
imports: [IonicModule, CommonModule, FormsModule, TabsPageRoutingModule],
declarations: [TabsPage],
})
export class TabsPageModule {}

View File

@ -1,19 +1,19 @@
<ion-tabs>
<ion-tab-bar slot="bottom">
<ion-tab-button tab="tab1" href="/tabs/tab1">
<ion-icon aria-hidden="true" name="triangle"></ion-icon>
<ion-label>Tab 1</ion-label>
<ion-tab-button tab="search" href="/tabs/tab1">
<ion-icon aria-hidden="true" src="/assets/svg/bookshelf.svg"></ion-icon>
<ion-label>Поиск книг</ion-label>
</ion-tab-button>
<ion-tab-button tab="tab2" href="/tabs/tab2">
<ion-icon aria-hidden="true" name="ellipse"></ion-icon>
<ion-label>Tab 2</ion-label>
<ion-tab-button tab="users" href="/tabs/users">
<ion-icon aria-hidden="true" src="/assets/svg/users.svg"></ion-icon>
<ion-label>Читатели</ion-label>
</ion-tab-button>
<ion-tab-button tab="tab3" href="/tabs/tab3">
<ion-icon aria-hidden="true" name="square"></ion-icon>
<ion-label>Tab 3</ion-label>
<ion-tab-button tab="rent" href="/tabs/rent">
<ion-icon aria-hidden="true" src="/assets/svg/expire.svg"></ion-icon>
<ion-label>Аренда</ion-label>
</ion-tab-button>
</ion-tab-bar>

View File

@ -3,10 +3,8 @@ import { Component } from '@angular/core';
@Component({
selector: 'app-tabs',
templateUrl: 'tabs.page.html',
styleUrls: ['tabs.page.scss']
styleUrls: ['tabs.page.scss'],
})
export class TabsPage {
constructor() {}
}

View File

@ -1,3 +1,3 @@
export const environment = {
production: true
production: true,
};

View File

@ -3,7 +3,7 @@
// The list of file replacements can be found in `angular.json`.
export const environment = {
production: false
production: false,
};
/*

View File

@ -8,5 +8,6 @@ if (environment.production) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.log(err));
platformBrowserDynamic()
.bootstrapModule(AppModule)
.catch((err) => console.log(err));

View File

@ -49,7 +49,6 @@ import './zone-flags';
*/
import 'zone.js'; // Included with Angular CLI.
/***************************************************************************************************
* APPLICATION IMPORTS
*/

View File

@ -4,7 +4,7 @@ import 'zone.js/testing';
import { getTestBed } from '@angular/core/testing';
import {
BrowserDynamicTestingModule,
platformBrowserDynamicTesting
platformBrowserDynamicTesting,
} from '@angular/platform-browser-dynamic/testing';
// First, initialize the Angular testing environment.