refactor(source): svg files & heroicons (#144)

* support for svg files

Support to load svg files and include them as bas64 encoded images in
the bundle.

* navbar svgs

* replace NavBar SVGs with heroicons

* layercontrol icons

* lint fix

* quest - questionmark

* plusbutton - plus

* linkeditem - elipse-vertical - link-slash

* contactinfo - envelope & phone

* avatar - arrow-up-tray

* ActionButton - link & plus

* StartEndView - calendar x2

* HeaderView - ellipse-vertical & pencil & trash

* SidebarControl - bars-3

* SearchControl - flag & magnifying-glass

* GratitudeControl - heart

* FilterControl - funnel

* AddButton - plus

* reduce test coverage requirements

* remove wrongfully commit dummy svg

* updated obsolete package.lock

* migrate more svgs from code to file, use hero icons where it seems applicable

* moved share icons to subfolder

* fixed layout

---------

Co-authored-by: Anton Tranelis <mail@antontranelis.de>
This commit is contained in:
Ulf Gebhardt 2025-02-24 15:58:31 +01:00 committed by GitHub
parent 12fd624780
commit 9668f8d417
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
42 changed files with 611 additions and 401 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',

420
package-lock.json generated
View File

@ -1,12 +1,12 @@
{
"name": "utopia-ui",
"version": "3.0.60",
"version": "3.0.64",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "utopia-ui",
"version": "3.0.60",
"version": "3.0.64",
"license": "GPL-3.0-only",
"dependencies": {
"@heroicons/react": "^2.0.17",
@ -70,12 +70,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": {
@ -1718,6 +1720,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",
@ -3221,6 +3461,19 @@
"node": ">=6"
}
},
"node_modules/camelcase": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
"integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/camelcase-css": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
@ -3612,6 +3865,33 @@
"dev": true,
"license": "MIT"
},
"node_modules/cosmiconfig": {
"version": "8.3.6",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz",
"integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==",
"dev": true,
"license": "MIT",
"dependencies": {
"import-fresh": "^3.3.0",
"js-yaml": "^4.1.0",
"parse-json": "^5.2.0",
"path-type": "^4.0.0"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/d-fischer"
},
"peerDependencies": {
"typescript": ">=4.9.5"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
@ -4260,6 +4540,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",
@ -4352,6 +4643,16 @@
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/error-ex": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
"dev": true,
"license": "MIT",
"dependencies": {
"is-arrayish": "^0.2.1"
}
},
"node_modules/es-abstract": {
"version": "1.23.9",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz",
@ -6405,6 +6706,13 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-arrayish": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
"integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
"dev": true,
"license": "MIT"
},
"node_modules/is-async-function": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz",
@ -7069,6 +7377,13 @@
"dev": true,
"license": "MIT"
},
"node_modules/json-parse-even-better-errors": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
"dev": true,
"license": "MIT"
},
"node_modules/json-schema": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
@ -7436,6 +7751,16 @@
"dev": true,
"license": "MIT"
},
"node_modules/lower-case": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
"integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
"dev": true,
"license": "MIT",
"dependencies": {
"tslib": "^2.0.3"
}
},
"node_modules/lru-cache": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@ -8356,6 +8681,17 @@
"dev": true,
"license": "MIT"
},
"node_modules/no-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
"integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
"dev": true,
"license": "MIT",
"dependencies": {
"lower-case": "^2.0.2",
"tslib": "^2.0.3"
}
},
"node_modules/node-releases": {
"version": "2.0.19",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
@ -8752,6 +9088,25 @@
"integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
"license": "MIT"
},
"node_modules/parse-json": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
"integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.0.0",
"error-ex": "^1.3.1",
"json-parse-even-better-errors": "^2.3.0",
"lines-and-columns": "^1.1.6"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@ -10356,6 +10711,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",
@ -10713,6 +11096,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",
@ -11149,6 +11543,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",
@ -12246,6 +12647,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

@ -75,12 +75,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": {
@ -108,6 +110,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)
@ -40,6 +41,7 @@ export default [
typescript({
tsconfig: './tsconfig.json',
}),
svg({ base64: true }),
],
external: [
'react',

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,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

@ -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 {
@ -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

@ -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

@ -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

@ -5,6 +5,8 @@
/* 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'
@ -57,14 +59,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 +74,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',
},
}

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

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',