diff --git a/package-lock.json b/package-lock.json index 6b41e2f..41aa224 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,9 +9,10 @@ "version": "0.0.0", "dependencies": { "@cloudflare/vite-plugin": "^1.17.1", - "@customcads/react-sdk": "^1.13.1-beta.1", + "@customcads/react-sdk": "^1.13.4-beta.2", "@icons-pack/react-simple-icons": "^13.8.0", "@microsoft/signalr": "^9.0.6", + "@radix-ui/react-alert-dialog": "^1.1.15", "@radix-ui/react-checkbox": "^1.3.3", "@radix-ui/react-collapsible": "^1.1.12", "@radix-ui/react-dialog": "^1.1.15", @@ -26,6 +27,7 @@ "@radix-ui/react-slider": "^1.3.6", "@radix-ui/react-slot": "^1.2.4", "@radix-ui/react-switch": "^1.2.6", + "@radix-ui/react-tabs": "^1.1.13", "@radix-ui/react-tooltip": "^1.2.8", "@stripe/react-stripe-js": "^5.2.0", "@stripe/stripe-js": "^8.1.0", @@ -47,8 +49,8 @@ "i18next": "^25.6.0", "js-cookie": "^3.0.5", "lucide-react": "^0.544.0", - "react": "^19.0.0", - "react-dom": "^19.0.0", + "react": "^19.2.6", + "react-dom": "^19.2.6", "react-i18next": "^16.1.5", "react-phone-number-input": "^3.4.12", "tailwind-merge": "^3.0.2", @@ -69,8 +71,8 @@ "@tanstack/react-router-devtools": "^1.141.2", "@types/js-cookie": "^3.0.6", "@types/node": "^20.19.9", - "@types/react": "^19.1.9", - "@types/react-dom": "^19.1.7", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", "@types/three": "^0.172.0", "@typescript-eslint/eslint-plugin": "^8.38.0", "@typescript-eslint/parser": "^8.38.0", @@ -740,15 +742,28 @@ } }, "node_modules/@customcads/react-sdk": { - "version": "1.13.1-beta.1", - "resolved": "https://registry.npmjs.org/@customcads/react-sdk/-/react-sdk-1.13.1-beta.1.tgz", - "integrity": "sha512-feK80p9G9z45F9ZHxJXIGQFjb/vAILNYJIcCtb/7niE9RHYW6KkV3QeWyQvxFtpPkLrUiztNYNcCaX36WfV4yg==", + "version": "1.13.4-beta.2", + "resolved": "https://registry.npmjs.org/@customcads/react-sdk/-/react-sdk-1.13.4-beta.2.tgz", + "integrity": "sha512-rRqs6pU1Q54mYbrZPXA9yPN0NSP6C1G91A062EAourYDlFrvaI5CXYAB0DLV544meAaIJzTPjZ4Y84ZZRMMt0g==", "dependencies": { - "@tanstack/react-query": "^5.90.5", - "axios": "^1.12.2", - "prettier": "^3.6.2", - "react": "^19.2.0", - "uuid": "^13.0.0" + "@tanstack/react-query": "^5.100.10", + "axios": "^1.16.0", + "prettier": "^3.8.3", + "react": "^19.2.6", + "uuid": "^14.0.0" + } + }, + "node_modules/@customcads/react-sdk/node_modules/uuid": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.0.tgz", + "integrity": "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist-node/bin/uuid" } }, "node_modules/@emnapi/runtime": { @@ -2126,6 +2141,52 @@ "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", "license": "MIT" }, + "node_modules/@radix-ui/react-alert-dialog": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.15.tgz", + "integrity": "sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dialog": "1.1.15", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-alert-dialog/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-arrow": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", @@ -3089,6 +3150,36 @@ } } }, + "node_modules/@radix-ui/react-tabs": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.13.tgz", + "integrity": "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-tooltip": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.8.tgz", @@ -4282,9 +4373,9 @@ } }, "node_modules/@tanstack/query-core": { - "version": "5.90.18", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.18.tgz", - "integrity": "sha512-rbGx6bHgPNVzutP7BEr+53UPKohpckqlMAad+To9UxTbeaQ+kC/1SDRj+QzkwbQ7qhLT/1IKp34yS6thda6fzA==", + "version": "5.100.10", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.100.10.tgz", + "integrity": "sha512-8UR0yJR+GiQ40m3lPhUr0xbfAupe6GSQiksSBSa9SM2NjezFyxXCIA69/lz8cSoNKZLrw1/PktIyQBJcVeMi3w==", "license": "MIT", "peer": true, "funding": { @@ -4370,13 +4461,13 @@ } }, "node_modules/@tanstack/react-query": { - "version": "5.90.18", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.18.tgz", - "integrity": "sha512-KqNZX0C5IFz4639zR1ilnQ288tQdJrMNLtzmlzyJ14xauBkhtLEy3mPU/V4KiHsr41eL1ILZbDP36TB12lYfCQ==", + "version": "5.100.10", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.100.10.tgz", + "integrity": "sha512-FLaZf2RCrA/Zgp4aiu5tG3TyasTRO7aZ99skxQpr3Hg/zXOhu6yq5FZCYQ/tRaJtM9ylnoK8tFK7PolXQadv6Q==", "license": "MIT", "peer": true, "dependencies": { - "@tanstack/query-core": "5.90.18" + "@tanstack/query-core": "5.100.10" }, "funding": { "type": "github", @@ -5121,9 +5212,9 @@ } }, "node_modules/@types/react": { - "version": "19.2.8", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.8.tgz", - "integrity": "sha512-3MbSL37jEchWZz2p2mjntRZtPt837ij10ApxKfgmXCTuHWagYg7iA5bqPw6C8BMPfwidlvfPI/fxOc42HLhcyg==", + "version": "19.2.14", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", + "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", "devOptional": true, "license": "MIT", "peer": true, @@ -5774,14 +5865,14 @@ "license": "MIT" }, "node_modules/axios": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", - "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.16.0.tgz", + "integrity": "sha512-6hp5CwvTPlN2A31g5dxnwAX0orzM7pmCRDLnZSX772mv8WDqICwFjowHuPs04Mc8deIld1+ejhtaMn5vp6b+1w==", "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.4", - "proxy-from-env": "^1.1.0" + "follow-redirects": "^1.16.0", + "form-data": "^4.0.5", + "proxy-from-env": "^2.1.0" } }, "node_modules/babel-dead-code-elimination": { @@ -7138,9 +7229,9 @@ "license": "ISC" }, "node_modules/follow-redirects": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", "funding": [ { "type": "individual", @@ -8637,9 +8728,9 @@ } }, "node_modules/prettier": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.0.tgz", - "integrity": "sha512-yEPsovQfpxYfgWNhCfECjG5AQaO+K3dp6XERmOepyPDVqcJm+bjyCVO3pmU+nAPe0N5dDvekfGezt/EIiRe1TA==", + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz", + "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==", "license": "MIT", "peer": true, "bin": { @@ -8677,10 +8768,13 @@ } }, "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } }, "node_modules/psl": { "version": "1.15.0", @@ -8710,9 +8804,9 @@ "license": "MIT" }, "node_modules/react": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz", - "integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==", + "version": "19.2.6", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.6.tgz", + "integrity": "sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==", "license": "MIT", "peer": true, "engines": { @@ -8720,16 +8814,16 @@ } }, "node_modules/react-dom": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz", - "integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==", + "version": "19.2.6", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.6.tgz", + "integrity": "sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==", "license": "MIT", "peer": true, "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^19.2.3" + "react": "^19.2.6" } }, "node_modules/react-i18next": { diff --git a/package.json b/package.json index bf0bc66..3855953 100644 --- a/package.json +++ b/package.json @@ -18,9 +18,10 @@ }, "dependencies": { "@cloudflare/vite-plugin": "^1.17.1", - "@customcads/react-sdk": "^1.13.1-beta.1", + "@customcads/react-sdk": "^1.13.4-beta.2", "@icons-pack/react-simple-icons": "^13.8.0", "@microsoft/signalr": "^9.0.6", + "@radix-ui/react-alert-dialog": "^1.1.15", "@radix-ui/react-checkbox": "^1.3.3", "@radix-ui/react-collapsible": "^1.1.12", "@radix-ui/react-dialog": "^1.1.15", @@ -35,6 +36,7 @@ "@radix-ui/react-slider": "^1.3.6", "@radix-ui/react-slot": "^1.2.4", "@radix-ui/react-switch": "^1.2.6", + "@radix-ui/react-tabs": "^1.1.13", "@radix-ui/react-tooltip": "^1.2.8", "@stripe/react-stripe-js": "^5.2.0", "@stripe/stripe-js": "^8.1.0", @@ -56,8 +58,8 @@ "i18next": "^25.6.0", "js-cookie": "^3.0.5", "lucide-react": "^0.544.0", - "react": "^19.0.0", - "react-dom": "^19.0.0", + "react": "^19.2.6", + "react-dom": "^19.2.6", "react-i18next": "^16.1.5", "react-phone-number-input": "^3.4.12", "tailwind-merge": "^3.0.2", @@ -78,8 +80,8 @@ "@tanstack/react-router-devtools": "^1.141.2", "@types/js-cookie": "^3.0.6", "@types/node": "^20.19.9", - "@types/react": "^19.1.9", - "@types/react-dom": "^19.1.7", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", "@types/three": "^0.172.0", "@typescript-eslint/eslint-plugin": "^8.38.0", "@typescript-eslint/parser": "^8.38.0", diff --git a/src/app/components/alert/index.tsx b/src/app/components/alert/index.tsx new file mode 100644 index 0000000..2c69da7 --- /dev/null +++ b/src/app/components/alert/index.tsx @@ -0,0 +1,27 @@ +import { useFormTranslations } from '@/app/hooks/locales/translations/components'; +import * as alert from '@/app/components/ui/alert'; + +type Props = { success: string | false; error?: string }; +const Alert = ({ success, error }: Props) => { + const tState = useFormTranslations('state'); + + if (error) { + return ( + + {tState('error')} + {error} + + ); + } + + if (success) { + return ( + + {tState('success')} + {success} + + ); + } +}; + +export default Alert; diff --git a/src/app/components/clipboard.tsx b/src/app/components/clipboard.tsx new file mode 100644 index 0000000..2ce68cb --- /dev/null +++ b/src/app/components/clipboard.tsx @@ -0,0 +1,55 @@ +import { useState } from 'react'; +import { ClipboardPen } from 'lucide-react'; +import { cn } from '@/lib/utils/tailwindcss'; +import { useLayoutTranslations } from '@/app/hooks/locales/translations/components'; +import { Tooltip, TooltipContent, TooltipTrigger } from './ui/tooltip'; +import { Button } from './ui/button'; + +type Props = { value: string }; +const Clipboard = ({ value }: Props) => { + const tUi = useLayoutTranslations('ui'); + const [isCopied, setIsCopied] = useState(false); + + const handleCopy = async () => { + await navigator.clipboard.writeText(value); + + setIsCopied(true); + setTimeout(() => { + setIsCopied(false); + }, 2000); + }; + + return ( + + + + + {tUi('clipboard-message')} + + + {tUi('clipboard-label')} + + ); +}; + +export default Clipboard; diff --git a/src/app/components/error/index.tsx b/src/app/components/error/index.tsx index d621901..e953807 100644 --- a/src/app/components/error/index.tsx +++ b/src/app/components/error/index.tsx @@ -1,7 +1,7 @@ import { Link } from '@tanstack/react-router'; import { AppErrorFields } from '@/types/errors'; import { cn } from '@/lib/utils/tailwindcss'; -import { useErrorsTranslations } from '@/app/hooks/locales/translations/common'; +import { useCommonTranslations } from '@/app/hooks/locales/translations/common'; import * as page from '@/app/utils/page'; type ErrorPageProps = { @@ -9,7 +9,7 @@ type ErrorPageProps = { error?: AppErrorFields; }; const ErrorPage = ({ status, error }: ErrorPageProps) => { - const tError = useErrorsTranslations(); + const tError = useCommonTranslations('errors'); const { title, message, tip } = error ?? { title: tError(`${status ?? 'default'}_title`), message: tError(`${status ?? 'default'}_message`), @@ -27,7 +27,7 @@ const ErrorPage = ({ status, error }: ErrorPageProps) => { {status === 401 && (
{tError('login_link')} diff --git a/src/app/components/fields/error.tsx b/src/app/components/fields/error.tsx index a3c0fd1..07edcf0 100644 --- a/src/app/components/fields/error.tsx +++ b/src/app/components/fields/error.tsx @@ -15,9 +15,10 @@ const Error = ({ meta, isSubmitted, hideIfPristine }: Props) => { if (!(isSubmitted || shouldShowError)) return; + const [error] = meta.errors; return ( - {meta.errors[0].message} + {error.message ?? error[0].message} ); }; diff --git a/src/app/components/fields/field.tsx b/src/app/components/fields/field.tsx new file mode 100644 index 0000000..71e278c --- /dev/null +++ b/src/app/components/fields/field.tsx @@ -0,0 +1,45 @@ +import { type AnyFieldApi } from '@tanstack/react-form'; +import { Children } from '@/types/react'; +import { useFormTranslations } from '@/app/hooks/locales/translations/components'; +import { Label } from '../ui/label'; +import FormInput from './input'; +import PasswordInput from './password'; +import Error from './error'; + +type Props = Children & { + api: AnyFieldApi; + isSubmitted: boolean; + canEdit?: boolean; + className?: string; +}; +const FormField = ({ api, isSubmitted, canEdit, ...props }: Props) => { + const tLabels = useFormTranslations('labels'); + const tPlaceholders = useFormTranslations('placeholders'); + + const DefaultInput = () => { + if (['password', 'confirmPassword'].includes(api.name)) { + return ; + } + + return ( + + ); + }; + + return ( + <> + + {props.children ?? DefaultInput()} + + + ); +}; + +export default FormField; diff --git a/src/app/components/fields/input.tsx b/src/app/components/fields/input.tsx new file mode 100644 index 0000000..654ae10 --- /dev/null +++ b/src/app/components/fields/input.tsx @@ -0,0 +1,15 @@ +import { AnyFieldApi } from '@tanstack/react-form'; +import { Input } from '@/app/components/ui/input'; + +type Props = { api: AnyFieldApi } & React.ComponentProps; +const FormInput = ({ api, ...props }: Props) => ( + api.handleChange(value)} + onBlur={api.handleBlur} + {...props} + /> +); + +export default FormInput; diff --git a/src/app/components/fields/password.tsx b/src/app/components/fields/password.tsx index 3f8f31f..d6b4f8e 100644 --- a/src/app/components/fields/password.tsx +++ b/src/app/components/fields/password.tsx @@ -1,26 +1,26 @@ import { useState } from 'react'; import { AnyFieldApi } from '@tanstack/react-form'; import { Eye, EyeOff, LucideIcon } from 'lucide-react'; -import { Input } from '@/app/components/ui/input'; +import { useFormTranslations } from '@/app/hooks/locales/translations/components'; +import FormInput from './input'; const ToggledIcon = ({ Icon }: { Icon: LucideIcon }) => ( ); -type Props = { api: AnyFieldApi; placeholder: string }; -const PasswordField = ({ api, placeholder }: Props) => { +type Props = { api: AnyFieldApi; placeholder?: string }; +const PasswordInput = ({ api, placeholder }: Props) => { const [isVisible, setIsVisible] = useState(false); const toggleVisibility = () => setIsVisible((prev) => !prev); + const tPlaceholders = useFormTranslations('placeholders'); + return (
- api.handleChange(value)} - onBlur={api.handleBlur} - placeholder={placeholder} + placeholder={placeholder ?? tPlaceholders('password')} /> @@ -29,4 +29,4 @@ const PasswordField = ({ api, placeholder }: Props) => { ); }; -export default PasswordField; +export default PasswordInput; diff --git a/src/app/components/fields/radio.tsx b/src/app/components/fields/radio.tsx index 7ebf8e2..5cb2f57 100644 --- a/src/app/components/fields/radio.tsx +++ b/src/app/components/fields/radio.tsx @@ -3,7 +3,7 @@ import { Label } from '@/app/components/ui/label'; type Props = { value: string; label?: string }; const RadioField = ({ value, label }: Props) => ( -
+