diff --git a/modules/customer-invoices/src/web/proformas/update/ui/blocks/selected-recipient/customer-card.tsx b/modules/customer-invoices/src/web/proformas/update/ui/blocks/selected-recipient/customer-card.tsx
index 1d45932d..a77c7cd1 100644
--- a/modules/customer-invoices/src/web/proformas/update/ui/blocks/selected-recipient/customer-card.tsx
+++ b/modules/customer-invoices/src/web/proformas/update/ui/blocks/selected-recipient/customer-card.tsx
@@ -15,20 +15,20 @@ interface CustomerCardProps {
function buildAddress(customer: CustomerSummary) {
// Línea 1: calle(s)
- const line1 = [customer.street, customer.street2].filter(Boolean).join(", ");
+ const line1 = [customer.address.street, customer.address.street2].filter(Boolean).join(", ");
// Línea 2: CP + ciudad con espacio no rompible entre CP y ciudad
const line2Parts: string[] = [];
- if (customer.postal_code && customer.city) {
- line2Parts.push(`${customer.postal_code}\u00A0${customer.city}`); // CP Ciudad
+ if (customer.address.postal_code && customer.address.city) {
+ line2Parts.push(`${customer.address.postal_code}\u00A0${customer.address.city}`); // CP Ciudad
} else {
- if (customer.postal_code) line2Parts.push(customer.postal_code);
- if (customer.city) line2Parts.push(customer.city);
+ if (customer.address.postal_code) line2Parts.push(customer.address.postal_code);
+ if (customer.address.city) line2Parts.push(customer.address.city);
}
const line2 = line2Parts.join(" ");
// Línea 3: provincia + país
- const line3 = [customer.province, customer.country].filter(Boolean).join(", ");
+ const line3 = [customer.address.province, customer.address.country].filter(Boolean).join(", ");
const stack = [line1, line2, line3].filter(Boolean);
const inline = stack.join(" · "); // separador compacto
diff --git a/modules/customer-invoices/src/web/proformas/update/ui/blocks/selected-recipient/selected-recipient-summary.tsx b/modules/customer-invoices/src/web/proformas/update/ui/blocks/selected-recipient/selected-recipient-summary.tsx
index 4fd1a77a..fa8a826b 100644
--- a/modules/customer-invoices/src/web/proformas/update/ui/blocks/selected-recipient/selected-recipient-summary.tsx
+++ b/modules/customer-invoices/src/web/proformas/update/ui/blocks/selected-recipient/selected-recipient-summary.tsx
@@ -1,5 +1,23 @@
import type { CustomerSelectionOption } from "@erp/customers";
-import { Button } from "@repo/shadcn-ui/components";
+import {
+ Badge,
+ Button,
+ Tooltip,
+ TooltipContent,
+ TooltipProvider,
+ TooltipTrigger,
+} from "@repo/shadcn-ui/components";
+import { cn } from "@repo/shadcn-ui/lib/utils";
+import {
+ Building2Icon,
+ ExternalLinkIcon,
+ MailIcon,
+ MapPinIcon,
+ PhoneIcon,
+ PlusIcon,
+ RefreshCwIcon,
+ UserIcon,
+} from "lucide-react";
import { useTranslation } from "../../../../../i18n";
@@ -8,8 +26,40 @@ type SelectedRecipientSummaryProps = {
readOnly?: boolean;
recipient?: CustomerSelectionOption | null;
+
onChangeClick: () => void;
onCreateClick?: () => void;
+ onViewClick?: (recipient: CustomerSelectionOption) => void;
+};
+
+const buildCustomerAddress = (recipient: CustomerSelectionOption): string => {
+ return [
+ recipient.street,
+ recipient.street2,
+ [recipient.postalCode, recipient.city].filter(Boolean).join(" "),
+ recipient.province,
+ recipient.country,
+ ]
+ .filter(Boolean)
+ .join(", ");
+};
+
+const getCustomerStatusBadgeClassName = (status: string): string => {
+ const normalizedStatus = status.toLowerCase();
+
+ if (["active", "activo", "enabled"].includes(normalizedStatus)) {
+ return "border-emerald-200 bg-emerald-50 text-emerald-700";
+ }
+
+ if (["inactive", "inactivo", "disabled"].includes(normalizedStatus)) {
+ return "border-muted bg-muted text-muted-foreground";
+ }
+
+ if (["blocked", "bloqueado"].includes(normalizedStatus)) {
+ return "border-destructive/20 bg-destructive/10 text-destructive";
+ }
+
+ return "border-border bg-muted/50 text-muted-foreground";
};
export const SelectedRecipientSummary = ({
@@ -19,43 +69,177 @@ export const SelectedRecipientSummary = ({
recipient,
onChangeClick,
onCreateClick,
+ onViewClick,
}: SelectedRecipientSummaryProps) => {
const { t } = useTranslation();
+ const showActions = !(readOnly || disabled);
+ const address = recipient ? buildCustomerAddress(recipient) : "";
+ const phone = recipient?.primaryPhone ?? recipient?.primaryMobile;
+
return (
-
-
-
- {recipient ? (
-
-
{recipient.name}
- {recipient.tin ? (
-
{recipient.tin}
- ) : null}
-
- ) : (
-
- {t("customers.selected_customer.empty", "No hay ningún cliente seleccionado")}
-
- )}
+
+
+
+
+ {recipient?.isCompany ? (
+
+ ) : (
+
+ )}
+
+
+
+ {recipient ? (
+
+
+
+
+
{recipient.name}
+
+ {recipient.status ? (
+
+ {recipient.status}
+
+ ) : null}
+
+
+ {recipient.tradeName && recipient.tradeName !== recipient.name ? (
+
+ {recipient.tradeName}
+
+ ) : null}
+
+ {recipient.tin ? (
+
{recipient.tin}
+ ) : null}
+
+
+
+ {recipient.primaryEmail ? (
+
+
+ {recipient.primaryEmail}
+
+ ) : null}
+
+ {phone ? (
+
+ ) : null}
+
+
+
+
+ {address ? (
+
+
+
+
+ {address}
+
+ }
+ />
+
+
+ {address}
+
+
+
+ ) : (
+
+ {t("customers.selected_customer.no_address", "Sin dirección registrada")}
+
+ )}
+
+
+ ) : (
+
+
+ {t("customers.selected_customer.empty_title", "Cliente no seleccionado")}
+
+
+ {t("customers.selected_customer.empty", "Selecciona o crea un cliente")}
+
+
+ )}
+
-
- {onCreateClick && !readOnly && !disabled && (
-
- )}
+ {showActions ? (
+
+ {recipient && onViewClick ? (
+
+ ) : null}
- {onChangeClick && !readOnly && !disabled && (
-
+
+ ) : null}
);
};
+
+const buildAddress = (recipient: CustomerSelectionOption): string => {
+ // Línea 1: calle(s)
+ const line1 = [recipient.street, recipient.street2].filter(Boolean).join(", ");
+
+ // Línea 2: CP + ciudad con espacio no rompible entre CP y ciudad
+ const line2Parts: string[] = [];
+ if (recipient.postalCode && recipient.city) {
+ line2Parts.push(`${recipient.postalCode}\u00A0${recipient.city}`); // CP Ciudad
+ } else {
+ if (recipient.postalCode) line2Parts.push(recipient.postalCode);
+ if (recipient.city) line2Parts.push(recipient.city);
+ }
+ const line2 = line2Parts.join(" ");
+
+ // Línea 3: provincia + país
+ const line3 = [recipient.province, recipient.country].filter(Boolean).join(", ");
+
+ const stack = [line1, line2, line3].filter(Boolean);
+ const inline = stack.join(" · "); // separador compacto
+ const full = stack.join(", ");
+
+ return { has: stack.length > 0, stack, inline, full };
+};
diff --git a/modules/customer-invoices/src/web/proformas/update/ui/editors/proforma-update-header-editor.tsx b/modules/customer-invoices/src/web/proformas/update/ui/editors/proforma-update-header-editor.tsx
index aca168a3..2daa188d 100644
--- a/modules/customer-invoices/src/web/proformas/update/ui/editors/proforma-update-header-editor.tsx
+++ b/modules/customer-invoices/src/web/proformas/update/ui/editors/proforma-update-header-editor.tsx
@@ -6,6 +6,7 @@ import {
TextAreaField,
TextField,
} from "@repo/rdx-ui/components";
+import { FileTextIcon } from "lucide-react";
import { useTranslation } from "../../../../i18n";
@@ -23,6 +24,8 @@ export const ProformaUpdateHeaderEditor = ({
return (
}
title={t("form_groups.proformas.basic_info.title")}
>
@@ -83,7 +86,6 @@ export const ProformaUpdateHeaderEditor = ({
placeholder={t("form_fields.proformas.notes.placeholder")}
readOnly={readOnly}
/>
-
);
diff --git a/modules/customer-invoices/src/web/proformas/update/ui/editors/proforma-update-items-editor.tsx b/modules/customer-invoices/src/web/proformas/update/ui/editors/proforma-update-items-editor.tsx
index 52f82a77..1a7563d3 100644
--- a/modules/customer-invoices/src/web/proformas/update/ui/editors/proforma-update-items-editor.tsx
+++ b/modules/customer-invoices/src/web/proformas/update/ui/editors/proforma-update-items-editor.tsx
@@ -1,4 +1,5 @@
import { FormSectionCard } from "@repo/rdx-ui/components";
+import { ListIcon } from "lucide-react";
import type { ComponentProps } from "react";
import { useTranslation } from "../../../../i18n";
@@ -19,6 +20,8 @@ export const ProformaUpdateItemsEditor = ({
return (
}
title={t("form_groups.items.title")}
>
+ }
+ title={t("form_groups.proformas.customer.title", "Cliente")}
+ >
{
}}
/>
}
- title={t("pages.proformas.update.title")}
+ title={<>{t("pages.proformas.update.title")}>}
/>
diff --git a/modules/customers/src/common/features/customer-selection/entities/customer-selection-option.entity.ts b/modules/customers/src/common/features/customer-selection/entities/customer-selection-option.entity.ts
index 3ce47d45..31bf0245 100644
--- a/modules/customers/src/common/features/customer-selection/entities/customer-selection-option.entity.ts
+++ b/modules/customers/src/common/features/customer-selection/entities/customer-selection-option.entity.ts
@@ -5,25 +5,21 @@
*/
export interface CustomerSelectionOption {
id: string;
- //status: string;
+ status: string;
- //isCompany: boolean;
+ isCompany: boolean;
name: string;
- //tradeName: string;
- tin: string;
+ tradeName: string | null;
+ tin: string | null;
- /*street: string;
- street2: string;
- city: string;
- province: string;
- postalCode: string;
- country: string;
- */
+ street: string | null;
+ street2: string | null;
+ city: string | null;
+ province: string | null;
+ postalCode: string | null;
+ country: string | null;
- //emailPrimary: string;
- //primaryPhone: string;
- //primaryMobile: string;
-
- languageCode: string;
- currencyCode: string;
+ primaryEmail: string | null;
+ primaryPhone: string | null;
+ primaryMobile: string | null;
}
diff --git a/modules/customers/src/common/features/customer-selection/utils/build-customer-selection-option.ts b/modules/customers/src/common/features/customer-selection/utils/build-customer-selection-option.ts
index dc105c62..c7a1550a 100644
--- a/modules/customers/src/common/features/customer-selection/utils/build-customer-selection-option.ts
+++ b/modules/customers/src/common/features/customer-selection/utils/build-customer-selection-option.ts
@@ -13,11 +13,18 @@ export const buildCustomerSelectionOption = (
isCompany: customer.isCompany,
name: customer.name,
+ tradeName: customer.tradeName,
tin: customer.tin,
- EmailPrimary: customer.EmailPrimary,
+ street: customer.address.street,
+ street2: null,
+ city: customer.address.city,
+ province: customer.address.province,
+ postalCode: customer.address.postalCode,
+ country: customer.address.country,
- languageCode: customer.languageCode,
- currencyCode: customer.currencyCode,
+ primaryEmail: customer.contact.primaryEmail,
+ primaryPhone: customer.contact.primaryPhone,
+ primaryMobile: customer.contact.primaryMobile,
};
};
diff --git a/packages/rdx-ui/src/components/form/form-section-card.tsx b/packages/rdx-ui/src/components/form/form-section-card.tsx
index de28fe13..0565effe 100644
--- a/packages/rdx-ui/src/components/form/form-section-card.tsx
+++ b/packages/rdx-ui/src/components/form/form-section-card.tsx
@@ -13,7 +13,11 @@ import type { ReactNode } from "react";
interface FormSectionCardProps {
title?: string;
description?: string;
+ icon?: ReactNode;
+ disabled?: boolean;
+
children: ReactNode;
+
className?: string;
headerClassName?: string;
contentClassName?: string;
@@ -22,7 +26,11 @@ interface FormSectionCardProps {
export const FormSectionCard = ({
title,
description,
+ icon,
+ disabled = false,
+
children,
+
className,
headerClassName,
contentClassName,
@@ -30,17 +38,32 @@ export const FormSectionCard = ({
const hasHeader = Boolean(title || description);
return (
-
-