diff --git a/app/package-lock.json b/app/package-lock.json index cb9a132..1d79547 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.1", "dependencies": { "@angular/animations": "^16.0.0", + "@angular/cdk": "^16.2.12", "@angular/common": "^16.0.0", "@angular/compiler": "^16.0.0", "@angular/core": "^16.0.0", @@ -38,8 +39,12 @@ "@ngrx/store-devtools": "^16.3.0", "@ngx-translate/core": "^15.0.0", "@ngx-translate/http-loader": "^8.0.0", + "@swimlane/ngx-charts": "^20.5.0", "@types/lodash": "^4.14.201", "@types/scriptjs": "^0.0.4", + "d3-scale": "^4.0.2", + "d3-selection": "^3.0.0", + "d3-shape": "^3.2.0", "ionicons": "^7.0.0", "jwt-decode": "^3.1.2", "lightweight-charts": "^4.1.0", @@ -65,6 +70,9 @@ "@commitlint/cli": "^17.8.0", "@commitlint/config-conventional": "^17.8.0", "@ionic/angular-toolkit": "^9.0.0", + "@types/d3-scale": "^4.0.8", + "@types/d3-selection": "^3.0.10", + "@types/d3-shape": "^3.1.5", "@types/jasmine": "~4.3.0", "@types/jest": "^29.5.6", "@types/node": "^12.11.1", @@ -514,6 +522,34 @@ "@angular/core": "16.2.12" } }, + "node_modules/@angular/cdk": { + "version": "16.2.12", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-16.2.12.tgz", + "integrity": "sha512-wT8/265zm2WKY0BDaRoYbrAT4kadrmejTRLjuimQIEUKnw4vBsJMWCwQkpFo3s6zr6eznGqYVAFb8KKPVLKGBg==", + "dependencies": { + "tslib": "^2.3.0" + }, + "optionalDependencies": { + "parse5": "^7.1.2" + }, + "peerDependencies": { + "@angular/common": "^16.0.0 || ^17.0.0", + "@angular/core": "^16.0.0 || ^17.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/cdk/node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "optional": true, + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/@angular/cli": { "version": "16.2.10", "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-16.2.10.tgz", @@ -5958,6 +5994,38 @@ "npm": ">=7.10.0" } }, + "node_modules/@swimlane/ngx-charts": { + "version": "20.5.0", + "resolved": "https://registry.npmjs.org/@swimlane/ngx-charts/-/ngx-charts-20.5.0.tgz", + "integrity": "sha512-PNBIHdu/R3ceD7jnw1uCBVOj4k3T6IxfdW6xsDsglGkZyoWMEEq4tLoEurjLEKzmDtRv9c35kVNOXy0lkOuXeA==", + "dependencies": { + "d3-array": "^3.1.1", + "d3-brush": "^3.0.0", + "d3-color": "^3.1.0", + "d3-ease": "^3.0.1", + "d3-format": "^3.1.0", + "d3-hierarchy": "^3.1.0", + "d3-interpolate": "^3.0.1", + "d3-sankey": "^0.12.3", + "d3-scale": "^4.0.2", + "d3-selection": "^3.0.0", + "d3-shape": "^3.2.0", + "d3-time-format": "^3.0.0", + "d3-transition": "^3.0.1", + "rfdc": "^1.3.0", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "@angular/animations": ">=12.0.0", + "@angular/cdk": ">=12.0.0", + "@angular/common": ">=12.0.0", + "@angular/core": ">=12.0.0", + "@angular/forms": ">=12.0.0", + "@angular/platform-browser": ">=12.0.0", + "@angular/platform-browser-dynamic": ">=12.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, "node_modules/@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", @@ -6284,6 +6352,42 @@ "@types/node": "*" } }, + "node_modules/@types/d3-path": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.0.2.tgz", + "integrity": "sha512-WAIEVlOCdd/NKRYTsqCpOMHQHemKBEINf8YXMYOtXH0GA7SY0dqMB78P3Uhgfy+4X+/Mlw2wDtlETkN6kQUCMA==", + "dev": true + }, + "node_modules/@types/d3-scale": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", + "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", + "dev": true, + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-selection": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.10.tgz", + "integrity": "sha512-cuHoUgS/V3hLdjJOLTT691+G2QoqAjCVLmr4kJXR4ha56w1Zdu8UUQ5TxLRqudgNjwXeQxKMq4j+lyf9sWuslg==", + "dev": true + }, + "node_modules/@types/d3-shape": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.5.tgz", + "integrity": "sha512-dfEWpZJ1Pdg8meLlICX1M3WBIpxnaH2eQV2eY43Y5ysRJOTAV9f3/R++lgJKFstfrEOE2zdJ0sv5qwr2Bkic6Q==", + "dev": true, + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz", + "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==", + "dev": true + }, "node_modules/@types/eslint": { "version": "8.44.7", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.7.tgz", @@ -9992,6 +10096,238 @@ "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", "dev": true }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-brush": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", + "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "3", + "d3-transition": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-sankey": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz", + "integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==", + "dependencies": { + "d3-array": "1 - 2", + "d3-shape": "^1.2.0" + } + }, + "node_modules/d3-sankey/node_modules/d3-array": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "dependencies": { + "internmap": "^1.0.0" + } + }, + "node_modules/d3-sankey/node_modules/d3-path": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", + "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==" + }, + "node_modules/d3-sankey/node_modules/d3-shape": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz", + "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==", + "dependencies": { + "d3-path": "1" + } + }, + "node_modules/d3-sankey/node_modules/internmap": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", + "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==" + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-3.0.0.tgz", + "integrity": "sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag==", + "dependencies": { + "d3-time": "1 - 2" + } + }, + "node_modules/d3-time-format/node_modules/d3-array": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "dependencies": { + "internmap": "^1.0.0" + } + }, + "node_modules/d3-time-format/node_modules/d3-time": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz", + "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==", + "dependencies": { + "d3-array": "2" + } + }, + "node_modules/d3-time-format/node_modules/internmap": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", + "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==" + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "dependencies": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" + } + }, "node_modules/dargs": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", @@ -10672,7 +11008,7 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.12" }, @@ -13415,6 +13751,14 @@ "node": ">= 0.4" } }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "engines": { + "node": ">=12" + } + }, "node_modules/ionicons": { "version": "7.2.1", "resolved": "https://registry.npmjs.org/ionicons/-/ionicons-7.2.1.tgz", @@ -20987,8 +21331,7 @@ "node_modules/rfdc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", - "dev": true + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" }, "node_modules/rimraf": { "version": "4.4.1", diff --git a/app/package.json b/app/package.json index 5f35909..4b3662f 100644 --- a/app/package.json +++ b/app/package.json @@ -19,6 +19,7 @@ "private": true, "dependencies": { "@angular/animations": "^16.0.0", + "@angular/cdk": "^16.2.12", "@angular/common": "^16.0.0", "@angular/compiler": "^16.0.0", "@angular/core": "^16.0.0", @@ -48,8 +49,12 @@ "@ngrx/store-devtools": "^16.3.0", "@ngx-translate/core": "^15.0.0", "@ngx-translate/http-loader": "^8.0.0", + "@swimlane/ngx-charts": "^20.5.0", "@types/lodash": "^4.14.201", "@types/scriptjs": "^0.0.4", + "d3-scale": "^4.0.2", + "d3-selection": "^3.0.0", + "d3-shape": "^3.2.0", "ionicons": "^7.0.0", "jwt-decode": "^3.1.2", "lightweight-charts": "^4.1.0", @@ -75,6 +80,9 @@ "@commitlint/cli": "^17.8.0", "@commitlint/config-conventional": "^17.8.0", "@ionic/angular-toolkit": "^9.0.0", + "@types/d3-scale": "^4.0.8", + "@types/d3-selection": "^3.0.10", + "@types/d3-shape": "^3.1.5", "@types/jasmine": "~4.3.0", "@types/jest": "^29.5.6", "@types/node": "^12.11.1", diff --git a/app/src/app/components/reservation-picker/reservation-picker.component.html b/app/src/app/components/reservation-picker/reservation-picker.component.html index fb41eb8..bc10f93 100644 --- a/app/src/app/components/reservation-picker/reservation-picker.component.html +++ b/app/src/app/components/reservation-picker/reservation-picker.component.html @@ -1,11 +1,24 @@ - - - - {{ "REFUGE.RESERVATIONS.BUTTON" | translate }} - - + + + + {{ "REFUGE.RESERVATIONS.BUTTON" | translate }} + + + + + + + + + + diff --git a/app/src/app/components/reservation-picker/reservation-picker.component.scss b/app/src/app/components/reservation-picker/reservation-picker.component.scss index e69de29..1e707e1 100644 --- a/app/src/app/components/reservation-picker/reservation-picker.component.scss +++ b/app/src/app/components/reservation-picker/reservation-picker.component.scss @@ -0,0 +1,6 @@ +#present-info-alert { + background: transparent; + --background: transparent; + color: #3e74b2; + font-size: 20px; +} diff --git a/app/src/app/components/reservation-picker/reservation-picker.component.ts b/app/src/app/components/reservation-picker/reservation-picker.component.ts index aec0d77..7457ccb 100644 --- a/app/src/app/components/reservation-picker/reservation-picker.component.ts +++ b/app/src/app/components/reservation-picker/reservation-picker.component.ts @@ -1,6 +1,7 @@ import { Component, Input, OnInit } from '@angular/core'; import { fromISOString } from '../../schemas/night/night'; import { Refuge } from '../../schemas/refuge/refuge'; +import { TranslateService } from '@ngx-translate/core'; import { AppState } from 'src/app/state/app.state'; import { Store } from '@ngrx/store'; import { addReservation } from '../../state/reservations/reservations.actions'; @@ -14,7 +15,10 @@ export class ReservationPickerComponent implements OnInit { @Input({ required: true }) refuge!: Refuge; date = ''; - constructor(private store: Store) {} + alertButtons = [this.translate.instant('REFUGE.RESERVATIONS.INFO.OKAY')]; + + constructor(private store: Store, private translate: TranslateService) { + } ngOnInit() {} diff --git a/app/src/app/components/reservations-chart/reservations-chart.component.html b/app/src/app/components/reservations-chart/reservations-chart.component.html index 092d976..c581e7b 100644 --- a/app/src/app/components/reservations-chart/reservations-chart.component.html +++ b/app/src/app/components/reservations-chart/reservations-chart.component.html @@ -1,6 +1,26 @@ -

+

{{ "REFUGE.OCCUPATION.HISTORIAL" | translate }}

-
-
+ diff --git a/app/src/app/components/reservations-chart/reservations-chart.component.scss b/app/src/app/components/reservations-chart/reservations-chart.component.scss index e69de29..ab68d70 100644 --- a/app/src/app/components/reservations-chart/reservations-chart.component.scss +++ b/app/src/app/components/reservations-chart/reservations-chart.component.scss @@ -0,0 +1,3 @@ +:host ::ng-deep .ngx-charts text { + fill: var(--ion-color-light-contrast) !important; +} diff --git a/app/src/app/components/reservations-chart/reservations-chart.component.ts b/app/src/app/components/reservations-chart/reservations-chart.component.ts index 6b891ba..3d096bc 100644 --- a/app/src/app/components/reservations-chart/reservations-chart.component.ts +++ b/app/src/app/components/reservations-chart/reservations-chart.component.ts @@ -1,19 +1,9 @@ -import { - AfterViewInit, - ChangeDetectorRef, - Component, - ElementRef, - Input, - OnInit, - ViewChild, -} from '@angular/core'; -import { Refuge } from '../../schemas/refuge/refuge'; -import { createChart } from 'lightweight-charts'; -import { getChartConfiguration } from '../../pages/refuge/chart-configuration'; -import { - OccupationService, - WeeklyOccupation, -} from '../../services/occupation/occupation.service'; +import {AfterViewInit, ChangeDetectorRef, Component, Input, OnInit, ViewChild} from '@angular/core'; +import {Refuge} from '../../schemas/refuge/refuge'; +import {BarVerticalComponent, Color, LegendOptions, LegendPosition, ScaleType} from '@swimlane/ngx-charts'; +import {OccupationService} from '../../services/occupation/occupation.service'; +import {of} from 'rxjs'; +import {random} from "lodash"; @Component({ selector: 'app-reservations-chart', @@ -21,76 +11,78 @@ import { styleUrls: ['./reservations-chart.component.scss'], }) export class ReservationsChartComponent implements OnInit, AfterViewInit { - @Input({ required: true }) refuge!: Refuge; - @ViewChild('chart', { static: false }) chart?: ElementRef; + @Input({required: true}) refuge!: Refuge; + // Get vertical bar component with viewchiod + @ViewChild('verticalBarChart') verticalBarChart?: BarVerticalComponent; + testDate1 = new Date('2023-10-14'); + testDate2 = new Date('2023-10-15'); + + testObservable = of([ + { + testDate1: 1, + testDate2: 2, + }, + ]); + + days: { name: string, value: number, tooltipText: string }[] = []; + + view = [700, 400] as [number, number]; + + gradient = false; + + colorScheme: Color = { + name: 'custom', + selectable: true, + group: ScaleType.Linear, + domain: [], + }; + xAxisTickFormatting = (value: string) => { + if (value === new Date().getUTCDate().toString()) { + return 'Today'; + } + return value + } constructor( private changeDetectorRef: ChangeDetectorRef, private occupationService: OccupationService, - ) {} + ) { + } - ngOnInit() {} + onSelect() { + console.log('myballs'); + } - ngAfterViewInit() { - this.createAndStartChart(); + getLabels() { + return this.days.map(entry => entry.name); } - private createAndStartChart() { - this.changeDetectorRef.detectChanges(); - if (this.chart === undefined) { - console.log('chart undefined'); - return; + ngOnInit() { + // Populate the multi array based on date conditions + for (let i = -7; i <= 7; i++) { + const currentDate = new Date(Date.now() + i * 24 * 60 * 60 * 1000); + + const color = + i === 0 ? '#01579b' : '#7aa3e5'; // Use different colors for the current day and the rest + + this.days.push({ + name: currentDate.getUTCDate().toString(), + value: random(0, 12), + tooltipText: "myballs", + }); + + this.colorScheme.domain.push(color); } - const chartElement = this.chart.nativeElement; - const chart = createChart( - chartElement, - getChartConfiguration( - this.getTextColorFromCss(), - this.getBackgroundColorFromCss(), - ), - ); - chart.applyOptions({ - timeScale: { - fixLeftEdge: true, - rightBarStaysOnScroll: true, - }, - }); - // Create chart adjusting the size to the current div size - const lineSeries = chart.addLineSeries(); - this.occupationService.getWeeklyOccupationMock(this.refuge.id).subscribe({ - next: (response) => { - // TODO check for errors here - const occupation = response as WeeklyOccupation; - const data = occupation.weekly_data - .map((dayData) => { - return { - time: `${dayData.date.getFullYear()}-${ - dayData.date.getMonth() + 1 - }-${this.getFormattedDayDate(dayData.date)}`, - value: dayData.count, - }; - }) - .reverse(); - lineSeries.setData(data); - this.occupationService.getTodayOccupationMock().subscribe({ - next: (response) => { - const time = new Date(); - const timeString = `${time.getFullYear()}-${ - time.getMonth() + 1 - }-${this.getFormattedDayDate(time)}`; - lineSeries.update({ time: timeString, value: response }); - }, - }); - }, - }); - chart.timeScale().fitContent(); + } - private getFormattedDayDate(date: Date): string { - if (date.getDate() < 10) { - return `0${date.getDate()}`; - } - return `${date.getDate()}`; + ngAfterViewInit() { + this.verticalBarChart!.activeEntries = [ + { + name: '14', + value: 5, + }, + ]; } private getBackgroundColorFromCss(): string { diff --git a/app/src/app/components/reservations/reservations.component.html b/app/src/app/components/reservations/reservations.component.html index 35a5c3d..c2809c9 100644 --- a/app/src/app/components/reservations/reservations.component.html +++ b/app/src/app/components/reservations/reservations.component.html @@ -1,14 +1,55 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - -

- {{ "REFUGE.RESERVATIONS.HEADER" | translate }} -

-
- - - > + +

+ {{'REFUGE.RESERVATIONS.HEADER' | translate }} +

+
+ + +
- - + +
- - + + + + + + + -

- {{ "REFUGE.RESERVATIONS.HEADER" | translate }} +

+ {{'REFUGE.RESERVATIONS.HEADER' | translate }}

- - - - - - - + + - +
diff --git a/app/src/app/pages/refuge/refuge.module.ts b/app/src/app/pages/refuge/refuge.module.ts index 0775641..040c9b5 100644 --- a/app/src/app/pages/refuge/refuge.module.ts +++ b/app/src/app/pages/refuge/refuge.module.ts @@ -13,6 +13,7 @@ import { ReservationsChartComponent } from '../../components/reservations-chart/ import { ReservationsPageModule } from '../reservations/reservations.module'; import { ReservationsComponent } from '../../components/reservations/reservations.component'; import { RefugeInfoComponent } from '../../components/refuge-info/refuge-info.component'; +import {BarChartModule} from "@swimlane/ngx-charts"; @NgModule({ imports: [ @@ -22,6 +23,7 @@ import { RefugeInfoComponent } from '../../components/refuge-info/refuge-info.co RefugePageRoutingModule, TranslateModule, ReservationsPageModule, + BarChartModule ], declarations: [ RefugePage, diff --git a/app/src/app/pages/refuge/refuge.page.html b/app/src/app/pages/refuge/refuge.page.html index 6133444..fd867fc 100644 --- a/app/src/app/pages/refuge/refuge.page.html +++ b/app/src/app/pages/refuge/refuge.page.html @@ -22,7 +22,8 @@
+
- + diff --git a/app/src/app/pages/refuge/refuge.page.scss b/app/src/app/pages/refuge/refuge.page.scss index 3ae2982..78b255c 100644 --- a/app/src/app/pages/refuge/refuge.page.scss +++ b/app/src/app/pages/refuge/refuge.page.scss @@ -49,6 +49,7 @@ margin-inline: 5%; } + :host ::ng-deep .tv-lightweight-charts table { width: 95% !important; } @@ -88,3 +89,19 @@ .ios .about-info h3 { font-weight: 700; } + +:host ::ng-deep h3.ion-padding-start { + margin-top: 1px !important; + margin-bottom: 10px; + font-weight: 500; + line-height: 1.2; + padding-inline-start: 0; +} + +:host ::ng-deep h3.ion-padding-top.ion-padding-start { + margin-top: 1px !important; + margin-bottom: 10px; + font-weight: 500; + line-height: 1.2; + padding-inline-start: 15px; +} diff --git a/app/src/app/pages/refuge/refuge.page.ts b/app/src/app/pages/refuge/refuge.page.ts index cb9a2fd..dc953a6 100644 --- a/app/src/app/pages/refuge/refuge.page.ts +++ b/app/src/app/pages/refuge/refuge.page.ts @@ -22,6 +22,7 @@ export class RefugePage implements OnInit, AfterViewInit { @Input() refuge?: Refuge; @Output() clickedBar = new EventEmitter(); + constructor( private refugeService: RefugeService, private store: Store, diff --git a/app/src/assets/i18n/ca.json b/app/src/assets/i18n/ca.json index 0e6398c..761c109 100644 --- a/app/src/assets/i18n/ca.json +++ b/app/src/assets/i18n/ca.json @@ -91,11 +91,18 @@ "CAPACITY_UNITY": "{{capacity}} persones" }, "RESERVATIONS": { - "HEADER": "Fes una Reserva", - "BUTTON": "Reserva" + "HEADER": "Fer una reserva", + "BUTTON": "Reservar", + "INFO": { + "OKAY": "D'acord", + "BODY": "La majoria dels refugis en realitat no tenen un sistema de reserves. S'espera que els hostes els utilitzin quan vulguin. No obstant això, el que RefuApp intenta proporcionar és un mecanisme a través del qual els hostes poden notificar a altres usuaris de RefuApp sobre la seva intenció d'anar a un refugi en una data específica, facilitant així saber si un refugi estarà ple o no.", + "HEADER": "Aclariment sobre reserves" + } }, "OCCUPATION": { - "HISTORIAL": "Històric d'Ocupació" + "HISTORIAL": "Històric d'Ocupació", + "XLABEL": "Dia", + "YLABEL": "Reserves" } }, "RESERVATIONS": { diff --git a/app/src/assets/i18n/en.json b/app/src/assets/i18n/en.json index efdf1ec..03169d5 100644 --- a/app/src/assets/i18n/en.json +++ b/app/src/assets/i18n/en.json @@ -92,10 +92,17 @@ }, "RESERVATIONS": { "HEADER": "Make a reservation", - "BUTTON": "Reservate" + "BUTTON": "Reserve", + "INFO": { + "OKAY": "Ok", + "BODY": "Most refuges don't actually have a reservation system. Guests are expected to use them whenever they want. However, RefuApp aims to provide a mechanism through which guests can notify other RefuApp users about their intent to visit a given refuge on a specific date, making it easier to determine if a refuge will likely be full or not.", + "HEADER": "Clarification about reservations" + } }, "OCCUPATION": { - "HISTORIAL": "Occupation historic" + "HISTORIAL": "Occupation historic", + "XLABEL": "Day", + "YLABEL": "Reservations" } }, "RESERVATIONS": { diff --git a/app/src/assets/i18n/es.json b/app/src/assets/i18n/es.json index f15d4a2..e5a9f67 100644 --- a/app/src/assets/i18n/es.json +++ b/app/src/assets/i18n/es.json @@ -91,11 +91,18 @@ "CAPACITY_UNITY": "{{capacity}} personas" }, "RESERVATIONS": { - "HEADER": "Hacer una Reserva", - "BUTTON": "Reservar" + "HEADER": "Hacer una reserva", + "BUTTON": "Reservar", + "INFO": { + "OKAY": "Aceptar", + "BODY": "La mayoría de los refugios en realidad no tienen un sistema de reservas. Se espera que los huéspedes los utilicen cuando lo deseen. Sin embargo, lo que RefuApp intenta proporcionar es un mecanismo a través del cual los huéspedes pueden notificar a otros usuarios de RefuApp sobre su intención de ir a un refugio en una fecha específica, facilitando así saber si un refugio estará lleno o no.", + "HEADER": "Aclaración sobre reservas" + } }, "OCCUPATION": { - "HISTORIAL": "Histórico de Ocupación" + "HISTORIAL": "Histórico de Ocupación", + "XLABEL": "Día", + "YLABEL": "Reservas" } }, "RESERVATIONS": {