@@ -216,6 +217,6 @@ export function useCustomersGridColumns(
},
},
],
- [t, onDeleteClick, onEditClick, onViewClick]
+ [t, onDeleteClick, onEditClick, onViewClick, onSummaryClick]
);
}
diff --git a/modules/customers/src/web/list/ui/blocks/index.ts b/modules/customers/src/web/list/ui/blocks/index.ts
index 23fe20b5..5ed67835 100644
--- a/modules/customers/src/web/list/ui/blocks/index.ts
+++ b/modules/customers/src/web/list/ui/blocks/index.ts
@@ -1 +1,2 @@
+export * from "./customer-sheet";
export * from "./customers-grid";
diff --git a/modules/customers/src/web/list/ui/components/address-cell.tsx b/modules/customers/src/web/list/ui/components/address-cell.tsx
index 2408526f..948c6e1c 100644
--- a/modules/customers/src/web/list/ui/components/address-cell.tsx
+++ b/modules/customers/src/web/list/ui/components/address-cell.tsx
@@ -4,14 +4,14 @@ import { useTranslation } from "../../../i18n";
import type { CustomerListRow } from "../../../shared";
const getGoogleMapsUrl = (customer: CustomerListRow) => {
- const fullAddress = `${customer.street}, ${customer.postal_code} ${customer.city}, ${customer.province}, ${customer.country}`;
+ const fullAddress = `${customer.street}, ${customer.postalCode} ${customer.city}, ${customer.province}, ${customer.country}`;
return `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(fullAddress)}`;
};
export const AddressCell = ({ customer }: { customer: CustomerListRow }) => {
const { t } = useTranslation();
const line1 = [customer.street, customer.street2].filter(Boolean).join(", ");
- const line2 = [customer.postal_code, customer.city].filter(Boolean).join(" ");
+ const line2 = [customer.postalCode, customer.city].filter(Boolean).join(" ");
const line3 = [customer.province, customer.country].filter(Boolean).join(", ");
return (
diff --git a/modules/customers/src/web/list/ui/components/contact-cell.tsx b/modules/customers/src/web/list/ui/components/contact-cell.tsx
index 779ddc8b..79f80704 100644
--- a/modules/customers/src/web/list/ui/components/contact-cell.tsx
+++ b/modules/customers/src/web/list/ui/components/contact-cell.tsx
@@ -3,32 +3,32 @@ import { MailIcon, PhoneIcon } from "lucide-react";
export const ContactCell = ({ customer }: { customer: CustomerListRow }) => (
diff --git a/modules/customers/src/web/list/ui/pages/list-customers-page.tsx b/modules/customers/src/web/list/ui/pages/list-customers-page.tsx
index 4acba309..a6efebfe 100644
--- a/modules/customers/src/web/list/ui/pages/list-customers-page.tsx
+++ b/modules/customers/src/web/list/ui/pages/list-customers-page.tsx
@@ -7,21 +7,22 @@ import { useNavigate } from "react-router-dom";
import { useTranslation } from "../../../i18n";
import { ErrorAlert } from "../../../shared/ui";
import { useListCustomersPageController } from "../../controllers";
-import { CustomersGrid, useCustomersGridColumns } from "../blocks";
+import { CustomerSheet, CustomersGrid, useCustomersGridColumns } from "../blocks";
export const ListCustomersPage = () => {
const { t } = useTranslation();
const navigate = useNavigate();
- const { listCtrl } = useListCustomersPageController();
+ const { listCtrl, sheetCtrl } = useListCustomersPageController();
const columns = useCustomersGridColumns({
onEditClick: (customer) => navigate(`/customers/${customer.id}/edit`),
onViewClick: (customer) => navigate(`/customers/${customer.id}`),
+ onSummaryClick: (customer) => sheetCtrl.openCustomerSheet(customer.id),
//onDeleteClick: (customer) => null, //confirmDelete(inv.id),
});
- if (listCtrl.isError || !listCtrl.data) {
+ if (listCtrl.isError) {
return (
{
onPageChange={listCtrl.setPageIndex}
onPageSizeChange={listCtrl.setPageSize}
// acciones rápidas del grid → page controller
- //onRowClick={(id) => navigate(`/proformas/${id}`)}
+ onRowClick={(id) => null}
pageIndex={listCtrl.pageIndex}
pageSize={listCtrl.pageSize}
/>
+
+ {/* Customer Sheet */}
+ navigate(`/customers/${customer.id}/edit`)}
+ onOpenChange={sheetCtrl.sheetState.onOpenChange}
+ onPinnedChange={sheetCtrl.sheetState.setPinned}
+ open={sheetCtrl.sheetState.sheetIsOpen}
+ pinned={sheetCtrl.sheetState.sheetIsPinned}
+ />
>
);
diff --git a/modules/customers/src/web/shared/adapters/get-customer-by-id.adapter.ts b/modules/customers/src/web/shared/adapters/get-customer-by-id.adapter.ts
index b7af9f88..eb77780a 100644
--- a/modules/customers/src/web/shared/adapters/get-customer-by-id.adapter.ts
+++ b/modules/customers/src/web/shared/adapters/get-customer-by-id.adapter.ts
@@ -1,39 +1,46 @@
import type { GetCustomerByIdResponseDTO } from "../../../common";
import type { Customer } from "../entities";
-export const mapGetCustomerByIdResponseDtoToCustomerAdapter = (
- dto: GetCustomerByIdResponseDTO
-): Customer => ({
- id: dto.id,
- companyId: dto.company_id,
- reference: dto.reference,
+export const GetCustomerByIdAdapter = {
+ fromDTO(dto: GetCustomerByIdResponseDTO, context?: unknown): Customer {
+ const taxesAdapter = (taxes: string) => taxes.split(";").filter((item) => item !== "#") || [];
- isCompany: dto.is_company,
- name: dto.name,
- tradeName: dto.trade_name,
- tin: dto.tin,
+ const defaultTaxes = taxesAdapter(dto.default_taxes);
+ console.log("defaultTaxes", defaultTaxes);
- street: dto.street,
- street2: dto.street2,
- city: dto.city,
- province: dto.province,
- postalCode: dto.postal_code,
- country: dto.country,
+ return {
+ id: dto.id,
+ companyId: dto.company_id,
+ reference: dto.reference,
- primaryEmail: dto.email_primary,
- secondaryEmail: dto.email_secondary,
- primaryPhone: dto.phone_primary,
- secondaryPhone: dto.phone_secondary,
- primaryMobile: dto.mobile_primary,
- secondaryMobile: dto.mobile_secondary,
+ isCompany: dto.is_company,
+ name: dto.name,
+ tradeName: dto.trade_name,
+ tin: dto.tin,
- fax: dto.fax,
- website: dto.website,
+ street: dto.street,
+ street2: dto.street2,
+ city: dto.city,
+ province: dto.province,
+ postalCode: dto.postal_code,
+ country: dto.country,
- legalRecord: dto.legal_record,
+ primaryEmail: dto.email_primary,
+ secondaryEmail: dto.email_secondary,
+ primaryPhone: dto.phone_primary,
+ secondaryPhone: dto.phone_secondary,
+ primaryMobile: dto.mobile_primary,
+ secondaryMobile: dto.mobile_secondary,
- defaultTaxes: dto.default_taxes,
- status: dto.status,
- languageCode: dto.language_code,
- currencyCode: dto.currency_code,
-});
+ fax: dto.fax,
+ website: dto.website,
+
+ legalRecord: dto.legal_record,
+
+ defaultTaxes: defaultTaxes,
+ status: dto.status,
+ languageCode: dto.language_code,
+ currencyCode: dto.currency_code,
+ };
+ },
+};
diff --git a/modules/customers/src/web/shared/adapters/list-customers.adapter.ts b/modules/customers/src/web/shared/adapters/list-customers.adapter.ts
index be99f5d7..d2e72322 100644
--- a/modules/customers/src/web/shared/adapters/list-customers.adapter.ts
+++ b/modules/customers/src/web/shared/adapters/list-customers.adapter.ts
@@ -25,33 +25,33 @@ const ListCustomersRowAdapter = {
return {
id: rowDto.id,
- company_id: rowDto.company_id,
+ companyId: rowDto.company_id,
status: rowDto.status,
reference: rowDto.reference,
- is_company: rowDto.is_company === "1",
+ isCompany: rowDto.is_company === "1",
name: rowDto.name,
- trade_name: rowDto.trade_name,
+ tradeName: rowDto.trade_name,
tin: rowDto.tin,
street: rowDto.street,
street2: rowDto.street2,
city: rowDto.city,
province: rowDto.province,
- postal_code: rowDto.postal_code,
+ postalCode: rowDto.postal_code,
country: rowDto.country,
- email_primary: rowDto.email_primary,
- email_secondary: rowDto.email_secondary,
- phone_primary: rowDto.phone_primary,
- phone_secondary: rowDto.phone_secondary,
- mobile_primary: rowDto.mobile_primary,
- mobile_secondary: rowDto.mobile_secondary,
+ primaryEmail: rowDto.email_primary,
+ secondaryEmail: rowDto.email_secondary,
+ primaryPhone: rowDto.phone_primary,
+ secondaryPhone: rowDto.phone_secondary,
+ primaryMobile: rowDto.mobile_primary,
+ secondaryMobile: rowDto.mobile_secondary,
fax: rowDto.fax,
website: rowDto.website,
- language_code: rowDto.language_code,
- currency_code: rowDto.currency_code,
+ languageCode: rowDto.language_code,
+ currencyCode: rowDto.currency_code,
};
},
};
diff --git a/modules/customers/src/web/shared/api/get-customer-by-id.api.ts b/modules/customers/src/web/shared/api/get-customer-by-id.api.ts
index fa1af04b..1f188c5e 100644
--- a/modules/customers/src/web/shared/api/get-customer-by-id.api.ts
+++ b/modules/customers/src/web/shared/api/get-customer-by-id.api.ts
@@ -1,9 +1,9 @@
import type { IDataSource } from "@erp/core/client";
-import type { Customer } from "../entities";
+import type { GetCustomerByIdResponseDTO } from "../../../common";
export async function getCustomerById(dataSource: IDataSource, signal: AbortSignal, id?: string) {
if (!id) throw new Error("customerId is required");
- const response = dataSource.getOne("customers", id, { signal });
+ const response = dataSource.getOne("customers", id, { signal });
return response;
}
diff --git a/modules/customers/src/web/shared/entities/customer-list-row.entity.ts b/modules/customers/src/web/shared/entities/customer-list-row.entity.ts
index 20d2e7c1..adc25731 100644
--- a/modules/customers/src/web/shared/entities/customer-list-row.entity.ts
+++ b/modules/customers/src/web/shared/entities/customer-list-row.entity.ts
@@ -1,30 +1,31 @@
export interface CustomerListRow {
id: string;
- company_id: string;
+ companyId: string;
status: string;
reference: string;
- is_company: boolean;
+ isCompany: boolean;
name: string;
- trade_name: string;
+ tradeName: string;
tin: string;
street: string;
street2: string;
city: string;
province: string;
- postal_code: string;
+ postalCode: string;
country: string;
- email_primary: string;
- email_secondary: string;
- phone_primary: string;
- phone_secondary: string;
- mobile_primary: string;
- mobile_secondary: string;
+ primaryEmail: string;
+ secondaryEmail: string;
+ primaryPhone: string;
+ secondaryPhone: string;
+ primaryMobile: string;
+ secondaryMobile: string;
+
fax: string;
website: string;
- language_code: string;
- currency_code: string;
+ languageCode: string;
+ currencyCode: string;
}
diff --git a/modules/customers/src/web/shared/hooks/use-customer-get-query.ts b/modules/customers/src/web/shared/hooks/use-customer-get-query.ts
index 816d5fa7..b324dbe2 100644
--- a/modules/customers/src/web/shared/hooks/use-customer-get-query.ts
+++ b/modules/customers/src/web/shared/hooks/use-customer-get-query.ts
@@ -6,7 +6,9 @@ import {
useQuery,
} from "@tanstack/react-query";
-import { type Customer, getCustomerById } from "../api";
+import { GetCustomerByIdAdapter } from "../adapters";
+import { getCustomerById } from "../api";
+import type { Customer } from "../entities";
export const CUSTOMER_QUERY_KEY = (customerId?: string): QueryKey => [
"customers:detail",
@@ -28,9 +30,12 @@ export const useCustomerGetQuery = (
return useQuery({
queryKey: CUSTOMER_QUERY_KEY(customerId),
- queryFn: async ({ signal }) => getCustomerById(dataSource, signal, customerId),
+ queryFn: async ({ signal }) => {
+ const dto = await getCustomerById(dataSource, signal, customerId);
+ return GetCustomerByIdAdapter.fromDTO(dto);
+ },
enabled,
- placeholderData: (previousData, _previousQuery) => previousData, // Mantener datos previos mientras se carga nueva datos (antiguo `keepPreviousData`)
+ placeholderData: (previousData) => previousData, // Mantener datos previos mientras se carga nueva datos (antiguo `keepPreviousData`)
});
};
diff --git a/modules/customers/src/web/view/adapters/customer-dto.adapter.ts b/modules/customers/src/web/view/adapters/customer-dto.adapter.ts
deleted file mode 100644
index 356d7751..00000000
--- a/modules/customers/src/web/view/adapters/customer-dto.adapter.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import type { Customer } from "../../shared";
-import type { CustomerData } from "../types";
-
-/**
- * Convierte el DTO completo de API a datos numéricos para el formulario.
- */
-export const CustomerDtoAdapter = {
- fromDto(customerDto: Customer, context?: unknown): CustomerData {
- return {
- ...customerDto,
- };
- },
-};
diff --git a/modules/customers/src/web/view/adapters/index.ts b/modules/customers/src/web/view/adapters/index.ts
deleted file mode 100644
index bc45e2cf..00000000
--- a/modules/customers/src/web/view/adapters/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from "./customer-dto.adapter";
diff --git a/modules/customers/src/web/view/controllers/use-customer-view.controller.ts b/modules/customers/src/web/view/controllers/use-customer-view.controller.ts
index 3758c130..222a0936 100644
--- a/modules/customers/src/web/view/controllers/use-customer-view.controller.ts
+++ b/modules/customers/src/web/view/controllers/use-customer-view.controller.ts
@@ -1,20 +1,22 @@
-import { useMemo, useState } from "react";
+import { useState } from "react";
import { useCustomerGetQuery } from "../../shared/hooks";
-import { CustomerDtoAdapter } from "../adapters";
-export const useCustomerViewController = () => {
- const [customerId, setCustomerId] = useState("");
+export const useCustomerViewController = (initialCustomerId = "") => {
+ const [customerId, setCustomerId] = useState(initialCustomerId);
const query = useCustomerGetQuery(customerId);
- const data = useMemo(
- () => (query.data ? CustomerDtoAdapter.fromDto(query.data) : undefined),
- [query.data]
- );
return {
- ...query,
- data,
+ data: query.data,
+ isLoading: query.isLoading,
+ isFetching: query.isFetching,
+
+ isError: query.isError,
+ error: query.error,
+
+ refetch: query.refetch,
+
customerId,
setCustomerId,
};
diff --git a/modules/customers/src/web/view/types/index.ts b/modules/customers/src/web/view/types/index.ts
deleted file mode 100644
index eea524d6..00000000
--- a/modules/customers/src/web/view/types/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from "./types";
diff --git a/modules/customers/src/web/view/types/types.ts b/modules/customers/src/web/view/types/types.ts
deleted file mode 100644
index 5c235d22..00000000
--- a/modules/customers/src/web/view/types/types.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import type { Customer } from "../../shared/api";
-
-export type CustomerData = Customer;
diff --git a/modules/customers/src/web/view/ui/pages/customer-view-page.tsx b/modules/customers/src/web/view/ui/pages/customer-view-page.tsx
index 324675df..e0e35e80 100644
--- a/modules/customers/src/web/view/ui/pages/customer-view-page.tsx
+++ b/modules/customers/src/web/view/ui/pages/customer-view-page.tsx
@@ -77,7 +77,7 @@ export const CustomerViewPage = () => {
{customerData?.tin}
- {customerData?.is_company ? "Empresa" : "Persona"}
+ {customerData?.isCompany ? "Empresa" : "Persona"}
}
rightSlot={
@@ -102,8 +102,8 @@ export const CustomerViewPage = () => {
title={
{customerData?.name}{" "}
- {customerData?.trade_name && (
- ({customerData.trade_name})
+ {customerData?.tradeName && (
+ ({customerData.tradeName})
)}
}
@@ -133,12 +133,12 @@ export const CustomerViewPage = () => {