diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 00000000000..26d35d1b8a0 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,24 @@ +import js from '@eslint/js' +import globals from 'globals' +import pluginReact from 'eslint-plugin-react' +import json from '@eslint/json' +import markdown from '@eslint/markdown' +import css from '@eslint/css' +import { defineConfig } from 'eslint/config' + +export default defineConfig([ + { files: ['**/*.{js,mjs,cjs,jsx}'], plugins: { js }, extends: ['js/recommended'] }, + { + files: ['**/*.{js,mjs,cjs,jsx}'], + languageOptions: { globals: { ...globals.browser, ...globals.node } }, + }, + pluginReact.configs.flat.recommended, + { files: ['**/*.json'], plugins: { json }, language: 'json/json', extends: ['json/recommended'] }, + { + files: ['**/*.md'], + plugins: { markdown }, + language: 'markdown/commonmark', + extends: ['markdown/recommended'], + }, + { files: ['**/*.css'], plugins: { css }, language: 'css/css', extends: ['css/recommended'] }, +]) diff --git a/package-lock.json b/package-lock.json index 11f939c8148..c68b42aca20 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,17 +28,23 @@ "devDependencies": { "@commitlint/cli": "^19.0.3", "@commitlint/config-conventional": "^19.0.3", + "@eslint/css": "^0.8.1", + "@eslint/js": "^9.27.0", + "@eslint/json": "^0.12.0", + "@eslint/markdown": "^6.4.0", "@nx/eslint": "20.2.1", "all-contributors-cli": "^6.26.1", "axios": "^1.5.1", "chalk": "^4.1.0", "cross-env": "^7.0.2", - "eslint": "^8.23.1", + "eslint": "^9.27.0", "eslint-plugin-jsonc": "^2.4.0", "eslint-plugin-markdown": "^5.0.0", "eslint-plugin-mongo": "^1.0.5", + "eslint-plugin-react": "^7.37.5", "eslint-plugin-yaml": "^0.5.0", "execa": "^9.3.1", + "globals": "^16.2.0", "husky": "^9.0.10", "js-yaml": "^4.0.0", "lerna": "^8.0.0", @@ -23285,6 +23291,15 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-classes/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/plugin-transform-computed-properties": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz", @@ -24266,6 +24281,15 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/types": { "version": "7.26.9", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.9.tgz", @@ -26906,10 +26930,104 @@ "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, + "node_modules/@eslint/config-array": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.0.tgz", + "integrity": "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==", + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.2.tgz", + "integrity": "sha512-+GPzk8PlG0sPpzdU5ZvIRMPidzAnZDl/s9L+y13iodqvb8leL53bTannOrQ/Im7UkpsmFU5Ily5U60LWixnmLg==", + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.14.0.tgz", + "integrity": "sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==", + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/css": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@eslint/css/-/css-0.8.1.tgz", + "integrity": "sha512-674JJD1q8sDlJORLep+gGnm3VRCQo/qLmKQgCIf2LnUK/tHf96StWjLX2IF3yyp3yeU9npZ6ixySMr2G256eiQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.14.0", + "@eslint/css-tree": "^3.3.3", + "@eslint/plugin-kit": "^0.3.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/css-tree": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/@eslint/css-tree/-/css-tree-3.5.4.tgz", + "integrity": "sha512-n+YfV26/+xZzOUen8IewwmB4A7uqBo2uaahFv8lqF1sIBsSG8BW4u98EW38xFUsvYz2N6p9yWqpqxuZAkm7CKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.20.0", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/@eslint/css-tree/node_modules/mdn-data": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.20.0.tgz", + "integrity": "sha512-/d3otgvmquUkAN2RVxSg6lIbQrYX7isR4aC5Hvw8JuHvzctR3eUG50WmsAZjb9MkbJ5LbijPSy7uIxEtQDGI0w==", + "dev": true, + "license": "CC0-1.0" + }, "node_modules/@eslint/eslintrc": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, "license": "MIT", "dependencies": { "ajv": "^6.12.4", @@ -26933,6 +27051,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", @@ -26949,6 +27068,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -26959,6 +27079,7 @@ "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, "license": "MIT", "dependencies": { "type-fest": "^0.20.2" @@ -26974,12 +27095,14 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, "license": "MIT" }, "node_modules/@eslint/eslintrc/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -26992,6 +27115,7 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" @@ -27001,12 +27125,258 @@ } }, "node_modules/@eslint/js": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", - "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "version": "9.27.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.27.0.tgz", + "integrity": "sha512-G5JD9Tu5HJEu4z2Uo4aHY2sLV64B7CDMXxFzqzjl3NKd6RVzSXNoE80jk7Y0lJkTTkjiIhBAqmlYwjuBY3tvpA==", "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/json": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@eslint/json/-/json-0.12.0.tgz", + "integrity": "sha512-n/7dz8HFStpEe4o5eYk0tdkBdGUS/ZGb0GQCeDWN1ZmRq67HMHK4vC33b0rQlTT6xdZoX935P4vstiWVk5Ying==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.12.0", + "@eslint/plugin-kit": "^0.2.7", + "@humanwhocodes/momoa": "^3.3.4", + "natural-compare": "^1.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/json/node_modules/@eslint/core": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz", + "integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/json/node_modules/@eslint/plugin-kit": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz", + "integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.13.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/json/node_modules/@eslint/plugin-kit/node_modules/@eslint/core": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz", + "integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/markdown": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@eslint/markdown/-/markdown-6.4.0.tgz", + "integrity": "sha512-J07rR8uBSNFJ9iliNINrchilpkmCihPmTVotpThUeKEn5G8aBBZnkjNBy/zovhJA5LBk1vWU9UDlhqKSc/dViQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint/core": "^0.10.0", + "@eslint/plugin-kit": "^0.2.5", + "mdast-util-from-markdown": "^2.0.2", + "mdast-util-frontmatter": "^2.0.1", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-frontmatter": "^2.0.0", + "micromark-extension-gfm": "^3.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/markdown/node_modules/@eslint/core": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.10.0.tgz", + "integrity": "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/markdown/node_modules/@eslint/plugin-kit": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz", + "integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.13.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/markdown/node_modules/@eslint/plugin-kit/node_modules/@eslint/core": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz", + "integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/markdown/node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@eslint/markdown/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@eslint/markdown/node_modules/mdast-util-from-markdown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", + "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@eslint/markdown/node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@eslint/markdown/node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/@eslint/markdown/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.1.tgz", + "integrity": "sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w==", + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.14.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@freesewing/aaron": { @@ -27388,11 +27758,47 @@ "@hapi/hoek": "^9.0.0" } }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.13.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", "deprecated": "Use @eslint/config-array instead", + "dev": true, "license": "Apache-2.0", "dependencies": { "@humanwhocodes/object-schema": "^2.0.3", @@ -27407,6 +27813,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -27417,6 +27824,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -27438,13 +27846,37 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@humanwhocodes/momoa": { + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/momoa/-/momoa-3.3.8.tgz", + "integrity": "sha512-/3PZzor2imi/RLLcnHztkwA79txiVvW145Ve2cp5dxRcH5qOUNJPToasqLFHniTfw4B4lT7jGDdBOPXbXYlIMQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, "node_modules/@humanwhocodes/object-schema": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "deprecated": "Use @eslint/object-schema instead", + "dev": true, "license": "BSD-3-Clause" }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@hutson/parse-repository-url": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", @@ -35631,13 +36063,13 @@ } }, "node_modules/call-bound": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", - "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "get-intrinsic": "^1.2.6" + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" }, "engines": { "node": ">= 0.4" @@ -39396,6 +39828,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" @@ -40053,59 +40486,63 @@ } }, "node_modules/eslint": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", - "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", - "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "version": "9.27.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.27.0.tgz", + "integrity": "sha512-ixRawFQuMB9DZ7fjU3iGGganFDp3+45bPOdaRurcFHSXO1e/sYwUX/FtQZpLZJR6SjMoJH8hR2pPEAfDyCoU2Q==", "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.1", - "@humanwhocodes/config-array": "^0.13.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.20.0", + "@eslint/config-helpers": "^0.2.1", + "@eslint/core": "^0.14.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.27.0", + "@eslint/plugin-kit": "^0.3.1", + "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", + "cross-spawn": "^7.0.6", "debug": "^4.3.2", - "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", + "eslint-scope": "^8.3.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", + "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" + "optionator": "^0.9.3" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, "node_modules/eslint-compat-utils": { @@ -40164,59 +40601,16 @@ } } }, - "node_modules/eslint-config-standard": { - "version": "17.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.1.0.tgz", - "integrity": "sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], + "node_modules/eslint-config-next/node_modules/eslint-plugin-react-hooks": { + "version": "5.0.0-canary-7118f5dd7-20230705", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.0.0-canary-7118f5dd7-20230705.tgz", + "integrity": "sha512-AZYbMo/NW9chdL7vk6HQzQhT+PvTAEVqWk9ziruUoW2kAOcN5qNyelv70e0F1VNQAbvutOC9oc+xfWycI9FxDw==", "license": "MIT", "engines": { - "node": ">=12.0.0" + "node": ">=10" }, "peerDependencies": { - "eslint": "^8.0.1", - "eslint-plugin-import": "^2.25.2", - "eslint-plugin-n": "^15.0.0 || ^16.0.0 ", - "eslint-plugin-promise": "^6.0.0" - } - }, - "node_modules/eslint-config-standard-jsx": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-11.0.0.tgz", - "integrity": "sha512-+1EV/R0JxEK1L0NGolAr8Iktm3Rgotx3BKwgaX+eAuSX8D952LULKtjgZD3F+e6SvibONnhLwoTi9DPxN5LvvQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "peerDependencies": { - "eslint": "^8.8.0", - "eslint-plugin-react": "^7.28.0" + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" } }, "node_modules/eslint-import-resolver-node": { @@ -40662,9 +41056,9 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.37.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.4.tgz", - "integrity": "sha512-BGP0jRmfYyvOyvMoRX/uoUeW+GqNj9y16bPQzqAHf3AYII/tDs+jMN0dBVkl88/OZwNGwrVFxE7riHsXVfy/LQ==", + "version": "7.37.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", + "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", "license": "MIT", "dependencies": { "array-includes": "^3.1.8", @@ -40677,7 +41071,7 @@ "hasown": "^2.0.2", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", - "object.entries": "^1.1.8", + "object.entries": "^1.1.9", "object.fromentries": "^2.0.8", "object.values": "^1.2.1", "prop-types": "^15.8.1", @@ -40693,18 +41087,6 @@ "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, - "node_modules/eslint-plugin-react-hooks": { - "version": "5.0.0-canary-7118f5dd7-20230705", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.0.0-canary-7118f5dd7-20230705.tgz", - "integrity": "sha512-AZYbMo/NW9chdL7vk6HQzQhT+PvTAEVqWk9ziruUoW2kAOcN5qNyelv70e0F1VNQAbvutOC9oc+xfWycI9FxDw==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" - } - }, "node_modules/eslint-plugin-react/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -40820,6 +41202,29 @@ "node": ">=10" } }, + "node_modules/eslint/node_modules/@eslint/eslintrc": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/eslint/node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -40847,33 +41252,62 @@ } }, "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz", + "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "license": "Apache-2.0", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/espree": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/eslint/node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -40890,16 +41324,26 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "node_modules/eslint/node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "license": "MIT", "dependencies": { - "type-fest": "^0.20.2" + "flatted": "^3.2.9", + "keyv": "^4.5.4" }, "engines": { - "node": ">=8" + "node": ">=16" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "license": "MIT", + "engines": { + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -40977,18 +41421,6 @@ "node": ">=8" } }, - "node_modules/eslint/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/eslint/node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -41005,6 +41437,7 @@ "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.9.0", @@ -41022,6 +41455,7 @@ "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -41659,6 +42093,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, "license": "MIT", "dependencies": { "flat-cache": "^3.0.4" @@ -41902,6 +42337,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, "license": "MIT", "dependencies": { "flatted": "^3.2.9", @@ -41916,6 +42352,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -41927,6 +42364,7 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -41947,6 +42385,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -41960,6 +42399,7 @@ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, "license": "ISC", "dependencies": { "glob": "^7.1.3" @@ -42529,17 +42969,17 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz", - "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.1", + "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", + "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", - "get-proto": "^1.0.0", + "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", @@ -43293,12 +43733,16 @@ } }, "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.2.0.tgz", + "integrity": "sha512-O+7l9tPdHCU320IigZZPj5zmRCFG9xHmx9cU8FqU2Rp+JN714seHV+2S9+JslCpY4gJwU2vOGox0wzgae/MCEg==", + "dev": true, "license": "MIT", "engines": { - "node": ">=4" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/globalthis": { @@ -46001,7 +46445,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", - "dev": true, + "devOptional": true, "license": "MIT", "bin": { "jiti": "lib/jiti-cli.mjs" @@ -53229,14 +53673,15 @@ } }, "node_modules/object.entries": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", - "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" + "es-object-atoms": "^1.1.1" }, "engines": { "node": ">= 0.4" @@ -60214,6 +60659,323 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/standard/node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/standard/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/standard/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/standard/node_modules/eslint": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/standard/node_modules/eslint-config-standard": { + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.1.0.tgz", + "integrity": "sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "eslint": "^8.0.1", + "eslint-plugin-import": "^2.25.2", + "eslint-plugin-n": "^15.0.0 || ^16.0.0 ", + "eslint-plugin-promise": "^6.0.0" + } + }, + "node_modules/standard/node_modules/eslint-config-standard-jsx": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-11.0.0.tgz", + "integrity": "sha512-+1EV/R0JxEK1L0NGolAr8Iktm3Rgotx3BKwgaX+eAuSX8D952LULKtjgZD3F+e6SvibONnhLwoTi9DPxN5LvvQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "peerDependencies": { + "eslint": "^8.8.0", + "eslint-plugin-react": "^7.28.0" + } + }, + "node_modules/standard/node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/standard/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/standard/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/standard/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/standard/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/standard/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/standard/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/standard/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/standard/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/standard/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/standard/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/standard/node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", diff --git a/package.json b/package.json index beace7969ce..e0249dde188 100644 --- a/package.json +++ b/package.json @@ -61,17 +61,23 @@ "devDependencies": { "@commitlint/cli": "^19.0.3", "@commitlint/config-conventional": "^19.0.3", + "@eslint/css": "^0.8.1", + "@eslint/js": "^9.27.0", + "@eslint/json": "^0.12.0", + "@eslint/markdown": "^6.4.0", "@nx/eslint": "20.2.1", "all-contributors-cli": "^6.26.1", "axios": "^1.5.1", "chalk": "^4.1.0", "cross-env": "^7.0.2", - "eslint": "^8.23.1", + "eslint": "^9.27.0", "eslint-plugin-jsonc": "^2.4.0", "eslint-plugin-markdown": "^5.0.0", "eslint-plugin-mongo": "^1.0.5", + "eslint-plugin-react": "^7.37.5", "eslint-plugin-yaml": "^0.5.0", "execa": "^9.3.1", + "globals": "^16.2.0", "husky": "^9.0.10", "js-yaml": "^4.0.0", "lerna": "^8.0.0", diff --git a/packages/react/components/Account/Apikeys.mjs b/packages/react/components/Account/Apikeys.mjs index c6b02dc3ff3..a8d196c6773 100644 --- a/packages/react/components/Account/Apikeys.mjs +++ b/packages/react/components/Account/Apikeys.mjs @@ -1,49 +1,34 @@ // Dependencies import { DateTime } from 'luxon' import orderBy from 'lodash/orderBy.js' -import { capitalize, shortDate } from '@freesewing/utils' +import { shortDate } from '@freesewing/utils' import { apikeyLevels } from '@freesewing/config' // Context import { ModalContext } from '@freesewing/react/context/Modal' import { LoadingStatusContext } from '@freesewing/react/context/LoadingStatus' - // Hooks import React, { useState, useEffect, useContext } from 'react' import { useAccount } from '@freesewing/react/hooks/useAccount' import { useBackend } from '@freesewing/react/hooks/useBackend' import { useSelection } from '@freesewing/react/hooks/useSelection' - // Components import { TableWrapper } from '@freesewing/react/components/Table' import { Link as WebLink } from '@freesewing/react/components/Link' -import { - BoolNoIcon, - BoolYesIcon, - PlusIcon, - RightIcon, - TrashIcon, -} from '@freesewing/react/components/Icon' +import { PlusIcon, RightIcon, TrashIcon } from '@freesewing/react/components/Icon' import { Uuid } from '@freesewing/react/components/Uuid' import { Popout } from '@freesewing/react/components/Popout' import { ModalWrapper } from '@freesewing/react/components/Modal' import { NumberCircle } from '@freesewing/react/components/Number' import { StringInput, Fieldset, ListInput } from '@freesewing/react/components/Input' -import { DisplayRow } from './shared.mjs' import { CopyToClipboardButton } from '@freesewing/react/components/Button' import { TimeAgo, TimeToGo } from '@freesewing/react/components/Time' import { KeyVal } from '@freesewing/react/components/KeyVal' -const t = (input) => { - console.log('t called', input) - return input -} - const fields = { id: 'Key', name: 'Name', calls: 'Calls', level: 'Level', - level: 'Level', createdAt: 'Created', expiresAt: 'Expires', } @@ -242,13 +227,6 @@ const NewApikey = ({ onCreate = false }) => { } else setLoadingStatus([true, 'An error occured. Please report this', true, false]) } - const clear = () => { - setApikey(false) - setGenerate(false) - setName('') - setLevel(1) - } - return (

New API key {apikey ? `: ${apikey.name}` : ''}

diff --git a/packages/react/components/Account/Bookmarks.mjs b/packages/react/components/Account/Bookmarks.mjs index 12a5aef3c3f..0388aba2785 100644 --- a/packages/react/components/Account/Bookmarks.mjs +++ b/packages/react/components/Account/Bookmarks.mjs @@ -7,7 +7,7 @@ import { useBackend } from '@freesewing/react/hooks/useBackend' import { LoadingStatusContext } from '@freesewing/react/context/LoadingStatus' import { ModalContext } from '@freesewing/react/context/Modal' // Components -import { BookmarkIcon, LeftIcon, PlusIcon, TrashIcon } from '@freesewing/react/components/Icon' +import { BookmarkIcon, PlusIcon, TrashIcon } from '@freesewing/react/components/Icon' import { Link as WebLink } from '@freesewing/react/components/Link' import { ModalWrapper } from '@freesewing/react/components/Modal' import { StringInput } from '@freesewing/react/components/Input' @@ -33,7 +33,7 @@ const types = { export const Bookmarks = () => { // Hooks & Context const backend = useBackend() - const { setModal, clearModal } = useContext(ModalContext) + const { setModal } = useContext(ModalContext) const { setLoadingStatus, LoadingProgress } = useContext(LoadingStatusContext) // State @@ -194,7 +194,7 @@ const NewBookmark = ({ onCreated = false }) => { // This method will create the bookmark const createBookmark = async () => { setLoadingStatus([true, 'Processing update']) - const [status, body] = await backend.createBookmark({ + const [status] = await backend.createBookmark({ title, url, type: 'custom', diff --git a/packages/react/components/Account/Compare.mjs b/packages/react/components/Account/Compare.mjs index 544e8e314fb..478c5ab5a4e 100644 --- a/packages/react/components/Account/Compare.mjs +++ b/packages/react/components/Account/Compare.mjs @@ -1,17 +1,13 @@ // Dependencies import { welcomeSteps } from './shared.mjs' - // Context import { LoadingStatusContext } from '@freesewing/react/context/LoadingStatus' - // Hooks import React, { useState, useContext } from 'react' import { useAccount } from '@freesewing/react/hooks/useAccount' import { useBackend } from '@freesewing/react/hooks/useBackend' - // Components -import { Link as WebLink } from '@freesewing/react/components/Link' -import { NoIcon, OkIcon, SaveIcon, RightIcon } from '@freesewing/react/components/Icon' +import { NoIcon, OkIcon, RightIcon } from '@freesewing/react/components/Icon' import { ListInput } from '@freesewing/react/components/Input' import { IconButton } from '@freesewing/react/components/Button' import { WelcomeIcons } from './shared.mjs' diff --git a/packages/react/components/Account/Consent.mjs b/packages/react/components/Account/Consent.mjs index 3543d9f18e6..c1b639e3018 100644 --- a/packages/react/components/Account/Consent.mjs +++ b/packages/react/components/Account/Consent.mjs @@ -1,36 +1,15 @@ // Dependencies -import { welcomeSteps } from './shared.mjs' -import { linkClasses, navigate } from '@freesewing/utils' - +import { navigate } from '@freesewing/utils' // Context import { LoadingStatusContext } from '@freesewing/react/context/LoadingStatus' - // Hooks import React, { useState, useContext } from 'react' import { useAccount } from '@freesewing/react/hooks/useAccount' import { useBackend } from '@freesewing/react/hooks/useBackend' - // Components import { Link as WebLink } from '@freesewing/react/components/Link' -import { NoIcon, OkIcon, SaveIcon } from '@freesewing/react/components/Icon' -import { ListInput } from '@freesewing/react/components/Input' import { Popout } from '@freesewing/react/components/Popout' -const strings = { - yes: { - title: 'Yes, in case it may help me', - desc: - 'Allowing us to compare your measurments to a baseline or others measurements sets ' + - 'allows us to detect potential problems in your measurements or patterns.', - }, - no: { - title: 'No, never compare', - desc: - 'We get it, comparison is the thief of joy. Just be aware that this limits our ability ' + - 'to warn you about potential problems in your measurements sets or patterns.', - }, -} - /** * A component to manage the user's consent setting * @@ -79,7 +58,7 @@ export const Consent = ({ signUp = false, Link = false, title = false }) => { // Helper method to remove the account const removeAccount = async () => { setLoadingStatus([true, 'One moment please']) - const [status, body] = await backend.removeAccount() + const [status] = await backend.removeAccount() if (status === 200) { setLoadingStatus([true, 'All done, farewell', true, true]) setToken(null) diff --git a/packages/react/components/Account/Control.mjs b/packages/react/components/Account/Control.mjs index c22e1c44c93..4e9e5d7250f 100644 --- a/packages/react/components/Account/Control.mjs +++ b/packages/react/components/Account/Control.mjs @@ -1,39 +1,16 @@ // Dependencies import { welcomeSteps } from './shared.mjs' import { controlDesc } from '@freesewing/config' - -// Context -import { LoadingStatusContext } from '@freesewing/react/context/LoadingStatus' - // Hooks -import React, { useState, useContext } from 'react' -import { useAccount } from '@freesewing/react/hooks/useAccount' -import { useBackend } from '@freesewing/react/hooks/useBackend' +import React from 'react' import { useControl } from '@freesewing/react/hooks/useControl' - // Components -import { Link as WebLink } from '@freesewing/react/components/Link' -import { RightIcon, NoIcon, OkIcon, SaveIcon } from '@freesewing/react/components/Icon' +import { RightIcon } from '@freesewing/react/components/Icon' import { ListInput } from '@freesewing/react/components/Input' import { ControlScore } from '@freesewing/react/components/Control' import { IconButton } from '@freesewing/react/components/Button' import { WelcomeIcons } from './shared.mjs' -const strings = { - 1: { - title: 'Keep it as simple as possible', - desc: - 'Allowing us to compare your measurments to a baseline or others measurements sets ' + - 'allows us to detect potential problems in your measurements or patterns.', - }, - 2: { - title: 'No, never compare', - desc: - 'We get it, comparison is the thief of joy. Just be aware that this limits our ability ' + - 'to warn you about potential problems in your measurements sets or patterns.', - }, -} - /** * A component to manage the user's control/UX setting * diff --git a/packages/react/components/Account/Email.mjs b/packages/react/components/Account/Email.mjs index 2d2460402e0..dc2a935a28d 100644 --- a/packages/react/components/Account/Email.mjs +++ b/packages/react/components/Account/Email.mjs @@ -1,15 +1,11 @@ // Dependencies -import { welcomeSteps } from './shared.mjs' -import { validateEmail, validateTld, getSearchParam } from '@freesewing/utils' - +import { validateEmail, validateTld, getSearchParam, navigate } from '@freesewing/utils' // Context import { LoadingStatusContext } from '@freesewing/react/context/LoadingStatus' - // Hooks import React, { useState, useContext, useEffect } from 'react' import { useAccount } from '@freesewing/react/hooks/useAccount' import { useBackend } from '@freesewing/react/hooks/useBackend' - // Components import { Link as WebLink } from '@freesewing/react/components/Link' import { SaveIcon } from '@freesewing/react/components/Icon' @@ -22,11 +18,10 @@ import { Spinner } from '@freesewing/react/components/Spinner' * * @component * @param {object} props - All component props - * @param {bool} [props.welcome = false] - Set to true to render the welcome/onboarding view * @param {React.Component} props.Link - A framework specific Link component for client-side routing * @returns {JSX.Element} */ -export const Email = ({ welcome = false, Link = false }) => { +export const Email = ({ Link = false }) => { if (!Link) Link = WebLink // Hooks @@ -104,7 +99,7 @@ export const EmailChangeConfirmation = ({ onSuccess = false }) => { const [check, setCheck] = useState() // Hooks - const { setAccount, setToken } = useAccount() + const { setAccount } = useAccount() const backend = useBackend() // Context @@ -134,7 +129,7 @@ export const EmailChangeConfirmation = ({ onSuccess = false }) => { }) // If it works, store account, which runs the onSuccess handler - if (body.result === 'success' && body.account) return storeAccount(body) + if (status === 200 && body.result === 'success' && body.account) return storeAccount(body) // If we get here, we're not sure what's wrong if (body.error) return setError(body.error) return setError(true) diff --git a/packages/react/components/Account/Export.mjs b/packages/react/components/Account/Export.mjs index d8245adde43..9c343d298a0 100644 --- a/packages/react/components/Account/Export.mjs +++ b/packages/react/components/Account/Export.mjs @@ -1,11 +1,8 @@ // Context import { LoadingStatusContext } from '@freesewing/react/context/LoadingStatus' - // Hooks import React, { useState, useContext } from 'react' -import { useAccount } from '@freesewing/react/hooks/useAccount' import { useBackend } from '@freesewing/react/hooks/useBackend' - // Components import { Link as WebLink } from '@freesewing/react/components/Link' import { DownloadIcon } from '@freesewing/react/components/Icon' diff --git a/packages/react/components/Account/Id.mjs b/packages/react/components/Account/Id.mjs index 3faedc04fc6..48c37c4496a 100644 --- a/packages/react/components/Account/Id.mjs +++ b/packages/react/components/Account/Id.mjs @@ -1,24 +1,16 @@ // Hooks -import React, { useState } from 'react' import { useAccount } from '@freesewing/react/hooks/useAccount' -// Components -import { Link as WebLink } from '@freesewing/react/components/Link' - /** - * A component to display the user's ID + * A component to display the current user's ID * * @component * @param {object} props - All component props - * @param {React.Component} props.Link - A framework specific Link component for client-side routing * @returns {JSX.Element} */ -export const UserId = ({ Link = false }) => { - if (!Link) Link = WebLink - +export const UserId = () => { // Hooks const { account } = useAccount() - const [id, setId] = useState(account.id) - return id || null + return account.id || null } diff --git a/packages/react/components/Account/Import.mjs b/packages/react/components/Account/Import.mjs index b320537fd72..e6f55c0bdab 100644 --- a/packages/react/components/Account/Import.mjs +++ b/packages/react/components/Account/Import.mjs @@ -1,14 +1,12 @@ +// Dependencies +import yaml from 'js-yaml' // Context import { LoadingStatusContext } from '@freesewing/react/context/LoadingStatus' - // Hooks -import React, { useState, useContext } from 'react' +import React, { useContext } from 'react' import { useAccount } from '@freesewing/react/hooks/useAccount' import { useBackend } from '@freesewing/react/hooks/useBackend' - // Components -import { Link as WebLink } from '@freesewing/react/components/Link' -import { SaveIcon } from '@freesewing/react/components/Icon' import { FileInput } from '@freesewing/react/components/Input' import { Popout } from '@freesewing/react/components/Popout' import { Yaml } from '@freesewing/react/components/Yaml' @@ -41,7 +39,7 @@ export const ImportSet = () => { if (set.measurements || set.measies) { const name = set.name || 'J. Doe' setLoadingStatus([true, `Importing ${name}`]) - const [status, body] = await backend.createSet({ + const [status] = await backend.createSet({ name: set.name || 'J. Doe', units: set.units || 'metric', notes: set.notes || '', diff --git a/packages/react/components/Account/Links.mjs b/packages/react/components/Account/Links.mjs index 78014ff38da..0e7bf417ad8 100644 --- a/packages/react/components/Account/Links.mjs +++ b/packages/react/components/Account/Links.mjs @@ -93,8 +93,6 @@ const titles = { const YesNo = ({ check }) => (check ? : ) -const t = (input) => input - /** * A component to manage the user's Instagram handle in their account data * diff --git a/packages/react/components/Account/Mfa.mjs b/packages/react/components/Account/Mfa.mjs index a1dc75e8944..5b6273ea86c 100644 --- a/packages/react/components/Account/Mfa.mjs +++ b/packages/react/components/Account/Mfa.mjs @@ -1,20 +1,15 @@ // Dependencies import { horFlexClasses } from '@freesewing/utils' - // Context import { LoadingStatusContext } from '@freesewing/react/context/LoadingStatus' - // Hooks import React, { useState, useContext } from 'react' import { useAccount } from '@freesewing/react/hooks/useAccount' import { useBackend } from '@freesewing/react/hooks/useBackend' - // Components -import { Link as WebLink } from '@freesewing/react/components/Link' import { NoIcon, LockIcon } from '@freesewing/react/components/Icon' import { PasswordInput } from '@freesewing/react/components/Input' import { Popout } from '@freesewing/react/components/Popout' -import { NumberCircle } from '@freesewing/react/components/Number' import { CopyToClipboardButton } from '@freesewing/react/components/Button' /** diff --git a/packages/react/components/Account/Newsletter.mjs b/packages/react/components/Account/Newsletter.mjs index f9aabcaa3bf..b311e687aab 100644 --- a/packages/react/components/Account/Newsletter.mjs +++ b/packages/react/components/Account/Newsletter.mjs @@ -1,18 +1,15 @@ // Dependencies import { welcomeSteps } from './shared.mjs' import { linkClasses } from '@freesewing/utils' - // Context import { LoadingStatusContext } from '@freesewing/react/context/LoadingStatus' - // Hooks import React, { useState, useContext } from 'react' import { useAccount } from '@freesewing/react/hooks/useAccount' import { useBackend } from '@freesewing/react/hooks/useBackend' - // Components import { Link as WebLink } from '@freesewing/react/components/Link' -import { NoIcon, OkIcon, SaveIcon, RightIcon } from '@freesewing/react/components/Icon' +import { NoIcon, OkIcon, RightIcon } from '@freesewing/react/components/Icon' import { ListInput } from '@freesewing/react/components/Input' import { Popout } from '@freesewing/react/components/Popout' import { IconButton } from '@freesewing/react/components/Button' diff --git a/packages/react/components/Account/Password.mjs b/packages/react/components/Account/Password.mjs index 5627573d73d..5432620c05e 100644 --- a/packages/react/components/Account/Password.mjs +++ b/packages/react/components/Account/Password.mjs @@ -1,15 +1,9 @@ -// Dependencies -import { welcomeSteps } from './shared.mjs' -import { horFlexClasses } from '@freesewing/utils' - // Context import { LoadingStatusContext } from '@freesewing/react/context/LoadingStatus' - // Hooks import React, { useState, useContext } from 'react' import { useAccount } from '@freesewing/react/hooks/useAccount' import { useBackend } from '@freesewing/react/hooks/useBackend' - // Components import { Link as WebLink } from '@freesewing/react/components/Link' import { RightIcon, SaveIcon } from '@freesewing/react/components/Icon' @@ -25,7 +19,7 @@ import { Popout } from '@freesewing/react/components/Popout' * @param {React.Component} props.Link - A framework specific Link component for client-side routing * @returns {JSX.Element} */ -export const Password = ({ welcome = false, Link = false }) => { +export const Password = ({ Link = false }) => { if (!Link) Link = WebLink // Hooks const backend = useBackend() diff --git a/packages/react/components/Account/Pattern.mjs b/packages/react/components/Account/Pattern.mjs index 48dc9d9296f..11065837fee 100644 --- a/packages/react/components/Account/Pattern.mjs +++ b/packages/react/components/Account/Pattern.mjs @@ -1,25 +1,13 @@ // Dependencies -import orderBy from 'lodash/orderBy.js' -import { - cloudflareImageUrl, - capitalize, - shortDate, - horFlexClasses, - newPatternUrl, - patternUrlFromState, -} from '@freesewing/utils' +import { cloudflareImageUrl, horFlexClasses, patternUrlFromState } from '@freesewing/utils' import { urls, control as controlConfig } from '@freesewing/config' - // Context import { LoadingStatusContext } from '@freesewing/react/context/LoadingStatus' import { ModalContext } from '@freesewing/react/context/Modal' - // Hooks import React, { useState, useEffect, useContext } from 'react' import { useAccount } from '@freesewing/react/hooks/useAccount' import { useBackend } from '@freesewing/react/hooks/useBackend' -import { useSelection } from '@freesewing/react/hooks/useSelection' - // Components import Markdown from 'react-markdown' import { @@ -28,7 +16,7 @@ import { PassiveImageInput, ListInput, } from '@freesewing/react/components/Input' -import { Link as WebLink, AnchorLink } from '@freesewing/react/components/Link' +import { Link as WebLink } from '@freesewing/react/components/Link' import { BoolNoIcon, BoolYesIcon, @@ -42,7 +30,6 @@ import { ResetIcon, UploadIcon, } from '@freesewing/react/components/Icon' -import { DisplayRow } from './shared.mjs' import { TimeAgo } from '@freesewing/react/components/Time' import { Popout } from '@freesewing/react/components/Popout' import { ModalWrapper } from '@freesewing/react/components/Modal' @@ -348,16 +335,7 @@ const BadgeLink = ({ label, href }) => ( /** * Helper component to show the pattern title, image, and various buttons */ -const PatternHeader = ({ - pattern, - Link, - account, - setModal, - setEdit, - togglePublic, - save, - clone, -}) => ( +const PatternHeader = ({ pattern, Link, account, setModal, setEdit, togglePublic, clone }) => ( <>

{pattern.name}

diff --git a/packages/react/components/Account/Patterns.mjs b/packages/react/components/Account/Patterns.mjs index 5ad44f06175..8fb053d07ce 100644 --- a/packages/react/components/Account/Patterns.mjs +++ b/packages/react/components/Account/Patterns.mjs @@ -1,16 +1,12 @@ // Dependencies import orderBy from 'lodash/orderBy.js' import { capitalize, shortDate } from '@freesewing/utils' - // Context import { LoadingStatusContext } from '@freesewing/react/context/LoadingStatus' - // Hooks import React, { useState, useEffect, useContext } from 'react' -import { useAccount } from '@freesewing/react/hooks/useAccount' import { useBackend } from '@freesewing/react/hooks/useBackend' import { useSelection } from '@freesewing/react/hooks/useSelection' - // Components import { TableWrapper } from '@freesewing/react/components/Table' import { PatternCard } from '@freesewing/react/components/Account' @@ -23,11 +19,6 @@ import { TrashIcon, } from '@freesewing/react/components/Icon' -const t = (input) => { - console.log('t called', input) - return input -} - /** * A component to display and manage the list of patterns in the user's account * @@ -97,13 +88,15 @@ export const Patterns = ({ Link = false }) => { onClick={removeSelectedPatterns} disabled={count < 1} > - {count} {t('patterns')} + {count} Patterns - + + + Create a new pattern
diff --git a/packages/react/components/Account/Reload.mjs b/packages/react/components/Account/Reload.mjs index 6e520079f69..ff5033a1a31 100644 --- a/packages/react/components/Account/Reload.mjs +++ b/packages/react/components/Account/Reload.mjs @@ -1,15 +1,11 @@ // Context import { LoadingStatusContext } from '@freesewing/react/context/LoadingStatus' - // Hooks -import React, { useState, useContext } from 'react' +import React, { useContext } from 'react' import { useAccount } from '@freesewing/react/hooks/useAccount' import { useBackend } from '@freesewing/react/hooks/useBackend' - // Components -import { Link as WebLink } from '@freesewing/react/components/Link' import { ReloadIcon } from '@freesewing/react/components/Icon' -import { Popout } from '@freesewing/react/components/Popout' import { IconButton } from '@freesewing/react/components/Button' /** diff --git a/packages/react/components/Account/Remove.mjs b/packages/react/components/Account/Remove.mjs index fa21969ab0a..0668874c665 100644 --- a/packages/react/components/Account/Remove.mjs +++ b/packages/react/components/Account/Remove.mjs @@ -3,16 +3,12 @@ import { navigate } from '@freesewing/utils' // Context import { LoadingStatusContext } from '@freesewing/react/context/LoadingStatus' import { ModalContext } from '@freesewing/react/context/Modal' - // Hooks -import React, { useState, useContext } from 'react' +import React, { useContext } from 'react' import { useAccount } from '@freesewing/react/hooks/useAccount' import { useBackend } from '@freesewing/react/hooks/useBackend' - // Components -import { Link as WebLink } from '@freesewing/react/components/Link' import { BackIcon as ExitIcon, TrashIcon } from '@freesewing/react/components/Icon' -import { Popout } from '@freesewing/react/components/Popout' import { IconButton } from '@freesewing/react/components/Button' import { ModalWrapper } from '@freesewing/react/components/Modal' diff --git a/packages/react/components/Account/Restrict.mjs b/packages/react/components/Account/Restrict.mjs index 392b0a13891..442a6c2b95a 100644 --- a/packages/react/components/Account/Restrict.mjs +++ b/packages/react/components/Account/Restrict.mjs @@ -6,14 +6,13 @@ import { LoadingStatusContext } from '@freesewing/react/context/LoadingStatus' import { ModalContext } from '@freesewing/react/context/Modal' // Hooks -import React, { useState, useContext } from 'react' +import React, { useContext } from 'react' import { useAccount } from '@freesewing/react/hooks/useAccount' import { useBackend } from '@freesewing/react/hooks/useBackend' // Components import { Link as WebLink } from '@freesewing/react/components/Link' import { BackIcon, NoIcon } from '@freesewing/react/components/Icon' -import { Popout } from '@freesewing/react/components/Popout' import { IconButton } from '@freesewing/react/components/Button' import { ModalWrapper } from '@freesewing/react/components/Modal' @@ -39,7 +38,7 @@ export const Restrict = ({ Link = false }) => { // Helper method to restrict the account const restrictAccount = async () => { setLoadingStatus([true, 'Talking to the backend']) - const [status, body] = await backend.restrictAccount() + const [status] = await backend.restrictAccount() if (status === 200) { setLoadingStatus([true, 'Done. Consider yourself restrcited.', true, true]) signOut() diff --git a/packages/react/components/Account/Set.mjs b/packages/react/components/Account/Set.mjs index b45cfcffd97..e822940cf86 100644 --- a/packages/react/components/Account/Set.mjs +++ b/packages/react/components/Account/Set.mjs @@ -58,11 +58,6 @@ import { bundlePatternTranslations, draft, flattenFlags } from '../Editor/lib/in import { Bonny } from '@freesewing/bonny' import { MiniNote, MiniTip } from '../Mini/index.mjs' -const t = (input) => { - console.log('t called', input) - return input -} - /** * Component to show an individual measurements set * @@ -650,8 +645,8 @@ const SuggestCset = ({ mset, Link }) => { const [name, setName] = useState('') const [notes, setNotes] = useState('') const [submission, setSubmission] = useState(false) - - console.log(mset) + // Context + const { setLoadingStatus } = useContext(LoadingStatusContext) // Hooks const backend = useBackend() @@ -803,7 +798,7 @@ const RenderedCset = ({ mset, imperial }) => { {formatMm(pattern.parts[0].front.points.head.y * -1, imperial)} high.

Here is what the automated analysis found:

- {Object.entries(flattenFlags(flags)).map(([key, flag], i) => { + {Object.entries(flattenFlags(flags)).map(([key, flag]) => { const desc = strings[flag.desc] || flag.desc return ( @@ -844,7 +839,7 @@ const RenderedCset = ({ mset, imperial }) => {
  • This preview is an approximation, not an exact representation. Bodies - have many variations that can't be captured with just a few measurements. We are + have many variations that can't be captured with just a few measurements. We are missing some information, like how weight is distributed or your posture.
  • @@ -881,7 +876,7 @@ export const NewSet = () => { // Hooks const backend = useBackend() const { account } = useAccount() - const { setLoadingStatus, LoadingProgress } = useContext(LoadingStatusContext) + const { setLoadingStatus } = useContext(LoadingStatusContext) // State const [name, setName] = useState('') diff --git a/packages/react/components/Account/Sets.mjs b/packages/react/components/Account/Sets.mjs index 96211188e4f..43786423297 100644 --- a/packages/react/components/Account/Sets.mjs +++ b/packages/react/components/Account/Sets.mjs @@ -1,8 +1,7 @@ // Dependencies -import { measurements } from '@freesewing/config' import { measurements as measurementsTranslations } from '@freesewing/i18n' import { requiredMeasurements as designMeasurements } from '@freesewing/collection' -import { cloudflareImageUrl, capitalize, hasRequiredMeasurements } from '@freesewing/utils' +import { cloudflareImageUrl, hasRequiredMeasurements } from '@freesewing/utils' // Context import { LoadingStatusContext } from '@freesewing/react/context/LoadingStatus' import { ModalContext } from '@freesewing/react/context/Modal' diff --git a/packages/react/components/Account/Units.mjs b/packages/react/components/Account/Units.mjs index 589ab330c21..c5823bb6efb 100644 --- a/packages/react/components/Account/Units.mjs +++ b/packages/react/components/Account/Units.mjs @@ -1,17 +1,13 @@ // Dependencies import { welcomeSteps } from './shared.mjs' - // Context import { LoadingStatusContext } from '@freesewing/react/context/LoadingStatus' - // Hooks import React, { useState, useContext } from 'react' import { useAccount } from '@freesewing/react/hooks/useAccount' import { useBackend } from '@freesewing/react/hooks/useBackend' - // Components -import { Link as WebLink } from '@freesewing/react/components/Link' -import { SaveIcon, RightIcon } from '@freesewing/react/components/Icon' +import { RightIcon } from '@freesewing/react/components/Icon' import { ListInput } from '@freesewing/react/components/Input' import { NumberCircle } from '@freesewing/react/components/Number' import { IconButton } from '@freesewing/react/components/Button' diff --git a/packages/react/components/Account/Username.mjs b/packages/react/components/Account/Username.mjs index ae844c09353..fc830f79ea7 100644 --- a/packages/react/components/Account/Username.mjs +++ b/packages/react/components/Account/Username.mjs @@ -57,10 +57,6 @@ export const Username = ({ welcome = false, Link = false }) => { ? '/welcome/' + welcomeSteps[account.control][5] : '/docs/about/guide' - let btnClasses = 'daisy-btn mt-4 capitalize ' - if (welcome) btnClasses += 'w-64 daisy-btn-secondary' - else btnClasses += 'w-full daisy-btn-primary' - return (
    { ) } - -const Row = ({ title, val }) => ( - - {title} - {val} - -) - -const ManageUser = ({ userId }) => { - // Hooks - const backend = useBackend() - const { setLoadingStatus } = useContext(LoadingStatusContext) - const { account } = useAccount() - const { role } = account - - // State - const [user, setUser] = useState({}) - const [patterns, setPatterns] = useState({}) - const [sets, setSets] = useState({}) - - // Effect - useEffect(() => { - const loadUser = async () => { - const result = await backend.adminLoadUser(userId) - if (result.success) { - setUser(result.data.user) - setPatterns(result.data.patterns) - setSets(result.data.sets) - } - } - loadUser() - }, [userId]) - - const updateUser = async (data) => { - setLoadingStatus([true, 'status:contactingBackend']) - const result = await backend.adminUpdateUser({ id: userId, data }) - if (result.success) { - setLoadingStatus([true, 'status:settingsSaved', true, true]) - setUser(result.data.user) - } else setLoadingStatus([true, 'status:backendError', true, false]) - } - - return user.id ? ( -
    - : null} - /> - {role === 'admin' ? ( -
    - {roles.map((role) => ( - - ))} -
    - ) : null} -
    - {user.mfaEnabled && ( - - )} - {Object.keys(freeSewingConfig.statuses).map((status) => ( - - ))} -
    - - {user.id ? : null} - {patterns ? : null} - {sets ? : null} - -
    - ) : ( - - ) -} diff --git a/packages/react/components/Button/index.mjs b/packages/react/components/Button/index.mjs index f1ddc74fa95..69627c890a7 100644 --- a/packages/react/components/Button/index.mjs +++ b/packages/react/components/Button/index.mjs @@ -1,14 +1,8 @@ import React, { useContext, useState } from 'react' import { copyToClipboard } from '@freesewing/utils' -import ReactDOMServer from 'react-dom/server' import { CopyIcon, OkIcon } from '@freesewing/react/components/Icon' import { LoadingStatusContext } from '@freesewing/react/context/LoadingStatus' -const strip = (html) => - typeof DOMParser === 'undefined' - ? html - : new DOMParser().parseFromString(html, 'text/html').body.textContent || '' - const handleCopied = (content, setCopied, setLoadingStatus, label) => { copyToClipboard(content) setCopied(true) @@ -55,7 +49,7 @@ export const CopyToClipboardButton = ({ children, content, label = false, sup = ) : ( )} - {sup ? null : children} + {sup ? null : children} ) } diff --git a/packages/react/components/Collection/index.mjs b/packages/react/components/Collection/index.mjs index efa3a356b66..ca0bfcf1be8 100644 --- a/packages/react/components/Collection/index.mjs +++ b/packages/react/components/Collection/index.mjs @@ -4,32 +4,22 @@ import { collection, tags, techniques, - designers, - developers, examples, - measurements, requiredMeasurements, optionalMeasurements, } from '@freesewing/collection' import { capitalize, linkClasses, mutateObject } from '@freesewing/utils' import { measurements as measurementsTranslations } from '@freesewing/i18n' - -// Context -import { LoadingStatusContext } from '@freesewing/react/context/LoadingStatus' -import { ModalContext } from '@freesewing/react/context/Modal' - // Hooks -import React, { useState, useContext, Fragment } from 'react' +import React, { useState, Fragment } from 'react' import { useFilter } from '@freesewing/react/hooks/useFilter' - // Components -import { Link as WebLink, AnchorLink } from '@freesewing/react/components/Link' +import { Link as WebLink } from '@freesewing/react/components/Link' import { CircleIcon, CisFemaleIcon, DocsIcon, FilterIcon, - HeartIcon, NewPatternIcon, ResetIcon, ShowcaseIcon, @@ -39,7 +29,6 @@ import { lineDrawingsBack, } from '@freesewing/react/components/LineDrawing' import { IconButton } from '@freesewing/react/components/Button' -import { ModalWrapper } from '@freesewing/react/components/Modal' import { KeyVal } from '@freesewing/react/components/KeyVal' import { MissingLinedrawing } from '../LineDrawing/missing.mjs' @@ -239,38 +228,6 @@ export const Collection = ({ Link = false, linkTo = 'about', editor = false, onC ) } -/* - * A helper component to show a design technique - * - * @param {object} props - All React props - * @param {function} props.Link - A Link component, typically specific to the framework for client-side routing - * @param {string} props.technique - The technique name/id - */ -const Technique = ({ Link = WebLink, technique }) => ( - - {technique} - -) - -/* - * A helper component to show a design tag - * - * @param {object} props - All React props - * @param {function} props.Link - A Link component, typically specific to the framework for client-side routing - * @param {string} props.tag - The tag name/id - */ -const Tag = ({ Link = WebLink, technique }) => ( - - {tag} - -) - const DesignCard = ({ name, lineDrawing = false, linkTo, Link, onClick }) => { if (!Link) Link = WebLink @@ -374,10 +331,6 @@ export const DesignInfo = ({ Link = false, design = false, noDocsLink = false }) // State const [back, setBack] = useState(false) - // Context - const { setModal, clearModal } = useContext(ModalContext) - const { setLoadingStatus } = useContext(LoadingStatusContext) - if (!design) return null // Line drawings @@ -391,13 +344,6 @@ export const DesignInfo = ({ Link = false, design = false, noDocsLink = false }) : [about[design].design] const tags = about[design].tags || [] const techniques = about[design].techniques || [] - const colors = { - 1: 'success', - 2: 'success', - 3: 'warning', - 4: 'warning', - 5: 'error', - } const makeButton = (
    @@ -554,21 +500,3 @@ export const DesignInfo = ({ Link = false, design = false, noDocsLink = false }) ) } - -const SharingIsCaring = ({ design }) => ( - <> -

    - Use #FreeSewing{capitalize(design)} to facilitate discovery -

    -

    - Please use the{' '} - - #FreeSewing{capitalize(design)} - {' '} - hashtag when discussing FreeSewing's {capitalize(design)} pattern online. -
    - Doing so can help others discover your post, which really is a win-win. -

    -

    If you like, you can copy the hashtag below:

    - -) diff --git a/packages/react/components/Editor/components/Accordion.mjs b/packages/react/components/Editor/components/Accordion.mjs index d92a1d4df82..67a942e6272 100644 --- a/packages/react/components/Editor/components/Accordion.mjs +++ b/packages/react/components/Editor/components/Accordion.mjs @@ -4,12 +4,12 @@ import React, { useState } from 'react' * DaisyUI's accordion seems rather unreliable. * So instead, we handle this in React state */ -const getProps = (isActive = false) => ({ +const getProps = () => ({ className: `tw:p-0 tw:rounded-lg tw:bg-transparent tw:hover:cursor-pointer tw:w-full tw:h-auto tw:content-start tw:text-left tw:list-none`, }) -const getSubProps = (isActive) => ({ +const getSubProps = () => ({ className: `tw:p-0 tw:rounded-none tw:bg-transparent tw:w-full tw:h-auto tw:content-start tw:text-left tw:list-none`, }) diff --git a/packages/react/components/Editor/components/Flag.mjs b/packages/react/components/Editor/components/Flag.mjs index 4fd1293f2fc..2b956042dcc 100644 --- a/packages/react/components/Editor/components/Flag.mjs +++ b/packages/react/components/Editor/components/Flag.mjs @@ -1,6 +1,6 @@ import React from 'react' import mustache from 'mustache' -import { flattenFlags, stripNamespace, bundlePatternTranslations } from '../lib/index.mjs' +import { flattenFlags } from '../lib/index.mjs' import { ChatIcon, ErrorIcon, @@ -115,7 +115,7 @@ export const FlagsAccordionTitle = ({ flags }) => { ) } -export const FlagsAccordionEntries = ({ flags, update, pattern, strings }) => { +export const FlagsAccordionEntries = ({ flags, update, strings }) => { const flagList = flattenFlags(flags) if (Object.keys(flagList).length < 1) return null diff --git a/packages/react/components/Editor/components/HeaderMenu.mjs b/packages/react/components/Editor/components/HeaderMenu.mjs index 0d5c15db305..7d426722a37 100644 --- a/packages/react/components/Editor/components/HeaderMenu.mjs +++ b/packages/react/components/Editor/components/HeaderMenu.mjs @@ -24,7 +24,6 @@ import { ResetIcon, RightIcon, RocketIcon, - RotateIcon, SaIcon, SaveAsIcon, SaveIcon, @@ -133,7 +132,7 @@ export const HeaderMenuTestViewDesignMeasurements = (props) => { } export const HeaderMenuDropdown = (props) => { - const { tooltip, toggle, open, setOpen, id, end = false } = props + const { toggle, open, setOpen, id } = props const [localOpen, setLocalOpen] = useState(false) useEffect(() => { @@ -460,10 +459,8 @@ export const HeaderMenuUndoIcons = (props) => { } export const HeaderMenuTestIcons = (props) => { - const { update, state, Design } = props + const { update } = props const Button = HeaderMenuButton - const size = 'tw:w-5 tw:h-5' - const undos = state._?.undos && state._.undos.length > 0 ? state._.undos : false return (
    @@ -660,11 +657,6 @@ export const HeaderMenuLayoutViewIcons = (props) => { } const pages = pattern.setStores[0].get('pages', {}) - const format = state.ui.print?.pages?.size - ? state.ui.print.pages.size - : settings.units === 'imperial' - ? 'letter' - : 'a4' const { cols, rows, count } = pages const blank = cols * rows - count diff --git a/packages/react/components/Editor/components/LoadingStatus.mjs b/packages/react/components/Editor/components/LoadingStatus.mjs index 0df781ae3ad..b36d14be75a 100644 --- a/packages/react/components/Editor/components/LoadingStatus.mjs +++ b/packages/react/components/Editor/components/LoadingStatus.mjs @@ -35,11 +35,6 @@ export const LoadingStatus = ({ state, update }) => { if (!state._.loading || Object.keys(state._.loading).length < 1) return null - const colorClasses = { - info: 'tw:bg-info tw:text-info-content', - primary: 'tw:bg-primary tw:text-primary-content', - } - return (
    diff --git a/packages/react/components/Editor/components/MovablePattern.mjs b/packages/react/components/Editor/components/MovablePattern.mjs index d455eceeab2..c94c1282e82 100644 --- a/packages/react/components/Editor/components/MovablePattern.mjs +++ b/packages/react/components/Editor/components/MovablePattern.mjs @@ -85,7 +85,7 @@ export const MovablePattern = ({ const sortedRenderProps = { ...renderProps, stacks: sortedStacks } - const Stack = ({ stackName, stack, settings, components, t }) => ( + const Stack = ({ stackName, stack, settings, components }) => ( { +const Button = ({ onClickCb, transform, Icon, title = '' }) => { const _onClick = (event) => { event.stopPropagation() onClickCb(event) @@ -413,23 +413,6 @@ const Button = ({ onClickCb, transform, Icon, children, title = '' }) => { ) } -export const ShowButtonsToggle = ({ ui, update }) => { - const hideButtons = (evt) => { - update.ui('hideMovableButtons', !evt.target.checked) - } - return ( - - ) -} - /** buttons for manipulating the part */ export const Buttons = ({ transform, flip, rotate, resetPart, rotate90, iconSize }) => { return ( diff --git a/packages/react/components/Editor/components/PatternLayout.mjs b/packages/react/components/Editor/components/PatternLayout.mjs index b2b6fc85720..5bddad435a8 100644 --- a/packages/react/components/Editor/components/PatternLayout.mjs +++ b/packages/react/components/Editor/components/PatternLayout.mjs @@ -1,17 +1,9 @@ import React from 'react' -import { useDesignTranslation } from '@freesewing/react/hooks/useDesignTranslation' import { ZoomContextProvider } from './ZoomablePattern.mjs' -import { - HeaderMenu, - HeaderMenuDraftViewDesignOptions, - HeaderMenuDraftViewCoreSettings, - HeaderMenuDraftViewUiPreferences, - HeaderMenuDraftViewFlags, -} from './HeaderMenu.mjs' +import { HeaderMenu } from './HeaderMenu.mjs' import { DesignOptionsMenu } from './menus/DesignOptionsMenu.mjs' import { CoreSettingsMenu } from './menus/CoreSettingsMenu.mjs' import { UiPreferencesMenu } from './menus/UiPreferencesMenu.mjs' -import { Accordion } from './Accordion.mjs' /** * A layout for views that include a drafted pattern @@ -24,9 +16,7 @@ import { Accordion } from './Accordion.mjs' * @param {object] pattern - The drafted pattern */ export const PatternLayout = (props) => { - const { menu = null, Design, pattern, update, config, state } = props - const i18n = useDesignTranslation(Design.designConfig.data.id) - const flags = props.pattern?.setStores?.[0]?.plugins?.['plugin-annotations']?.flags + const { Design, pattern, update, config, state } = props return ( diff --git a/packages/react/components/Editor/components/Set.mjs b/packages/react/components/Editor/components/Set.mjs index 1a347d7e962..5acbe1fe94a 100644 --- a/packages/react/components/Editor/components/Set.mjs +++ b/packages/react/components/Editor/components/Set.mjs @@ -58,7 +58,7 @@ export const UserSetPicker = ({ href={config.hrefNewSet} className="tw:daisy-btn tw:daisy-btn-accent tw:capitalize" target="_BLANK" - rel="nofollow" + rel="noreferrer" > Create a new measurements set diff --git a/packages/react/components/Editor/components/ZoomablePattern.mjs b/packages/react/components/Editor/components/ZoomablePattern.mjs index b090e4a8d06..04b731d8938 100644 --- a/packages/react/components/Editor/components/ZoomablePattern.mjs +++ b/packages/react/components/Editor/components/ZoomablePattern.mjs @@ -7,7 +7,7 @@ import { ZoomInIcon, ZoomOutIcon, RotateIcon } from '@freesewing/react/component * A pattern you can pan and zoom */ export const ZoomablePattern = forwardRef(function ZoomablePatternRef(props, ref) { - const { renderProps, rotate, update, components = {}, strings = {} } = props + const { renderProps, rotate, components = {}, strings = {} } = props const { onTransformed, zoomFunctions, setZoomFunctions } = useContext(ZoomContext) return ( diff --git a/packages/react/components/Editor/components/menus/Container.mjs b/packages/react/components/Editor/components/menus/Container.mjs index 1098cc0d959..4330e783665 100644 --- a/packages/react/components/Editor/components/menus/Container.mjs +++ b/packages/react/components/Editor/components/menus/Container.mjs @@ -36,10 +36,8 @@ export const MenuItem = ({ allowOverride = false, ux = 5, state, - docs, config, Design, - i18n, }) => { // Local state - whether the override input should be shown const [override, setOverride] = useState(false) diff --git a/packages/react/components/Editor/components/menus/CoreSettingsMenu.mjs b/packages/react/components/Editor/components/menus/CoreSettingsMenu.mjs index 0324ef0fa7c..d65204276ce 100644 --- a/packages/react/components/Editor/components/menus/CoreSettingsMenu.mjs +++ b/packages/react/components/Editor/components/menus/CoreSettingsMenu.mjs @@ -21,7 +21,7 @@ import { MenuScaleSettingValue, } from './Value.mjs' import { MenuItemGroup, MenuItem } from './Container.mjs' -import { SettingsIcon } from '@freesewing/react/components/Icon' +import { SettingsIcon, TrashIcon } from '@freesewing/react/components/Icon' /** * The core settings menu diff --git a/packages/react/components/Editor/components/menus/DraftMenu.mjs b/packages/react/components/Editor/components/menus/DraftMenu.mjs index 1fbb3c0a925..717c0737759 100644 --- a/packages/react/components/Editor/components/menus/DraftMenu.mjs +++ b/packages/react/components/Editor/components/menus/DraftMenu.mjs @@ -3,7 +3,7 @@ import { OptionsIcon, SettingsIcon, UiIcon } from '@freesewing/react/components/ import { DesignOptionsMenu } from './DesignOptionsMenu.mjs' import { CoreSettingsMenu } from './CoreSettingsMenu.mjs' import { UiPreferencesMenu } from './UiPreferencesMenu.mjs' -import { FlagsAccordionEntries } from '../Flag.mjs' +import { FlagsAccordionEntries, FlagsAccordionTitle } from '../Flag.mjs' import { Accordion } from '../Accordion.mjs' export const DraftMenu = ({ Design, pattern, state, update, i18n }) => { diff --git a/packages/react/components/Editor/components/menus/Input.mjs b/packages/react/components/Editor/components/menus/Input.mjs index 1be1f5c8d2f..a2cb6d1be28 100644 --- a/packages/react/components/Editor/components/menus/Input.mjs +++ b/packages/react/components/Editor/components/menus/Input.mjs @@ -16,12 +16,7 @@ import { mergeOptions } from '@freesewing/core' import { KeyVal } from '@freesewing/react/components/KeyVal' /** A boolean version of {@see MenuListInput} that sets up the necessary configuration */ -export const MenuBoolInput = (props) => { - const { name, config } = props - //const boolConfig = useBoolConfig(name, config) - - return -} +export const MenuBoolInput = (props) => /** A placeholder for an input to handle constant values */ export const MenuConstantInput = ({ @@ -59,41 +54,6 @@ export const MenuDegInput = (props) => { ) } -const getTitleAndDesc = (config = {}, i18n = {}, isDesignOption = false) => { - if (config.choiceTitles && config.choiceDescriptions) { - const current = typeof config.current === 'undefined' ? config.dflt : config.current - return { - title: config.choiceTitles[current], - desc: config.choiceDescriptions[current], - } - } - - let titleKey = config.choiceTitles - ? 'fixme' //config.choiceTitles[entry] - : isDesignOption - ? i18n?.en?.o?.[name] || name - : `${name}.o.${entry}` - if (!config.choiceTitles && i18n && i18n.en.o[`${name}.${entry}`]) - titleKey = i18n.en.o[`${name}.${entry}`] - const title = config.title - ? config.title - : config.titleMethod - ? config.titleMethod(entry) - : typeof titleKey === 'string' - ? i18n.en.o[titleKey]?.t - : titleKey.t - const desc = config.valueMethod - ? config.valueMethod(entry) - : typeof titleKey === 'string' - ? i18n.en.o[titleKey]?.d - : titleKey.d - - return { - title: 'fixmeTitle', - desc: 'fixmeDesc', - } -} - /** * An input for selecting and item from a list * @param {String} options.name the name of the property this input changes @@ -111,11 +71,9 @@ export const MenuListInput = ({ current, updateHandler, compact = false, - t, changed, design, isDesignOption = false, - i18n, }) => { const handleChange = useSharedHandlers({ dflt: config.dflt, @@ -125,7 +83,7 @@ export const MenuListInput = ({ }) return config.list.map((entry) => { - const { title = false, about = false } = config //getTitleAndDesc(config, i18n, isDesignOption) + const { title = false, about = false } = config if (!title || !about) console.log('No title or about in', { name, config, design }) const sideBySide = config.sideBySide || about.length + title.length < 42 @@ -286,7 +244,6 @@ export const MenuSliderInput = ({ setReset, children, changed, - i18n, state, Design, }) => { diff --git a/packages/react/components/Editor/components/menus/TestMenu.mjs b/packages/react/components/Editor/components/menus/TestMenu.mjs index d01d8891dae..e3dbb0b0a21 100644 --- a/packages/react/components/Editor/components/menus/TestMenu.mjs +++ b/packages/react/components/Editor/components/menus/TestMenu.mjs @@ -92,7 +92,7 @@ const SampleOptionButton = ({ name, i18n, update }) => ( ) -const SampleMeasurementButton = ({ name, i18n, update }) => ( +const SampleMeasurementButton = ({ name, update }) => ( ) : null} @@ -137,11 +139,7 @@ export const SaveView = ({ config, state, update }) => { } /> {withNotes ? ( - + ) : null}

    Don't have a PayPal account? - + Ko-fi.com/FreeSewing

    diff --git a/packages/react/components/Pattern/defs.mjs b/packages/react/components/Pattern/defs.mjs index 7160dc5e8d8..b83b5930172 100644 --- a/packages/react/components/Pattern/defs.mjs +++ b/packages/react/components/Pattern/defs.mjs @@ -1,4 +1,3 @@ -// eslint-disable-next-line no-unused-vars import React from 'react' import sanitize from 'html-react-parser' diff --git a/packages/react/components/Pattern/index.mjs b/packages/react/components/Pattern/index.mjs index bee2e647b8b..d731c0a4c61 100644 --- a/packages/react/components/Pattern/index.mjs +++ b/packages/react/components/Pattern/index.mjs @@ -1,5 +1,3 @@ -// Dependencies -import { cloudflareImageUrl } from '@freesewing/utils' // Components import React, { forwardRef } from 'react' import { Svg as DefaultSvg } from './svg.mjs' @@ -14,7 +12,6 @@ import { Grid as DefaultGrid } from './grid.mjs' import { Text as DefaultText, TextOnPath as DefaultTextOnPath } from './text.mjs' import { Circle as DefaultCircle } from './circle.mjs' import { getId, getProps, withinPartBounds, translateStrings } from './utils.mjs' -import { Link as WebLink } from '@freesewing/react/components/Link' /** * Default Pattern components that you can override @@ -101,6 +98,7 @@ const Pattern = forwardRef((props, ref) => { ) }) +Pattern.displayName = 'Pattern' export { // utils diff --git a/packages/react/components/Pattern/part.mjs b/packages/react/components/Pattern/part.mjs index c21fec65d2f..4d8c7ce6c2f 100644 --- a/packages/react/components/Pattern/part.mjs +++ b/packages/react/components/Pattern/part.mjs @@ -1,4 +1,3 @@ -// eslint-disable-next-line no-unused-vars import React, { forwardRef } from 'react' import { getId, getProps } from './utils.mjs' diff --git a/packages/react/components/Pattern/path.mjs b/packages/react/components/Pattern/path.mjs index d4e3cd9f160..e0ad889d23e 100644 --- a/packages/react/components/Pattern/path.mjs +++ b/packages/react/components/Pattern/path.mjs @@ -1,4 +1,3 @@ -// eslint-disable-next-line no-unused-vars import React from 'react' import { getId, getProps } from './utils.mjs' diff --git a/packages/react/components/Pattern/point.mjs b/packages/react/components/Pattern/point.mjs index 248896585c9..e59f975bb22 100644 --- a/packages/react/components/Pattern/point.mjs +++ b/packages/react/components/Pattern/point.mjs @@ -1,4 +1,3 @@ -// eslint-disable-next-line no-unused-vars import React from 'react' import { withinPartBounds } from './utils.mjs' diff --git a/packages/react/components/Pattern/snippet.mjs b/packages/react/components/Pattern/snippet.mjs index 741a401c6a1..510a0dcf64d 100644 --- a/packages/react/components/Pattern/snippet.mjs +++ b/packages/react/components/Pattern/snippet.mjs @@ -1,4 +1,3 @@ -// eslint-disable-next-line no-unused-vars import React from 'react' import { getProps } from './utils.mjs' diff --git a/packages/react/components/Pattern/svg.mjs b/packages/react/components/Pattern/svg.mjs index 8cfdcaa49c2..72779230a97 100644 --- a/packages/react/components/Pattern/svg.mjs +++ b/packages/react/components/Pattern/svg.mjs @@ -1,4 +1,3 @@ -// eslint-disable-next-line no-unused-vars import React from 'react' import { forwardRef } from 'react' diff --git a/packages/react/components/Pattern/text.mjs b/packages/react/components/Pattern/text.mjs index 46fd035eef2..3016d61f33a 100644 --- a/packages/react/components/Pattern/text.mjs +++ b/packages/react/components/Pattern/text.mjs @@ -1,4 +1,3 @@ -// eslint-disable-next-line no-unused-vars import React from 'react' import { translateStrings } from './utils.mjs' diff --git a/packages/react/components/Pattern/utils.mjs b/packages/react/components/Pattern/utils.mjs index 81f8adfc688..3ee8744e297 100644 --- a/packages/react/components/Pattern/utils.mjs +++ b/packages/react/components/Pattern/utils.mjs @@ -1,5 +1,3 @@ -import React from 'react' - /** * A method to generated an ID for an object part of a FreeSewing pattern * diff --git a/packages/react/components/Popout/index.mjs b/packages/react/components/Popout/index.mjs index bb8583503a7..f6692dd00ac 100644 --- a/packages/react/components/Popout/index.mjs +++ b/packages/react/components/Popout/index.mjs @@ -7,44 +7,44 @@ import { CloseIcon } from '@freesewing/react/components/Icon' */ const types = { comment: { - bg: 'tw:bg-success/5', + bg: 'tw:bg-success/5', border: 'tw:border-success', - text: 'tw:text-success', + text: 'tw:text-success', }, error: { - bg: 'tw:bg-error/5', + bg: 'tw:bg-error/5', border: 'tw:border-error', - text: 'tw:text-error', + text: 'tw:text-error', }, fixme: { - bg: 'tw:bg-neutral/5', + bg: 'tw:bg-neutral/5', border: 'tw:border-neutral', - text: 'tw:text-error', + text: 'tw:text-error', }, link: { - bg: 'tw:bg-secondary/5', + bg: 'tw:bg-secondary/5', border: 'tw:border-secondary', - text: 'tw:text-secondary', + text: 'tw:text-secondary', }, note: { - bg: 'tw:bg-primary/5', + bg: 'tw:bg-primary/5', border: 'tw:border-primary', - text: 'tw:text-primary', + text: 'tw:text-primary', }, related: { - bg: 'tw:bg-info/5', + bg: 'tw:bg-info/5', border: 'tw:border-info', - text: 'tw:text-info', + text: 'tw:text-info', }, tip: { - bg: 'tw:bg-accent/5', + bg: 'tw:bg-accent/5', border: 'tw:border-accent', - text: 'tw:text-accent', + text: 'tw:text-accent', }, warning: { - bg: 'tw:bg-warning/5', + bg: 'tw:bg-warning/5', border: 'tw:border-warning', - text: 'tw:text-warning', + text: 'tw:text-warning', }, } @@ -68,7 +68,7 @@ export const Popout = ({ compact = false, dense = false, hideable = false, - type = "note", + type = 'note', title = false, }) => { // Make this hideable/dismissable @@ -76,15 +76,17 @@ export const Popout = ({ if (hide) return null - return compact - ? {children} - : {children} + return compact ? ( + + {children} + + ) : ( + {children} + ) } -const RegularPopout = ({ by, children, compact, hideable, type, title, setHide }) => ( -
    +const RegularPopout = ({ by, children, hideable, type, title, setHide }) => ( +
    - ) const CompactPopout = ({ by, children, compact, dense, hideable, type, title, setHide }) => ( @@ -122,20 +123,27 @@ const CompactPopout = ({ by, children, compact, dense, hideable, type, title, se ) const PopoutTitle = ({ by, compact, hideable, setHide, title, type }) => ( -
    +
    {title ? title : types[type].title ? types[type].title : type.toUpperCase()} {compact ? | : null} - {(type === 'comment' && by) && by {by}} + {type === 'comment' && by && ( + + {' '} + by {by} + + )}
    {hideable && ( - )} -
    +
    ) diff --git a/packages/react/components/Profile/index.mjs b/packages/react/components/Profile/index.mjs index b5022e77220..3b76cc07251 100644 --- a/packages/react/components/Profile/index.mjs +++ b/packages/react/components/Profile/index.mjs @@ -1,5 +1,5 @@ // Dependencies -import { linkClasses, cloudflareImageUrl, getSearchParam } from '@freesewing/utils' +import { cloudflareImageUrl, getSearchParam } from '@freesewing/utils' // Context import { ModalContext } from '@freesewing/react/context/Modal' // Hooks @@ -9,7 +9,6 @@ import { useBackend } from '@freesewing/react/hooks/useBackend' // Components import { ModalWrapper } from '@freesewing/react/components/Modal' import { Link as WebLink } from '@freesewing/react/components/Link' -import { NoIcon, OkIcon, SaveIcon, RightIcon, WarningIcon } from '@freesewing/react/components/Icon' import { MiniWarning } from '@freesewing/react/components/Mini' import { KeyVal } from '@freesewing/react/components/KeyVal' import Markdown from 'react-markdown' @@ -40,12 +39,7 @@ export const OwnProfile = (props) => { * @param {number} [props.uid = false] - The user ID for which to show the profile * @returns {JSX.Element} */ -export const UserProfile = ({ - Link = false, - setTitle = false, - uid = false, - fromUrl = false, -}) => { +export const UserProfile = ({ Link = false, setTitle = false, uid = false, fromUrl = false }) => { if (!uid && !fromUrl) return ( @@ -69,7 +63,7 @@ export const UserProfile = ({ const urlId = getSearchParam(fromUrl) if (urlId && urlId !== ruid) setRuid(urlId) } - if (ruid) loadProfileData(ruid, backend, setData) + if (ruid) loadProfileData(ruid, backend, setData, setTitle) }, [uid, fromUrl, ruid]) return ( @@ -121,7 +115,10 @@ export const Avatar = ({ ihash }) => { ) } -async function loadProfileData(uid, backend, setData) { +async function loadProfileData(uid, backend, setData, setTitle = false) { const [status, body] = await backend.getUserProfile(uid) - if (status === 200 && body.result === 'success' && body.profile) setData(body.profile) + if (status === 200 && body.result === 'success' && body.profile) { + setData(body.profile) + if (typeof setTitle === 'function' && body.profile.username) setTitle(body.profile.username) + } } diff --git a/packages/react/components/Role/index.mjs b/packages/react/components/Role/index.mjs index e6d0689b8e6..51fce1e35f2 100644 --- a/packages/react/components/Role/index.mjs +++ b/packages/react/components/Role/index.mjs @@ -9,7 +9,7 @@ import { Link as DefaultLink } from '@freesewing/react/components/Link' import { LockIcon, PlusIcon } from '@freesewing/react/components/Icon' import { Spinner } from '@freesewing/react/components/Spinner' import { Popout } from '@freesewing/react/components/Popout' -import { H1, H2, H3 } from '@freesewing/react/components/Heading' +import { H3 } from '@freesewing/react/components/Heading' import { Consent } from '@freesewing/react/components/Account' const Wrap = ({ children }) => ( @@ -104,7 +104,7 @@ const AccountStatusUnknown = ({ banner }) => ( ) -const RoleLacking = ({ t, requiredRole, role, banner }) => ( +const RoleLacking = ({ requiredRole, role, banner }) => ( {banner}

    You lack the required role to access this content

    @@ -174,7 +174,7 @@ const ConsentLacking = ({ banner, refresh }) => { * @param {JSX.Element} props.children - The component children, will be rendered if props.js is not set * @returns {JSX.Element} */ -export const RoleBlock = ({ children, role = "admin", Link = false }) => { +export const RoleBlock = ({ children, role = 'admin', Link = false }) => { if (!Link) Link = DefaultLink const requiredRole = role @@ -275,7 +275,6 @@ export const UserVisitorContent = ({ userContent = null, visitorContent = null } const [ready, setReady] = useState(false) const [error, setError] = useState(false) - const [refreshCount, setRefreshCount] = useState(0) /* * Avoid hydration errors @@ -300,14 +299,15 @@ export const UserVisitorContent = ({ userContent = null, visitorContent = null } if (!account.bestBefore || account.bestBefore < Date.now()) verifyUser() } setReady(true) - }, [refreshCount]) - - const refresh = () => { - setRefreshCount(refreshCount + 1) - setError(false) - } + }, []) if (!ready) return + if (error) + return ( + + This is unexpected. You may want to report this. + + ) return token && account.username ? userContent : visitorContent } diff --git a/packages/react/components/SignIn/index.mjs b/packages/react/components/SignIn/index.mjs index fe2dd641e69..49b402f5621 100644 --- a/packages/react/components/SignIn/index.mjs +++ b/packages/react/components/SignIn/index.mjs @@ -1,11 +1,5 @@ // Utils -import { - linkClasses, - horFlexClasses, - horFlexClassesNoSm, - capitalize, - getSearchParam, -} from '@freesewing/utils' +import { horFlexClasses, horFlexClassesNoSm, getSearchParam, navigate } from '@freesewing/utils' // Context import { LoadingStatusContext } from '@freesewing/react/context/LoadingStatus' // Hooks @@ -21,13 +15,11 @@ import { KeyIcon, LockIcon, WarningIcon, - GoogleIcon, - GitHubIcon, FreeSewingIcon, UserIcon, } from '@freesewing/react/components/Icon' import { MfaInput, StringInput, PasswordInput } from '@freesewing/react/components/Input' -import { H1, H2, H3, H4 } from '@freesewing/react/components/Heading' +import { H1 } from '@freesewing/react/components/Heading' /* * @@ -44,7 +36,7 @@ import { H1, H2, H3, H4 } from '@freesewing/react/components/Heading' * @returns {JSX.Element} */ export const SignIn = ({ onSuccess = false, silent = false }) => { - const { account, setAccount, setToken, seenUser, setSeenUser } = useAccount() + const { setAccount, setToken, seenUser, setSeenUser } = useAccount() const backend = useBackend() const { setLoadingStatus } = useContext(LoadingStatusContext) @@ -149,15 +141,6 @@ export const SignIn = ({ onSuccess = false, silent = false }) => { } } - const initOauth = async (provider) => { - setLoadingStatus([true, 'Contacting the FreeSewing backend']) - const [status, body] = await backend.oauthInit(provider.toLowerCase()) - if (status === 200 && body.result === 'success') { - setLoadingStatus([true, `Contacting ${capitalize(provider)}`]) - window.location.href = body.authUrl - } - } - const btnClasses = `tw:daisy-btn tw:capitalize tw:w-full tw:mt-4 ${ signInFailed ? 'tw:daisy-btn-warning' : 'tw:daisy-btn-primary' } tw:transition-colors tw:ease-in-out tw:duration-300 ${horFlexClassesNoSm}` @@ -412,7 +395,12 @@ export const SignInConfirmation = ({ onSuccess = false }) => { } // Short-circuit errors - if (error === 'noId') return You seem to have arrived on this page in a way that is not supported + if (error === 'noId') + return ( + + You seem to have arrived on this page in a way that is not supported + + ) if (error && mfa) return error === 'signInFailed' ? ( <> diff --git a/packages/react/components/SignUp/index.mjs b/packages/react/components/SignUp/index.mjs index c26e838ae00..cebe61e11cc 100644 --- a/packages/react/components/SignUp/index.mjs +++ b/packages/react/components/SignUp/index.mjs @@ -3,7 +3,6 @@ import { validateEmail, validateTld, getSearchParam } from '@freesewing/utils' // Hooks import React, { useState, useContext, useEffect } from 'react' -import { useAccount } from '@freesewing/react/hooks/useAccount' import { useBackend } from '@freesewing/react/hooks/useBackend' // Context @@ -12,16 +11,7 @@ import { ModalContext } from '@freesewing/react/context/Modal' // Components import { Link } from '@freesewing/react/components/Link' -import { - LeftIcon, - RightIcon, - HelpIcon, - GoogleIcon, - GitHubIcon, - KeyIcon, - EmailIcon, - DownIcon, -} from '@freesewing/react/components/Icon' +import { LeftIcon, HelpIcon, KeyIcon, EmailIcon } from '@freesewing/react/components/Icon' import { ModalWrapper } from '@freesewing/react/components/Modal' import { EmailInput } from '@freesewing/react/components/Input' import { IconButton } from '@freesewing/react/components/Button' @@ -42,7 +32,6 @@ export const SignUp = ({ embed = false }) => { const [email, setEmail] = useState('') const [emailValid, setEmailValid] = useState(false) const [result, setResult] = useState(false) - const [showAll, setShowAll] = useState(false) // Hooks const backend = useBackend() @@ -93,14 +82,6 @@ export const SignUp = ({ embed = false }) => { } } - const initOauth = async (provider) => { - setLoadingStatus([true, 'Contacting the backend']) - const [status, body] = await backend.oauthInit(provider.toLowerCase()) - if (status === 200 && body.result === 'success') { - setLoadingStatus([true, `Contacting ${provider}`]) - window.location.href = body.authUrl - } - } const Heading = embed ? ({ children }) =>

    {children}

    : ({ children }) =>

    {children}

    @@ -200,10 +181,9 @@ export const SignUp = ({ embed = false }) => { * * @component * @param {object} props - All component props - * @param {function} [props.onSuccess = false] - A method to run when the sign in is successful * @returns {JSX.Element} */ -export const SignUpConfirmation = ({ onSuccess = false }) => { +export const SignUpConfirmation = () => { // State const [id, setId] = useState() const [error, setError] = useState(false) @@ -219,7 +199,12 @@ export const SignUpConfirmation = ({ onSuccess = false }) => { }, [id, check]) // Short-circuit errors - if (error === 'noId') return You seem to have arrived on this page in a way that is not supported + if (error === 'noId') + return ( + + You seem to have arrived on this page in a way that is not supported + + ) // If we do not (yet) have the data, show a loader if (!id || !check) return ( diff --git a/packages/react/components/Stats/index.mjs b/packages/react/components/Stats/index.mjs index 40ad6439f45..77f0b77a666 100644 --- a/packages/react/components/Stats/index.mjs +++ b/packages/react/components/Stats/index.mjs @@ -7,11 +7,7 @@ import { useBackend } from '@freesewing/react/hooks/useBackend' import { Spinner } from '@freesewing/react/components/Spinner' import { Link as WebLink } from '@freesewing/react/components/Link' import { ChartWrapper } from '@freesewing/react/components/Echart' - -const meta = { - title: 'FreeSewing by numbers', - description: 'Some high-level numbers about Freesewing', -} +import { Popout } from '@freesewing/react/components/Popout' const option = { tooltip: { @@ -104,6 +100,13 @@ export const Stats = ({ Link = false }) => { }, ] + if (error) + return ( + + This is unexpected. You may want to report this. + + ) + return ( <>
    diff --git a/packages/react/components/Tab/index.mjs b/packages/react/components/Tab/index.mjs index d973e458961..518085b042f 100644 --- a/packages/react/components/Tab/index.mjs +++ b/packages/react/components/Tab/index.mjs @@ -37,7 +37,7 @@ export const Tabs = ({ tabs = '', active = 0, children, withModal = false }) => return (
    -
    +
    {tablist.map((title, tabId) => { const btnClasses = `tw:text-lg tw:font-bold tw:capitalize tw:daisy-tab tw:h-auto tw:grow tw:py-1 ${ activeTab === tabId ? 'tw:daisy-tab-active' : '' diff --git a/packages/react/components/Uuid/index.mjs b/packages/react/components/Uuid/index.mjs index 2d423ede21a..4dd737f068d 100644 --- a/packages/react/components/Uuid/index.mjs +++ b/packages/react/components/Uuid/index.mjs @@ -1,4 +1,4 @@ -import React, { useState } from 'react' +import React from 'react' import { shortUuid } from '@freesewing/utils' import { Link as WebLink } from '@freesewing/react/components/Link' import { CopyToClipboardButton } from '@freesewing/react/components/Button' @@ -14,9 +14,7 @@ import { CopyToClipboardButton } from '@freesewing/react/components/Button' * @param {string} [props.label = false] - An optional label to pass to the CopyToClipboardButton * @returns {JSX.Element} */ -export const Uuid = ({ uuid, href = false, label = "UUID", Link = false }) => { - const [full, setFull] = useState() - const short = shortUuid(uuid) +export const Uuid = ({ uuid, href = false, label = 'UUID', Link = false }) => { if (!Link) Link = WebLink if (href === false) diff --git a/packages/react/components/Xray/index.mjs b/packages/react/components/Xray/index.mjs index 6099b60678c..b300f096809 100644 --- a/packages/react/components/Xray/index.mjs +++ b/packages/react/components/Xray/index.mjs @@ -81,3 +81,5 @@ export const Xray = forwardRef((props, ref) => { ) }) + +Xray.displayName = 'Xray' diff --git a/packages/react/components/Xray/path.mjs b/packages/react/components/Xray/path.mjs index 1c916562154..09a22194d68 100644 --- a/packages/react/components/Xray/path.mjs +++ b/packages/react/components/Xray/path.mjs @@ -96,9 +96,8 @@ export const PathXray = ({ ) } -const PathXrayInfo = ({ path, pathName, stackName, part }) => { +const PathXrayInfo = ({ path, pathName, stackName }) => { const [rounded, setRounded] = useState(true) - const log = (val) => console.log(val) const rounder = rounded ? round : (val) => val return ( diff --git a/packages/react/components/Xray/point.mjs b/packages/react/components/Xray/point.mjs index 693f13f7bc1..24067df9c1e 100644 --- a/packages/react/components/Xray/point.mjs +++ b/packages/react/components/Xray/point.mjs @@ -71,7 +71,7 @@ export const PointXray = ({ ) } -const PointXrayInfo = ({ point, pointName, stackName, part }) => { +const PointXrayInfo = ({ point, pointName, stackName }) => { const [rounded, setRounded] = useState(true) const rounder = rounded ? round : (val) => val diff --git a/packages/react/eslint.config.mjs b/packages/react/eslint.config.mjs new file mode 100644 index 00000000000..81d850381fb --- /dev/null +++ b/packages/react/eslint.config.mjs @@ -0,0 +1,30 @@ +import js from '@eslint/js' +import globals from 'globals' +import pluginReact from 'eslint-plugin-react' +import { defineConfig } from 'eslint/config' + +export default defineConfig([ + { + files: ['**/*.{js,mjs,cjs,jsx}'], + plugins: { js }, + extends: ['js/recommended'], + }, + { + files: ['**/*.{js,mjs,cjs,jsx}'], + languageOptions: { globals: { ...globals.browser, ...globals.node } }, + }, + { + plugins: pluginReact.configs.flat.recommended.plugins, + languageOptions: pluginReact.configs.flat.recommended.languageOptions, + rules: { + ...pluginReact.configs.flat.recommended.rules, + // Maybe one day someone wants to do this, but we use jsdoc for now + 'react/prop-types': 0, + }, + settings: { + react: { + version: 'detect', + }, + }, + }, +]) diff --git a/packages/react/hooks/useControl/index.mjs b/packages/react/hooks/useControl/index.mjs index 0794be5433f..406b58cd0e7 100644 --- a/packages/react/hooks/useControl/index.mjs +++ b/packages/react/hooks/useControl/index.mjs @@ -1,8 +1,7 @@ // Context import { LoadingStatusContext } from '@freesewing/react/context/LoadingStatus' - // Hooks -import React, { useState, useContext } from 'react' +import { useState, useContext } from 'react' import { useAccount } from '@freesewing/react/hooks/useAccount' import { useBackend } from '@freesewing/react/hooks/useBackend' diff --git a/packages/react/hooks/useFilter/index.mjs b/packages/react/hooks/useFilter/index.mjs index b9b74b8232d..06a4ad034d8 100644 --- a/packages/react/hooks/useFilter/index.mjs +++ b/packages/react/hooks/useFilter/index.mjs @@ -1,8 +1,6 @@ -import React from 'react' import { useAtom } from 'jotai' import { atomWithHash } from 'jotai-location' -const filterAtom = atomWithHash('filter', { }) +const filterAtom = atomWithHash('filter', {}) export const useFilter = () => useAtom(filterAtom) - diff --git a/packages/react/hooks/useSelection/index.mjs b/packages/react/hooks/useSelection/index.mjs index ac3825ef3c0..c6b7b75f072 100644 --- a/packages/react/hooks/useSelection/index.mjs +++ b/packages/react/hooks/useSelection/index.mjs @@ -1,4 +1,4 @@ -import React, { useState } from 'react' +import { useState } from 'react' export const useSelection = (items) => { const [selection, setSelection] = useState({}) diff --git a/packages/react/hooks/useStateObject/index.mjs b/packages/react/hooks/useStateObject/index.mjs index 71e48aa7a53..8ebb560751b 100644 --- a/packages/react/hooks/useStateObject/index.mjs +++ b/packages/react/hooks/useStateObject/index.mjs @@ -1,4 +1,4 @@ -import React, { useState } from 'react' +import { useState } from 'react' import set from 'lodash/set.js' import unset from 'lodash/unset.js' diff --git a/packages/react/lib/RestClient/index.mjs b/packages/react/lib/RestClient/index.mjs index cf8e8d94b88..d7e751004d3 100644 --- a/packages/react/lib/RestClient/index.mjs +++ b/packages/react/lib/RestClient/index.mjs @@ -68,9 +68,11 @@ async function withoutBody(method = 'GET', url, headers = {}, raw = false, log = try { body = raw ? await response.text() : await response.json() } catch (err) { + console.log(err) try { body = await response.text() } catch (err) { + console.log(err) body = false } } @@ -125,9 +127,11 @@ async function withBody(method = 'POST', url, data, headers, raw = false, log = try { body = raw ? await response.text() : await response.json() } catch (err) { + console.log(err) try { body = await response.text() } catch (err) { + console.log(err) body = false } } diff --git a/packages/react/lib/force-tailwind.mjs b/packages/react/lib/force-tailwind.mjs deleted file mode 100644 index 212907a4c97..00000000000 --- a/packages/react/lib/force-tailwind.mjs +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react' - -const html = ( - <> - - -)