Merge branch 'main' into initial-e2e-test-setup

This commit is contained in:
mahula 2025-03-01 16:15:50 +01:00
commit 100cc51551
63 changed files with 776 additions and 803 deletions

View File

@ -80,7 +80,7 @@ module.exports = {
'import/no-relative-parent-imports': [
'error',
{
ignore: ['#[src,types,root,components,utils]/*'],
ignore: ['#[src,types,root,components,utils,assets]/*'],
},
],
'import/no-self-import': 'error',

View File

@ -19,14 +19,26 @@ jobs:
run: |
npm install
npm run build
npm link
working-directory: ./
- name: Build static files
id: build
run: npm install && npm run docs:generate
run: npm run docs:generate
working-directory: ./
- name: Generate coverage
id: coverage
run: npm run test:unit
- name: Create coverage badges
id: coverage-badge
uses: jaywcjlove/coverage-badges-cli@main
with:
style: flat
source: coverage/coverage-summary.json
output: docs/test-coverage.svg
jsonPath: total.lines.pct
- name: Upload static files as artifact
id: deployment
uses: actions/upload-pages-artifact@v3.0.1

View File

@ -16,7 +16,8 @@ jobs:
filters: |
docs:
- '.github/workflows/**/*'
- '**/*'
- '**/*.md'
- 'LICENSE'
# build:
# if: needs.files-changed.outputs.frontend == 'true'

View File

@ -17,6 +17,8 @@ jobs:
unit:
- '.github/workflows/**/*'
- '**/*'
- '!**/*.md'
predicate-quantifier: 'every'
unit:
if: needs.files-changed.outputs.unit == 'true'

View File

@ -1,4 +1,4 @@
# Utopia UI [![npm version](https://img.shields.io/npm/v/utopia-ui.svg)](https://www.npmjs.com/package/utopia-ui) ![Build Status](https://img.shields.io/github/actions/workflow/status/utopia-os/utopia-ui/test.build.yml?branch=main) [![Docs Coverage](https://utopia-os.org/utopia-ui/coverage.svg)](https://utopia-os.org/utopia-ui/) ![License](https://img.shields.io/github/license/utopia-os/utopia-ui)
# Utopia UI [![npm version](https://img.shields.io/npm/v/utopia-ui.svg)](https://www.npmjs.com/package/utopia-ui) ![Build Status](https://img.shields.io/github/actions/workflow/status/utopia-os/utopia-ui/test.build.yml?branch=main) ![Test Coverage](https://utopia-os.org/utopia-ui/test-coverage.svg) [![Docs Coverage](https://utopia-os.org/utopia-ui/coverage.svg)](https://utopia-os.org/utopia-ui/) ![License](https://img.shields.io/github/license/utopia-os/utopia-ui)
**UI Framework for Real-Life-Networking-Apps**

566
package-lock.json generated
View File

@ -1,12 +1,12 @@
{
"name": "utopia-ui",
"version": "3.0.64",
"version": "3.0.74",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "utopia-ui",
"version": "3.0.64",
"version": "3.0.74",
"license": "GPL-3.0-only",
"dependencies": {
"@heroicons/react": "^2.0.17",
@ -72,12 +72,14 @@
"rollup": "^4.34.6",
"rollup-plugin-dts": "^6.1.1",
"rollup-plugin-postcss": "^4.0.2",
"rollup-plugin-svg": "^2.0.0",
"tailwindcss": "^3.3.1",
"typedoc": "^0.27.6",
"typedoc-plugin-coverage": "^3.4.1",
"typedoc-plugin-missing-exports": "^3.1.0",
"typescript": "^5.7.3",
"vite": "^6.0.11",
"vite-plugin-svgr": "^4.3.0",
"vitest": "^3.0.5"
},
"peerDependencies": {
@ -1226,14 +1228,13 @@
}
},
"node_modules/@esbuild/aix-ppc64": {
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz",
"integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==",
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.0.tgz",
"integrity": "sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"aix"
@ -1243,14 +1244,13 @@
}
},
"node_modules/@esbuild/android-arm": {
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz",
"integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==",
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.0.tgz",
"integrity": "sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
@ -1260,14 +1260,13 @@
}
},
"node_modules/@esbuild/android-arm64": {
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz",
"integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==",
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.0.tgz",
"integrity": "sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
@ -1277,14 +1276,13 @@
}
},
"node_modules/@esbuild/android-x64": {
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz",
"integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==",
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.0.tgz",
"integrity": "sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
@ -1294,14 +1292,13 @@
}
},
"node_modules/@esbuild/darwin-arm64": {
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz",
"integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==",
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.0.tgz",
"integrity": "sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
@ -1311,14 +1308,13 @@
}
},
"node_modules/@esbuild/darwin-x64": {
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz",
"integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==",
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.0.tgz",
"integrity": "sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
@ -1328,14 +1324,13 @@
}
},
"node_modules/@esbuild/freebsd-arm64": {
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz",
"integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==",
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.0.tgz",
"integrity": "sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
@ -1345,14 +1340,13 @@
}
},
"node_modules/@esbuild/freebsd-x64": {
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz",
"integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==",
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.0.tgz",
"integrity": "sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
@ -1362,14 +1356,13 @@
}
},
"node_modules/@esbuild/linux-arm": {
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz",
"integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==",
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.0.tgz",
"integrity": "sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
@ -1379,14 +1372,13 @@
}
},
"node_modules/@esbuild/linux-arm64": {
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz",
"integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==",
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.0.tgz",
"integrity": "sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
@ -1396,14 +1388,13 @@
}
},
"node_modules/@esbuild/linux-ia32": {
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz",
"integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==",
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.0.tgz",
"integrity": "sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
@ -1413,14 +1404,13 @@
}
},
"node_modules/@esbuild/linux-loong64": {
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz",
"integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==",
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.0.tgz",
"integrity": "sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==",
"cpu": [
"loong64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
@ -1430,14 +1420,13 @@
}
},
"node_modules/@esbuild/linux-mips64el": {
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz",
"integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==",
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.0.tgz",
"integrity": "sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==",
"cpu": [
"mips64el"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
@ -1447,14 +1436,13 @@
}
},
"node_modules/@esbuild/linux-ppc64": {
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz",
"integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==",
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.0.tgz",
"integrity": "sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
@ -1464,14 +1452,13 @@
}
},
"node_modules/@esbuild/linux-riscv64": {
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz",
"integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==",
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.0.tgz",
"integrity": "sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==",
"cpu": [
"riscv64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
@ -1481,14 +1468,13 @@
}
},
"node_modules/@esbuild/linux-s390x": {
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz",
"integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==",
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.0.tgz",
"integrity": "sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==",
"cpu": [
"s390x"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
@ -1498,14 +1484,13 @@
}
},
"node_modules/@esbuild/linux-x64": {
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz",
"integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==",
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.0.tgz",
"integrity": "sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
@ -1515,14 +1500,13 @@
}
},
"node_modules/@esbuild/netbsd-arm64": {
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz",
"integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==",
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.0.tgz",
"integrity": "sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
@ -1532,14 +1516,13 @@
}
},
"node_modules/@esbuild/netbsd-x64": {
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz",
"integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==",
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.0.tgz",
"integrity": "sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
@ -1549,14 +1532,13 @@
}
},
"node_modules/@esbuild/openbsd-arm64": {
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz",
"integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==",
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.0.tgz",
"integrity": "sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
@ -1566,14 +1548,13 @@
}
},
"node_modules/@esbuild/openbsd-x64": {
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz",
"integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==",
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.0.tgz",
"integrity": "sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
@ -1583,14 +1564,13 @@
}
},
"node_modules/@esbuild/sunos-x64": {
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz",
"integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==",
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.0.tgz",
"integrity": "sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"sunos"
@ -1600,14 +1580,13 @@
}
},
"node_modules/@esbuild/win32-arm64": {
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz",
"integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==",
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.0.tgz",
"integrity": "sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
@ -1617,14 +1596,13 @@
}
},
"node_modules/@esbuild/win32-ia32": {
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz",
"integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==",
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.0.tgz",
"integrity": "sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
@ -1634,14 +1612,13 @@
}
},
"node_modules/@esbuild/win32-x64": {
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz",
"integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==",
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.0.tgz",
"integrity": "sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
@ -2449,6 +2426,244 @@
"dev": true,
"license": "MIT"
},
"node_modules/@svgr/babel-plugin-add-jsx-attribute": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz",
"integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=14"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/gregberge"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@svgr/babel-plugin-remove-jsx-attribute": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz",
"integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=14"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/gregberge"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz",
"integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=14"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/gregberge"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz",
"integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=14"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/gregberge"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@svgr/babel-plugin-svg-dynamic-title": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz",
"integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=14"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/gregberge"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@svgr/babel-plugin-svg-em-dimensions": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz",
"integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=14"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/gregberge"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@svgr/babel-plugin-transform-react-native-svg": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz",
"integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=14"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/gregberge"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@svgr/babel-plugin-transform-svg-component": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz",
"integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/gregberge"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@svgr/babel-preset": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz",
"integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==",
"dev": true,
"license": "MIT",
"dependencies": {
"@svgr/babel-plugin-add-jsx-attribute": "8.0.0",
"@svgr/babel-plugin-remove-jsx-attribute": "8.0.0",
"@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0",
"@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0",
"@svgr/babel-plugin-svg-dynamic-title": "8.0.0",
"@svgr/babel-plugin-svg-em-dimensions": "8.0.0",
"@svgr/babel-plugin-transform-react-native-svg": "8.1.0",
"@svgr/babel-plugin-transform-svg-component": "8.0.0"
},
"engines": {
"node": ">=14"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/gregberge"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@svgr/core": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz",
"integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/core": "^7.21.3",
"@svgr/babel-preset": "8.1.0",
"camelcase": "^6.2.0",
"cosmiconfig": "^8.1.3",
"snake-case": "^3.0.4"
},
"engines": {
"node": ">=14"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/gregberge"
}
},
"node_modules/@svgr/hast-util-to-babel-ast": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz",
"integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.21.3",
"entities": "^4.4.0"
},
"engines": {
"node": ">=14"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/gregberge"
}
},
"node_modules/@svgr/hast-util-to-babel-ast/node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/@svgr/plugin-jsx": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz",
"integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/core": "^7.21.3",
"@svgr/babel-preset": "8.1.0",
"@svgr/hast-util-to-babel-ast": "8.0.0",
"svg-parser": "^2.0.4"
},
"engines": {
"node": ">=14"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/gregberge"
},
"peerDependencies": {
"@svgr/core": "*"
}
},
"node_modules/@tanstack/query-core": {
"version": "5.66.4",
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.66.4.tgz",
@ -5610,6 +5825,17 @@
"url": "https://github.com/fb55/domutils?sponsor=1"
}
},
"node_modules/dot-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz",
"integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==",
"dev": true,
"license": "MIT",
"dependencies": {
"no-case": "^3.0.4",
"tslib": "^2.0.3"
}
},
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
@ -5941,12 +6167,11 @@
}
},
"node_modules/esbuild": {
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz",
"integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==",
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.0.tgz",
"integrity": "sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"bin": {
"esbuild": "bin/esbuild"
},
@ -5954,31 +6179,31 @@
"node": ">=18"
},
"optionalDependencies": {
"@esbuild/aix-ppc64": "0.24.2",
"@esbuild/android-arm": "0.24.2",
"@esbuild/android-arm64": "0.24.2",
"@esbuild/android-x64": "0.24.2",
"@esbuild/darwin-arm64": "0.24.2",
"@esbuild/darwin-x64": "0.24.2",
"@esbuild/freebsd-arm64": "0.24.2",
"@esbuild/freebsd-x64": "0.24.2",
"@esbuild/linux-arm": "0.24.2",
"@esbuild/linux-arm64": "0.24.2",
"@esbuild/linux-ia32": "0.24.2",
"@esbuild/linux-loong64": "0.24.2",
"@esbuild/linux-mips64el": "0.24.2",
"@esbuild/linux-ppc64": "0.24.2",
"@esbuild/linux-riscv64": "0.24.2",
"@esbuild/linux-s390x": "0.24.2",
"@esbuild/linux-x64": "0.24.2",
"@esbuild/netbsd-arm64": "0.24.2",
"@esbuild/netbsd-x64": "0.24.2",
"@esbuild/openbsd-arm64": "0.24.2",
"@esbuild/openbsd-x64": "0.24.2",
"@esbuild/sunos-x64": "0.24.2",
"@esbuild/win32-arm64": "0.24.2",
"@esbuild/win32-ia32": "0.24.2",
"@esbuild/win32-x64": "0.24.2"
"@esbuild/aix-ppc64": "0.25.0",
"@esbuild/android-arm": "0.25.0",
"@esbuild/android-arm64": "0.25.0",
"@esbuild/android-x64": "0.25.0",
"@esbuild/darwin-arm64": "0.25.0",
"@esbuild/darwin-x64": "0.25.0",
"@esbuild/freebsd-arm64": "0.25.0",
"@esbuild/freebsd-x64": "0.25.0",
"@esbuild/linux-arm": "0.25.0",
"@esbuild/linux-arm64": "0.25.0",
"@esbuild/linux-ia32": "0.25.0",
"@esbuild/linux-loong64": "0.25.0",
"@esbuild/linux-mips64el": "0.25.0",
"@esbuild/linux-ppc64": "0.25.0",
"@esbuild/linux-riscv64": "0.25.0",
"@esbuild/linux-s390x": "0.25.0",
"@esbuild/linux-x64": "0.25.0",
"@esbuild/netbsd-arm64": "0.25.0",
"@esbuild/netbsd-x64": "0.25.0",
"@esbuild/openbsd-arm64": "0.25.0",
"@esbuild/openbsd-x64": "0.25.0",
"@esbuild/sunos-x64": "0.25.0",
"@esbuild/win32-arm64": "0.25.0",
"@esbuild/win32-ia32": "0.25.0",
"@esbuild/win32-x64": "0.25.0"
}
},
"node_modules/escalade": {
@ -10998,9 +11223,9 @@
}
},
"node_modules/postcss": {
"version": "8.5.2",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.2.tgz",
"integrity": "sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==",
"version": "8.5.3",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
"integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
"funding": [
{
"type": "opencollective",
@ -11015,7 +11240,6 @@
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"dependencies": {
"nanoid": "^3.3.8",
"picocolors": "^1.1.1",
@ -12772,6 +12996,34 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/rollup-plugin-svg": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/rollup-plugin-svg/-/rollup-plugin-svg-2.0.0.tgz",
"integrity": "sha512-DmE7dSQHo1SC5L2uH2qul3Mjyd5oV6U1aVVkyvTLX/mUsRink7f1b1zaIm+32GEBA6EHu8H/JJi3DdWqM53ySQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"rollup-pluginutils": "^1.3.1"
}
},
"node_modules/rollup-plugin-svg/node_modules/estree-walker": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.2.1.tgz",
"integrity": "sha512-6/I1dwNKk0N9iGOU3ydzAAurz4NPo/ttxZNCqgIVbWFvWyzWBSNonRrJ5CpjDuyBfmM7ENN7WCzUi9aT/UPXXQ==",
"dev": true,
"license": "MIT"
},
"node_modules/rollup-plugin-svg/node_modules/rollup-pluginutils": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz",
"integrity": "sha512-SjdWWWO/CUoMpDy8RUbZ/pSpG68YHmhk5ROKNIoi2En9bJ8bTt3IhYi254RWiTclQmL7Awmrq+rZFOhZkJAHmQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"estree-walker": "^0.2.1",
"minimatch": "^3.0.2"
}
},
"node_modules/rollup-pluginutils": {
"version": "2.8.2",
"resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz",
@ -13208,6 +13460,17 @@
"node": ">=8"
}
},
"node_modules/snake-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz",
"integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==",
"dev": true,
"license": "MIT",
"dependencies": {
"dot-case": "^3.0.4",
"tslib": "^2.0.3"
}
},
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@ -13804,6 +14067,13 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/svg-parser": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz",
"integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==",
"dev": true,
"license": "MIT"
},
"node_modules/svgo": {
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz",
@ -15394,14 +15664,13 @@
}
},
"node_modules/vite": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.1.0.tgz",
"integrity": "sha512-RjjMipCKVoR4hVfPY6GQTgveinjNuyLw+qruksLDvA5ktI1150VmcMBKmQaEWJhg/j6Uaf6dNCNA0AfdzUb/hQ==",
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.2.0.tgz",
"integrity": "sha512-7dPxoo+WsT/64rDcwoOjk76XHj+TqNTIvHKcuMQ1k4/SeHDaQt5GFAeLYzrimZrMpn/O6DtdI03WUjdxuPM0oQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"esbuild": "^0.24.2",
"postcss": "^8.5.1",
"esbuild": "^0.25.0",
"postcss": "^8.5.3",
"rollup": "^4.30.1"
},
"bin": {
@ -15488,6 +15757,21 @@
"url": "https://opencollective.com/vitest"
}
},
"node_modules/vite-plugin-svgr": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/vite-plugin-svgr/-/vite-plugin-svgr-4.3.0.tgz",
"integrity": "sha512-Jy9qLB2/PyWklpYy0xk0UU3TlU0t2UMpJXZvf+hWII1lAmRHrOUKi11Uw8N3rxoNk7atZNYO3pR3vI1f7oi+6w==",
"dev": true,
"license": "MIT",
"dependencies": {
"@rollup/pluginutils": "^5.1.3",
"@svgr/core": "^8.1.0",
"@svgr/plugin-jsx": "^8.1.0"
},
"peerDependencies": {
"vite": ">=2.6.0"
}
},
"node_modules/vitest": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.5.tgz",

View File

@ -1,6 +1,6 @@
{
"name": "utopia-ui",
"version": "3.0.64",
"version": "3.0.74",
"description": "Reuseable React Components to build mapping apps for real life communities and networks",
"repository": "https://github.com/utopia-os/utopia-ui",
"homepage": "https://utopia-os.org/",
@ -79,12 +79,14 @@
"rollup": "^4.34.6",
"rollup-plugin-dts": "^6.1.1",
"rollup-plugin-postcss": "^4.0.2",
"rollup-plugin-svg": "^2.0.0",
"tailwindcss": "^3.3.1",
"typedoc": "^0.27.6",
"typedoc-plugin-coverage": "^3.4.1",
"typedoc-plugin-missing-exports": "^3.1.0",
"typescript": "^5.7.3",
"vite": "^6.0.11",
"vite-plugin-svgr": "^4.3.0",
"vitest": "^3.0.5"
},
"peerDependencies": {
@ -112,6 +114,7 @@
"yet-another-react-lightbox": "^3.21.7"
},
"imports": {
"#assets/*": "./src/assets/*",
"#components/*": "./src/Components/*",
"#utils/*": "./src/Utils/*",
"#types/*": "./src/types/*",

View File

@ -6,6 +6,7 @@ import resolve from '@rollup/plugin-node-resolve'
import typescript from '@rollup/plugin-typescript'
import { dts } from 'rollup-plugin-dts'
import postcss from 'rollup-plugin-postcss'
import svg from 'rollup-plugin-svg'
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
@ -39,7 +40,9 @@ export default [
}),
typescript({
tsconfig: './tsconfig.json',
noEmitOnError: true,
}),
svg({ base64: true }),
],
external: [
'react',

View File

@ -17,7 +17,6 @@ export function AppShell({
appName: string
children: React.ReactNode
assetsApi: AssetsApi
userType: string
}) {
return (
<ContextWrapper>

View File

@ -1,3 +1,5 @@
import Bars3Icon from '@heroicons/react/16/solid/Bars3Icon'
import EllipsisVerticalIcon from '@heroicons/react/16/solid/EllipsisVerticalIcon'
import QuestionMarkIcon from '@heroicons/react/24/outline/QuestionMarkCircleIcon'
import { useEffect, useRef, useState } from 'react'
import { Link, useLocation } from 'react-router-dom'
@ -68,19 +70,7 @@ export default function NavBar({ appName }: { appName: string }) {
aria-controls='#sidenav'
aria-haspopup='true'
>
<svg
xmlns='http://www.w3.org/2000/svg'
fill='none'
viewBox='0 0 24 24'
className='tw-inline-block tw-w-5 tw-h-5 tw-stroke-current'
>
<path
strokeLinecap='round'
strokeLinejoin='round'
strokeWidth='2'
d='M4 6h16M4 12h16M4 18h16'
></path>
</svg>
<Bars3Icon className='tw-inline-block tw-w-5 tw-h-5' />
</button>
<div className='tw-flex-1 tw-mr-2'>
<div
@ -121,14 +111,7 @@ export default function NavBar({ appName }: { appName: string }) {
</Link>
<div className='tw-dropdown tw-dropdown-end'>
<label tabIndex={0} className='tw-btn tw-btn-ghost tw-btn-square'>
<svg
xmlns='http://www.w3.org/2000/svg'
className='tw-h-5 tw-w-5'
viewBox='0 0 20 20'
fill='currentColor'
>
<path d='M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z' />
</svg>
<EllipsisVerticalIcon className='tw-h-5 tw-w-5' />
</label>
<ul
tabIndex={0}
@ -165,14 +148,7 @@ export default function NavBar({ appName }: { appName: string }) {
</div>
<div className='tw-dropdown tw-dropdown-end'>
<label tabIndex={1} className='tw-btn tw-btn-ghost md:tw-hidden'>
<svg
xmlns='http://www.w3.org/2000/svg'
className='tw-h-5 tw-w-5'
viewBox='0 0 20 20'
fill='currentColor'
>
<path d='M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z' />
</svg>
<EllipsisVerticalIcon className='tw-h-5 tw-w-5' />
</label>
<ul
tabIndex={1}

View File

@ -1,41 +0,0 @@
/* eslint-disable @typescript-eslint/restrict-template-expressions */
import { useEffect, useState } from 'react'
import { useItems } from '#components/Map/hooks/useItems'
/**
* @category AppShell
*/
export const Sitemap = ({ url }: { url: string }) => {
const [sitemap, setSitemap] = useState('')
const items = useItems()
useEffect(() => {
if (items.length) {
const generateSitemap = () => {
let sitemapXML = '<?xml version="1.0" encoding="UTF-8"?>\n'
sitemapXML += '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n'
items.forEach((item) => {
sitemapXML += ' <url>\n'
sitemapXML += ` <loc>${url}/${item.slug}</loc>\n`
sitemapXML += ' </url>\n'
})
sitemapXML += '</urlset>'
return sitemapXML
}
setSitemap(generateSitemap())
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [items])
return (
<div>
<h1>Sitemap</h1>
<textarea value={sitemap} readOnly rows={items.length + 4} cols={80} />
</div>
)
}

View File

@ -1,4 +1,3 @@
export * from './AppShell'
export { SideBar } from './SideBar'
export { Content } from './Content'
export { Sitemap } from './Sitemap'

View File

@ -1,3 +1,4 @@
import QuestionMarkCircleIcon from '@heroicons/react/24/outline/QuestionMarkCircleIcon'
import { useEffect, useState } from 'react'
import { useAuth } from '#components/Auth/useAuth'
@ -50,20 +51,7 @@ export function Quests() {
</div>
<h2 className='tw-card-title tw-m-auto '>
Level 1
<svg
xmlns='http://www.w3.org/2000/svg'
fill='none'
viewBox='0 0 24 24'
strokeWidth={1.5}
stroke='#aaa'
className='tw-w-5 tw-h-5 tw-cursor-pointer'
>
<path
strokeLinecap='round'
strokeLinejoin='round'
d='M9.879 7.519c1.171-1.025 3.071-1.025 4.242 0 1.172 1.025 1.172 2.687 0 3.712-.203.179-.43.326-.67.442-.745.361-1.45.999-1.45 1.827v.75M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9 5.25h.008v.008H12v-.008z'
/>
</svg>
<QuestionMarkCircleIcon />
</h2>
<ul className='tw-flex-row'>
<li>

View File

@ -0,0 +1,32 @@
import { render, screen, fireEvent } from '@testing-library/react'
import { describe, it, expect, beforeEach, vi } from 'vitest'
import ComboBoxInput from './ComboBoxInput'
describe('<ComboBoxInput />', () => {
let wrapper: ReturnType<typeof render>
const updateFormValue = vi.fn()
beforeEach(() => {
vi.clearAllMocks()
wrapper = render(
<ComboBoxInput
value={'option-1'}
onValueChange={updateFormValue}
options={['Option 1', 'Option 2']}
/>,
)
})
it('renders properly', () => {
expect(wrapper.container.firstChild).toMatchSnapshot()
})
describe('handleChange', () => {
it('calls updateFormValue with new value', () => {
fireEvent.change(screen.getByRole('combobox'), { target: { value: 'Option 2' } })
expect(updateFormValue).toBeCalledWith('Option 2')
})
})
})

View File

@ -1,74 +0,0 @@
import InformationCircleIcon from '@heroicons/react/24/outline/InformationCircleIcon'
import { useState } from 'react'
interface SelectBoxProps {
labelTitle?: string
labelStyle?: string
type?: string
containerStyle?: string
defaultValue: string
placeholder?: string
updateFormValue: (value: string) => void
options: { name: string; value: string }[]
labelDescription?: string
}
/**
* @category Input
*/
export function SelectBox(props: SelectBoxProps) {
const {
labelTitle,
labelDescription,
defaultValue,
containerStyle,
placeholder,
labelStyle,
options,
updateFormValue,
} = props
const [value, setValue] = useState(defaultValue || '')
const updateValue = (newValue: string) => {
updateFormValue(newValue)
setValue(newValue)
}
return (
<div className={`tw-inline-block ${containerStyle ?? ''}`}>
{labelTitle ? (
<label className={`tw-label ${labelStyle ?? ''}`}>
<div className='tw-label-text'>
{labelTitle}
{labelDescription && (
<div className='tw-tooltip tw-tooltip-right' data-tip={labelDescription}>
<InformationCircleIcon className='tw-w-4 tw-h-4' />
</div>
)}
</div>
</label>
) : (
''
)}
<select
className='tw-select tw-select-bordered tw-w-full'
value={value}
onChange={(e) => updateValue(e.target.value)}
>
<option disabled value='PLACEHOLDER'>
{placeholder}
</option>
{options.map((o, k) => {
return (
<option value={o.value || o.name} key={k}>
{o.name}
</option>
)
})}
</select>
</div>
)
}

View File

@ -0,0 +1,33 @@
import { render, screen, fireEvent } from '@testing-library/react'
import { describe, it, expect, beforeEach, vi } from 'vitest'
import { TextAreaInput } from './TextAreaInput'
describe('<TextAreaInput />', () => {
let wrapper: ReturnType<typeof render>
const updateFormValue = vi.fn()
beforeEach(() => {
vi.clearAllMocks()
wrapper = render(<TextAreaInput defaultValue={''} updateFormValue={updateFormValue} />)
})
it('renders properly', () => {
expect(wrapper.container.firstChild).toMatchSnapshot()
})
describe('handleChange', () => {
it('calls updateFormValue with new value', () => {
fireEvent.change(screen.getByRole('textbox'), { target: { value: 'test' } })
expect(updateFormValue).toBeCalledWith('test')
})
})
describe('labelTitle', () => {
it('sets label', () => {
wrapper.rerender(<TextAreaInput defaultValue={''} labelTitle='My Title' />)
expect(wrapper.container.firstChild).toMatchSnapshot()
})
})
})

View File

@ -1,7 +1,5 @@
import { useEffect, useRef, useState } from 'react'
import { useTags } from '#components/Map/hooks/useTags'
interface TextAreaProps {
labelTitle?: string
labelStyle?: string
@ -14,8 +12,6 @@ interface TextAreaProps {
updateFormValue?: (value: string) => void
}
type KeyValue = Record<string, string>
/**
* @category Input
*/
@ -33,14 +29,6 @@ export function TextAreaInput({
const ref = useRef<HTMLTextAreaElement>(null)
const [inputValue, setInputValue] = useState<string>(defaultValue)
const tags = useTags()
const values: KeyValue[] = []
tags.forEach((tag) => {
values.push({ key: tag.name, value: tag.name, color: tag.color })
})
useEffect(() => {
setInputValue(defaultValue)
}, [defaultValue])

View File

@ -0,0 +1,18 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`<ComboBoxInput /> > renders properly 1`] = `
<select
class="tw-form-select tw-block tw-w-full tw-py-2 tw-px-4 tw-border tw-border-gray-300 rounded-md tw-shadow-sm tw-text-sm focus:tw-outline-none focus:tw-ring-indigo-500 focus:tw-border-indigo-500 sm:tw-text-sm"
>
<option
value="Option 1"
>
Option 1
</option>
<option
value="Option 2"
>
Option 2
</option>
</select>
`;

View File

@ -0,0 +1,34 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`<TextAreaInput /> > labelTitle > sets label 1`] = `
<div
class="tw-form-control tw-w-full "
>
<label
class="tw-label"
>
<span
class="tw-label-text tw-text-base-content "
>
My Title
</span>
</label>
<textarea
class="tw-textarea tw-textarea-bordered tw-w-full tw-leading-5 "
placeholder=""
required=""
/>
</div>
`;
exports[`<TextAreaInput /> > renders properly 1`] = `
<div
class="tw-form-control tw-w-full "
>
<textarea
class="tw-textarea tw-textarea-bordered tw-w-full tw-leading-5 "
placeholder=""
required=""
/>
</div>
`;

View File

@ -1,3 +1,2 @@
export { TextAreaInput } from './TextAreaInput'
export { TextInput } from './TextInput'
export { SelectBox } from './SelectBox'

View File

@ -1,5 +1,6 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import PlusSVG from '#assets/plus.svg'
import { useLayers } from '#components/Map/hooks/useLayers'
import { useHasUserPermission } from '#components/Map/hooks/usePermissions'
@ -30,16 +31,7 @@ export default function AddButton({
{canAddItems() ? (
<div className='tw-dropdown tw-dropdown-top tw-dropdown-end tw-dropdown-hover tw-z-500 tw-absolute tw-right-4 tw-bottom-4'>
<label tabIndex={0} className='tw-z-500 tw-btn tw-btn-circle tw-shadow tw-bg-base-100'>
<svg
xmlns='http://www.w3.org/2000/svg'
fill='none'
viewBox='0 0 24 24'
strokeWidth='3'
stroke='currentColor'
className='tw-w-5 tw-h-5'
>
<path strokeLinecap='round' strokeLinejoin='round' d='M12 4.5v15m7.5-7.5h-15' />
</svg>
<img src={PlusSVG} alt='Layers' className='tw-h-5 tw-w-5' />
</label>
<ul tabIndex={0} className='tw-dropdown-content tw-pr-1 tw-list-none'>
{layers.map(

View File

@ -1,3 +1,4 @@
import FunnelIcon from '@heroicons/react/24/outline/FunnelIcon'
import { useEffect, useState } from 'react'
import {
@ -11,8 +12,8 @@ export function FilterControl() {
const [open, setOpen] = useState(false)
const groupTypes = [
{ text: 'Regional Gruppe', value: 'wuerdekompass' },
{ text: 'Themen Gruppe', value: 'themenkompass' },
{ text: 'Regional Gruppe', value: 'Regional-Gruppe' },
{ text: 'Themen Gruppe', value: 'Themen-Gruppe' },
{ text: 'liebevoll.jetzt', value: 'liebevoll.jetzt' },
]
@ -71,20 +72,7 @@ export function FilterControl() {
setOpen(true)
}}
>
<svg
xmlns='http://www.w3.org/2000/svg'
fill='none'
viewBox='0 0 24 24'
strokeWidth={2.3}
stroke='currentColor'
className='size-6'
>
<path
strokeLinecap='round'
strokeLinejoin='round'
d='M12 3c2.755 0 5.455.232 8.083.678.533.09.917.556.917 1.096v1.044a2.25 2.25 0 0 1-.659 1.591l-5.432 5.432a2.25 2.25 0 0 0-.659 1.591v2.927a2.25 2.25 0 0 1-1.244 2.013L9.75 21v-6.568a2.25 2.25 0 0 0-.659-1.591L3.659 7.409A2.25 2.25 0 0 1 3 5.818V4.774c0-.54.384-1.006.917-1.096A48.32 48.32 0 0 1 12 3Z'
/>
</svg>
<FunnelIcon className='size-6 tw-stroke-[2.5]' />
</div>
</div>
)}

View File

@ -1,3 +1,4 @@
import HeartIcon from '@heroicons/react/24/outline/HeartIcon'
import { useNavigate } from 'react-router-dom'
import { useAuth } from '#components/Auth/useAuth'
@ -16,20 +17,7 @@ export const GratitudeControl = () => {
navigate('/select-user')
}}
>
<svg
xmlns='http://www.w3.org/2000/svg'
fill='none'
viewBox='0 0 24 24'
strokeWidth={2.5}
stroke='currentColor'
className='size-6'
>
<path
strokeLinecap='round'
strokeLinejoin='round'
d='M21 8.25c0-2.485-2.099-4.5-4.688-4.5-1.935 0-3.597 1.126-4.312 2.733-.715-1.607-2.377-2.733-4.313-2.733C5.1 3.75 3 5.765 3 8.25c0 7.22 9 12 9 12s9-4.78 9-12Z'
/>
</svg>
<HeartIcon className='tw-stroke-[2.5]' />
</div>
}
</div>

View File

@ -1,5 +1,6 @@
import { useState } from 'react'
import LayerSVG from '#assets/layer.svg'
import { useIsLayerVisible, useToggleVisibleLayer } from '#components/Map/hooks/useFilter'
import { useLayers } from '#components/Map/hooks/useLayers'
@ -55,20 +56,7 @@ export function LayerControl() {
setOpen(true)
}}
>
<svg version='1.1' viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'>
<path
id='svg_1'
fill='currentColor'
d='m2.75565,11.90727l-1.03852,0.28372c-0.77718,0.38859 -0.77718,1.0138 0,1.4023l7.0156,3.5078c0.77718,0.38859 2.0275,0.38859 2.8047,0l7.0156,-3.5078c0.77718,-0.38859 0.77718,-1.0138 0,-1.4023l-0.63311,-0.48643l-4.67718,2.23624c-1.5452,0.77262 -3.31877,1.58343 -4.86407,0.81081l-5.62302,-2.84434z'
/>
<path
id='svg_2'
strokeWidth='2'
stroke='currentColor'
fill='none'
d='m11.247,4.30851l6.2349,3.0877c0.69083,0.34211 0.69083,0.89295 0,1.2351l-6.2349,3.0877c-0.69083,0.34211 -1.8031,0.34212 -2.494,0l-6.2349,-3.0877c-0.69083,-0.34211 -0.69083,-0.89295 0,-1.2351l6.2349,-3.0877c0.69083,-0.34211 1.8031,-0.34211 2.494,0z'
/>
</svg>
<img src={LayerSVG} alt='Layers' />
</div>
)}
</div>

View File

@ -7,6 +7,9 @@
import { control } from 'leaflet'
import { useEffect, useRef, useState } from 'react'
import { useMap, useMapEvents } from 'react-leaflet'
import TargetSVG from '#assets/target.svg'
// eslint-disable-next-line import/no-unassigned-import
import 'leaflet.locatecontrol'
import 'leaflet.locatecontrol/dist/L.Control.Locate.css'
@ -56,15 +59,12 @@ export const LocateControl = () => {
{loading ? (
<span className='tw-loading tw-loading-spinner tw-loading-md tw-mt-1'></span>
) : (
<svg
fill={`${active ? '#fc8702' : 'currentColor'}`}
viewBox='0 0 32 32'
version='1.1'
xmlns='http://www.w3.org/2000/svg'
<img
src={TargetSVG}
alt='x'
className='tw-mt-1 tw-p-[1px]'
>
<path d='M30 14.75h-2.824c-0.608-5.219-4.707-9.318-9.874-9.921l-0.053-0.005v-2.824c0-0.69-0.56-1.25-1.25-1.25s-1.25 0.56-1.25 1.25v0 2.824c-5.219 0.608-9.318 4.707-9.921 9.874l-0.005 0.053h-2.824c-0.69 0-1.25 0.56-1.25 1.25s0.56 1.25 1.25 1.25v0h2.824c0.608 5.219 4.707 9.318 9.874 9.921l0.053 0.005v2.824c0 0.69 0.56 1.25 1.25 1.25s1.25-0.56 1.25-1.25v0-2.824c5.219-0.608 9.318-4.707 9.921-9.874l0.005-0.053h2.824c0.69 0 1.25-0.56 1.25-1.25s-0.56-1.25-1.25-1.25v0zM17.25 24.624v-2.624c0-0.69-0.56-1.25-1.25-1.25s-1.25 0.56-1.25 1.25v0 2.624c-3.821-0.57-6.803-3.553-7.368-7.326l-0.006-0.048h2.624c0.69 0 1.25-0.56 1.25-1.25s-0.56-1.25-1.25-1.25v0h-2.624c0.57-3.821 3.553-6.804 7.326-7.368l0.048-0.006v2.624c0 0.69 0.56 1.25 1.25 1.25s1.25-0.56 1.25-1.25v0-2.624c3.821 0.57 6.803 3.553 7.368 7.326l0.006 0.048h-2.624c-0.69 0-1.25 0.56-1.25 1.25s0.56 1.25 1.25 1.25v0h2.624c-0.571 3.821-3.553 6.803-7.326 7.368l-0.048 0.006z'></path>
</svg>
style={{ fill: `${active ? '#fc8702' : 'currentColor'}` }}
/>
)}
</div>
</div>

View File

@ -1,3 +1,4 @@
import FistSVG from '#assets/fist.svg'
import { useQuestsOpen, useSetQuestOpen } from '#components/Gaming/hooks/useQuests'
export function QuestControl() {
@ -17,14 +18,7 @@ export function QuestControl() {
className='tw-card-body hover:tw-bg-slate-300 tw-rounded-2xl tw-p-2 tw-h-10 tw-w-10 tw-transition-all tw-duration-300 hover:tw-cursor-pointer'
onClick={() => setQuestsOpen(true)}
>
<svg
xmlns='http://www.w3.org/2000/svg'
fill='currentColor'
stroke='currentColor'
viewBox='0 0 448 512'
>
<path d='M192 0c17.7 0 32 14.3 32 32V144H160V32c0-17.7 14.3-32 32-32zM64 64c0-17.7 14.3-32 32-32s32 14.3 32 32v80H64V64zm192 0c0-17.7 14.3-32 32-32s32 14.3 32 32v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V64zm96 64c0-17.7 14.3-32 32-32s32 14.3 32 32v64c0 17.7-14.3 32-32 32s-32-14.3-32-32V128zm-96 88l0-.6c9.4 5.4 20.3 8.6 32 8.6c13.2 0 25.4-4 35.6-10.8c8.7 24.9 32.5 42.8 60.4 42.8c11.7 0 22.6-3.1 32-8.6V256c0 52.3-25.1 98.8-64 128v96c0 17.7-14.3 32-32 32H160c-17.7 0-32-14.3-32-32V401.6c-17.3-7.9-33.2-18.8-46.9-32.5L69.5 357.5C45.5 333.5 32 300.9 32 267V240c0-35.3 28.7-64 64-64h88c22.1 0 40 17.9 40 40s-17.9 40-40 40H128c-8.8 0-16 7.2-16 16s7.2 16 16 16h56c39.8 0 72-32.2 72-72z' />
</svg>
<img src={FistSVG} alt='Quests' className='tw-h-[2em]' />
</div>
</div>
)}

View File

@ -10,6 +10,8 @@
/* eslint-disable @typescript-eslint/restrict-plus-operands */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-call */
import FlagIcon from '@heroicons/react/24/outline/FlagIcon'
import MagnifyingGlassIcon from '@heroicons/react/24/outline/MagnifyingGlassIcon'
import axios from 'axios'
import { LatLng, LatLngBounds, marker } from 'leaflet'
import { useEffect, useRef, useState } from 'react'
@ -234,21 +236,7 @@ export const SearchControl = () => {
hide()
}}
>
<svg
xmlns='http://www.w3.org/2000/svg'
fill='none'
viewBox='0 0 24 24'
strokeWidth='1.5'
stroke='currentColor'
className='tw-text-current tw-mr-2 tw-mt-0 tw-w-4'
>
<path
strokeLinecap='round'
strokeLinejoin='round'
d='m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z'
/>
</svg>
<MagnifyingGlassIcon className='tw-text-current tw-mr-2 tw-mt-0 tw-w-4' />
<div>
<div className='tw-text-sm tw-overflow-hidden tw-text-ellipsis tw-whitespace-nowrap tw-max-w-[17rem]'>
{geo?.properties.name ? geo?.properties.name : value}
@ -295,21 +283,7 @@ export const SearchControl = () => {
)
}}
>
<svg
xmlns='http://www.w3.org/2000/svg'
fill='none'
viewBox='0 0 24 24'
strokeWidth={1.5}
stroke='currentColor'
className='tw-text-current tw-mr-2 tw-mt-0 tw-w-4'
>
<path
strokeLinecap='round'
strokeLinejoin='round'
d='M3 3v1.5M3 21v-6m0 0 2.77-.693a9 9 0 0 1 6.208.682l.108.054a9 9 0 0 0 6.086.71l3.114-.732a48.524 48.524 0 0 1-.005-10.499l-3.11.732a9 9 0 0 1-6.085-.711l-.108-.054a9 9 0 0 0-6.208-.682L3 4.5M3 15V4.5'
/>
</svg>
<FlagIcon className='tw-text-current tw-mr-2 tw-mt-0 tw-w-4' />
<div>
<div className='tw-text-sm tw-overflow-hidden tw-text-ellipsis tw-whitespace-nowrap tw-max-w-[17rem]'>
{value}

View File

@ -1,3 +1,5 @@
import Bars3Icon from '@heroicons/react/16/solid/Bars3Icon'
// Converts leaflet.locatecontrol to a React Component
export const SidebarControl = () => {
return (
@ -11,19 +13,7 @@ export const SidebarControl = () => {
aria-controls='#sidenav'
aria-haspopup='true'
>
<svg
xmlns='http://www.w3.org/2000/svg'
fill='none'
viewBox='0 0 24 24'
className='tw-inline-block tw-w-5 tw-h-5 tw-stroke-current'
>
<path
strokeLinecap='round'
strokeLinejoin='round'
strokeWidth='2'
d='M4 6h16M4 12h16M4 18h16'
></path>
</svg>
<Bars3Icon className='tw-inline-block tw-w-5 tw-h-5' />
</button>
</div>
</div>

View File

@ -53,6 +53,13 @@ export function ItemFormPopup(props: ItemFormPopupProps) {
})
formItem.position = { type: 'Point', coordinates: [props.position.lng, props.position.lat] }
evt.preventDefault()
const name = formItem.name ? formItem.name : user?.first_name
if (!name) {
toast.error('Name is must be defined')
return
}
setSpinner(true)
formItem.text &&
@ -98,8 +105,8 @@ export function ItemFormPopup(props: ItemFormPopupProps) {
;(!props.layer.userProfileLayer || !item) &&
(await props.layer.api?.createItem!({
...formItem,
name,
id: uuid,
name: formItem.name ? formItem.name : user?.first_name,
}))
success = true
// eslint-disable-next-line no-catch-all/no-catch-all

View File

@ -9,9 +9,13 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-non-null-assertion */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import EllipsisVerticalIcon from '@heroicons/react/16/solid/EllipsisVerticalIcon'
import PencilIcon from '@heroicons/react/24/solid/PencilIcon'
import TrashIcon from '@heroicons/react/24/solid/TrashIcon'
import { useState, useEffect } from 'react'
import { useNavigate } from 'react-router-dom'
import TargetDotSVG from '#assets/targetDot.svg'
import { useAppState } from '#components/AppShell/hooks/useAppState'
import { useHasUserPermission } from '#components/Map/hooks/usePermissions'
import DialogModal from '#components/Templates/DialogModal'
@ -127,14 +131,7 @@ export function HeaderView({
tabIndex={0}
className='tw-bg-base-100 tw-btn tw-m-1 tw-leading-3 tw-border-none tw-min-h-0 tw-h-6'
>
<svg
xmlns='http://www.w3.org/2000/svg'
className='tw-h-5 tw-w-5'
viewBox='0 0 20 20'
fill='currentColor'
>
<path d='M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z' />
</svg>
<EllipsisVerticalIcon className='tw-h-5 tw-w-5' />
</label>
<ul
tabIndex={0}
@ -154,14 +151,7 @@ export function HeaderView({
: editCallback(e)
}
>
<svg
xmlns='http://www.w3.org/2000/svg'
className='tw-h-5 tw-w-5'
viewBox='0 0 20 20'
fill='currentColor'
>
<path d='M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z' />
</svg>
<PencilIcon className='tw-h-5 tw-w-5' />
</a>
</li>
)}
@ -173,16 +163,7 @@ export function HeaderView({
className='!tw-text-base-content tw-cursor-pointer'
onClick={setPositionCallback}
>
<svg
stroke='currentColor'
fill='currentColor'
strokeWidth='0'
viewBox='0 0 512 512'
className='tw-w-5 tw-h-5'
xmlns='http://www.w3.org/2000/svg'
>
<path d='M256 0c17.7 0 32 14.3 32 32V42.4c93.7 13.9 167.7 88 181.6 181.6H480c17.7 0 32 14.3 32 32s-14.3 32-32 32H469.6c-13.9 93.7-88 167.7-181.6 181.6V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V469.6C130.3 455.7 56.3 381.7 42.4 288H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H42.4C56.3 130.3 130.3 56.3 224 42.4V32c0-17.7 14.3-32 32-32zM107.4 288c12.5 58.3 58.4 104.1 116.6 116.6V384c0-17.7 14.3-32 32-32s32 14.3 32 32v20.6c58.3-12.5 104.1-58.4 116.6-116.6H384c-17.7 0-32-14.3-32-32s14.3-32 32-32h20.6C392.1 165.7 346.3 119.9 288 107.4V128c0 17.7-14.3 32-32 32s-32-14.3-32-32V107.4C165.7 119.9 119.9 165.7 107.4 224H128c17.7 0 32 14.3 32 32s-14.3 32-32 32H107.4zM256 224a32 32 0 1 1 0 64 32 32 0 1 1 0-64z'></path>
</svg>
<img src={TargetDotSVG} alt='Position' className='tw-w-5 tw-h-5' />
</a>
</li>
)}
@ -194,18 +175,7 @@ export function HeaderView({
{loading ? (
<span className='tw-loading tw-loading-spinner tw-loading-sm'></span>
) : (
<svg
xmlns='http://www.w3.org/2000/svg'
className='tw-h-5 tw-w-5'
viewBox='0 0 20 20'
fill='currentColor'
>
<path
fillRule='evenodd'
d='M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z'
clipRule='evenodd'
/>
</svg>
<TrashIcon className='tw-h-5 tw-w-5' />
)}
</a>
</li>

View File

@ -1,4 +1,6 @@
/* eslint-disable @typescript-eslint/prefer-optional-chain */
import CalendarIcon from '@heroicons/react/24/solid/CalendarDaysIcon'
import type { Item } from '#types/Item'
/**
@ -8,20 +10,7 @@ export const StartEndView = ({ item }: { item?: Item }) => {
return (
<div className='tw-flex tw-flex-row tw-mb-4 tw-mt-1'>
<div className='tw-basis-2/5 tw-flex tw-flex-row'>
<svg
xmlns='http://www.w3.org/2000/svg'
className='tw-h-4 tw-w-4 tw-mr-2'
fill='none'
viewBox='0 0 24 24'
stroke='currentColor'
strokeWidth={2}
>
<path
strokeLinecap='round'
strokeLinejoin='round'
d='M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z'
/>
</svg>
<CalendarIcon className='tw-h-4 tw-w-4 tw-mr-2' />
<time
className='tw-align-middle'
dateTime={item && item.start ? item.start.substring(0, 10) : ''}
@ -33,20 +22,7 @@ export const StartEndView = ({ item }: { item?: Item }) => {
<span>-</span>
</div>
<div className='tw-basis-2/5 tw-flex tw-flex-row'>
<svg
xmlns='http://www.w3.org/2000/svg'
className='tw-h-4 tw-w-4 tw-mr-2'
fill='none'
viewBox='0 0 24 24'
stroke='currentColor'
strokeWidth={2}
>
<path
strokeLinecap='round'
strokeLinejoin='round'
d='M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z'
/>
</svg>
<CalendarIcon className='tw-h-4 tw-w-4 tw-mr-2' />
<time
className='tw-align-middle'
dateTime={item && item.end ? item.end.substring(0, 10) : ''}

View File

@ -32,7 +32,6 @@ import { GratitudeControl } from './Subcomponents/Controls/GratitudeControl'
import { LayerControl } from './Subcomponents/Controls/LayerControl'
import { SearchControl } from './Subcomponents/Controls/SearchControl'
import { TagsControl } from './Subcomponents/Controls/TagsControl'
import { PopupButton } from './Subcomponents/ItemPopupComponents/PopupButton'
import { TextView } from './Subcomponents/ItemPopupComponents/TextView'
import { SelectPosition } from './Subcomponents/SelectPosition'
@ -80,7 +79,9 @@ export function UtopiaMapInner({
itemId=''
rawText={'Support us building free opensource maps and help us grow 🌱☀️'}
/>
<PopupButton url={'https://opencollective.com/utopia-project'} text={'Donate'} />
<a href='https://opencollective.com/utopia-project'>
<div className='tw-btn tw-btn-sm tw-float-right'>Donate</div>
</a>
</div>
</>,
{ autoClose: false },

View File

@ -82,7 +82,6 @@ function useItemsManager(initialItems: Item[]): {
},
})
result.map((item) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
dispatch({ type: 'ADD', item: { ...item, layer } })
return null
})

View File

@ -2,6 +2,8 @@
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
/* eslint-disable @typescript-eslint/restrict-template-expressions */
/* eslint-disable @typescript-eslint/no-explicit-any */
import LinkIcon from '@heroicons/react/24/outline/LinkIcon'
import PlusIcon from '@heroicons/react/24/outline/PlusIcon'
import { useState } from 'react'
import { TextInput } from '#components/Input'
@ -65,16 +67,7 @@ export function ActionButton({
color: '#fff',
}}
>
<svg
className='tw-h-5 tw-w-5'
stroke='currentColor'
fill='currentColor'
strokeWidth='0'
viewBox='0 0 512 512'
xmlns='http://www.w3.org/2000/svg'
>
<path d='M326.612 185.391c59.747 59.809 58.927 155.698.36 214.59-.11.12-.24.25-.36.37l-67.2 67.2c-59.27 59.27-155.699 59.262-214.96 0-59.27-59.26-59.27-155.7 0-214.96l37.106-37.106c9.84-9.84 26.786-3.3 27.294 10.606.648 17.722 3.826 35.527 9.69 52.721 1.986 5.822.567 12.262-3.783 16.612l-13.087 13.087c-28.026 28.026-28.905 73.66-1.155 101.96 28.024 28.579 74.086 28.749 102.325.51l67.2-67.19c28.191-28.191 28.073-73.757 0-101.83-3.701-3.694-7.429-6.564-10.341-8.569a16.037 16.037 0 0 1-6.947-12.606c-.396-10.567 3.348-21.456 11.698-29.806l21.054-21.055c5.521-5.521 14.182-6.199 20.584-1.731a152.482 152.482 0 0 1 20.522 17.197zM467.547 44.449c-59.261-59.262-155.69-59.27-214.96 0l-67.2 67.2c-.12.12-.25.25-.36.37-58.566 58.892-59.387 154.781.36 214.59a152.454 152.454 0 0 0 20.521 17.196c6.402 4.468 15.064 3.789 20.584-1.731l21.054-21.055c8.35-8.35 12.094-19.239 11.698-29.806a16.037 16.037 0 0 0-6.947-12.606c-2.912-2.005-6.64-4.875-10.341-8.569-28.073-28.073-28.191-73.639 0-101.83l67.2-67.19c28.239-28.239 74.3-28.069 102.325.51 27.75 28.3 26.872 73.934-1.155 101.96l-13.087 13.087c-4.35 4.35-5.769 10.79-3.783 16.612 5.864 17.194 9.042 34.999 9.69 52.721.509 13.906 17.454 20.446 27.294 10.606l37.106-37.106c59.271-59.259 59.271-155.699.001-214.959z'></path>
</svg>
<LinkIcon className='tw-h-5 tw-w-5 tw-stroke-[2.5]' />
</button>
)}
{triggerAddButton && (
@ -89,16 +82,7 @@ export function ActionButton({
color: '#fff',
}}
>
<svg
xmlns='http://www.w3.org/2000/svg'
fill='none'
viewBox='0 0 24 24'
strokeWidth='4'
stroke='currentColor'
className='tw-w-5 tw-h-5'
>
<path strokeLinecap='round' strokeLinejoin='round' d='M12 4.5v15m7.5-7.5h-15' />
</svg>
<PlusIcon className='tw-w-5 tw-h-5 tw-stroke-[2.5]' />
</button>
)}
</div>

View File

@ -2,9 +2,11 @@
/* eslint-disable @typescript-eslint/no-floating-promises */
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/prefer-optional-chain */
import ArrowUpTrayIcon from '@heroicons/react/24/outline/ArrowUpTrayIcon'
import { useState, useCallback, useRef } from 'react'
import { ReactCrop, centerCrop, makeAspectCrop } from 'react-image-crop'
import UserSVG from '#assets/user.svg'
import { useAppState } from '#components/AppShell/hooks/useAppState'
import 'react-image-crop/dist/ReactCrop.css'
import DialogModal from '#components/Templates/DialogModal'
@ -169,20 +171,7 @@ export const AvatarWidget: React.FC<AvatarWidgetProps> = ({ avatar, setAvatar })
onChange={onImageChange}
/>
<div className='button tw-btn tw-btn-lg tw-btn-circle tw-animate-none'>
<svg
xmlns='http://www.w3.org/2000/svg'
fill='none'
viewBox='0 0 24 24'
strokeWidth='1.5'
stroke='currentColor'
className='tw-w-6 tw-h-6'
>
<path
strokeLinecap='round'
strokeLinejoin='round'
d='M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5'
/>
</svg>
<ArrowUpTrayIcon className='tw-w-6 tw-h-6' />
</div>
{avatar ? (
<div className='tw-h-20 tw-w-20'>
@ -193,22 +182,7 @@ export const AvatarWidget: React.FC<AvatarWidgetProps> = ({ avatar, setAvatar })
</div>
) : (
<div className='tw-h-20 tw-w-20'>
<svg
xmlns='http://www.w3.org/2000/svg'
version='1.0'
viewBox='0 0 150 150'
className='tw-w-20 tw-h-20 tw-rounded-full'
style={{ backgroundColor: '#eee' }}
>
<path
fill='#ccc'
d='M 104.68731,56.689353 C 102.19435,80.640493 93.104981,97.26875 74.372196,97.26875 55.639402,97.26875 46.988823,82.308034 44.057005,57.289941 41.623314,34.938838 55.639402,15.800152 74.372196,15.800152 c 18.732785,0 32.451944,18.493971 30.315114,40.889201 z'
/>
<path
fill='#ccc'
d='M 92.5675 89.6048 C 90.79484 93.47893 89.39893 102.4504 94.86478 106.9039 C 103.9375 114.2963 106.7064 116.4723 118.3117 118.9462 C 144.0432 124.4314 141.6492 138.1543 146.5244 149.2206 L 4.268444 149.1023 C 8.472223 138.6518 6.505799 124.7812 32.40051 118.387 C 41.80992 116.0635 45.66513 113.8823 53.58659 107.0158 C 58.52744 102.7329 57.52583 93.99267 56.43084 89.26926 C 52.49275 88.83011 94.1739 88.14054 92.5675 89.6048 z'
/>
</svg>
<img src={UserSVG} className='tw-rounded-full'></img>
</div>
)}
</label>

View File

@ -2,6 +2,8 @@
/* eslint-disable @typescript-eslint/no-unsafe-return */
/* eslint-disable @typescript-eslint/restrict-plus-operands */
import EnvelopeIcon from '@heroicons/react/24/outline/EnvelopeIcon'
import PhoneIcon from '@heroicons/react/24/outline/PhoneIcon'
import { useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
@ -48,19 +50,7 @@ export const ContactInfoView = ({ item, heading }: { item: Item; heading: string
href={`mailto:${item.contact}`}
className='tw-mt-2 tw-text-green-500 tw-inline-flex tw-items-center'
>
<svg
xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24'
fill='none'
stroke='currentColor'
strokeWidth='2'
strokeLinecap='round'
strokeLinejoin='round'
className='tw-w-4 tw-h-4 tw-mr-1'
>
<path d='M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z'></path>
<polyline points='22,6 12,13 2,6'></polyline>
</svg>
<EnvelopeIcon className='tw-w-4 tw-h-4 tw-mr-1' />
{item.contact}
</a>
</p>
@ -71,18 +61,7 @@ export const ContactInfoView = ({ item, heading }: { item: Item; heading: string
href={`tel:${item.telephone}`}
className='tw-mt-2 tw-text-green-500 tw-inline-flex tw-items-center tw-whitespace-nowrap'
>
<svg
xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24'
fill='none'
stroke='currentColor'
strokeWidth='2'
strokeLinecap='round'
strokeLinejoin='round'
className='tw-w-4 tw-h-4 tw-mr-1'
>
<path d='M22 16.92v3a2 2 0 01-2.18 2 19.79 19.79 0 01-8.63-3.07 19.5 19.5 0 01-6-6 19.79 19.79 0 01-3.07-8.67A2 2 0 014.11 2h3a2 2 0 012 1.72 12.84 12.84 0 00.7 2.81 2 2 0 01-.45 2.11L8.09 9.91a16 16 0 006 6l1.27-1.27a2 2 0 012.11-.45 12.84 12.84 0 002.81.7A2 2 0 0122 16.92z' />
</svg>
<PhoneIcon className='tw-w-4 tw-h-4 tw-mr-1' />
{item.telephone}
</a>
</p>

View File

@ -2,9 +2,10 @@
/* eslint-disable @typescript-eslint/no-empty-function */
/* eslint-disable @typescript-eslint/no-unsafe-return */
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/restrict-plus-operands */
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
import EllipsisVerticalIcon from '@heroicons/react/16/solid/EllipsisVerticalIcon'
import LinkSlashIcon from '@heroicons/react/24/outline/LinkSlashIcon'
import { useEffect } from 'react'
import { useAppState } from '#components/AppShell/hooks/useAppState'
@ -24,7 +25,7 @@ export function LinkedItemsHeaderView({
}) {
const appState = useAppState()
const avatar = appState.assetsApi.url + item.image
const avatar = item.image ? appState.assetsApi.url + item.image : null
const title = item.name
const subtitle = item.subname
@ -57,14 +58,7 @@ export function LinkedItemsHeaderView({
tabIndex={0}
className=' tw-btn tw-m-1 tw-leading-3 tw-border-none tw-min-h-0 tw-h-6'
>
<svg
xmlns='http://www.w3.org/2000/svg'
className='tw-h-5 tw-w-5'
viewBox='0 0 20 20'
fill='currentColor'
>
<path d='M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z' />
</svg>
<EllipsisVerticalIcon className='tw-h-5 tw-w-5' />
</label>
<ul
tabIndex={0}
@ -79,16 +73,7 @@ export function LinkedItemsHeaderView({
{loading ? (
<span className='tw-loading tw-loading-spinner tw-loading-sm'></span>
) : (
<svg
className='tw-h-5 tw-w-5'
stroke='currentColor'
fill='currentColor'
strokeWidth='0'
viewBox='0 0 512 512'
xmlns='http://www.w3.org/2000/svg'
>
<path d='M304.083 405.907c4.686 4.686 4.686 12.284 0 16.971l-44.674 44.674c-59.263 59.262-155.693 59.266-214.961 0-59.264-59.265-59.264-155.696 0-214.96l44.675-44.675c4.686-4.686 12.284-4.686 16.971 0l39.598 39.598c4.686 4.686 4.686 12.284 0 16.971l-44.675 44.674c-28.072 28.073-28.072 73.75 0 101.823 28.072 28.072 73.75 28.073 101.824 0l44.674-44.674c4.686-4.686 12.284-4.686 16.971 0l39.597 39.598zm-56.568-260.216c4.686 4.686 12.284 4.686 16.971 0l44.674-44.674c28.072-28.075 73.75-28.073 101.824 0 28.072 28.073 28.072 73.75 0 101.823l-44.675 44.674c-4.686 4.686-4.686 12.284 0 16.971l39.598 39.598c4.686 4.686 12.284 4.686 16.971 0l44.675-44.675c59.265-59.265 59.265-155.695 0-214.96-59.266-59.264-155.695-59.264-214.961 0l-44.674 44.674c-4.686 4.686-4.686 12.284 0 16.971l39.597 39.598zm234.828 359.28l22.627-22.627c9.373-9.373 9.373-24.569 0-33.941L63.598 7.029c-9.373-9.373-24.569-9.373-33.941 0L7.029 29.657c-9.373 9.373-9.373 24.569 0 33.941l441.373 441.373c9.373 9.372 24.569 9.372 33.941 0z'></path>
</svg>
<LinkSlashIcon className='tw-h-5 tw-w-5 tw-stroke-[3]' />
)}
</a>
</li>

View File

@ -1,5 +1,7 @@
import { useState } from 'react'
import MarkdownSVG from '#assets/markdown.svg'
export const MarkdownHint = () => {
const [expended, setExpended] = useState<boolean>(false)
return (
@ -8,18 +10,7 @@ export const MarkdownHint = () => {
title='Markdown is supported'
className='flex tw-flex-row tw-text-gray-400 tw-cursor-pointer tw-items-center'
>
<svg
aria-hidden='true'
height='16'
viewBox='0 0 16 16'
version='1.1'
width='16'
data-view-component='true'
className='octicon octicon-markdown'
fill='rgb(156 163 175 / var(--tw-text-opacity))'
>
<path d='M14.85 3c.63 0 1.15.52 1.14 1.15v7.7c0 .63-.51 1.15-1.15 1.15H1.15C.52 13 0 12.48 0 11.84V4.15C0 3.52.52 3 1.15 3ZM9 11V5H7L5.5 7 4 5H2v6h2V8l1.5 1.92L7 8v3Zm2.99.5L14.5 8H13V5h-2v3H9.5Z'></path>
</svg>
<img src={MarkdownSVG} alt='Markdown' className='octicon octicon-markdown tw-gray-400' />
{expended && (
<a
href='https://www.markdownguide.org/cheat-sheet/#basic-syntax'

View File

@ -1,5 +1,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-unsafe-call */
import PlusIcon from '@heroicons/react/24/outline/PlusIcon'
import { useHasUserPermission } from '#components/Map/hooks/usePermissions'
import type { LayerProps } from '#types/LayerProps'
@ -28,16 +30,7 @@ export function PlusButton({
}}
style={{ backgroundColor: color, color: '#fff' }}
>
<svg
xmlns='http://www.w3.org/2000/svg'
fill='none'
viewBox='0 0 24 24'
strokeWidth='2'
stroke='currentColor'
className='tw-w-5 tw-h-5'
>
<path strokeLinecap='round' strokeLinejoin='round' d='M12 4.5v15m7.5-7.5h-15' />
</svg>
<PlusIcon className='tw-w-5 tw-h-5 tw-stroke-[2.5]' />
</button>
</div>
)}

View File

@ -1,5 +1,8 @@
import { toast } from 'react-toastify'
import ChevronSVG from '#assets/chevron.svg'
import ClipboardSVG from '#assets/share/clipboard.svg'
import SocialShareButton from './SocialShareButton'
const SocialShareBar = ({
@ -41,14 +44,7 @@ const SocialShareBar = ({
onClick={() => copyLink()}
title='share link via email'
>
<svg
xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24'
fill='white'
className='tw-h-4 tw-w-4'
>
<path d='M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z' />
</svg>
<img src={ChevronSVG} alt='\/' className='tw-h-4 tw-w-4' />
</a>
)}
{platforms.includes('clipboard') && (
@ -62,17 +58,7 @@ const SocialShareBar = ({
onClick={() => copyLink()}
title='copy Link'
>
<svg
stroke='currentColor'
fill='currentColor'
strokeWidth='0'
viewBox='0 0 256 256'
height='1.5em'
width='1.5em'
xmlns='http://www.w3.org/2000/svg'
>
<path d='M180,64H40A12,12,0,0,0,28,76V216a12,12,0,0,0,12,12H180a12,12,0,0,0,12-12V76A12,12,0,0,0,180,64ZM168,204H52V88H168ZM228,40V180a12,12,0,0,1-24,0V52H76a12,12,0,0,1,0-24H216A12,12,0,0,1,228,40Z'></path>
</svg>
<img src={ClipboardSVG} className='tw-w-5' />
</div>
)}
</div>

View File

@ -5,72 +5,42 @@
import { cloneElement } from 'react'
import FacebookSVG from '#assets/share/facebook.svg'
import LinkedinSVG from '#assets/share/linkedin.svg'
import TelegramSVG from '#assets/share/telegram.svg'
import TwitterSVG from '#assets/share/twitter.svg'
import WhatsappSVG from '#assets/share/whatsapp.svg'
import XingSVG from '#assets/share/xing.svg'
const platformConfigs = {
facebook: {
shareUrl: 'https://www.facebook.com/sharer/sharer.php?u={url}',
icon: (
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'>
<path d='M18 2h-3a5 5 0 00-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 011-1h3z' />
</svg>
),
icon: <img src={FacebookSVG} alt='Facebook' />,
bgColor: '#3b5998',
},
twitter: {
shareUrl: 'https://twitter.com/intent/tweet?text={title}:%20{url}',
icon: (
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'>
<path d='M23 3a10.9 10.9 0 01-3.14 1.53 4.48 4.48 0 00-7.86 3v1A10.66 10.66 0 013 4s-4 9 5 13a11.64 11.64 0 01-7 2c9 5 20 0 20-11.5a4.5 4.5 0 00-.08-.83A7.72 7.72 0 0023 3z' />
</svg>
),
icon: <img src={TwitterSVG} alt='Twitter' />,
bgColor: '#55acee',
},
linkedin: {
shareUrl: 'http://www.linkedin.com/shareArticle?mini=true&url={url}&title={title}',
icon: (
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'>
<path d='M16 8a6 6 0 016 6v7h-4v-7a2 2 0 00-2-2 2 2 0 00-2 2v7h-4v-7a6 6 0 016-6zM2 9h4v12H2z' />
<circle cx='4' cy='4' r='2' />
</svg>
),
icon: <img src={LinkedinSVG} alt='Linkedin' />,
bgColor: '#4875b4',
},
xing: {
shareUrl: 'https://www.xing-share.com/app/user?op=share;sc_p=xing-share;url={url}',
icon: (
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'>
<path d='M18.188 0c-.517 0-.741.325-.927.66 0 0-7.455 13.224-7.702 13.657.015.024 4.919 9.023 4.919 9.023.17.308.436.66.967.66h3.454c.211 0 .375-.078.463-.22.089-.151.089-.346-.009-.536l-4.879-8.916c-.004-.006-.004-.016 0-.022L22.139.756c.095-.191.097-.387.006-.535C22.056.078 21.894 0 21.686 0h-3.498zM3.648 4.74c-.211 0-.385.074-.473.216-.09.149-.078.339.02.531l2.34 4.05c.004.01.004.016 0 .021L1.86 16.051c-.099.188-.093.381 0 .529.085.142.239.234.45.234h3.461c.518 0 .766-.348.945-.667l3.734-6.609-2.378-4.155c-.172-.315-.434-.659-.962-.659H3.648v.016z' />
</svg>
),
icon: <img src={XingSVG} alt='Xing' />,
bgColor: '#026466',
},
whatsapp: {
shareUrl: 'https://api.whatsapp.com/send?text={title}%20{url}',
icon: (
<svg
stroke='currentColor'
fill='currentColor'
strokeWidth='0'
viewBox='0 0 512 512'
xmlns='http://www.w3.org/2000/svg'
>
<path d='M497.39 361.8l-112-48a24 24 0 0 0-28 6.9l-49.6 60.6A370.66 370.66 0 0 1 130.6 204.11l60.6-49.6a23.94 23.94 0 0 0 6.9-28l-48-112A24.16 24.16 0 0 0 122.6.61l-104 24A24 24 0 0 0 0 48c0 256.5 207.9 464 464 464a24 24 0 0 0 23.4-18.6l24-104a24.29 24.29 0 0 0-14.01-27.6z'></path>
</svg>
),
icon: <img src={WhatsappSVG} alt='Whatsapp' />,
bgColor: '#25D366',
},
telegram: {
shareUrl: 'https://t.me/share/url?url={url}&text={title}',
icon: (
<svg
stroke='white'
fill='white'
strokeWidth='0'
viewBox='0 0 448 512'
xmlns='http://www.w3.org/2000/svg'
>
<path d='M446.7 98.6l-67.6 318.8c-5.1 22.5-18.4 28.1-37.3 17.5l-103-75.9-49.7 47.8c-5.5 5.5-10.1 10.1-20.7 10.1l7.4-104.9 190.9-172.5c8.3-7.4-1.8-11.5-12.9-4.1L117.8 284 16.2 252.2c-22.1-6.9-22.5-22.1 4.6-32.7L418.2 66.4c18.4-6.9 34.5 4.1 28.5 32.2z'></path>
</svg>
),
icon: <img src={TelegramSVG} alt='Telegram' />,
bgColor: '#0088cc',
},
}

View File

@ -1,48 +0,0 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
import { useEffect, useRef } from 'react'
export const CircleLayout = ({
items,
radius,
fontSize,
}: {
items: any
radius: number
fontSize: any
}) => {
const containerRef = useRef<HTMLDivElement>(null)
useEffect(() => {
const container = containerRef.current
const itemCount = items.length
if (container) {
for (let i = 0; i < itemCount; i++) {
const startAngle = Math.PI / 2
const angle = startAngle + (i / itemCount) * (2 * Math.PI)
const x = radius * Math.cos(angle)
const y = radius * Math.sin(angle)
// eslint-disable-next-line security/detect-object-injection
const child = container.children[i] as HTMLElement
child.style.transform = `translate(${x}px, ${y}px)`
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [items])
return (
<div
className='tw-absolute tw-mx-auto tw-flex tw-justify-center tw-items-center tw-h-full tw-w-full'
ref={containerRef}
>
{items.map((item: any) => (
<div key={item} className='tw-absolute' style={{ fontSize }}>
{item}
</div>
))}
</div>
)
}

View File

@ -1,64 +0,0 @@
import { ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/24/outline'
import { add, format, parse, startOfToday, sub } from 'date-fns'
import { useState } from 'react'
import { LUNAR_MONTH, getLastNewMoon, getNextNewMoon } from '#utils/Moon'
import { CircleLayout } from './CircleLayout'
import { MapOverlayPage } from './MapOverlayPage'
/**
* @category Templates
*/
export const MoonCalendar = () => {
const today = startOfToday()
const [currMonth, setCurrMonth] = useState(() => format(today, 'MMM-yyyy'))
const firstDayOfMonth = parse(currMonth, 'MMM-yyyy', new Date())
const getPrevMonth = (event: React.MouseEvent<SVGSVGElement>) => {
event.preventDefault()
const firstDayOfPrevMonth = add(firstDayOfMonth, { months: -1 })
setCurrMonth(format(firstDayOfPrevMonth, 'MMM-yyyy'))
}
const getNextMonth = (event: React.MouseEvent<SVGSVGElement>) => {
event.preventDefault()
const firstDayOfNextMonth = add(firstDayOfMonth, { months: 1 })
setCurrMonth(format(firstDayOfNextMonth, 'MMM-yyyy'))
}
return (
<MapOverlayPage backdrop className='tw-h-96 tw-w-80'>
<p className='tw-self-center tw-text-lg tw-font-bold'>Moon Cycle</p>
<div className='tw-relative tw-h-full'>
<CircleLayout
items={['🌑', '🌒', '🌓', '🌔', '🌕', '🌖', '🌗', '🌘']}
radius={80}
fontSize={'3em'}
/>
<CircleLayout
items={[
format(getLastNewMoon(), 'dd.MM hh:mm'),
format(
sub(getNextNewMoon(), { seconds: ((LUNAR_MONTH * 86400) / 4) * 3 }),
'dd.MM hh:mm',
),
format(sub(getNextNewMoon(), { seconds: (LUNAR_MONTH * 86400) / 2 }), 'dd.MM hh:mm'),
format(sub(getNextNewMoon(), { seconds: (LUNAR_MONTH * 86400) / 4 }), 'dd.MM hh:mm'),
]}
radius={120}
fontSize={'0.8em'}
/>
</div>
<div className='tw-flex tw-flex-row'>
<ChevronLeftIcon className='tw-w-6 tw-h-6 tw-cursor-pointer' onClick={getPrevMonth} />
<p className='tw-text-center tw-p-1 tw-h-full tw-grow'>
from {format(getLastNewMoon(), 'dd.MM')} - to {format(getNextNewMoon(), 'dd.MM')}
</p>
<ChevronRightIcon className='tw-w-6 tw-h-6 tw-cursor-pointer' onClick={getNextMonth} />
</div>
</MapOverlayPage>
)
}

View File

@ -1,9 +1,7 @@
export { CardPage } from './CardPage'
export { TitleCard } from './TitleCard'
export { MapOverlayPage } from './MapOverlayPage'
export { MoonCalendar } from './MoonCalendar'
export { SelectUser } from './SelectUser'
export { OverlayItemsIndexPage } from './OverlayItemsIndexPage'
export { AttestationForm } from './AttestationForm'
export { MarketView } from './MarketView'

8
src/assets/chevron.svg Normal file
View File

@ -0,0 +1,8 @@
<svg
xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24'
fill='white'
className='tw-h-4 tw-w-4'
>
<path d='M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z' />
</svg>

After

Width:  |  Height:  |  Size: 310 B

8
src/assets/fist.svg Normal file
View File

@ -0,0 +1,8 @@
<svg
xmlns='http://www.w3.org/2000/svg'
fill='currentColor'
stroke='currentColor'
viewBox='0 0 448 512'
>
<path d='M192 0c17.7 0 32 14.3 32 32V144H160V32c0-17.7 14.3-32 32-32zM64 64c0-17.7 14.3-32 32-32s32 14.3 32 32v80H64V64zm192 0c0-17.7 14.3-32 32-32s32 14.3 32 32v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V64zm96 64c0-17.7 14.3-32 32-32s32 14.3 32 32v64c0 17.7-14.3 32-32 32s-32-14.3-32-32V128zm-96 88l0-.6c9.4 5.4 20.3 8.6 32 8.6c13.2 0 25.4-4 35.6-10.8c8.7 24.9 32.5 42.8 60.4 42.8c11.7 0 22.6-3.1 32-8.6V256c0 52.3-25.1 98.8-64 128v96c0 17.7-14.3 32-32 32H160c-17.7 0-32-14.3-32-32V401.6c-17.3-7.9-33.2-18.8-46.9-32.5L69.5 357.5C45.5 333.5 32 300.9 32 267V240c0-35.3 28.7-64 64-64h88c22.1 0 40 17.9 40 40s-17.9 40-40 40H128c-8.8 0-16 7.2-16 16s7.2 16 16 16h56c39.8 0 72-32.2 72-72z' />
</svg>

After

Width:  |  Height:  |  Size: 902 B

13
src/assets/layer.svg Normal file
View File

@ -0,0 +1,13 @@
<svg version='1.1' viewBox='0 0 20 20' stroke-width="2" xmlns='http://www.w3.org/2000/svg'>
<path
id='svg_1'
fill='currentColor'
d='m2.75565,11.90727l-1.03852,0.28372c-0.77718,0.38859 -0.77718,1.0138 0,1.4023l7.0156,3.5078c0.77718,0.38859 2.0275,0.38859 2.8047,0l7.0156,-3.5078c0.77718,-0.38859 0.77718,-1.0138 0,-1.4023l-0.63311,-0.48643l-4.67718,2.23624c-1.5452,0.77262 -3.31877,1.58343 -4.86407,0.81081l-5.62302,-2.84434z'
/>
<path
id='svg_2'
stroke='currentColor'
fill='none'
d='m11.247,4.30851l6.2349,3.0877c0.69083,0.34211 0.69083,0.89295 0,1.2351l-6.2349,3.0877c-0.69083,0.34211 -1.8031,0.34212 -2.494,0l-6.2349,-3.0877c-0.69083,-0.34211 -0.69083,-0.89295 0,-1.2351l6.2349,-3.0877c0.69083,-0.34211 1.8031,-0.34211 2.494,0z'
/>
</svg>

After

Width:  |  Height:  |  Size: 812 B

12
src/assets/markdown.svg Normal file
View File

@ -0,0 +1,12 @@
<svg xmlns='http://www.w3.org/2000/svg'
aria-hidden='true'
height='16'
viewBox='0 0 16 16'
version='1.1'
width='16'
data-view-component='true'
className='octicon octicon-markdown'
fill='rgb(156 163 175)'
>
<path d='M14.85 3c.63 0 1.15.52 1.14 1.15v7.7c0 .63-.51 1.15-1.15 1.15H1.15C.52 13 0 12.48 0 11.84V4.15C0 3.52.52 3 1.15 3ZM9 11V5H7L5.5 7 4 5H2v6h2V8l1.5 1.92L7 8v3Zm2.99.5L14.5 8H13V5h-2v3H9.5Z'></path>
</svg>

After

Width:  |  Height:  |  Size: 468 B

1
src/assets/plus.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="3" stroke="currentColor" class="tw-w-5 tw-h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15"></path></svg>

After

Width:  |  Height:  |  Size: 226 B

View File

@ -0,0 +1 @@
<svg stroke="currentColor" fill="white" stroke-width="0" viewBox="0 0 256 256" height="1.5em" width="1.5em" xmlns="http://www.w3.org/2000/svg"><path d="M180,64H40A12,12,0,0,0,28,76V216a12,12,0,0,0,12,12H180a12,12,0,0,0,12-12V76A12,12,0,0,0,180,64ZM168,204H52V88H168ZM228,40V180a12,12,0,0,1-24,0V52H76a12,12,0,0,1,0-24H216A12,12,0,0,1,228,40Z"></path></svg>

After

Width:  |  Height:  |  Size: 356 B

View File

@ -0,0 +1,3 @@
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'>
<path d='M18 2h-3a5 5 0 00-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 011-1h3z' />
</svg>

After

Width:  |  Height:  |  Size: 170 B

View File

@ -0,0 +1,4 @@
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'>
<path d='M16 8a6 6 0 016 6v7h-4v-7a2 2 0 00-2-2 2 2 0 00-2 2v7h-4v-7a6 6 0 016-6zM2 9h4v12H2z' />
<circle cx='4' cy='4' r='2' />
</svg>

After

Width:  |  Height:  |  Size: 231 B

View File

@ -0,0 +1,9 @@
<svg
stroke='white'
fill='white'
strokeWidth='0'
viewBox='0 0 448 512'
xmlns='http://www.w3.org/2000/svg'
>
<path d='M446.7 98.6l-67.6 318.8c-5.1 22.5-18.4 28.1-37.3 17.5l-103-75.9-49.7 47.8c-5.5 5.5-10.1 10.1-20.7 10.1l7.4-104.9 190.9-172.5c8.3-7.4-1.8-11.5-12.9-4.1L117.8 284 16.2 252.2c-22.1-6.9-22.5-22.1 4.6-32.7L418.2 66.4c18.4-6.9 34.5 4.1 28.5 32.2z'></path>
</svg>

After

Width:  |  Height:  |  Size: 433 B

View File

@ -0,0 +1,3 @@
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'>
<path d='M23 3a10.9 10.9 0 01-3.14 1.53 4.48 4.48 0 00-7.86 3v1A10.66 10.66 0 013 4s-4 9 5 13a11.64 11.64 0 01-7 2c9 5 20 0 20-11.5a4.5 4.5 0 00-.08-.83A7.72 7.72 0 0023 3z' />
</svg>

After

Width:  |  Height:  |  Size: 271 B

View File

@ -0,0 +1,9 @@
<svg
stroke='currentColor'
fill='white'
strokeWidth='0'
viewBox='0 0 512 512'
xmlns='http://www.w3.org/2000/svg'
>
<path d='M497.39 361.8l-112-48a24 24 0 0 0-28 6.9l-49.6 60.6A370.66 370.66 0 0 1 130.6 204.11l60.6-49.6a23.94 23.94 0 0 0 6.9-28l-48-112A24.16 24.16 0 0 0 122.6.61l-104 24A24 24 0 0 0 0 48c0 256.5 207.9 464 464 464a24 24 0 0 0 23.4-18.6l24-104a24.29 24.29 0 0 0-14.01-27.6z'></path>
</svg>

After

Width:  |  Height:  |  Size: 464 B

View File

@ -0,0 +1,3 @@
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'>
<path d='M18.188 0c-.517 0-.741.325-.927.66 0 0-7.455 13.224-7.702 13.657.015.024 4.919 9.023 4.919 9.023.17.308.436.66.967.66h3.454c.211 0 .375-.078.463-.22.089-.151.089-.346-.009-.536l-4.879-8.916c-.004-.006-.004-.016 0-.022L22.139.756c.095-.191.097-.387.006-.535C22.056.078 21.894 0 21.686 0h-3.498zM3.648 4.74c-.211 0-.385.074-.473.216-.09.149-.078.339.02.531l2.34 4.05c.004.01.004.016 0 .021L1.86 16.051c-.099.188-.093.381 0 .529.085.142.239.234.45.234h3.461c.518 0 .766-.348.945-.667l3.734-6.609-2.378-4.155c-.172-.315-.434-.659-.962-.659H3.648v.016z' />
</svg>

After

Width:  |  Height:  |  Size: 655 B

8
src/assets/target.svg Normal file
View File

@ -0,0 +1,8 @@
<svg
fill='currentColor'
viewBox='0 0 32 32'
version='1.1'
xmlns='http://www.w3.org/2000/svg'
>
<path d='M30 14.75h-2.824c-0.608-5.219-4.707-9.318-9.874-9.921l-0.053-0.005v-2.824c0-0.69-0.56-1.25-1.25-1.25s-1.25 0.56-1.25 1.25v0 2.824c-5.219 0.608-9.318 4.707-9.921 9.874l-0.005 0.053h-2.824c-0.69 0-1.25 0.56-1.25 1.25s0.56 1.25 1.25 1.25v0h2.824c0.608 5.219 4.707 9.318 9.874 9.921l0.053 0.005v2.824c0 0.69 0.56 1.25 1.25 1.25s1.25-0.56 1.25-1.25v0-2.824c5.219-0.608 9.318-4.707 9.921-9.874l0.005-0.053h2.824c0.69 0 1.25-0.56 1.25-1.25s-0.56-1.25-1.25-1.25v0zM17.25 24.624v-2.624c0-0.69-0.56-1.25-1.25-1.25s-1.25 0.56-1.25 1.25v0 2.624c-3.821-0.57-6.803-3.553-7.368-7.326l-0.006-0.048h2.624c0.69 0 1.25-0.56 1.25-1.25s-0.56-1.25-1.25-1.25v0h-2.624c0.57-3.821 3.553-6.804 7.326-7.368l0.048-0.006v2.624c0 0.69 0.56 1.25 1.25 1.25s1.25-0.56 1.25-1.25v0-2.624c3.821 0.57 6.803 3.553 7.368 7.326l0.006 0.048h-2.624c-0.69 0-1.25 0.56-1.25 1.25s0.56 1.25 1.25 1.25v0h2.624c-0.571 3.821-3.553 6.803-7.326 7.368l-0.048 0.006z'></path>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

10
src/assets/targetDot.svg Normal file
View File

@ -0,0 +1,10 @@
<svg
stroke='currentColor'
fill='currentColor'
strokeWidth='0'
viewBox='0 0 512 512'
className='tw-w-5 tw-h-5'
xmlns='http://www.w3.org/2000/svg'
>
<path d='M256 0c17.7 0 32 14.3 32 32V42.4c93.7 13.9 167.7 88 181.6 181.6H480c17.7 0 32 14.3 32 32s-14.3 32-32 32H469.6c-13.9 93.7-88 167.7-181.6 181.6V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V469.6C130.3 455.7 56.3 381.7 42.4 288H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H42.4C56.3 130.3 130.3 56.3 224 42.4V32c0-17.7 14.3-32 32-32zM107.4 288c12.5 58.3 58.4 104.1 116.6 116.6V384c0-17.7 14.3-32 32-32s32 14.3 32 32v20.6c58.3-12.5 104.1-58.4 116.6-116.6H384c-17.7 0-32-14.3-32-32s14.3-32 32-32h20.6C392.1 165.7 346.3 119.9 288 107.4V128c0 17.7-14.3 32-32 32s-32-14.3-32-32V107.4C165.7 119.9 119.9 165.7 107.4 224H128c17.7 0 32 14.3 32 32s-14.3 32-32 32H107.4zM256 224a32 32 0 1 1 0 64 32 32 0 1 1 0-64z'></path>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

1
src/assets/user.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.0" viewBox="0 0 150 150" class="tw-w-20 tw-h-20 tw-rounded-full" style="background-color: rgb(238, 238, 238);"><path fill="#ccc" d="M 104.68731,56.689353 C 102.19435,80.640493 93.104981,97.26875 74.372196,97.26875 55.639402,97.26875 46.988823,82.308034 44.057005,57.289941 41.623314,34.938838 55.639402,15.800152 74.372196,15.800152 c 18.732785,0 32.451944,18.493971 30.315114,40.889201 z"></path><path fill="#ccc" d="M 92.5675 89.6048 C 90.79484 93.47893 89.39893 102.4504 94.86478 106.9039 C 103.9375 114.2963 106.7064 116.4723 118.3117 118.9462 C 144.0432 124.4314 141.6492 138.1543 146.5244 149.2206 L 4.268444 149.1023 C 8.472223 138.6518 6.505799 124.7812 32.40051 118.387 C 41.80992 116.0635 45.66513 113.8823 53.58659 107.0158 C 58.52744 102.7329 57.52583 93.99267 56.43084 89.26926 C 52.49275 88.83011 94.1739 88.14054 92.5675 89.6048 z"></path></svg>

After

Width:  |  Height:  |  Size: 911 B

View File

@ -18,8 +18,7 @@ export interface LayerProps {
markerShape: string
markerDefaultColor: string
markerDefaultColor2?: string
// eslint-disable-next-line @typescript-eslint/no-explicit-any
api?: ItemsApi<any>
api?: ItemsApi<Item>
itemType: ItemType
userProfileLayer?: boolean
customEditLink?: string

7
src/types/SVG.d.ts vendored Normal file
View File

@ -0,0 +1,7 @@
declare module '*.svg' {
import type { FunctionComponent, SVGProps } from 'react'
export const ReactComponent: FunctionComponent<SVGProps<SVGSVGElement>>
const src: string
export default src
}

View File

@ -20,6 +20,7 @@
"allowSyntheticDefaultImports": true,
"skipLibCheck": true,
"paths": {
"#assets/*": ["./src/assets/*"],
"#components/*": ["./src/Components/*"],
"#utils/*": ["./src/Utils/*"],
"#types/*": ["./src/types/*"],

View File

@ -1,9 +1,10 @@
import react from '@vitejs/plugin-react'
import { defineConfig } from 'vite'
import svgr from 'vite-plugin-svgr'
import { configDefaults } from 'vitest/config'
export default defineConfig({
plugins: [react()],
plugins: [react(), svgr()],
test: {
globals: true,
environment: 'happy-dom',
@ -11,12 +12,13 @@ export default defineConfig({
coverage: {
all: true,
include: ['src/**/*.{js,jsx,ts,tsx}'],
exclude: [...configDefaults.exclude],
exclude: [...configDefaults.exclude, 'src/**/*.cy.tsx'],
reporter: ['html', 'json-summary'],
thresholds: {
lines: 0,
functions: 61,
lines: 1,
functions: 59,
branches: 62,
statements: 0,
statements: 1,
},
},
},