diff --git a/package-lock.json b/package-lock.json
index dd6d6697..0d2f12f4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -125,6 +125,7 @@
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz",
"integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==",
"dev": true,
+ "peer": true,
"dependencies": {
"@ampproject/remapping": "^2.2.0",
"@babel/code-frame": "^7.24.7",
@@ -2346,6 +2347,7 @@
"integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"env-paths": "^2.2.1",
"import-fresh": "^3.3.0",
@@ -2688,6 +2690,7 @@
"resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz",
"integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@babel/runtime": "^7.18.3",
"@emotion/babel-plugin": "^11.13.5",
@@ -2731,6 +2734,7 @@
"resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.1.tgz",
"integrity": "sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@babel/runtime": "^7.18.3",
"@emotion/babel-plugin": "^11.13.5",
@@ -3853,6 +3857,7 @@
"resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-7.1.2.tgz",
"integrity": "sha512-slqJByDub7Y1UcokrM17BoMBMvn8n7daXFXVoTv0MEH5k3sHjmsH8ql/Mt3s9vQ20cORDr83UZ448TEGcbrXtw==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@babel/runtime": "^7.27.1"
},
@@ -3879,6 +3884,7 @@
"resolved": "https://registry.npmjs.org/@mui/material/-/material-7.1.2.tgz",
"integrity": "sha512-Z5PYKkA6Kd8vS04zKxJNpwuvt6IoMwqpbidV7RCrRQQKwczIwcNcS8L6GnN4pzFYfEs+N9v6co27DmG07rcnoA==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@babel/runtime": "^7.27.1",
"@mui/core-downloads-tracker": "^7.1.2",
@@ -3995,6 +4001,7 @@
"resolved": "https://registry.npmjs.org/@mui/system/-/system-7.1.1.tgz",
"integrity": "sha512-Kj1uhiqnj4Zo7PDjAOghtXJtNABunWvhcRU0O7RQJ7WOxeynoH6wXPcilphV8QTFtkKaip8EiNJRiCD+B3eROA==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@babel/runtime": "^7.27.1",
"@mui/private-theming": "^7.1.1",
@@ -4388,6 +4395,7 @@
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.1.0.tgz",
"integrity": "sha512-BDa2VAMLSh3otEiaMJ/3Y36GU4qf6GI+VivQ/P41NC6GHcdxpKlqV0ikSZ5gdQsmS3ojXeRx5vasgNTinF0Q4g==",
"dev": true,
+ "peer": true,
"dependencies": {
"@octokit/auth-token": "^4.0.0",
"@octokit/graphql": "^7.0.0",
@@ -4585,6 +4593,7 @@
"integrity": "sha512-Z4c23LHV0muZ8hfv4jw6HngPJkbbtZxTkxPNIg7cJcTc9C28N/p2q7g3JZS2SiKBBHJ3uM1dgDye66bB7LEk5w==",
"devOptional": true,
"license": "Apache-2.0",
+ "peer": true,
"dependencies": {
"playwright": "1.53.1"
},
@@ -4789,36 +4798,6 @@
}
}
},
- "node_modules/@release-it/conventional-changelog/node_modules/conventional-commits-filter": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-5.0.0.tgz",
- "integrity": "sha512-tQMagCOC59EVgNZcC5zl7XqO30Wki9i9J3acbUvkaosCT6JX3EeFwJD7Qqp4MCikRnzS18WXV3BLIQ66ytu6+Q==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@release-it/conventional-changelog/node_modules/conventional-commits-parser": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-6.0.0.tgz",
- "integrity": "sha512-TbsINLp48XeMXR8EvGjTnKGsZqBemisPoyWESlpRyR8lif0lcwzqz+NMtYSj1ooF/WYjSuu7wX0CtdeeMEQAmA==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "peer": true,
- "dependencies": {
- "meow": "^13.0.0"
- },
- "bin": {
- "conventional-commits-parser": "dist/cli/index.js"
- },
- "engines": {
- "node": ">=18"
- }
- },
"node_modules/@release-it/conventional-changelog/node_modules/git-semver-tags": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-8.0.0.tgz",
@@ -4853,8 +4832,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@remirror/core-constants/-/core-constants-3.0.0.tgz",
"integrity": "sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==",
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/@rtsao/scc": {
"version": "1.1.0",
@@ -5768,6 +5746,7 @@
"resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.80.7.tgz",
"integrity": "sha512-u2F0VK6+anItoEvB3+rfvTO9GEh2vb00Je05OwlUe/A0lkJBgW1HckiY3f9YZa+jx6IOe4dHPh10dyp9aY3iRQ==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@tanstack/query-core": "5.80.7"
},
@@ -5802,6 +5781,7 @@
"integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@babel/code-frame": "^7.10.4",
"@babel/runtime": "^7.12.5",
@@ -5890,7 +5870,6 @@
"resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.12.0.tgz",
"integrity": "sha512-DYijoE0igV0Oi+ZppFsp2UrQsM/4HZtmmpD78BJM9zfCbd1YvAUIxmzmXr8uqU18OHd1uQy+/zvuNoUNYyw67g==",
"license": "MIT",
- "peer": true,
"dependencies": {
"tippy.js": "^6.3.7"
},
@@ -5908,7 +5887,6 @@
"resolved": "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-2.12.0.tgz",
"integrity": "sha512-BYpyZx/56KCDksWuJJbhki/uNgt9sACuSSZFH5AN1yS1ISD+EzIxqf6Pzzv8QCoNJ+KcRNVaZsOlOFaJGoyzag==",
"license": "MIT",
- "peer": true,
"dependencies": {
"tippy.js": "^6.3.7"
},
@@ -6148,15 +6126,13 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz",
"integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==",
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/@types/markdown-it": {
"version": "14.1.2",
"resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz",
"integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==",
"license": "MIT",
- "peer": true,
"dependencies": {
"@types/linkify-it": "^5",
"@types/mdurl": "^2"
@@ -6166,8 +6142,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz",
"integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==",
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/@types/mdx": {
"version": "2.0.13",
@@ -6180,6 +6155,7 @@
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.1.tgz",
"integrity": "sha512-MX4Zioh39chHlDJbKmEgydJDS3tspMP/lnQC67G3SWsTnb9NeYVWOjkxpOSy4oMfPs4StcWHwBrvUb4ybfnuaw==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"undici-types": "~7.8.0"
}
@@ -6206,6 +6182,7 @@
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.8.tgz",
"integrity": "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"csstype": "^3.0.2"
}
@@ -6245,8 +6222,7 @@
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz",
"integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==",
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/@types/uuid": {
"version": "9.0.8",
@@ -6292,6 +6268,7 @@
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz",
"integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==",
"license": "BSD-2-Clause",
+ "peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "7.18.0",
"@typescript-eslint/types": "7.18.0",
@@ -6710,6 +6687,7 @@
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
"integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
"license": "MIT",
+ "peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -6793,6 +6771,7 @@
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
@@ -7885,6 +7864,7 @@
"url": "https://github.com/sponsors/ai"
}
],
+ "peer": true,
"dependencies": {
"caniuse-lite": "^1.0.30001629",
"electron-to-chromium": "^1.4.796",
@@ -8912,8 +8892,7 @@
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz",
"integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==",
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/cross-spawn": {
"version": "7.0.3",
@@ -9217,6 +9196,7 @@
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz",
"integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==",
+ "peer": true,
"funding": {
"type": "github",
"url": "https://github.com/sponsors/kossnocorp"
@@ -9671,7 +9651,6 @@
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
- "peer": true,
"engines": {
"node": ">=0.12"
},
@@ -9877,6 +9856,7 @@
"dev": true,
"hasInstallScript": true,
"license": "MIT",
+ "peer": true,
"bin": {
"esbuild": "bin/esbuild"
},
@@ -9994,6 +9974,7 @@
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz",
"integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
@@ -10077,6 +10058,7 @@
"integrity": "sha512-zc1UmCpNltmVY34vuLRV61r1K27sWuX39E+uyUnY8xS2Bex88VV9cugG+UZbRSRGtGyFboj+D8JODyme1plMpw==",
"dev": true,
"license": "MIT",
+ "peer": true,
"bin": {
"eslint-config-prettier": "bin/cli.js"
},
@@ -10159,6 +10141,7 @@
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz",
"integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@rtsao/scc": "^1.1.0",
"array-includes": "^3.1.8",
@@ -12010,6 +11993,7 @@
}
],
"license": "MIT",
+ "peer": true,
"dependencies": {
"@babel/runtime": "^7.27.1"
},
@@ -13230,7 +13214,6 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz",
"integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==",
- "peer": true,
"dependencies": {
"uc.micro": "^2.0.0"
}
@@ -13498,7 +13481,6 @@
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz",
"integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==",
"license": "MIT",
- "peer": true,
"dependencies": {
"argparse": "^2.0.1",
"entities": "^4.4.0",
@@ -13535,8 +13517,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
"integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==",
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/memfs": {
"version": "3.5.3",
@@ -14874,8 +14855,7 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz",
"integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==",
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/os-browserify": {
"version": "0.3.0",
@@ -15366,6 +15346,7 @@
"url": "https://github.com/sponsors/ai"
}
],
+ "peer": true,
"dependencies": {
"nanoid": "^3.3.6",
"picocolors": "^1.0.0",
@@ -15541,6 +15522,7 @@
"integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==",
"dev": true,
"license": "MIT",
+ "peer": true,
"bin": {
"prettier": "bin/prettier.cjs"
},
@@ -15640,7 +15622,6 @@
"resolved": "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.3.0.tgz",
"integrity": "sha512-8wRKhlEwEJ4I13Ju54q2NZR1pVKGTgJ/8XsQ8L5A5uUsQ/YQScQJuEAuh8Bn8i6IwAMjjLRABd9lVli+DlIiVw==",
"license": "MIT",
- "peer": true,
"dependencies": {
"prosemirror-transform": "^1.0.0"
}
@@ -15650,7 +15631,6 @@
"resolved": "https://registry.npmjs.org/prosemirror-collab/-/prosemirror-collab-1.3.1.tgz",
"integrity": "sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==",
"license": "MIT",
- "peer": true,
"dependencies": {
"prosemirror-state": "^1.0.0"
}
@@ -15660,7 +15640,6 @@
"resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.7.1.tgz",
"integrity": "sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==",
"license": "MIT",
- "peer": true,
"dependencies": {
"prosemirror-model": "^1.0.0",
"prosemirror-state": "^1.0.0",
@@ -15672,7 +15651,6 @@
"resolved": "https://registry.npmjs.org/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.2.tgz",
"integrity": "sha512-CCk6Gyx9+Tt2sbYk5NK0nB1ukHi2ryaRgadV/LvyNuO3ena1payM2z6Cg0vO1ebK8cxbzo41ku2DE5Axj1Zuiw==",
"license": "MIT",
- "peer": true,
"dependencies": {
"prosemirror-state": "^1.0.0",
"prosemirror-transform": "^1.1.0",
@@ -15684,7 +15662,6 @@
"resolved": "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.3.2.tgz",
"integrity": "sha512-wtjswVBd2vaQRrnYZaBCbyDqr232Ed4p2QPtRIUK5FuqHYKGWkEwl08oQM4Tw7DOR0FsasARV5uJFvMZWxdNxQ==",
"license": "MIT",
- "peer": true,
"dependencies": {
"prosemirror-keymap": "^1.0.0",
"prosemirror-model": "^1.0.0",
@@ -15697,7 +15674,6 @@
"resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.4.1.tgz",
"integrity": "sha512-2JZD8z2JviJrboD9cPuX/Sv/1ChFng+xh2tChQ2X4bB2HeK+rra/bmJ3xGntCcjhOqIzSDG6Id7e8RJ9QPXLEQ==",
"license": "MIT",
- "peer": true,
"dependencies": {
"prosemirror-state": "^1.2.2",
"prosemirror-transform": "^1.0.0",
@@ -15710,7 +15686,6 @@
"resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.5.0.tgz",
"integrity": "sha512-K0xJRCmt+uSw7xesnHmcn72yBGTbY45vm8gXI4LZXbx2Z0jwh5aF9xrGQgrVPu0WbyFVFF3E/o9VhJYz6SQWnA==",
"license": "MIT",
- "peer": true,
"dependencies": {
"prosemirror-state": "^1.0.0",
"prosemirror-transform": "^1.0.0"
@@ -15721,7 +15696,6 @@
"resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.2.3.tgz",
"integrity": "sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==",
"license": "MIT",
- "peer": true,
"dependencies": {
"prosemirror-state": "^1.0.0",
"w3c-keyname": "^2.2.0"
@@ -15732,7 +15706,6 @@
"resolved": "https://registry.npmjs.org/prosemirror-markdown/-/prosemirror-markdown-1.13.2.tgz",
"integrity": "sha512-FPD9rHPdA9fqzNmIIDhhnYQ6WgNoSWX9StUZ8LEKapaXU9i6XgykaHKhp6XMyXlOWetmaFgGDS/nu/w9/vUc5g==",
"license": "MIT",
- "peer": true,
"dependencies": {
"@types/markdown-it": "^14.0.0",
"markdown-it": "^14.0.0",
@@ -15744,7 +15717,6 @@
"resolved": "https://registry.npmjs.org/prosemirror-menu/-/prosemirror-menu-1.2.5.tgz",
"integrity": "sha512-qwXzynnpBIeg1D7BAtjOusR+81xCp53j7iWu/IargiRZqRjGIlQuu1f3jFi+ehrHhWMLoyOQTSRx/IWZJqOYtQ==",
"license": "MIT",
- "peer": true,
"dependencies": {
"crelt": "^1.0.0",
"prosemirror-commands": "^1.0.0",
@@ -15767,7 +15739,6 @@
"resolved": "https://registry.npmjs.org/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.4.tgz",
"integrity": "sha512-ELxP4TlX3yr2v5rM7Sb70SqStq5NvI15c0j9j/gjsrO5vaw+fnnpovCLEGIcpeGfifkuqJwl4fon6b+KdrODYQ==",
"license": "MIT",
- "peer": true,
"dependencies": {
"prosemirror-model": "^1.25.0"
}
@@ -15777,7 +15748,6 @@
"resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.5.1.tgz",
"integrity": "sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==",
"license": "MIT",
- "peer": true,
"dependencies": {
"prosemirror-model": "^1.0.0",
"prosemirror-state": "^1.0.0",
@@ -15801,7 +15771,6 @@
"resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.7.1.tgz",
"integrity": "sha512-eRQ97Bf+i9Eby99QbyAiyov43iOKgWa7QCGly+lrDt7efZ1v8NWolhXiB43hSDGIXT1UXgbs4KJN3a06FGpr1Q==",
"license": "MIT",
- "peer": true,
"dependencies": {
"prosemirror-keymap": "^1.2.2",
"prosemirror-model": "^1.25.0",
@@ -15815,7 +15784,6 @@
"resolved": "https://registry.npmjs.org/prosemirror-trailing-node/-/prosemirror-trailing-node-3.0.0.tgz",
"integrity": "sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==",
"license": "MIT",
- "peer": true,
"dependencies": {
"@remirror/core-constants": "3.0.0",
"escape-string-regexp": "^4.0.0"
@@ -15831,7 +15799,6 @@
"resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.10.4.tgz",
"integrity": "sha512-pwDy22nAnGqNR1feOQKHxoFkkUtepoFAd3r2hbEDsnf4wp57kKA36hXsB3njA9FtONBEwSDnDeCiJe+ItD+ykw==",
"license": "MIT",
- "peer": true,
"dependencies": {
"prosemirror-model": "^1.21.0"
}
@@ -15928,7 +15895,6 @@
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
"integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==",
- "peer": true,
"engines": {
"node": ">=6"
}
@@ -16059,6 +16025,7 @@
"resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz",
"integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=0.10.0"
}
@@ -16126,6 +16093,7 @@
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz",
"integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"scheduler": "^0.26.0"
},
@@ -16155,6 +16123,7 @@
"resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.58.1.tgz",
"integrity": "sha512-Lml/KZYEEFfPhUVgE0RdCVpnC4yhW+PndRhbiTtdvSlQTL8IfVR+iQkBjLIvmmc6+GGoVeM11z37ktKFPAb0FA==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=18.0.0"
},
@@ -16202,6 +16171,7 @@
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",
"integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==",
"dev": true,
+ "peer": true,
"engines": {
"node": ">=0.10.0"
}
@@ -16689,6 +16659,7 @@
}
],
"license": "MIT",
+ "peer": true,
"dependencies": {
"@iarna/toml": "2.2.5",
"@octokit/rest": "20.1.1",
@@ -17094,8 +17065,7 @@
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz",
"integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==",
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/run-applescript": {
"version": "7.0.0",
@@ -17299,6 +17269,7 @@
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz",
"integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==",
"dev": true,
+ "peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.3",
"json-schema-traverse": "^1.0.0",
@@ -17776,6 +17747,7 @@
"integrity": "sha512-sVKbCj/OTx67jhmauhxc2dcr1P+yOgz/x3h0krwjyMgdc5Oubvxyg4NYDZmzAw+ym36g/lzH8N0Ccp4dwtdfxw==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@storybook/core": "8.6.14"
},
@@ -18321,7 +18293,6 @@
"resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz",
"integrity": "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==",
"license": "MIT",
- "peer": true,
"dependencies": {
"@popperjs/core": "^2.9.0"
}
@@ -18521,6 +18492,7 @@
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+ "peer": true,
"engines": {
"node": ">=10"
},
@@ -18613,6 +18585,7 @@
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
"license": "Apache-2.0",
+ "peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -18625,8 +18598,7 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
"integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==",
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/uglify-js": {
"version": "3.17.4",
@@ -18866,7 +18838,6 @@
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz",
"integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==",
"license": "MIT",
- "peer": true,
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
@@ -18937,8 +18908,7 @@
"version": "2.2.8",
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
"integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==",
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/watchpack": {
"version": "2.4.1",
@@ -18967,6 +18937,7 @@
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.92.1.tgz",
"integrity": "sha512-JECQ7IwJb+7fgUFBlrJzbyu3GEuNBcdqr1LD7IbSzwkSmIevTm8PF+wej3Oxuz/JFBUZ6O1o43zsPkwm1C4TmA==",
"dev": true,
+ "peer": true,
"dependencies": {
"@types/eslint-scope": "^3.7.3",
"@types/estree": "^1.0.5",
@@ -19042,6 +19013,7 @@
"resolved": "https://registry.npmjs.org/webpack-hot-middleware/-/webpack-hot-middleware-2.26.1.tgz",
"integrity": "sha512-khZGfAeJx6I8K9zKohEWWYN6KDlVw2DHownoe+6Vtwj1LP9WFgegXnVMSkZ/dBEBtXFwrkkydsaPFlB7f8wU2A==",
"dev": true,
+ "peer": true,
"dependencies": {
"ansi-html-community": "0.0.8",
"html-entities": "^2.1.0",
diff --git a/src/components/LanguageSwitcher.tsx b/src/components/LanguageSwitcher.tsx
new file mode 100644
index 00000000..b94998bc
--- /dev/null
+++ b/src/components/LanguageSwitcher.tsx
@@ -0,0 +1,61 @@
+"use client";
+
+import { usePathname, useRouter } from "next/navigation";
+import MenuItem from "@mui/material/MenuItem";
+import Select, { SelectChangeEvent } from "@mui/material/Select";
+
+const languages = [
+ { code: "en", label: "English" },
+ { code: "uk", label: "Українська" },
+];
+
+export default function LanguageSwitcher() {
+ const pathname = usePathname();
+ const router = useRouter();
+
+ const currentLang = pathname.split("/")[1] || "en";
+
+ const handleChange = (event: SelectChangeEvent) => {
+ const newLang = event.target.value;
+
+ // Якщо шлях взагалі порожній (наприклад, просто /), то додаємо мову
+ if (!pathname) {
+ router.push(`/${newLang}`);
+ return;
+ }
+
+ const pathSegments = pathname.split("/");
+ pathSegments[1] = newLang;
+ const newPath = pathSegments.join("/");
+
+ router.push(newPath);
+ };
+
+ return (
+
+ );
+}
diff --git a/src/components/app-bar.tsx b/src/components/app-bar.tsx
index 4c1e7e8e..bbcff3cd 100644
--- a/src/components/app-bar.tsx
+++ b/src/components/app-bar.tsx
@@ -20,6 +20,7 @@ import Link from "@/components/link";
import { RoleEnum } from "@/services/api/types/role";
import Divider from "@mui/material/Divider";
import ThemeSwitchButton from "@/components/switch-theme-button";
+import LanguageSwitcher from "@/components/LanguageSwitcher";
import { IS_SIGN_UP_ENABLED } from "@/services/auth/config";
function ResponsiveAppBar() {
@@ -193,10 +194,13 @@ function ResponsiveAppBar() {
+
{!isLoaded ? (
diff --git a/src/services/i18n/config.ts b/src/services/i18n/config.ts
index 070b15f0..2e9489d6 100644
--- a/src/services/i18n/config.ts
+++ b/src/services/i18n/config.ts
@@ -1,5 +1,5 @@
export const fallbackLanguage = "en" as const;
-export const languages = [fallbackLanguage] as const;
+export const languages = [fallbackLanguage, "uk"] as const;
export const defaultNamespace = "common";
export const cookieName = "i18next";
diff --git a/src/services/i18n/locales/uk/admin-panel-home.json b/src/services/i18n/locales/uk/admin-panel-home.json
new file mode 100644
index 00000000..e754e0d1
--- /dev/null
+++ b/src/services/i18n/locales/uk/admin-panel-home.json
@@ -0,0 +1,4 @@
+{
+ "title": "Панель адміністратора",
+ "description": "Ласкаво просимо до панелі адміністратора."
+}
\ No newline at end of file
diff --git a/src/services/i18n/locales/uk/admin-panel-roles.json b/src/services/i18n/locales/uk/admin-panel-roles.json
new file mode 100644
index 00000000..7fc47e35
--- /dev/null
+++ b/src/services/i18n/locales/uk/admin-panel-roles.json
@@ -0,0 +1,6 @@
+{
+ "role": {
+ "1": "Адміністратор",
+ "2": "Користувач"
+ }
+}
\ No newline at end of file
diff --git a/src/services/i18n/locales/uk/admin-panel-users-create.json b/src/services/i18n/locales/uk/admin-panel-users-create.json
new file mode 100644
index 00000000..2c3debf7
--- /dev/null
+++ b/src/services/i18n/locales/uk/admin-panel-users-create.json
@@ -0,0 +1,61 @@
+{
+ "title": "Створити користувача",
+ "actions": {
+ "submit": "Зберегти",
+ "cancel": "Скасувати"
+ },
+ "inputs": {
+ "email": {
+ "label": "Email",
+ "validation": {
+ "invalid": "Недійсний email",
+ "required": "Email є обов'язковим",
+ "server": {
+ "emailAlreadyExists": "Такий email вже існує"
+ }
+ }
+ },
+ "firstName": {
+ "label": "Ім'я",
+ "validation": {
+ "required": "Ім'я є обов'язковим"
+ }
+ },
+ "lastName": {
+ "label": "Прізвище",
+ "validation": {
+ "required": "Прізвище є обов'язковим"
+ }
+ },
+ "role": {
+ "label": "Роль",
+ "validation": {
+ "required": "Роль є обов'язковою"
+ },
+ "options": {
+ "1": "Адміністратор",
+ "2": "Користувач"
+ }
+ },
+ "password": {
+ "label": "Пароль",
+ "validation": {
+ "required": "Пароль є обов'язковим",
+ "min": "Пароль має містити щонайменше 6 символів"
+ }
+ },
+ "passwordConfirmation": {
+ "label": "Підтвердження пароля",
+ "validation": {
+ "required": "Підтвердження пароля є обов'язковим",
+ "match": "Підтвердження пароля має збігатися з паролем"
+ }
+ },
+ "": "Do not remove this property"
+ },
+ "alerts": {
+ "user": {
+ "success": "Профіль користувача успішно створено"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/services/i18n/locales/uk/admin-panel-users-edit.json b/src/services/i18n/locales/uk/admin-panel-users-edit.json
new file mode 100644
index 00000000..61b3a329
--- /dev/null
+++ b/src/services/i18n/locales/uk/admin-panel-users-edit.json
@@ -0,0 +1,65 @@
+{
+ "title1": "Редагувати користувача",
+ "title2": "Змінити пароль",
+ "actions": {
+ "submit": "Зберегти",
+ "cancel": "Скасувати"
+ },
+ "inputs": {
+ "email": {
+ "label": "Email",
+ "validation": {
+ "invalid": "Недійсний email",
+ "required": "Email є обов'язковим",
+ "server": {
+ "emailAlreadyExists": "Такий email вже існує"
+ }
+ }
+ },
+ "firstName": {
+ "label": "Ім'я",
+ "validation": {
+ "required": "Ім'я є обов'язковим"
+ }
+ },
+ "lastName": {
+ "label": "Прізвище",
+ "validation": {
+ "required": "Прізвище є обов'язковим"
+ }
+ },
+ "role": {
+ "label": "Роль",
+ "validation": {
+ "required": "Роль є обов'язковою"
+ },
+ "options": {
+ "1": "Адміністратор",
+ "2": "Користувач"
+ }
+ },
+ "password": {
+ "label": "Пароль",
+ "validation": {
+ "required": "Пароль є обов'язковим",
+ "min": "Пароль має містити щонайменше 6 символів"
+ }
+ },
+ "passwordConfirmation": {
+ "label": "Підтвердження пароля",
+ "validation": {
+ "required": "Підтвердження пароля є обов'язковим",
+ "match": "Підтвердження пароля має збігатися з паролем"
+ }
+ },
+ "": "Do not remove this property"
+ },
+ "alerts": {
+ "password": {
+ "success": "Пароль успішно оновлено"
+ },
+ "user": {
+ "success": "Профіль користувача успішно оновлено"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/services/i18n/locales/uk/admin-panel-users.json b/src/services/i18n/locales/uk/admin-panel-users.json
new file mode 100644
index 00000000..37f66458
--- /dev/null
+++ b/src/services/i18n/locales/uk/admin-panel-users.json
@@ -0,0 +1,36 @@
+{
+ "title": "Користувачі",
+ "table": {
+ "column1": "ID",
+ "column2": "Ім'я",
+ "column3": "Email",
+ "column4": "Роль"
+ },
+ "actions": {
+ "add": "Додати користувача",
+ "edit": "Редагувати",
+ "delete": "Видалити",
+ "create": "Створити користувача"
+ },
+ "confirm": {
+ "delete": {
+ "title": "Видалити користувача",
+ "message": "Ви впевнені, що хочете видалити цього користувача?"
+ }
+ },
+ "filter": {
+ "actions": {
+ "filter": "Фільтр",
+ "apply": "Застосувати"
+ },
+ "inputs": {
+ "role": {
+ "label": "Роль",
+ "options": {
+ "1": "Адміністратор",
+ "2": "Користувач"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/services/i18n/locales/uk/common.json b/src/services/i18n/locales/uk/common.json
new file mode 100644
index 00000000..df7ef228
--- /dev/null
+++ b/src/services/i18n/locales/uk/common.json
@@ -0,0 +1,40 @@
+{
+ "app-name": "ДОДАТОК",
+ "loading": "Завантаження...",
+ "navigation": {
+ "home": "Головна",
+ "signIn": "Увійти",
+ "signUp": "Зареєструватися",
+ "profile": "Профіль",
+ "users": "Користувачі",
+ "logout": "Вийти"
+ },
+ "formInputs": {
+ "avatarInput": {
+ "dropzoneText": "Перетягніть зображення сюди...",
+ "dragAndDrop": "Або перетягніть якесь зображення сюди",
+ "selectFile": "Виберіть зображення"
+ },
+ "multipleImageInput": {
+ "dropzoneText": "Перетягніть зображення сюди...",
+ "dragAndDrop": "Або перетягніть якісь зображення сюди",
+ "selectFile": "Виберіть зображення"
+ },
+ "singleImageInput": {
+ "dropzoneText": "Перетягніть зображення сюди...",
+ "dragAndDrop": "Або перетягніть якесь зображення сюди",
+ "selectFile": "Виберіть зображення"
+ }
+ },
+ "leavePage": {
+ "title": "Залишити цю сторінку?",
+ "message": "Зміни, які ви зробили, можуть бути не збережені",
+ "stay": "Залишитися на сторінці",
+ "leave": "Залишити сторінку"
+ },
+ "auth": {
+ "facebook": {
+ "action": "Увійти через Facebook"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/services/i18n/locales/uk/confirm-dialog.json b/src/services/i18n/locales/uk/confirm-dialog.json
new file mode 100644
index 00000000..63fcef8b
--- /dev/null
+++ b/src/services/i18n/locales/uk/confirm-dialog.json
@@ -0,0 +1,8 @@
+{
+ "title": "Підтвердження",
+ "message": "Ви впевнені, що хочете виконати цю дію?",
+ "actions": {
+ "yes": "Так",
+ "no": "Ні"
+ }
+}
\ No newline at end of file
diff --git a/src/services/i18n/locales/uk/confirm-email.json b/src/services/i18n/locales/uk/confirm-email.json
new file mode 100644
index 00000000..d4f15670
--- /dev/null
+++ b/src/services/i18n/locales/uk/confirm-email.json
@@ -0,0 +1,5 @@
+{
+ "title": "Підтвердження Email",
+ "emailConfirmed": "Email було успішно підтверджено!",
+ "emailConfirmFailed": "Не вдалося підтвердити Email!"
+}
\ No newline at end of file
diff --git a/src/services/i18n/locales/uk/confirm-new-email.json b/src/services/i18n/locales/uk/confirm-new-email.json
new file mode 100644
index 00000000..11001411
--- /dev/null
+++ b/src/services/i18n/locales/uk/confirm-new-email.json
@@ -0,0 +1,5 @@
+{
+ "title": "Підтвердження нового Email",
+ "emailConfirmed": "Email було змінено!",
+ "emailConfirmFailed": "Не вдалося змінити адресу електронної пошти!"
+}
\ No newline at end of file
diff --git a/src/services/i18n/locales/uk/forgot-password.json b/src/services/i18n/locales/uk/forgot-password.json
new file mode 100644
index 00000000..0980b5db
--- /dev/null
+++ b/src/services/i18n/locales/uk/forgot-password.json
@@ -0,0 +1,21 @@
+{
+ "title": "Забули пароль",
+ "actions": {
+ "submit": "Надіслати посилання для скидання"
+ },
+ "inputs": {
+ "email": {
+ "label": "Email",
+ "validation": {
+ "required": "Email є обов'язковим",
+ "invalid": "Недійсний формат email",
+ "server": {
+ "emailNotExists": "Користувача з таким email не існує"
+ }
+ }
+ }
+ },
+ "alerts": {
+ "success": "Посилання для скидання пароля надіслано на ваш email"
+ }
+}
\ No newline at end of file
diff --git a/src/services/i18n/locales/uk/home.json b/src/services/i18n/locales/uk/home.json
new file mode 100644
index 00000000..b8d70f98
--- /dev/null
+++ b/src/services/i18n/locales/uk/home.json
@@ -0,0 +1,4 @@
+{
+ "title": "Головна",
+ "description": "Ласкаво просимо до прикладу додатку reactjs-boilerplate. Повну документацію можна знайти <0>тут0>."
+}
\ No newline at end of file
diff --git a/src/services/i18n/locales/uk/password-change.json b/src/services/i18n/locales/uk/password-change.json
new file mode 100644
index 00000000..b4c155da
--- /dev/null
+++ b/src/services/i18n/locales/uk/password-change.json
@@ -0,0 +1,29 @@
+{
+ "title": "Зміна пароля",
+ "actions": {
+ "submit": "Встановити новий пароль"
+ },
+ "inputs": {
+ "password": {
+ "label": "Пароль",
+ "validation": {
+ "required": "Пароль є обов'язковим",
+ "min": "Пароль має містити щонайменше 6 символів",
+ "server": {
+ "incorrectPassword": "Недійсний пароль"
+ }
+ }
+ },
+ "passwordConfirmation": {
+ "label": "Підтвердження пароля",
+ "validation": {
+ "required": "Підтвердження пароля є обов'язковим",
+ "match": "Підтвердження пароля має збігатися з паролем"
+ }
+ }
+ },
+ "alerts": {
+ "success": "Пароль успішно скинуто",
+ "expired": "Термін дії посилання для скидання пароля закінчився"
+ }
+}
\ No newline at end of file
diff --git a/src/services/i18n/locales/uk/privacy-policy.json b/src/services/i18n/locales/uk/privacy-policy.json
new file mode 100644
index 00000000..d5e67436
--- /dev/null
+++ b/src/services/i18n/locales/uk/privacy-policy.json
@@ -0,0 +1,135 @@
+{
+ "title": "Політика конфіденційності",
+ "description-1": "Ця Політика конфіденційності описує Наші правила та процедури щодо збору, використання та розкриття Вашої інформації під час використання Вами Сервісу, а також розповідає Вам про Ваші права на конфіденційність та про те, як закон захищає Вас.",
+ "description-2": "Ми використовуємо Ваші Персональні дані для надання та покращення Сервісу. Використовуючи Сервіс, Ви погоджуєтеся на збір та використання інформації відповідно до цієї Політики конфіденційності.",
+ "lastUpdated": "Останнє оновлення: 16 травня 2024 р.",
+ "description1": "Це перший текст опису.",
+ "description2": "Це другий текст опису.",
+ "interpretation_and_definitions": "Тлумачення та Визначення",
+ "interpretation": "Тлумачення",
+ "interpretation_description": "Слова, початкова літера яких написана з великої літери, мають значення, визначені за наступних умов. Наведені нижче визначення мають однакове значення незалежно від того, чи вживаються вони в однині чи в множині.",
+ "definitions": "Визначення",
+ "definitions_description": "Для цілей цієї Політики конфіденційності:",
+ "account_title": "Акаунт ",
+ "account_description": "означає унікальний обліковий запис, створений для Вас для доступу до нашого Сервісу або його частин.",
+ "affiliate_title": "Афілійована особа ",
+ "affiliate_description": " означає організацію, яка контролює, контролюється або перебуває під спільним контролем зі стороною, де «контроль» означає володіння 50% або більше акцій, часток у капіталі або інших цінних паперів, що дають право голосу при обранні директорів або іншого органу управління.",
+ "company_title": "Компанія ",
+ "company_description": " (іменується «Компанія», «Ми», «Нас» або «Наш» у цій Угоді) відноситься до BC Boilerplates.",
+ "cookies_title": "Файли Cookie ",
+ "cookies_definition": "це невеликі файли, які розміщуються на Вашому комп'ютері, мобільному пристрої або будь-якому іншому пристрої веб-сайтом і містять деталі історії Ваших переглядів на цьому веб-сайті, серед багатьох інших цілей.",
+ "device_title": "Пристрій ",
+ "device_description": "означає будь-який пристрій, який може отримати доступ до Сервісу, наприклад комп'ютер, мобільний телефон або цифровий планшет.",
+ "personal_data_title": "Персональні дані ",
+ "personal_data_definition": "це будь-яка інформація, яка стосується ідентифікованої особи або особи, яку можна ідентифікувати.",
+ "service_title": "Сервіс ",
+ "service_description": "відноситься до Веб-сайту.",
+ "service_provider_title": "Постачальник послуг ",
+ "service_provider_description": "означає будь-яку фізичну або юридичну особу, яка обробляє дані від імені Компанії. Це стосується сторонніх компаній або осіб, найнятих Компанією для сприяння роботі Сервісу, надання Сервісу від імені Компанії, виконання послуг, пов'язаних із Сервісом, або надання допомоги Компанії в аналізі того, як використовується Сервіс.",
+ "usage_data_title": "Дані про використання ",
+ "usage_data_description": "відноситься до даних, які збираються автоматично, згенеровані під час використання Сервісу або самою інфраструктурою Сервісу (наприклад, тривалість відвідування сторінки).",
+ "website_title": "Веб-сайт ",
+ "website_description": "відноситься до Extensive React Boilerplate, доступного за адресою ",
+ "you_title": "Ви ",
+ "you_description": "означає особу, яка отримує доступ до Сервісу або використовує його, або компанію чи іншу юридичну особу, від імені якої така особа отримує доступ до Сервісу або використовує його.",
+ "collecting_and_using_personal_data": "Збір та Використання Ваших Персональних Даних",
+ "types_of_data_collected": "Типи зібраних даних",
+ "personal_data": "Персональні дані",
+ "personal_data_description": "Використовуючи Наш Сервіс, Ми можемо попросити Вас надати Нам певну особисту інформацію, за допомогою якої можна зв'язатися з Вами або ідентифікувати Вас. Особиста інформація може включати, але не обмежується:",
+ "usage_data": "Дані про використання",
+ "usage_data_auto_collected": "Дані про використання збираються автоматично під час використання Сервісу.",
+ "mobile_device_info_collection": "Коли Ви отримуєте доступ до Сервісу за допомогою мобільного пристрою або через нього, Ми можемо збирати певну інформацію автоматично, включаючи, але не обмежуючись: тип мобільного пристрою, який Ви використовуєте, унікальний ідентифікатор Вашого мобільного пристрою, IP-адресу Вашого мобільного пристрою, Вашу мобільну операційну систему, тип мобільного інтернет-браузера, унікальні ідентифікатори пристрою та інші діагностичні дані.",
+ "browser_info_collection": "Ми також можемо збирати інформацію, яку Ваш браузер надсилає щоразу, коли Ви відвідуєте наш Сервіс або коли Ви отримуєте доступ до Сервісу за допомогою мобільного пристрою.",
+ "tracking_technologies_and_cookies": "Технології відстеження та файли Cookie",
+ "tracking_technologies_and_cookies_description": "Ми використовуємо файли Cookie та подібні технології відстеження для відстеження активності в Нашому Сервісі та зберігання певної інформації. Використовуються такі технології відстеження, як маяки, теги та скрипти для збору та відстеження інформації, а також для покращення та аналізу Нашого Сервісу. Технології, які Ми використовуємо, можуть включати:",
+ "cookies_or_browser_cookies": "Файли Cookie або браузерні Cookie.",
+ "cookies_description": "Cookie — це невеликий файл, який розміщується на Вашому Пристрої. Ви можете налаштувати свій браузер так, щоб він відхиляв усі файли Cookie або вказував, коли надсилається файл Cookie. Однак, якщо Ви не приймаєте файли Cookie, Ви не зможете використовувати деякі частини нашого Сервісу. Якщо Ви не налаштували свій браузер на відхилення файлів Cookie, наш Сервіс може використовувати їх.",
+ "web_beacons": "Веб-маяки.",
+ "web_beacons_description": "Певні розділи нашого Сервісу та наші електронні листи можуть містити невеликі електронні файли, відомі як веб-маяки (також називаються clear gifs, піксельні теги та однопіксельні gifs), які дозволяють Компанії, наприклад, підраховувати користувачів, які відвідали ці сторінки або відкрили електронний лист, та для іншої пов'язаної статистики веб-сайту (наприклад, запис популярності певного розділу та перевірка цілісності системи та сервера).",
+ "cookies_paragraph": "Файли Cookie можуть бути «Постійними» або «Сеансовими». Постійні файли Cookie залишаються на Вашому персональному комп'ютері або мобільному пристрої, коли Ви перебуваєте в автономному режимі, тоді як Сеансові видаляються, як тільки Ви закриваєте веб-браузер.",
+ "purpose_of_cookies": "Ми використовуємо як Сеансові, так і Постійні файли Cookie для цілей, викладених нижче:",
+ "necessary_cookies_title": "Необхідні / Основні файли Cookie",
+ "session_cookies": "Тип: Сеансові файли Cookie",
+ "administered_by": "Адмініструються: Компанією",
+ "necessary_cookies_purpose": "Мета: Ці файли Cookie є важливими для надання Вам послуг, доступних через Веб-сайт, і дозволяють Вам використовувати деякі з його функцій. Вони допомагають аутентифікувати користувачів та запобігати шахрайському використанню облікових записів користувачів. Без цих файлів Cookie послуги, про які Ви просили, не можуть бути надані.",
+ "cookies_policy_title": "Політика використання файлів Cookie / Прийняття повідомлень",
+ "persistent_cookies": "Тип: Постійні файли Cookie",
+ "cookies_policy_purpose": "Мета: Ці файли Cookie визначають, чи користувачі погодилися на використання файлів Cookie на Веб-сайті.",
+ "functionality_cookies_title": "Функціональні файли Cookie",
+ "functionality_cookies_purpose": "Мета: Ці файли Cookie дозволяють нам запам'ятовувати вибір, який Ви робите під час використання Веб-сайту, наприклад, запам'ятовувати ваші дані для входу або мовні налаштування. Мета цих файлів Cookie — надати Вам більш персоналізований досвід та уникнути необхідності повторного введення ваших налаштувань.",
+ "cookies_policy_info": "Для отримання додаткової інформації про файли Cookie, які ми використовуємо, та вашого вибору щодо них, будь ласка, відвідайте нашу Політику щодо файлів Cookie або розділ Cookies нашої Політики конфіденційності.",
+ "use_of_personal_data": "Використання Ваших Персональних Даних",
+ "personal_data_purposes": "Компанія може використовувати Персональні дані для таких цілей:",
+ "provide_and_maintain_service": "Для надання та підтримки нашого Сервісу,",
+ "provide_and_maintain_service_desc": "включаючи моніторинг використання нашого Сервісу.",
+ "manage_account": "Для управління Вашим Акаунтом:",
+ "manage_account_desc": "для управління Вашою реєстрацією як користувача Сервісу. Персональні дані, які Ви надаєте, можуть дати Вам доступ до різних функцій Сервісу, які доступні Вам як зареєстрованому користувачеві.",
+ "performance_of_contract": "Для виконання контракту:",
+ "performance_of_contract_desc": "розробка, дотримання та укладення договору купівлі-продажу продуктів, предметів або послуг, які Ви придбали, або будь-якого іншого договору з Нами через Сервіс.",
+ "contact_you": "Для зв'язку з Вами:",
+ "contact_you_desc": "Щоб зв'язуватися з Вами за допомогою електронної пошти, телефонних дзвінків, SMS або інших еквівалентних форм електронного зв'язку, таких як push-сповіщення.",
+ "provide_news_and_offers": "Для надання Вам ",
+ "provide_news_and_offers_desc": "новин, спеціальних пропозицій та загальної інформації про інші товари, послуги та події, які ми пропонуємо.",
+ "manage_requests": "Для обробки Ваших запитів:",
+ "manage_requests_desc": "Для обслуговування та управління Вашими запитами до Нас.",
+ "business_transfers": "Для перекладу бізнесу:",
+ "business_transfers_desc": "Ми можемо використовувати Вашу інформацію для оцінки або проведення злиття, реструктуризації, реорганізації, розпуску або іншого продажу чи передачі активів.",
+ "other_purposes": "Або для інших цілей:",
+ "other_purposes_desc": "Ми можемо використовувати Вашу інформацію для інших цілей, таких як аналіз даних, виявлення тенденцій використання, визначення ефективності наших рекламних кампаній.",
+ "personal_data_sharing": "Ми можемо ділитися Вашою особистою інформацією в наступних ситуаціях:",
+ "with_service_providers": "З постачальниками послуг:",
+ "with_service_providers_desc": "Ми можемо ділитися Вашою інформацією з Постачальниками послуг для моніторингу та аналізу використання нашого Сервісу.",
+ "for_business_transfers": "Для передачі бізнесу:",
+ "for_business_transfers_desc": "Ми можемо поділитися Вашою інформацією під час переговорів про будь-яке злиття або продаж активів.",
+ "with_affiliates": "З афілійованими особами:",
+ "with_affiliates_desc": "Ми можемо ділитися Вашою інформацією з Нашими афілійованими особами, і в цьому випадку ми вимагатимемо від них дотримання цієї Політики.",
+ "with_business_partners": "З діловими партнерами:",
+ "with_business_partners_desc": "Ми можемо ділитися Вашою інформацією з Нашими діловими партнерами, щоб пропонувати Вам певні продукти або послуги.",
+ "with_other_users": "З іншими користувачами:",
+ "with_other_users_desc": "коли Ви ділитеся інформацією в публічних зонах з іншими користувачами.",
+ "with_consent": "За Вашою згодою:",
+ "with_consent_desc": "Ми можемо розкрити Вашу особисту інформацію для будь-яких інших цілей за Вашою згодою.",
+ "retention_of_personal_data": "Зберігання Ваших Персональних Даних",
+ "retention_policy_paragraph1": "Компанія зберігатиме Ваші Персональні дані лише стільки часу, скільки необхідно для цілей, викладених у цій Політиці конфіденційності.",
+ "retention_policy_paragraph2": "Компанія також зберігатиме Дані про використання для цілей внутрішнього аналізу.",
+ "transfer_of_personal_data": "Передача Ваших Персональних Даних",
+ "transfer_info_paragraph1": "Ваша інформація, включаючи Персональні дані, обробляється в операційних офісах Компанії та в будь-яких інших місцях, де знаходяться сторони, які беруть участь в обробці.",
+ "transfer_info_paragraph2": "Ваша згода з цією Політикою конфіденційності супроводжується подачею такої інформації, що означає Вашу згоду на таку передачу.",
+ "transfer_info_paragraph3": "Компанія вживатиме всіх обґрунтовано необхідних заходів, щоб гарантувати безпеку Ваших даних.",
+ "delete_personal_data": "Видалення Ваших Персональних Даних",
+ "delete_info_paragraph1": "Ви маєте право видалити або попросити Нас допомогти у видаленні Персональних даних, які Ми зібрали про Вас.",
+ "delete_info_paragraph2": "Наш Сервіс може надати Вам можливість видалити певну інформацію про Вас у межах Сервісу.",
+ "delete_info_paragraph3": "Ви можете оновити, змінити або видалити Вашу інформацію в будь-який час, увійшовши до свого Акаунту.",
+ "delete_info_paragraph4": "Зверніть увагу, що Ми можемо зберегти певну інформацію, коли у нас є законне зобов'язання або законна підстава для цього.",
+ "disclosure_of_personal_data": "Розкриття Ваших Персональних Даних",
+ "business_transactions": "Ділові операції",
+ "business_transactions_paragraph": "Якщо Компанія бере участь у злитті, поглинанні або продажі активів, Ваші Персональні дані можуть бути передані.",
+ "law_enforcement": "Правоохоронні органи",
+ "law_enforcement_paragraph": "За певних обставин Компанія може бути зобов'язана розкрити Ваші Персональні дані, якщо цього вимагає закон.",
+ "other_legal_requirements": "Інші законодавчі вимоги",
+ "other_legal_requirements_paragraph": "Компанія може розкрити Ваші Персональні дані з добросовісним переконанням, що такі дії необхідні для:",
+ "legal_requirement_item1": "Дотримання юридичного зобов'язання",
+ "legal_requirement_item2": "Захисту та відстоювання прав або власності Компанії",
+ "legal_requirement_item3": "Запобігання або розслідування можливих правопорушень у зв'язку з Сервісом",
+ "legal_requirement_item4": "Захисту особистої безпеки Користувачів Сервісу або громадськості",
+ "legal_requirement_item5": "Захисту від юридичної відповідальності",
+ "security_of_personal_data": "Безпека Ваших Персональних Даних",
+ "security_paragraph": "Безпека Ваших Персональних Даних важлива для Нас, але пам'ятайте, що жоден метод передачі через Інтернет або метод електронного зберігання не є на 100% безпечним.",
+ "childrens_privacy": "Конфіденційність дітей",
+ "childrens_privacy_paragraph1": "Наш Сервіс не адресований нікому віком до 13 років. Ми свідомо не збираємо інформацію від осіб молодше 13 років.",
+ "childrens_privacy_paragraph2": "Якщо Нам потрібно покладатися на згоду як юридичну підставу для обробки Вашої інформації, Ми можемо вимагати згоди Ваших батьків.",
+ "links_to_other_websites": "Посилання на інші веб-сайти",
+ "links_to_other_websites_paragraph1": "Наш Сервіс може містити посилання на інші веб-сайти, якими Ми не керуємо.",
+ "links_to_other_websites_paragraph2": "Ми не контролюємо та не несемо відповідальності за вміст або політику конфіденційності сторонніх сайтів.",
+ "changes_to_privacy_policy": "Зміни до цієї Політики конфіденційності",
+ "changes_to_privacy_policy_paragraph1": "Ми можемо час від часу оновлювати нашу Політику конфіденційності.",
+ "changes_to_privacy_policy_paragraph2": "Ми повідомимо Вас електронною поштою та/або помітним повідомленням у нашому Сервісі.",
+ "changes_to_privacy_policy_paragraph3": "Рекомендуємо періодично переглядати цю Політику на предмет будь-яких змін.",
+ "contact_us": "Зв'яжіться з нами",
+ "contact_us_paragraph": "Якщо у вас є запитання щодо цієї Політики конфіденційності, Ви можете зв'язатися з нами:",
+ "contact_us_by_email": "Електронною поштою:",
+ "contact_us_on_website": "Відвідавши цю сторінку на нашому сайті:",
+ "contact_us_on_github_discussions": "У обговореннях Github для",
+ "contact_us_on_github_discussions_or": "або",
+ "contact_us_on_discord": "У нашому Discord "
+}
\ No newline at end of file
diff --git a/src/services/i18n/locales/uk/profile.json b/src/services/i18n/locales/uk/profile.json
new file mode 100644
index 00000000..9c657771
--- /dev/null
+++ b/src/services/i18n/locales/uk/profile.json
@@ -0,0 +1,78 @@
+{
+ "title": "Профіль",
+ "title1": "Редагувати профіль",
+ "title2": "Змінити Email",
+ "title3": "Змінити пароль",
+ "actions": {
+ "edit": "Редагувати",
+ "submit": "Зберегти",
+ "cancel": "Скасувати"
+ },
+ "inputs": {
+ "firstName": {
+ "label": "Ім'я",
+ "validation": {
+ "required": "Ім'я є обов'язковим"
+ }
+ },
+ "lastName": {
+ "label": "Прізвище",
+ "validation": {
+ "required": "Прізвище є обов'язковим"
+ }
+ },
+ "email": {
+ "label": "Новий Email",
+ "validation": {
+ "required": "Email є обов'язковим",
+ "email": "Email має бути дійсним",
+ "currentEmail": "Email має відрізнятися від поточного",
+ "server": {
+ "emailExists": "Такий Email вже зайнятий"
+ }
+ }
+ },
+ "emailConfirmation": {
+ "label": "Підтвердження Email",
+ "validation": {
+ "required": "Підтвердження Email є обов'язковим",
+ "match": "Підтвердження Email має збігатися з Email"
+ }
+ },
+ "oldPassword": {
+ "label": "Старий пароль",
+ "validation": {
+ "required": "Старий пароль є обов'язковим",
+ "min": "Старий пароль має містити щонайменше 6 символів",
+ "server": {
+ "incorrectOldPassword": "Старий пароль недійсний"
+ }
+ }
+ },
+ "password": {
+ "label": "Новий пароль",
+ "validation": {
+ "required": "Новий пароль є обов'язковим",
+ "min": "Новий пароль має містити щонайменше 6 символів"
+ }
+ },
+ "passwordConfirmation": {
+ "label": "Підтвердження пароля",
+ "validation": {
+ "required": "Підтвердження пароля є обов'язковим",
+ "match": "Підтвердження пароля має збігатися з паролем"
+ }
+ }
+ },
+ "alerts": {
+ "email": {
+ "success": "Запит на зміну email надіслано на вашу нову адресу. Будь ласка, перевірте пошту та перейдіть за посиланням, щоб підтвердити зміну."
+ },
+ "password": {
+ "success": "Пароль успішно оновлено"
+ },
+ "profile": {
+ "success": "Профіль успішно оновлено"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/services/i18n/locales/uk/sign-in.json b/src/services/i18n/locales/uk/sign-in.json
new file mode 100644
index 00000000..7819d935
--- /dev/null
+++ b/src/services/i18n/locales/uk/sign-in.json
@@ -0,0 +1,32 @@
+{
+ "title": "Увійти",
+ "actions": {
+ "submit": "Увійти",
+ "createAccount": "Створити акаунт",
+ "forgotPassword": "Забули пароль?"
+ },
+ "inputs": {
+ "email": {
+ "label": "Email",
+ "validation": {
+ "required": "Email є обов'язковим",
+ "invalid": "Недійсний формат email",
+ "server": {
+ "emailNotExists": "Email не існує",
+ "notFound": "Email не існує"
+ }
+ }
+ },
+ "password": {
+ "label": "Пароль",
+ "validation": {
+ "required": "Пароль є обов'язковим",
+ "min": "Пароль має містити щонайменше 6 символів",
+ "server": {
+ "incorrectPassword": "Недійсний пароль"
+ }
+ }
+ }
+ },
+ "or": "АБО"
+}
\ No newline at end of file
diff --git a/src/services/i18n/locales/uk/sign-up.json b/src/services/i18n/locales/uk/sign-up.json
new file mode 100644
index 00000000..dfd8038b
--- /dev/null
+++ b/src/services/i18n/locales/uk/sign-up.json
@@ -0,0 +1,49 @@
+{
+ "title": "Зареєструватися",
+ "actions": {
+ "submit": "Зареєструватися",
+ "accountAlreadyExists": "Вже маєте акаунт?"
+ },
+ "inputs": {
+ "firstName": {
+ "label": "Ім'я",
+ "validation": {
+ "required": "Ім'я є обов'язковим"
+ }
+ },
+ "lastName": {
+ "label": "Прізвище",
+ "validation": {
+ "required": "Прізвище є обов'язковим"
+ }
+ },
+ "email": {
+ "label": "Email",
+ "validation": {
+ "required": "Email є обов'язковим",
+ "invalid": "Недійсний формат email",
+ "server": {
+ "emailAlreadyExists": "Такий email вже існує"
+ }
+ }
+ },
+ "password": {
+ "label": "Пароль",
+ "validation": {
+ "required": "Пароль є обов'язковим",
+ "min": "Пароль має містити щонайменше 6 символів",
+ "server": {
+ "incorrectPassword": "Недійсний пароль"
+ }
+ }
+ },
+ "policy": {
+ "label": "Політика конфіденційності",
+ "agreement": "Я прочитав(-ла) та приймаю ",
+ "validation": {
+ "required": "Згода з Політикою конфіденційності є обов'язковою"
+ }
+ }
+ },
+ "or": "АБО"
+}
\ No newline at end of file