From 9ae1bd8e1ca914b34047880ca0c9f847c3bd3b34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20=C5=9Al=C4=99zak?= Date: Wed, 23 Jul 2025 08:54:28 +0200 Subject: [PATCH 01/11] fix tsc checks, replace eslint with biomejs --- .github/workflows/lint-web.yml | 2 +- Dockerfile | 2 +- web/.nvmrc | 2 +- web/.typesafe-i18n.json | 6 +- web/biome.json | 75 + web/package.json | 22 +- web/pnpm-lock.yaml | 734 +---- web/src/components/LogoContainer/style.scss | 2 - web/src/i18n/formatters.ts | 15 +- web/src/i18n/i18n-react.tsx | 29 +- web/src/i18n/i18n-types.ts | 2487 +++++++++-------- web/src/i18n/i18n-util.async.ts | 29 +- web/src/i18n/i18n-util.sync.ts | 25 +- web/src/i18n/i18n-util.ts | 87 +- web/src/pages/enrollment/EnrollmentPage.tsx | 6 +- .../components/AdminInfo/style.scss | 2 - .../EnrollmentSideBar/EnrollmentSideBar.tsx | 4 +- .../components/EnrollmentSideBar/style.scss | 3 +- .../EnrollmentStepControls.tsx | 2 +- .../EnrollmentStepControls/style.scss | 6 +- .../EnrollmentStepIndicator/style.scss | 3 +- .../enrollment/components/TimeLeft/style.scss | 2 - .../hooks/store/useEnrollmentStore.tsx | 2 +- .../DataVerificationStep.tsx | 2 +- .../steps/DataVerificationStep/style.scss | 3 +- .../steps/DeviceStep/DeviceStep.tsx | 4 +- .../components/CreateDevice.tsx | 4 +- .../DeviceConfiguration.tsx | 11 +- .../components/DeviceConfiguration/style.scss | 2 - .../components/ConfigureDeviceCard/style.scss | 2 - .../components/QuickGuideCard/style.scss | 2 - .../enrollment/steps/DeviceStep/style.scss | 4 +- .../enrollment/steps/FinishStep/style.scss | 2 - .../steps/PasswordStep/PasswordStep.tsx | 6 +- .../enrollment/steps/PasswordStep/style.scss | 2 - .../steps/WelcomeStep/WelcomeStep.tsx | 22 +- .../enrollment/steps/WelcomeStep/style.scss | 5 +- web/src/pages/enrollment/style.scss | 2 - .../DeviceSetupMethodCard.tsx | 2 +- .../main/DeviceSetupMethodCard/style.scss | 2 - web/src/pages/main/MainPage.tsx | 4 +- web/src/pages/main/style.scss | 2 - web/src/pages/mfa/OpenIDCallback.tsx | 2 +- web/src/pages/mfa/style.scss | 2 - .../components/OpenIDCallbackCard.tsx | 104 +- .../openidCallback/components/style.scss | 3 +- web/src/pages/openidCallback/style.scss | 3 +- .../pages/passwordReset/PasswordResetPage.tsx | 6 +- .../hooks/usePasswordResetStore.tsx | 2 +- .../passwordReset/steps/CodeStep/CodeStep.tsx | 2 +- .../steps/EmailStep/EmailStep.tsx | 4 +- .../steps/PasswordStep/PasswordStep.tsx | 4 +- web/src/pages/passwordReset/style.scss | 8 +- web/src/pages/sessionTimeout/style.scss | 2 - web/src/pages/token/components/TokenCard.tsx | 110 +- web/src/pages/token/components/style.scss | 2 - web/src/pages/token/style.scss | 5 +- .../Form/FormDevTools/FormDevTools.tsx | 21 - .../components/Form/FormDevTools/style.scss | 23 - .../components/Form/FormInput/FormInput.tsx | 12 +- .../components/Form/FormSelect/FormSelect.tsx | 30 +- .../components/Form/FormToggle/FormToggle.tsx | 8 +- .../layout/ActionButton/ActionButton.tsx | 2 +- .../layout/BigInfoBox/BigInfoBox.tsx | 2 +- .../components/layout/Button/Button.tsx | 7 +- .../shared/components/layout/Card/Card.tsx | 4 +- .../shared/components/layout/Card/style.scss | 2 - .../components/layout/Checkbox/CheckBox.tsx | 4 +- .../components/layout/Divider/Divider.tsx | 2 +- .../layout/FloatingArrow/FloatingArrow.tsx | 2 +- .../layout/FloatingBox/FloatingBox.tsx | 2 +- .../shared/components/layout/Input/Input.tsx | 17 +- .../shared/components/layout/Input/types.ts | 4 +- .../layout/MessageBox/MessageBox.tsx | 12 +- .../layout/PageContainer/PageContainer.tsx | 2 +- .../layout/PageContainer/style.scss | 2 - .../components/layout/Select/Select.tsx | 12 +- .../SelectOptionRow/SelectOptionRow.tsx | 2 +- .../shared/components/layout/Select/types.ts | 4 +- web/src/shared/components/layout/Tag/Tag.tsx | 2 +- .../components/layout/Toggle/Toggle.tsx | 4 +- .../components/ToggleOption/ToggleOption.tsx | 4 +- .../layout/hooks/theme/useTheme.tsx | 2 +- .../components/layout/hooks/theme/utils.ts | 2 +- .../components/svg/DefguardLogoText.tsx | 1 + .../svg/EnrollmentSelectGraphic.tsx | 1 + .../components/svg/IconArrowSingleLarge.tsx | 1 + .../components/svg/IconArrowSingleSmall.tsx | 1 + web/src/shared/components/svg/IconAsterix.tsx | 1 + web/src/shared/components/svg/IconCancel.tsx | 1 + web/src/shared/components/svg/IconCopy.tsx | 1 + .../shared/components/svg/IconDownload.tsx | 1 + .../shared/components/svg/IconHamburger.tsx | 1 + web/src/shared/components/svg/IconInfo.tsx | 1 + .../shared/components/svg/IconInfoSuccess.tsx | 1 + web/src/shared/components/svg/IconQr.tsx | 1 + web/src/shared/components/svg/IconWarning.tsx | 1 + web/src/shared/components/svg/IconX.tsx | 1 + .../svg/PasswordResetSelectGraphic.tsx | 1 + web/src/shared/components/svg/TeoniteLogo.tsx | 1 + web/src/shared/hooks/api/useApi.tsx | 4 +- web/src/shared/hooks/api/utils.ts | 2 +- web/src/shared/patterns.ts | 2 +- web/src/shared/validators/password.ts | 2 +- web/tsconfig.app.json | 40 + web/tsconfig.json | 41 +- web/vite.config.ts | 8 +- 107 files changed, 1863 insertions(+), 2331 deletions(-) create mode 100644 web/biome.json delete mode 100644 web/src/shared/components/Form/FormDevTools/FormDevTools.tsx delete mode 100644 web/src/shared/components/Form/FormDevTools/style.scss create mode 100644 web/tsconfig.app.json diff --git a/.github/workflows/lint-web.yml b/.github/workflows/lint-web.yml index a34f7c8..c5d0573 100644 --- a/.github/workflows/lint-web.yml +++ b/.github/workflows/lint-web.yml @@ -21,7 +21,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 24 - name: install deps working-directory: ./web run: | diff --git a/Dockerfile b/Dockerfile index f99b078..43765a6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:22-alpine AS web +FROM node:24-alpine AS web WORKDIR /app COPY web/package.json . diff --git a/web/.nvmrc b/web/.nvmrc index 0595241..19f23bc 100644 --- a/web/.nvmrc +++ b/web/.nvmrc @@ -1 +1 @@ -v20.4 \ No newline at end of file +v24.4 diff --git a/web/.typesafe-i18n.json b/web/.typesafe-i18n.json index b3224e1..dd9526a 100644 --- a/web/.typesafe-i18n.json +++ b/web/.typesafe-i18n.json @@ -1,4 +1,4 @@ { - "adapter": "react", - "$schema": "https://unpkg.com/typesafe-i18n@5.26.2/schema/typesafe-i18n.json" -} \ No newline at end of file + "adapter": "react", + "$schema": "https://unpkg.com/typesafe-i18n@5.26.2/schema/typesafe-i18n.json" +} diff --git a/web/biome.json b/web/biome.json new file mode 100644 index 0000000..8853a47 --- /dev/null +++ b/web/biome.json @@ -0,0 +1,75 @@ +{ + "$schema": "https://biomejs.dev/schemas/2.1.2/schema.json", + "vcs": { "enabled": false, "clientKind": "git", "useIgnoreFile": false }, + "files": { "ignoreUnknown": false }, + "formatter": { + "enabled": true, + "formatWithErrors": false, + "indentStyle": "space", + "indentWidth": 2, + "lineEnding": "lf", + "lineWidth": 90, + "attributePosition": "auto", + "bracketSameLine": false, + "bracketSpacing": true, + "expand": "auto", + "useEditorconfig": true, + "includes": ["./src/**", "!./src/i18n/*.ts", "!./src/i18n/*.tsx"] + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, + "a11y": "off", + "complexity": { + "noBannedTypes": "error", + "noUselessTypeConstraint": "error" + }, + "correctness": { + "noChildrenProp": "error", + "noPrecisionLoss": "error", + "noUnusedVariables": "error", + "useExhaustiveDependencies": "error", + "useHookAtTopLevel": "error", + "useJsxKeyInIterable": "error" + }, + "security": { "noDangerouslySetInnerHtmlWithChildren": "error" }, + "style": { + "noNamespace": "error", + "noNonNullAssertion": "error", + "useArrayLiterals": "error", + "useAsConstAssertion": "error", + "useBlockStatements": "off" + }, + "suspicious": { + "noCommentText": "error", + "noDuplicateJsxProps": "error", + "noExplicitAny": "error", + "noExtraNonNullAssertion": "error", + "noMisleadingInstantiator": "error", + "noUnsafeDeclarationMerging": "error", + "noArrayIndexKey": "off" + } + }, + "includes": ["src/**", "!**/dist/", "!src/shared/components/svg/*", "!src/i18n/**"] + }, + "javascript": { + "formatter": { + "jsxQuoteStyle": "double", + "quoteProperties": "asNeeded", + "trailingCommas": "all", + "semicolons": "always", + "arrowParentheses": "always", + "bracketSameLine": false, + "quoteStyle": "single", + "attributePosition": "auto", + "bracketSpacing": true + } + }, + "html": { "formatter": { "selfCloseVoidElements": "always" } }, + "overrides": [{ "includes": ["**/*.js"] }], + "assist": { + "enabled": true, + "actions": { "source": { "organizeImports": "on" } } + } +} diff --git a/web/package.json b/web/package.json index 4d3d096..15fe53d 100644 --- a/web/package.json +++ b/web/package.json @@ -5,14 +5,15 @@ "type": "module", "scripts": { "dev": "npm-run-all --parallel vite typesafe-i18n", - "build": "vite build", + "typecheck": "tsc --project ./tsconfig.app.json", + "build": "pnpm run typecheck && vite build", "preview": "vite preview", "typesafe-i18n": "typesafe-i18n", "generate-translation-types": "typesafe-i18n --no-watch", - "lint": "eslint --config ./.eslintrc.cjs src && prettier --check 'src/**/*.ts' 'src/**/*.tsx' 'src/**/*.scss'", - "fix": "prettier -w src/**/*.{ts,tsx,scss} && eslint --fix --config ./.eslintrc.cjs src", + "fix": "biome check --fix && prettier src/**/*.scss -w --log-level silent", + "lint": "biome lint && pnpm run typecheck && prettier src/**/*.scss --check --log-level error", + "lint-ci": "biome ci && pnpm run typecheck && prettier src/**/*.scss --check --log-level error", "vite": "vite", - "eslint": "eslint", "prettier": "prettier", "parse-svgs": "svgr --no-index --jsx-runtime 'automatic' --svgo-config ./svgo.config.json --prettier-config ./.prettierrc --out-dir ./src/shared/components/svg/ --typescript ./src/shared/images/svg/", "svgr": "svgr" @@ -65,6 +66,7 @@ "zustand": "^4.5.7" }, "devDependencies": { + "@biomejs/biome": "2.1.2", "@svgr/cli": "^8.1.0", "@tanstack/react-query": "^4.40.1", "@tanstack/react-query-devtools": "^4.40.1", @@ -73,27 +75,15 @@ "@types/node": "^20.19.9", "@types/react": "^18.3.23", "@types/react-dom": "^18.3.7", - "@typescript-eslint/eslint-plugin": "^6.21.0", - "@typescript-eslint/parser": "^6.21.0", "@vitejs/plugin-react": "^4.7.0", "@vitejs/plugin-react-swc": "^3.11.0", "autoprefixer": "^10.4.21", - "eslint": "^8.57.1", - "eslint-config-prettier": "^8.10.2", - "eslint-plugin-import": "^2.32.0", - "eslint-plugin-prettier": "^5.5.3", - "eslint-plugin-react": "^7.37.5", - "eslint-plugin-react-hooks": "^4.6.2", - "eslint-plugin-react-refresh": "^0.4.20", - "eslint-plugin-simple-import-sort": "^10.0.0", "npm-run-all": "^4.1.5", "postcss": "^8.5.6", "prettier": "^3.6.2", "sass": "~1.70.0", - "typedoc": "^0.24.8", "typesafe-i18n": "^5.26.2", "typescript": "^5.8.3", - "typescript-eslint-language-service": "^5.0.5", "vite": "^4.5.14" } } diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index 9be0cfc..5fb5541 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -87,6 +87,9 @@ importers: specifier: ^4.5.7 version: 4.5.7(@types/react@18.3.23)(react@18.3.1) devDependencies: + '@biomejs/biome': + specifier: 2.1.2 + version: 2.1.2 '@svgr/cli': specifier: ^8.1.0 version: 8.1.0(typescript@5.8.3) @@ -111,12 +114,6 @@ importers: '@types/react-dom': specifier: ^18.3.7 version: 18.3.7(@types/react@18.3.23) - '@typescript-eslint/eslint-plugin': - specifier: ^6.21.0 - version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3) - '@typescript-eslint/parser': - specifier: ^6.21.0 - version: 6.21.0(eslint@8.57.1)(typescript@5.8.3) '@vitejs/plugin-react': specifier: ^4.7.0 version: 4.7.0(vite@4.5.14(@types/node@20.19.9)(sass@1.70.0)) @@ -126,30 +123,6 @@ importers: autoprefixer: specifier: ^10.4.21 version: 10.4.21(postcss@8.5.6) - eslint: - specifier: ^8.57.1 - version: 8.57.1 - eslint-config-prettier: - specifier: ^8.10.2 - version: 8.10.2(eslint@8.57.1) - eslint-plugin-import: - specifier: ^2.32.0 - version: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1) - eslint-plugin-prettier: - specifier: ^5.5.3 - version: 5.5.3(eslint-config-prettier@8.10.2(eslint@8.57.1))(eslint@8.57.1)(prettier@3.6.2) - eslint-plugin-react: - specifier: ^7.37.5 - version: 7.37.5(eslint@8.57.1) - eslint-plugin-react-hooks: - specifier: ^4.6.2 - version: 4.6.2(eslint@8.57.1) - eslint-plugin-react-refresh: - specifier: ^0.4.20 - version: 0.4.20(eslint@8.57.1) - eslint-plugin-simple-import-sort: - specifier: ^10.0.0 - version: 10.0.0(eslint@8.57.1) npm-run-all: specifier: ^4.1.5 version: 4.1.5 @@ -162,9 +135,6 @@ importers: sass: specifier: ~1.70.0 version: 1.70.0 - typedoc: - specifier: ^0.24.8 - version: 0.24.8(typescript@5.8.3) typesafe-i18n: specifier: ^5.26.2 version: 5.26.2(typescript@5.8.3) @@ -267,6 +237,59 @@ packages: resolution: {integrity: sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ==} engines: {node: '>=6.9.0'} + '@biomejs/biome@2.1.2': + resolution: {integrity: sha512-yq8ZZuKuBVDgAS76LWCfFKHSYIAgqkxVB3mGVVpOe2vSkUTs7xG46zXZeNPRNVjiJuw0SZ3+J2rXiYx0RUpfGg==} + engines: {node: '>=14.21.3'} + hasBin: true + + '@biomejs/cli-darwin-arm64@2.1.2': + resolution: {integrity: sha512-leFAks64PEIjc7MY/cLjE8u5OcfBKkcDB0szxsWUB4aDfemBep1WVKt0qrEyqZBOW8LPHzrFMyDl3FhuuA0E7g==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [darwin] + + '@biomejs/cli-darwin-x64@2.1.2': + resolution: {integrity: sha512-Nmmv7wRX5Nj7lGmz0FjnWdflJg4zii8Ivruas6PBKzw5SJX/q+Zh2RfnO+bBnuKLXpj8kiI2x2X12otpH6a32A==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [darwin] + + '@biomejs/cli-linux-arm64-musl@2.1.2': + resolution: {integrity: sha512-qgHvafhjH7Oca114FdOScmIKf1DlXT1LqbOrrbR30kQDLFPEOpBG0uzx6MhmsrmhGiCFCr2obDamu+czk+X0HQ==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-arm64@2.1.2': + resolution: {integrity: sha512-NWNy2Diocav61HZiv2enTQykbPP/KrA/baS7JsLSojC7Xxh2nl9IczuvE5UID7+ksRy2e7yH7klm/WkA72G1dw==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-x64-musl@2.1.2': + resolution: {integrity: sha512-xlB3mU14ZUa3wzLtXfmk2IMOGL+S0aHFhSix/nssWS/2XlD27q+S6f0dlQ8WOCbYoXcuz8BCM7rCn2lxdTrlQA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-linux-x64@2.1.2': + resolution: {integrity: sha512-Km/UYeVowygTjpX6sGBzlizjakLoMQkxWbruVZSNE6osuSI63i4uCeIL+6q2AJlD3dxoiBJX70dn1enjQnQqwA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-win32-arm64@2.1.2': + resolution: {integrity: sha512-G8KWZli5ASOXA3yUQgx+M4pZRv3ND16h77UsdunUL17uYpcL/UC7RkWTdkfvMQvogVsAuz5JUcBDjgZHXxlKoA==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [win32] + + '@biomejs/cli-win32-x64@2.1.2': + resolution: {integrity: sha512-9zajnk59PMpjBkty3bK2IrjUsUHvqe9HWwyAWQBjGLE7MIBjbX2vwv1XPEhmO2RRuGoTkVx3WCanHrjAytICLA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [win32] + '@emotion/is-prop-valid@0.8.8': resolution: {integrity: sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==} @@ -490,10 +513,6 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@pkgr/core@0.2.9': - resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - '@remix-run/router@1.23.0': resolution: {integrity: sha512-O3rHJzAQKamUz1fvE0Qaw0xSFqsA/yafi2iqeE0pvdFtCO1viYx8QL6f3Ln/aCCTLxs68SLf0KPM9eSeM8yBnA==} engines: {node: '>=14.0.0'} @@ -501,9 +520,6 @@ packages: '@rolldown/pluginutils@1.0.0-beta.27': resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} - '@rtsao/scc@1.1.0': - resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} - '@stablelib/base64@1.0.1': resolution: {integrity: sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ==} @@ -739,12 +755,6 @@ packages: '@types/hast@2.3.10': resolution: {integrity: sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==} - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - - '@types/json5@0.0.29': - resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} - '@types/lodash-es@4.17.12': resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} @@ -771,23 +781,9 @@ packages: '@types/react@18.3.23': resolution: {integrity: sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==} - '@types/semver@7.7.0': - resolution: {integrity: sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==} - '@types/unist@2.0.11': resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} - '@typescript-eslint/eslint-plugin@6.21.0': - resolution: {integrity: sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha - eslint: ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - '@typescript-eslint/parser@6.21.0': resolution: {integrity: sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==} engines: {node: ^16.0.0 || >=18.0.0} @@ -802,16 +798,6 @@ packages: resolution: {integrity: sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==} engines: {node: ^16.0.0 || >=18.0.0} - '@typescript-eslint/type-utils@6.21.0': - resolution: {integrity: sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - '@typescript-eslint/types@6.21.0': resolution: {integrity: sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==} engines: {node: ^16.0.0 || >=18.0.0} @@ -825,12 +811,6 @@ packages: typescript: optional: true - '@typescript-eslint/utils@6.21.0': - resolution: {integrity: sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 - '@typescript-eslint/visitor-keys@6.21.0': resolution: {integrity: sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==} engines: {node: ^16.0.0 || >=18.0.0} @@ -866,9 +846,6 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-sequence-parser@1.1.3: - resolution: {integrity: sha512-+fksAx9eG3Ab6LDnLs3ZqZa8KVJ/jYnX+D4Qe1azX+LFGFAXqynCQLOdLpNYN/l9e7l6hMWwZbrnctqr6eSQSw==} - ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} @@ -891,34 +868,10 @@ packages: resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} engines: {node: '>= 0.4'} - array-includes@3.1.9: - resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} - engines: {node: '>= 0.4'} - array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} - array.prototype.findlast@1.2.5: - resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} - engines: {node: '>= 0.4'} - - array.prototype.findlastindex@1.2.6: - resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} - engines: {node: '>= 0.4'} - - array.prototype.flat@1.3.3: - resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} - engines: {node: '>= 0.4'} - - array.prototype.flatmap@1.3.3: - resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} - engines: {node: '>= 0.4'} - - array.prototype.tosorted@1.1.4: - resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} - engines: {node: '>= 0.4'} - arraybuffer.prototype.slice@1.0.4: resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} engines: {node: '>= 0.4'} @@ -1113,14 +1066,6 @@ packages: dayjs@1.11.13: resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} - debug@3.2.7: - resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - debug@4.4.1: resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} engines: {node: '>=6.0'} @@ -1164,10 +1109,6 @@ packages: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} - doctrine@2.1.0: - resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} - engines: {node: '>=0.10.0'} - doctrine@3.0.0: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} @@ -1214,10 +1155,6 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} - es-iterator-helpers@1.2.1: - resolution: {integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==} - engines: {node: '>= 0.4'} - es-object-atoms@1.1.1: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} @@ -1226,10 +1163,6 @@ packages: resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} engines: {node: '>= 0.4'} - es-shim-unscopables@1.1.0: - resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} - engines: {node: '>= 0.4'} - es-to-primitive@1.3.0: resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} engines: {node: '>= 0.4'} @@ -1251,82 +1184,6 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} - eslint-config-prettier@8.10.2: - resolution: {integrity: sha512-/IGJ6+Dka158JnP5n5YFMOszjDWrXggGz1LaK/guZq9vZTmniaKlHcsscvkAhn9y4U+BU3JuUdYvtAMcv30y4A==} - hasBin: true - peerDependencies: - eslint: '>=7.0.0' - - eslint-import-resolver-node@0.3.9: - resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} - - eslint-module-utils@2.12.1: - resolution: {integrity: sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: '*' - eslint-import-resolver-node: '*' - eslint-import-resolver-typescript: '*' - eslint-import-resolver-webpack: '*' - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - eslint: - optional: true - eslint-import-resolver-node: - optional: true - eslint-import-resolver-typescript: - optional: true - eslint-import-resolver-webpack: - optional: true - - eslint-plugin-import@2.32.0: - resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - - eslint-plugin-prettier@5.5.3: - resolution: {integrity: sha512-NAdMYww51ehKfDyDhv59/eIItUVzU0Io9H2E8nHNGKEeeqlnci+1gCvrHib6EmZdf6GxF+LCV5K7UC65Ezvw7w==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - '@types/eslint': '>=8.0.0' - eslint: '>=8.0.0' - eslint-config-prettier: '>= 7.0.0 <10.0.0 || >=10.1.0' - prettier: '>=3.0.0' - peerDependenciesMeta: - '@types/eslint': - optional: true - eslint-config-prettier: - optional: true - - eslint-plugin-react-hooks@4.6.2: - resolution: {integrity: sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==} - engines: {node: '>=10'} - peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 - - eslint-plugin-react-refresh@0.4.20: - resolution: {integrity: sha512-XpbHQ2q5gUF8BGOX4dHe+71qoirYMhApEPZ7sfhF/dNnOF1UXnCMGZf79SFTBO7Bz5YEIT4TMieSlJBWhP9WBA==} - peerDependencies: - eslint: '>=8.40' - - eslint-plugin-react@7.37.5: - resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} - engines: {node: '>=4'} - peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 - - eslint-plugin-simple-import-sort@10.0.0: - resolution: {integrity: sha512-AeTvO9UCMSNzIHRkg8S6c3RPy5YEwKWSQPx3DYghLedo2ZQxowPFLGDN1AZ2evfg6r6mjBSZSLxLFsWSu3acsw==} - peerDependencies: - eslint: '>=5.0.0' - eslint-scope@7.2.2: resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1371,9 +1228,6 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - fast-diff@1.3.0: - resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} - fast-glob@3.3.3: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} @@ -1746,10 +1600,6 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - iterator.prototype@1.1.5: - resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} - engines: {node: '>= 0.4'} - js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -1777,22 +1627,11 @@ packages: json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - json5@1.0.2: - resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} - hasBin: true - json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} hasBin: true - jsonc-parser@3.3.1: - resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} - - jsx-ast-utils@3.3.5: - resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} - engines: {node: '>=4.0'} - keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -1831,14 +1670,6 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - lunr@2.3.9: - resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} - - marked@4.3.0: - resolution: {integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==} - engines: {node: '>= 12'} - hasBin: true - math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} @@ -1962,13 +1793,6 @@ packages: resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} engines: {node: '>=16 || 14 >=14.17'} - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} - engines: {node: '>=16 || 14 >=14.17'} - - minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} @@ -2032,22 +1856,6 @@ packages: resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} engines: {node: '>= 0.4'} - object.entries@1.1.9: - resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==} - engines: {node: '>= 0.4'} - - object.fromentries@2.0.8: - resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} - engines: {node: '>= 0.4'} - - object.groupby@1.0.3: - resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} - engines: {node: '>= 0.4'} - - object.values@1.2.1: - resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} - engines: {node: '>= 0.4'} - once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} @@ -2141,10 +1949,6 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - prettier-linter-helpers@1.0.0: - resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} - engines: {node: '>=6.0.0'} - prettier@2.8.8: resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} engines: {node: '>=10.13.0'} @@ -2269,10 +2073,6 @@ packages: engines: {node: '>= 0.4'} hasBin: true - resolve@2.0.0-next.5: - resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} - hasBin: true - reusify@1.1.0: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -2362,9 +2162,6 @@ packages: resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} engines: {node: '>= 0.4'} - shiki@0.14.7: - resolution: {integrity: sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg==} - side-channel-list@1.0.0: resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} engines: {node: '>= 0.4'} @@ -2414,17 +2211,10 @@ packages: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} - string.prototype.matchall@4.0.12: - resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} - engines: {node: '>= 0.4'} - string.prototype.padend@3.1.6: resolution: {integrity: sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==} engines: {node: '>= 0.4'} - string.prototype.repeat@1.0.0: - resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} - string.prototype.trim@1.2.10: resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} engines: {node: '>= 0.4'} @@ -2486,10 +2276,6 @@ packages: engines: {node: '>=14.0.0'} hasBin: true - synckit@0.11.11: - resolution: {integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==} - engines: {node: ^14.18.0 || >=16.0.0} - tabbable@6.2.0: resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} @@ -2512,9 +2298,6 @@ packages: peerDependencies: typescript: '>=4.2.0' - tsconfig-paths@3.15.0: - resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} - tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -2542,13 +2325,6 @@ packages: resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} engines: {node: '>= 0.4'} - typedoc@0.24.8: - resolution: {integrity: sha512-ahJ6Cpcvxwaxfu4KtjA8qZNqS43wYt6JL27wYiIgl1vd38WW/KWX11YuAeZhuz9v+ttrutSsgK+XO1CjL1kA3w==} - engines: {node: '>= 14.14'} - hasBin: true - peerDependencies: - typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x - typesafe-i18n@5.26.2: resolution: {integrity: sha512-2QAriFmiY5JwUAJtG7yufoE/XZ1aFBY++wj7YFS2yo89a3jLBfKoWSdq5JfQYk1V2BS7V2c/u+KEcaCQoE65hw==} hasBin: true @@ -2658,12 +2434,6 @@ packages: terser: optional: true - vscode-oniguruma@1.7.0: - resolution: {integrity: sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==} - - vscode-textmate@8.0.0: - resolution: {integrity: sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==} - which-boxed-primitive@1.1.1: resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} engines: {node: '>= 0.4'} @@ -2840,6 +2610,41 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 + '@biomejs/biome@2.1.2': + optionalDependencies: + '@biomejs/cli-darwin-arm64': 2.1.2 + '@biomejs/cli-darwin-x64': 2.1.2 + '@biomejs/cli-linux-arm64': 2.1.2 + '@biomejs/cli-linux-arm64-musl': 2.1.2 + '@biomejs/cli-linux-x64': 2.1.2 + '@biomejs/cli-linux-x64-musl': 2.1.2 + '@biomejs/cli-win32-arm64': 2.1.2 + '@biomejs/cli-win32-x64': 2.1.2 + + '@biomejs/cli-darwin-arm64@2.1.2': + optional: true + + '@biomejs/cli-darwin-x64@2.1.2': + optional: true + + '@biomejs/cli-linux-arm64-musl@2.1.2': + optional: true + + '@biomejs/cli-linux-arm64@2.1.2': + optional: true + + '@biomejs/cli-linux-x64-musl@2.1.2': + optional: true + + '@biomejs/cli-linux-x64@2.1.2': + optional: true + + '@biomejs/cli-win32-arm64@2.1.2': + optional: true + + '@biomejs/cli-win32-x64@2.1.2': + optional: true + '@emotion/is-prop-valid@0.8.8': dependencies: '@emotion/memoize': 0.7.4 @@ -3006,14 +2811,10 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 - '@pkgr/core@0.2.9': {} - '@remix-run/router@1.23.0': {} '@rolldown/pluginutils@1.0.0-beta.27': {} - '@rtsao/scc@1.1.0': {} - '@stablelib/base64@1.0.1': {} '@stablelib/binary@1.0.1': @@ -3250,10 +3051,6 @@ snapshots: dependencies: '@types/unist': 2.0.11 - '@types/json-schema@7.0.15': {} - - '@types/json5@0.0.29': {} - '@types/lodash-es@4.17.12': dependencies: '@types/lodash': 4.17.20 @@ -3281,30 +3078,8 @@ snapshots: '@types/prop-types': 15.7.15 csstype: 3.1.3 - '@types/semver@7.7.0': {} - '@types/unist@2.0.11': {} - '@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3)': - dependencies: - '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.8.3) - '@typescript-eslint/scope-manager': 6.21.0 - '@typescript-eslint/type-utils': 6.21.0(eslint@8.57.1)(typescript@5.8.3) - '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.1 - eslint: 8.57.1 - graphemer: 1.4.0 - ignore: 5.3.2 - natural-compare: 1.4.0 - semver: 7.7.2 - ts-api-utils: 1.4.3(typescript@5.8.3) - optionalDependencies: - typescript: 5.8.3 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3)': dependencies: '@typescript-eslint/scope-manager': 6.21.0 @@ -3323,18 +3098,6 @@ snapshots: '@typescript-eslint/types': 6.21.0 '@typescript-eslint/visitor-keys': 6.21.0 - '@typescript-eslint/type-utils@6.21.0(eslint@8.57.1)(typescript@5.8.3)': - dependencies: - '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.8.3) - '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.8.3) - debug: 4.4.1 - eslint: 8.57.1 - ts-api-utils: 1.4.3(typescript@5.8.3) - optionalDependencies: - typescript: 5.8.3 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/types@6.21.0': {} '@typescript-eslint/typescript-estree@6.21.0(typescript@5.8.3)': @@ -3352,20 +3115,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@6.21.0(eslint@8.57.1)(typescript@5.8.3)': - dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@8.57.1) - '@types/json-schema': 7.0.15 - '@types/semver': 7.7.0 - '@typescript-eslint/scope-manager': 6.21.0 - '@typescript-eslint/types': 6.21.0 - '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.8.3) - eslint: 8.57.1 - semver: 7.7.2 - transitivePeerDependencies: - - supports-color - - typescript - '@typescript-eslint/visitor-keys@6.21.0': dependencies: '@typescript-eslint/types': 6.21.0 @@ -3408,8 +3157,6 @@ snapshots: ansi-regex@5.0.1: {} - ansi-sequence-parser@1.1.3: {} - ansi-styles@3.2.1: dependencies: color-convert: 1.9.3 @@ -3432,60 +3179,8 @@ snapshots: call-bound: 1.0.4 is-array-buffer: 3.0.5 - array-includes@3.1.9: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - is-string: 1.1.1 - math-intrinsics: 1.1.0 - array-union@2.1.0: {} - array.prototype.findlast@1.2.5: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - es-shim-unscopables: 1.1.0 - - array.prototype.findlastindex@1.2.6: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - es-shim-unscopables: 1.1.0 - - array.prototype.flat@1.3.3: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-shim-unscopables: 1.1.0 - - array.prototype.flatmap@1.3.3: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-shim-unscopables: 1.1.0 - - array.prototype.tosorted@1.1.4: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-shim-unscopables: 1.1.0 - arraybuffer.prototype.slice@1.0.4: dependencies: array-buffer-byte-length: 1.0.2 @@ -3707,10 +3402,6 @@ snapshots: dayjs@1.11.13: {} - debug@3.2.7: - dependencies: - ms: 2.1.3 - debug@4.4.1: dependencies: ms: 2.1.3 @@ -3745,10 +3436,6 @@ snapshots: dependencies: path-type: 4.0.0 - doctrine@2.1.0: - dependencies: - esutils: 2.0.3 - doctrine@3.0.0: dependencies: esutils: 2.0.3 @@ -3851,25 +3538,6 @@ snapshots: es-errors@1.3.0: {} - es-iterator-helpers@1.2.1: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-set-tostringtag: 2.1.0 - function-bind: 1.1.2 - get-intrinsic: 1.3.0 - globalthis: 1.0.4 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - has-proto: 1.2.0 - has-symbols: 1.1.0 - internal-slot: 1.1.0 - iterator.prototype: 1.1.5 - safe-array-concat: 1.1.3 - es-object-atoms@1.1.1: dependencies: es-errors: 1.3.0 @@ -3881,10 +3549,6 @@ snapshots: has-tostringtag: 1.0.2 hasown: 2.0.2 - es-shim-unscopables@1.1.0: - dependencies: - hasown: 2.0.2 - es-to-primitive@1.3.0: dependencies: is-callable: 1.2.7 @@ -3922,100 +3586,6 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-prettier@8.10.2(eslint@8.57.1): - dependencies: - eslint: 8.57.1 - - eslint-import-resolver-node@0.3.9: - dependencies: - debug: 3.2.7 - is-core-module: 2.16.1 - resolve: 1.22.10 - transitivePeerDependencies: - - supports-color - - eslint-module-utils@2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1): - dependencies: - debug: 3.2.7 - optionalDependencies: - '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.8.3) - eslint: 8.57.1 - eslint-import-resolver-node: 0.3.9 - transitivePeerDependencies: - - supports-color - - eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1): - dependencies: - '@rtsao/scc': 1.1.0 - array-includes: 3.1.9 - array.prototype.findlastindex: 1.2.6 - array.prototype.flat: 1.3.3 - array.prototype.flatmap: 1.3.3 - debug: 3.2.7 - doctrine: 2.1.0 - eslint: 8.57.1 - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1) - hasown: 2.0.2 - is-core-module: 2.16.1 - is-glob: 4.0.3 - minimatch: 3.1.2 - object.fromentries: 2.0.8 - object.groupby: 1.0.3 - object.values: 1.2.1 - semver: 6.3.1 - string.prototype.trimend: 1.0.9 - tsconfig-paths: 3.15.0 - optionalDependencies: - '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.8.3) - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - - eslint-plugin-prettier@5.5.3(eslint-config-prettier@8.10.2(eslint@8.57.1))(eslint@8.57.1)(prettier@3.6.2): - dependencies: - eslint: 8.57.1 - prettier: 3.6.2 - prettier-linter-helpers: 1.0.0 - synckit: 0.11.11 - optionalDependencies: - eslint-config-prettier: 8.10.2(eslint@8.57.1) - - eslint-plugin-react-hooks@4.6.2(eslint@8.57.1): - dependencies: - eslint: 8.57.1 - - eslint-plugin-react-refresh@0.4.20(eslint@8.57.1): - dependencies: - eslint: 8.57.1 - - eslint-plugin-react@7.37.5(eslint@8.57.1): - dependencies: - array-includes: 3.1.9 - array.prototype.findlast: 1.2.5 - array.prototype.flatmap: 1.3.3 - array.prototype.tosorted: 1.1.4 - doctrine: 2.1.0 - es-iterator-helpers: 1.2.1 - eslint: 8.57.1 - estraverse: 5.3.0 - hasown: 2.0.2 - jsx-ast-utils: 3.3.5 - minimatch: 3.1.2 - object.entries: 1.1.9 - object.fromentries: 2.0.8 - object.values: 1.2.1 - prop-types: 15.8.1 - resolve: 2.0.0-next.5 - semver: 6.3.1 - string.prototype.matchall: 4.0.12 - string.prototype.repeat: 1.0.0 - - eslint-plugin-simple-import-sort@10.0.0(eslint@8.57.1): - dependencies: - eslint: 8.57.1 - eslint-scope@7.2.2: dependencies: esrecurse: 4.3.0 @@ -4100,8 +3670,6 @@ snapshots: fast-deep-equal@3.1.3: {} - fast-diff@1.3.0: {} - fast-glob@3.3.3: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -4475,15 +4043,6 @@ snapshots: isexe@2.0.0: {} - iterator.prototype@1.1.5: - dependencies: - define-data-property: 1.1.4 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - get-proto: 1.0.1 - has-symbols: 1.1.0 - set-function-name: 2.0.2 - js-tokens@4.0.0: {} js-yaml@4.1.0: @@ -4502,21 +4061,8 @@ snapshots: json-stable-stringify-without-jsonify@1.0.1: {} - json5@1.0.2: - dependencies: - minimist: 1.2.8 - json5@2.2.3: {} - jsonc-parser@3.3.1: {} - - jsx-ast-utils@3.3.5: - dependencies: - array-includes: 3.1.9 - array.prototype.flat: 1.3.3 - object.assign: 4.1.7 - object.values: 1.2.1 - keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -4557,10 +4103,6 @@ snapshots: dependencies: yallist: 3.1.1 - lunr@2.3.9: {} - - marked@4.3.0: {} - math-intrinsics@1.1.0: {} mdast-util-definitions@5.1.2: @@ -4769,12 +4311,6 @@ snapshots: dependencies: brace-expansion: 2.0.2 - minimatch@9.0.5: - dependencies: - brace-expansion: 2.0.2 - - minimist@1.2.8: {} - mri@1.2.0: {} ms@2.1.3: {} @@ -4838,33 +4374,6 @@ snapshots: has-symbols: 1.1.0 object-keys: 1.1.1 - object.entries@1.1.9: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - - object.fromentries@2.0.8: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-object-atoms: 1.1.1 - - object.groupby@1.0.3: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - - object.values@1.2.1: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - once@1.4.0: dependencies: wrappy: 1.0.2 @@ -4948,10 +4457,6 @@ snapshots: prelude-ls@1.2.1: {} - prettier-linter-helpers@1.0.0: - dependencies: - fast-diff: 1.3.0 - prettier@2.8.8: {} prettier@3.6.2: {} @@ -5100,12 +4605,6 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - resolve@2.0.0-next.5: - dependencies: - is-core-module: 2.16.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - reusify@1.1.0: {} rimraf@3.0.2: @@ -5199,13 +4698,6 @@ snapshots: shell-quote@1.8.3: {} - shiki@0.14.7: - dependencies: - ansi-sequence-parser: 1.1.3 - jsonc-parser: 3.3.1 - vscode-oniguruma: 1.7.0 - vscode-textmate: 8.0.0 - side-channel-list@1.0.0: dependencies: es-errors: 1.3.0 @@ -5266,22 +4758,6 @@ snapshots: es-errors: 1.3.0 internal-slot: 1.1.0 - string.prototype.matchall@4.0.12: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - gopd: 1.2.0 - has-symbols: 1.1.0 - internal-slot: 1.1.0 - regexp.prototype.flags: 1.5.4 - set-function-name: 2.0.2 - side-channel: 1.1.0 - string.prototype.padend@3.1.6: dependencies: call-bind: 1.0.8 @@ -5289,11 +4765,6 @@ snapshots: es-abstract: 1.24.0 es-object-atoms: 1.1.1 - string.prototype.repeat@1.0.0: - dependencies: - define-properties: 1.2.1 - es-abstract: 1.24.0 - string.prototype.trim@1.2.10: dependencies: call-bind: 1.0.8 @@ -5365,10 +4836,6 @@ snapshots: csso: 5.0.5 picocolors: 1.1.1 - synckit@0.11.11: - dependencies: - '@pkgr/core': 0.2.9 - tabbable@6.2.0: {} text-table@0.2.0: {} @@ -5385,13 +4852,6 @@ snapshots: dependencies: typescript: 5.8.3 - tsconfig-paths@3.15.0: - dependencies: - '@types/json5': 0.0.29 - json5: 1.0.2 - minimist: 1.2.8 - strip-bom: 3.0.0 - tslib@2.8.1: {} type-check@0.4.0: @@ -5433,14 +4893,6 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 - typedoc@0.24.8(typescript@5.8.3): - dependencies: - lunr: 2.3.9 - marked: 4.3.0 - minimatch: 9.0.5 - shiki: 0.14.7 - typescript: 5.8.3 - typesafe-i18n@5.26.2(typescript@5.8.3): dependencies: typescript: 5.8.3 @@ -5550,10 +5002,6 @@ snapshots: fsevents: 2.3.3 sass: 1.70.0 - vscode-oniguruma@1.7.0: {} - - vscode-textmate@8.0.0: {} - which-boxed-primitive@1.1.1: dependencies: is-bigint: 1.1.0 diff --git a/web/src/components/LogoContainer/style.scss b/web/src/components/LogoContainer/style.scss index 3f2ceb8..b0421db 100644 --- a/web/src/components/LogoContainer/style.scss +++ b/web/src/components/LogoContainer/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - .logo-container { display: flex; flex-flow: row; diff --git a/web/src/i18n/formatters.ts b/web/src/i18n/formatters.ts index 2fec895..10cd025 100644 --- a/web/src/i18n/formatters.ts +++ b/web/src/i18n/formatters.ts @@ -1,12 +1,13 @@ import type { FormattersInitializer } from 'typesafe-i18n'; -import type { Formatters,Locales } from './i18n-types'; +import type { Formatters, Locales } from './i18n-types'; -export const initFormatters: FormattersInitializer = (locale: Locales) => { +export const initFormatters: FormattersInitializer = ( + locale: Locales, +) => { + const formatters: Formatters = { + // add your formatter functions here + }; - const formatters: Formatters = { - // add your formatter functions here - }; - - return formatters; + return formatters; }; diff --git a/web/src/i18n/i18n-react.tsx b/web/src/i18n/i18n-react.tsx index f113051..4b7b868 100644 --- a/web/src/i18n/i18n-react.tsx +++ b/web/src/i18n/i18n-react.tsx @@ -1,16 +1,27 @@ // This file was auto-generated by 'typesafe-i18n'. Any manual changes will be overwritten. /* eslint-disable */ -import { useContext } from 'react' -import { initI18nReact } from 'typesafe-i18n/react' -import type { I18nContextType } from 'typesafe-i18n/react' -import type { Formatters, Locales, TranslationFunctions, Translations } from './i18n-types' -import { loadedFormatters, loadedLocales } from './i18n-util' +import { useContext } from 'react'; +import type { I18nContextType } from 'typesafe-i18n/react'; +import { initI18nReact } from 'typesafe-i18n/react'; +import type { + Formatters, + Locales, + TranslationFunctions, + Translations, +} from './i18n-types'; +import { loadedFormatters, loadedLocales } from './i18n-util'; -const { component: TypesafeI18n, context: I18nContext } = initI18nReact(loadedLocales, loadedFormatters) +const { component: TypesafeI18n, context: I18nContext } = initI18nReact< + Locales, + Translations, + TranslationFunctions, + Formatters +>(loadedLocales, loadedFormatters); -const useI18nContext = (): I18nContextType => useContext(I18nContext) +const useI18nContext = (): I18nContextType => + useContext(I18nContext); -export { I18nContext, useI18nContext } +export { I18nContext, useI18nContext }; -export default TypesafeI18n +export default TypesafeI18n; diff --git a/web/src/i18n/i18n-types.ts b/web/src/i18n/i18n-types.ts index fba01d2..d1f5126 100644 --- a/web/src/i18n/i18n-types.ts +++ b/web/src/i18n/i18n-types.ts @@ -1,172 +1,175 @@ // This file was auto-generated by 'typesafe-i18n'. Any manual changes will be overwritten. /* eslint-disable */ -import type { BaseTranslation as BaseTranslationType, LocalizedString, RequiredParams } from 'typesafe-i18n' +import type { + BaseTranslation as BaseTranslationType, + LocalizedString, + RequiredParams, +} from 'typesafe-i18n'; -export type BaseTranslation = BaseTranslationType -export type BaseLocale = 'en' +export type BaseTranslation = BaseTranslationType; +export type BaseLocale = 'en'; -export type Locales = - | 'en' +export type Locales = 'en'; -export type Translation = RootTranslation +export type Translation = RootTranslation; -export type Translations = RootTranslation +export type Translations = RootTranslation; type RootTranslation = { - time: { - seconds: { - /** - * s​e​c​o​n​d - */ - singular: string - /** - * s​e​c​o​n​d​s - */ - prular: string - } - minutes: { - /** - * m​i​n​u​t​e - */ - singular: string - /** - * m​i​n​u​t​e​s - */ - prular: string - } - } - form: { - errors: { - /** - * F​i​e​l​d​ ​i​s​ ​i​n​v​a​l​i​d - */ - invalid: string - /** - * E​n​t​e​r​ ​a​ ​v​a​l​i​d​ ​E​-​m​a​i​l - */ - email: string - /** - * F​i​e​l​d​ ​i​s​ ​r​e​q​u​i​r​e​d - */ - required: string - /** - * M​i​n​ ​l​e​n​g​t​h​ ​o​f​ ​{​l​e​n​g​t​h​} - * @param {number} length - */ - minLength: RequiredParams<'length'> - /** - * M​a​x​ ​l​e​n​g​t​h​ ​o​f​ ​{​l​e​n​g​t​h​} - * @param {number} length - */ - maxLength: RequiredParams<'length'> - /** - * A​t​ ​l​e​a​s​t​ ​o​n​e​ ​s​p​e​c​i​a​l​ ​c​h​a​r​a​c​t​e​r - */ - specialsRequired: string - /** - * S​p​e​c​i​a​l​ ​c​h​a​r​a​c​t​e​r​s​ ​a​r​e​ ​f​o​r​b​i​d​d​e​n - */ - specialsForbidden: string - /** - * A​t​ ​l​e​a​s​t​ ​o​n​e​ ​n​u​m​b​e​r​ ​r​e​q​u​i​r​e​d - */ - numberRequired: string - password: { - /** - * P​l​e​a​s​e​ ​c​o​r​r​e​c​t​ ​t​h​e​ ​f​o​l​l​o​w​i​n​g​: - */ - floatingTitle: string - } - /** - * A​t​ ​l​e​a​s​t​ ​o​n​e​ ​l​o​w​e​r​ ​c​a​s​e​ ​c​h​a​r​a​c​t​e​r - */ - oneLower: string - /** - * A​t​ ​l​e​a​s​t​ ​o​n​e​ ​u​p​p​e​r​ ​c​a​s​e​ ​c​h​a​r​a​c​t​e​r - */ - oneUpper: string - } - } - common: { - controls: { - /** - * B​a​c​k - */ - back: string - /** - * N​e​x​t - */ - next: string - /** - * S​u​b​m​i​t - */ - submit: string - } - } - components: { - adminInfo: { - /** - * Y​o​u​r​ ​a​d​m​i​n - */ - title: string - } - } - pages: { - enrollment: { - sideBar: { - /** - * E​n​r​o​l​l​m​e​n​t - */ - title: string - steps: { - /** - * W​e​l​c​o​m​e - */ - welcome: string - /** - * D​a​t​a​ ​v​e​r​i​f​i​c​a​t​i​o​n - */ - verification: string - /** - * C​r​e​a​t​e​ ​p​a​s​s​w​o​r​d - */ - password: string - /** - * C​o​n​f​i​g​u​r​e​ ​V​P​N - */ - vpn: string - /** - * F​i​n​i​s​h - */ - finish: string - } - /** - * A​p​p​l​i​c​a​t​i​o​n​ ​v​e​r​s​i​o​n - */ - appVersion: string - } - stepsIndicator: { - /** - * S​t​e​p - */ - step: string - /** - * o​f - */ - of: string - } - /** - * T​i​m​e​ ​l​e​f​t - */ - timeLeft: string - steps: { - welcome: { - /** - * H​e​l​l​o​,​ ​{​n​a​m​e​} - * @param {string} name - */ - title: RequiredParams<'name'> - /** + time: { + seconds: { + /** + * s​e​c​o​n​d + */ + singular: string; + /** + * s​e​c​o​n​d​s + */ + prular: string; + }; + minutes: { + /** + * m​i​n​u​t​e + */ + singular: string; + /** + * m​i​n​u​t​e​s + */ + prular: string; + }; + }; + form: { + errors: { + /** + * F​i​e​l​d​ ​i​s​ ​i​n​v​a​l​i​d + */ + invalid: string; + /** + * E​n​t​e​r​ ​a​ ​v​a​l​i​d​ ​E​-​m​a​i​l + */ + email: string; + /** + * F​i​e​l​d​ ​i​s​ ​r​e​q​u​i​r​e​d + */ + required: string; + /** + * M​i​n​ ​l​e​n​g​t​h​ ​o​f​ ​{​l​e​n​g​t​h​} + * @param {number} length + */ + minLength: RequiredParams<'length'>; + /** + * M​a​x​ ​l​e​n​g​t​h​ ​o​f​ ​{​l​e​n​g​t​h​} + * @param {number} length + */ + maxLength: RequiredParams<'length'>; + /** + * A​t​ ​l​e​a​s​t​ ​o​n​e​ ​s​p​e​c​i​a​l​ ​c​h​a​r​a​c​t​e​r + */ + specialsRequired: string; + /** + * S​p​e​c​i​a​l​ ​c​h​a​r​a​c​t​e​r​s​ ​a​r​e​ ​f​o​r​b​i​d​d​e​n + */ + specialsForbidden: string; + /** + * A​t​ ​l​e​a​s​t​ ​o​n​e​ ​n​u​m​b​e​r​ ​r​e​q​u​i​r​e​d + */ + numberRequired: string; + password: { + /** + * P​l​e​a​s​e​ ​c​o​r​r​e​c​t​ ​t​h​e​ ​f​o​l​l​o​w​i​n​g​: + */ + floatingTitle: string; + }; + /** + * A​t​ ​l​e​a​s​t​ ​o​n​e​ ​l​o​w​e​r​ ​c​a​s​e​ ​c​h​a​r​a​c​t​e​r + */ + oneLower: string; + /** + * A​t​ ​l​e​a​s​t​ ​o​n​e​ ​u​p​p​e​r​ ​c​a​s​e​ ​c​h​a​r​a​c​t​e​r + */ + oneUpper: string; + }; + }; + common: { + controls: { + /** + * B​a​c​k + */ + back: string; + /** + * N​e​x​t + */ + next: string; + /** + * S​u​b​m​i​t + */ + submit: string; + }; + }; + components: { + adminInfo: { + /** + * Y​o​u​r​ ​a​d​m​i​n + */ + title: string; + }; + }; + pages: { + enrollment: { + sideBar: { + /** + * E​n​r​o​l​l​m​e​n​t + */ + title: string; + steps: { + /** + * W​e​l​c​o​m​e + */ + welcome: string; + /** + * D​a​t​a​ ​v​e​r​i​f​i​c​a​t​i​o​n + */ + verification: string; + /** + * C​r​e​a​t​e​ ​p​a​s​s​w​o​r​d + */ + password: string; + /** + * C​o​n​f​i​g​u​r​e​ ​V​P​N + */ + vpn: string; + /** + * F​i​n​i​s​h + */ + finish: string; + }; + /** + * A​p​p​l​i​c​a​t​i​o​n​ ​v​e​r​s​i​o​n + */ + appVersion: string; + }; + stepsIndicator: { + /** + * S​t​e​p + */ + step: string; + /** + * o​f + */ + of: string; + }; + /** + * T​i​m​e​ ​l​e​f​t + */ + timeLeft: string; + steps: { + welcome: { + /** + * H​e​l​l​o​,​ ​{​n​a​m​e​} + * @param {string} name + */ + title: RequiredParams<'name'>; + /** * ​I​n​ ​o​r​d​e​r​ ​t​o​ ​g​a​i​n​ ​a​c​c​e​s​s​ ​t​o​ ​t​h​e​ ​c​o​m​p​a​n​y​ ​i​n​f​r​a​s​t​r​u​c​t​u​r​e​,​ ​w​e​ ​r​e​q​u​i​r​e​ ​y​o​u​ ​t​o​ ​c​o​m​p​l​e​t​e​ ​t​h​i​s​ ​e​n​r​o​l​l​m​e​n​t​ ​p​r​o​c​e​s​s​.​ ​D​u​r​i​n​g​ ​t​h​i​s​ ​p​r​o​c​e​s​s​,​ ​y​o​u​ ​w​i​l​l​ ​n​e​e​d​ ​t​o​:​ ​ @@ -178,124 +181,124 @@ type RootTranslation = { ​I​f​ ​y​o​u​ ​h​a​v​e​ ​a​n​y​ ​q​u​e​s​t​i​o​n​s​,​ ​p​l​e​a​s​e​ ​c​o​n​s​u​l​t​ ​y​o​u​r​ ​a​s​s​i​g​n​e​d​ ​a​d​m​i​n​.​A​l​l​ ​n​e​c​e​s​s​a​r​y​ ​i​n​f​o​r​m​a​t​i​o​n​ ​c​a​n​ ​b​e​ ​f​o​u​n​d​ ​a​t​ ​t​h​e​ ​b​o​t​t​o​m​ ​o​f​ ​t​h​e​ ​s​i​d​e​b​a​r​. * @param {string} time */ - explanation: RequiredParams<'time'> - } - dataVerification: { - /** - * D​a​t​a​ ​v​e​r​i​f​i​c​a​t​i​o​n - */ - title: string - /** - * P​l​e​a​s​e​,​ ​c​h​e​c​k​ ​y​o​u​r​ ​d​a​t​a​.​ ​I​f​ ​a​n​y​t​h​i​n​g​ ​i​s​ ​w​r​o​n​g​,​ ​n​o​t​i​f​y​ ​y​o​u​r​ ​a​d​m​i​n​ ​a​f​t​e​r​ ​y​o​u​ ​c​o​m​p​l​e​t​e​ ​t​h​e​ ​p​r​o​c​e​s​s​. - */ - messageBox: string - form: { - fields: { - firstName: { - /** - * N​a​m​e - */ - label: string - } - lastName: { - /** - * L​a​s​t​ ​n​a​m​e - */ - label: string - } - email: { - /** - * E​-​m​a​i​l - */ - label: string - } - phone: { - /** - * P​h​o​n​e​ ​n​u​m​b​e​r - */ - label: string - } - } - } - } - password: { - /** - * C​r​e​a​t​e​ ​p​a​s​s​w​o​r​d - */ - title: string - form: { - fields: { - password: { - /** - * C​r​e​a​t​e​ ​n​e​w​ ​p​a​s​s​w​o​r​d - */ - label: string - } - repeat: { - /** - * C​o​n​f​i​r​m​ ​n​e​w​ ​p​a​s​s​w​o​r​d - */ - label: string - errors: { - /** - * P​a​s​s​w​o​r​d​s​ ​a​r​e​n​'​t​ ​m​a​t​c​h​i​n​g - */ - matching: string - } - } - } - } - } - deviceSetup: { - /** - * *​ ​T​h​i​s​ ​s​t​e​p​ ​i​s​ ​O​P​T​I​O​N​A​L​.​ ​Y​o​u​ ​c​a​n​ ​s​k​i​p​ ​i​t​ ​i​f​ ​y​o​u​ ​w​i​s​h​.​ ​T​h​i​s​ ​c​a​n​ ​b​e​ ​c​o​n​f​i​g​u​r​e​d​ ​l​a​t​e​r​ ​i​n​ ​d​e​f​g​u​a​r​d​. - */ - optionalMessage: string - cards: { - device: { - /** - * C​o​n​f​i​g​u​r​e​ ​y​o​u​r​ ​d​e​v​i​c​e​ ​f​o​r​ ​V​P​N - */ - title: string - create: { - /** - * C​r​e​a​t​e​ ​C​o​n​f​i​g​u​r​a​t​i​o​n - */ - submit: string - /** - * P​l​e​a​s​e​ ​b​e​ ​a​d​v​i​s​e​d​ ​t​h​a​t​ ​y​o​u​ ​h​a​v​e​ ​t​o​ ​d​o​w​n​l​o​a​d​ ​t​h​e​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​ ​n​o​w​,​ ​s​i​n​c​e​ ​w​e​ ​d​o​ ​n​o​t​ ​s​t​o​r​e​ ​y​o​u​r​ ​p​r​i​v​a​t​e​ ​k​e​y​.​ ​A​f​t​e​r​ ​t​h​i​s​ ​d​i​a​l​o​g​ ​i​s​ ​c​l​o​s​e​d​,​ ​y​o​u​ ​w​i​l​l​ ​n​o​t​ ​b​e​ ​a​b​l​e​ ​t​o​ ​g​e​t​ ​y​o​u​r​ ​f​u​l​l​l​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​ ​f​i​l​e​ ​(​w​i​t​h​ ​p​r​i​v​a​t​e​ ​k​e​y​s​,​ ​o​n​l​y​ ​b​l​a​n​k​ ​t​e​m​p​l​a​t​e​)​. - */ - messageBox: string - form: { - fields: { - name: { - /** - * D​e​v​i​c​e​ ​N​a​m​e - */ - label: string - } - 'public': { - /** - * M​y​ ​P​u​b​l​i​c​ ​K​e​y - */ - label: string - } - toggle: { - /** - * G​e​n​e​r​a​t​e​ ​k​e​y​ ​p​a​i​r - */ - generate: string - /** - * U​s​e​ ​m​y​ ​o​w​n​ ​p​u​b​l​i​c​ ​k​e​y - */ - own: string - } - } - } - } - config: { - messageBox: { - /** + explanation: RequiredParams<'time'>; + }; + dataVerification: { + /** + * D​a​t​a​ ​v​e​r​i​f​i​c​a​t​i​o​n + */ + title: string; + /** + * P​l​e​a​s​e​,​ ​c​h​e​c​k​ ​y​o​u​r​ ​d​a​t​a​.​ ​I​f​ ​a​n​y​t​h​i​n​g​ ​i​s​ ​w​r​o​n​g​,​ ​n​o​t​i​f​y​ ​y​o​u​r​ ​a​d​m​i​n​ ​a​f​t​e​r​ ​y​o​u​ ​c​o​m​p​l​e​t​e​ ​t​h​e​ ​p​r​o​c​e​s​s​. + */ + messageBox: string; + form: { + fields: { + firstName: { + /** + * N​a​m​e + */ + label: string; + }; + lastName: { + /** + * L​a​s​t​ ​n​a​m​e + */ + label: string; + }; + email: { + /** + * E​-​m​a​i​l + */ + label: string; + }; + phone: { + /** + * P​h​o​n​e​ ​n​u​m​b​e​r + */ + label: string; + }; + }; + }; + }; + password: { + /** + * C​r​e​a​t​e​ ​p​a​s​s​w​o​r​d + */ + title: string; + form: { + fields: { + password: { + /** + * C​r​e​a​t​e​ ​n​e​w​ ​p​a​s​s​w​o​r​d + */ + label: string; + }; + repeat: { + /** + * C​o​n​f​i​r​m​ ​n​e​w​ ​p​a​s​s​w​o​r​d + */ + label: string; + errors: { + /** + * P​a​s​s​w​o​r​d​s​ ​a​r​e​n​'​t​ ​m​a​t​c​h​i​n​g + */ + matching: string; + }; + }; + }; + }; + }; + deviceSetup: { + /** + * *​ ​T​h​i​s​ ​s​t​e​p​ ​i​s​ ​O​P​T​I​O​N​A​L​.​ ​Y​o​u​ ​c​a​n​ ​s​k​i​p​ ​i​t​ ​i​f​ ​y​o​u​ ​w​i​s​h​.​ ​T​h​i​s​ ​c​a​n​ ​b​e​ ​c​o​n​f​i​g​u​r​e​d​ ​l​a​t​e​r​ ​i​n​ ​d​e​f​g​u​a​r​d​. + */ + optionalMessage: string; + cards: { + device: { + /** + * C​o​n​f​i​g​u​r​e​ ​y​o​u​r​ ​d​e​v​i​c​e​ ​f​o​r​ ​V​P​N + */ + title: string; + create: { + /** + * C​r​e​a​t​e​ ​C​o​n​f​i​g​u​r​a​t​i​o​n + */ + submit: string; + /** + * P​l​e​a​s​e​ ​b​e​ ​a​d​v​i​s​e​d​ ​t​h​a​t​ ​y​o​u​ ​h​a​v​e​ ​t​o​ ​d​o​w​n​l​o​a​d​ ​t​h​e​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​ ​n​o​w​,​ ​s​i​n​c​e​ ​w​e​ ​d​o​ ​n​o​t​ ​s​t​o​r​e​ ​y​o​u​r​ ​p​r​i​v​a​t​e​ ​k​e​y​.​ ​A​f​t​e​r​ ​t​h​i​s​ ​d​i​a​l​o​g​ ​i​s​ ​c​l​o​s​e​d​,​ ​y​o​u​ ​w​i​l​l​ ​n​o​t​ ​b​e​ ​a​b​l​e​ ​t​o​ ​g​e​t​ ​y​o​u​r​ ​f​u​l​l​l​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​ ​f​i​l​e​ ​(​w​i​t​h​ ​p​r​i​v​a​t​e​ ​k​e​y​s​,​ ​o​n​l​y​ ​b​l​a​n​k​ ​t​e​m​p​l​a​t​e​)​. + */ + messageBox: string; + form: { + fields: { + name: { + /** + * D​e​v​i​c​e​ ​N​a​m​e + */ + label: string; + }; + public: { + /** + * M​y​ ​P​u​b​l​i​c​ ​K​e​y + */ + label: string; + }; + toggle: { + /** + * G​e​n​e​r​a​t​e​ ​k​e​y​ ​p​a​i​r + */ + generate: string; + /** + * U​s​e​ ​m​y​ ​o​w​n​ ​p​u​b​l​i​c​ ​k​e​y + */ + own: string; + }; + }; + }; + }; + config: { + messageBox: { + /** * ​ ​ ​ ​ ​ ​ ​ ​<​p​>​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​P​l​e​a​s​e​ ​b​e​ ​a​d​v​i​s​e​d​ ​t​h​a​t​ ​y​o​u​ ​h​a​v​e​ ​t​o​ ​d​o​w​n​l​o​a​d​ ​t​h​e​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​ ​n​o​w​,​ @@ -305,306 +308,306 @@ type RootTranslation = { ​ ​ ​ ​ ​ ​ ​ ​ ​<​/​p​>​ */ - auto: string - /** + auto: string; + /** * ​ ​ ​ ​ ​ ​ ​ ​ ​<​p​>​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​P​l​e​a​s​e​ ​b​e​ ​a​d​v​i​s​e​d​ ​t​h​a​t​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​ ​p​r​o​v​i​d​e​d​ ​h​e​r​e​ ​<​s​t​r​o​n​g​>​ ​d​o​e​s​ ​n​o​t​ ​i​n​c​l​u​d​e​ ​p​r​i​v​a​t​e​ ​k​e​y​ ​a​n​d​ ​u​s​e​s​ ​p​u​b​l​i​c​ ​k​e​y​ ​t​o​ ​f​i​l​l​ ​i​t​'​s​ ​p​l​a​c​e​ ​<​/​s​t​r​o​n​g​>​ ​y​o​u​ ​w​i​l​l​ ​n​e​e​d​ ​t​o​ ​r​e​p​a​l​c​e​ ​i​t​ ​o​n​ ​y​o​u​r​ ​o​w​n​ ​f​o​r​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​ ​t​o​ ​w​o​r​k​ ​p​r​o​p​e​r​l​y​.​ ​ ​ ​ ​ ​ ​ ​ ​ ​<​/​p​>​ */ - manual: string - } - /** - * M​y​ ​D​e​v​i​c​e​ ​N​a​m​e - */ - deviceNameLabel: string - /** - * Y​o​u​ ​d​o​n​'​t​ ​h​a​v​e​ ​a​c​c​e​s​s​ ​t​o​ ​a​n​y​ ​n​e​t​w​o​r​k​s - */ - noNetworksMessage: string - /** - * U​s​e​ ​p​r​o​v​i​d​e​d​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​ ​f​i​l​e​ ​b​e​l​o​w​ ​b​y​ ​s​c​a​n​n​i​n​g​ ​Q​R​ ​C​o​d​e​ ​o​r​ ​i​m​p​o​r​t​i​n​g​ ​i​t​ ​a​s​ ​f​i​l​e​ ​o​n​ ​y​o​u​r​ ​d​e​v​i​c​e​s​ ​W​i​r​e​G​u​a​r​d​ ​a​p​p​. - */ - cardTitle: string - card: { - /** - * C​o​n​f​i​g​ ​f​i​l​e​ ​f​o​r​ ​l​o​c​a​t​i​o​n - */ - selectLabel: string - } - } - } - guide: { - /** - * Q​u​i​c​k​ ​G​u​i​d​e - */ - title: string - /** - * T​h​i​s​ ​q​u​i​c​k​ ​g​u​i​d​e​ ​w​i​l​l​ ​h​e​l​p​ ​y​o​u​ ​w​i​t​h​ ​d​e​v​i​c​e​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​. - */ - messageBox: string - /** - * S​t​e​p​ ​{​s​t​e​p​}​: - * @param {number} step - */ - step: RequiredParams<'step'> - steps: { - wireguard: { - /** - * D​o​w​n​l​o​a​d​ ​a​n​d​ ​i​n​s​t​a​l​l​ ​W​i​r​e​G​u​a​r​d​ ​c​l​i​e​n​t​ ​o​n​ ​y​o​u​r​ ​c​o​m​p​p​u​t​e​r​ ​o​r​ ​a​p​p​ ​o​n​ ​p​h​o​n​e​. - */ - content: string - /** - * D​o​w​n​l​o​a​d​ ​W​i​r​e​G​u​a​r​d - */ - button: string - } - /** - * D​o​w​n​l​o​a​d​ ​p​r​o​v​i​d​e​d​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​ ​f​i​l​e​ ​t​o​ ​y​o​u​r​ ​d​e​v​i​c​e​. - */ - downloadConfig: string - /** + manual: string; + }; + /** + * M​y​ ​D​e​v​i​c​e​ ​N​a​m​e + */ + deviceNameLabel: string; + /** + * Y​o​u​ ​d​o​n​'​t​ ​h​a​v​e​ ​a​c​c​e​s​s​ ​t​o​ ​a​n​y​ ​n​e​t​w​o​r​k​s + */ + noNetworksMessage: string; + /** + * U​s​e​ ​p​r​o​v​i​d​e​d​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​ ​f​i​l​e​ ​b​e​l​o​w​ ​b​y​ ​s​c​a​n​n​i​n​g​ ​Q​R​ ​C​o​d​e​ ​o​r​ ​i​m​p​o​r​t​i​n​g​ ​i​t​ ​a​s​ ​f​i​l​e​ ​o​n​ ​y​o​u​r​ ​d​e​v​i​c​e​s​ ​W​i​r​e​G​u​a​r​d​ ​a​p​p​. + */ + cardTitle: string; + card: { + /** + * C​o​n​f​i​g​ ​f​i​l​e​ ​f​o​r​ ​l​o​c​a​t​i​o​n + */ + selectLabel: string; + }; + }; + }; + guide: { + /** + * Q​u​i​c​k​ ​G​u​i​d​e + */ + title: string; + /** + * T​h​i​s​ ​q​u​i​c​k​ ​g​u​i​d​e​ ​w​i​l​l​ ​h​e​l​p​ ​y​o​u​ ​w​i​t​h​ ​d​e​v​i​c​e​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​. + */ + messageBox: string; + /** + * S​t​e​p​ ​{​s​t​e​p​}​: + * @param {number} step + */ + step: RequiredParams<'step'>; + steps: { + wireguard: { + /** + * D​o​w​n​l​o​a​d​ ​a​n​d​ ​i​n​s​t​a​l​l​ ​W​i​r​e​G​u​a​r​d​ ​c​l​i​e​n​t​ ​o​n​ ​y​o​u​r​ ​c​o​m​p​p​u​t​e​r​ ​o​r​ ​a​p​p​ ​o​n​ ​p​h​o​n​e​. + */ + content: string; + /** + * D​o​w​n​l​o​a​d​ ​W​i​r​e​G​u​a​r​d + */ + button: string; + }; + /** + * D​o​w​n​l​o​a​d​ ​p​r​o​v​i​d​e​d​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​ ​f​i​l​e​ ​t​o​ ​y​o​u​r​ ​d​e​v​i​c​e​. + */ + downloadConfig: string; + /** * O​p​e​n​ ​W​i​r​e​G​u​a​r​d​ ​a​n​d​ ​s​e​l​e​c​t​ ​"​A​d​d​ ​T​u​n​n​e​l​"​ ​(​I​m​p​o​r​t​ ​t​u​n​n​e​l​(​s​)​ ​f​r​o​m​ ​f​i​l​e​)​.​ ​F​i​n​d​ ​y​o​u​r​ ​D​e​f​g​u​a​r​d​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​ ​f​i​l​e​ ​a​n​d​ ​h​i​t​ ​"​O​K​"​.​ ​O​n​ ​p​h​o​n​e​ ​u​s​e​ ​W​i​r​e​G​u​a​r​d​ ​a​p​p​ ​“​+​”​ ​i​c​o​n​ ​a​n​d​ ​s​c​a​n​ ​Q​R​ ​c​o​d​e​. */ - addTunnel: string - /** - * S​e​l​e​c​t​ ​y​o​u​r​ ​t​u​n​n​e​l​ ​f​r​o​m​ ​t​h​e​ ​l​i​s​t​ ​a​n​d​ ​p​r​e​s​s​ ​"​a​c​t​i​v​a​t​e​"​. - */ - activate: string - /** + addTunnel: string; + /** + * S​e​l​e​c​t​ ​y​o​u​r​ ​t​u​n​n​e​l​ ​f​r​o​m​ ​t​h​e​ ​l​i​s​t​ ​a​n​d​ ​p​r​e​s​s​ ​"​a​c​t​i​v​a​t​e​"​. + */ + activate: string; + /** * ​*​*​G​r​e​a​t​ ​w​o​r​k​ ​-​ ​y​o​u​r​ ​D​e​f​g​u​a​r​d​ ​V​P​N​ ​i​s​ ​n​o​w​ ​a​c​t​i​v​e​!​*​*​ ​ ​I​f​ ​y​o​u​ ​w​a​n​t​ ​t​o​ ​d​i​s​e​n​g​a​g​e​ ​y​o​u​r​ ​V​P​N​ ​c​o​n​n​e​c​t​i​o​n​,​ ​s​i​m​p​l​y​ ​p​r​e​s​s​ ​"​d​e​a​c​t​i​v​a​t​e​"​.​ */ - finish: string - } - } - } - } - finish: { - /** - * C​o​n​f​i​g​u​r​a​t​i​o​n​ ​c​o​m​p​l​e​t​e​d​! - */ - title: string - } - } - } - resetPassword: { - steps: { - email: { - controls: { - /** - * S​e​n​d - */ - send: string - } - /** - * E​n​t​e​r​ ​y​o​u​r​ ​e​-​m​a​i​l - */ - title: string - form: { - fields: { - email: { - /** - * E​-​m​a​i​l - */ - label: string - } - } - } - } - linkSent: { - controls: { - /** - * B​a​c​k​ ​t​o​ ​m​a​i​n​ ​m​e​n​u - */ - back: string - } - /** - * I​f​ ​t​h​e​ ​p​r​o​v​i​d​e​d​ ​e​m​a​i​l​ ​a​d​d​r​e​s​s​ ​i​s​ ​a​s​s​i​g​n​e​d​ ​t​o​ ​a​n​y​ ​a​c​c​o​u​n​t​ ​-​ ​t​h​e​ ​p​a​s​s​w​o​r​d​ ​r​e​s​e​t​ ​w​i​l​l​ ​b​e​ ​i​n​i​t​i​a​t​e​d​ ​a​n​d​ ​y​o​u​ ​w​i​l​l​ ​r​e​c​i​e​v​e​ ​a​n​ ​e​m​a​i​l​ ​w​i​t​h​ ​f​u​r​t​h​e​r​ ​i​s​t​r​u​c​t​i​o​n​s​. - */ - messageBox: string - } - securityCode: { - controls: { - /** - * S​e​n​d​ ​c​o​d​e - */ - sendCode: string - } - /** - * E​n​t​e​r​ ​s​e​c​u​r​i​t​y​ ​c​o​d​e - */ - title: string - /** - * I​n​ ​o​r​d​e​r​ ​t​o​ ​r​e​s​e​t​ ​t​h​e​ ​p​a​s​s​w​o​r​d​,​ ​p​l​e​a​s​e​ ​p​r​o​v​i​d​e​ ​s​e​c​u​r​i​t​y​ ​c​o​d​e​ ​t​h​a​t​ ​w​i​l​l​ ​b​e​ ​s​e​n​t​ ​t​o​ ​y​o​u​r​ ​n​u​m​b​e​r​: - */ - messagebox: string - form: { - fields: { - code: { - /** - * S​e​c​u​r​i​t​y​ ​c​o​d​e - */ - label: string - } - } - } - } - resetPassword: { - /** - * R​e​s​e​t​ ​y​o​u​r​ ​p​a​s​s​w​o​r​d - */ - title: string - controls: { - /** - * R​e​s​e​t​ ​p​a​s​s​w​o​r​d - */ - submit: string - } - form: { - errors: { - /** - * F​i​e​l​d​s​ ​d​o​e​s​n​'​t​ ​m​a​t​c​h - */ - repeat: string - } - fields: { - password: { - /** - * N​e​w​ ​p​a​s​s​w​o​r​d - */ - label: string - } - repeat: { - /** - * C​o​n​f​i​r​m​ ​p​a​s​s​w​o​r​d - */ - label: string - } - } - } - } - resetSuccess: { - controls: { - /** - * R​e​t​u​r​n​ ​t​o​ ​s​e​r​v​i​c​e​s​ ​m​e​n​u - */ - back: string - } - /** - * C​o​n​g​r​a​t​u​l​a​t​i​o​n​s​,​ ​y​o​u​r​ ​n​e​w​ ​p​a​s​s​w​o​r​d​ ​i​s​ ​s​e​t​. - */ - messageBox: string - } - resetFailed: { - controls: { - /** - * R​e​t​u​r​n​ ​t​o​ ​s​t​a​r​t - */ - back: string - } - /** - * T​h​e​ ​e​n​t​e​r​e​d​ ​c​o​d​e​ ​i​s​ ​i​n​v​a​l​i​d​.​ ​P​l​e​a​s​e​ ​s​t​a​r​t​ ​t​h​e​ ​p​r​o​c​e​s​s​ ​f​r​o​m​ ​t​h​e​ ​b​e​g​i​n​n​i​n​g​. - */ - messageBox: string - } - } - } - sessionTimeout: { - card: { - /** - * S​e​s​s​i​o​n​ ​t​i​m​e​d​ ​o​u​t - */ - header: string - /** - * S​o​r​r​y​,​ ​y​o​u​ ​h​a​v​e​ ​e​x​c​e​e​d​e​d​ ​t​h​e​ ​t​i​m​e​ ​l​i​m​i​t​ ​t​o​ ​c​o​m​p​l​e​t​e​ ​t​h​e​ ​p​r​o​c​e​s​s​.​ ​P​l​e​a​s​e​ ​t​r​y​ ​a​g​a​i​n​.​ ​I​f​ ​y​o​u​ ​n​e​e​d​ ​a​s​s​i​s​t​a​n​c​e​,​ ​p​l​e​a​s​e​ ​w​a​t​c​h​ ​o​u​r​ ​g​u​i​d​e​ ​o​r​ ​c​o​n​t​a​c​t​ ​y​o​u​r​ ​a​d​m​i​n​i​s​t​r​a​t​o​r​. - */ - message: string - } - controls: { - /** - * E​n​t​e​r​ ​n​e​w​ ​t​o​k​e​n - */ - back: string - /** - * C​o​n​t​a​c​t​ ​a​d​m​i​n - */ - contact: string - } - } - token: { - card: { - /** - * P​l​e​a​s​e​,​ ​e​n​t​e​r​ ​y​o​u​r​ ​p​e​r​s​o​n​a​l​ ​e​n​r​o​l​l​m​e​n​t​ ​t​o​k​e​n - */ - title: string - messageBox: { - /** - * Y​o​u​ ​c​a​n​ ​f​i​n​d​ ​t​o​k​e​n​ ​i​n​ ​e​-​m​a​i​l​ ​m​e​s​s​a​g​e​ ​o​r​ ​u​s​e​ ​d​i​r​e​c​t​ ​l​i​n​k​. - */ - email: string - } - form: { - errors: { - token: { - /** - * T​o​k​e​n​ ​i​s​ ​r​e​q​u​i​r​e​d - */ - required: string - } - } - fields: { - token: { - /** - * T​o​k​e​n - */ - placeholder: string - } - } - controls: { - /** - * N​e​x​t - */ - submit: string - } - } - oidc: { - /** - * S​i​g​n​ ​i​n​ ​w​i​t​h - */ - oidcButton: string - /** - * O​r​ ​S​i​g​n​ ​I​n​ ​w​i​t​h​ ​E​x​t​e​r​n​a​l​ ​S​S​O - */ - title: string - /** - * I​f​ ​y​o​u​ ​w​o​u​l​d​ ​l​i​k​e​ ​t​o​ ​i​n​i​t​i​a​t​e​ ​t​h​e​ ​e​n​r​o​l​l​m​e​n​t​ ​p​r​o​c​e​s​s​ ​u​s​i​n​g​ ​E​x​t​e​r​n​a​l​ ​S​S​O​,​ ​p​l​e​a​s​e​ ​c​l​i​c​k​ ​t​h​e​ ​l​i​n​k​ ​b​e​l​o​w​ ​t​o​ ​s​i​g​n​ ​i​n​ ​a​n​d​ ​s​t​a​r​t​ ​t​h​e​ ​p​r​o​c​e​s​s​. - */ - infoBox: string - } - } - } - oidcLogin: { - card: { - /** - * S​t​a​r​t​ ​y​o​u​r​ ​e​n​r​o​l​l​m​e​n​t​ ​p​r​o​c​e​s​s - */ - title: string - /** - * T​h​a​n​k​ ​y​o​u​ ​f​o​r​ ​v​a​l​i​d​a​t​i​n​g​ ​y​o​u​r​ ​a​c​c​o​u​n​t​,​ ​p​l​e​a​s​e​ ​f​o​l​l​o​w​ ​i​n​s​t​r​u​c​t​i​o​n​ ​b​e​l​o​w​ ​f​o​r​ ​c​o​n​f​i​g​u​r​i​n​g​ ​y​o​u​r​ ​V​P​N​ ​c​o​n​n​e​c​t​i​o​n​. - */ - infoBox: string - steps: { - /** - * P​l​e​a​s​e​ ​d​o​w​n​l​o​a​d​ ​a​n​d​ ​i​n​s​t​a​l​l​ ​d​e​f​g​u​a​r​d​ ​V​P​N​ ​D​e​s​k​t​o​p​ ​C​l​i​e​n​t​. - */ - first: string - /** + finish: string; + }; + }; + }; + }; + finish: { + /** + * C​o​n​f​i​g​u​r​a​t​i​o​n​ ​c​o​m​p​l​e​t​e​d​! + */ + title: string; + }; + }; + }; + resetPassword: { + steps: { + email: { + controls: { + /** + * S​e​n​d + */ + send: string; + }; + /** + * E​n​t​e​r​ ​y​o​u​r​ ​e​-​m​a​i​l + */ + title: string; + form: { + fields: { + email: { + /** + * E​-​m​a​i​l + */ + label: string; + }; + }; + }; + }; + linkSent: { + controls: { + /** + * B​a​c​k​ ​t​o​ ​m​a​i​n​ ​m​e​n​u + */ + back: string; + }; + /** + * I​f​ ​t​h​e​ ​p​r​o​v​i​d​e​d​ ​e​m​a​i​l​ ​a​d​d​r​e​s​s​ ​i​s​ ​a​s​s​i​g​n​e​d​ ​t​o​ ​a​n​y​ ​a​c​c​o​u​n​t​ ​-​ ​t​h​e​ ​p​a​s​s​w​o​r​d​ ​r​e​s​e​t​ ​w​i​l​l​ ​b​e​ ​i​n​i​t​i​a​t​e​d​ ​a​n​d​ ​y​o​u​ ​w​i​l​l​ ​r​e​c​i​e​v​e​ ​a​n​ ​e​m​a​i​l​ ​w​i​t​h​ ​f​u​r​t​h​e​r​ ​i​s​t​r​u​c​t​i​o​n​s​. + */ + messageBox: string; + }; + securityCode: { + controls: { + /** + * S​e​n​d​ ​c​o​d​e + */ + sendCode: string; + }; + /** + * E​n​t​e​r​ ​s​e​c​u​r​i​t​y​ ​c​o​d​e + */ + title: string; + /** + * I​n​ ​o​r​d​e​r​ ​t​o​ ​r​e​s​e​t​ ​t​h​e​ ​p​a​s​s​w​o​r​d​,​ ​p​l​e​a​s​e​ ​p​r​o​v​i​d​e​ ​s​e​c​u​r​i​t​y​ ​c​o​d​e​ ​t​h​a​t​ ​w​i​l​l​ ​b​e​ ​s​e​n​t​ ​t​o​ ​y​o​u​r​ ​n​u​m​b​e​r​: + */ + messagebox: string; + form: { + fields: { + code: { + /** + * S​e​c​u​r​i​t​y​ ​c​o​d​e + */ + label: string; + }; + }; + }; + }; + resetPassword: { + /** + * R​e​s​e​t​ ​y​o​u​r​ ​p​a​s​s​w​o​r​d + */ + title: string; + controls: { + /** + * R​e​s​e​t​ ​p​a​s​s​w​o​r​d + */ + submit: string; + }; + form: { + errors: { + /** + * F​i​e​l​d​s​ ​d​o​e​s​n​'​t​ ​m​a​t​c​h + */ + repeat: string; + }; + fields: { + password: { + /** + * N​e​w​ ​p​a​s​s​w​o​r​d + */ + label: string; + }; + repeat: { + /** + * C​o​n​f​i​r​m​ ​p​a​s​s​w​o​r​d + */ + label: string; + }; + }; + }; + }; + resetSuccess: { + controls: { + /** + * R​e​t​u​r​n​ ​t​o​ ​s​e​r​v​i​c​e​s​ ​m​e​n​u + */ + back: string; + }; + /** + * C​o​n​g​r​a​t​u​l​a​t​i​o​n​s​,​ ​y​o​u​r​ ​n​e​w​ ​p​a​s​s​w​o​r​d​ ​i​s​ ​s​e​t​. + */ + messageBox: string; + }; + resetFailed: { + controls: { + /** + * R​e​t​u​r​n​ ​t​o​ ​s​t​a​r​t + */ + back: string; + }; + /** + * T​h​e​ ​e​n​t​e​r​e​d​ ​c​o​d​e​ ​i​s​ ​i​n​v​a​l​i​d​.​ ​P​l​e​a​s​e​ ​s​t​a​r​t​ ​t​h​e​ ​p​r​o​c​e​s​s​ ​f​r​o​m​ ​t​h​e​ ​b​e​g​i​n​n​i​n​g​. + */ + messageBox: string; + }; + }; + }; + sessionTimeout: { + card: { + /** + * S​e​s​s​i​o​n​ ​t​i​m​e​d​ ​o​u​t + */ + header: string; + /** + * S​o​r​r​y​,​ ​y​o​u​ ​h​a​v​e​ ​e​x​c​e​e​d​e​d​ ​t​h​e​ ​t​i​m​e​ ​l​i​m​i​t​ ​t​o​ ​c​o​m​p​l​e​t​e​ ​t​h​e​ ​p​r​o​c​e​s​s​.​ ​P​l​e​a​s​e​ ​t​r​y​ ​a​g​a​i​n​.​ ​I​f​ ​y​o​u​ ​n​e​e​d​ ​a​s​s​i​s​t​a​n​c​e​,​ ​p​l​e​a​s​e​ ​w​a​t​c​h​ ​o​u​r​ ​g​u​i​d​e​ ​o​r​ ​c​o​n​t​a​c​t​ ​y​o​u​r​ ​a​d​m​i​n​i​s​t​r​a​t​o​r​. + */ + message: string; + }; + controls: { + /** + * E​n​t​e​r​ ​n​e​w​ ​t​o​k​e​n + */ + back: string; + /** + * C​o​n​t​a​c​t​ ​a​d​m​i​n + */ + contact: string; + }; + }; + token: { + card: { + /** + * P​l​e​a​s​e​,​ ​e​n​t​e​r​ ​y​o​u​r​ ​p​e​r​s​o​n​a​l​ ​e​n​r​o​l​l​m​e​n​t​ ​t​o​k​e​n + */ + title: string; + messageBox: { + /** + * Y​o​u​ ​c​a​n​ ​f​i​n​d​ ​t​o​k​e​n​ ​i​n​ ​e​-​m​a​i​l​ ​m​e​s​s​a​g​e​ ​o​r​ ​u​s​e​ ​d​i​r​e​c​t​ ​l​i​n​k​. + */ + email: string; + }; + form: { + errors: { + token: { + /** + * T​o​k​e​n​ ​i​s​ ​r​e​q​u​i​r​e​d + */ + required: string; + }; + }; + fields: { + token: { + /** + * T​o​k​e​n + */ + placeholder: string; + }; + }; + controls: { + /** + * N​e​x​t + */ + submit: string; + }; + }; + oidc: { + /** + * S​i​g​n​ ​i​n​ ​w​i​t​h + */ + oidcButton: string; + /** + * O​r​ ​S​i​g​n​ ​I​n​ ​w​i​t​h​ ​E​x​t​e​r​n​a​l​ ​S​S​O + */ + title: string; + /** + * I​f​ ​y​o​u​ ​w​o​u​l​d​ ​l​i​k​e​ ​t​o​ ​i​n​i​t​i​a​t​e​ ​t​h​e​ ​e​n​r​o​l​l​m​e​n​t​ ​p​r​o​c​e​s​s​ ​u​s​i​n​g​ ​E​x​t​e​r​n​a​l​ ​S​S​O​,​ ​p​l​e​a​s​e​ ​c​l​i​c​k​ ​t​h​e​ ​l​i​n​k​ ​b​e​l​o​w​ ​t​o​ ​s​i​g​n​ ​i​n​ ​a​n​d​ ​s​t​a​r​t​ ​t​h​e​ ​p​r​o​c​e​s​s​. + */ + infoBox: string; + }; + }; + }; + oidcLogin: { + card: { + /** + * S​t​a​r​t​ ​y​o​u​r​ ​e​n​r​o​l​l​m​e​n​t​ ​p​r​o​c​e​s​s + */ + title: string; + /** + * T​h​a​n​k​ ​y​o​u​ ​f​o​r​ ​v​a​l​i​d​a​t​i​n​g​ ​y​o​u​r​ ​a​c​c​o​u​n​t​,​ ​p​l​e​a​s​e​ ​f​o​l​l​o​w​ ​i​n​s​t​r​u​c​t​i​o​n​ ​b​e​l​o​w​ ​f​o​r​ ​c​o​n​f​i​g​u​r​i​n​g​ ​y​o​u​r​ ​V​P​N​ ​c​o​n​n​e​c​t​i​o​n​. + */ + infoBox: string; + steps: { + /** + * P​l​e​a​s​e​ ​d​o​w​n​l​o​a​d​ ​a​n​d​ ​i​n​s​t​a​l​l​ ​d​e​f​g​u​a​r​d​ ​V​P​N​ ​D​e​s​k​t​o​p​ ​C​l​i​e​n​t​. + */ + first: string; + /** * 2​.​ ​O​p​e​n​ ​t​h​e​ ​c​l​i​e​n​t​ ​a​n​d​ ​<​i​>​A​d​d​ ​I​n​s​t​a​n​c​e​<​/​i​>​.​ ​C​o​p​y​ ​t​h​e​ ​d​a​t​a​ ​p​r​o​v​i​d​e​d​ ​b​e​l​o​w​ ​i​n​t​o​ ​t​h​e​ ​c​o​r​r​e​s​p​o​n​d​i​n​g​ ​f​i​e​l​d​s​.​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​Y​o​u​ ​c​a​n​ ​a​l​s​o​ ​l​e​a​r​n​ ​m​o​r​e​ ​a​b​o​u​t​ ​t​h​e​ ​p​r​o​c​e​s​s​ ​i​n​ ​o​u​r​ ​<​a​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​h​r​e​f​=​"​h​t​t​p​s​:​/​/​d​o​c​s​.​d​e​f​g​u​a​r​d​.​n​e​t​/​h​e​l​p​/​c​o​n​f​i​g​u​r​i​n​g​-​v​p​n​/​a​d​d​-​n​e​w​-​i​n​s​t​a​n​c​e​"​ @@ -613,221 +616,221 @@ type RootTranslation = { ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​d​o​c​u​m​e​n​t​a​t​i​o​n​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​<​/​a​>​. */ - second: string - tokenInput: { - /** - * I​n​s​t​a​n​c​e​ ​U​R​L - */ - instanceUrl: string - /** - * T​o​k​e​n - */ - token: string - /** - * P​l​e​a​s​e​ ​p​r​o​v​i​d​e​ ​i​n​s​t​a​n​c​e​ ​U​R​L​ ​a​n​d​ ​t​o​k​e​n - */ - title: string - /** - * A​d​d​ ​I​n​s​t​a​n​c​e - */ - addInstance: string - } - } - } - } - openidMfaCallback: { - error: { - /** - * A​u​t​h​e​n​t​i​c​a​t​i​o​n​ ​E​r​r​o​r - */ - title: string - /** - * T​h​e​r​e​ ​w​a​s​ ​a​n​ ​e​r​r​o​r​ ​d​u​r​i​n​g​ ​a​u​t​h​e​n​t​i​c​a​t​i​o​n​ ​w​i​t​h​ ​t​h​e​ ​p​r​o​v​i​d​e​r​.​ ​P​l​e​a​s​e​ ​g​o​ ​b​a​c​k​ ​t​o​ ​t​h​e​ ​*​*​D​e​f​g​u​a​r​d​ ​V​P​N​ ​C​l​i​e​n​t​*​*​ ​a​n​d​ ​r​e​p​e​a​t​ ​t​h​e​ ​p​r​o​c​e​s​s​. - */ - message: string - /** - * E​r​r​o​r​ ​D​e​t​a​i​l​s - */ - detailsTitle: string - } - success: { - /** - * A​u​t​h​e​n​t​i​c​a​t​i​o​n​ ​C​o​m​p​l​e​t​e​d - */ - title: string - /** - * Y​o​u​ ​h​a​v​e​ ​b​e​e​n​ ​s​u​c​c​e​s​s​f​u​l​l​y​ ​a​u​t​h​e​n​t​i​c​a​t​e​d​.​ ​P​l​e​a​s​e​ ​c​l​o​s​e​ ​t​h​i​s​ ​w​i​n​d​o​w​ ​a​n​d​ ​g​e​t​ ​b​a​c​k​ ​t​o​ ​t​h​e​ ​*​*​D​e​f​g​u​a​r​d​ ​V​P​N​ ​C​l​i​e​n​t​*​*​. - */ - message: string - } - } - openidMfaRedirect: { - error: { - /** - * A​u​t​h​e​n​t​i​c​a​t​i​o​n​ ​E​r​r​o​r - */ - title: string - /** - * N​o​ ​t​o​k​e​n​ ​p​r​o​v​i​d​e​d​ ​i​n​ ​t​h​e​ ​U​R​L​.​ ​P​l​e​a​s​e​ ​e​n​s​u​r​e​ ​y​o​u​ ​h​a​v​e​ ​a​ ​v​a​l​i​d​ ​t​o​k​e​n​ ​t​o​ ​p​r​o​c​e​e​d​ ​w​i​t​h​ ​O​p​e​n​I​D​ ​a​u​t​h​e​n​t​i​c​a​t​i​o​n​. - */ - message: string - } - } - } -} + second: string; + tokenInput: { + /** + * I​n​s​t​a​n​c​e​ ​U​R​L + */ + instanceUrl: string; + /** + * T​o​k​e​n + */ + token: string; + /** + * P​l​e​a​s​e​ ​p​r​o​v​i​d​e​ ​i​n​s​t​a​n​c​e​ ​U​R​L​ ​a​n​d​ ​t​o​k​e​n + */ + title: string; + /** + * A​d​d​ ​I​n​s​t​a​n​c​e + */ + addInstance: string; + }; + }; + }; + }; + openidMfaCallback: { + error: { + /** + * A​u​t​h​e​n​t​i​c​a​t​i​o​n​ ​E​r​r​o​r + */ + title: string; + /** + * T​h​e​r​e​ ​w​a​s​ ​a​n​ ​e​r​r​o​r​ ​d​u​r​i​n​g​ ​a​u​t​h​e​n​t​i​c​a​t​i​o​n​ ​w​i​t​h​ ​t​h​e​ ​p​r​o​v​i​d​e​r​.​ ​P​l​e​a​s​e​ ​g​o​ ​b​a​c​k​ ​t​o​ ​t​h​e​ ​*​*​D​e​f​g​u​a​r​d​ ​V​P​N​ ​C​l​i​e​n​t​*​*​ ​a​n​d​ ​r​e​p​e​a​t​ ​t​h​e​ ​p​r​o​c​e​s​s​. + */ + message: string; + /** + * E​r​r​o​r​ ​D​e​t​a​i​l​s + */ + detailsTitle: string; + }; + success: { + /** + * A​u​t​h​e​n​t​i​c​a​t​i​o​n​ ​C​o​m​p​l​e​t​e​d + */ + title: string; + /** + * Y​o​u​ ​h​a​v​e​ ​b​e​e​n​ ​s​u​c​c​e​s​s​f​u​l​l​y​ ​a​u​t​h​e​n​t​i​c​a​t​e​d​.​ ​P​l​e​a​s​e​ ​c​l​o​s​e​ ​t​h​i​s​ ​w​i​n​d​o​w​ ​a​n​d​ ​g​e​t​ ​b​a​c​k​ ​t​o​ ​t​h​e​ ​*​*​D​e​f​g​u​a​r​d​ ​V​P​N​ ​C​l​i​e​n​t​*​*​. + */ + message: string; + }; + }; + openidMfaRedirect: { + error: { + /** + * A​u​t​h​e​n​t​i​c​a​t​i​o​n​ ​E​r​r​o​r + */ + title: string; + /** + * N​o​ ​t​o​k​e​n​ ​p​r​o​v​i​d​e​d​ ​i​n​ ​t​h​e​ ​U​R​L​.​ ​P​l​e​a​s​e​ ​e​n​s​u​r​e​ ​y​o​u​ ​h​a​v​e​ ​a​ ​v​a​l​i​d​ ​t​o​k​e​n​ ​t​o​ ​p​r​o​c​e​e​d​ ​w​i​t​h​ ​O​p​e​n​I​D​ ​a​u​t​h​e​n​t​i​c​a​t​i​o​n​. + */ + message: string; + }; + }; + }; +}; export type TranslationFunctions = { - time: { - seconds: { - /** - * second - */ - singular: () => LocalizedString - /** - * seconds - */ - prular: () => LocalizedString - } - minutes: { - /** - * minute - */ - singular: () => LocalizedString - /** - * minutes - */ - prular: () => LocalizedString - } - } - form: { - errors: { - /** - * Field is invalid - */ - invalid: () => LocalizedString - /** - * Enter a valid E-mail - */ - email: () => LocalizedString - /** - * Field is required - */ - required: () => LocalizedString - /** - * Min length of {length} - */ - minLength: (arg: { length: number }) => LocalizedString - /** - * Max length of {length} - */ - maxLength: (arg: { length: number }) => LocalizedString - /** - * At least one special character - */ - specialsRequired: () => LocalizedString - /** - * Special characters are forbidden - */ - specialsForbidden: () => LocalizedString - /** - * At least one number required - */ - numberRequired: () => LocalizedString - password: { - /** - * Please correct the following: - */ - floatingTitle: () => LocalizedString - } - /** - * At least one lower case character - */ - oneLower: () => LocalizedString - /** - * At least one upper case character - */ - oneUpper: () => LocalizedString - } - } - common: { - controls: { - /** - * Back - */ - back: () => LocalizedString - /** - * Next - */ - next: () => LocalizedString - /** - * Submit - */ - submit: () => LocalizedString - } - } - components: { - adminInfo: { - /** - * Your admin - */ - title: () => LocalizedString - } - } - pages: { - enrollment: { - sideBar: { - /** - * Enrollment - */ - title: () => LocalizedString - steps: { - /** - * Welcome - */ - welcome: () => LocalizedString - /** - * Data verification - */ - verification: () => LocalizedString - /** - * Create password - */ - password: () => LocalizedString - /** - * Configure VPN - */ - vpn: () => LocalizedString - /** - * Finish - */ - finish: () => LocalizedString - } - /** - * Application version - */ - appVersion: () => LocalizedString - } - stepsIndicator: { - /** - * Step - */ - step: () => LocalizedString - /** - * of - */ - of: () => LocalizedString - } - /** - * Time left - */ - timeLeft: () => LocalizedString - steps: { - welcome: { - /** - * Hello, {name} - */ - title: (arg: { name: string }) => LocalizedString - /** + time: { + seconds: { + /** + * second + */ + singular: () => LocalizedString; + /** + * seconds + */ + prular: () => LocalizedString; + }; + minutes: { + /** + * minute + */ + singular: () => LocalizedString; + /** + * minutes + */ + prular: () => LocalizedString; + }; + }; + form: { + errors: { + /** + * Field is invalid + */ + invalid: () => LocalizedString; + /** + * Enter a valid E-mail + */ + email: () => LocalizedString; + /** + * Field is required + */ + required: () => LocalizedString; + /** + * Min length of {length} + */ + minLength: (arg: { length: number }) => LocalizedString; + /** + * Max length of {length} + */ + maxLength: (arg: { length: number }) => LocalizedString; + /** + * At least one special character + */ + specialsRequired: () => LocalizedString; + /** + * Special characters are forbidden + */ + specialsForbidden: () => LocalizedString; + /** + * At least one number required + */ + numberRequired: () => LocalizedString; + password: { + /** + * Please correct the following: + */ + floatingTitle: () => LocalizedString; + }; + /** + * At least one lower case character + */ + oneLower: () => LocalizedString; + /** + * At least one upper case character + */ + oneUpper: () => LocalizedString; + }; + }; + common: { + controls: { + /** + * Back + */ + back: () => LocalizedString; + /** + * Next + */ + next: () => LocalizedString; + /** + * Submit + */ + submit: () => LocalizedString; + }; + }; + components: { + adminInfo: { + /** + * Your admin + */ + title: () => LocalizedString; + }; + }; + pages: { + enrollment: { + sideBar: { + /** + * Enrollment + */ + title: () => LocalizedString; + steps: { + /** + * Welcome + */ + welcome: () => LocalizedString; + /** + * Data verification + */ + verification: () => LocalizedString; + /** + * Create password + */ + password: () => LocalizedString; + /** + * Configure VPN + */ + vpn: () => LocalizedString; + /** + * Finish + */ + finish: () => LocalizedString; + }; + /** + * Application version + */ + appVersion: () => LocalizedString; + }; + stepsIndicator: { + /** + * Step + */ + step: () => LocalizedString; + /** + * of + */ + of: () => LocalizedString; + }; + /** + * Time left + */ + timeLeft: () => LocalizedString; + steps: { + welcome: { + /** + * Hello, {name} + */ + title: (arg: { name: string }) => LocalizedString; + /** * In order to gain access to the company infrastructure, we require you to complete this enrollment process. During this process, you will need to: @@ -838,124 +841,124 @@ export type TranslationFunctions = { You have a time limit of **{time} minutes** to complete this process. If you have any questions, please consult your assigned admin.All necessary information can be found at the bottom of the sidebar. */ - explanation: (arg: { time: string }) => LocalizedString - } - dataVerification: { - /** - * Data verification - */ - title: () => LocalizedString - /** - * Please, check your data. If anything is wrong, notify your admin after you complete the process. - */ - messageBox: () => LocalizedString - form: { - fields: { - firstName: { - /** - * Name - */ - label: () => LocalizedString - } - lastName: { - /** - * Last name - */ - label: () => LocalizedString - } - email: { - /** - * E-mail - */ - label: () => LocalizedString - } - phone: { - /** - * Phone number - */ - label: () => LocalizedString - } - } - } - } - password: { - /** - * Create password - */ - title: () => LocalizedString - form: { - fields: { - password: { - /** - * Create new password - */ - label: () => LocalizedString - } - repeat: { - /** - * Confirm new password - */ - label: () => LocalizedString - errors: { - /** - * Passwords aren't matching - */ - matching: () => LocalizedString - } - } - } - } - } - deviceSetup: { - /** - * * This step is OPTIONAL. You can skip it if you wish. This can be configured later in defguard. - */ - optionalMessage: () => LocalizedString - cards: { - device: { - /** - * Configure your device for VPN - */ - title: () => LocalizedString - create: { - /** - * Create Configuration - */ - submit: () => LocalizedString - /** - * Please be advised that you have to download the configuration now, since we do not store your private key. After this dialog is closed, you will not be able to get your fulll configuration file (with private keys, only blank template). - */ - messageBox: () => LocalizedString - form: { - fields: { - name: { - /** - * Device Name - */ - label: () => LocalizedString - } - 'public': { - /** - * My Public Key - */ - label: () => LocalizedString - } - toggle: { - /** - * Generate key pair - */ - generate: () => LocalizedString - /** - * Use my own public key - */ - own: () => LocalizedString - } - } - } - } - config: { - messageBox: { - /** + explanation: (arg: { time: string }) => LocalizedString; + }; + dataVerification: { + /** + * Data verification + */ + title: () => LocalizedString; + /** + * Please, check your data. If anything is wrong, notify your admin after you complete the process. + */ + messageBox: () => LocalizedString; + form: { + fields: { + firstName: { + /** + * Name + */ + label: () => LocalizedString; + }; + lastName: { + /** + * Last name + */ + label: () => LocalizedString; + }; + email: { + /** + * E-mail + */ + label: () => LocalizedString; + }; + phone: { + /** + * Phone number + */ + label: () => LocalizedString; + }; + }; + }; + }; + password: { + /** + * Create password + */ + title: () => LocalizedString; + form: { + fields: { + password: { + /** + * Create new password + */ + label: () => LocalizedString; + }; + repeat: { + /** + * Confirm new password + */ + label: () => LocalizedString; + errors: { + /** + * Passwords aren't matching + */ + matching: () => LocalizedString; + }; + }; + }; + }; + }; + deviceSetup: { + /** + * * This step is OPTIONAL. You can skip it if you wish. This can be configured later in defguard. + */ + optionalMessage: () => LocalizedString; + cards: { + device: { + /** + * Configure your device for VPN + */ + title: () => LocalizedString; + create: { + /** + * Create Configuration + */ + submit: () => LocalizedString; + /** + * Please be advised that you have to download the configuration now, since we do not store your private key. After this dialog is closed, you will not be able to get your fulll configuration file (with private keys, only blank template). + */ + messageBox: () => LocalizedString; + form: { + fields: { + name: { + /** + * Device Name + */ + label: () => LocalizedString; + }; + public: { + /** + * My Public Key + */ + label: () => LocalizedString; + }; + toggle: { + /** + * Generate key pair + */ + generate: () => LocalizedString; + /** + * Use my own public key + */ + own: () => LocalizedString; + }; + }; + }; + }; + config: { + messageBox: { + /** *

Please be advised that you have to download the configuration now, @@ -965,305 +968,305 @@ export type TranslationFunctions = {

*/ - auto: () => LocalizedString - /** + auto: () => LocalizedString; + /** *

Please be advised that configuration provided here does not include private key and uses public key to fill it's place you will need to repalce it on your own for configuration to work properly.

*/ - manual: () => LocalizedString - } - /** - * My Device Name - */ - deviceNameLabel: () => LocalizedString - /** - * You don't have access to any networks - */ - noNetworksMessage: () => LocalizedString - /** - * Use provided configuration file below by scanning QR Code or importing it as file on your devices WireGuard app. - */ - cardTitle: () => LocalizedString - card: { - /** - * Config file for location - */ - selectLabel: () => LocalizedString - } - } - } - guide: { - /** - * Quick Guide - */ - title: () => LocalizedString - /** - * This quick guide will help you with device configuration. - */ - messageBox: () => LocalizedString - /** - * Step {step}: - */ - step: (arg: { step: number }) => LocalizedString - steps: { - wireguard: { - /** - * Download and install WireGuard client on your compputer or app on phone. - */ - content: () => LocalizedString - /** - * Download WireGuard - */ - button: () => LocalizedString - } - /** - * Download provided configuration file to your device. - */ - downloadConfig: () => LocalizedString - /** + manual: () => LocalizedString; + }; + /** + * My Device Name + */ + deviceNameLabel: () => LocalizedString; + /** + * You don't have access to any networks + */ + noNetworksMessage: () => LocalizedString; + /** + * Use provided configuration file below by scanning QR Code or importing it as file on your devices WireGuard app. + */ + cardTitle: () => LocalizedString; + card: { + /** + * Config file for location + */ + selectLabel: () => LocalizedString; + }; + }; + }; + guide: { + /** + * Quick Guide + */ + title: () => LocalizedString; + /** + * This quick guide will help you with device configuration. + */ + messageBox: () => LocalizedString; + /** + * Step {step}: + */ + step: (arg: { step: number }) => LocalizedString; + steps: { + wireguard: { + /** + * Download and install WireGuard client on your compputer or app on phone. + */ + content: () => LocalizedString; + /** + * Download WireGuard + */ + button: () => LocalizedString; + }; + /** + * Download provided configuration file to your device. + */ + downloadConfig: () => LocalizedString; + /** * Open WireGuard and select "Add Tunnel" (Import tunnel(s) from file). Find your Defguard configuration file and hit "OK". On phone use WireGuard app “+” icon and scan QR code. */ - addTunnel: () => LocalizedString - /** - * Select your tunnel from the list and press "activate". - */ - activate: () => LocalizedString - /** + addTunnel: () => LocalizedString; + /** + * Select your tunnel from the list and press "activate". + */ + activate: () => LocalizedString; + /** * **Great work - your Defguard VPN is now active!** If you want to disengage your VPN connection, simply press "deactivate". */ - finish: () => LocalizedString - } - } - } - } - finish: { - /** - * Configuration completed! - */ - title: () => LocalizedString - } - } - } - resetPassword: { - steps: { - email: { - controls: { - /** - * Send - */ - send: () => LocalizedString - } - /** - * Enter your e-mail - */ - title: () => LocalizedString - form: { - fields: { - email: { - /** - * E-mail - */ - label: () => LocalizedString - } - } - } - } - linkSent: { - controls: { - /** - * Back to main menu - */ - back: () => LocalizedString - } - /** - * If the provided email address is assigned to any account - the password reset will be initiated and you will recieve an email with further istructions. - */ - messageBox: () => LocalizedString - } - securityCode: { - controls: { - /** - * Send code - */ - sendCode: () => LocalizedString - } - /** - * Enter security code - */ - title: () => LocalizedString - /** - * In order to reset the password, please provide security code that will be sent to your number: - */ - messagebox: () => LocalizedString - form: { - fields: { - code: { - /** - * Security code - */ - label: () => LocalizedString - } - } - } - } - resetPassword: { - /** - * Reset your password - */ - title: () => LocalizedString - controls: { - /** - * Reset password - */ - submit: () => LocalizedString - } - form: { - errors: { - /** - * Fields doesn't match - */ - repeat: () => LocalizedString - } - fields: { - password: { - /** - * New password - */ - label: () => LocalizedString - } - repeat: { - /** - * Confirm password - */ - label: () => LocalizedString - } - } - } - } - resetSuccess: { - controls: { - /** - * Return to services menu - */ - back: () => LocalizedString - } - /** - * Congratulations, your new password is set. - */ - messageBox: () => LocalizedString - } - resetFailed: { - controls: { - /** - * Return to start - */ - back: () => LocalizedString - } - /** - * The entered code is invalid. Please start the process from the beginning. - */ - messageBox: () => LocalizedString - } - } - } - sessionTimeout: { - card: { - /** - * Session timed out - */ - header: () => LocalizedString - /** - * Sorry, you have exceeded the time limit to complete the process. Please try again. If you need assistance, please watch our guide or contact your administrator. - */ - message: () => LocalizedString - } - controls: { - /** - * Enter new token - */ - back: () => LocalizedString - /** - * Contact admin - */ - contact: () => LocalizedString - } - } - token: { - card: { - /** - * Please, enter your personal enrollment token - */ - title: () => LocalizedString - messageBox: { - /** - * You can find token in e-mail message or use direct link. - */ - email: () => LocalizedString - } - form: { - errors: { - token: { - /** - * Token is required - */ - required: () => LocalizedString - } - } - fields: { - token: { - /** - * Token - */ - placeholder: () => LocalizedString - } - } - controls: { - /** - * Next - */ - submit: () => LocalizedString - } - } - oidc: { - /** - * Sign in with - */ - oidcButton: () => LocalizedString - /** - * Or Sign In with External SSO - */ - title: () => LocalizedString - /** - * If you would like to initiate the enrollment process using External SSO, please click the link below to sign in and start the process. - */ - infoBox: () => LocalizedString - } - } - } - oidcLogin: { - card: { - /** - * Start your enrollment process - */ - title: () => LocalizedString - /** - * Thank you for validating your account, please follow instruction below for configuring your VPN connection. - */ - infoBox: () => LocalizedString - steps: { - /** - * Please download and install defguard VPN Desktop Client. - */ - first: () => LocalizedString - /** + finish: () => LocalizedString; + }; + }; + }; + }; + finish: { + /** + * Configuration completed! + */ + title: () => LocalizedString; + }; + }; + }; + resetPassword: { + steps: { + email: { + controls: { + /** + * Send + */ + send: () => LocalizedString; + }; + /** + * Enter your e-mail + */ + title: () => LocalizedString; + form: { + fields: { + email: { + /** + * E-mail + */ + label: () => LocalizedString; + }; + }; + }; + }; + linkSent: { + controls: { + /** + * Back to main menu + */ + back: () => LocalizedString; + }; + /** + * If the provided email address is assigned to any account - the password reset will be initiated and you will recieve an email with further istructions. + */ + messageBox: () => LocalizedString; + }; + securityCode: { + controls: { + /** + * Send code + */ + sendCode: () => LocalizedString; + }; + /** + * Enter security code + */ + title: () => LocalizedString; + /** + * In order to reset the password, please provide security code that will be sent to your number: + */ + messagebox: () => LocalizedString; + form: { + fields: { + code: { + /** + * Security code + */ + label: () => LocalizedString; + }; + }; + }; + }; + resetPassword: { + /** + * Reset your password + */ + title: () => LocalizedString; + controls: { + /** + * Reset password + */ + submit: () => LocalizedString; + }; + form: { + errors: { + /** + * Fields doesn't match + */ + repeat: () => LocalizedString; + }; + fields: { + password: { + /** + * New password + */ + label: () => LocalizedString; + }; + repeat: { + /** + * Confirm password + */ + label: () => LocalizedString; + }; + }; + }; + }; + resetSuccess: { + controls: { + /** + * Return to services menu + */ + back: () => LocalizedString; + }; + /** + * Congratulations, your new password is set. + */ + messageBox: () => LocalizedString; + }; + resetFailed: { + controls: { + /** + * Return to start + */ + back: () => LocalizedString; + }; + /** + * The entered code is invalid. Please start the process from the beginning. + */ + messageBox: () => LocalizedString; + }; + }; + }; + sessionTimeout: { + card: { + /** + * Session timed out + */ + header: () => LocalizedString; + /** + * Sorry, you have exceeded the time limit to complete the process. Please try again. If you need assistance, please watch our guide or contact your administrator. + */ + message: () => LocalizedString; + }; + controls: { + /** + * Enter new token + */ + back: () => LocalizedString; + /** + * Contact admin + */ + contact: () => LocalizedString; + }; + }; + token: { + card: { + /** + * Please, enter your personal enrollment token + */ + title: () => LocalizedString; + messageBox: { + /** + * You can find token in e-mail message or use direct link. + */ + email: () => LocalizedString; + }; + form: { + errors: { + token: { + /** + * Token is required + */ + required: () => LocalizedString; + }; + }; + fields: { + token: { + /** + * Token + */ + placeholder: () => LocalizedString; + }; + }; + controls: { + /** + * Next + */ + submit: () => LocalizedString; + }; + }; + oidc: { + /** + * Sign in with + */ + oidcButton: () => LocalizedString; + /** + * Or Sign In with External SSO + */ + title: () => LocalizedString; + /** + * If you would like to initiate the enrollment process using External SSO, please click the link below to sign in and start the process. + */ + infoBox: () => LocalizedString; + }; + }; + }; + oidcLogin: { + card: { + /** + * Start your enrollment process + */ + title: () => LocalizedString; + /** + * Thank you for validating your account, please follow instruction below for configuring your VPN connection. + */ + infoBox: () => LocalizedString; + steps: { + /** + * Please download and install defguard VPN Desktop Client. + */ + first: () => LocalizedString; + /** * 2. Open the client and Add Instance. Copy the data provided below into the corresponding fields. You can also learn more about the process in our . */ - second: () => LocalizedString - tokenInput: { - /** - * Instance URL - */ - instanceUrl: () => LocalizedString - /** - * Token - */ - token: () => LocalizedString - /** - * Please provide instance URL and token - */ - title: () => LocalizedString - /** - * Add Instance - */ - addInstance: () => LocalizedString - } - } - } - } - openidMfaCallback: { - error: { - /** - * Authentication Error - */ - title: () => LocalizedString - /** - * There was an error during authentication with the provider. Please go back to the **Defguard VPN Client** and repeat the process. - */ - message: () => LocalizedString - /** - * Error Details - */ - detailsTitle: () => LocalizedString - } - success: { - /** - * Authentication Completed - */ - title: () => LocalizedString - /** - * You have been successfully authenticated. Please close this window and get back to the **Defguard VPN Client**. - */ - message: () => LocalizedString - } - } - openidMfaRedirect: { - error: { - /** - * Authentication Error - */ - title: () => LocalizedString - /** - * No token provided in the URL. Please ensure you have a valid token to proceed with OpenID authentication. - */ - message: () => LocalizedString - } - } - } -} + second: () => LocalizedString; + tokenInput: { + /** + * Instance URL + */ + instanceUrl: () => LocalizedString; + /** + * Token + */ + token: () => LocalizedString; + /** + * Please provide instance URL and token + */ + title: () => LocalizedString; + /** + * Add Instance + */ + addInstance: () => LocalizedString; + }; + }; + }; + }; + openidMfaCallback: { + error: { + /** + * Authentication Error + */ + title: () => LocalizedString; + /** + * There was an error during authentication with the provider. Please go back to the **Defguard VPN Client** and repeat the process. + */ + message: () => LocalizedString; + /** + * Error Details + */ + detailsTitle: () => LocalizedString; + }; + success: { + /** + * Authentication Completed + */ + title: () => LocalizedString; + /** + * You have been successfully authenticated. Please close this window and get back to the **Defguard VPN Client**. + */ + message: () => LocalizedString; + }; + }; + openidMfaRedirect: { + error: { + /** + * Authentication Error + */ + title: () => LocalizedString; + /** + * No token provided in the URL. Please ensure you have a valid token to proceed with OpenID authentication. + */ + message: () => LocalizedString; + }; + }; + }; +}; -export type Formatters = {} +export type Formatters = {}; diff --git a/web/src/i18n/i18n-util.async.ts b/web/src/i18n/i18n-util.async.ts index d87b526..6076abd 100644 --- a/web/src/i18n/i18n-util.async.ts +++ b/web/src/i18n/i18n-util.async.ts @@ -1,26 +1,29 @@ // This file was auto-generated by 'typesafe-i18n'. Any manual changes will be overwritten. /* eslint-disable */ -import { initFormatters } from './formatters' -import type { Locales, Translations } from './i18n-types' -import { loadedFormatters, loadedLocales, locales } from './i18n-util' +import { initFormatters } from './formatters'; +import type { Locales, Translations } from './i18n-types'; +import { loadedFormatters, loadedLocales, locales } from './i18n-util'; const localeTranslationLoaders = { - en: () => import('./en'), -} + en: () => import('./en'), +}; -const updateDictionary = (locale: Locales, dictionary: Partial): Translations => - loadedLocales[locale] = { ...loadedLocales[locale], ...dictionary } +const updateDictionary = ( + locale: Locales, + dictionary: Partial, +): Translations => (loadedLocales[locale] = { ...loadedLocales[locale], ...dictionary }); export const importLocaleAsync = async (locale: Locales): Promise => - (await localeTranslationLoaders[locale]()).default as unknown as Translations + (await localeTranslationLoaders[locale]()).default as unknown as Translations; export const loadLocaleAsync = async (locale: Locales): Promise => { - updateDictionary(locale, await importLocaleAsync(locale)) - loadFormatters(locale) -} + updateDictionary(locale, await importLocaleAsync(locale)); + loadFormatters(locale); +}; -export const loadAllLocalesAsync = (): Promise => Promise.all(locales.map(loadLocaleAsync)) +export const loadAllLocalesAsync = (): Promise => + Promise.all(locales.map(loadLocaleAsync)); export const loadFormatters = (locale: Locales): void => - void (loadedFormatters[locale] = initFormatters(locale)) + void (loadedFormatters[locale] = initFormatters(locale)); diff --git a/web/src/i18n/i18n-util.sync.ts b/web/src/i18n/i18n-util.sync.ts index bebffe4..4a34592 100644 --- a/web/src/i18n/i18n-util.sync.ts +++ b/web/src/i18n/i18n-util.sync.ts @@ -1,24 +1,23 @@ // This file was auto-generated by 'typesafe-i18n'. Any manual changes will be overwritten. /* eslint-disable */ -import { initFormatters } from './formatters' -import type { Locales, Translations } from './i18n-types' -import { loadedFormatters, loadedLocales, locales } from './i18n-util' - -import en from './en' +import en from './en'; +import { initFormatters } from './formatters'; +import type { Locales, Translations } from './i18n-types'; +import { loadedFormatters, loadedLocales, locales } from './i18n-util'; const localeTranslations = { - en, -} + en, +}; export const loadLocale = (locale: Locales): void => { - if (loadedLocales[locale]) return + if (loadedLocales[locale]) return; - loadedLocales[locale] = localeTranslations[locale] as unknown as Translations - loadFormatters(locale) -} + loadedLocales[locale] = localeTranslations[locale] as unknown as Translations; + loadFormatters(locale); +}; -export const loadAllLocales = (): void => locales.forEach(loadLocale) +export const loadAllLocales = (): void => locales.forEach(loadLocale); export const loadFormatters = (locale: Locales): void => - void (loadedFormatters[locale] = initFormatters(locale)) + void (loadedFormatters[locale] = initFormatters(locale)); diff --git a/web/src/i18n/i18n-util.ts b/web/src/i18n/i18n-util.ts index 452e0a6..eb99683 100644 --- a/web/src/i18n/i18n-util.ts +++ b/web/src/i18n/i18n-util.ts @@ -1,37 +1,60 @@ // This file was auto-generated by 'typesafe-i18n'. Any manual changes will be overwritten. /* eslint-disable */ -import { i18n as initI18n, i18nObject as initI18nObject, i18nString as initI18nString } from 'typesafe-i18n' -import type { LocaleDetector } from 'typesafe-i18n/detectors' -import type { LocaleTranslationFunctions, TranslateByString } from 'typesafe-i18n' -import { detectLocale as detectLocaleFn } from 'typesafe-i18n/detectors' -import { initExtendDictionary } from 'typesafe-i18n/utils' -import type { Formatters, Locales, Translations, TranslationFunctions } from './i18n-types' - -export const baseLocale: Locales = 'en' - -export const locales: Locales[] = [ - 'en' -] - -export const isLocale = (locale: string): locale is Locales => locales.includes(locale as Locales) - -export const loadedLocales: Record = {} as Record - -export const loadedFormatters: Record = {} as Record - -export const extendDictionary = initExtendDictionary() - -export const i18nString = (locale: Locales): TranslateByString => initI18nString(locale, loadedFormatters[locale]) +import type { LocaleTranslationFunctions, TranslateByString } from 'typesafe-i18n'; +import { + i18n as initI18n, + i18nObject as initI18nObject, + i18nString as initI18nString, +} from 'typesafe-i18n'; +import type { LocaleDetector } from 'typesafe-i18n/detectors'; +import { detectLocale as detectLocaleFn } from 'typesafe-i18n/detectors'; +import { initExtendDictionary } from 'typesafe-i18n/utils'; +import type { + Formatters, + Locales, + TranslationFunctions, + Translations, +} from './i18n-types'; + +export const baseLocale: Locales = 'en'; + +export const locales: Locales[] = ['en']; + +export const isLocale = (locale: string): locale is Locales => + locales.includes(locale as Locales); + +export const loadedLocales: Record = {} as Record< + Locales, + Translations +>; + +export const loadedFormatters: Record = {} as Record< + Locales, + Formatters +>; + +export const extendDictionary = initExtendDictionary(); + +export const i18nString = (locale: Locales): TranslateByString => + initI18nString(locale, loadedFormatters[locale]); export const i18nObject = (locale: Locales): TranslationFunctions => - initI18nObject( - locale, - loadedLocales[locale], - loadedFormatters[locale] - ) - -export const i18n = (): LocaleTranslationFunctions => - initI18n(loadedLocales, loadedFormatters) - -export const detectLocale = (...detectors: LocaleDetector[]): Locales => detectLocaleFn(baseLocale, locales, ...detectors) + initI18nObject( + locale, + loadedLocales[locale], + loadedFormatters[locale], + ); + +export const i18n = (): LocaleTranslationFunctions< + Locales, + Translations, + TranslationFunctions +> => + initI18n( + loadedLocales, + loadedFormatters, + ); + +export const detectLocale = (...detectors: LocaleDetector[]): Locales => + detectLocaleFn(baseLocale, locales, ...detectors); diff --git a/web/src/pages/enrollment/EnrollmentPage.tsx b/web/src/pages/enrollment/EnrollmentPage.tsx index 4c44b77..0309d78 100644 --- a/web/src/pages/enrollment/EnrollmentPage.tsx +++ b/web/src/pages/enrollment/EnrollmentPage.tsx @@ -1,7 +1,7 @@ import './style.scss'; import dayjs from 'dayjs'; -import { ReactNode, useEffect, useRef } from 'react'; +import { type ReactNode, useEffect, useRef } from 'react'; import { useNavigate } from 'react-router-dom'; import { useBreakpoint } from 'use-breakpoint'; import { shallow } from 'zustand/shallow'; @@ -40,7 +40,7 @@ export const EnrollmentPage = () => { const stepsMax = useEnrollmentStore((state) => state.stepsMax); const loading = useEnrollmentStore((state) => state.loading); - const [setEnrollmentState, back, reset, nextSubject] = useEnrollmentStore( + const [setEnrollmentState, back, _reset, nextSubject] = useEnrollmentStore( (state) => [state.setState, state.perviousStep, state.reset, state.nextSubject], shallow, ); @@ -76,7 +76,7 @@ export const EnrollmentPage = () => { navigate(routes.timeout, { replace: true }); } } - }, [sessionEnd, navigate, reset]); + }, [sessionEnd, navigate]); useEffect(() => { enrollmentFinished.current = stepsMax === currentStep; diff --git a/web/src/pages/enrollment/components/AdminInfo/style.scss b/web/src/pages/enrollment/components/AdminInfo/style.scss index 8fb4686..484af21 100644 --- a/web/src/pages/enrollment/components/AdminInfo/style.scss +++ b/web/src/pages/enrollment/components/AdminInfo/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - .admin-info { width: 100%; diff --git a/web/src/pages/enrollment/components/EnrollmentSideBar/EnrollmentSideBar.tsx b/web/src/pages/enrollment/components/EnrollmentSideBar/EnrollmentSideBar.tsx index 8b1a28a..80c4746 100644 --- a/web/src/pages/enrollment/components/EnrollmentSideBar/EnrollmentSideBar.tsx +++ b/web/src/pages/enrollment/components/EnrollmentSideBar/EnrollmentSideBar.tsx @@ -2,7 +2,7 @@ import './style.scss'; import classNames from 'classnames'; import { useEffect, useMemo, useState } from 'react'; -import { LocalizedString } from 'typesafe-i18n'; +import type { LocalizedString } from 'typesafe-i18n'; import { useI18nContext } from '../../../../i18n/i18n-react'; import { Divider } from '../../../../shared/components/layout/Divider/Divider'; @@ -42,7 +42,7 @@ export const EnrollmentSideBar = () => { }); } // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + }, [appVersion, getAppInfo]); const steps = useMemo((): LocalizedString[] => { const stepsLL = LL.pages.enrollment.sideBar.steps; diff --git a/web/src/pages/enrollment/components/EnrollmentSideBar/style.scss b/web/src/pages/enrollment/components/EnrollmentSideBar/style.scss index e13cd32..fd02a72 100644 --- a/web/src/pages/enrollment/components/EnrollmentSideBar/style.scss +++ b/web/src/pages/enrollment/components/EnrollmentSideBar/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #enrollment-side-bar { box-sizing: border-box; width: 270px; @@ -61,6 +59,7 @@ & > .admin-info { box-sizing: border-box; padding: 20px 10px 20px 40px; + & > p { @include typography(app-body-2); @include text-overflow-dots; diff --git a/web/src/pages/enrollment/components/EnrollmentStepControls/EnrollmentStepControls.tsx b/web/src/pages/enrollment/components/EnrollmentStepControls/EnrollmentStepControls.tsx index 85ee8d6..c392faf 100644 --- a/web/src/pages/enrollment/components/EnrollmentStepControls/EnrollmentStepControls.tsx +++ b/web/src/pages/enrollment/components/EnrollmentStepControls/EnrollmentStepControls.tsx @@ -1,7 +1,7 @@ import './style.scss'; import classNames from 'classnames'; -import { ReactNode } from 'react'; +import type { ReactNode } from 'react'; import { AdminInfo } from '../AdminInfo/AdminInfo'; import { TimeLeft } from '../TimeLeft/TimeLeft'; diff --git a/web/src/pages/enrollment/components/EnrollmentStepControls/style.scss b/web/src/pages/enrollment/components/EnrollmentStepControls/style.scss index 6c2fcb5..e326ed5 100644 --- a/web/src/pages/enrollment/components/EnrollmentStepControls/style.scss +++ b/web/src/pages/enrollment/components/EnrollmentStepControls/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #enrollment { & > .controls { box-sizing: border-box; @@ -38,6 +36,7 @@ @include media-breakpoint-down(lg) { height: 44px; } + &.variant-standard { svg { g { @@ -45,6 +44,7 @@ } } } + &.variant-primary { svg { g { @@ -59,6 +59,7 @@ display: flex; flex-flow: row nowrap; overflow: hidden; + .admin-info { display: flex; flex-flow: row wrap; @@ -75,6 +76,7 @@ @include typography(app-copyright); } } + & > .time-left { margin-left: auto; text-align: right; diff --git a/web/src/pages/enrollment/components/EnrollmentStepIndicator/style.scss b/web/src/pages/enrollment/components/EnrollmentStepIndicator/style.scss index 1fd9c13..f16c343 100644 --- a/web/src/pages/enrollment/components/EnrollmentStepIndicator/style.scss +++ b/web/src/pages/enrollment/components/EnrollmentStepIndicator/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - .step-indicator { width: 100%; height: auto; @@ -9,6 +7,7 @@ @include typography(app-avatar-s); color: var(--text-body-primary); + & > span { color: var(--text-body-tertiary); } diff --git a/web/src/pages/enrollment/components/TimeLeft/style.scss b/web/src/pages/enrollment/components/TimeLeft/style.scss index 9e11b98..1aad4b0 100644 --- a/web/src/pages/enrollment/components/TimeLeft/style.scss +++ b/web/src/pages/enrollment/components/TimeLeft/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - .time-left { display: inline-block; diff --git a/web/src/pages/enrollment/hooks/store/useEnrollmentStore.tsx b/web/src/pages/enrollment/hooks/store/useEnrollmentStore.tsx index fb9c659..f7ef168 100644 --- a/web/src/pages/enrollment/hooks/store/useEnrollmentStore.tsx +++ b/web/src/pages/enrollment/hooks/store/useEnrollmentStore.tsx @@ -3,7 +3,7 @@ import { Subject } from 'rxjs'; import { createJSONStorage, devtools, persist } from 'zustand/middleware'; import { createWithEqualityFn } from 'zustand/traditional'; -import { +import type { AdminInfo, Device, DeviceConfig, diff --git a/web/src/pages/enrollment/steps/DataVerificationStep/DataVerificationStep.tsx b/web/src/pages/enrollment/steps/DataVerificationStep/DataVerificationStep.tsx index ba3632c..a4eb6b4 100644 --- a/web/src/pages/enrollment/steps/DataVerificationStep/DataVerificationStep.tsx +++ b/web/src/pages/enrollment/steps/DataVerificationStep/DataVerificationStep.tsx @@ -2,7 +2,7 @@ import './style.scss'; import { zodResolver } from '@hookform/resolvers/zod'; import { useEffect, useMemo, useRef } from 'react'; -import { SubmitHandler, useForm } from 'react-hook-form'; +import { type SubmitHandler, useForm } from 'react-hook-form'; import { z } from 'zod'; import { shallow } from 'zustand/shallow'; diff --git a/web/src/pages/enrollment/steps/DataVerificationStep/style.scss b/web/src/pages/enrollment/steps/DataVerificationStep/style.scss index 638b8e8..fefa18a 100644 --- a/web/src/pages/enrollment/steps/DataVerificationStep/style.scss +++ b/web/src/pages/enrollment/steps/DataVerificationStep/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #enrollment-data-verification-card { padding: 0 20px; @@ -49,6 +47,7 @@ margin-bottom: 8px; padding: 0; } + & > p { @include typography(app-input); diff --git a/web/src/pages/enrollment/steps/DeviceStep/DeviceStep.tsx b/web/src/pages/enrollment/steps/DeviceStep/DeviceStep.tsx index 22d260e..2ef2a9d 100644 --- a/web/src/pages/enrollment/steps/DeviceStep/DeviceStep.tsx +++ b/web/src/pages/enrollment/steps/DeviceStep/DeviceStep.tsx @@ -1,7 +1,7 @@ import './style.scss'; import { useMutation } from '@tanstack/react-query'; -import { AxiosError } from 'axios'; +import type { AxiosError } from 'axios'; import classNames from 'classnames'; import { useEffect } from 'react'; import { shallow } from 'zustand/shallow'; @@ -59,7 +59,7 @@ export const DeviceStep = () => { if (userPassword) { const sub = nextSubject.subscribe(() => { if ( - (deviceState && deviceState.device && deviceState.configs) || + (deviceState?.device && deviceState.configs) || settings?.vpn_setup_optional || settings?.only_client_activation || deviceManagementDisabled diff --git a/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/components/CreateDevice.tsx b/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/components/CreateDevice.tsx index 2796593..be27b38 100644 --- a/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/components/CreateDevice.tsx +++ b/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/components/CreateDevice.tsx @@ -1,7 +1,7 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { useMutation } from '@tanstack/react-query'; import { useMemo, useState } from 'react'; -import { SubmitHandler, useController, useForm } from 'react-hook-form'; +import { type SubmitHandler, useController, useForm } from 'react-hook-form'; import { z } from 'zod'; import { useI18nContext } from '../../../../../../../i18n/i18n-react'; @@ -13,7 +13,7 @@ import { ButtonStyleVariant, } from '../../../../../../../shared/components/layout/Button/types'; import { MessageBox } from '../../../../../../../shared/components/layout/MessageBox/MessageBox'; -import { ToggleOption } from '../../../../../../../shared/components/layout/Toggle/types'; +import type { ToggleOption } from '../../../../../../../shared/components/layout/Toggle/types'; import { useApi } from '../../../../../../../shared/hooks/api/useApi'; import { generateWGKeys } from '../../../../../../../shared/utils/generateWGKeys'; import { useEnrollmentStore } from '../../../../../hooks/store/useEnrollmentStore'; diff --git a/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/components/DeviceConfiguration/DeviceConfiguration.tsx b/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/components/DeviceConfiguration/DeviceConfiguration.tsx index a0b75ff..25d6bc9 100644 --- a/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/components/DeviceConfiguration/DeviceConfiguration.tsx +++ b/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/components/DeviceConfiguration/DeviceConfiguration.tsx @@ -14,9 +14,9 @@ import { Input } from '../../../../../../../../shared/components/layout/Input/In import { MessageBox } from '../../../../../../../../shared/components/layout/MessageBox/MessageBox'; import { MessageBoxType } from '../../../../../../../../shared/components/layout/MessageBox/types'; import { Select } from '../../../../../../../../shared/components/layout/Select/Select'; -import { SelectOption } from '../../../../../../../../shared/components/layout/Select/types'; +import type { SelectOption } from '../../../../../../../../shared/components/layout/Select/types'; import SvgIconHamburger from '../../../../../../../../shared/components/svg/IconHamburger'; -import { DeviceConfig } from '../../../../../../../../shared/hooks/api/types'; +import type { DeviceConfig } from '../../../../../../../../shared/hooks/api/types'; import { downloadWGConfig } from '../../../../../../../../shared/utils/downloadWGConfig'; import { useEnrollmentStore } from '../../../../../../hooks/store/useEnrollmentStore'; @@ -43,7 +43,10 @@ export const DeviceConfiguration = () => { })) ?? [], [deviceState?.configs], ); - const networksAvailable = deviceState?.configs?.length > 0 ?? false; + + const networksAvailable = + deviceState && Array.isArray(deviceState.configs) && deviceState.configs.length > 0; + const preparedConfig = useMemo(() => { if (deviceState?.device?.privateKey) { return selected?.config.replace('YOUR_PRIVATE_KEY', deviceState.device.privateKey); @@ -57,7 +60,7 @@ export const DeviceConfiguration = () => { }, [selected, deviceState?.device?.privateKey, deviceState?.device?.pubkey]); useEffect(() => { - if (deviceState?.configs && deviceState.configs.length) { + if (deviceState?.configs?.length) { setSelected(deviceState.configs[0]); } }, [deviceState?.configs]); diff --git a/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/components/DeviceConfiguration/style.scss b/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/components/DeviceConfiguration/style.scss index a903bc8..656ed24 100644 --- a/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/components/DeviceConfiguration/style.scss +++ b/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/components/DeviceConfiguration/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #configure-device-card { .qr-info { display: flex; diff --git a/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/style.scss b/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/style.scss index 5f6a49c..d785fd0 100644 --- a/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/style.scss +++ b/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #configure-device-card { .message-box { margin-bottom: 20px; diff --git a/web/src/pages/enrollment/steps/DeviceStep/components/QuickGuideCard/style.scss b/web/src/pages/enrollment/steps/DeviceStep/components/QuickGuideCard/style.scss index 3b014cb..9b38196 100644 --- a/web/src/pages/enrollment/steps/DeviceStep/components/QuickGuideCard/style.scss +++ b/web/src/pages/enrollment/steps/DeviceStep/components/QuickGuideCard/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #device-setup-guide { & > h3 { margin-bottom: 23px; diff --git a/web/src/pages/enrollment/steps/DeviceStep/style.scss b/web/src/pages/enrollment/steps/DeviceStep/style.scss index 775dee3..7e9f171 100644 --- a/web/src/pages/enrollment/steps/DeviceStep/style.scss +++ b/web/src/pages/enrollment/steps/DeviceStep/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #enrollment-device-step { width: 100%; height: auto; @@ -15,6 +13,7 @@ .message { width: 100%; + & > * { text-align: center; } @@ -28,6 +27,7 @@ row-gap: 25px; align-items: flex-start; justify-content: center; + & > .card { width: 100%; max-width: 750px; diff --git a/web/src/pages/enrollment/steps/FinishStep/style.scss b/web/src/pages/enrollment/steps/FinishStep/style.scss index a9402e2..92bc806 100644 --- a/web/src/pages/enrollment/steps/FinishStep/style.scss +++ b/web/src/pages/enrollment/steps/FinishStep/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #enrollment-finish-card { width: 100%; max-width: 1200px; diff --git a/web/src/pages/enrollment/steps/PasswordStep/PasswordStep.tsx b/web/src/pages/enrollment/steps/PasswordStep/PasswordStep.tsx index 09b9c28..0362682 100644 --- a/web/src/pages/enrollment/steps/PasswordStep/PasswordStep.tsx +++ b/web/src/pages/enrollment/steps/PasswordStep/PasswordStep.tsx @@ -2,7 +2,7 @@ import './style.scss'; import { zodResolver } from '@hookform/resolvers/zod'; import { useEffect, useMemo, useRef } from 'react'; -import { SubmitHandler, useForm } from 'react-hook-form'; +import { type SubmitHandler, useForm } from 'react-hook-form'; import { z } from 'zod'; import { shallow } from 'zustand/shallow'; @@ -68,12 +68,12 @@ export const PasswordStep = () => { return () => { sub.unsubscribe(); }; - }, [nextSubject, submitRef]); + }, [nextSubject]); useEffect(() => { reset(); //eslint-disable-next-line - }, []); + }, [reset]); return ( diff --git a/web/src/pages/enrollment/steps/PasswordStep/style.scss b/web/src/pages/enrollment/steps/PasswordStep/style.scss index 9123aa6..4df9aac 100644 --- a/web/src/pages/enrollment/steps/PasswordStep/style.scss +++ b/web/src/pages/enrollment/steps/PasswordStep/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #enrollment-password-card { width: 100%; max-width: 650px; diff --git a/web/src/pages/enrollment/steps/WelcomeStep/WelcomeStep.tsx b/web/src/pages/enrollment/steps/WelcomeStep/WelcomeStep.tsx index 625454a..b8ab368 100644 --- a/web/src/pages/enrollment/steps/WelcomeStep/WelcomeStep.tsx +++ b/web/src/pages/enrollment/steps/WelcomeStep/WelcomeStep.tsx @@ -46,17 +46,15 @@ export const WelcomeStep = () => { }, [next, nextSubject]); return ( - <> - - -

- {LL.pages.enrollment.steps.welcome.title({ name: `${userInfo?.first_name}` })} -

-
- {markdown} -
- -
- + + +

+ {LL.pages.enrollment.steps.welcome.title({ name: `${userInfo?.first_name}` })} +

+
+ {markdown} +
+ +
); }; diff --git a/web/src/pages/enrollment/steps/WelcomeStep/style.scss b/web/src/pages/enrollment/steps/WelcomeStep/style.scss index 49b2586..e8497a5 100644 --- a/web/src/pages/enrollment/steps/WelcomeStep/style.scss +++ b/web/src/pages/enrollment/steps/WelcomeStep/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #enrollment { #enrollment-welcome-card { box-sizing: border-box; @@ -15,6 +13,7 @@ & > .explenation { user-select: none; margin-bottom: 30px; + p, ul, ol, @@ -31,11 +30,13 @@ & > .admin-info { user-select: text; + & > p { &:not(.title) { font-weight: 700; } } + & > .title { user-select: none; } diff --git a/web/src/pages/enrollment/style.scss b/web/src/pages/enrollment/style.scss index ce34d58..39d9a6e 100644 --- a/web/src/pages/enrollment/style.scss +++ b/web/src/pages/enrollment/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #enrollment { @include media-breakpoint-up(lg) { margin-left: 270px; diff --git a/web/src/pages/main/DeviceSetupMethodCard/DeviceSetupMethodCard.tsx b/web/src/pages/main/DeviceSetupMethodCard/DeviceSetupMethodCard.tsx index ce6127a..02a04f8 100644 --- a/web/src/pages/main/DeviceSetupMethodCard/DeviceSetupMethodCard.tsx +++ b/web/src/pages/main/DeviceSetupMethodCard/DeviceSetupMethodCard.tsx @@ -1,6 +1,6 @@ import './style.scss'; -import { ReactNode } from 'react'; +import type { ReactNode } from 'react'; import { Button } from '../../../shared/components/layout/Button/Button'; import { diff --git a/web/src/pages/main/DeviceSetupMethodCard/style.scss b/web/src/pages/main/DeviceSetupMethodCard/style.scss index e4f92ec..e9c2eec 100644 --- a/web/src/pages/main/DeviceSetupMethodCard/style.scss +++ b/web/src/pages/main/DeviceSetupMethodCard/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - .device-setup-method { width: 100%; box-sizing: border-box; diff --git a/web/src/pages/main/MainPage.tsx b/web/src/pages/main/MainPage.tsx index 0779fe3..3e5f879 100644 --- a/web/src/pages/main/MainPage.tsx +++ b/web/src/pages/main/MainPage.tsx @@ -26,7 +26,7 @@ export const MainPage = () => { // check if navigated from link with token if not do nothing useEffect(() => { const token = searchParams.get('token'); - if (token && token.length && !requestPending.current) { + if (token?.length && !requestPending.current) { requestPending.current = true; startEnrollment({ token, @@ -51,7 +51,7 @@ export const MainPage = () => { }); } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [searchParams]); + }, [searchParams, initEnrollment, navigate, startEnrollment]); return ( diff --git a/web/src/pages/main/style.scss b/web/src/pages/main/style.scss index 51893bf..7a45a6e 100644 --- a/web/src/pages/main/style.scss +++ b/web/src/pages/main/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #main-page { @include media-breakpoint-up(lg) { padding: 100px 50px; diff --git a/web/src/pages/mfa/OpenIDCallback.tsx b/web/src/pages/mfa/OpenIDCallback.tsx index 4ee6b3a..3a729ef 100644 --- a/web/src/pages/mfa/OpenIDCallback.tsx +++ b/web/src/pages/mfa/OpenIDCallback.tsx @@ -1,7 +1,7 @@ import './style.scss'; import { useQuery } from '@tanstack/react-query'; -import { AxiosError } from 'axios'; +import type { AxiosError } from 'axios'; import { useState } from 'react'; import ReactMarkdown from 'react-markdown'; import rehypeSanitize from 'rehype-sanitize'; diff --git a/web/src/pages/mfa/style.scss b/web/src/pages/mfa/style.scss index 4a2e4e2..d598cc6 100644 --- a/web/src/pages/mfa/style.scss +++ b/web/src/pages/mfa/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #openid-mfa-page { gap: var(--spacing-xs); diff --git a/web/src/pages/openidCallback/components/OpenIDCallbackCard.tsx b/web/src/pages/openidCallback/components/OpenIDCallbackCard.tsx index ad77e0b..fc70c4f 100644 --- a/web/src/pages/openidCallback/components/OpenIDCallbackCard.tsx +++ b/web/src/pages/openidCallback/components/OpenIDCallbackCard.tsx @@ -1,7 +1,7 @@ import './style.scss'; import { useQuery } from '@tanstack/react-query'; -import { AxiosError } from 'axios'; +import type { AxiosError } from 'axios'; import parse from 'html-react-parser'; import { useState } from 'react'; import { useBreakpoint } from 'use-breakpoint'; @@ -105,61 +105,59 @@ export const OpenIDCallbackCard = () => { } return ( - <> - -

{LL.pages.oidcLogin.card.title()}

- -
-

1. {LL.pages.oidcLogin.card.steps.first()}

-
-
-

{parse(LL.pages.oidcLogin.card.steps.second())}

- -

{LL.pages.oidcLogin.card.steps.tokenInput.title()}

-
- -
- - { - // This should never be undefined, but just in case - navigator.clipboard.writeText(data?.url || ''); - }} - /> -
+ +

{LL.pages.oidcLogin.card.title()}

+ +
+

1. {LL.pages.oidcLogin.card.steps.first()}

+
+
+

{parse(LL.pages.oidcLogin.card.steps.second())}

+ +

{LL.pages.oidcLogin.card.steps.tokenInput.title()}

+
+ +
+ + { + // This should never be undefined, but just in case + navigator.clipboard.writeText(data?.url || ''); + }} + />
+
-
- -
- - { - // This should never be undefined, but just in case - navigator.clipboard.writeText(data?.token || ''); - }} - /> -
+
+ +
+ + { + // This should never be undefined, but just in case + navigator.clipboard.writeText(data?.token || ''); + }} + />
+
-
-
- +
+
); }; diff --git a/web/src/pages/openidCallback/components/style.scss b/web/src/pages/openidCallback/components/style.scss index 8904637..06aaacb 100644 --- a/web/src/pages/openidCallback/components/style.scss +++ b/web/src/pages/openidCallback/components/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #openidcallback-page { .openidcallback-card { box-sizing: border-box; @@ -40,6 +38,7 @@ svg { width: 36px; height: 36px; + path { fill: var(--text-button-secondary); } diff --git a/web/src/pages/openidCallback/style.scss b/web/src/pages/openidCallback/style.scss index 6bc0f3b..524b04b 100644 --- a/web/src/pages/openidCallback/style.scss +++ b/web/src/pages/openidCallback/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #openidcallback-page { @include media-breakpoint-up(lg) { padding: 100px 50px; @@ -12,6 +10,7 @@ & > .logo-container { display: none; margin-bottom: 30px; + @include media-breakpoint-up(lg) { display: flex; margin-bottom: 100px; diff --git a/web/src/pages/passwordReset/PasswordResetPage.tsx b/web/src/pages/passwordReset/PasswordResetPage.tsx index 7a4e59f..0f0fefa 100644 --- a/web/src/pages/passwordReset/PasswordResetPage.tsx +++ b/web/src/pages/passwordReset/PasswordResetPage.tsx @@ -1,7 +1,7 @@ import './style.scss'; import dayjs from 'dayjs'; -import { ReactNode, useEffect, useRef } from 'react'; +import { type ReactNode, useEffect, useRef } from 'react'; import { useNavigate, useSearchParams } from 'react-router-dom'; import { LogoContainer } from '../../components/LogoContainer/LogoContainer'; @@ -39,7 +39,7 @@ export const PasswordResetPage = () => { useEffect(() => { const token = searchParams.get('token'); - if (token && token.length && !requestPending.current) { + if (token?.length && !requestPending.current) { requestPending.current = true; start({ token, @@ -63,7 +63,7 @@ export const PasswordResetPage = () => { }); } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [searchParams]); + }, [searchParams, navigate, setStore, start]); return ( diff --git a/web/src/pages/passwordReset/hooks/usePasswordResetStore.tsx b/web/src/pages/passwordReset/hooks/usePasswordResetStore.tsx index 6481bcc..3f0571b 100644 --- a/web/src/pages/passwordReset/hooks/usePasswordResetStore.tsx +++ b/web/src/pages/passwordReset/hooks/usePasswordResetStore.tsx @@ -1,6 +1,6 @@ import { create } from 'zustand'; -import { AdminInfo, UserInfo } from '../../../shared/hooks/api/types'; +import type { AdminInfo, UserInfo } from '../../../shared/hooks/api/types'; const defaultValues: StoreValues = { loading: false, diff --git a/web/src/pages/passwordReset/steps/CodeStep/CodeStep.tsx b/web/src/pages/passwordReset/steps/CodeStep/CodeStep.tsx index cf775ac..4ac735c 100644 --- a/web/src/pages/passwordReset/steps/CodeStep/CodeStep.tsx +++ b/web/src/pages/passwordReset/steps/CodeStep/CodeStep.tsx @@ -2,7 +2,7 @@ import './style.scss'; import { zodResolver } from '@hookform/resolvers/zod'; import { useMemo, useRef } from 'react'; -import { SubmitHandler, useForm } from 'react-hook-form'; +import { type SubmitHandler, useForm } from 'react-hook-form'; import { z } from 'zod'; import { useI18nContext } from '../../../../i18n/i18n-react'; diff --git a/web/src/pages/passwordReset/steps/EmailStep/EmailStep.tsx b/web/src/pages/passwordReset/steps/EmailStep/EmailStep.tsx index f1fc849..6348cea 100644 --- a/web/src/pages/passwordReset/steps/EmailStep/EmailStep.tsx +++ b/web/src/pages/passwordReset/steps/EmailStep/EmailStep.tsx @@ -2,9 +2,9 @@ import './style.scss'; import { zodResolver } from '@hookform/resolvers/zod'; import { useMutation } from '@tanstack/react-query'; -import { AxiosError } from 'axios'; +import type { AxiosError } from 'axios'; import { useMemo, useRef } from 'react'; -import { SubmitHandler, useForm } from 'react-hook-form'; +import { type SubmitHandler, useForm } from 'react-hook-form'; import { useNavigate } from 'react-router-dom'; import { z } from 'zod'; import { shallow } from 'zustand/shallow'; diff --git a/web/src/pages/passwordReset/steps/PasswordStep/PasswordStep.tsx b/web/src/pages/passwordReset/steps/PasswordStep/PasswordStep.tsx index 15fc3d7..d4751ac 100644 --- a/web/src/pages/passwordReset/steps/PasswordStep/PasswordStep.tsx +++ b/web/src/pages/passwordReset/steps/PasswordStep/PasswordStep.tsx @@ -1,8 +1,8 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { useMutation } from '@tanstack/react-query'; -import { AxiosError } from 'axios'; +import type { AxiosError } from 'axios'; import { useMemo, useRef } from 'react'; -import { SubmitHandler, useForm } from 'react-hook-form'; +import { type SubmitHandler, useForm } from 'react-hook-form'; import { z } from 'zod'; import { shallow } from 'zustand/shallow'; diff --git a/web/src/pages/passwordReset/style.scss b/web/src/pages/passwordReset/style.scss index af2a504..efb60e7 100644 --- a/web/src/pages/passwordReset/style.scss +++ b/web/src/pages/passwordReset/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #password-reset { @include media-breakpoint-up(lg) { padding: 100px 50px; @@ -11,6 +9,7 @@ & > .logo-container { display: none; + @include media-breakpoint-up(lg) { display: flex; margin-bottom: 100px; @@ -41,12 +40,14 @@ .arrow-single { height: 36px; width: 36px; + svg { g { fill: var(--surface-icon-primary); } } } + &.variant-primary { .arrow-single { svg { @@ -76,11 +77,14 @@ margin-bottom: 35px; color: var(--text-body-primary); } + & > .message-box { width: 100%; } + & > form { width: 100%; + & > * { width: 100%; } diff --git a/web/src/pages/sessionTimeout/style.scss b/web/src/pages/sessionTimeout/style.scss index 4d21dab..1996733 100644 --- a/web/src/pages/sessionTimeout/style.scss +++ b/web/src/pages/sessionTimeout/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #session-timeout { & > .logo-container { display: none; diff --git a/web/src/pages/token/components/TokenCard.tsx b/web/src/pages/token/components/TokenCard.tsx index 2787bfc..7f074c3 100644 --- a/web/src/pages/token/components/TokenCard.tsx +++ b/web/src/pages/token/components/TokenCard.tsx @@ -4,7 +4,7 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { useMutation, useQuery } from '@tanstack/react-query'; import dayjs from 'dayjs'; import { useMemo } from 'react'; -import { SubmitHandler, useForm } from 'react-hook-form'; +import { type SubmitHandler, useForm } from 'react-hook-form'; import { useNavigate } from 'react-router-dom'; import { useBreakpoint } from 'use-breakpoint'; import { z } from 'zod'; @@ -123,60 +123,58 @@ export const TokenCard = () => { } return ( - <> - -

{LL.pages.token.card.title()}

- -
- - - {openidData?.url && ( - <> -

{LL.pages.token.card.oidc.title()}

- -
- -
- - )} -
-
-
- + +

{LL.pages.token.card.title()}

+ +
+ + + {openidData?.url && ( + <> +

{LL.pages.token.card.oidc.title()}

+ +
+ +
+ + )} +
+
+
); }; diff --git a/web/src/pages/token/components/style.scss b/web/src/pages/token/components/style.scss index 1f78224..28c665e 100644 --- a/web/src/pages/token/components/style.scss +++ b/web/src/pages/token/components/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #token-page { .token-card { box-sizing: border-box; diff --git a/web/src/pages/token/style.scss b/web/src/pages/token/style.scss index 03ad499..b979bb8 100644 --- a/web/src/pages/token/style.scss +++ b/web/src/pages/token/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #token-page { @include media-breakpoint-up(lg) { padding: 100px 50px; @@ -12,6 +10,7 @@ & > .logo-container { display: none; margin-bottom: 30px; + @include media-breakpoint-up(lg) { display: flex; margin-bottom: 100px; @@ -36,12 +35,14 @@ .arrow-single { height: 36px; width: 36px; + svg { g { fill: var(--surface-icon-primary); } } } + &.variant-primary { .arrow-single { svg { diff --git a/web/src/shared/components/Form/FormDevTools/FormDevTools.tsx b/web/src/shared/components/Form/FormDevTools/FormDevTools.tsx deleted file mode 100644 index 56ffa63..0000000 --- a/web/src/shared/components/Form/FormDevTools/FormDevTools.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import './style.scss'; - -import { DevTool } from '@hookform/devtools'; -import ReactDOM from 'react-dom'; -import { Control } from 'react-hook-form'; - -interface Props { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - control: Control; -} - -export const DevTools: React.FC = ({ control }) => { - const element = document.querySelector('#root'); - if (!element) return null; - return ReactDOM.createPortal( -
- -
, - element, - ); -}; diff --git a/web/src/shared/components/Form/FormDevTools/style.scss b/web/src/shared/components/Form/FormDevTools/style.scss deleted file mode 100644 index 024f244..0000000 --- a/web/src/shared/components/Form/FormDevTools/style.scss +++ /dev/null @@ -1,23 +0,0 @@ -@use '../../../scss/base/variables/' as v; - -.dev-tools { - & > div { - z-index: 999999999999999999; - } - - p { - color: v.$white; - } - - td { - color: v.$white; - } - - code { - color: v.$white; - } -} - -.ReactQueryDevtools { - color: v.$white; -} diff --git a/web/src/shared/components/Form/FormInput/FormInput.tsx b/web/src/shared/components/Form/FormInput/FormInput.tsx index d001388..f7f6ff9 100644 --- a/web/src/shared/components/Form/FormInput/FormInput.tsx +++ b/web/src/shared/components/Form/FormInput/FormInput.tsx @@ -1,9 +1,13 @@ import { isUndefined } from 'lodash-es'; import { useMemo } from 'react'; -import { FieldValues, useController, UseControllerProps } from 'react-hook-form'; +import { + type FieldValues, + type UseControllerProps, + useController, +} from 'react-hook-form'; import { Input } from '../../layout/Input/Input'; -import { InputFloatingErrors, InputProps } from '../../layout/Input/types'; +import type { InputFloatingErrors, InputProps } from '../../layout/Input/types'; interface Props extends Omit { controller: UseControllerProps; @@ -34,7 +38,7 @@ export const FormInput = ({ }, [error, isDirty, isSubmitted, isTouched]); const floatingErrorsData = useMemo((): InputFloatingErrors | undefined => { - if (floatingErrors && floatingErrors.title && error && error.types && isInvalid) { + if (floatingErrors?.title && error && error.types && isInvalid) { let errors: string[] = []; for (const val of Object.values(error.types)) { if (typeof val === 'string') { @@ -44,7 +48,7 @@ export const FormInput = ({ errors = [...errors, ...val]; } } - if (floatingErrors.errorMessages && floatingErrors.errorMessages.length) { + if (floatingErrors.errorMessages?.length) { errors = [...errors, ...floatingErrors.errorMessages]; } return { diff --git a/web/src/shared/components/Form/FormSelect/FormSelect.tsx b/web/src/shared/components/Form/FormSelect/FormSelect.tsx index a8234f8..45f5dbe 100644 --- a/web/src/shared/components/Form/FormSelect/FormSelect.tsx +++ b/web/src/shared/components/Form/FormSelect/FormSelect.tsx @@ -1,20 +1,19 @@ import { isUndefined } from 'lodash-es'; import { useMemo } from 'react'; -import { FieldValues, useController, UseControllerProps } from 'react-hook-form'; - import { - Select, - SelectOption, - SelectProps, - SelectValue, -} from '../../layout/Select/Select'; + type FieldValues, + type UseControllerProps, + useController, +} from 'react-hook-form'; + +import { Select } from '../../layout/Select/Select'; +import type { SelectProps } from '../../layout/Select/types'; -interface Props - extends Omit, 'onChange'> { +interface Props extends SelectProps { controller: UseControllerProps; } -export const FormSelect = ({ +export const FormSelect = ({ controller, ...rest }: Props) => { @@ -34,20 +33,15 @@ export const FormSelect = ({ return false; }, [error, isDirty, isSubmitted, isTouched]); - const isValid = useMemo( - () => !isInvalid && (isTouched || isDirty || isSubmitted), - [isDirty, isInvalid, isSubmitted, isTouched], - ); - return ( { )} {!networksAvailable && ( - + )} ); diff --git a/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/style.scss b/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/style.scss index d785fd0..46c6450 100644 --- a/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/style.scss +++ b/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/style.scss @@ -1,5 +1,5 @@ #configure-device-card { - .message-box { + .message-box-old { margin-bottom: 20px; } diff --git a/web/src/pages/enrollment/steps/DeviceStep/components/QuickGuideCard/QuickGuideCard.tsx b/web/src/pages/enrollment/steps/DeviceStep/components/QuickGuideCard/QuickGuideCard.tsx index 3bc1752..9e55212 100644 --- a/web/src/pages/enrollment/steps/DeviceStep/components/QuickGuideCard/QuickGuideCard.tsx +++ b/web/src/pages/enrollment/steps/DeviceStep/components/QuickGuideCard/QuickGuideCard.tsx @@ -9,7 +9,7 @@ import { ButtonStyleVariant, } from '../../../../../../shared/components/layout/Button/types'; import { Card } from '../../../../../../shared/components/layout/Card/Card'; -import { MessageBox } from '../../../../../../shared/components/layout/MessageBox/MessageBox'; +import { MessageBoxOld } from '../../../../../../shared/components/layout/MessageBox/MessageBoxOld'; export const QuickGuideCard = () => { const { LL } = useI18nContext(); @@ -19,7 +19,7 @@ export const QuickGuideCard = () => { return (

{cardLL.title()}

- +

{cardLL.steps.wireguard.content()}

diff --git a/web/src/pages/enrollment/steps/DeviceStep/components/QuickGuideCard/style.scss b/web/src/pages/enrollment/steps/DeviceStep/components/QuickGuideCard/style.scss index 9b38196..0a5b3b1 100644 --- a/web/src/pages/enrollment/steps/DeviceStep/components/QuickGuideCard/style.scss +++ b/web/src/pages/enrollment/steps/DeviceStep/components/QuickGuideCard/style.scss @@ -9,7 +9,7 @@ margin-bottom: 20px; } - & > .message-box { + & > .message-box-old { margin-bottom: 10px; } diff --git a/web/src/pages/enrollment/steps/DeviceStep/style.scss b/web/src/pages/enrollment/steps/DeviceStep/style.scss index 7e9f171..b7b8a72 100644 --- a/web/src/pages/enrollment/steps/DeviceStep/style.scss +++ b/web/src/pages/enrollment/steps/DeviceStep/style.scss @@ -8,7 +8,7 @@ padding: 0 25px 0 25px; } - & > .message-box { + & > .message-box-old { margin-bottom: 25px; .message { diff --git a/web/src/pages/main/style.scss b/web/src/pages/main/style.scss index 7a45a6e..aca7c3e 100644 --- a/web/src/pages/main/style.scss +++ b/web/src/pages/main/style.scss @@ -28,7 +28,7 @@ width: auto; } - .message-box { + .message-box-old { margin-bottom: 20px; } diff --git a/web/src/pages/openidCallback/components/OpenIDCallbackCard.tsx b/web/src/pages/openidCallback/components/OpenIDCallbackCard.tsx index fc70c4f..7c79510 100644 --- a/web/src/pages/openidCallback/components/OpenIDCallbackCard.tsx +++ b/web/src/pages/openidCallback/components/OpenIDCallbackCard.tsx @@ -2,24 +2,27 @@ import './style.scss'; import { useQuery } from '@tanstack/react-query'; import type { AxiosError } from 'axios'; -import parse from 'html-react-parser'; -import { useState } from 'react'; +import { useMemo, useState } from 'react'; +import QRCode from 'react-qr-code'; import { useBreakpoint } from 'use-breakpoint'; - import { useI18nContext } from '../../../i18n/i18n-react'; -import { ActionButton } from '../../../shared/components/layout/ActionButton/ActionButton'; -import { ActionButtonVariant } from '../../../shared/components/layout/ActionButton/types'; import { BigInfoBox } from '../../../shared/components/layout/BigInfoBox/BigInfoBox'; import { Button } from '../../../shared/components/layout/Button/Button'; -import { ButtonStyleVariant } from '../../../shared/components/layout/Button/types'; +import { + ButtonSize, + ButtonStyleVariant, +} from '../../../shared/components/layout/Button/types'; import { Card } from '../../../shared/components/layout/Card/Card'; -import { Input } from '../../../shared/components/layout/Input/Input'; import { LoaderSpinner } from '../../../shared/components/layout/LoaderSpinner/LoaderSpinner'; -import { MessageBox } from '../../../shared/components/layout/MessageBox/MessageBox'; import { MessageBoxType } from '../../../shared/components/layout/MessageBox/types'; -import SvgIconDownload from '../../../shared/components/svg/IconDownload'; import { deviceBreakpoints } from '../../../shared/constants'; +import { CopyField } from '../../../shared/defguard-ui/components/Layout/CopyField/CopyField'; +import { MessageBox } from '../../../shared/defguard-ui/components/Layout/MessageBox/MessageBox'; +import { MessageBoxStyleVariant } from '../../../shared/defguard-ui/components/Layout/MessageBox/types'; +import { useToaster } from '../../../shared/defguard-ui/hooks/toasts/useToaster'; +import { isPresent } from '../../../shared/defguard-ui/utils/isPresent'; import { useApi } from '../../../shared/hooks/api/useApi'; +import { useClipboard } from '../../../shared/hooks/useClipboard'; type ErrorResponse = { error: string; @@ -30,6 +33,8 @@ export const OpenIDCallbackCard = () => { const { breakpoint } = useBreakpoint(deviceBreakpoints); const { LL } = useI18nContext(); const [error, setError] = useState(null); + const { writeToClipboard } = useClipboard(); + const toaster = useToaster(); const { isLoading, data } = useQuery( [], @@ -78,6 +83,18 @@ export const OpenIDCallbackCard = () => { }, ); + const qrData = useMemo(() => { + if (data) { + return btoa( + JSON.stringify({ + url: data.url, + token: data.token, + }), + ); + } + return undefined; + }, [data]); + if (isLoading) { return (
@@ -107,8 +124,247 @@ export const OpenIDCallbackCard = () => { return (

{LL.pages.oidcLogin.card.title()}

+

+ Please enter the provided Instance URL and Token into your Defguard Client. You + can scan the QR code or copy and paste the token manually. +

-
+ + {isPresent(data) && ( + <> + + + + )} + {isPresent(qrData) && ( +
+
+ +
+
+ )} +
+

+ Scan the QR code with your installed Defguard app. If you haven't installed it + yet, use your device's app store or the link below. +

+
+
+ {/*

1. {LL.pages.oidcLogin.card.steps.first()}

@@ -144,8 +401,9 @@ export const OpenIDCallbackCard = () => { { - // This should never be undefined, but just in case - navigator.clipboard.writeText(data?.token || ''); + if (data) { + writeToClipboard(data.token); + } }} />
@@ -157,7 +415,7 @@ export const OpenIDCallbackCard = () => { disabled={true} /> -
+
*/} ); }; diff --git a/web/src/pages/openidCallback/components/style.scss b/web/src/pages/openidCallback/components/style.scss index 06aaacb..309025e 100644 --- a/web/src/pages/openidCallback/components/style.scss +++ b/web/src/pages/openidCallback/components/style.scss @@ -1,11 +1,15 @@ #openidcallback-page { .openidcallback-card { box-sizing: border-box; - padding: 50px 40px; + padding: var(--spacing-m) var(--spacing-s); width: 100%; display: flex; flex-direction: column; - gap: 20px; + gap: var(--spacing-m); + + @include media-breakpoint-up(lg) { + padding: var(--spacing-l) var(--spacing-m); + } .steps { display: flex; @@ -17,7 +21,7 @@ } p { - @include typography(openidcallback-steps); + @include typography(app-body-2); color: var(--text-body-primary); } @@ -32,7 +36,7 @@ width: 334px; span { - @include typography(client-download-button); + @include typography(app-button-l); } svg { @@ -58,7 +62,7 @@ width: 198px; span { - @include typography(client-download-button); + @include typography(app-button-l); } } @@ -95,6 +99,40 @@ margin-bottom: 15px; text-align: left; } + + h3 { + @include typography(app-body-2); + } + + .row { + display: flex; + flex-flow: row wrap; + align-items: center; + justify-content: center; + box-sizing: border-box; + padding: 0 var(--spacing-s); + column-gap: var(--spacing-s); + + a { + display: flex; + text-decoration: none; + + .btn { + text-decoration: none; + } + } + } + + .qr { + padding: var(--spacing-m) 0; + } + + .qr-description { + color: var(--text-body-tertiary); + text-align: center; + max-width: 485px; + @include typography(app-input); + } } .loader-container { diff --git a/web/src/pages/passwordReset/steps/CodeStep/CodeStep.tsx b/web/src/pages/passwordReset/steps/CodeStep/CodeStep.tsx index 4ac735c..d841d7d 100644 --- a/web/src/pages/passwordReset/steps/CodeStep/CodeStep.tsx +++ b/web/src/pages/passwordReset/steps/CodeStep/CodeStep.tsx @@ -15,7 +15,7 @@ import { ButtonStyleVariant, } from '../../../../shared/components/layout/Button/types'; import { Card } from '../../../../shared/components/layout/Card/Card'; -import { MessageBox } from '../../../../shared/components/layout/MessageBox/MessageBox'; +import { MessageBoxOld } from '../../../../shared/components/layout/MessageBox/MessageBoxOld'; import { MessageBoxType } from '../../../../shared/components/layout/MessageBox/types'; type FormFields = { @@ -64,7 +64,7 @@ export const CodeStep = () => {

{LL.pages.resetPassword.steps.securityCode.title()}

- { />
- diff --git a/web/src/pages/passwordReset/steps/LinkSentStep/LinkSentStep.tsx b/web/src/pages/passwordReset/steps/LinkSentStep/LinkSentStep.tsx index d49ac1a..a625d85 100644 --- a/web/src/pages/passwordReset/steps/LinkSentStep/LinkSentStep.tsx +++ b/web/src/pages/passwordReset/steps/LinkSentStep/LinkSentStep.tsx @@ -15,7 +15,7 @@ import { ButtonStyleVariant, } from '../../../../shared/components/layout/Button/types'; import { Card } from '../../../../shared/components/layout/Card/Card'; -import { MessageBox } from '../../../../shared/components/layout/MessageBox/MessageBox'; +import { MessageBoxOld } from '../../../../shared/components/layout/MessageBox/MessageBoxOld'; import { MessageBoxType } from '../../../../shared/components/layout/MessageBox/types'; import { routes } from '../../../../shared/routes'; import { usePasswordResetStore } from '../../hooks/usePasswordResetStore'; @@ -45,7 +45,7 @@ export const LinkSentStep = () => { />
- diff --git a/web/src/pages/passwordReset/steps/SuccessStep/SuccessStep.tsx b/web/src/pages/passwordReset/steps/SuccessStep/SuccessStep.tsx index 86e0d8f..6be8f73 100644 --- a/web/src/pages/passwordReset/steps/SuccessStep/SuccessStep.tsx +++ b/web/src/pages/passwordReset/steps/SuccessStep/SuccessStep.tsx @@ -15,7 +15,7 @@ import { ButtonStyleVariant, } from '../../../../shared/components/layout/Button/types'; import { Card } from '../../../../shared/components/layout/Card/Card'; -import { MessageBox } from '../../../../shared/components/layout/MessageBox/MessageBox'; +import { MessageBoxOld } from '../../../../shared/components/layout/MessageBox/MessageBoxOld'; import { MessageBoxType } from '../../../../shared/components/layout/MessageBox/types'; import { routes } from '../../../../shared/routes'; import { usePasswordResetStore } from '../../hooks/usePasswordResetStore'; @@ -45,7 +45,7 @@ export const SuccessStep = () => { /> - diff --git a/web/src/pages/passwordReset/style.scss b/web/src/pages/passwordReset/style.scss index efb60e7..9ed8f44 100644 --- a/web/src/pages/passwordReset/style.scss +++ b/web/src/pages/passwordReset/style.scss @@ -78,7 +78,7 @@ color: var(--text-body-primary); } - & > .message-box { + & > .message-box-old { width: 100%; } diff --git a/web/src/shared/components/layout/MessageBox/MessageBox.tsx b/web/src/shared/components/layout/MessageBox/MessageBoxOld.tsx similarity index 95% rename from web/src/shared/components/layout/MessageBox/MessageBox.tsx rename to web/src/shared/components/layout/MessageBox/MessageBoxOld.tsx index bb36942..92083b0 100644 --- a/web/src/shared/components/layout/MessageBox/MessageBox.tsx +++ b/web/src/shared/components/layout/MessageBox/MessageBoxOld.tsx @@ -26,7 +26,7 @@ interface Props extends ComponentPropsWithoutRef<'div'> { /** * Styled box with message. */ -export const MessageBox = ({ +export const MessageBoxOld = ({ message, className, dismissId, @@ -38,7 +38,7 @@ export const MessageBox = ({ const dismissible = !isUndefined(dismissId); const getClassName = useMemo(() => { - return classNames('message-box', className, type.valueOf()); + return classNames('message-box-old', className, type.valueOf()); }, [className, type]); const getIcon = useMemo(() => { diff --git a/web/src/shared/components/layout/MessageBox/style.scss b/web/src/shared/components/layout/MessageBox/style.scss index d684d70..702d901 100644 --- a/web/src/shared/components/layout/MessageBox/style.scss +++ b/web/src/shared/components/layout/MessageBox/style.scss @@ -1,4 +1,4 @@ -.message-box { +.message-box-old { height: auto; min-height: 57px; width: 100%; @@ -47,6 +47,7 @@ .message { box-sizing: border-box; padding: 17px 0; + p, span, b, @@ -80,6 +81,7 @@ & > circle { fill: var(--surface-positive-primary); } + & > g { & > rect { fill: var(--surface-positive-accent); @@ -92,14 +94,17 @@ &.warning { background-color: var(--surface-important-accent); + .message { color: var(--text-important); } + .icon-container { & > svg { & > circle { fill: var(--surface-important); } + & > rect { fill: var(--surface-important-accent); } @@ -109,6 +114,7 @@ &.error { background-color: var(--surface-alert-accent); + .message { color: var(--text-alert); } @@ -119,6 +125,7 @@ & > circle { fill: var(--surface-alert-primary); } + & > path { fill: var(--surface-alert-accent); } @@ -129,15 +136,18 @@ &.info { background-color: var(--surface-info-modal); + .message { color: var(--text-body-secondary); } + & > .icon-container { & > svg { & > g { & > circle { fill: var(--surface-icon-primary); } + & > rect { fill: var(--surface-button); } diff --git a/web/src/shared/defguard-ui b/web/src/shared/defguard-ui index cad0546..920e920 160000 --- a/web/src/shared/defguard-ui +++ b/web/src/shared/defguard-ui @@ -1 +1 @@ -Subproject commit cad0546f8d1b448b12186103783635e4bff24da9 +Subproject commit 920e920da026faa9db54fe0cf77c8c70870abb3e diff --git a/web/src/shared/hooks/api/utils.ts b/web/src/shared/hooks/api/utils.ts index 0278cd0..fa8a162 100644 --- a/web/src/shared/hooks/api/utils.ts +++ b/web/src/shared/hooks/api/utils.ts @@ -1,5 +1,3 @@ -import { useEffect, useRef } from 'react'; - // biome-ignore lint/suspicious/noExplicitAny: Doesn't care about the type export const removeNulls = (obj: any) => { return JSON.parse(JSON.stringify(obj), (_, value) => { @@ -7,25 +5,3 @@ export const removeNulls = (obj: any) => { return value; }); }; - -/** -Under normal circumstances, useEffect should run only once when passed an empty dependency array. -However, in dev mode with react strict mode enabled, everything is rendered twice for debugging purposes. -This also causes useEffect to run twice, which is not always desirable. -This custom hook ensures that the effect runs only once in dev mode as well. -*/ - -// biome-ignore lint/suspicious/noConfusingVoidType: Should work like this -export default function useEffectOnce(fn: () => void | (() => void)) { - const isMounted = useRef(false); - useEffect(() => { - if (isMounted.current) { - return; - } - - const callback = fn(); - isMounted.current = true; - - return callback; - }, [fn]); -} diff --git a/web/src/shared/hooks/useClipboard.tsx b/web/src/shared/hooks/useClipboard.tsx new file mode 100644 index 0000000..964a8b4 --- /dev/null +++ b/web/src/shared/hooks/useClipboard.tsx @@ -0,0 +1,32 @@ +import { useCallback } from 'react'; + +import { useToaster } from '../defguard-ui/hooks/toasts/useToaster'; + +export const useClipboard = () => { + const toaster = useToaster(); + + const writeToClipboard = useCallback( + async (content: string, customMessage?: string) => { + if (window.isSecureContext) { + try { + await navigator.clipboard.writeText(content); + if (customMessage) { + toaster.success(customMessage); + } else { + toaster.success('Content copied to clipboard'); + } + } catch (e) { + toaster.error('Writing to clipboard failed !'); + console.error(e); + } + } else { + toaster.warning('Cannot access clipboard in insecure contexts'); + } + }, + [toaster], + ); + + return { + writeToClipboard, + }; +}; diff --git a/web/src/shared/scss/_base.scss b/web/src/shared/scss/_base.scss index 48ce86b..92774b7 100644 --- a/web/src/shared/scss/_base.scss +++ b/web/src/shared/scss/_base.scss @@ -68,4 +68,4 @@ strong { ol, ul { padding-inline-start: 30px; -} \ No newline at end of file +} diff --git a/web/src/shared/scss/index.scss b/web/src/shared/scss/index.scss index 7a834a7..8d5bd0f 100644 --- a/web/src/shared/scss/index.scss +++ b/web/src/shared/scss/index.scss @@ -1,2 +1,2 @@ @forward './base'; -@forward './effects'; \ No newline at end of file +@forward './effects'; From d317328f16b06c9338cba7b1b8c02229ec9240bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20=C5=9Al=C4=99zak?= Date: Thu, 24 Jul 2025 10:17:30 +0200 Subject: [PATCH 10/11] fix runs-on in gh workflow lint ui --- .github/workflows/lint-web.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint-web.yml b/.github/workflows/lint-web.yml index c5d0573..ca0db67 100644 --- a/.github/workflows/lint-web.yml +++ b/.github/workflows/lint-web.yml @@ -16,7 +16,7 @@ on: jobs: lint-web: - runs-on: self-hosted + runs-on: [self-hosted, Linux, X64] steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 From 6bd463f92183b106d04dd53058b557664d950de4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20=C5=9Al=C4=99zak?= Date: Thu, 24 Jul 2025 10:38:31 +0200 Subject: [PATCH 11/11] check text --- web/src/i18n/en/index.ts | 2 +- .../pages/openidCallback/components/OpenIDCallbackCard.tsx | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/web/src/i18n/en/index.ts b/web/src/i18n/en/index.ts index d35e242..a840cbb 100644 --- a/web/src/i18n/en/index.ts +++ b/web/src/i18n/en/index.ts @@ -166,7 +166,7 @@ If you have any questions, please consult your assigned admin.All necessary info steps: { wireguard: { content: - 'Download and install WireGuard client on your computer or app on phone.', + 'Download and install WireGuard client on your computer or app on a mobile device.', button: 'Download WireGuard', }, downloadConfig: 'Download provided configuration file to your device.', diff --git a/web/src/pages/openidCallback/components/OpenIDCallbackCard.tsx b/web/src/pages/openidCallback/components/OpenIDCallbackCard.tsx index 7c79510..7373633 100644 --- a/web/src/pages/openidCallback/components/OpenIDCallbackCard.tsx +++ b/web/src/pages/openidCallback/components/OpenIDCallbackCard.tsx @@ -18,7 +18,6 @@ import { MessageBoxType } from '../../../shared/components/layout/MessageBox/typ import { deviceBreakpoints } from '../../../shared/constants'; import { CopyField } from '../../../shared/defguard-ui/components/Layout/CopyField/CopyField'; import { MessageBox } from '../../../shared/defguard-ui/components/Layout/MessageBox/MessageBox'; -import { MessageBoxStyleVariant } from '../../../shared/defguard-ui/components/Layout/MessageBox/types'; import { useToaster } from '../../../shared/defguard-ui/hooks/toasts/useToaster'; import { isPresent } from '../../../shared/defguard-ui/utils/isPresent'; import { useApi } from '../../../shared/hooks/api/useApi'; @@ -124,15 +123,11 @@ export const OpenIDCallbackCard = () => { return (

{LL.pages.oidcLogin.card.title()}

+

Please enter the provided Instance URL and Token into your Defguard Client. You can scan the QR code or copy and paste the token manually.

- - {isPresent(data) && ( <>