diff --git a/.gitignore b/.gitignore index 42e78ef..ddaf2c7 100644 --- a/.gitignore +++ b/.gitignore @@ -135,3 +135,5 @@ storybook-static *storybook.log .DS_Store + +vite.config.ts.timestamp* diff --git a/package-lock.json b/package-lock.json index 0664fb6..9685907 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,9 @@ "@chromatic-com/storybook": "1.3.3", "@emotion/react": "11.11.4", "@emotion/styled": "11.11.5", + "@fullcalendar/daygrid": "^6.1.15", + "@fullcalendar/react": "^6.1.15", + "@fullcalendar/timegrid": "^6.1.15", "@mui/material": "5.15.15", "@mui/x-date-pickers-pro": "^7.8.0", "@snyk/protect": "latest", @@ -28,6 +31,7 @@ "@storybook/test": "8.0.10", "@testing-library/jest-dom": "6.4.2", "@testing-library/react": "15.0.2", + "@turf/bbox": "^7.0.0", "@types/react": "18.2.79", "@types/react-dom": "18", "@typescript-eslint/eslint-plugin": "7.7.0", @@ -46,9 +50,11 @@ "husky": "^9.0.11", "jsdom": "24.0.0", "lodash": "4.17.21", + "mapbox-gl": "^3.5.2", "moment": "^2.30.1", "postcss": "8.4.38", "prettier": "3.2.5", + "react-map-gl": "^7.1.7", "storybook": "^8.1.11", "vite": "5.2.9", "vite-plugin-dts": "3.8.3", @@ -2359,6 +2365,48 @@ "dev": true, "license": "MIT" }, + "node_modules/@fullcalendar/core": { + "version": "6.1.15", + "resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-6.1.15.tgz", + "integrity": "sha512-BuX7o6ALpLb84cMw1FCB9/cSgF4JbVO894cjJZ6kP74jzbUZNjtwffwRdA+Id8rrLjT30d/7TrkW90k4zbXB5Q==", + "dev": true, + "peer": true, + "dependencies": { + "preact": "~10.12.1" + } + }, + "node_modules/@fullcalendar/daygrid": { + "version": "6.1.15", + "resolved": "https://registry.npmjs.org/@fullcalendar/daygrid/-/daygrid-6.1.15.tgz", + "integrity": "sha512-j8tL0HhfiVsdtOCLfzK2J0RtSkiad3BYYemwQKq512cx6btz6ZZ2RNc/hVnIxluuWFyvx5sXZwoeTJsFSFTEFA==", + "dev": true, + "peerDependencies": { + "@fullcalendar/core": "~6.1.15" + } + }, + "node_modules/@fullcalendar/react": { + "version": "6.1.15", + "resolved": "https://registry.npmjs.org/@fullcalendar/react/-/react-6.1.15.tgz", + "integrity": "sha512-L0b9hybS2J4e7lq6G2CD4nqriyLEqOH1tE8iI6JQjAMTVh5JicOo5Mqw+fhU5bJ7hLfMw2K3fksxX3Ul1ssw5w==", + "dev": true, + "peerDependencies": { + "@fullcalendar/core": "~6.1.15", + "react": "^16.7.0 || ^17 || ^18 || ^19", + "react-dom": "^16.7.0 || ^17 || ^18 || ^19" + } + }, + "node_modules/@fullcalendar/timegrid": { + "version": "6.1.15", + "resolved": "https://registry.npmjs.org/@fullcalendar/timegrid/-/timegrid-6.1.15.tgz", + "integrity": "sha512-61ORr3A148RtxQ2FNG7JKvacyA/TEVZ7z6I+3E9Oeu3dqTf6M928bFcpehRTIK6zIA6Yifs7BeWHgOE9dFnpbw==", + "dev": true, + "dependencies": { + "@fullcalendar/daygrid": "~6.1.15" + }, + "peerDependencies": { + "@fullcalendar/core": "~6.1.15" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", "dev": true, @@ -2561,6 +2609,76 @@ "@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==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@mapbox/mapbox-gl-supported": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-3.0.0.tgz", + "integrity": "sha512-2XghOwu16ZwPJLOFVuIOaLbN0iKMn867evzXFyf0P22dqugezfJwLmdanAgU25ITvz1TvOfVP4jsDImlDJzcWg==", + "dev": true + }, + "node_modules/@mapbox/point-geometry": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz", + "integrity": "sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ==", + "dev": true + }, + "node_modules/@mapbox/tiny-sdf": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-2.0.6.tgz", + "integrity": "sha512-qMqa27TLw+ZQz5Jk+RcwZGH7BQf5G/TrutJhspsca/3SHwmgKQ1iq+d3Jxz5oysPVYTGP6aXxCo5Lk9Er6YBAA==", + "dev": true + }, + "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==", + "dev": true + }, + "node_modules/@mapbox/vector-tile": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@mapbox/vector-tile/-/vector-tile-1.3.1.tgz", + "integrity": "sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw==", + "dev": true, + "dependencies": { + "@mapbox/point-geometry": "~0.1.0" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@maplibre/maplibre-gl-style-spec": { + "version": "19.3.3", + "resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-19.3.3.tgz", + "integrity": "sha512-cOZZOVhDSulgK0meTsTkmNXb1ahVvmTmWmfx9gRBwc6hq98wS9JP35ESIoNq3xqEan+UN+gn8187Z6E4NKhLsw==", + "dev": true, + "dependencies": { + "@mapbox/jsonlint-lines-primitives": "~2.0.2", + "@mapbox/unitbezier": "^0.0.1", + "json-stringify-pretty-compact": "^3.0.0", + "minimist": "^1.2.8", + "rw": "^1.3.3", + "sort-object": "^3.0.3" + }, + "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/@mdx-js/react": { "version": "3.0.1", "dev": true, @@ -4777,6 +4895,57 @@ "@testing-library/dom": ">=7.21.4" } }, + "node_modules/@turf/bbox": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@turf/bbox/-/bbox-7.0.0.tgz", + "integrity": "sha512-IyXG5HAsn6IZLdAtQo7aWYccjU5WsV+uzIzhGaXrh/qTVylSYmRiWgLdiekHZVED9nv9r7D/EJUMOT4zyA6POA==", + "dev": true, + "dependencies": { + "@turf/helpers": "^7.0.0", + "@turf/meta": "^7.0.0", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/bbox/node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "dev": true + }, + "node_modules/@turf/helpers": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@turf/helpers/-/helpers-7.0.0.tgz", + "integrity": "sha512-vwZvxRuyjGpGXvhXSbT9mX6FK92dBMLWbMbDJ/MXQUPx17ReVPFc+6N6IcxAzZfkiCnqy7vpuq0c+/TTrQxIiA==", + "dev": true, + "dependencies": { + "deep-equal": "^2.2.3", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/helpers/node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "dev": true + }, + "node_modules/@turf/meta": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@turf/meta/-/meta-7.0.0.tgz", + "integrity": "sha512-cEXr13uFwhXq5mFBy0IK1U/QepE5qgk3zXpBYsla3lYV7cB83Vh+NNUR+r0/w/QoJqest1TG4H20F9tGYWPi/g==", + "dev": true, + "dependencies": { + "@turf/helpers": "^7.0.0" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, "node_modules/@types/argparse": { "version": "1.0.38", "dev": true, @@ -4907,6 +5076,12 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/geojson": { + "version": "7946.0.14", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz", + "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==", + "dev": true + }, "node_modules/@types/glob": { "version": "7.2.0", "dev": true, @@ -4944,6 +5119,32 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/mapbox__point-geometry": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@types/mapbox__point-geometry/-/mapbox__point-geometry-0.1.4.tgz", + "integrity": "sha512-mUWlSxAmYLfwnRBmgYV86tgYmMIICX4kza8YnE/eIlywGe2XoOxlpVnXWwir92xRLjwyarqwpu2EJKD2pk0IUA==", + "dev": true + }, + "node_modules/@types/mapbox__vector-tile": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@types/mapbox__vector-tile/-/mapbox__vector-tile-1.3.4.tgz", + "integrity": "sha512-bpd8dRn9pr6xKvuEBQup8pwQfD4VUyqO/2deGjfpe6AwC8YRlyEipvefyRJUSiCJTZuCb8Pl1ciVV5ekqJ96Bg==", + "dev": true, + "dependencies": { + "@types/geojson": "*", + "@types/mapbox__point-geometry": "*", + "@types/pbf": "*" + } + }, + "node_modules/@types/mapbox-gl": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@types/mapbox-gl/-/mapbox-gl-3.4.0.tgz", + "integrity": "sha512-tbn++Mm94H1kE7W6FF0oVC9rMXHVzDDNUbS7KfBMRF8NV/8csFi+67ytKcZJ4LsrpsJ+8MC6Os6ZinEDCsrunw==", + "dev": true, + "dependencies": { + "@types/geojson": "*" + } + }, "node_modules/@types/mdx": { "version": "2.0.13", "dev": true, @@ -4972,6 +5173,12 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/pbf": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.5.tgz", + "integrity": "sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA==", + "dev": true + }, "node_modules/@types/prop-types": { "version": "15.7.12", "dev": true, @@ -5798,6 +6005,15 @@ "deep-equal": "^2.0.5" } }, + "node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/array-buffer-byte-length": { "version": "1.0.1", "dev": true, @@ -5981,6 +6197,15 @@ "node": "*" } }, + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ast-types": { "version": "0.16.1", "dev": true, @@ -6322,6 +6547,25 @@ "node": ">= 0.8" } }, + "node_modules/bytewise": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/bytewise/-/bytewise-1.1.0.tgz", + "integrity": "sha512-rHuuseJ9iQ0na6UDhnrRVDh8YnWVlU6xM3VH6q/+yHDeUH2zIhUzP+2/h3LIrhLDBtTqzWpE3p3tP/boefskKQ==", + "dev": true, + "dependencies": { + "bytewise-core": "^1.2.2", + "typewise": "^1.0.3" + } + }, + "node_modules/bytewise-core": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bytewise-core/-/bytewise-core-1.2.3.tgz", + "integrity": "sha512-nZD//kc78OOxeYtRlVk8/zXqTB4gf/nlguL1ggWA8FuchMyOxcyHR4QPQZMUmA7czC+YnaBrPUCubqAWe50DaA==", + "dev": true, + "dependencies": { + "typewise-core": "^1.2" + } + }, "node_modules/cac": { "version": "6.7.14", "dev": true, @@ -6424,6 +6668,12 @@ "node": ">=0.8.0" } }, + "node_modules/cheap-ruler": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cheap-ruler/-/cheap-ruler-4.0.0.tgz", + "integrity": "sha512-0BJa8f4t141BYKQyn9NSQt1PguFQXMXwZiA5shfoaBYHAb2fFk2RAX+tiWMoQU+Agtzt3mdt0JtuyshAXqZ+Vw==", + "dev": true + }, "node_modules/check-error": { "version": "1.0.3", "dev": true, @@ -6739,6 +6989,12 @@ "dev": true, "license": "MIT" }, + "node_modules/csscolorparser": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz", + "integrity": "sha512-umPSgYwZkdFoUrH5hIq5kf0wPSXiro51nPw0j2K/c83KflkPSTBGMz6NJvMB+07VlL0y7VPo6QJcDjcgKTTm3w==", + "dev": true + }, "node_modules/cssesc": { "version": "3.0.0", "license": "MIT", @@ -7090,6 +7346,12 @@ "node": ">=12" } }, + "node_modules/earcut": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.0.tgz", + "integrity": "sha512-41Fs7Q/PLq1SDbqjsgcY7GA42T0jvaCNGXgGtsNdvg+Yv8eIu06bxv4/PoREkZ9nMDNwnUSG9OFB9+yv8eKhDg==", + "dev": true + }, "node_modules/eastasianwidth": { "version": "0.2.0", "license": "MIT" @@ -8304,6 +8566,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "dev": true, @@ -8364,6 +8638,12 @@ "walk-up-path": "^3.0.1" } }, + "node_modules/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "dev": true + }, "node_modules/file-entry-cache": { "version": "6.0.1", "dev": true, @@ -8740,6 +9020,12 @@ "node": ">=6.9.0" } }, + "node_modules/geojson-vt": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-4.0.2.tgz", + "integrity": "sha512-AV9ROqlNqoZEIJGfm1ncNjEXfkz2hdFlZf0qkVfmkwdKa8vj7H16YUOT81rJw1rdFhyEDlN2Tds91p/glzbl5A==", + "dev": true + }, "node_modules/get-func-name": { "version": "2.0.2", "dev": true, @@ -8793,6 +9079,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/giget": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/giget/-/giget-1.2.3.tgz", @@ -8817,6 +9112,12 @@ "dev": true, "license": "ISC" }, + "node_modules/gl-matrix": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.4.3.tgz", + "integrity": "sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA==", + "dev": true + }, "node_modules/glob": { "version": "10.3.12", "license": "ISC", @@ -8915,6 +9216,12 @@ "dev": true, "license": "MIT" }, + "node_modules/grid-index": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/grid-index/-/grid-index-1.1.0.tgz", + "integrity": "sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA==", + "dev": true + }, "node_modules/handlebars": { "version": "4.7.8", "dev": true, @@ -9423,6 +9730,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "license": "MIT", @@ -9946,6 +10262,12 @@ "dev": true, "license": "MIT" }, + "node_modules/json-stringify-pretty-compact": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-3.0.0.tgz", + "integrity": "sha512-Rc2suX5meI0S3bfdZuA7JMFBGkJ875ApfVyq2WHELjBiiG22My/l7/8zPpH/CfFVQHuVLd8NLR0nv6vi0BYYKA==", + "dev": true + }, "node_modules/json5": { "version": "2.2.3", "dev": true, @@ -9982,6 +10304,12 @@ "node": ">=4.0" } }, + "node_modules/kdbush": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz", + "integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==", + "dev": true + }, "node_modules/keyv": { "version": "4.5.4", "dev": true, @@ -10115,6 +10443,12 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", + "dev": true + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -10265,6 +10599,43 @@ "dev": true, "license": "MIT" }, + "node_modules/mapbox-gl": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-3.5.2.tgz", + "integrity": "sha512-KUrmDmLFKPp3MSsWGNTH5uvtYwJknV+eFJ+vxiN6hqKpzbme37z+JfYs5Mehs3CgFaIV/pUdnEV9UPUZJPuS+Q==", + "dev": true, + "dependencies": { + "@mapbox/jsonlint-lines-primitives": "^2.0.2", + "@mapbox/mapbox-gl-supported": "^3.0.0", + "@mapbox/point-geometry": "^0.1.0", + "@mapbox/tiny-sdf": "^2.0.6", + "@mapbox/unitbezier": "^0.0.1", + "@mapbox/vector-tile": "^1.3.1", + "@mapbox/whoots-js": "^3.1.0", + "@types/geojson": "^7946.0.14", + "@types/mapbox__vector-tile": "^1.3.4", + "cheap-ruler": "^4.0.0", + "csscolorparser": "~1.0.3", + "earcut": "^3.0.0", + "fflate": "^0.8.1", + "geojson-vt": "^4.0.2", + "gl-matrix": "^3.4.3", + "grid-index": "^1.1.0", + "kdbush": "^4.0.2", + "lodash.clonedeep": "^4.5.0", + "murmurhash-js": "^1.0.0", + "pbf": "^3.2.1", + "potpack": "^2.0.0", + "quickselect": "^3.0.0", + "rw": "^1.3.3", + "serialize-to-js": "^3.1.2", + "supercluster": "^8.0.1", + "tiny-lru": "^11.2.11", + "tinyqueue": "^3.0.0", + "tweakpane": "^4.0.4", + "vt-pbf": "^3.1.3" + } + }, "node_modules/markdown-to-jsx": { "version": "7.3.2", "dev": true, @@ -10487,6 +10858,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==", + "dev": true + }, "node_modules/mz": { "version": "2.7.0", "license": "MIT", @@ -11255,6 +11632,19 @@ "node": "*" } }, + "node_modules/pbf": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.3.0.tgz", + "integrity": "sha512-XDF38WCH3z5OV/OVa8GKUNtLAyneuzbCisx7QUCF8Q6Nutx0WnJrQe5O+kOtBlLfRNUws98Y58Lblp+NJG5T4Q==", + "dev": true, + "dependencies": { + "ieee754": "^1.1.12", + "resolve-protobuf-schema": "^2.1.0" + }, + "bin": { + "pbf": "bin/pbf" + } + }, "node_modules/picocolors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", @@ -11476,6 +11866,23 @@ "version": "4.2.0", "license": "MIT" }, + "node_modules/potpack": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/potpack/-/potpack-2.0.0.tgz", + "integrity": "sha512-Q+/tYsFU9r7xoOJ+y/ZTtdVQwTWfzjbiXBDMM/JKUux3+QPP02iUuIoeBQ+Ot6oEDlC+/PGjB/5A3K7KKb7hcw==", + "dev": true + }, + "node_modules/preact": { + "version": "10.12.1", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.12.1.tgz", + "integrity": "sha512-l8386ixSsBdbreOAkqtrwqHwdvR35ID8c3rKPa8lCWuO86dBi32QWHV4vfsZK1utLLFMvw+Z5Ad4XLkZzchscg==", + "dev": true, + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "dev": true, @@ -11583,6 +11990,12 @@ "dev": true, "license": "MIT" }, + "node_modules/protocol-buffers-schema": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz", + "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==", + "dev": true + }, "node_modules/proxy-addr": { "version": "2.0.7", "dev": true, @@ -11645,6 +12058,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==", + "dev": true + }, "node_modules/ramda": { "version": "0.29.0", "dev": true, @@ -11777,6 +12196,30 @@ "dev": true, "license": "MIT" }, + "node_modules/react-map-gl": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/react-map-gl/-/react-map-gl-7.1.7.tgz", + "integrity": "sha512-mwjc0obkBJOXCcoXQr3VoLqmqwo9vS4bXfbGsdxXzEgVCv/PM0v+1QggL7W0d/ccIy+VCjbXNlGij+PENz6VNg==", + "dev": true, + "dependencies": { + "@maplibre/maplibre-gl-style-spec": "^19.2.1", + "@types/mapbox-gl": ">=1.0.0" + }, + "peerDependencies": { + "mapbox-gl": ">=1.13.0", + "maplibre-gl": ">=1.13.0", + "react": ">=16.3.0", + "react-dom": ">=16.3.0" + }, + "peerDependenciesMeta": { + "mapbox-gl": { + "optional": true + }, + "maplibre-gl": { + "optional": true + } + } + }, "node_modules/react-refresh": { "version": "0.14.2", "dev": true, @@ -12058,6 +12501,15 @@ "node": ">=8" } }, + "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==", + "dev": true, + "dependencies": { + "protocol-buffers-schema": "^3.3.1" + } + }, "node_modules/restore-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", @@ -12210,6 +12662,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==", + "dev": true + }, "node_modules/safe-array-concat": { "version": "1.1.2", "dev": true, @@ -12334,6 +12792,15 @@ "dev": true, "license": "MIT" }, + "node_modules/serialize-to-js": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/serialize-to-js/-/serialize-to-js-3.1.2.tgz", + "integrity": "sha512-owllqNuDDEimQat7EPG0tH7JjO090xKNzUtYz6X+Sk2BXDnOCilDdNLwjWeFywG9xkJul1ULvtUQa9O4pUaY0w==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/serve-static": { "version": "1.15.0", "dev": true, @@ -12378,6 +12845,33 @@ "node": ">= 0.4" } }, + "node_modules/set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", "dev": true, @@ -12453,6 +12947,41 @@ "node": ">=8" } }, + "node_modules/sort-asc": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/sort-asc/-/sort-asc-0.2.0.tgz", + "integrity": "sha512-umMGhjPeHAI6YjABoSTrFp2zaBtXBej1a0yKkuMUyjjqu6FJsTF+JYwCswWDg+zJfk/5npWUUbd33HH/WLzpaA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sort-desc": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/sort-desc/-/sort-desc-0.2.0.tgz", + "integrity": "sha512-NqZqyvL4VPW+RAxxXnB8gvE1kyikh8+pR+T+CXLksVRN9eiQqkQlPwqWYU0mF9Jm7UnctShlxLyAt1CaBOTL1w==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sort-object": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sort-object/-/sort-object-3.0.3.tgz", + "integrity": "sha512-nK7WOY8jik6zaG9CRwZTaD5O7ETWDLZYMM12pqY8htll+7dYeqGfEUPcUBHOpSJg2vJOrvFIY2Dl5cX2ih1hAQ==", + "dev": true, + "dependencies": { + "bytewise": "^1.1.0", + "get-value": "^2.0.2", + "is-extendable": "^0.1.1", + "sort-asc": "^0.2.0", + "sort-desc": "^0.2.0", + "union-value": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map": { "version": "0.5.7", "dev": true, @@ -12496,6 +13025,55 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/sprintf-js": { "version": "1.0.3", "dev": true, @@ -13023,6 +13601,15 @@ "node": ">= 6" } }, + "node_modules/supercluster": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-8.0.1.tgz", + "integrity": "sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==", + "dev": true, + "dependencies": { + "kdbush": "^4.0.2" + } + }, "node_modules/supports-color": { "version": "5.5.0", "dev": true, @@ -13280,6 +13867,15 @@ "dev": true, "license": "MIT" }, + "node_modules/tiny-lru": { + "version": "11.2.11", + "resolved": "https://registry.npmjs.org/tiny-lru/-/tiny-lru-11.2.11.tgz", + "integrity": "sha512-27BIW0dIWTYYoWNnqSmoNMKe5WIbkXsc0xaCQHd3/3xT2XMuMJrzHdrO9QBFR14emBz1Bu0dOAs2sCBBrvgPQA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/tinybench": { "version": "2.8.0", "dev": true, @@ -13293,6 +13889,12 @@ "node": ">=14.0.0" } }, + "node_modules/tinyqueue": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-3.0.0.tgz", + "integrity": "sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==", + "dev": true + }, "node_modules/tinyspy": { "version": "2.2.1", "dev": true, @@ -13441,6 +14043,15 @@ "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" } }, + "node_modules/tweakpane": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/tweakpane/-/tweakpane-4.0.4.tgz", + "integrity": "sha512-RkWD54zDlEbnN01wQPk0ANHGbdCvlJx/E8A1QxhTfCbX+ROWos1Ws2MnhOm39aUGMOh+36TjUwpDmLfmwTr1Fg==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/cocopon" + } + }, "node_modules/tween-functions": { "version": "1.2.0", "dev": true, @@ -13569,6 +14180,21 @@ "node": ">=14.17" } }, + "node_modules/typewise": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typewise/-/typewise-1.0.3.tgz", + "integrity": "sha512-aXofE06xGhaQSPzt8hlTY+/YWQhm9P0jYUp1f2XtmW/3Bk0qzXcyFWAtPoo2uTGQj1ZwbDuSyuxicq+aDo8lCQ==", + "dev": true, + "dependencies": { + "typewise-core": "^1.2.0" + } + }, + "node_modules/typewise-core": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/typewise-core/-/typewise-core-1.2.0.tgz", + "integrity": "sha512-2SCC/WLzj2SbUwzFOzqMCkz5amXLlxtJqDKTICqg30x+2DZxcfZN2MvQZmGfXWKNWaKK9pBPsvkcwv8bF/gxKg==", + "dev": true + }, "node_modules/ufo": { "version": "1.5.3", "dev": true, @@ -13657,6 +14283,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/unique-string": { "version": "2.0.0", "dev": true, @@ -14280,6 +14921,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/vt-pbf": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/vt-pbf/-/vt-pbf-3.1.3.tgz", + "integrity": "sha512-2LzDFzt0mZKZ9IpVF2r69G9bXaP2Q2sArJCmcCgvfTdCCZzSyz4aCLoQyUilu37Ll56tCblIZrXFIjNUpGIlmA==", + "dev": true, + "dependencies": { + "@mapbox/point-geometry": "0.1.0", + "@mapbox/vector-tile": "^1.3.1", + "pbf": "^3.2.1" + } + }, "node_modules/vue-template-compiler": { "version": "2.7.16", "dev": true, diff --git a/package.json b/package.json index 5d50ec6..a6757c4 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,9 @@ "@chromatic-com/storybook": "1.3.3", "@emotion/react": "11.11.4", "@emotion/styled": "11.11.5", + "@fullcalendar/daygrid": "^6.1.15", + "@fullcalendar/react": "^6.1.15", + "@fullcalendar/timegrid": "^6.1.15", "@mui/material": "5.15.15", "@mui/x-date-pickers-pro": "^7.8.0", "@snyk/protect": "latest", @@ -58,6 +61,7 @@ "@storybook/test": "8.0.10", "@testing-library/jest-dom": "6.4.2", "@testing-library/react": "15.0.2", + "@turf/bbox": "^7.0.0", "@types/react": "18.2.79", "@types/react-dom": "18", "@typescript-eslint/eslint-plugin": "7.7.0", @@ -76,9 +80,11 @@ "husky": "^9.0.11", "jsdom": "24.0.0", "lodash": "4.17.21", + "mapbox-gl": "^3.5.2", "moment": "^2.30.1", "postcss": "8.4.38", "prettier": "3.2.5", + "react-map-gl": "^7.1.7", "storybook": "^8.1.11", "vite": "5.2.9", "vite-plugin-dts": "3.8.3", diff --git a/src/atoms/01_Button/Button.tsx b/src/atoms/01_Button/Button.tsx index 7ac1feb..d97209b 100644 --- a/src/atoms/01_Button/Button.tsx +++ b/src/atoms/01_Button/Button.tsx @@ -95,20 +95,21 @@ export const HButton = function ({ { 'relative normal-case shadow-none hover:shadow-none': true, 'rounded-md w-full px-a3 py-b1': !!children, - 'rounded-md px-0 py-0 min-h-b5 max-w-b5 min-w-b5': !children, + 'rounded-md px-0 py-0 min-h-b5 max-w-b5 min-w-b5 max-h-b5': !children, }, buttonTheme === EButtonTheme.PRIMARY && { [` class1 text-body-dark - dark:text-body-light + dark:text-body-dark + bg-primary-light hover:bg-primary-contrast - dark:bg-primary-white - dark:hover:bg-primary-soft + dark:bg-primary-contrast + dark:hover:bg-primary-light `]: variant === ButtonVariant.FILLED, [` @@ -240,7 +241,7 @@ export const HButton = function ({ [EButtonTheme.PASSION_SELECTED]: EIconColor.PASSION_SELECTED, }, [ButtonVariant.FILLED]: { - [EButtonTheme.PRIMARY]: EIconColor.PRIMARY, + [EButtonTheme.PRIMARY]: EIconColor.WHITE, [EButtonTheme.SECONDARY]: EIconColor.WHITE, [EButtonTheme.PASSION]: EIconColor.PASSION, [EButtonTheme.PASSION_SELECTED]: EIconColor.PASSION_SELECTED, diff --git a/src/atoms/03_Link/Link.tsx b/src/atoms/03_Link/Link.tsx index 83f878c..71fd2e1 100644 --- a/src/atoms/03_Link/Link.tsx +++ b/src/atoms/03_Link/Link.tsx @@ -1,7 +1,7 @@ /* eslint no-unused-vars:0, no-shadow:0, @typescript-eslint/no-explicit-any:0 */ // @atoms/Button.tsx import type { ReactNode as ChildrenType } from 'react'; -import { useEffect, useRef } from 'react'; +import { useEffect, useRef, useCallback } from 'react'; import clsx from 'clsx'; import MLink from '@mui/material/Link'; @@ -57,25 +57,31 @@ export const HLink = function ({ }: ILink) { const startApp = useRef<() => void>(() => {}); - const isInternal = (link: string) => - link.startsWith('web+dreampip://') || - link?.startsWith('https://www.dreampip.com') || - link?.replace('http://', '').replace('https://', '').startsWith(host) || - link.startsWith('/'); + const isInternal = useCallback( + (link: string) => + link.startsWith('web+dreampip://') || + link?.startsWith('https://www.dreampip.com') || + link?.replace('http://', '').replace('https://', '').startsWith(host) || + link.startsWith('/'), + [host], + ); // deep-linking: protocol - const toProtocol = (link: string): string => { - if (link.startsWith('https://')) { - return link?.replace('https://', 'web+dreampip://'); - } - if (link.startsWith('http://')) { - return link?.replace('http://', 'web+dreampip://'); - } - if (link.startsWith('/')) { - return `web+dreampip://${host}${link}`; - } - return link; - }; + const toProtocol = useCallback( + (link: string): string => { + if (link.startsWith('https://')) { + return link?.replace('https://', 'web+dreampip://'); + } + if (link.startsWith('http://')) { + return link?.replace('http://', 'web+dreampip://'); + } + if (link.startsWith('/')) { + return `web+dreampip://${host}${link}`; + } + return link; + }, + [host], + ); const handleOnClick = () => { if (onClick) { diff --git a/src/molecules/02_AudioPlayer/__docs__/Example.tsx b/src/molecules/02_AudioPlayer/__docs__/Example.tsx index cc59d21..6f063b7 100644 --- a/src/molecules/02_AudioPlayer/__docs__/Example.tsx +++ b/src/molecules/02_AudioPlayer/__docs__/Example.tsx @@ -1,8 +1,8 @@ // @atoms/02_AudioPlayer/__test__/Example.tsx import React, { FC } from 'react'; -import AudioPlayer, { ICard } from '../AudioPlayer.tsx'; +import AudioPlayer, { IAudioPlayer } from '../AudioPlayer.tsx'; -const Example: FC = function ({ theme = 'light', cards }) { +const Example: FC = function ({ theme = 'light', cards }) { return ; }; diff --git a/src/molecules/03_Calendar/CalendarView.tsx b/src/molecules/03_Calendar/CalendarView.tsx new file mode 100644 index 0000000..54742ed --- /dev/null +++ b/src/molecules/03_Calendar/CalendarView.tsx @@ -0,0 +1,875 @@ +/* eslint jsx-a11y/media-has-caption:0, no-nested-ternary:0, no-unused-vars:0, max-len:0, no-shadow:0, @typescript-eslint/no-explicit-any:0, object-curly-newline:0 */ +// @atoms/CalendarView.tsx +import clsx from 'clsx'; +import React, { useState, useRef } from 'react'; + +import LibCal from '@fullcalendar/react'; +import timeGridPlugin from '@fullcalendar/timegrid'; // a plugin! +import dayGridPlugin from '@fullcalendar/daygrid'; +import { Box, Modal } from '@mui/material'; + +import { Button } from '../../atoms/01_Button'; +import { Typography } from '../../atoms/02_Typography'; +import { ESystemIcon } from '../../atoms/05_SystemIcon'; + +export const EventLocale: any = { + default: { + locale: 'en-us', + timezone: 'Europe/Rome', + email: 'Email Address', + name: 'Name', + phone: 'Phone', + 'phone-helper': + "Your phone should be in the format '+12345678' with the country code.", + artists: 'Artists', + country: 'Country', + city: 'City', + when: 'When', + related: 'Other episodes from our guests', + episodes: "Listen to this event's episodes", + back: 'Back to events', + countdown: 'Countdown', + photos: 'Photos', + local: 'Local time', + already: "You're already registered for this event, hope to see you there!", + register: 'Click here to add your name to the list', + buy: 'Click here to buy tickets', + calendar: 'Add to calendar', + or: 'Or, add your name to the event discount list:', + reset: 'Reset filters', + countries: 'Countries', + events: 'Events', + eventsDescription: + 'A list of our events. Brought with love to your boroughs.', + D: 'Day', + W: 'Week', + Q: 'Quarter', + M: 'Month', + timeframe: 'Timeframe', + space: 'Space', + time: 'Time', + know: 'Know more at', + brought: 'Brought to you by', + T: 'Today', + L: 'List', + allDay: 'all day', + terms: 'Terms', + calendarPrompt: 'Would you like to add this event to your calendar?', + redirectPrompt: 'Would you like to be redirected to the event page?', + ctaMessage: "Don't see your event?", + sendEmail: 'Add it', + mode: 'Switch view', + }, + 'it-it': { + locale: 'it-it', + timezone: 'Europe/Rome', + email: 'Indirizzo e-mail', + name: 'Nome', + phone: 'Numero di cellulare', + 'phone-helper': + "Il tuo telefono deve essere nel formato '+393123123123', con il prefisso del paese.", + artists: 'Artisti', + country: 'Nazione', + city: 'Città', + when: 'Quando', + related: 'Altri episodi dei nostri ospiti', + episodes: 'Ascolta gli episodi di questo evento', + back: 'Vedi altri eventi', + countdown: 'Conto alla rovescia', + photos: 'Fotografie', + local: 'Ora locale', + already: 'Sei già registrato per questo evento, spero di vederti lì!', + register: "Clicca qui per iscriverti alla lista dell'evento.", + buy: 'Clicca qui per acquistare i biglietti', + calendar: 'Aggiungi a calendario', + or: "Oppure, iscriverti alla lista sconti dell'evento:", + reset: 'Ripristina filtri', + countries: 'Paesi', + events: 'Eventi', + eventsDescription: + 'Un elenco dei nostri eventi. Portato con amore nei tuoi quartieri.', + D: 'Giorno', + W: 'Settimana', + Q: 'Trimestre', + M: 'Mese', + timeframe: 'Arco temporale', + space: 'Spazio', + time: 'Tempo', + know: 'Scopri di più su', + brought: 'Portato a voi da', + T: 'Oggi', + L: 'Lista', + allDay: 'tutto il giorno', + terms: 'Termini', + calendarPrompt: 'Vuoi aggiungere questo evento al tuo calendario?', + redirectPrompt: "Vuoi essere reindirizzato alla pagina dell'evento?", + ctaMessage: 'Non vedi il tuo evento?', + sendEmail: 'Aggiungilo', + mode: 'Cambia visualizzazione', + }, + 'pt-br': { + locale: 'pt-br', + timezone: 'America/Bahia', + email: 'Endereço de email', + name: 'Nome', + phone: 'Celular', + 'phone-helper': + "Seu telefone deve estar no formato '+5571991234567', com o código do país e da cidade.", + artists: 'Artistas', + country: 'País', + city: 'Cidade', + when: 'Quando', + related: 'Outros episódios por nossos convidados', + episodes: 'Escute os episódios desse evento', + back: 'Veja outros eventos', + countdown: 'Contagem regressiva', + photos: 'Fotos', + local: 'Horário local', + already: 'Você já se inscreveu para este evento, espero ver-te lá!', + register: 'Clique aqui e adicione seu nome na lista', + buy: 'Clique aqui para comprar ingressos', + calendar: 'Adicione ao calendário', + or: 'Ou adicione seu nome na lista de desconto:', + reset: 'Redefinir filtros', + countries: 'Países', + events: 'Eventos', + eventsDescription: + 'Uma lista de nossos eventos. Trazidos com amor para seus bairros.', + D: 'Dia', + W: 'Semana', + Q: 'Trimestre', + M: 'Mês', + timeframe: 'Período', + space: 'Espaço', + time: 'Tempo', + know: 'Saiba mais em', + brought: 'Trazido até você por', + T: 'Hoje', + L: 'Lista', + allDay: 'o dia todo', + terms: 'Termos', + calendarPrompt: 'Você quer adicionar este evento ao seu calendário?', + redirectPrompt: 'Você quer ser redirecionado para a página do evento?', + ctaMessage: 'Não vê seu evento?', + sendEmail: 'Adicione-o', + mode: 'Mudar visualização', + }, + 'es-es': { + locale: 'es-es', + timezone: 'Europe/Madrid', + email: 'Dirección de correo', + name: 'Nombre', + phone: 'Teléfono', + 'phone-helper': + "Tu teléfono debe estar en el formato '+34911234567', con el código del país.", + artists: 'Artistas', + country: 'País', + city: 'Ciudad', + when: 'Cuándo', + related: 'Otros episodios de nuestros invitados', + episodes: 'Escucha los episodios de este evento', + back: 'Ver otros eventos', + countdown: 'Cuenta regresiva', + photos: 'Fotos', + local: 'Hora local', + already: 'Ya estás inscrito para este evento, ¡esperamos verte allí!', + register: 'Haz clic aquí para añadir tu nombre a la lista', + buy: 'Haz clic aquí para comprar entradas', + calendar: 'Añadir al calendario', + or: 'O añade tu nombre a la lista de descuentos del evento:', + reset: 'Restablecer filtros', + countries: 'Países', + events: 'Eventos', + eventsDescription: + 'Una lista de nuestros eventos. Traído con amor a tus barrios.', + D: 'Día', + W: 'Semana', + Q: 'Trimestre', + M: 'Mes', + timeframe: 'Periodo de tiempo', + space: 'Espacio', + time: 'Tiempo', + know: 'Conoce más en', + brought: 'Traído a ti por', + T: 'Hoy', + L: 'Lista', + allDay: 'todo el día', + terms: 'Términos', + calendarPrompt: '¿Quieres agregar este evento a tu calendario?', + redirectPrompt: '¿Quieres ser redirigido a la página del evento?', + ctaMessage: '¿No ves tu evento?', + sendEmail: 'Añádelo', + mode: 'Cambiar vista', + }, + 'de-de': { + locale: 'de-de', + timezone: 'Europe/Berlin', + email: 'E-Mail-Adresse', + name: 'Name', + phone: 'Telefon', + 'phone-helper': + "Ihre Telefonnummer sollte im Format '+49123456789' mit der Ländervorwahl sein.", + artists: 'Künstler', + country: 'Land', + city: 'Stadt', + when: 'Wann', + related: 'Weitere Episoden von unseren Gästen', + episodes: 'Hören Sie die Episoden dieses Events', + back: 'Zurück zu den Veranstaltungen', + countdown: 'Countdown', + photos: 'Fotos', + local: 'Ortszeit', + already: + 'Du bist bereits für diese Veranstaltung angemeldet, wir hoffen, dich dort zu sehen!', + register: 'Klicken Sie hier, um Ihren Namen zur Liste hinzuzufügen', + buy: 'Klicken Sie hier, um Tickets zu kaufen', + calendar: 'Zum Kalender hinzufügen', + or: 'Oder fügen Sie Ihren Namen zur Rabattliste des Events hinzu:', + reset: 'Filter zurücksetzen', + countries: 'Länder', + events: 'Veranstaltungen', + eventsDescription: + 'Eine Liste unserer Veranstaltungen. Mit Liebe in deine Bezirke gebracht.', + D: 'Tag', + W: 'Woche', + Q: 'Quartal', + M: 'Monat', + timeframe: 'Zeitraum', + space: 'Raum', + time: 'Zeit', + know: 'Erfahren Sie mehr unter', + brought: 'Präsentiert von', + T: 'Heute', + L: 'Liste', + allDay: 'ganztägig', + terms: 'Bedingungen', + calendarPrompt: + 'Möchten Sie diese Veranstaltung zu Ihrem Kalender hinzufügen?', + redirectPrompt: + 'Möchten Sie zur Veranstaltungsseite weitergeleitet werden?', + ctaMessage: 'Siehst du dein Event nicht?', + sendEmail: 'Füge es hinzu', + mode: 'Ansicht wechseln', + }, + 'fr-fr': { + locale: 'fr-fr', + timezone: 'Europe/Paris', + email: 'Adresse e-mail', + name: 'Nom', + phone: 'Téléphone', + 'phone-helper': + "Votre téléphone doit être au format '+33123456789', avec l'indicatif du pays.", + artists: 'Artistes', + country: 'Pays', + city: 'Ville', + when: 'Quand', + related: 'Autres épisodes de nos invités', + episodes: 'Écoutez les épisodes de cet événement', + back: "Voir d'autres événements", + countdown: 'Compte à rebours', + photos: 'Photos', + local: 'Heure locale', + already: 'Vous êtes déjà inscrit à cet événement, espérons vous y voir !', + register: 'Cliquez ici pour ajouter votre nom à la liste', + buy: 'Cliquez ici pour acheter des billets', + calendar: 'Ajouter au calendrier', + or: "Ou ajoutez votre nom à la liste de réduction de l'événement:", + reset: 'Réinitialiser les filtres', + countries: 'Pays', + events: 'Événements', + eventsDescription: + 'Une liste de nos événements. Apportée avec amour dans vos quartiers.', + D: 'Jour', + W: 'Semaine', + Q: 'Trimestre', + M: 'Mois', + timeframe: 'Période', + space: 'Espace', + time: 'Temps', + know: 'En savoir plus sur', + brought: 'Présenté par', + T: "Aujourd'hui", + L: 'Liste', + allDay: 'toute la journée', + terms: 'Termes', + calendarPrompt: 'Voulez-vous ajouter cet événement à votre calendrier?', + redirectPrompt: "Voulez-vous être redirigé vers la page de l'événement?", + ctaMessage: 'Vous ne voyez pas votre événement?', + sendEmail: 'Ajoutez-le', + mode: 'Changer de vue', + }, + ro: { + locale: 'ro', + timezone: 'Europe/Bucharest', + email: 'Adresa de email', + name: 'Nume', + phone: 'Telefon', + 'phone-helper': + "Numărul tău de telefon ar trebui să fie în formatul '+40123456789', cu codul țării.", + artists: 'Artiști', + country: 'Țară', + city: 'Oraș', + when: 'Când', + related: 'Alte episoade cu invitații noștri', + episodes: 'Ascultă episoadele acestui eveniment', + back: 'Înapoi la evenimente', + countdown: 'Numărătoare inversă', + photos: 'Fotografii', + local: 'Ora locală', + already: + 'Ești deja înregistrat pentru acest eveniment, sper să te văd acolo!', + register: 'Apasă aici pentru a-ți adăuga numele în listă', + buy: 'Apasă aici pentru a cumpăra bilete', + calendar: 'Adaugă în calendar', + or: 'Sau, adaugă-ți numele în lista de reduceri a evenimentului:', + reset: 'Resetează filtrele', + countries: 'Țări', + events: 'Evenimente', + eventsDescription: + 'O listă a evenimentelor noastre. Adusă cu dragoste în cartierele tale.', + D: 'Zi', + W: 'Săptămână', + Q: 'Trimestru', + M: 'Lună', + timeframe: 'Perioadă de timp', + space: 'Spațiu', + time: 'Timp', + know: 'Aflați mai multe la', + brought: 'Adus pentru tine de', + T: 'Astăzi', + L: 'Listă', + allDay: 'toată ziua', + terms: 'Termeni', + calendarPrompt: 'Doriți să adăugați acest eveniment în calendarul dvs?', + redirectPrompt: 'Doriți să fiți redirecționat către pagina evenimentului?', + ctaMessage: 'Nu vezi evenimentul tău?', + sendEmail: 'Adaugă-l', + mode: 'Schimbă vizualizarea', + }, + 'pl-pl': { + locale: 'pl-pl', + timezone: 'Europe/Rome', + email: 'Adres e-mail', + name: 'Imię', + phone: 'Telefon', + 'phone-helper': + "Twój numer telefonu powinien mieć format '+12345678' z kodem kraju.", + artists: 'Artyści', + country: 'Kraj', + city: 'Miasto', + when: 'Kiedy', + related: 'Inne odcinki z naszymi gośćmi', + episodes: 'Słuchaj odcinków z tego wydarzenia', + back: 'Powrót do wydarzeń', + countdown: 'Odliczanie', + photos: 'Zdjęcia', + local: 'Czas lokalny', + already: + 'Jesteś już zarejestrowany na to wydarzenie, mamy nadzieję, że się tam zobaczymy!', + register: 'Kliknij tutaj, aby dodać swoje imię do listy', + buy: 'Kliknij tutaj, aby kupić bilety', + calendar: 'Dodaj do kalendarza', + or: 'Lub dodaj swoje imię do listy zniżek na wydarzenie:', + reset: 'Zresetuj filtry', + countries: 'Kraje', + events: 'Wydarzenia', + eventsDescription: + 'Lista naszych wydarzeń. Przygotowane z miłością do twoich dzielnic.', + D: 'Dzień', + W: 'Tydzień', + Q: 'Kwartał', + M: 'Miesiąc', + timeframe: 'Okres czasu', + space: 'Przestrzeń', + time: 'Czas', + know: 'Dowiedz się więcej na', + brought: 'Przedstawione przez', + T: 'Dziś', + L: 'Lista', + allDay: 'Cały dzień', + terms: 'Warunki', + calendarPrompt: 'Czy chcesz dodać to wydarzenie do swojego kalendarza?', + redirectPrompt: 'Czy chcesz zostać przekierowany na stronę wydarzenia?', + ctaMessage: 'Nie widzisz swojego wydarzenia?', + sendEmail: 'Dodaj je', + mode: 'Zmień widok', + }, + 'cs-cz': { + locale: 'cs-cz', + timezone: 'Europe/Rome', + email: 'E-mailová adresa', + name: 'Jméno', + phone: 'Telefon', + 'phone-helper': "Váš telefon by měl mít formát '+12345678' s kódem země.", + artists: 'Umělci', + country: 'Země', + city: 'Město', + when: 'Kdy', + related: 'Další epizody od našich hostů', + episodes: 'Poslouchejte epizody z této události', + back: 'Zpět na události', + countdown: 'Odpočítávání', + photos: 'Fotografie', + local: 'Místní čas', + already: 'Na tuto událost jste již registrováni, těšíme se na vás!', + register: 'Klikněte zde, abyste se přidali na seznam', + buy: 'Klikněte zde pro nákup vstupenek', + calendar: 'Přidat do kalendáře', + or: 'Nebo se přidejte na seznam slev k události:', + reset: 'Resetovat filtry', + countries: 'Země', + events: 'Události', + eventsDescription: 'Seznam našich událostí. S láskou pro vaše obvody.', + D: 'Den', + W: 'Týden', + Q: 'Čtvrtletí', + M: 'Měsíc', + timeframe: 'Časový rámec', + space: 'Prostor', + time: 'Čas', + know: 'Více informací na', + brought: 'Přináší vám', + T: 'Dnes', + L: 'Seznam', + allDay: 'Celý den', + terms: 'Podmínky', + calendarPrompt: 'Chcete přidat tuto událost do svého kalendáře?', + redirectPrompt: 'Chcete být přesměrováni na stránku události?', + ctaMessage: 'Nevidíte svou událost?', + sendEmail: 'Přidejte ji', + mode: 'Změnit zobrazení', + }, + 'sv-se': { + locale: 'sv-se', + timezone: 'Europe/Rome', + email: 'E-postadress', + name: 'Namn', + phone: 'Telefon', + 'phone-helper': + "Ditt telefonnummer ska vara i formatet '+12345678' med landskod.", + artists: 'Artister', + country: 'Land', + city: 'Stad', + when: 'När', + related: 'Andra avsnitt från våra gäster', + episodes: 'Lyssna på detta evenemangs avsnitt', + back: 'Tillbaka till evenemang', + countdown: 'Nedräkning', + photos: 'Foton', + local: 'Lokal tid', + already: 'Du är redan registrerad för detta evenemang, hoppas vi ses där!', + register: 'Klicka här för att lägga till ditt namn i listan', + buy: 'Klicka här för att köpa biljetter', + calendar: 'Lägg till i kalender', + or: 'Eller, lägg till ditt namn i evenemangets rabattlista:', + reset: 'Återställ filter', + countries: 'Länder', + events: 'Evenemang', + eventsDescription: + 'En lista över våra evenemang. Levererat med kärlek till dina stadsdelar.', + D: 'Dag', + W: 'Vecka', + Q: 'Kvartal', + M: 'Månad', + timeframe: 'Tidsram', + space: 'Utrymme', + time: 'Tid', + know: 'Läs mer på', + brought: 'Presenteras av', + T: 'Idag', + L: 'Lista', + allDay: 'Hela dagen', + terms: 'Villkor', + calendarPrompt: 'Vill du lägga till denna händelse i din kalender?', + redirectPrompt: 'Vill du omdirigeras till evenemangssidan?', + ctaMessage: 'Ser du inte ditt evenemang?', + sendEmail: 'Lägg till det', + mode: 'Byt vy', + }, + 'et-ee': { + locale: 'et-ee', + timezone: 'Europe/Rome', + email: 'E-posti aadress', + name: 'Nimi', + phone: 'Telefon', + 'phone-helper': + "Teie telefoninumber peaks olema formaadis '+12345678' koos riigikoodiga.", + artists: 'Kunstnikud', + country: 'Riik', + city: 'Linn', + when: 'Millal', + related: 'Teised episoodid meie külalistelt', + episodes: 'Kuula selle sündmuse episoode', + back: 'Tagasi ürituste juurde', + countdown: 'Loendur', + photos: 'Fotod', + local: 'Kohalik aeg', + already: + 'Olete juba sellele üritusele registreerunud, loodame teid seal näha!', + register: 'Klõpsake siin, et lisada oma nimi nimekirja', + buy: 'Klõpsake siin, et osta pileteid', + calendar: 'Lisa kalendrisse', + or: 'Või lisage oma nimi ürituse soodustuste nimekirja:', + reset: 'Lähtesta filtrid', + countries: 'Riigid', + events: 'Üritused', + eventsDescription: + 'Nimekiri meie üritustest. Toome armastusega teie linnaosadesse.', + D: 'Päev', + W: 'Nädal', + Q: 'Kvartal', + M: 'Kuu', + timeframe: 'Ajaraam', + space: 'Ruum', + time: 'Aeg', + know: 'Rohkem teavet leiate', + brought: 'Teieni toob', + T: 'Täna', + L: 'Nimekiri', + allDay: 'Terve päev', + terms: 'Tingimused', + calendarPrompt: 'Kas soovite selle sündmuse oma kalendrisse lisada?', + redirectPrompt: 'Kas soovite suunata sündmuse lehele?', + ctaMessage: 'Ei näe oma sündmust?', + sendEmail: 'Lisa see', + mode: 'Vaheta vaadet', + }, + 'ja-jp': { + locale: 'ja-jp', + timezone: 'Europe/Rome', + email: 'メールアドレス', + name: '名前', + phone: '電話', + 'phone-helper': + "電話番号は国コードを含む '+12345678' の形式である必要があります。", + artists: 'アーティスト', + country: '国', + city: '市', + when: 'いつ', + related: 'ゲストからの他のエピソード', + episodes: 'このイベントのエピソードを聴く', + back: 'イベントに戻る', + countdown: 'カウントダウン', + photos: '写真', + local: '現地時間', + already: 'すでにこのイベントに登録されています、お待ちしています!', + register: 'リストに名前を追加するにはこちらをクリック', + buy: 'チケットを購入するにはこちらをクリック', + calendar: 'カレンダーに追加', + or: 'または、イベントの割引リストに名前を追加してください:', + reset: 'フィルターをリセット', + countries: '国々', + events: 'イベント', + eventsDescription: '私たちのイベントのリスト。あなたの地区への愛を込めて。', + D: '日', + W: '週', + Q: '四半期', + M: '月', + timeframe: '期間', + space: 'スペース', + time: '時間', + know: '詳しくはこちらで', + brought: '提供元:', + T: '今日', + L: 'リスト', + allDay: '終日', + terms: '利用規約', + calendarPrompt: 'このイベントをカレンダーに追加しますか?', + redirectPrompt: 'イベントページにリダイレクトしますか?', + ctaMessage: 'イベントが見えませんか?', + sendEmail: '追加してください', + mode: '表示切替', + }, + country: { + Brazil: 'pt-br', + Italy: 'it-it', + Spain: 'es-es', + Germany: 'de-de', + France: 'fr-fr', + Romania: 'ro', + Poland: 'pl-pl', + 'Czech Republic': 'cs-cz', + Sweden: 'sv-se', + Estonia: 'et-ee', + Japan: 'ja-jp', + default: 'en-us', + }, +}; + +export const DEFAULT_EVENTS = { + calData: [ + { + id: '[musica, samba] Banda - Samba do São Lázaro', + title: '[musica, samba] Banda - Samba do São Lázaro', + url: 'https://instagram.com/samba_do_sl', + location: + 'Largo de São Lázaro - Ondina, Salvador - BA, 40170-010, Brazil', + start: '2024-08-09T17:00:00-03:00', + end: '2024-08-09T20:00:00-03:00', + classNames: ['musica', 'samba'], + allDay: false, + terms: ['musica', 'samba'], + city: 'salvador', + artists: ['Banda'], + project: ['Samba do São Lázaro'], + timeframe: 'W', + }, + ], + mapData: { + type: 'FeatureCollection', + features: [ + { + type: 'Feature', + geometry: { + type: 'Point', + coordinates: [-38.5120851, -13.0076901], + }, + properties: { + name: '[musica, samba] Banda - Samba do São Lázaro', + terms: ['musica', 'samba'], + city: 'salvador', + artists: ['Banda'], + project: ['Samba do São Lázaro'], + starttime: '2024-08-09T17:00:00-03:00', + endtime: '2024-08-09T20:00:00-03:00', + location: + 'Largo de São Lázaro - Ondina, Salvador - BA, 40170-010, Brazil', + link: 'https://instagram.com/samba_do_sl', + timeframe: 'W', + clusterId: 'molecule__MapView', + }, + }, + ], + timeframe: 'W', + }, +}; + +export enum ECalendarViewVariant { + DEFAULT = 'default', +} + +export interface IBackgroundImage { + mobile?: string; + desktop?: string; +} + +export interface IAudioTrack { + id?: string; + className?: string; + onPlay?: () => void; + title?: string; + url?: string; + isPlaying?: boolean; +} + +export interface ICalendarView { + id?: string; + className?: string; + events?: any[]; + locale?: string; + initialView?: string; + headerToolbar?: any; + nowIndicator?: boolean; + theme?: 'light' | 'dark'; +} + +export const HCalendarView = function ({ + id = 'atom__CalendarView', + className = '', + events = DEFAULT_EVENTS.calData, + locale = 'en-US', + initialView = 'timeGridWeek', + headerToolbar = { + left: 'title', + center: '', + right: '', + }, + nowIndicator = false, + theme = 'light', +}: ICalendarView) { + const calendarRef = useRef(null); + const [open, setOpen] = useState(false); + const [modalPrompt, setModalPrompt] = useState(''); + const [askedCal, setAskedCal] = useState(false); + const [info, setInfo] = useState({ event: { url: '' } }); + // to-do add localization + const localization = + EventLocale[locale as keyof typeof EventLocale] || EventLocale.default; + const gridSx = [ + { + [`class03 + relative + flex + flex-col + w-full + h-full + col-span-full col-start-0 + content-center + items-center + align-center + justify-center + [&_*]:text-body-light + [&_.fc-event_*]:text-body-dark + [&_*]:dark:text-body-dark + [&_.fc-event_*]:dark:text-body-light + [&_.fc]:w-full + `]: true, + }, + ]; + + const style = { + position: 'absolute', + top: '50%', + left: '50%', + transform: 'translate(-50%, -50%)', + width: 400, + backgroundColor: 'white', + border: '2px solid #000', + boxShadow: 24, + p: 4, + }; + + const gridStyles = `${clsx(gridSx)} ${className}`; + + const redirectConsent = () => { + setModalPrompt(localization.redirectPrompt); + setOpen(true); + }; + + const handleOKModalClick = async () => { + if (!askedCal) { + // const cal = await import('../lib/cal'); + // const { createICal } = cal; + // const { download } = cal; + // const invite = await createICal({ + // start: info.event.start, + // end: info.event.end, + // title: info.event.title, + // url: info.event.url, + // location: info.event.extendedProps.location, + // locale, + // }); + // await download(`purizu-external-${info.event.title}.ics`, invite); + setAskedCal(true); + setTimeout(() => { + redirectConsent(); + }, 1000); + } + setOpen(false); + if (askedCal) { + window.open(info.event.url); + setAskedCal(false); + } + }; + + const handleCancelModalClick = () => { + setOpen(false); + if (!askedCal) { + setAskedCal(true); + setTimeout(() => { + redirectConsent(); + }, 1000); + } else { + setAskedCal(false); + } + }; + + const handlePreviousClick = () => { + const calendarAPI = calendarRef?.current?.getApi(); + calendarAPI?.prev(); + }; + + const handleNextClick = () => { + const calendarAPI = calendarRef?.current?.getApi(); + calendarAPI?.next(); + }; + + const handleTodayClick = () => { + const calendarAPI = calendarRef?.current?.getApi(); + calendarAPI?.today(); + }; + + return ( +
+ { + info.jsEvent.preventDefault(); // don't let the browser navigate + setModalPrompt(localization.calendarPrompt); + setOpen(true); + setInfo(info); + }} + viewDidMount={(info: any) => { + try { + const delta = + info?.view?.calendar?.currentData?.dateProfile?.renderRange + ?.start || 0; + info?.view?.calendar?.scrollToTime(new Date().getTime() - delta); + } catch (e) { + console.error(e); + } + }} + /> +
+
+ + + + {modalPrompt} + + + + + +
+ ); +}; + +export default HCalendarView; diff --git a/src/molecules/03_Calendar/__docs__/03-CalendarView.stories.tsx b/src/molecules/03_Calendar/__docs__/03-CalendarView.stories.tsx new file mode 100644 index 0000000..9315a76 --- /dev/null +++ b/src/molecules/03_Calendar/__docs__/03-CalendarView.stories.tsx @@ -0,0 +1,28 @@ +// @atoms/03_CalendarView/__test__/03-CalendarView.stories.tsx +import type { Meta, StoryObj } from '@storybook/react'; +import Example from './Example.tsx'; +import { ECalendarViewVariant } from '../CalendarView'; + +const meta: Meta = { + title: 'Molecules/03-CalendarView', + component: Example, + argTypes: { + theme: { + options: ['light', 'dark'], + control: { type: 'radio' }, + }, + variant: { + options: Object.values(ECalendarViewVariant), + control: { type: 'radio' }, + }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + variant: ECalendarViewVariant.DEFAULT, + }, +}; diff --git a/src/molecules/03_Calendar/__docs__/CalendarView.mdx b/src/molecules/03_Calendar/__docs__/CalendarView.mdx new file mode 100644 index 0000000..39e631b --- /dev/null +++ b/src/molecules/03_Calendar/__docs__/CalendarView.mdx @@ -0,0 +1,55 @@ +import { Canvas, Meta } from "@storybook/blocks"; +import Example from "./Example.tsx"; +import * as CalendarView from "./03-CalendarView.stories.tsx"; + + + +# CalendarView + +CalendarView component with different props. + +#### Example + + + +## Usage + +```ts +import { CalendarView } from "@dreampipcom/oneiros"; + +export const DEFAULT_TRACKS = [ + { + id: 'dreampip__chan_0000', + className: '', + onPlay: () => {}, + title: 'This is the track playing', + url: 'https://www.dreampip.com/api/nexus/audio', + isPlaying: false, + }, + { + id: 'dreampip__chan_0001', + className: '', + onPlay: () => {}, + title: 'This is the track playing', + url: 'https://www.dreampip.com/api/nexus/audio/1', + isPlaying: false, + }, +]; + +const App = () => { + return ( + + ); +}; + +export default Example; +``` + +#### Arguments + +- **tracks** — An array of Tracks props, where each index represents a Card in the grid. +- **onPlayTrack** — A function to run when the play button is clicked. +- **nativeControls** — A boolean to determine whether the native browser player should display. +- **prompt** — A string to show by the side of the player. \ No newline at end of file diff --git a/src/molecules/03_Calendar/__docs__/Example.tsx b/src/molecules/03_Calendar/__docs__/Example.tsx new file mode 100644 index 0000000..8fd2715 --- /dev/null +++ b/src/molecules/03_Calendar/__docs__/Example.tsx @@ -0,0 +1,9 @@ +// @atoms/03_CalendarView/__test__/Example.tsx +import React, { FC } from 'react'; +import CalendarView, { ICalendarView } from '../CalendarView.tsx'; + +const Example: FC = function ({ theme = 'light', cards }) { + return ; +}; + +export default Example; diff --git a/src/molecules/03_Calendar/__test__/03-CalendarView.test.tsx b/src/molecules/03_Calendar/__test__/03-CalendarView.test.tsx new file mode 100644 index 0000000..5bdb96e --- /dev/null +++ b/src/molecules/03_Calendar/__test__/03-CalendarView.test.tsx @@ -0,0 +1,13 @@ +// @atoms/03_Card/__test__/03-CalendarView.test.tsx +import React from 'react'; +import { describe, expect, it } from 'vitest'; +import { render } from '@testing-library/react'; +import CalendarView from '../CalendarView'; + +describe('CalendarView component', () => { + it('CalendarView should render correctly', () => { + const result = render(); + const component = result.container.querySelector('#grid-atom--test'); + expect(component).toBeInTheDocument(); + }); +}); diff --git a/src/molecules/03_Calendar/index.ts b/src/molecules/03_Calendar/index.ts new file mode 100644 index 0000000..f552f90 --- /dev/null +++ b/src/molecules/03_Calendar/index.ts @@ -0,0 +1,3 @@ +// @atoms/CalendarView/index.ts +export { default as CalendarView, ECalendarViewVariant } from './CalendarView'; +export const CalendarViewName = 'CalendarView'; diff --git a/src/molecules/04_Map/MapView.tsx b/src/molecules/04_Map/MapView.tsx new file mode 100644 index 0000000..ea1b790 --- /dev/null +++ b/src/molecules/04_Map/MapView.tsx @@ -0,0 +1,675 @@ +/* eslint no-unreachable:0, @typescript-eslint/no-unused-vars:0, no-import-assign:0, import/no-unresolved:0, import/no-webpack-loader-syntax:0, jsx-a11y/media-has-caption:0, no-nested-ternary:0, no-unused-vars:0, max-len:0, no-shadow:0, @typescript-eslint/no-explicit-any:0, object-curly-newline:0 */ +// @atoms/MapView.tsx +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-nocheck +import clsx from 'clsx'; +import Map, { Source, Layer, Popup as GLPop } from 'react-map-gl'; +import bbox from '@turf/bbox'; +import React, { useRef, useState, useEffect } from 'react'; +import { Button, ButtonVariant, EButtonTheme } from '../../atoms/01_Button'; +import { Typography } from '../../atoms/02_Typography'; +import { Link } from '../../atoms/03_Link'; +import { SystemIcon, ESystemIcon } from '../../atoms/05_SystemIcon'; + +import 'mapbox-gl'; +import 'mapbox-gl/dist/mapbox-gl.css'; + +export const MapLocale = { + default: { + locale: 'en-us', + view: 'View more', + calendar: 'Add to calendar', + }, + 'it-it': { + locale: 'it-it', + view: 'Vedi altro', + calendar: 'Aggiungi al calendario', + }, + 'pt-br': { + locale: 'pt-pt', + view: 'Veja mais', + calendar: 'Adicionar ao calendário', + }, + 'es-es': { + locale: 'es-es', + view: 'Ver más', + calendar: 'Añadir al calendario', + }, + 'de-de': { + locale: 'de-de', + view: 'Mehr anzeigen', + calendar: 'Zum Kalender hinzufügen', + }, + 'fr-fr': { + locale: 'fr-fr', + view: 'Voir plus', + calendar: 'Ajouter au calendrier', + }, + ro: { + locale: 'ro-ro', + view: 'Vezi mai mult', + calendar: 'Adaugă în calendar', + }, + 'pl-pl': { + locale: 'pl-pl', + view: 'Zobacz więcej', + calendar: 'Dodaj do kalendarza', + }, + 'cs-cz': { + locale: 'cs-cz', + view: 'Zobrazit více', + calendar: 'Přidat do kalendáře', + }, + 'sv-se': { + locale: 'sv-se', + view: 'Visa mer', + calendar: 'Lägg till i kalendern', + }, + 'et-ee': { + locale: 'et-ee', + view: 'Vaata rohkem', + calendar: 'Lisa kalendrisse', + }, + 'ja-jp': { + locale: 'ja-jp', + view: 'もっと見る', + calendar: 'カレンダーに追加', + }, +}; + +export const MAP_CENTRES = { + bologna: { + coordinates: [44.4950954609241, 11.342671827389358], + zoom: 13, + slug: 'bologna', + city: 'Bologna', + }, + milan: { + coordinates: [45.468964617372144, 9.185626132750581], + zoom: 12, + slug: 'milan', + city: 'Milan', + }, + rome: { + coordinates: [41.89155469633848, 12.489295340697346], + zoom: 10, + slug: 'rome', + city: 'Rome', + }, + salvador: { + coordinates: [-13.004604344148513, -38.508604693368525], + zoom: 11, + slug: 'salvador', + city: 'Salvador', + }, + // + barcelona: { + coordinates: [41.406545280288164, 2.1748619972294425], + zoom: 10, + slug: 'barcelona', + city: 'Barcelona', + }, + montevideo: { + coordinates: [-34.87964393846871, -56.17967780626219], + zoom: 11, + slug: 'montevideo', + city: 'Montevideo', + }, + 'buenos-aires': { + coordinates: [-34.605404817586916, -58.44372023511807], + zoom: 11, + slug: 'buenos-aires', + city: 'Buenos Aires', + }, + 'sao-paulo': { + coordinates: [-23.539530638879445, -46.632974596201784], + zoom: 9, + slug: 'sao-paulo', + city: 'São Paulo', + }, + 'rio-de-janeiro': { + coordinates: [-22.896288364477716, -43.18010298590159], + zoom: 9, + slug: 'rio-de-janeiro', + city: 'Rio de Janeiro', + }, + 'new-york': { + coordinates: [40.78343167530586, -73.9649807684582], + zoom: 9, + slug: 'new-york', + city: 'New York', + }, + 'los-angeles': { + coordinates: [34.04280112429188, -118.27994380137976], + zoom: 9, + slug: 'los-angeles', + city: 'Los Angeles', + }, + london: { + coordinates: [51.49707494166325, -0.11830187408555738], + zoom: 9, + slug: 'london', + city: 'London', + }, + amsterdam: { + coordinates: [52.37300011627217, 4.89914502114092], + zoom: 10, + slug: 'amsterdam', + city: 'Amsterdam', + }, + berlin: { + coordinates: [52.51558001390169, 13.405471175511197], + zoom: 10, + slug: 'berlin', + city: 'Berlin', + }, + paris: { + coordinates: [48.85837373820162, 2.347719247553416], + zoom: 10, + slug: 'paris', + city: 'Paris', + }, + madrid: { + coordinates: [40.419543366570025, -3.6980869726309074], + zoom: 10, + slug: 'madrid', + city: 'Madrid', + }, + lisbon: { + coordinates: [38.72170956493803, -9.137077200346017], + zoom: 11, + slug: 'lisbon', + city: 'Lisbon', + }, + // 'brussels': { + // coordinates: [50.847942220069974, 4.359278621249498], + // zoom: 10, + // slug: 'brussels' + // }, + // 'helsinki': { + // coordinates: [60.17060646408163, 24.9417479081061], + // zoom: 10, + // slug: 'helsinki' + // }, + // 'stockholm': { + // coordinates: [59.3291904587081, 18.0747421483835], + // zoom: 10, + // slug: 'stockholm' + // }, + // 'vienna': { + // coordinates: [48.205271439006324, 16.370205155676686], + // zoom: 11, + // slug: 'vienna' + // }, + // 'malmo': { + // coordinates: [55.60429001203468, 13.002924043355616], + // zoom: 11, + // slug: 'malmo' + // }, + // 'copenhagen': { + // coordinates: [55.67646697784446, 12.568415929865017], + // zoom: 11, + // slug: 'copenhagen' + // }, + // 'tallinn': { + // coordinates: [59.43529132682876, 24.758830754731353], + // zoom: 11, + // slug: 'tallinn' + // }, + // 'kassel': { + // coordinates: [51.31249663730745, 9.474345469392675], + // zoom: 11, + // slug: 'kassel' + // }, + // 'warsaw': { + // coordinates: [52.2286176198592, 21.01380667963312], + // zoom: 11, + // slug: 'warsaw' + // }, + // 'bucharest': { + // coordinates: [44.427254325634394, 26.10012813246689], + // zoom: 11, + // slug: 'bucharest' + // }, + // 'prague': { + // coordinates: [50.075419900329166, 14.432655632695203], + // zoom: 11, + // slug: 'prague' + // }, + // 'zurich': { + // coordinates: [47.3784801240796, 8.520658940136343], + // zoom: 11, + // slug: 'zurich' + // }, + // 'cape-town': { + // coordinates: [-33.91965737680834, 18.433543390603305], + // zoom: 11, + // slug: 'cape-town' + // }, + // + // 'tokyo': { + // coordinates: [35.77884404494747, 139.74709804249656], + // zoom: 11, + // slug: 'tokyo' + // }, + // 'sydney': { + // coordinates: [-33.86377138104712, 51.21894962803245], + // zoom: 11, + // slug: 'sydney' + // }, + // 'vilnius': { + // coordinates: [54.68549232478511, 25.279117815293635], + // zoom: 11, + // slug: 'vilnius' + // }, + // 'riga': { + // coordinates: [56.96603489318597, 24.10777947553373], + // zoom: 11, + // slug: 'riga' + // }, + global: { + coordinates: [0, 0], + zoom: 7, + slug: 'global', + city: 'All cities', + }, +}; + +export const clusterLayer = { + id: 'clusters', + type: 'circle', + source: 'molecule__MapView', + filter: ['has', 'point_count'], + paint: { + 'circle-color': [ + 'step', + ['get', 'point_count'], + '#fff', + 10, + '#22cc00', + 30, + '#cc2200', + ], + 'circle-radius': ['step', ['get', 'point_count'], 20, 5, 30, 10, 40], + }, +}; + +export const clusterCountLayer = { + id: 'molecule__MapView', + type: 'symbol', + source: 'molecule__MapView', + filter: ['has', 'point_count'], + layout: { + 'text-field': '{point_count_abbreviated}', + // 'text-font': ['Comfortaa', 'Arial Unicode MS Bold'], + 'text-size': 12, + }, +}; + +export const unclusteredPointLayer = { + id: 'point', + type: 'circle', + source: 'molecule__MapView', + filter: ['!', ['has', 'point_count']], + paint: { + 'circle-color': '#fff', + 'circle-radius': 10, + 'circle-stroke-width': 1, + 'circle-stroke-color': '#fff', + }, +}; + +export const DEFAULT_EVENTS = { + calData: [ + { + id: '[musica, samba] Banda - Samba do São Lázaro', + title: '[musica, samba] Banda - Samba do São Lázaro', + url: 'https://instagram.com/samba_do_sl', + location: + 'Largo de São Lázaro - Ondina, Salvador - BA, 40170-010, Brazil', + start: '2024-08-09T17:00:00-03:00', + end: '2024-08-09T20:00:00-03:00', + classNames: ['musica', 'samba'], + allDay: false, + terms: ['musica', 'samba'], + city: 'salvador', + artists: ['Banda'], + project: ['Samba do São Lázaro'], + timeframe: 'W', + }, + ], + mapData: { + type: 'FeatureCollection', + features: [ + { + type: 'Feature', + geometry: { + type: 'Point', + coordinates: [-38.5120851, -13.0076901], + }, + properties: { + name: '[musica, samba] Banda - Samba do São Lázaro', + terms: ['musica', 'samba'], + city: 'salvador', + artists: ['Banda'], + project: ['Samba do São Lázaro'], + starttime: '2024-08-09T17:00:00-03:00', + endtime: '2024-08-09T20:00:00-03:00', + location: + 'Largo de São Lázaro - Ondina, Salvador - BA, 40170-010, Brazil', + link: 'https://instagram.com/samba_do_sl', + timeframe: 'W', + clusterId: 'molecule__MapView', + }, + }, + ], + timeframe: 'W', + }, +}; + +export enum EMapViewVariant { + DEFAULT = 'default', +} + +export interface IMapView { + id?: string; + className?: string; + events?: any; + locale?: string; + mobile?: boolean; + city?: string; + settings?: any; + timeframe?: string; + mapBoxToken?: string; + fetchNewData?: () => void; + theme?: 'light' | 'dark'; +} + +export interface IMapPopup { + id?: string; + className?: string; + onOpen?: () => void; + onClose?: () => void; + locale?: string; + feature?: any; + theme?: 'light' | 'dark'; +} + +const Popup = function ({ + id = 'molecule__MapView', + className, + theme, + feature, + locale = 'en-US', + onClose = () => {}, + onOpen = () => {}, +}: IMapPopup) { + const { name, starttime, endtime, link } = feature.properties; + const coordinates = feature.geometry; + const [lng, lat] = coordinates; + const start = new Date(starttime).toLocaleString(locale || 'en-US', {}); + const end = new Date(endtime).toLocaleString(locale || 'en-US', {}); + + const localization = MapLocale[locale] || MapLocale.default; + // style={{ zIndex: 99999, width: '300px', position: 'absolute', bottom: '-128px', backgroundColor: '#1b1b1b', padding: '8px' } + return ( + +
+ + {name} + +
+ + {`${start}—${end}`} + +
+ + {localization.view} + +
+
+ +
+
+ ); +}; + +export const HMapView = function ({ + id = 'molecule__MapView', + className = '', + events = DEFAULT_EVENTS, + locale, + mobile, + city, + settings, + timeframe, + mapBoxToken, + fetchNewData, + theme = 'light', +}: IMapView) { + const mapRef = useRef(null); + const popup = useRef({ open: false, feature: undefined }); + const hoverPopup = useRef(null); + const [popupOpen, setPopupOpen] = useState(false); + const [hoverPopupOpen, setHoverPopupOpen] = useState(false); + + const gridSx = [ + { + [`class04 + flex + col-span-full col-start-0 + content-center + items-center + align-center + justify-center + `]: true, + }, + ]; + + const gridStyles = `${clsx(gridSx)} ${className}`; + + const onPopUpClose = () => { + setPopupOpen(false); + setHoverPopupOpen(false); + }; + + const onClickCluster = ({ target }) => { + if (popupOpen || hoverPopupOpen) { + setPopupOpen(false); + setHoverPopupOpen(false); + return; + } + const clusterId = target.properties.cluster_id; + const mapboxSource = mapRef.current.getSource('molecule__MapView'); + mapboxSource.getClusterExpansionZoom(clusterId, (err, zoom) => { + if (err) { + return; + } + + mapRef.current.easeTo({ + center: target.geometry.coordinates, + zoom, + duration: 500, + }); + }); + }; + + const onClickPoint = ({ target, event }: any) => { + if (popupOpen || hoverPopupOpen) { + setPopupOpen(false); + setHoverPopupOpen(false); + return; + } + const { lngLat } = event; + const geometry = target.geometry.coordinates; + popup.current = { + feature: { properties: target.properties, geometry, lngLat }, + }; + setPopupOpen(true); + }; + + useEffect(() => { + if (events?.timeframe !== timeframe) { + fetchNewData({ force: true }); + } + }, [timeframe]); + + useEffect(() => { + // if (!events?.mapData) return; + if (mapRef?.current && events?.mapData?.features?.length) { + const bounds = bbox(events?.mapData); + + if (bounds?.length) { + try { + mapRef.current.fitBounds(bounds, { padding: 200, maxZoom: 14 }); + } catch (e) { + mapRef.current.fitBounds(bounds, { padding: 20, maxZoom: 14 }); + } + } + } + }, [JSON.stringify(events?.mapData)]); + + const onClick = (event) => { + const [target] = event.features; + + if (!target) return; + + if (target.layer.id === 'clusters') { + onClickCluster({ target, event }); + } + if (target.layer.id === 'point') { + onClickPoint({ target, event }); + } + }; + + const onMouseEnter = (event) => { + const [target] = event.features; + const { clusterId } = target.properties; + const mapboxSource = mapRef.current.getSource(clusterId); + mapboxSource.getClusterLeaves(clusterId, 5, 0, (err, features: any) => { + if (err) return; + hoverPopup.current = features; + hoverPopup.current.coordinates = target.geometry.coordinates; + setHoverPopupOpen(true); + }); + }; + + const onMouseLeave = () => { + setHoverPopupOpen(false); + }; + + const centre = [settings?.where?.lon, settings?.where?.lat] || [0, 0]; + const zoom = settings?.zoom || 3; + + return ( +
+ + + + + + + {popupOpen ? ( + + ) : undefined} + {hoverPopupOpen && hoverPopup.current ? ( + + {hoverPopup?.current?.length && + hoverPopup?.current?.map((feature: any) => ( + + {feature?.properties?.name} +
+
+ ))} +
+ ) : undefined} +
+
+ ); +}; + +export default HMapView; diff --git a/src/molecules/04_Map/__docs__/04-MapView.stories.tsx b/src/molecules/04_Map/__docs__/04-MapView.stories.tsx new file mode 100644 index 0000000..d2c5ed6 --- /dev/null +++ b/src/molecules/04_Map/__docs__/04-MapView.stories.tsx @@ -0,0 +1,29 @@ +// @atoms/04_MapView/__test__/04-MapView.stories.tsx +import type { Meta, StoryObj } from '@storybook/react'; +import Example from './Example.tsx'; +import { EMapViewVariant } from '../MapView'; + +const meta: Meta = { + title: 'Molecules/04-MapView', + component: Example, + argTypes: { + theme: { + options: ['light', 'dark'], + control: { type: 'radio' }, + }, + variant: { + options: Object.values(EMapViewVariant), + control: { type: 'radio' }, + }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + variant: EMapViewVariant.DEFAULT, + mapBoxToken: import.meta.env.VITE_MAPBOX_TOKEN, + }, +}; diff --git a/src/molecules/04_Map/__docs__/Example.tsx b/src/molecules/04_Map/__docs__/Example.tsx new file mode 100644 index 0000000..17e07c6 --- /dev/null +++ b/src/molecules/04_Map/__docs__/Example.tsx @@ -0,0 +1,13 @@ +// @atoms/04_MapView/__test__/Example.tsx +import React, { FC } from 'react'; +import MapView, { IMapView } from '../MapView.tsx'; + +const Example: FC = function ({ + theme = 'light', + cards, + mapBoxToken, +}) { + return ; +}; + +export default Example; diff --git a/src/molecules/04_Map/__docs__/MapView.mdx b/src/molecules/04_Map/__docs__/MapView.mdx new file mode 100644 index 0000000..eace441 --- /dev/null +++ b/src/molecules/04_Map/__docs__/MapView.mdx @@ -0,0 +1,55 @@ +import { Canvas, Meta } from "@storybook/blocks"; +import Example from "./Example.tsx"; +import * as MapView from "./04-MapView.stories.tsx"; + + + +# MapView + +MapView component with different props. + +#### Example + + + +## Usage + +```ts +import { MapView } from "@dreampipcom/oneiros"; + +export const DEFAULT_TRACKS = [ + { + id: 'dreampip__chan_0000', + className: '', + onPlay: () => {}, + title: 'This is the track playing', + url: 'https://www.dreampip.com/api/nexus/audio', + isPlaying: false, + }, + { + id: 'dreampip__chan_0001', + className: '', + onPlay: () => {}, + title: 'This is the track playing', + url: 'https://www.dreampip.com/api/nexus/audio/1', + isPlaying: false, + }, +]; + +const App = () => { + return ( + + ); +}; + +export default Example; +``` + +#### Arguments + +- **tracks** — An array of Tracks props, where each index represents a Card in the grid. +- **onPlayTrack** — A function to run when the play button is clicked. +- **nativeControls** — A boolean to determine whether the native browser player should display. +- **prompt** — A string to show by the side of the player. \ No newline at end of file diff --git a/src/molecules/04_Map/__test__/04-MapView.test.tsx b/src/molecules/04_Map/__test__/04-MapView.test.tsx new file mode 100644 index 0000000..c5d90cb --- /dev/null +++ b/src/molecules/04_Map/__test__/04-MapView.test.tsx @@ -0,0 +1,13 @@ +// @atoms/04_Card/__test__/04-MapView.test.tsx +import React from 'react'; +import { describe, expect, it } from 'vitest'; +import { render } from '@testing-library/react'; +import MapView from '../MapView'; + +describe('MapView component', () => { + it('MapView should render correctly', () => { + const result = render(); + const component = result.container.querySelector('#grid-atom--test'); + expect(component).toBeInTheDocument(); + }); +}); diff --git a/src/molecules/04_Map/index.ts b/src/molecules/04_Map/index.ts new file mode 100644 index 0000000..67276e1 --- /dev/null +++ b/src/molecules/04_Map/index.ts @@ -0,0 +1,3 @@ +// @atoms/MapView/index.ts +export { default as MapView, EMapViewVariant } from './MapView'; +export const MapViewName = 'MapView'; diff --git a/vite.config.ts.timestamp-1722777108318-4e7053192373e.mjs b/vite.config.ts.timestamp-1722777108318-4e7053192373e.mjs deleted file mode 100644 index 12ea111..0000000 --- a/vite.config.ts.timestamp-1722777108318-4e7053192373e.mjs +++ /dev/null @@ -1,50 +0,0 @@ -// vite.config.ts -import eslint from "file:///Users/angeloreale/ar/dreampip/oneiros/node_modules/vite-plugin-eslint/dist/index.mjs"; -import { defineConfig } from "file:///Users/angeloreale/ar/dreampip/oneiros/node_modules/vite/dist/node/index.js"; -import react from "file:///Users/angeloreale/ar/dreampip/oneiros/node_modules/@vitejs/plugin-react/dist/index.mjs"; -import dts from "file:///Users/angeloreale/ar/dreampip/oneiros/node_modules/vite-plugin-dts/dist/index.mjs"; - -// package.json -var peerDependencies = { - clsx: "2.1.0", - lazysizes: "^5.3.2", - react: "^18.2.0", - "react-dom": "^18.2.0", - tailwindcss: "3.4.4", - typescript: "5.4.5" -}; - -// vite.config.ts -var vite_config_default = defineConfig((env) => ({ - build: { - lib: { - entry: "./src/index.ts", - name: "vite-react-ts-button", - fileName: (format) => `index.${format}.js`, - formats: ["cjs", "es"] - }, - rollupOptions: { - external: [...Object.keys(peerDependencies), "react/jsx-runtime"] - }, - sourcemap: true, - emptyOutDir: true - }, - plugins: [ - dts({ - insertTypesEntry: true - }), - react({ fastRefresh: false }), - env.mode !== "test" && eslint({ - exclude: ["/virtual:/**", "node_modules/**", "/sb-preview/**"] - }) - ], - test: { - globals: true, - environment: "jsdom", - setupFiles: "./setupTests.ts" - } -})); -export { - vite_config_default as default -}; -//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiLCAicGFja2FnZS5qc29uIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZGlybmFtZSA9IFwiL1VzZXJzL2FuZ2Vsb3JlYWxlL2FyL2RyZWFtcGlwL29uZWlyb3NcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcIi9Vc2Vycy9hbmdlbG9yZWFsZS9hci9kcmVhbXBpcC9vbmVpcm9zL3ZpdGUuY29uZmlnLnRzXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ltcG9ydF9tZXRhX3VybCA9IFwiZmlsZTovLy9Vc2Vycy9hbmdlbG9yZWFsZS9hci9kcmVhbXBpcC9vbmVpcm9zL3ZpdGUuY29uZmlnLnRzXCI7Ly8vIDxyZWZlcmVuY2UgdHlwZXM9J3ZpdGVzdCcgLz5cbmltcG9ydCBlc2xpbnQgZnJvbSAndml0ZS1wbHVnaW4tZXNsaW50JztcbmltcG9ydCB7IGRlZmluZUNvbmZpZyB9IGZyb20gJ3ZpdGUnO1xuaW1wb3J0IHJlYWN0IGZyb20gJ0B2aXRlanMvcGx1Z2luLXJlYWN0JztcbmltcG9ydCBkdHMgZnJvbSAndml0ZS1wbHVnaW4tZHRzJztcbmltcG9ydCB7IHBlZXJEZXBlbmRlbmNpZXMgfSBmcm9tICcuL3BhY2thZ2UuanNvbic7XG5cbmV4cG9ydCBkZWZhdWx0IGRlZmluZUNvbmZpZygoZW52KSA9PiAoe1xuICBidWlsZDoge1xuICAgIGxpYjoge1xuICAgICAgZW50cnk6ICcuL3NyYy9pbmRleC50cycsXG4gICAgICBuYW1lOiAndml0ZS1yZWFjdC10cy1idXR0b24nLFxuICAgICAgZmlsZU5hbWU6IChmb3JtYXQpID0+IGBpbmRleC4ke2Zvcm1hdH0uanNgLFxuICAgICAgZm9ybWF0czogWydjanMnLCAnZXMnXSxcbiAgICB9LFxuICAgIHJvbGx1cE9wdGlvbnM6IHtcbiAgICAgIGV4dGVybmFsOiBbLi4uT2JqZWN0LmtleXMocGVlckRlcGVuZGVuY2llcyksICdyZWFjdC9qc3gtcnVudGltZSddLFxuICAgIH0sXG4gICAgc291cmNlbWFwOiB0cnVlLFxuICAgIGVtcHR5T3V0RGlyOiB0cnVlLFxuICB9LFxuICBwbHVnaW5zOiBbXG4gICAgZHRzKHtcbiAgICAgIGluc2VydFR5cGVzRW50cnk6IHRydWUsXG4gICAgfSksXG4gICAgcmVhY3QoeyBmYXN0UmVmcmVzaDogZmFsc2UgfSksXG4gICAgZW52Lm1vZGUgIT09ICd0ZXN0JyAmJlxuICAgICAgZXNsaW50KHtcbiAgICAgICAgZXhjbHVkZTogWycvdmlydHVhbDovKionLCAnbm9kZV9tb2R1bGVzLyoqJywgJy9zYi1wcmV2aWV3LyoqJ10sXG4gICAgICB9KSxcbiAgXSxcbiAgdGVzdDoge1xuICAgIGdsb2JhbHM6IHRydWUsXG4gICAgZW52aXJvbm1lbnQ6ICdqc2RvbScsXG4gICAgc2V0dXBGaWxlczogJy4vc2V0dXBUZXN0cy50cycsXG4gIH0sXG59KSk7XG4iLCAie1xuICBcIm5hbWVcIjogXCJAZHJlYW1waXBjb20vb25laXJvc1wiLFxuICBcInZlcnNpb25cIjogXCIwLjAuMVwiLFxuICBcImRlc2NyaXB0aW9uXCI6IFwiRHJlYW1QaXAncyBEZXNpZ24gU3lzdGVtIENvbXBvbmVudCBMaWJyYXJ5LlwiLFxuICBcInR5cGVcIjogXCJtb2R1bGVcIixcbiAgXCJtYWluXCI6IFwiZGlzdC9pbmRleC5janMuanNcIixcbiAgXCJtb2R1bGVcIjogXCJkaXN0L2luZGV4LmVzLmpzXCIsXG4gIFwidHlwZXNcIjogXCJkaXN0L2luZGV4LmQudHNcIixcbiAgXCJyZXBvc2l0b3J5XCI6IFwiaHR0cHM6Ly9naXRodWIuY29tL2RyZWFtcGlwY29tL29uZWlyb3NcIixcbiAgXCJmaWxlc1wiOiBbXG4gICAgXCIvZGlzdC8qKi8qXCJcbiAgXSxcbiAgXCJzY3JpcHRzXCI6IHtcbiAgICBcImZvcm1hdDppY29uc1wiOiBcInByZXR0aWVyIC0td3JpdGUgLS1wYXJzZXIgdHlwZXNjcmlwdCAnKiovKi57dHMsdHN4fSdcIixcbiAgICBcImxpbnQ6aWNvbnNcIjogXCJlc2xpbnQgLiAtLWV4dCAudHMsLnRzeCAtLWlnbm9yZS1wYXRoIC5naXRpZ25vcmUgLS1maXhcIixcbiAgICBcImZvcm1hdFwiOiBcInByZXR0aWVyIC0td3JpdGUgLS1wYXJzZXIgdHlwZXNjcmlwdCAnKiovKi57dHMsdHN4fScgLS1pZ25vcmUtcGF0aCAuaWdub3JlaWNvbnNcIixcbiAgICBcImxpbnRcIjogXCJlc2xpbnQgLiAtLWV4dCAudHMsLnRzeCAtLWlnbm9yZS1wYXRoIC5pZ25vcmVpY29ucyAtLWZpeFwiLFxuICAgIFwiYnVpbGRcIjogXCJ0c2MgLXAgdHNjb25maWcuanNvbiAmJiBjcCAuL3RhaWx3aW5kLmNvbmZpZy50cyAuL3B1YmxpYy8gJiYgdHNjIC1wIHRzY29uZmlnLWRpc3QuanNvbiAmJiB2aXRlIGJ1aWxkXCIsXG4gICAgXCJidWlsZDp3YXRjaFwiOiBcInRzYyAtcCB0c2NvbmZpZy5qc29uICYmIGNwIC4vdGFpbHdpbmQuY29uZmlnLnRzIC4vcHVibGljLyAmJiB0c2MgLXAgdHNjb25maWctZGlzdC5qc29uICYmIHZpdGUgYnVpbGQgLS13YXRjaFwiLFxuICAgIFwidGVzdFwiOiBcInZpdGVzdCBydW5cIixcbiAgICBcInRlc3Qtd2F0Y2hcIjogXCJ2aXRlc3RcIixcbiAgICBcInRlc3Q6dWlcIjogXCJ2aXRlc3QgLS11aVwiLFxuICAgIFwic3Rvcnlib29rXCI6IFwic3Rvcnlib29rIGRldiAtcCA2MDA2XCIsXG4gICAgXCJidWlsZC1zdG9yeWJvb2tcIjogXCJzdG9yeWJvb2sgYnVpbGRcIixcbiAgICBcImZvcm1hdDpmaXhcIjogXCJucG0gcnVuIGNpOmZvcm1hdFwiLFxuICAgIFwiY2k6Zm9ybWF0XCI6IFwibnBtIHJ1biBmb3JtYXQgJiYgbnBtIHJ1biBsaW50XCIsXG4gICAgXCJjaTpmb3JtYXQ6aWNvbnNcIjogXCJucG0gcnVuIGZvcm1hdDppY29ucyAmJiBucG0gcnVuIGxpbnQ6aWNvbnNcIixcbiAgICBcInByZXBhcmVcIjogXCJodXNreVwiLFxuICAgIFwic255ay1wcm90ZWN0XCI6IFwic255ay1wcm90ZWN0XCIsXG4gICAgXCJwcmVwdWJsaXNoT25seVwiOiBcIm5wbSBjaSAmJiBucG0gcnVuIGJ1aWxkXCJcbiAgfSxcbiAgXCJrZXl3b3Jkc1wiOiBbXG4gICAgXCJGcm9udC1FbmRcIixcbiAgICBcIkRlc2lnblwiLFxuICAgIFwiU3lzdGVtXCIsXG4gICAgXCJDb21wb25lbnRcIixcbiAgICBcIkxpYnJhcnlcIlxuICBdLFxuICBcImF1dGhvclwiOiBcIkFuZ2VsbyBSZWFsZVwiLFxuICBcImxpY2Vuc2VcIjogXCJIUEwzLUVDTy1BTkQtQU5DXCIsXG4gIFwiZGV2RGVwZW5kZW5jaWVzXCI6IHtcbiAgICBcIkBjaHJvbWF0aWMtY29tL3N0b3J5Ym9va1wiOiBcIjEuMy4zXCIsXG4gICAgXCJAZW1vdGlvbi9yZWFjdFwiOiBcIjExLjExLjRcIixcbiAgICBcIkBlbW90aW9uL3N0eWxlZFwiOiBcIjExLjExLjVcIixcbiAgICBcIkBtdWkvbWF0ZXJpYWxcIjogXCI1LjE1LjE1XCIsXG4gICAgXCJAbXVpL3gtZGF0ZS1waWNrZXJzLXByb1wiOiBcIl43LjguMFwiLFxuICAgIFwiQHNueWsvcHJvdGVjdFwiOiBcImxhdGVzdFwiLFxuICAgIFwiQHN0b3J5Ym9vay9hZGRvbi1hMTF5XCI6IFwiOC4wLjEwXCIsXG4gICAgXCJAc3Rvcnlib29rL2FkZG9uLWVzc2VudGlhbHNcIjogXCI4LjAuMTBcIixcbiAgICBcIkBzdG9yeWJvb2svYWRkb24taW50ZXJhY3Rpb25zXCI6IFwiOC4wLjEwXCIsXG4gICAgXCJAc3Rvcnlib29rL2FkZG9uLWxpbmtzXCI6IFwiOC4wLjEwXCIsXG4gICAgXCJAc3Rvcnlib29rL2FkZG9uLW9uYm9hcmRpbmdcIjogXCI4LjAuMTBcIixcbiAgICBcIkBzdG9yeWJvb2svYWRkb24tdGhlbWVzXCI6IFwiOC4wLjEwXCIsXG4gICAgXCJAc3Rvcnlib29rL2Jsb2Nrc1wiOiBcIjguMC4xMFwiLFxuICAgIFwiQHN0b3J5Ym9vay9idWlsZGVyLXZpdGVcIjogXCI4LjAuMTBcIixcbiAgICBcIkBzdG9yeWJvb2svcmVhY3RcIjogXCI4LjAuMTBcIixcbiAgICBcIkBzdG9yeWJvb2svcmVhY3Qtdml0ZVwiOiBcIjguMC4xMFwiLFxuICAgIFwiQHN0b3J5Ym9vay90ZXN0XCI6IFwiOC4wLjEwXCIsXG4gICAgXCJAdGVzdGluZy1saWJyYXJ5L2plc3QtZG9tXCI6IFwiNi40LjJcIixcbiAgICBcIkB0ZXN0aW5nLWxpYnJhcnkvcmVhY3RcIjogXCIxNS4wLjJcIixcbiAgICBcIkB0eXBlcy9yZWFjdFwiOiBcIjE4LjIuNzlcIixcbiAgICBcIkB0eXBlcy9yZWFjdC1kb21cIjogXCIxOFwiLFxuICAgIFwiQHR5cGVzY3JpcHQtZXNsaW50L2VzbGludC1wbHVnaW5cIjogXCI3LjcuMFwiLFxuICAgIFwiQHR5cGVzY3JpcHQtZXNsaW50L3BhcnNlclwiOiBcIjcuNy4wXCIsXG4gICAgXCJAdml0ZWpzL3BsdWdpbi1yZWFjdFwiOiBcIjQuMi4xXCIsXG4gICAgXCJhdXRvcHJlZml4ZXJcIjogXCIxMC40LjE5XCIsXG4gICAgXCJlc2xpbnRcIjogXCI4LjU3LjBcIixcbiAgICBcImVzbGludC1jb25maWctYWlyYm5iXCI6IFwiMTkuMC40XCIsXG4gICAgXCJlc2xpbnQtY29uZmlnLXByZXR0aWVyXCI6IFwiOS4xLjBcIixcbiAgICBcImVzbGludC1wbHVnaW4taW1wb3J0XCI6IFwiMi4yOS4xXCIsXG4gICAgXCJlc2xpbnQtcGx1Z2luLWpzeC1hMTF5XCI6IFwiNi44LjBcIixcbiAgICBcImVzbGludC1wbHVnaW4tcHJldHRpZXJcIjogXCI1LjEuM1wiLFxuICAgIFwiZXNsaW50LXBsdWdpbi1yZWFjdFwiOiBcIjcuMzQuMVwiLFxuICAgIFwiZXNsaW50LXBsdWdpbi1yZWFjdC1ob29rc1wiOiBcIjQuNi4wXCIsXG4gICAgXCJlc2xpbnQtcGx1Z2luLXN0b3J5Ym9va1wiOiBcIjAuOC4wXCIsXG4gICAgXCJodXNreVwiOiBcIl45LjAuMTFcIixcbiAgICBcImpzZG9tXCI6IFwiMjQuMC4wXCIsXG4gICAgXCJsb2Rhc2hcIjogXCI0LjE3LjIxXCIsXG4gICAgXCJtb21lbnRcIjogXCJeMi4zMC4xXCIsXG4gICAgXCJwb3N0Y3NzXCI6IFwiOC40LjM4XCIsXG4gICAgXCJwcmV0dGllclwiOiBcIjMuMi41XCIsXG4gICAgXCJzdG9yeWJvb2tcIjogXCJeOC4xLjExXCIsXG4gICAgXCJ2aXRlXCI6IFwiNS4yLjlcIixcbiAgICBcInZpdGUtcGx1Z2luLWR0c1wiOiBcIjMuOC4zXCIsXG4gICAgXCJ2aXRlLXBsdWdpbi1lc2xpbnRcIjogXCJeMS44LjFcIixcbiAgICBcInZpdGUtdHNjb25maWctcGF0aHNcIjogXCI0LjMuMlwiLFxuICAgIFwidml0ZXN0XCI6IFwiMS41LjBcIlxuICB9LFxuICBcInBlZXJEZXBlbmRlbmNpZXNcIjoge1xuICAgIFwiY2xzeFwiOiBcIjIuMS4wXCIsXG4gICAgXCJsYXp5c2l6ZXNcIjogXCJeNS4zLjJcIixcbiAgICBcInJlYWN0XCI6IFwiXjE4LjIuMFwiLFxuICAgIFwicmVhY3QtZG9tXCI6IFwiXjE4LjIuMFwiLFxuICAgIFwidGFpbHdpbmRjc3NcIjogXCIzLjQuNFwiLFxuICAgIFwidHlwZXNjcmlwdFwiOiBcIjUuNC41XCJcbiAgfSxcbiAgXCJvcHRpb25hbERlcGVuZGVuY2llc1wiOiB7XG4gICAgXCJAcm9sbHVwL3JvbGx1cC1saW51eC14NjQtZ251XCI6IFwiNC45LjVcIlxuICB9LFxuICBcInNueWtcIjogdHJ1ZVxufVxuIl0sCiAgIm1hcHBpbmdzIjogIjtBQUNBLE9BQU8sWUFBWTtBQUNuQixTQUFTLG9CQUFvQjtBQUM3QixPQUFPLFdBQVc7QUFDbEIsT0FBTyxTQUFTOzs7QUNvRmQsdUJBQW9CO0FBQUEsRUFDbEIsTUFBUTtBQUFBLEVBQ1IsV0FBYTtBQUFBLEVBQ2IsT0FBUztBQUFBLEVBQ1QsYUFBYTtBQUFBLEVBQ2IsYUFBZTtBQUFBLEVBQ2YsWUFBYztBQUNoQjs7O0FEeEZGLElBQU8sc0JBQVEsYUFBYSxDQUFDLFNBQVM7QUFBQSxFQUNwQyxPQUFPO0FBQUEsSUFDTCxLQUFLO0FBQUEsTUFDSCxPQUFPO0FBQUEsTUFDUCxNQUFNO0FBQUEsTUFDTixVQUFVLENBQUMsV0FBVyxTQUFTLE1BQU07QUFBQSxNQUNyQyxTQUFTLENBQUMsT0FBTyxJQUFJO0FBQUEsSUFDdkI7QUFBQSxJQUNBLGVBQWU7QUFBQSxNQUNiLFVBQVUsQ0FBQyxHQUFHLE9BQU8sS0FBSyxnQkFBZ0IsR0FBRyxtQkFBbUI7QUFBQSxJQUNsRTtBQUFBLElBQ0EsV0FBVztBQUFBLElBQ1gsYUFBYTtBQUFBLEVBQ2Y7QUFBQSxFQUNBLFNBQVM7QUFBQSxJQUNQLElBQUk7QUFBQSxNQUNGLGtCQUFrQjtBQUFBLElBQ3BCLENBQUM7QUFBQSxJQUNELE1BQU0sRUFBRSxhQUFhLE1BQU0sQ0FBQztBQUFBLElBQzVCLElBQUksU0FBUyxVQUNYLE9BQU87QUFBQSxNQUNMLFNBQVMsQ0FBQyxnQkFBZ0IsbUJBQW1CLGdCQUFnQjtBQUFBLElBQy9ELENBQUM7QUFBQSxFQUNMO0FBQUEsRUFDQSxNQUFNO0FBQUEsSUFDSixTQUFTO0FBQUEsSUFDVCxhQUFhO0FBQUEsSUFDYixZQUFZO0FBQUEsRUFDZDtBQUNGLEVBQUU7IiwKICAibmFtZXMiOiBbXQp9Cg==