diff --git a/.vscode/extensions.json b/.vscode/extensions.json index d93500f9..a8582dec 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,12 +1,10 @@ { "recommendations": [ - "mfeckies.handlebars-formatter", "bradlc.vscode-tailwindcss", "biomejs.biome", "cweijan.vscode-mysql-client2", "ms-vscode.vscode-json", "formulahendry.auto-rename-tag", - "cweijan.dbclient-jdbc", - "nabous.handlebars-preview-plus" + "cweijan.dbclient-jdbc" ] } diff --git a/modules/core/package.json b/modules/core/package.json index 04f7afcf..e4ef1f9e 100644 --- a/modules/core/package.json +++ b/modules/core/package.json @@ -44,9 +44,8 @@ "axios": "^1.9.0", "dinero.js": "^1.9.1", "express": "^4.18.2", - "handlebars": "^4.7.8", "http-status": "^2.1.0", - "lucide-react": "^0.503.0", + "lucide-react": "^0.577.0", "mime-types": "^3.0.1", "react-hook-form": "^7.58.1", "react-i18next": "^15.5.1", diff --git a/modules/core/src/api/infrastructure/documents/renderers/handlebars/renderer-template-resolver-SOBRA.ts b/modules/core/src/api/infrastructure/documents/renderers/handlebars/renderer-template-resolver-SOBRA.ts deleted file mode 100644 index f8e1b4d6..00000000 --- a/modules/core/src/api/infrastructure/documents/renderers/handlebars/renderer-template-resolver-SOBRA.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { existsSync, readFileSync } from "node:fs"; -import { join } from "node:path"; - -import type { IRendererTemplateResolver } from "../../../application"; - -import { FastReportTemplateNotFoundError } from "./fastreport"; - -/** - * Resuelve rutas de plantillas para desarrollo y producción. - */ -export abstract class RendererTemplateResolver implements IRendererTemplateResolver { - constructor(protected readonly rootPath: string) {} - - /** Une partes de ruta relativas al rootPath */ - protected resolveJoin(parts: string[]): string { - return join(this.rootPath, ...parts); - } - - /** - * Devuelve el directorio donde residen las plantillas de un módulo/empresa - * según el entorno (dev/prod). - */ - protected resolveTemplateDirectory(module: string, companySlug: string): string { - const isDev = process.env.NODE_ENV === "development"; - - if (isDev) { - // //templates// - return this.resolveJoin([module, "templates", companySlug]); - } - - // /templates/// - //return this.resolveJoin(["templates", module, companySlug]); - return this.resolveJoin([module]); - } - - /** Resuelve una ruta de recurso relativa al directorio de plantilla */ - protected resolveAssetPath(templateDir: string, relative: string): string { - return join(templateDir, relative); - } - - /** - * Devuelve la ruta absoluta del fichero de plantilla. - */ - public resolveTemplatePath(module: string, companySlug: string, templateName: string): string { - const dir = this.resolveTemplateDirectory(module, companySlug); - const filePath = this.resolveAssetPath(dir, templateName); - - if (!existsSync(filePath)) { - throw new FastReportTemplateNotFoundError( - `Template not found: module=${module} company=${companySlug} name=${templateName}` - ); - } - - return filePath; - } - - /** Lee el contenido de un fichero plantilla */ - protected readTemplateFile(templatePath: string): string { - return readFileSync(templatePath, "utf8"); - } -} diff --git a/modules/core/src/web/components/form/form-debug.tsx b/modules/core/src/web/components/form/form-debug.tsx index 744c90f7..c6d2fc10 100644 --- a/modules/core/src/web/components/form/form-debug.tsx +++ b/modules/core/src/web/components/form/form-debug.tsx @@ -1,9 +1,44 @@ -import { DevTool } from '@hookform/devtools'; -import { useState } from "react"; +import { Suspense, lazy, useState } from "react"; import { useFormContext } from "react-hook-form"; +const HookFormDevTool = lazy(async () => { + const mod = await import("@hookform/devtools"); + return { default: mod.DevTool }; +}); + +type FormDebugProps = { + enabled?: boolean; + placement?: "top-left" | "top-right" | "bottom-left" | "bottom-right"; +}; + +export function FormDebug({ enabled = false, placement = "top-right" }: FormDebugProps) { + return enabled ? : null; +} + +function FormDebugInner({ + placement, +}: { + placement: "top-left" | "top-right" | "bottom-left" | "bottom-right"; +}) { + const { control } = useFormContext(); + + return ( + + + + ); +} + // Renderiza una propiedad recursivamente con expansión -function DebugField({ label, oldValue, newValue }: { label?: string; oldValue: any; newValue: any }) { +function DebugField({ + label, + oldValue, + newValue, +}: { + label?: string; + oldValue: any; + newValue: any; +}) { const [open, setOpen] = useState(false); const isObject = typeof newValue === "object" && newValue !== null; @@ -12,8 +47,8 @@ function DebugField({ label, oldValue, newValue }: { label?: string; oldValue: a return (
  • {label && {label}: } - {String(oldValue)}{" "} - ➝ {String(newValue)} + {String(oldValue)} ➝{" "} + {String(newValue)}
  • ); } @@ -21,58 +56,19 @@ function DebugField({ label, oldValue, newValue }: { label?: string; oldValue: a return (
  • {open && (
      {Object.keys(newValue).map((key) => ( - + ))}
    )}
  • ); } - -export const FormDebug = () => { - const { control } = useFormContext(); - //const { watch, formState } = useFormContext(); - //const { isDirty, dirtyFields, defaultValues } = formState; - //const currentValues = watch(); - - return - - /*return ( -
    -

    - ¿Formulario modificado? {isDirty ? "Sí" : "No"} -

    -
    - Campos modificados: - {Object.keys(dirtyFields).length > 0 ? ( -
      - {Object.keys(dirtyFields).map((key) => ( - - ))} -
    - ) : ( -

    Ninguno

    - )} -
    -
    - );*/ -}; diff --git a/modules/core/src/web/hooks/use-hook-form/use-hook-form.ts b/modules/core/src/web/hooks/use-hook-form/use-hook-form.ts index 5474fcbb..e55c78b3 100644 --- a/modules/core/src/web/hooks/use-hook-form/use-hook-form.ts +++ b/modules/core/src/web/hooks/use-hook-form/use-hook-form.ts @@ -1,7 +1,7 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { useEffect, useRef } from "react"; -import { FieldValues, UseFormProps, UseFormReturn, useForm } from "react-hook-form"; -import * as z4 from "zod/v4/core"; +import { type FieldValues, type UseFormProps, type UseFormReturn, useForm } from "react-hook-form"; +import type * as z4 from "zod/v4/core"; type UseHookFormProps = UseFormProps< TFields, @@ -24,6 +24,9 @@ export function useHookForm { mounted = false; }; diff --git a/modules/customer-invoices/package.json b/modules/customer-invoices/package.json index 39a302e4..ad247af8 100644 --- a/modules/customer-invoices/package.json +++ b/modules/customer-invoices/package.json @@ -52,9 +52,8 @@ "date-fns": "^4.1.0", "dinero.js": "^1.9.1", "express": "^4.18.2", - "handlebars": "^4.7.8", "libphonenumber-js": "^1.12.7", - "lucide-react": "^0.503.0", + "lucide-react": "^0.577.0", "pg-hstore": "^2.3.4", "react-hook-form": "^7.58.1", "react-i18next": "^15.5.1", diff --git a/modules/customer-invoices/src/web/issued-invoices/list/ui/pages/issued-invoice-list-page.tsx b/modules/customer-invoices/src/web/issued-invoices/list/ui/pages/issued-invoice-list-page.tsx index 349e58e1..864c29ed 100644 --- a/modules/customer-invoices/src/web/issued-invoices/list/ui/pages/issued-invoice-list-page.tsx +++ b/modules/customer-invoices/src/web/issued-invoices/list/ui/pages/issued-invoice-list-page.tsx @@ -1,5 +1,4 @@ -import { PageHeader, SimpleSearchInput } from "@erp/core/components"; -import { ErrorAlert } from "@erp/customers/components"; +import { ErrorAlert, PageHeader, SimpleSearchInput } from "@erp/core/components"; import { AppContent, AppHeader, BackHistoryButton, LogoVerifactu } from "@repo/rdx-ui/components"; import { Alert, diff --git a/modules/customers/package.json b/modules/customers/package.json index 1c0f402d..110b7423 100644 --- a/modules/customers/package.json +++ b/modules/customers/package.json @@ -43,7 +43,7 @@ "@tanstack/react-query": "^5.90.6", "@tanstack/react-table": "^8.21.3", "express": "^4.18.2", - "lucide-react": "^0.503.0", + "lucide-react": "^0.577.0", "react-data-table-component": "^7.7.0", "react-hook-form": "^7.58.1", "react-i18next": "^16.2.4", diff --git a/modules/customers/src/api/application/di/customer-input-mappers.di.ts b/modules/customers/src/api/application/di/customer-input-mappers.di.ts index b62f6aee..07631877 100644 --- a/modules/customers/src/api/application/di/customer-input-mappers.di.ts +++ b/modules/customers/src/api/application/di/customer-input-mappers.di.ts @@ -1,9 +1,15 @@ import type { ICatalogs } from "@erp/core/api"; -import { CreateCustomerInputMapper, type ICreateCustomerInputMapper } from "../mappers"; +import { + CreateCustomerInputMapper, + type ICreateCustomerInputMapper, + type IUpdateCustomerInputMapper, + UpdateCustomerInputMapper, +} from "../mappers"; export interface ICustomerInputMappers { createInputMapper: ICreateCustomerInputMapper; + updateInputMapper: IUpdateCustomerInputMapper; } export const buildCustomerInputMappers = (catalogs: ICatalogs): ICustomerInputMappers => { @@ -11,9 +17,10 @@ export const buildCustomerInputMappers = (catalogs: ICatalogs): ICustomerInputMa // Mappers el DTO a las props validadas (CustomerProps) y luego construir agregado const createInputMapper = new CreateCustomerInputMapper({ taxCatalog }); - //const updateCustomerInputMapper = new UpdateCustomerInputMapper(); + const updateInputMapper = new UpdateCustomerInputMapper(); return { createInputMapper, + updateInputMapper, }; }; diff --git a/modules/customers/src/api/application/di/customer-updater.di.ts b/modules/customers/src/api/application/di/customer-updater.di.ts new file mode 100644 index 00000000..d40ff454 --- /dev/null +++ b/modules/customers/src/api/application/di/customer-updater.di.ts @@ -0,0 +1,12 @@ +import type { ICustomerRepository } from "../repositories"; +import { CustomerUpdater, type ICustomerUpdater } from "../services"; + +export const buildCustomerUpdater = (params: { + repository: ICustomerRepository; +}): ICustomerUpdater => { + const { repository } = params; + + return new CustomerUpdater({ + repository, + }); +}; diff --git a/modules/customers/src/api/application/di/index.ts b/modules/customers/src/api/application/di/index.ts index 4e27b007..08ab611a 100644 --- a/modules/customers/src/api/application/di/index.ts +++ b/modules/customers/src/api/application/di/index.ts @@ -2,4 +2,5 @@ export * from "./customer-creator.di"; export * from "./customer-finder.di"; export * from "./customer-input-mappers.di"; export * from "./customer-snapshot-builders.di"; +export * from "./customer-updater.di"; export * from "./customer-use-cases.di"; diff --git a/modules/customers/src/api/application/use-cases/update/update-customer.use-case.ts b/modules/customers/src/api/application/use-cases/update/update-customer.use-case.ts index 073464c0..6cb5bf8b 100644 --- a/modules/customers/src/api/application/use-cases/update/update-customer.use-case.ts +++ b/modules/customers/src/api/application/use-cases/update/update-customer.use-case.ts @@ -65,14 +65,7 @@ export class UpdateCustomerUseCase { return Result.fail(updateResult.error); } - const customerOrError = await this.service.updateCustomerInCompany( - companyId, - updateResult.data, - transaction - ); - const customer = customerOrError.data; - const dto = presenter.toOutput(customer); - return Result.ok(dto); + return Result.ok(this.fullSnapshotBuilder.toOutput(updateResult.data)); } catch (error: unknown) { return Result.fail(error as Error); } diff --git a/modules/customers/src/api/infrastructure/di/customers.di.ts b/modules/customers/src/api/infrastructure/di/customers.di.ts index 10ddb23b..a8331c4e 100644 --- a/modules/customers/src/api/infrastructure/di/customers.di.ts +++ b/modules/customers/src/api/infrastructure/di/customers.di.ts @@ -10,8 +10,10 @@ import { buildCustomerFinder, buildCustomerInputMappers, buildCustomerSnapshotBuilders, + buildCustomerUpdater, buildGetCustomerByIdUseCase, buildListCustomersUseCase, + buildUpdateCustomerUseCase, } from "../../application"; import { buildCustomerPersistenceMappers } from "./customer-persistence-mappers.di"; @@ -49,6 +51,7 @@ export function buildCustomersDependencies(params: ModuleParams): CustomersInter const inputMappers = buildCustomerInputMappers(catalogs); const finder = buildCustomerFinder({ repository }); const creator = buildCustomerCreator({ repository }); + const updater = buildCustomerUpdater({ repository }); const snapshotBuilders = buildCustomerSnapshotBuilders(); //const documentGeneratorPipeline = buildCustomerDocumentService(params); @@ -80,7 +83,7 @@ export function buildCustomersDependencies(params: ModuleParams): CustomersInter updateCustomer: () => buildUpdateCustomerUseCase({ - creator, + updater, dtoMapper: inputMappers.updateInputMapper, fullSnapshotBuilder: snapshotBuilders.full, transactionManager, diff --git a/modules/customers/src/web/common/hooks/use-customer-update-mutation.ts b/modules/customers/src/web/common/hooks/use-customer-update-mutation.ts index 8513c0eb..8f229f8d 100644 --- a/modules/customers/src/web/common/hooks/use-customer-update-mutation.ts +++ b/modules/customers/src/web/common/hooks/use-customer-update-mutation.ts @@ -4,6 +4,7 @@ import { type DefaultError, useMutation, useQueryClient } from "@tanstack/react- import { UpdateCustomerByIdRequestSchema } from "../../../common"; import type { Customer } from "../api"; +import type { CustomerData } from "../types"; import { toValidationErrors } from "./toValidationErrors"; @@ -13,7 +14,7 @@ type UpdateCustomerContext = {}; type UpdateCustomerPayload = { id: string; - data: Partial; + data: Partial; }; export const useCustomerUpdateMutation = () => { diff --git a/modules/customers/src/web/common/index.ts b/modules/customers/src/web/common/index.ts index 35312304..0733bf1a 100644 --- a/modules/customers/src/web/common/index.ts +++ b/modules/customers/src/web/common/index.ts @@ -1,2 +1,3 @@ export * from "./api"; export * from "./hooks"; +export * from "./types"; diff --git a/modules/customers/src/web/common/types.ts b/modules/customers/src/web/common/types.ts new file mode 100644 index 00000000..70d2d083 --- /dev/null +++ b/modules/customers/src/web/common/types.ts @@ -0,0 +1,3 @@ +import type { Customer } from "./api"; + +export type CustomerData = Customer; diff --git a/modules/customers/src/web/components/editor/customer-edit-form.tsx b/modules/customers/src/web/components/editor/customer-edit-form.tsx index a2f293aa..5ae88c01 100644 --- a/modules/customers/src/web/components/editor/customer-edit-form.tsx +++ b/modules/customers/src/web/components/editor/customer-edit-form.tsx @@ -1,4 +1,3 @@ -import { FormDebug } from "@erp/core/components"; import { cn } from "@repo/shadcn-ui/lib/utils"; import { CustomerAdditionalConfigFields } from "./customer-additional-config-fields"; @@ -16,8 +15,7 @@ type CustomerFormProps = { export const CustomerEditForm = ({ formId, onSubmit, className, focusRef }: CustomerFormProps) => { return (
    - -
    +
    diff --git a/modules/customers/src/web/components/editor/customer-taxes-multi-select.tsx b/modules/customers/src/web/components/editor/customer-taxes-multi-select.tsx index d7a951ea..5599515b 100644 --- a/modules/customers/src/web/components/editor/customer-taxes-multi-select.tsx +++ b/modules/customers/src/web/components/editor/customer-taxes-multi-select.tsx @@ -45,8 +45,8 @@ export const CustomerTaxesMultiSelect = (props: CustomerTaxesMultiSelect) => { animation={0} autoFilter={true} className={cn( - "flex w-full -mt-0.5 px-1 py-0.5 rounded-md border min-h-8 h-auto items-center justify-between bg-background hover:bg-inherit [&_svg]:pointer-events-auto", - "hover:border-ring hover:ring-ring/50 hover:ring-[2px]", + "flex w-full -mt-0.5 px-1 py-0.5 rounded-md border border-input min-h-8 h-auto items-center justify-between hover:bg-inherit [&_svg]:pointer-events-auto", + "hover:border-ring hover:ring-ring/50 hover:ring-[2px] font-medium bg-muted/50", className )} defaultValue={value} diff --git a/modules/customers/src/web/schemas/index.ts b/modules/customers/src/web/schemas/index.ts index 8a8efbb0..6f1fb312 100644 --- a/modules/customers/src/web/schemas/index.ts +++ b/modules/customers/src/web/schemas/index.ts @@ -1,3 +1,2 @@ export * from "./customer.api.schema"; export * from "./customer.form.schema"; -export * from "./customer-resume.form.schema"; diff --git a/modules/customers/src/web/update/controllers/use-customer-update-page.controller.ts b/modules/customers/src/web/update/controllers/use-customer-update-page.controller.ts index e74bb275..24d2e850 100644 --- a/modules/customers/src/web/update/controllers/use-customer-update-page.controller.ts +++ b/modules/customers/src/web/update/controllers/use-customer-update-page.controller.ts @@ -6,12 +6,8 @@ import { type FieldErrors, FormProvider } from "react-hook-form"; import { useCustomerGetQuery, useCustomerUpdateMutation } from "../../common"; import { useTranslation } from "../../i18n"; -import { - type Customer, - type CustomerFormData, - CustomerFormSchema, - defaultCustomerFormData, -} from "../../schemas"; +import { type Customer, CustomerFormSchema, defaultCustomerFormData } from "../../schemas"; +import type { CustomerFormData } from "../types"; export interface UseCustomerUpdateControllerOptions { onUpdated?(updated: Customer): void; diff --git a/modules/customers/src/web/update/types/types.ts b/modules/customers/src/web/update/types/types.ts index bb510873..abda9345 100644 --- a/modules/customers/src/web/update/types/types.ts +++ b/modules/customers/src/web/update/types/types.ts @@ -1,3 +1,89 @@ -import type { Customer } from "../api"; +import { z } from "zod/v4"; -export type CustomerData = Customer; +export const CustomerFormSchema = z.object({ + reference: z.string().optional(), + + is_company: z.string().default("true"), + name: z + .string({ + error: "El nombre es obligatorio", + }) + .min(1, "El nombre no puede estar vacío"), + trade_name: z.string().optional(), + tin: z.string().optional(), + default_taxes: z.array(z.string()).default([]), + + street: z.string().optional(), + street2: z.string().optional(), + city: z.string().optional(), + province: z.string().optional(), + postal_code: z.string().optional(), + country: z + .string({ + error: "El país es obligatorio", + }) + .min(1, "El país no puede estar vacío") + .toLowerCase() // asegura minúsculas + .default("es"), + + email_primary: z.string().optional(), + email_secondary: z.string().optional(), + phone_primary: z.string().optional(), + phone_secondary: z.string().optional(), + mobile_primary: z.string().optional(), + mobile_secondary: z.string().optional(), + + fax: z.string().optional(), + website: z.string().optional(), + + legal_record: z.string().optional(), + + language_code: z + .string({ + error: "El idioma es obligatorio", + }) + .min(1, "Debe indicar un idioma") + .toUpperCase() // asegura mayúsculas + .default("es"), + + currency_code: z + .string({ + error: "La moneda es obligatoria", + }) + .min(1, "La moneda no puede estar vacía") + .toUpperCase() // asegura mayúsculas + .default("EUR"), +}); + +export type CustomerFormData = z.infer; + +export const defaultCustomerFormData: CustomerFormData = { + reference: "", + + is_company: "true", + name: "", + trade_name: "", + tin: "", + default_taxes: ["iva_21"], + + street: "", + street2: "", + city: "", + province: "", + postal_code: "", + country: "es", + + email_primary: "", + email_secondary: "", + phone_primary: "", + phone_secondary: "", + mobile_primary: "", + mobile_secondary: "", + + fax: "", + website: "", + + legal_record: "", + language_code: "es", + currency_code: "EUR", +}; diff --git a/modules/customers/src/web/update/ui/pages/customer-update-page.tsx b/modules/customers/src/web/update/ui/pages/customer-update-page.tsx index d3f99f4a..f95efa70 100644 --- a/modules/customers/src/web/update/ui/pages/customer-update-page.tsx +++ b/modules/customers/src/web/update/ui/pages/customer-update-page.tsx @@ -31,6 +31,8 @@ export const CustomerUpdatePage = () => { FormProvider, } = useCustomerUpdateController(initialCustomerId, {}); + console.log("venga!!!"); + if (isLoading) { return ; } @@ -68,7 +70,7 @@ export const CustomerUpdatePage = () => { ); return ( - + { diff --git a/modules/factuges/src/api/infraestructure/express/factuges.routes.ts b/modules/factuges/src/api/infraestructure/express/factuges.routes.ts index 53c38637..cc3d4f8f 100644 --- a/modules/factuges/src/api/infraestructure/express/factuges.routes.ts +++ b/modules/factuges/src/api/infraestructure/express/factuges.routes.ts @@ -2,9 +2,9 @@ import { mockUser, requireAuthenticated, requireCompanyContext } from "@erp/auth import { type ModuleParams, type RequestWithAuth, validateRequest } from "@erp/core/api"; import type { ProformaPublicServices } from "@erp/customer-invoices/api"; import type { CustomerPublicServices } from "@erp/customers/api"; +import { CreateProformaFromFactugesRequestSchema } from "@erp/factuges/common"; import { type NextFunction, type Request, type Response, Router } from "express"; -import { CreateProformaFromFactugesRequestSchema } from "../../../common/dto/request/create-proforma-from-factuges.request.dto"; import type { FactugesInternalDeps } from "../di/factuges.di"; import { CreateProformaFromFactugesController } from "./controllers"; diff --git a/package.json b/package.json index c0230898..e9793694 100644 --- a/package.json +++ b/package.json @@ -25,10 +25,11 @@ "@repo/typescript-config": "workspace:*", "@typescript-eslint/eslint-plugin": "^8.56.1", "@typescript-eslint/parser": "^8.56.1", + "baseline-browser-mapping": "^2.10.8", "change-case": "^5.4.4", "inquirer": "^12.10.0", - "plop": "^4.0.4", - "rimraf": "^5.0.5", + "plop": "^4.0.5", + "rimraf": "^6.0.0", "ts-node": "^10.9.2", "turbo": "^2.5.8", "typescript": "5.9.3" diff --git a/packages/rdx-ui/src/components/form/SelectField.tsx b/packages/rdx-ui/src/components/form/SelectField.tsx index aa6fd35c..eb7e0b51 100644 --- a/packages/rdx-ui/src/components/form/SelectField.tsx +++ b/packages/rdx-ui/src/components/form/SelectField.tsx @@ -1,32 +1,43 @@ import { + Field, + FieldDescription, + FieldError, + FieldLabel, FormControl, - FormDescription, - FormField, - FormItem, - FormLabel, - FormMessage, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@repo/shadcn-ui/components"; - import { cn } from "@repo/shadcn-ui/lib/utils"; -import { Control, FieldPath, FieldValues, useController, useFormState } from "react-hook-form"; +import { + type Control, + Controller, + type FieldPath, + type FieldValues, + useController, + useFormState, +} from "react-hook-form"; + import { useTranslation } from "../../locales/i18n.ts"; type SelectFieldProps = { control: Control; name: FieldPath; - items: Array<{ value: string; label: string }>; label?: string; - placeholder?: string; description?: string; disabled?: boolean; required?: boolean; readOnly?: boolean; + + placeholder?: string; + items: Array<{ value: string; label: string }>; + + orientation?: "vertical" | "horizontal" | "responsive"; + className?: string; + inputClassName?: string; }; export function SelectField({ @@ -39,61 +50,61 @@ export function SelectField({ disabled = false, required = false, readOnly = false, + + orientation = "vertical", + className, + inputClassName, }: SelectFieldProps) { const { t } = useTranslation(); - const { isSubmitting, isValidating } = useFormState({ control, name }); + const { isSubmitting } = useFormState({ control, name }); const { field, fieldState } = useController({ control, name }); const isDisabled = disabled || readOnly; return ( - ( - - {label && ( -
    -
    - - {label} - - {required && ( - {t("common.required")} - )} -
    - {/* Punto “unsaved” */} - {fieldState.isDirty && ( - {t("common.modified")} - )} -
    - )} - + render={({ field, fieldState }) => { + return ( + + {label && {label}} - - {description || "\u00A0"} - - -
    - )} + + + {description || "\u00A0"} + + + ); + }} /> ); } diff --git a/packages/rdx-ui/src/components/form/TextAreaField.tsx b/packages/rdx-ui/src/components/form/TextAreaField.tsx index a1ad0726..4f992a2c 100644 --- a/packages/rdx-ui/src/components/form/TextAreaField.tsx +++ b/packages/rdx-ui/src/components/form/TextAreaField.tsx @@ -1,5 +1,3 @@ -// DatePickerField.tsx - import { Field, FieldDescription, @@ -7,19 +5,26 @@ import { FieldLabel, Textarea, } from "@repo/shadcn-ui/components"; +import { cn } from "@repo/shadcn-ui/lib/utils"; +import { + type Control, + Controller, + type FieldPath, + type FieldValues, + useFormState, +} from "react-hook-form"; -import { cn } from '@repo/shadcn-ui/lib/utils'; -import { Control, Controller, FieldPath, FieldValues, useFormState } from "react-hook-form"; -import { CommonInputProps } from "./types.js"; +import type { CommonInputProps } from "./types.js"; type TextAreaFieldProps = CommonInputProps & { control: Control; name: FieldPath; - label?: string; + required?: boolean; + readOnly?: boolean; description?: string; - orientation?: "vertical" | "horizontal" | "responsive", + orientation?: "vertical" | "horizontal" | "responsive"; inputClassName?: string; }; @@ -32,14 +37,14 @@ export function TextAreaField({ required = false, readOnly = false, - orientation = 'vertical', + orientation = "vertical", className, inputClassName, ...inputRest }: TextAreaFieldProps) { - const { isSubmitting, isValidating } = useFormState({ control, name }); + const { isSubmitting } = useFormState({ control, name }); const disabled = isSubmitting || inputRest.disabled; return ( @@ -48,25 +53,30 @@ export function TextAreaField({ name={name} render={({ field, fieldState }) => { return ( - - {label && {label}} + + {label && {label}}