feat: mejorar la interfaz de usuario en las secciones de configuración de verifactu y detalles de la empresa

This commit is contained in:
David Arranz 2026-09-05 11:52:53 +02:00
parent bbca943c87
commit 81da489ca8
6 changed files with 290 additions and 244 deletions

View File

@ -77,7 +77,18 @@ mock.module("@repo/rdx-ui/components", {
RdxPanel: ({ children, title }: { children: ReactNode; title: string }) => ( RdxPanel: ({ children, title }: { children: ReactNode; title: string }) => (
<section data-title={title}>{children}</section> <section data-title={title}>{children}</section>
), ),
RdxEditorStickyFooter: () => null, RdxEditorActionBar: ({
primary,
secondary,
}: {
primary?: ReactNode;
secondary?: ReactNode;
}) => (
<div>
{secondary}
{primary}
</div>
),
RdxFormGrid: ({ children }: { children: ReactNode }) => <div>{children}</div>, RdxFormGrid: ({ children }: { children: ReactNode }) => <div>{children}</div>,
RhfSubmitActionButton: (props: Record<string, unknown>) => { RhfSubmitActionButton: (props: Record<string, unknown>) => {
capturedSubmitProps = props; capturedSubmitProps = props;
@ -94,6 +105,14 @@ mock.module("@repo/rdx-ui/components", {
}, },
}); });
mock.module("@repo/shadcn-ui/components", {
namedExports: {
Card: ({ children }: { children: ReactNode }) => <section>{children}</section>,
CardContent: ({ children }: { children: ReactNode }) => <div>{children}</div>,
CardHeader: ({ children }: { children: ReactNode }) => <header>{children}</header>,
},
});
mock.module("react-hook-form", { mock.module("react-hook-form", {
namedExports: { namedExports: {
FormProvider: ({ children }: { children: ReactNode }) => children, FormProvider: ({ children }: { children: ReactNode }) => children,

View File

@ -10,7 +10,8 @@ import {
SelectField, SelectField,
TextField, TextField,
} from "@repo/rdx-ui/components"; } from "@repo/rdx-ui/components";
import { ContactIcon, LandmarkIcon, ScrollTextIcon } from "lucide-react"; import { Card, CardContent, CardHeader } from "@repo/shadcn-ui/components";
import { Building2Icon, ContactIcon, LandmarkIcon, ScrollTextIcon } from "lucide-react";
import { FormProvider } from "react-hook-form"; import { FormProvider } from "react-hook-form";
import { useTranslation } from "../../../../i18n"; import { useTranslation } from "../../../../i18n";
@ -64,16 +65,23 @@ export const CompanyDetailsSettingsPage = () => {
return ( return (
<FormProvider {...ctrl.form}> <FormProvider {...ctrl.form}>
<UnsavedChangesProvider isDirty={ctrl.form.formState.isDirty}> <UnsavedChangesProvider isDirty={ctrl.form.formState.isDirty}>
<div className="flex min-h-[24rem] flex-col gap-6"> <Card>
<div className="space-y-2"> <CardHeader>
<div className="flex min-w-0 items-start gap-4">
<div className="flex size-11 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary">
<Building2Icon aria-hidden className="size-6" />
</div>
<div className="min-w-0 space-y-1">
<h2 className="text-2xl font-semibold tracking-tight"> <h2 className="text-2xl font-semibold tracking-tight">
{t("settings.companyDetails.title")} {t("settings.companyDetails.title")}
</h2> </h2>
<p className="max-w-3xl text-sm text-muted-foreground"> <p className="text-sm text-muted-foreground">
{t("settings.companyDetails.description")} {t("settings.companyDetails.description")}
</p> </p>
</div> </div>
</div>
</CardHeader>
<CardContent className="space-y-6">
{ctrl.inlineLoadError ? ( {ctrl.inlineLoadError ? (
<ErrorAlert <ErrorAlert
message={ctrl.inlineLoadError.description} message={ctrl.inlineLoadError.description}
@ -92,7 +100,7 @@ export const CompanyDetailsSettingsPage = () => {
description={t("settings.companyDetails.sections.general.description")} description={t("settings.companyDetails.sections.general.description")}
icon={<ScrollTextIcon className="size-5" />} icon={<ScrollTextIcon className="size-5" />}
title={t("settings.companyDetails.sections.general.title")} title={t("settings.companyDetails.sections.general.title")}
variant="card" variant="plain"
> >
<RdxFormGrid className="md:grid-cols-2"> <RdxFormGrid className="md:grid-cols-2">
<TextField<CompanySettingsForm> <TextField<CompanySettingsForm>
@ -124,12 +132,16 @@ export const CompanyDetailsSettingsPage = () => {
/> />
<TextField<CompanySettingsForm> <TextField<CompanySettingsForm>
description={t("settings.companyDetails.sections.general.fields.tin.description")} description={t(
"settings.companyDetails.sections.general.fields.tin.description"
)}
disabled={ctrl.isSaving} disabled={ctrl.isSaving}
inputClassName="bg-background" inputClassName="bg-background"
label={t("settings.companyDetails.sections.general.fields.tin.label")} label={t("settings.companyDetails.sections.general.fields.tin.label")}
name="tin" name="tin"
placeholder={t("settings.companyDetails.sections.general.fields.tin.placeholder")} placeholder={t(
"settings.companyDetails.sections.general.fields.tin.placeholder"
)}
/> />
</RdxFormGrid> </RdxFormGrid>
</RdxPanel> </RdxPanel>
@ -138,7 +150,7 @@ export const CompanyDetailsSettingsPage = () => {
description={t("settings.companyDetails.sections.contact.description")} description={t("settings.companyDetails.sections.contact.description")}
icon={<ContactIcon className="size-5" />} icon={<ContactIcon className="size-5" />}
title={t("settings.companyDetails.sections.contact.title")} title={t("settings.companyDetails.sections.contact.title")}
variant="card" variant="plain"
> >
<RdxFormGrid className="md:grid-cols-2"> <RdxFormGrid className="md:grid-cols-2">
<TextField<CompanySettingsForm> <TextField<CompanySettingsForm>
@ -190,21 +202,25 @@ export const CompanyDetailsSettingsPage = () => {
description={t("settings.companyDetails.sections.paymentTerm.description")} description={t("settings.companyDetails.sections.paymentTerm.description")}
icon={<LandmarkIcon className="size-5" />} icon={<LandmarkIcon className="size-5" />}
title={t("settings.companyDetails.sections.paymentTerm.title")} title={t("settings.companyDetails.sections.paymentTerm.title")}
variant="card" variant="plain"
> >
<RdxFormGrid className="md:grid-cols-2"> <RdxFormGrid className="md:grid-cols-2">
<SelectField<CompanySettingsForm> <SelectField<CompanySettingsForm>
className="col-span-full" className="col-span-full"
clearable clearable
clearLabel={t("settings.companyDetails.sections.paymentTerm.field.none")} clearLabel={t("settings.companyDetails.sections.paymentTerm.field.none")}
description={t("settings.companyDetails.sections.paymentTerm.field.description")} description={t(
"settings.companyDetails.sections.paymentTerm.field.description"
)}
disabled={ctrl.isSaving} disabled={ctrl.isSaving}
emptyValue="" emptyValue=""
inputClassName="bg-background" inputClassName="bg-background"
items={ctrl.paymentTermOptions} items={ctrl.paymentTermOptions}
label={t("settings.companyDetails.sections.paymentTerm.field.label")} label={t("settings.companyDetails.sections.paymentTerm.field.label")}
name="defaultPaymentTermId" name="defaultPaymentTermId"
placeholder={t("settings.companyDetails.sections.paymentTerm.field.placeholder")} placeholder={t(
"settings.companyDetails.sections.paymentTerm.field.placeholder"
)}
/> />
</RdxFormGrid> </RdxFormGrid>
</RdxPanel> </RdxPanel>
@ -235,7 +251,8 @@ export const CompanyDetailsSettingsPage = () => {
/> />
} }
/> />
</div> </CardContent>
</Card>
</UnsavedChangesProvider> </UnsavedChangesProvider>
</FormProvider> </FormProvider>
); );

View File

@ -6,6 +6,8 @@ import {
RdxEditorActionBar, RdxEditorActionBar,
RhfSubmitActionButton, RhfSubmitActionButton,
} from "@repo/rdx-ui/components"; } from "@repo/rdx-ui/components";
import { Card, CardContent, CardHeader } from "@repo/shadcn-ui/components";
import { ShieldCheckIcon } from "lucide-react";
import { FormProvider } from "react-hook-form"; import { FormProvider } from "react-hook-form";
import { useTranslation } from "../../../../i18n"; import { useTranslation } from "../../../../i18n";
@ -51,12 +53,17 @@ export const CompanyVerifactuSettingsPage = () => {
return ( return (
<FormProvider {...profileCtrl.form}> <FormProvider {...profileCtrl.form}>
<UnsavedChangesProvider isDirty={profileCtrl.form.formState.isDirty}> <UnsavedChangesProvider isDirty={profileCtrl.form.formState.isDirty}>
<div className="flex min-h-[32rem] flex-col gap-6"> <Card>
<div className="space-y-2"> <CardHeader>
<div className="flex min-w-0 items-start gap-4">
<div className="flex size-11 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary">
<ShieldCheckIcon aria-hidden className="size-6" />
</div>
<div className="min-w-0 space-y-1">
<h2 className="text-2xl font-semibold tracking-tight"> <h2 className="text-2xl font-semibold tracking-tight">
{t("settings.verifactu.title")} {t("settings.verifactu.title")}
</h2> </h2>
<p className="max-w-3xl text-sm text-muted-foreground"> <p className="text-sm text-muted-foreground">
{t("settings.verifactu.description")} {t("settings.verifactu.description")}
</p> </p>
{ctrl.mode === "initial" ? ( {ctrl.mode === "initial" ? (
@ -65,7 +72,9 @@ export const CompanyVerifactuSettingsPage = () => {
</p> </p>
) : null} ) : null}
</div> </div>
</div>
</CardHeader>
<CardContent className="space-y-6">
{profileCtrl.isUpdateError ? ( {profileCtrl.isUpdateError ? (
<ErrorAlert <ErrorAlert
message={ message={
@ -124,7 +133,8 @@ export const CompanyVerifactuSettingsPage = () => {
/> />
} }
/> />
</div> </CardContent>
</Card>
</UnsavedChangesProvider> </UnsavedChangesProvider>
</FormProvider> </FormProvider>
); );

View File

@ -32,7 +32,7 @@ export const CompanyVerifactuConfigurationSection = ({
description={t("settings.verifactu.configuration.description")} description={t("settings.verifactu.configuration.description")}
icon={<ShieldCheckIcon className="size-5" />} icon={<ShieldCheckIcon className="size-5" />}
title={t("settings.verifactu.configuration.title")} title={t("settings.verifactu.configuration.title")}
variant="card" variant="plain"
> >
<RdxFormGrid className="md:grid-cols-2"> <RdxFormGrid className="md:grid-cols-2">
{showExemptionFields ? ( {showExemptionFields ? (

View File

@ -21,7 +21,7 @@ export const CompanyVerifactuDefaultsSection = ({
description={t("settings.verifactu.defaults.description")} description={t("settings.verifactu.defaults.description")}
icon={<LandmarkIcon className="size-5" />} icon={<LandmarkIcon className="size-5" />}
title={t("settings.verifactu.defaults.title")} title={t("settings.verifactu.defaults.title")}
variant="card" variant="plain"
> >
<RdxFormGrid className="md:grid-cols-2"> <RdxFormGrid className="md:grid-cols-2">
<SelectField <SelectField

View File

@ -23,7 +23,7 @@ export const CompanyVerifactuStatusSection = () => {
description={t("settings.verifactu.status.description")} description={t("settings.verifactu.status.description")}
icon={<FileCogIcon className="size-5" />} icon={<FileCogIcon className="size-5" />}
title={t("settings.verifactu.status.title")} title={t("settings.verifactu.status.title")}
variant="card" variant="plain"
> >
<Controller <Controller
control={control} control={control}