fix(frontend): enhance RHF hooks logic

This commit is contained in:
yassinedorbozgithub
2025-05-30 18:57:42 +01:00
parent c2a0fc8265
commit ae08a7fff9
26 changed files with 147 additions and 116 deletions

View File

@@ -16,7 +16,7 @@ import { useEffect } from "react";
import { useConfirmAccount, useLogin } from "@/hooks/entities/auth-hooks";
import { useAuth } from "@/hooks/useAuth";
import { useForm } from "@/hooks/useForm";
import { useStrictForm } from "@/hooks/useStrictForm";
import { useToast } from "@/hooks/useToast";
import { useTranslate } from "@/hooks/useTranslate";
import { ILoginAttributes } from "@/types/auth/login.types";
@@ -61,7 +61,7 @@ export const Login = () => {
register,
formState: { errors },
handleSubmit,
} = useForm<ILoginAttributes>({
} = useStrictForm<ILoginAttributes>({
defaultValues: DEFAULT_VALUES,
rules: {
identifier: {

View File

@@ -23,7 +23,7 @@ import { useRouter } from "next/router";
import { useEffect, useState } from "react";
import { useAcceptInvite } from "@/hooks/entities/auth-hooks";
import { useForm } from "@/hooks/useForm";
import { useStrictForm } from "@/hooks/useStrictForm";
import { useToast } from "@/hooks/useToast";
import { useTranslate } from "@/hooks/useTranslate";
import { IRegisterAttributes } from "@/types/auth/register.types";
@@ -68,7 +68,7 @@ export const Register = () => {
setValue,
formState: { errors },
handleSubmit,
} = useForm<TRegisterExtendedPayload>({
} = useStrictForm<TRegisterExtendedPayload>({
defaultValues: DEFAULT_VALUES,
rules: {
first_name: {

View File

@@ -12,7 +12,7 @@ import Link from "next/link";
import { useRouter } from "next/router";
import { useResetPassword } from "@/hooks/entities/reset-hooks";
import { useForm } from "@/hooks/useForm";
import { useStrictForm } from "@/hooks/useStrictForm";
import { useToast } from "@/hooks/useToast";
import { useTranslate } from "@/hooks/useTranslate";
@@ -28,7 +28,7 @@ export const ResetPassword = () => {
register,
handleSubmit,
formState: { errors },
} = useForm<{ password: string; password2: string }>({
} = useStrictForm<{ password: string; password2: string }>({
defaultValues: { password: "", password2: "" },
rules: {
password: {

View File

@@ -10,7 +10,7 @@ import { Button, Grid, Paper, Typography } from "@mui/material";
import Link from "next/link";
import { useRequestResetPassword } from "@/hooks/entities/reset-hooks";
import { useForm } from "@/hooks/useForm";
import { useStrictForm } from "@/hooks/useStrictForm";
import { useToast } from "@/hooks/useToast";
import { useTranslate } from "@/hooks/useTranslate";
@@ -25,7 +25,7 @@ export const ResetPasswordRequest = () => {
register,
handleSubmit,
formState: { errors },
} = useForm<{ email: string }>({
} = useStrictForm<{ email: string }>({
defaultValues: { email: "" },
rules: {
email: {

View File

@@ -15,7 +15,7 @@ import { Input } from "@/app-components/inputs/Input";
import { ToggleableInput } from "@/app-components/inputs/ToggleableInput";
import { useCreate } from "@/hooks/crud/useCreate";
import { useUpdate } from "@/hooks/crud/useUpdate";
import { useForm } from "@/hooks/useForm";
import { useStrictForm } from "@/hooks/useStrictForm";
import { useToast } from "@/hooks/useToast";
import { useTranslate } from "@/hooks/useTranslate";
import { EntityType } from "@/services/types";
@@ -59,7 +59,7 @@ export const MenuForm: FC<ComponentFormProps<MenuFormData>> = ({
formState: { errors },
resetField,
handleSubmit,
} = useForm<IMenuItemAttributes>({
} = useStrictForm<IMenuItemAttributes>({
defaultValues: DEFAULT_VALUES,
rules: {
type: {

View File

@@ -13,7 +13,7 @@ import { ContentContainer, ContentItem } from "@/app-components/dialogs";
import { Input } from "@/app-components/inputs/Input";
import { useCreate } from "@/hooks/crud/useCreate";
import { useUpdate } from "@/hooks/crud/useUpdate";
import { useForm } from "@/hooks/useForm";
import { useStrictForm } from "@/hooks/useStrictForm";
import { useToast } from "@/hooks/useToast";
import { useTranslate } from "@/hooks/useTranslate";
import { EntityType, RouterType } from "@/services/types";
@@ -47,7 +47,7 @@ export const CategoryForm: FC<ComponentFormProps<ICategory>> = ({
register,
formState: { errors },
handleSubmit,
} = useForm<ICategoryAttributes>({
} = useStrictForm<ICategoryAttributes>({
rules: {
label: { required: t("message.label_is_required") },
},

View File

@@ -15,7 +15,7 @@ import { ContentContainer, ContentItem } from "@/app-components/dialogs";
import { Input } from "@/app-components/inputs/Input";
import { useCreate } from "@/hooks/crud/useCreate";
import { useUpdate } from "@/hooks/crud/useUpdate";
import { useForm } from "@/hooks/useForm";
import { useStrictForm } from "@/hooks/useStrictForm";
import { useToast } from "@/hooks/useToast";
import { useTranslate } from "@/hooks/useTranslate";
import { EntityType } from "@/services/types";
@@ -40,7 +40,7 @@ export const ContentTypeForm: FC<ComponentFormProps<IContentType>> = ({
setValue,
formState: { errors },
handleSubmit,
} = useForm<Partial<IContentType>>({
} = useStrictForm<Partial<IContentType>>({
defaultValues: {
name: contentType?.name || "",
fields: contentType?.fields || FIELDS_FORM_DEFAULT_VALUES,

View File

@@ -21,7 +21,7 @@ import { Adornment } from "@/app-components/inputs/Adornment";
import { Input } from "@/app-components/inputs/Input";
import { useCreate } from "@/hooks/crud/useCreate";
import { useUpdate } from "@/hooks/crud/useUpdate";
import { useForm } from "@/hooks/useForm";
import { useStrictForm } from "@/hooks/useStrictForm";
import { useToast } from "@/hooks/useToast";
import { useTranslate } from "@/hooks/useTranslate";
import { EntityType } from "@/services/types";
@@ -141,7 +141,7 @@ export const ContentForm: FC<ComponentFormProps<IContent, IContentType>> = ({
control,
formState: { errors },
handleSubmit,
} = useForm<IContentAttributes & { [key: string]: any }>({
} = useStrictForm<IContentAttributes & { [key: string]: any }>({
defaultValues: {
entity: content?.entity || "",
status: content?.status || false,

View File

@@ -14,7 +14,7 @@ import { ContentContainer, ContentItem } from "@/app-components/dialogs";
import { Input } from "@/app-components/inputs/Input";
import { useCreate } from "@/hooks/crud/useCreate";
import { useUpdate } from "@/hooks/crud/useUpdate";
import { useForm } from "@/hooks/useForm";
import { useStrictForm } from "@/hooks/useStrictForm";
import { useToast } from "@/hooks/useToast";
import { useTranslate } from "@/hooks/useTranslate";
import { EntityType } from "@/services/types";
@@ -55,7 +55,7 @@ export const ContextVarForm: FC<ComponentFormProps<IContextVar>> = ({
setValue,
formState: { errors },
handleSubmit,
} = useForm<IContextVarAttributes>({
} = useStrictForm<IContextVarAttributes>({
defaultValues: {
name: contextVar?.name || "",
label: contextVar?.label || "",

View File

@@ -12,7 +12,7 @@ import { ContentContainer, ContentItem } from "@/app-components/dialogs";
import { Input } from "@/app-components/inputs/Input";
import { useCreate } from "@/hooks/crud/useCreate";
import { useUpdate } from "@/hooks/crud/useUpdate";
import { useForm } from "@/hooks/useForm";
import { useStrictForm } from "@/hooks/useStrictForm";
import { useToast } from "@/hooks/useToast";
import { useTranslate } from "@/hooks/useTranslate";
import { EntityType } from "@/services/types";
@@ -46,7 +46,7 @@ export const LabelForm: FC<ComponentFormProps<ILabel>> = ({
setValue,
formState: { errors },
handleSubmit,
} = useForm<ILabelAttributes>({
} = useStrictForm<ILabelAttributes>({
defaultValues: {
name: label?.name || "",
title: label?.title || "",

View File

@@ -14,7 +14,7 @@ import { ContentContainer, ContentItem } from "@/app-components/dialogs";
import { Input } from "@/app-components/inputs/Input";
import { useCreate } from "@/hooks/crud/useCreate";
import { useUpdate } from "@/hooks/crud/useUpdate";
import { useForm } from "@/hooks/useForm";
import { useStrictForm } from "@/hooks/useStrictForm";
import { useToast } from "@/hooks/useToast";
import { useTranslate } from "@/hooks/useTranslate";
import { EntityType } from "@/services/types";
@@ -47,7 +47,7 @@ export const LanguageForm: FC<ComponentFormProps<ILanguage>> = ({
formState: { errors },
handleSubmit,
control,
} = useForm<ILanguageAttributes>({
} = useStrictForm<ILanguageAttributes>({
defaultValues: {
title: language?.title || "",
code: language?.code || "",

View File

@@ -19,7 +19,7 @@ import { ContentContainer, ContentItem } from "@/app-components/dialogs";
import { Input } from "@/app-components/inputs/Input";
import { useCreate } from "@/hooks/crud/useCreate";
import { useUpdate } from "@/hooks/crud/useUpdate";
import { useForm } from "@/hooks/useForm";
import { useStrictForm } from "@/hooks/useStrictForm";
import { useToast } from "@/hooks/useToast";
import { useTranslate } from "@/hooks/useTranslate";
import { EntityType } from "@/services/types";
@@ -55,7 +55,7 @@ export const NlpEntityVarForm: FC<ComponentFormProps<INlpEntity>> = ({
register,
formState: { errors },
handleSubmit,
} = useForm<INlpEntityAttributes>({
} = useStrictForm<INlpEntityAttributes>({
defaultValues: {
name: nlpEntity?.name || "",
doc: nlpEntity?.doc || "",

View File

@@ -32,8 +32,8 @@ import AutoCompleteSelect from "@/app-components/inputs/AutoCompleteSelect";
import Selectable from "@/app-components/inputs/Selectable";
import { useGetFromCache } from "@/hooks/crud/useGet";
import { useApiClient } from "@/hooks/useApiClient";
import { useForm } from "@/hooks/useForm";
import { useNlp } from "@/hooks/useNlp";
import { useStrictForm } from "@/hooks/useStrictForm";
import { useTranslate } from "@/hooks/useTranslate";
import { EntityType, Format } from "@/services/types";
import { ILanguage } from "@/types/language.types";
@@ -86,7 +86,7 @@ const NlpDatasetSample: FC<NlpDatasetSampleProps> = ({
[allKeywordEntities, allTraitEntities, JSON.stringify(sample)],
);
const { handleSubmit, control, register, reset, setValue, watch } =
useForm<INlpSampleFormAttributes>({
useStrictForm<INlpSampleFormAttributes>({
defaultValues,
});
const currentText = watch("text");

View File

@@ -9,7 +9,7 @@
import { FormControlLabel, Switch } from "@mui/material";
import { useRouter } from "next/router";
import { FC, Fragment, useEffect } from "react";
import { Controller, useForm } from "react-hook-form";
import { Controller } from "react-hook-form";
import { ContentContainer, ContentItem } from "@/app-components/dialogs";
import { Input } from "@/app-components/inputs/Input";
@@ -18,6 +18,7 @@ import { RegexInput } from "@/app-components/inputs/RegexInput";
import { useCreate } from "@/hooks/crud/useCreate";
import { useGet } from "@/hooks/crud/useGet";
import { useUpdate } from "@/hooks/crud/useUpdate";
import { useStrictForm } from "@/hooks/useStrictForm";
import { useToast } from "@/hooks/useToast";
import { useTranslate } from "@/hooks/useTranslate";
import { EntityType, Format } from "@/services/types";
@@ -88,7 +89,7 @@ export const NlpValueForm: FC<ComponentFormProps<INlpValue, INlpEntity>> = ({
handleSubmit,
control,
formState: { errors },
} = useForm<
} = useStrictForm<
INlpValueAttributes & {
expressions: string[];
}
@@ -99,6 +100,11 @@ export const NlpValueForm: FC<ComponentFormProps<INlpValue, INlpEntity>> = ({
expressions: nlpValue?.expressions || [],
metadata: nlpValue?.metadata || getDefaultNlpMetadata(nlpEntity),
},
rules: {
value: {
required: t("message.value_is_required"),
},
},
});
const onSubmitForm = async (params: INlpValueAttributes) => {
if (nlpValue) {
@@ -137,9 +143,7 @@ export const NlpValueForm: FC<ComponentFormProps<INlpValue, INlpEntity>> = ({
required
autoFocus
helperText={errors.value?.message}
{...register("value", {
required: t("message.value_is_required"),
})}
{...register("value")}
/>
</ContentItem>
{isPattern && (

View File

@@ -22,7 +22,7 @@ import { Input } from "@/app-components/inputs/Input";
import { PasswordInput } from "@/app-components/inputs/PasswordInput";
import { useUpdateProfile } from "@/hooks/entities/auth-hooks";
import { CURRENT_USER_KEY } from "@/hooks/useAuth";
import { useForm } from "@/hooks/useForm";
import { useStrictForm } from "@/hooks/useStrictForm";
import { useToast } from "@/hooks/useToast";
import { useTranslate } from "@/hooks/useTranslate";
import { IProfileAttributes, IUser } from "@/types/user.types";
@@ -51,7 +51,7 @@ export const ProfileForm: FC<ProfileFormProps> = ({ user }) => {
formState: { errors },
register,
setValue,
} = useForm<IProfileAttributes>({
} = useStrictForm<IProfileAttributes>({
defaultValues: {
first_name: user.first_name,
last_name: user.last_name,

View File

@@ -12,7 +12,7 @@ import { ContentContainer, ContentItem } from "@/app-components/dialogs";
import { Input } from "@/app-components/inputs/Input";
import { useCreate } from "@/hooks/crud/useCreate";
import { useUpdate } from "@/hooks/crud/useUpdate";
import { useForm } from "@/hooks/useForm";
import { useStrictForm } from "@/hooks/useStrictForm";
import { useToast } from "@/hooks/useToast";
import { useTranslate } from "@/hooks/useTranslate";
import { EntityType } from "@/services/types";
@@ -43,7 +43,7 @@ export const RoleForm: FC<ComponentFormProps<IRole>> = ({
reset,
register,
formState: { errors },
} = useForm<IRoleAttributes>({
} = useStrictForm<IRoleAttributes>({
defaultValues: { name: "" },
rules: {
name: {

View File

@@ -8,12 +8,13 @@
import { Button, Grid, Link } from "@mui/material";
import { FC, Fragment, useEffect } from "react";
import { Controller, useForm } from "react-hook-form";
import { Controller } from "react-hook-form";
import { ContentContainer, ContentItem } from "@/app-components/dialogs";
import AutoCompleteEntitySelect from "@/app-components/inputs/AutoCompleteEntitySelect";
import { Input } from "@/app-components/inputs/Input";
import { useUpdate } from "@/hooks/crud/useUpdate";
import { useStrictForm } from "@/hooks/useStrictForm";
import { useToast } from "@/hooks/useToast";
import { useTranslate } from "@/hooks/useTranslate";
import { EntityType, Format } from "@/services/types";
@@ -47,7 +48,7 @@ export const SubscriberForm: FC<ComponentFormProps<ISubscriber>> = ({
control,
formState: { errors },
handleSubmit,
} = useForm<ISubscriberAttributes>();
} = useStrictForm<ISubscriberAttributes>();
const onSubmitForm = (params: ISubscriberAttributes) => {
if (subscriber?.id) {
updateSubscriber({ id: subscriber.id, params });

View File

@@ -14,7 +14,7 @@ import { ContentContainer, ContentItem } from "@/app-components/dialogs";
import { Input } from "@/app-components/inputs/Input";
import { useFind } from "@/hooks/crud/useFind";
import { useUpdate } from "@/hooks/crud/useUpdate";
import { useForm } from "@/hooks/useForm";
import { useStrictForm } from "@/hooks/useStrictForm";
import { useToast } from "@/hooks/useToast";
import { useTranslate } from "@/hooks/useTranslate";
import { EntityType } from "@/services/types";
@@ -73,7 +73,7 @@ export const TranslationForm: FC<ComponentFormProps<ITranslation>> = ({
toast.success(t("message.success_save"));
},
});
const { control, handleSubmit } = useForm<ITranslationAttributes>({
const { control, handleSubmit } = useStrictForm<ITranslationAttributes>({
defaultValues: {
translations: translation?.translations,
},

View File

@@ -8,12 +8,13 @@
import { Button, Grid, Link } from "@mui/material";
import { FC, Fragment, useEffect } from "react";
import { Controller, useForm } from "react-hook-form";
import { Controller } from "react-hook-form";
import { ContentContainer, ContentItem } from "@/app-components/dialogs";
import AutoCompleteEntitySelect from "@/app-components/inputs/AutoCompleteEntitySelect";
import { Input } from "@/app-components/inputs/Input";
import { useUpdate } from "@/hooks/crud/useUpdate";
import { useStrictForm } from "@/hooks/useStrictForm";
import { useToast } from "@/hooks/useToast";
import { useTranslate } from "@/hooks/useTranslate";
import { EntityType, Format } from "@/services/types";
@@ -46,7 +47,7 @@ export const EditUserForm: FC<ComponentFormProps<IUser, IRole[]>> = ({
control,
formState: { errors },
handleSubmit,
} = useForm<IUserAttributes>({
} = useStrictForm<IUserAttributes>({
defaultValues: { roles: roles?.map((role) => role.id) },
});
const validationRules = {

View File

@@ -13,7 +13,7 @@ import { ContentContainer, ContentItem } from "@/app-components/dialogs";
import AutoCompleteEntitySelect from "@/app-components/inputs/AutoCompleteEntitySelect";
import { Input } from "@/app-components/inputs/Input";
import { useSendInvitation } from "@/hooks/entities/invitation-hooks";
import { useForm } from "@/hooks/useForm";
import { useStrictForm } from "@/hooks/useStrictForm";
import { useToast } from "@/hooks/useToast";
import { useTranslate } from "@/hooks/useTranslate";
import { EntityType, Format } from "@/services/types";
@@ -45,7 +45,7 @@ export const InviteUserForm: FC<ComponentFormProps<undefined>> = ({
register,
formState: { errors },
handleSubmit,
} = useForm<IInvitationAttributes>({
} = useStrictForm<IInvitationAttributes>({
defaultValues: DEFAULT_VALUES,
rules: {
email: {

View File

@@ -17,7 +17,7 @@ import { Input } from "@/app-components/inputs/Input";
import TriggerIcon from "@/app-components/svg/TriggerIcon";
import { TabPanel } from "@/app-components/tabs/TabPanel";
import { useUpdate } from "@/hooks/crud/useUpdate";
import { useForm } from "@/hooks/useForm";
import { useStrictForm } from "@/hooks/useStrictForm";
import { useToast } from "@/hooks/useToast";
import { useTranslate } from "@/hooks/useTranslate";
import { EntityType } from "@/services/types";
@@ -81,7 +81,7 @@ export const BlockEditForm: FC<ComponentFormProps<IBlock>> = ({
message: block?.message || [""],
capture_vars: block?.capture_vars || [],
} as IBlockAttributes;
const methods = useForm<IBlockAttributes>({
const methods = useStrictForm<IBlockAttributes>({
defaultValues: DEFAULT_VALUES,
rules: {
name: {

View File

@@ -1,69 +0,0 @@
/*
* Copyright © 2025 Hexastack. All rights reserved.
*
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
*/
import {
FieldValues,
Path,
RegisterOptions,
UseFormProps,
UseFormRegister,
UseFormReturn,
useForm as useReactHookForm,
} from "react-hook-form";
import { useValidationRules } from "./useValidationRules";
export type TRegisterOption<TFieldValues extends FieldValues = FieldValues> =
Record<
keyof TFieldValues,
RegisterOptions<TFieldValues, Path<TFieldValues>> | undefined
>;
type TRegisterProps<TFieldValues extends FieldValues> = Parameters<
UseFormRegister<TFieldValues>
>;
type TRules<TFieldValues extends FieldValues = FieldValues> = {
rules?: Partial<TRegisterOption<TFieldValues>>;
};
const useRegister = <TFieldValues extends FieldValues>(
register: UseFormRegister<TFieldValues>,
rules?: Partial<TRegisterOption<TFieldValues>>,
) => {
const defaultRules = useValidationRules();
return (...args: TRegisterProps<TFieldValues>) => {
const fieldName = args[0].split(".").at(-1) || "";
const defaultOptions = (defaultRules[fieldName] || {}) as
| TFieldValues
| undefined;
const fieldOptions = args[1] || rules?.[fieldName];
const mergedOptions = { ...defaultOptions, ...fieldOptions };
return register(args[0], mergedOptions);
};
};
export const useForm = <
TFieldValues extends FieldValues = FieldValues,
TContext = any,
TTransformedValues extends FieldValues | undefined = undefined,
R = UseFormReturn<TFieldValues, TContext, TTransformedValues>,
>(
props?: UseFormProps<TFieldValues, TContext> & TRules<TFieldValues>,
): R => {
const { rules, ...restProps } = props || {};
const { register, ...restMethods } = useReactHookForm<
TFieldValues,
TContext,
TTransformedValues
>(restProps);
return { ...restMethods, register: useRegister(register, rules) } as R;
};

View File

@@ -0,0 +1,36 @@
/*
* Copyright © 2025 Hexastack. All rights reserved.
*
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
*/
import {
FieldValues,
UseFormProps,
UseFormReturn,
useForm,
} from "react-hook-form";
import { TRules } from "@/types/react-hook-form.types";
import { useStrictRegister } from "./useStrictRegister";
export const useStrictForm = <
TFieldValues extends FieldValues = FieldValues,
TContext = any,
TTransformedValues extends FieldValues | undefined = undefined,
R = UseFormReturn<TFieldValues, TContext, TTransformedValues>,
>(
props?: UseFormProps<TFieldValues, TContext> & TRules<TFieldValues>,
): R => {
const { rules, ...restProps } = props || {};
const { register, ...restMethods } = useForm<
TFieldValues,
TContext,
TTransformedValues
>(restProps);
return { ...restMethods, register: useStrictRegister(register, rules) } as R;
};

View File

@@ -0,0 +1,31 @@
/*
* Copyright © 2025 Hexastack. All rights reserved.
*
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
*/
import { FieldValues, UseFormRegister } from "react-hook-form";
import { TRegisterOption, TRegisterProps } from "@/types/react-hook-form.types";
import { useValidationRules } from "./useValidationRules";
export const useStrictRegister = <TFieldValues extends FieldValues>(
register: UseFormRegister<TFieldValues>,
rules?: Partial<TRegisterOption<TFieldValues>>,
) => {
const defaultRules = useValidationRules();
return (...args: TRegisterProps<TFieldValues>) => {
const fieldName = args[0].split(".").at(-1) || "";
const defaultOptions = (defaultRules[fieldName] || {}) as
| TFieldValues
| undefined;
const fieldOptions = args[1] || rules?.[fieldName];
const mergedOptions = { ...defaultOptions, ...fieldOptions };
return register(args[0], mergedOptions);
};
};

View File

@@ -9,8 +9,7 @@
import { FieldValues } from "react-hook-form";
import { useTranslate } from "@/hooks/useTranslate";
import { TRegisterOption } from "./useForm";
import { TRegisterOption } from "@/types/react-hook-form.types";
export const useValidationRules = () => {
const { t } = useTranslate();

View File

@@ -0,0 +1,28 @@
/*
* Copyright © 2025 Hexastack. All rights reserved.
*
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
*/
import {
FieldValues,
Path,
RegisterOptions,
UseFormRegister,
} from "react-hook-form";
export type TRegisterOption<TFieldValues extends FieldValues = FieldValues> =
Record<
keyof TFieldValues,
RegisterOptions<TFieldValues, Path<TFieldValues>> | undefined
>;
export type TRegisterProps<TFieldValues extends FieldValues> = Parameters<
UseFormRegister<TFieldValues>
>;
export type TRules<TFieldValues extends FieldValues = FieldValues> = {
rules?: Partial<TRegisterOption<TFieldValues>>;
};