diff --git a/package-lock.json b/package-lock.json index 21c6e11..4e1e68a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,13 +6,19 @@ "": { "dependencies": { "@mdi/font": "^7.4.47", + "apexcharts": "^5.10.5", + "echarts": "^6.0.0", "flag-icons": "^7.5.0", + "maplibre-gl": "^5.22.0", + "vue-echarts": "^8.0.1", + "vue3-apexcharts": "^1.11.1", "vuetify": "^4.0.5" }, "devDependencies": { "@inertiajs/vue3": "^2.0.0", "@tailwindcss/forms": "^0.5.3", "@tailwindcss/vite": "^4.0.0", + "@types/leaflet": "^1.9.21", "@types/node": "^25.5.0", "@vitejs/plugin-vue": "^6.0.0", "autoprefixer": "^10.4.12", @@ -176,6 +182,111 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@mapbox/jsonlint-lines-primitives": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz", + "integrity": "sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@mapbox/point-geometry": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-1.1.0.tgz", + "integrity": "sha512-YGcBz1cg4ATXDCM/71L9xveh4dynfGmcLDqufR+nQQy3fKwsAZsWd/x4621/6uJaeB9mwOHE6hPeDgXz9uViUQ==", + "license": "ISC" + }, + "node_modules/@mapbox/tiny-sdf": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-2.1.0.tgz", + "integrity": "sha512-uFJhNh36BR4OCuWIEiWaEix9CA2WzT6CAIcqVjWYpnx8+QDtS+oC4QehRrx5cX4mgWs37MmKnwUejeHxVymzNg==", + "license": "BSD-2-Clause" + }, + "node_modules/@mapbox/unitbezier": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-0.0.1.tgz", + "integrity": "sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==", + "license": "BSD-2-Clause" + }, + "node_modules/@mapbox/vector-tile": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@mapbox/vector-tile/-/vector-tile-2.0.4.tgz", + "integrity": "sha512-AkOLcbgGTdXScosBWwmmD7cDlvOjkg/DetGva26pIRiZPdeJYjYKarIlb4uxVzi6bwHO6EWH82eZ5Nuv4T5DUg==", + "license": "BSD-3-Clause", + "dependencies": { + "@mapbox/point-geometry": "~1.1.0", + "@types/geojson": "^7946.0.16", + "pbf": "^4.0.1" + } + }, + "node_modules/@mapbox/whoots-js": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz", + "integrity": "sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q==", + "license": "ISC", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@maplibre/geojson-vt": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@maplibre/geojson-vt/-/geojson-vt-6.0.4.tgz", + "integrity": "sha512-HYv3POhMRCdhP3UPPATM/hfcy6/WuVIf5FKboH8u/ZuFMTnAIcSVlq5nfOqroLokd925w2QtE7YwquFOIacwVQ==", + "license": "ISC", + "dependencies": { + "kdbush": "^4.0.2" + } + }, + "node_modules/@maplibre/maplibre-gl-style-spec": { + "version": "24.8.1", + "resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-24.8.1.tgz", + "integrity": "sha512-zxa92qF96ZNojLxeAjnaRpjVCy+swoUNJvDhtpC90k7u5F0TMr4GmvNqMKvYrMoPB8d7gRSXbMG1hBbmgESIsw==", + "license": "ISC", + "dependencies": { + "@mapbox/jsonlint-lines-primitives": "~2.0.2", + "@mapbox/unitbezier": "^0.0.1", + "json-stringify-pretty-compact": "^4.0.0", + "minimist": "^1.2.8", + "quickselect": "^3.0.0", + "rw": "^1.3.3", + "tinyqueue": "^3.0.0" + }, + "bin": { + "gl-style-format": "dist/gl-style-format.mjs", + "gl-style-migrate": "dist/gl-style-migrate.mjs", + "gl-style-validate": "dist/gl-style-validate.mjs" + } + }, + "node_modules/@maplibre/mlt": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@maplibre/mlt/-/mlt-1.1.8.tgz", + "integrity": "sha512-8vtfYGidr1rNkv5IwIoU2lfe3Oy+Wa8HluzQYcQi9cveU9K3pweAal/poQj4GJ0K/EW4bTQp2wVAs09g2yDRZg==", + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "@mapbox/point-geometry": "^1.1.0" + } + }, + "node_modules/@maplibre/vt-pbf": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@maplibre/vt-pbf/-/vt-pbf-4.3.0.tgz", + "integrity": "sha512-jIvp8F5hQCcreqOOpEt42TJMUlsrEcpf/kI1T2v85YrQRV6PPXUcEXUg5karKtH6oh47XJZ4kHu56pUkOuqA7w==", + "license": "MIT", + "dependencies": { + "@mapbox/point-geometry": "^1.1.0", + "@mapbox/vector-tile": "^2.0.4", + "@maplibre/geojson-vt": "^5.0.4", + "@types/geojson": "^7946.0.16", + "@types/supercluster": "^7.1.3", + "pbf": "^4.0.1", + "supercluster": "^8.0.1" + } + }, + "node_modules/@maplibre/vt-pbf/node_modules/@maplibre/geojson-vt": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@maplibre/geojson-vt/-/geojson-vt-5.0.4.tgz", + "integrity": "sha512-KGg9sma45S+stfH9vPCJk1J0lSDLWZgCT9Y8u8qWZJyjFlP8MNP1WGTxIMYJZjDvVT3PDn05kN1C95Sut1HpgQ==", + "license": "ISC" + }, "node_modules/@mdi/font": { "version": "7.4.47", "resolved": "https://registry.npmjs.org/@mdi/font/-/font-7.4.47.tgz", @@ -804,6 +915,22 @@ "tslib": "^2.4.0" } }, + "node_modules/@types/geojson": { + "version": "7946.0.16", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", + "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", + "license": "MIT" + }, + "node_modules/@types/leaflet": { + "version": "1.9.21", + "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.21.tgz", + "integrity": "sha512-TbAd9DaPGSnzp6QvtYngntMZgcRk+igFELwR2N99XZn7RXUdKgsXMR+28bUO0rPsWp8MIu/f47luLIQuSLYv/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/geojson": "*" + } + }, "node_modules/@types/lodash": { "version": "4.17.24", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.24.tgz", @@ -832,6 +959,15 @@ "undici-types": "~7.18.0" } }, + "node_modules/@types/supercluster": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@types/supercluster/-/supercluster-7.1.3.tgz", + "integrity": "sha512-Z0pOY34GDFl3Q6hUFYf3HkTwKEE02e7QgtJppBt+beEAxnyOpJua+voGFvxINBHa06GwLFFym7gRPY2SiKIfIA==", + "license": "MIT", + "dependencies": { + "@types/geojson": "*" + } + }, "node_modules/@vitejs/plugin-vue": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.5.tgz", @@ -1030,6 +1166,13 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/apexcharts": { + "version": "5.10.5", + "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-5.10.5.tgz", + "integrity": "sha512-RirosfLQLqYpWBdn4Pdv9B1M0M2FepzVxPRpcuXQPTilvuZvKt02vgVlEexhCVu2p4fApDIV/3yC9voAIK+qjw==", + "license": "SEE LICENSE IN LICENSE", + "peer": true + }, "node_modules/arg": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", @@ -2499,6 +2642,28 @@ "node": ">= 0.4" } }, + "node_modules/earcut": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.2.tgz", + "integrity": "sha512-X7hshQbLyMJ/3RPhyObLARM2sNxxmRALLKx1+NVFFnQ9gKzmCrxm9+uLIAdBcvc8FNLpctqlQ2V6AE92Ol9UDQ==", + "license": "ISC" + }, + "node_modules/echarts": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/echarts/-/echarts-6.0.0.tgz", + "integrity": "sha512-Tte/grDQRiETQP4xz3iZWSvoHrkCQtwqd6hs+mifXcjrCuo2iKWbajFObuLJVBlDIJlOzgQPd1hsaKt/3+OMkQ==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "2.3.0", + "zrender": "6.0.0" + } + }, + "node_modules/echarts/node_modules/tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", + "license": "0BSD" + }, "node_modules/electron-to-chromium": { "version": "1.5.331", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.331.tgz", @@ -2835,6 +3000,12 @@ "node": ">= 0.4" } }, + "node_modules/gl-matrix": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.4.4.tgz", + "integrity": "sha512-latSnyDNt/8zYUB6VIJ6PCh2jBjJX6gnDsoCZ7LyW7GkqrD51EWwa9qCoGixj8YqBtETQK/xY7OmpTF8xz1DdQ==", + "license": "MIT" + }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -3096,6 +3267,12 @@ "jsesc": "bin/jsesc" } }, + "node_modules/json-stringify-pretty-compact": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-4.0.0.tgz", + "integrity": "sha512-3CNZ2DnrpByG9Nqj6Xo8vqbjT4F6N+tb4Gb28ESAZjYZ5yqvmc56J+/kuIwkaAMOyblTQhUW7PxMkUb8Q36N3Q==", + "license": "MIT" + }, "node_modules/json5": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", @@ -3106,6 +3283,12 @@ "json5": "lib/cli.js" } }, + "node_modules/kdbush": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz", + "integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==", + "license": "ISC" + }, "node_modules/laravel-precognition": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/laravel-precognition/-/laravel-precognition-1.0.2.tgz", @@ -3455,6 +3638,40 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, + "node_modules/maplibre-gl": { + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-5.22.0.tgz", + "integrity": "sha512-nc8YA+YSEioMZg5W0cb6Cf3wQ8aJge66dsttyBgpOArOnlmFJO1Kc5G32kYVPeUYhLpBja83T99uanmJvYAIyQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@mapbox/jsonlint-lines-primitives": "^2.0.2", + "@mapbox/point-geometry": "^1.1.0", + "@mapbox/tiny-sdf": "^2.0.7", + "@mapbox/unitbezier": "^0.0.1", + "@mapbox/vector-tile": "^2.0.4", + "@mapbox/whoots-js": "^3.1.0", + "@maplibre/geojson-vt": "^6.0.4", + "@maplibre/maplibre-gl-style-spec": "^24.8.1", + "@maplibre/mlt": "^1.1.8", + "@maplibre/vt-pbf": "^4.3.0", + "@types/geojson": "^7946.0.16", + "earcut": "^3.0.2", + "gl-matrix": "^3.4.4", + "kdbush": "^4.0.2", + "murmurhash-js": "^1.0.0", + "pbf": "^4.0.1", + "potpack": "^2.1.0", + "quickselect": "^3.0.0", + "tinyqueue": "^3.0.0" + }, + "engines": { + "node": ">=16.14.0", + "npm": ">=8.1.0" + }, + "funding": { + "url": "https://github.com/maplibre/maplibre-gl-js?sponsor=1" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -3552,7 +3769,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3578,6 +3794,12 @@ "dev": true, "license": "MIT" }, + "node_modules/murmurhash-js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/murmurhash-js/-/murmurhash-js-1.0.0.tgz", + "integrity": "sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw==", + "license": "MIT" + }, "node_modules/mz": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", @@ -3695,6 +3917,18 @@ "dev": true, "license": "MIT" }, + "node_modules/pbf": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pbf/-/pbf-4.0.1.tgz", + "integrity": "sha512-SuLdBvS42z33m8ejRbInMapQe8n0D3vN/Xd5fmWM3tufNgRQFBpaW2YVJxQZV4iPNqb0vEFvssMEo5w9c6BTIA==", + "license": "BSD-3-Clause", + "dependencies": { + "resolve-protobuf-schema": "^2.1.0" + }, + "bin": { + "pbf": "bin/pbf" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -3898,6 +4132,12 @@ "dev": true, "license": "MIT" }, + "node_modules/potpack": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/potpack/-/potpack-2.1.0.tgz", + "integrity": "sha512-pcaShQc1Shq0y+E7GqJqvZj8DTthWV1KeHGdi0Z6IAin2Oi3JnLCOfwnCo84qc+HAp52wT9nK9H7FAJp5a44GQ==", + "license": "ISC" + }, "node_modules/private": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", @@ -3908,6 +4148,12 @@ "node": ">= 0.6" } }, + "node_modules/protocol-buffers-schema": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.1.tgz", + "integrity": "sha512-VG2K63Igkiv9p76tk1lilczEK1cT+kCjKtkdhw1dQZV3k3IXJbd3o6Ho8b9zJZaHSnT2hKe4I+ObmX9w6m5SmQ==", + "license": "MIT" + }, "node_modules/proxy-from-env": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", @@ -3962,6 +4208,12 @@ ], "license": "MIT" }, + "node_modules/quickselect": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz", + "integrity": "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==", + "license": "ISC" + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -4109,6 +4361,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-protobuf-schema": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz", + "integrity": "sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==", + "license": "MIT", + "dependencies": { + "protocol-buffers-schema": "^3.3.1" + } + }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", @@ -4178,6 +4439,12 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", + "license": "BSD-3-Clause" + }, "node_modules/rxjs": { "version": "7.8.2", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", @@ -4390,6 +4657,15 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/supercluster": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-8.0.1.tgz", + "integrity": "sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==", + "license": "ISC", + "dependencies": { + "kdbush": "^4.0.2" + } + }, "node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -4522,6 +4798,12 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, + "node_modules/tinyqueue": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-3.0.0.tgz", + "integrity": "sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==", + "license": "ISC" + }, "node_modules/to-fast-properties": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", @@ -4821,6 +5103,31 @@ } } }, + "node_modules/vue-echarts": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/vue-echarts/-/vue-echarts-8.0.1.tgz", + "integrity": "sha512-23rJTFLu1OUEGRWjJGmdGt8fP+8+ja1gVgzMYPIPaHWpXegcO1viIAaeu2H4QHESlVeHzUAHIxKXGrwjsyXAaA==", + "license": "MIT", + "peerDependencies": { + "echarts": "^6.0.0", + "vue": "^3.3.0" + } + }, + "node_modules/vue3-apexcharts": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/vue3-apexcharts/-/vue3-apexcharts-1.11.1.tgz", + "integrity": "sha512-MbN3vg8bMG19wc0Lm1HkeQvODgLm56DgpIxtNUO0xpf/JCzYWVGE4jzXp2JISzy2s3Kul1yOxNQUYsLvKQ5L9g==", + "license": "see LICENSE in LICENSE", + "peerDependencies": { + "apexcharts": ">=5.10.0", + "vue": ">=3.0.0" + }, + "peerDependenciesMeta": { + "apexcharts": { + "optional": false + } + } + }, "node_modules/vuetify": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/vuetify/-/vuetify-4.0.5.tgz", @@ -4925,6 +5232,21 @@ "engines": { "node": ">=12" } + }, + "node_modules/zrender": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/zrender/-/zrender-6.0.0.tgz", + "integrity": "sha512-41dFXEEXuJpNecuUQq6JlbybmnHaqqpGlbH1yxnA5V9MMP4SbohSVZsJIwz+zdjQXSSlR1Vc34EgH1zxyTDvhg==", + "license": "BSD-3-Clause", + "dependencies": { + "tslib": "2.3.0" + } + }, + "node_modules/zrender/node_modules/tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", + "license": "0BSD" } } } diff --git a/package.json b/package.json index 32e267e..5317a09 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "@inertiajs/vue3": "^2.0.0", "@tailwindcss/forms": "^0.5.3", "@tailwindcss/vite": "^4.0.0", + "@types/leaflet": "^1.9.21", "@types/node": "^25.5.0", "@vitejs/plugin-vue": "^6.0.0", "autoprefixer": "^10.4.12", @@ -27,7 +28,12 @@ }, "dependencies": { "@mdi/font": "^7.4.47", + "apexcharts": "^5.10.5", + "echarts": "^6.0.0", "flag-icons": "^7.5.0", + "maplibre-gl": "^5.22.0", + "vue-echarts": "^8.0.1", + "vue3-apexcharts": "^1.11.1", "vuetify": "^4.0.5" } } diff --git a/resources/css/app.css b/resources/css/app.css index 6e187ad..a985000 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -23,7 +23,7 @@ a { .glass { - background: rgba(17, 24, 39, 0.2); /* --surface at 60% */ + background: rgb(0 12 41 / 0.6); -webkit-backdrop-filter: blur(12px) saturate(180%); backdrop-filter: blur(12px) saturate(180%); box-shadow: 0 4px 24px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(56, 189, 248, 0.05); diff --git a/resources/js/Components/FlightsGoneBy/AirlineSearchBox.vue b/resources/js/Components/FlightsGoneBy/AirlineSearchBox.vue index 7e58106..2b3cd6b 100644 --- a/resources/js/Components/FlightsGoneBy/AirlineSearchBox.vue +++ b/resources/js/Components/FlightsGoneBy/AirlineSearchBox.vue @@ -64,7 +64,7 @@ const searchAirlines = async (query: string) => { diff --git a/resources/js/Components/FlightsGoneBy/Charts/CountriesChart.vue b/resources/js/Components/FlightsGoneBy/Charts/CountriesChart.vue new file mode 100644 index 0000000..02421c1 --- /dev/null +++ b/resources/js/Components/FlightsGoneBy/Charts/CountriesChart.vue @@ -0,0 +1,213 @@ + + + + + diff --git a/resources/js/Components/FlightsGoneBy/Charts/FlightClassChart.vue b/resources/js/Components/FlightsGoneBy/Charts/FlightClassChart.vue new file mode 100644 index 0000000..887f6fb --- /dev/null +++ b/resources/js/Components/FlightsGoneBy/Charts/FlightClassChart.vue @@ -0,0 +1,112 @@ + + + + + diff --git a/resources/js/Components/FlightsGoneBy/Charts/FlightReasonsChart.vue b/resources/js/Components/FlightsGoneBy/Charts/FlightReasonsChart.vue new file mode 100644 index 0000000..8f85141 --- /dev/null +++ b/resources/js/Components/FlightsGoneBy/Charts/FlightReasonsChart.vue @@ -0,0 +1,112 @@ + + + + + diff --git a/resources/js/Components/FlightsGoneBy/Charts/FlightsPerMonthChart.vue b/resources/js/Components/FlightsGoneBy/Charts/FlightsPerMonthChart.vue new file mode 100644 index 0000000..c631ceb --- /dev/null +++ b/resources/js/Components/FlightsGoneBy/Charts/FlightsPerMonthChart.vue @@ -0,0 +1,103 @@ + + + + + diff --git a/resources/js/Components/FlightsGoneBy/Charts/FlightsPerYearChart.vue b/resources/js/Components/FlightsGoneBy/Charts/FlightsPerYearChart.vue new file mode 100644 index 0000000..f3b2f18 --- /dev/null +++ b/resources/js/Components/FlightsGoneBy/Charts/FlightsPerYearChart.vue @@ -0,0 +1,118 @@ + + + + + diff --git a/resources/js/Components/FlightsGoneBy/Charts/SeatTypeChart.vue b/resources/js/Components/FlightsGoneBy/Charts/SeatTypeChart.vue new file mode 100644 index 0000000..f5a4ccf --- /dev/null +++ b/resources/js/Components/FlightsGoneBy/Charts/SeatTypeChart.vue @@ -0,0 +1,112 @@ + + + + + diff --git a/resources/js/Components/FlightsGoneBy/Charts/TopAirlinesChart.vue b/resources/js/Components/FlightsGoneBy/Charts/TopAirlinesChart.vue new file mode 100644 index 0000000..2ffe71a --- /dev/null +++ b/resources/js/Components/FlightsGoneBy/Charts/TopAirlinesChart.vue @@ -0,0 +1,195 @@ + + + + + diff --git a/resources/js/Components/FlightsGoneBy/Charts/TopAirportsChart.vue b/resources/js/Components/FlightsGoneBy/Charts/TopAirportsChart.vue new file mode 100644 index 0000000..0abbf34 --- /dev/null +++ b/resources/js/Components/FlightsGoneBy/Charts/TopAirportsChart.vue @@ -0,0 +1,289 @@ + + + + + diff --git a/resources/js/Components/FlightsGoneBy/Charts/TopRoutesChart.vue b/resources/js/Components/FlightsGoneBy/Charts/TopRoutesChart.vue new file mode 100644 index 0000000..85af715 --- /dev/null +++ b/resources/js/Components/FlightsGoneBy/Charts/TopRoutesChart.vue @@ -0,0 +1,11 @@ + + + + + diff --git a/resources/js/Components/FlightsGoneBy/DepartureBoard.vue b/resources/js/Components/FlightsGoneBy/DepartureBoard.vue index 7694be8..b86c0b2 100644 --- a/resources/js/Components/FlightsGoneBy/DepartureBoard.vue +++ b/resources/js/Components/FlightsGoneBy/DepartureBoard.vue @@ -21,6 +21,8 @@ const headers = [ { title: 'DATE', key: 'departure_date', sortable: true }, { title: 'DEPART', key: 'departure_time_display', sortable: false }, { title: 'ARRIVE', key: 'arrival_time_display', sortable: false }, + { title: 'DURATION', key: 'duration', sortable: true }, + { title: 'DISTANCE', key: 'distance', sortable: true }, { title: 'AIRCRAFT', key: 'aircraft.designator', sortable: true }, { title: 'CLASS', key: 'flight_class', sortable: true }, ] @@ -40,7 +42,8 @@ const customKeySort = { }, airline: (a: Flight['airline'], b: Flight['airline']) => { return (a?.IATA_code ?? '').localeCompare(b?.IATA_code ?? '') - } + }, + duration: (a: any, b: any) => (a ?? 0) - (b ?? 0), } // Track active sort state @@ -176,6 +179,17 @@ const tableItems = computed(() => + + {{ (item as Flight).duration_display ?? '—' }} + + + + + + {{ (item as Flight).distance ? Math.round((item as Flight).distance).toLocaleString() + ' km' : '' }} + + + diff --git a/resources/js/Components/FlightsGoneBy/FlightCharts.vue b/resources/js/Components/FlightsGoneBy/FlightCharts.vue new file mode 100644 index 0000000..c65e154 --- /dev/null +++ b/resources/js/Components/FlightsGoneBy/FlightCharts.vue @@ -0,0 +1,74 @@ + + + + + diff --git a/resources/js/Components/FlightsGoneBy/FlightMap.vue b/resources/js/Components/FlightsGoneBy/FlightMap.vue new file mode 100644 index 0000000..e1dda2c --- /dev/null +++ b/resources/js/Components/FlightsGoneBy/FlightMap.vue @@ -0,0 +1,568 @@ + + + + + + + diff --git a/resources/js/Components/FlightsGoneBy/FlightStatsBar.vue b/resources/js/Components/FlightsGoneBy/FlightStatsBar.vue new file mode 100644 index 0000000..7608053 --- /dev/null +++ b/resources/js/Components/FlightsGoneBy/FlightStatsBar.vue @@ -0,0 +1,285 @@ + + + + + diff --git a/resources/js/Components/FlightsGoneBy/ProfileMap.vue b/resources/js/Components/FlightsGoneBy/ProfileMap.vue new file mode 100644 index 0000000..568cbb9 --- /dev/null +++ b/resources/js/Components/FlightsGoneBy/ProfileMap.vue @@ -0,0 +1,203 @@ + + + + + diff --git a/resources/js/Components/FlightsGoneBy/Radar.vue b/resources/js/Components/FlightsGoneBy/Radar.vue index 1c5457c..3e52096 100644 --- a/resources/js/Components/FlightsGoneBy/Radar.vue +++ b/resources/js/Components/FlightsGoneBy/Radar.vue @@ -70,7 +70,9 @@ - +
+ +
@@ -82,6 +84,7 @@ position: relative; min-height: 100dvh; background: var(--bg); + isolation: isolate; } .radar-svg { position: absolute; @@ -90,6 +93,12 @@ height: 100%; opacity:0.1; pointer-events: none; + z-index: 0 +} + +.radar-content { + position: relative; + z-index: 1; } .ring { fill: none; stroke: rgba(56,189,248,0.12); stroke-width: 1; } diff --git a/resources/js/Layouts/MainLayout.vue b/resources/js/Layouts/MainLayout.vue index f22f6f6..51da2b5 100644 --- a/resources/js/Layouts/MainLayout.vue +++ b/resources/js/Layouts/MainLayout.vue @@ -33,7 +33,6 @@ router.on('success', () => { display: flex; flex-direction: column; min-height: 100dvh; - background: var(--bg); color: var(--text); overflow-y: auto; } diff --git a/resources/js/Pages/FlightProfile.vue b/resources/js/Pages/FlightProfile.vue index 2142f06..dc24e1c 100644 --- a/resources/js/Pages/FlightProfile.vue +++ b/resources/js/Pages/FlightProfile.vue @@ -5,6 +5,7 @@ import { Flight } from "@/Types/types"; import DepartureBoard from "@/Components/FlightsGoneBy/DepartureBoard.vue"; import BoardingPasses from "@/Components/FlightsGoneBy/BoardingPasses.vue"; import { ref } from "vue"; +import ProfileMap from "@/Components/FlightsGoneBy/ProfileMap.vue"; defineOptions({ layout: MainLayout @@ -19,8 +20,8 @@ defineProps<{ flights: Flight[] }>() -type View = 'board' | 'passes' -const activeView = ref('board') +type View = 'board' | 'passes' | 'map' +const activeView = ref('map') @@ -69,7 +79,6 @@ const activeView = ref('board') /* ── Wrapper ── */ .board-wrapper { min-height: 100dvh; - background: #0d0f14; padding: 2.5rem 2rem; font-family: 'Barlow', sans-serif; width: 100%; diff --git a/resources/js/app.ts b/resources/js/app.ts index 6e0546d..7045432 100644 --- a/resources/js/app.ts +++ b/resources/js/app.ts @@ -8,6 +8,8 @@ import { createApp, h, DefineComponent } from 'vue'; import vuetify from './plugins/vuetify'; import '@mdi/font/css/materialdesignicons.css' import 'flag-icons/css/flag-icons.min.css' +import VueApexCharts from 'vue3-apexcharts' + const appName = document.querySelector('meta[name="app-name"]')?.getAttribute('content') || 'Laravel'; @@ -23,6 +25,7 @@ createInertiaApp({ .use(plugin) .use(ZiggyVue) .use(vuetify) + .use(VueApexCharts) .mount(el); }, progress: {