From bf9ed99a90fa56ac26476013a79c8f634cb2d4ec Mon Sep 17 00:00:00 2001 From: david Date: Sat, 7 Mar 2026 19:27:23 +0100 Subject: [PATCH] . --- apps/web/src/routes/app-routes.tsx | 26 +- modules/core/src/api/application/index.ts | 1 + .../core/src/api/application/mappers/index.ts | 1 + .../mappers/mapper.interface.ts} | 18 +- modules/core/src/api/domain/index.ts | 1 - .../core/src/api/domain/repositories/index.ts | 1 - .../mappers/sequelize-domain-mapper.ts | 2 +- .../mappers/sequelize-mapper.interface.ts | 2 +- .../mappers/sequelize-read-model-mapper.ts | 8 +- .../application-models/index.ts | 0 .../application/issued-invoices/dtos/index.ts | 1 - .../api/application/issued-invoices/index.ts | 3 +- ...ssued-invoice-summary-mapper.interface.ts} | 6 +- .../issued-invoices/models/index.ts | 1 + .../issued-invoice-summary.ts} | 2 +- .../issued-invoice-repository.interface.ts | 4 +- .../services/issued-invoice-finder.ts | 6 +- ...sued-invoice-list-item-snapshot-builder.ts | 6 +- .../proformas/application-models/index.ts | 0 .../api/application/proformas/dtos/index.ts | 1 - .../src/api/application/proformas/index.ts | 3 +- .../mappers/proforma-list-mapper.interface.ts | 2 +- .../api/application/proformas/models/index.ts | 1 + .../proforma-resume.ts} | 0 .../proforma-repository.interface.ts | 2 +- .../proformas/services/proforma-finder.ts | 2 +- .../proforma-list-item-snapshot-builder.ts | 2 +- .../aggregates/customer-invoice.aggregate.ts | 1 + ...ze-issued-invoice-recipient.list.mapper.ts | 4 +- .../sequelize-issued-invoice.list.mapper.ts | 17 +- .../repositories/issued-invoice.repository.ts | 6 +- .../proformas/di/proforma-public-services.ts | 18 +- .../repositories/proforma.repository.ts | 6 +- .../src/web/customer-invoice-routes.tsx | 27 +- .../issued-invoice-summary-dto.adapter.ts | 10 +- .../src/web/proformas/create/index.ts | 1 + .../src/web/proformas/create/ui/index.ts | 1 + .../web/proformas/create/ui/pages/index.ts | 1 + .../create/ui/pages/proforma-create-page.tsx | 47 ++ .../list/ui/pages/proforma-list-page.tsx | 1 - .../customer-application.service.ts | 4 +- .../api/application/di/customer-finder.di.ts | 6 + .../di/customer-snapshot-builders.di.ts | 41 ++ .../application/di/customer-use-cases.di.ts | 83 ++++ .../customers/src/api/application/di/index.ts | 5 + .../customers/src/api/application/index.ts | 8 +- .../customer-domain-mapper.interface.ts | 7 + .../customer-summary-mapper.interface.ts | 7 + .../src/api/application/mappers/index.ts | 2 + .../application/models/customer-summary.ts | 41 ++ .../src/api/application/models/index.ts | 1 + .../customer-repository.interface.ts | 13 +- .../repositories/index.ts | 0 .../application/services/customer-finder.ts | 56 +++ .../src/api/application/services/index.ts | 1 + .../application/snapshot-builders/index.ts | 3 + .../customer-list-item-snapshot-builder.ts | 14 + .../customer-list-item-snapshot.interface.ts | 1 + .../snapshot-builders/list/index.ts | 2 + .../map-dto-to-create-customer-props.ts | 4 +- .../use-cases/list-customers.use-case.ts | 52 ++- .../{customer.ts => customer.aggregate.ts} | 22 +- .../src/api/domain/aggregates/index.ts | 2 +- modules/customers/src/api/domain/index.ts | 1 - ...ss-type.ts => customer-address-type.vo.ts} | 0 ...stomer-number.ts => customer-number.vo.ts} | 0 ...customer-serie.ts => customer-serie.vo.ts} | 0 ...stomer-status.ts => customer-status.vo.ts} | 0 .../src/api/domain/value-objects/index.ts | 8 +- modules/customers/src/api/index.ts | 20 +- .../src/api/infrastructure/dependencies.ts | 4 +- .../di/customer-persistence-mappers.di.ts | 36 ++ .../di/customer-repositories.di.ts | 14 + .../src/api/infrastructure/di/customers.di.ts | 73 +++ .../src/api/infrastructure/di/index.ts | 1 + .../express/customers.routes.ts | 2 +- .../mappers/domain/customer.mapper.ts | 22 +- ...t.mapper.ts => customer-summary.mapper.ts} | 52 +-- .../infrastructure/mappers/queries/index.ts | 2 +- .../repositories/customer.repository.ts | 62 +-- .../web/components/client-selector-modal.tsx | 118 ++--- .../customer-modal-selector/customer-card.tsx | 78 ++-- .../customer-create-modal.tsx | 86 ++-- .../customer-modal-selector-field.tsx | 24 +- .../customer-modal-selector.tsx | 94 ++-- .../customer-search-dialog.tsx | 75 ++-- .../customer-view-dialog.tsx | 417 +++++++++--------- .../src/web/components/customers-layout.tsx | 7 - .../customer-additional-config-fields.tsx | 40 +- .../editor/customer-address-fields.tsx | 64 +-- .../editor/customer-editor-skeleton.tsx | 23 +- modules/customers/src/web/components/index.ts | 2 - modules/customers/src/web/customer-routes.tsx | 20 +- modules/customers/src/web/hooks/index.ts | 1 - .../adapters/customer-summary-dto.adapter.ts | 12 + .../customers/src/web/list/adapters/index.ts | 1 + .../src/web/list/api/get-customer-list.api.ts | 18 + modules/customers/src/web/list/api/index.ts | 1 + .../src/web/list/controllers/index.ts | 1 + .../use-customer-list-page.controller.ts | 9 + .../use-customer-list.controller.ts | 43 ++ modules/customers/src/web/list/hooks/index.ts | 1 + .../hooks/use-customer-list-query.tsx | 51 ++- modules/customers/src/web/list/index.ts | 1 + .../blocks/customers-grid/customers-grid.tsx | 61 +++ .../list/ui/blocks/customers-grid/index.ts | 2 + .../use-customer-grid-columns.tsx | 201 +++++++++ .../customers/src/web/list/ui/blocks/index.ts | 1 + .../web/list/ui/components/address-cell.tsx | 18 + .../web/list/ui/components/contact-cell.tsx | 35 ++ .../src/web/list/ui/components/index.ts | 5 + .../src/web/list/ui/components/initials.tsx | 4 + .../src/web/list/ui/components/kind-badge.tsx | 9 + .../src/web/list/ui/components/soft.tsx | 5 + modules/customers/src/web/list/ui/index.ts | 3 + .../web/list/ui/pages/customer-list-page.tsx | 73 +++ .../customers/src/web/list/ui/pages/index.ts | 1 + .../web/pages/create/customer-create-page.tsx | 39 +- .../create/use-customer-create-controller.ts | 5 +- .../web/pages/list/customers-list-page.tsx | 102 ----- modules/customers/src/web/pages/list/index.ts | 2 +- .../pages/list/use-customers-list-columns.tsx | 18 +- .../pages/update/customer-update-modal.tsx | 54 +-- .../web/pages/update/customer-update-page.tsx | 49 +- .../update/use-customer-update-controller.ts | 7 +- .../src/web/pages/view/customer-view-page.tsx | 221 +++++----- .../web/types/customer-summary.web.schema.ts | 9 + .../src/web/types/customer.api.schema.ts | 17 + modules/customers/src/web/types/index.ts | 2 + .../src/web/ui/blocks/customer-layout.tsx | 6 + modules/customers/src/web/ui/blocks/index.ts | 1 + .../components/customer-status-badge.tsx | 0 .../src/web/ui/components/error-alert.tsx | 16 + .../customers/src/web/ui/components/index.ts | 2 + modules/customers/src/web/ui/index.ts | 2 + 135 files changed, 1988 insertions(+), 1083 deletions(-) create mode 100644 modules/core/src/api/application/mappers/index.ts rename modules/core/src/api/{domain/repositories/repository.interface.ts => application/mappers/mapper.interface.ts} (82%) delete mode 100644 modules/core/src/api/domain/repositories/index.ts delete mode 100644 modules/customer-invoices/src/api/application/issued-invoices/application-models/index.ts delete mode 100644 modules/customer-invoices/src/api/application/issued-invoices/dtos/index.ts rename modules/customer-invoices/src/api/application/issued-invoices/mappers/{issued-invoice-list-mapper.interface.ts => issued-invoice-summary-mapper.interface.ts} (57%) create mode 100644 modules/customer-invoices/src/api/application/issued-invoices/models/index.ts rename modules/customer-invoices/src/api/application/issued-invoices/{dtos/issued-invoice-list.dto.ts => models/issued-invoice-summary.ts} (95%) delete mode 100644 modules/customer-invoices/src/api/application/proformas/application-models/index.ts delete mode 100644 modules/customer-invoices/src/api/application/proformas/dtos/index.ts create mode 100644 modules/customer-invoices/src/api/application/proformas/models/index.ts rename modules/customer-invoices/src/api/application/proformas/{dtos/proforma-list.dto.ts => models/proforma-resume.ts} (100%) create mode 100644 modules/customer-invoices/src/web/proformas/create/index.ts create mode 100644 modules/customer-invoices/src/web/proformas/create/ui/index.ts create mode 100644 modules/customer-invoices/src/web/proformas/create/ui/pages/index.ts create mode 100644 modules/customer-invoices/src/web/proformas/create/ui/pages/proforma-create-page.tsx create mode 100644 modules/customers/src/api/application/di/customer-finder.di.ts create mode 100644 modules/customers/src/api/application/di/customer-snapshot-builders.di.ts create mode 100644 modules/customers/src/api/application/di/customer-use-cases.di.ts create mode 100644 modules/customers/src/api/application/di/index.ts create mode 100644 modules/customers/src/api/application/mappers/customer-domain-mapper.interface.ts create mode 100644 modules/customers/src/api/application/mappers/customer-summary-mapper.interface.ts create mode 100644 modules/customers/src/api/application/mappers/index.ts create mode 100644 modules/customers/src/api/application/models/customer-summary.ts create mode 100644 modules/customers/src/api/application/models/index.ts rename modules/customers/src/api/{domain => application}/repositories/customer-repository.interface.ts (84%) rename modules/customers/src/api/{domain => application}/repositories/index.ts (100%) create mode 100644 modules/customers/src/api/application/services/customer-finder.ts create mode 100644 modules/customers/src/api/application/services/index.ts create mode 100644 modules/customers/src/api/application/snapshot-builders/index.ts create mode 100644 modules/customers/src/api/application/snapshot-builders/list/customer-list-item-snapshot-builder.ts create mode 100644 modules/customers/src/api/application/snapshot-builders/list/customer-list-item-snapshot.interface.ts create mode 100644 modules/customers/src/api/application/snapshot-builders/list/index.ts rename modules/customers/src/api/domain/aggregates/{customer.ts => customer.aggregate.ts} (88%) rename modules/customers/src/api/domain/value-objects/{customer-address-type.ts => customer-address-type.vo.ts} (100%) rename modules/customers/src/api/domain/value-objects/{customer-number.ts => customer-number.vo.ts} (100%) rename modules/customers/src/api/domain/value-objects/{customer-serie.ts => customer-serie.vo.ts} (100%) rename modules/customers/src/api/domain/value-objects/{customer-status.ts => customer-status.vo.ts} (100%) create mode 100644 modules/customers/src/api/infrastructure/di/customer-persistence-mappers.di.ts create mode 100644 modules/customers/src/api/infrastructure/di/customer-repositories.di.ts create mode 100644 modules/customers/src/api/infrastructure/di/customers.di.ts create mode 100644 modules/customers/src/api/infrastructure/di/index.ts rename modules/customers/src/api/infrastructure/mappers/queries/{customer.list.mapper.ts => customer-summary.mapper.ts} (82%) delete mode 100644 modules/customers/src/web/components/customers-layout.tsx create mode 100644 modules/customers/src/web/list/adapters/customer-summary-dto.adapter.ts create mode 100644 modules/customers/src/web/list/adapters/index.ts create mode 100644 modules/customers/src/web/list/api/get-customer-list.api.ts create mode 100644 modules/customers/src/web/list/api/index.ts create mode 100644 modules/customers/src/web/list/controllers/index.ts create mode 100644 modules/customers/src/web/list/controllers/use-customer-list-page.controller.ts create mode 100644 modules/customers/src/web/list/controllers/use-customer-list.controller.ts create mode 100644 modules/customers/src/web/list/hooks/index.ts rename modules/customers/src/web/{ => list}/hooks/use-customer-list-query.tsx (60%) create mode 100644 modules/customers/src/web/list/index.ts create mode 100644 modules/customers/src/web/list/ui/blocks/customers-grid/customers-grid.tsx create mode 100644 modules/customers/src/web/list/ui/blocks/customers-grid/index.ts create mode 100644 modules/customers/src/web/list/ui/blocks/customers-grid/use-customer-grid-columns.tsx create mode 100644 modules/customers/src/web/list/ui/blocks/index.ts create mode 100644 modules/customers/src/web/list/ui/components/address-cell.tsx create mode 100644 modules/customers/src/web/list/ui/components/contact-cell.tsx create mode 100644 modules/customers/src/web/list/ui/components/index.ts create mode 100644 modules/customers/src/web/list/ui/components/initials.tsx create mode 100644 modules/customers/src/web/list/ui/components/kind-badge.tsx create mode 100644 modules/customers/src/web/list/ui/components/soft.tsx create mode 100644 modules/customers/src/web/list/ui/index.ts create mode 100644 modules/customers/src/web/list/ui/pages/customer-list-page.tsx create mode 100644 modules/customers/src/web/list/ui/pages/index.ts delete mode 100644 modules/customers/src/web/pages/list/customers-list-page.tsx create mode 100644 modules/customers/src/web/types/customer-summary.web.schema.ts create mode 100644 modules/customers/src/web/types/customer.api.schema.ts create mode 100644 modules/customers/src/web/types/index.ts create mode 100644 modules/customers/src/web/ui/blocks/customer-layout.tsx create mode 100644 modules/customers/src/web/ui/blocks/index.ts rename modules/customers/src/web/{ => ui}/components/customer-status-badge.tsx (100%) create mode 100644 modules/customers/src/web/ui/components/error-alert.tsx create mode 100644 modules/customers/src/web/ui/components/index.ts create mode 100644 modules/customers/src/web/ui/index.ts diff --git a/apps/web/src/routes/app-routes.tsx b/apps/web/src/routes/app-routes.tsx index 4284531e..396df5cf 100644 --- a/apps/web/src/routes/app-routes.tsx +++ b/apps/web/src/routes/app-routes.tsx @@ -1,7 +1,9 @@ -import { IModuleClient } from "@erp/core/client"; +import type { IModuleClient } from "@erp/core/client"; import { AppLayout } from "@repo/rdx-ui/components"; -import { createBrowserRouter, createRoutesFromElements, Navigate, Route } from "react-router-dom"; +import { Navigate, Route, createBrowserRouter, createRoutesFromElements } from "react-router-dom"; + import { ModuleRoutes } from "@/components/module-routes"; + import { ErrorPage, LoginForm } from "../pages"; import { modules } from "../register-modules"; // Aquí ca @@ -33,24 +35,24 @@ export const getAppRouter = () => { return createBrowserRouter( createRoutesFromElements( - + {/* Auth Layout */} - - } /> - } /> - } /> + + } index /> + } path="login" /> + } path="*" /> {/* App Layout */} }> {/* Dynamic Module Routes */} - } /> + } path="*" /> {/* Main Layout */} - } /> - } /> - } /> - } /> + } path="/dashboard" /> + } path="/settings" /> + } path="/catalog" /> + } path="/quotes" /> ) diff --git a/modules/core/src/api/application/index.ts b/modules/core/src/api/application/index.ts index a48e02db..0419356e 100644 --- a/modules/core/src/api/application/index.ts +++ b/modules/core/src/api/application/index.ts @@ -1,4 +1,5 @@ export * from "./documents"; +export * from "./mappers"; export * from "./presenters"; export * from "./renderers"; export * from "./snapshot-builders"; diff --git a/modules/core/src/api/application/mappers/index.ts b/modules/core/src/api/application/mappers/index.ts new file mode 100644 index 00000000..9fe93da2 --- /dev/null +++ b/modules/core/src/api/application/mappers/index.ts @@ -0,0 +1 @@ +export * from "./mapper.interface"; diff --git a/modules/core/src/api/domain/repositories/repository.interface.ts b/modules/core/src/api/application/mappers/mapper.interface.ts similarity index 82% rename from modules/core/src/api/domain/repositories/repository.interface.ts rename to modules/core/src/api/application/mappers/mapper.interface.ts index 501bb752..e616aa62 100644 --- a/modules/core/src/api/domain/repositories/repository.interface.ts +++ b/modules/core/src/api/application/mappers/mapper.interface.ts @@ -56,23 +56,21 @@ export type DomainMapperWithBulk = IDomainMapper>; /** - * - * 👓 Mapper de Read Model (Persistencia ↔ DTO/Proyección de Lectura) - * - Responsabilidad: transformar registros de persistencia en DTOs para lectura (listados, resúmenes, informes). + * 👓 Mapper de Read Model (Persistencia → Read Model/Proyección de Lectura) + * - Responsabilidad: transformar registros de persistencia en read models para lectura (listados, resúmenes, informes). * - No intenta reconstruir agregados ni validar value objects de dominio. **/ -export interface IQueryMapperWithBulk { +export interface IQueryMapperWithBulk { /** - * Convierte un registro crudo en un DTO de lectura. + * Convierte un registro crudo en un read model de lectura. */ - mapToDTO(raw: TPersistence, params?: MapperParamsType): Result; - + mapToReadModel(raw: TPersistence, params?: MapperParamsType): Result; /** - * Convierte múltiples registros crudos en una Collection de DTOs de lectura. + * Convierte múltiples registros crudos en una Collection de read models de lectura. */ - mapToDTOCollection( + mapToReadModelCollection( raws: TPersistence[], totalCount: number, params?: MapperParamsType - ): Result, Error>; + ): Result, Error>; } diff --git a/modules/core/src/api/domain/index.ts b/modules/core/src/api/domain/index.ts index 02c26663..ba0555aa 100644 --- a/modules/core/src/api/domain/index.ts +++ b/modules/core/src/api/domain/index.ts @@ -1,3 +1,2 @@ export * from "./errors"; -export * from "./repositories"; export * from "./value-objects"; diff --git a/modules/core/src/api/domain/repositories/index.ts b/modules/core/src/api/domain/repositories/index.ts deleted file mode 100644 index fa66b99c..00000000 --- a/modules/core/src/api/domain/repositories/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./repository.interface"; diff --git a/modules/core/src/api/infrastructure/persistence/sequelize/mappers/sequelize-domain-mapper.ts b/modules/core/src/api/infrastructure/persistence/sequelize/mappers/sequelize-domain-mapper.ts index ec8bb20b..f1212aca 100644 --- a/modules/core/src/api/infrastructure/persistence/sequelize/mappers/sequelize-domain-mapper.ts +++ b/modules/core/src/api/infrastructure/persistence/sequelize/mappers/sequelize-domain-mapper.ts @@ -1,7 +1,7 @@ import { Collection, Result, ResultCollection } from "@repo/rdx-utils"; import type { Model } from "sequelize"; -import type { MapperParamsType } from "../../../../domain"; +import type { MapperParamsType } from "../../../../application"; import type { ISequelizeDomainMapper } from "./sequelize-mapper.interface"; diff --git a/modules/core/src/api/infrastructure/persistence/sequelize/mappers/sequelize-mapper.interface.ts b/modules/core/src/api/infrastructure/persistence/sequelize/mappers/sequelize-mapper.interface.ts index ae32a8c5..b3d4e3b7 100644 --- a/modules/core/src/api/infrastructure/persistence/sequelize/mappers/sequelize-mapper.interface.ts +++ b/modules/core/src/api/infrastructure/persistence/sequelize/mappers/sequelize-mapper.interface.ts @@ -1,4 +1,4 @@ -import type { DomainMapperWithBulk, IQueryMapperWithBulk } from "../../../../domain"; +import type { DomainMapperWithBulk, IQueryMapperWithBulk } from "@erp/core/api/application"; export interface ISequelizeDomainMapper extends DomainMapperWithBulk {} diff --git a/modules/core/src/api/infrastructure/persistence/sequelize/mappers/sequelize-read-model-mapper.ts b/modules/core/src/api/infrastructure/persistence/sequelize/mappers/sequelize-read-model-mapper.ts index 7351e319..9f88c13f 100644 --- a/modules/core/src/api/infrastructure/persistence/sequelize/mappers/sequelize-read-model-mapper.ts +++ b/modules/core/src/api/infrastructure/persistence/sequelize/mappers/sequelize-read-model-mapper.ts @@ -1,16 +1,16 @@ import { Collection, Result } from "@repo/rdx-utils"; import type { Model } from "sequelize"; -import type { MapperParamsType } from "../../../../domain"; +import type { MapperParamsType } from "../../../../application"; import type { ISequelizeQueryMapper } from "./sequelize-mapper.interface"; export abstract class SequelizeQueryMapper implements ISequelizeQueryMapper { - public abstract mapToDTO(raw: TModel, params?: MapperParamsType): Result; + public abstract mapToReadModel(raw: TModel, params?: MapperParamsType): Result; - public mapToDTOCollection( + public mapToReadModelCollection( raws: TModel[], totalCount: number, params?: MapperParamsType @@ -23,7 +23,7 @@ export abstract class SequelizeQueryMapper } const items = _source.map((value, index) => { - const result = this.mapToDTO(value as TModel, { index, ...params }); + const result = this.mapToReadModel(value as TModel, { index, ...params }); if (result.isFailure) { throw result.error; } diff --git a/modules/customer-invoices/src/api/application/issued-invoices/application-models/index.ts b/modules/customer-invoices/src/api/application/issued-invoices/application-models/index.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/modules/customer-invoices/src/api/application/issued-invoices/dtos/index.ts b/modules/customer-invoices/src/api/application/issued-invoices/dtos/index.ts deleted file mode 100644 index 7e005094..00000000 --- a/modules/customer-invoices/src/api/application/issued-invoices/dtos/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./issued-invoice-list.dto"; diff --git a/modules/customer-invoices/src/api/application/issued-invoices/index.ts b/modules/customer-invoices/src/api/application/issued-invoices/index.ts index 680f4d36..b68ea0dc 100644 --- a/modules/customer-invoices/src/api/application/issued-invoices/index.ts +++ b/modules/customer-invoices/src/api/application/issued-invoices/index.ts @@ -1,7 +1,6 @@ -export * from "./application-models"; export * from "./di"; -export * from "./dtos"; export * from "./mappers"; +export * from "./models"; export * from "./repositories"; export * from "./services"; export * from "./snapshot-builders"; diff --git a/modules/customer-invoices/src/api/application/issued-invoices/mappers/issued-invoice-list-mapper.interface.ts b/modules/customer-invoices/src/api/application/issued-invoices/mappers/issued-invoice-summary-mapper.interface.ts similarity index 57% rename from modules/customer-invoices/src/api/application/issued-invoices/mappers/issued-invoice-list-mapper.interface.ts rename to modules/customer-invoices/src/api/application/issued-invoices/mappers/issued-invoice-summary-mapper.interface.ts index c0e4334c..2d4727c1 100644 --- a/modules/customer-invoices/src/api/application/issued-invoices/mappers/issued-invoice-list-mapper.interface.ts +++ b/modules/customer-invoices/src/api/application/issued-invoices/mappers/issued-invoice-summary-mapper.interface.ts @@ -1,8 +1,8 @@ import type { MapperParamsType } from "@erp/core/api"; import type { Result } from "@repo/rdx-utils"; -import type { IssuedInvoiceListDTO } from "../dtos"; +import type { IssuedInvoiceSummary } from "../models"; -export interface IIssuedInvoiceListMapper { - mapToDTO(raw: unknown, params?: MapperParamsType): Result; +export interface IIssuedInvoiceSummaryMapper { + mapToDTO(raw: unknown, params?: MapperParamsType): Result; } diff --git a/modules/customer-invoices/src/api/application/issued-invoices/models/index.ts b/modules/customer-invoices/src/api/application/issued-invoices/models/index.ts new file mode 100644 index 00000000..c056b01a --- /dev/null +++ b/modules/customer-invoices/src/api/application/issued-invoices/models/index.ts @@ -0,0 +1 @@ +export * from "./issued-invoice-summary"; diff --git a/modules/customer-invoices/src/api/application/issued-invoices/dtos/issued-invoice-list.dto.ts b/modules/customer-invoices/src/api/application/issued-invoices/models/issued-invoice-summary.ts similarity index 95% rename from modules/customer-invoices/src/api/application/issued-invoices/dtos/issued-invoice-list.dto.ts rename to modules/customer-invoices/src/api/application/issued-invoices/models/issued-invoice-summary.ts index 1a9fc20f..fea0d4c8 100644 --- a/modules/customer-invoices/src/api/application/issued-invoices/dtos/issued-invoice-list.dto.ts +++ b/modules/customer-invoices/src/api/application/issued-invoices/models/issued-invoice-summary.ts @@ -10,7 +10,7 @@ import type { VerifactuRecord, } from "../../../domain"; -export type IssuedInvoiceListDTO = { +export type IssuedInvoiceSummary = { id: UniqueID; companyId: UniqueID; diff --git a/modules/customer-invoices/src/api/application/issued-invoices/repositories/issued-invoice-repository.interface.ts b/modules/customer-invoices/src/api/application/issued-invoices/repositories/issued-invoice-repository.interface.ts index f7a1b0de..b4b6f2c9 100644 --- a/modules/customer-invoices/src/api/application/issued-invoices/repositories/issued-invoice-repository.interface.ts +++ b/modules/customer-invoices/src/api/application/issued-invoices/repositories/issued-invoice-repository.interface.ts @@ -3,7 +3,7 @@ import type { UniqueID } from "@repo/rdx-ddd"; import type { Collection, Result } from "@repo/rdx-utils"; import type { IssuedInvoice } from "../../../domain"; -import type { IssuedInvoiceListDTO } from "../dtos"; +import type { IssuedInvoiceSummary } from "../models"; export interface IIssuedInvoiceRepository { create(invoice: IssuedInvoice, transaction?: unknown): Promise>; @@ -24,5 +24,5 @@ export interface IIssuedInvoiceRepository { companyId: UniqueID, criteria: Criteria, transaction: unknown - ): Promise, Error>>; + ): Promise, Error>>; } diff --git a/modules/customer-invoices/src/api/application/issued-invoices/services/issued-invoice-finder.ts b/modules/customer-invoices/src/api/application/issued-invoices/services/issued-invoice-finder.ts index 1b736d98..ecff558a 100644 --- a/modules/customer-invoices/src/api/application/issued-invoices/services/issued-invoice-finder.ts +++ b/modules/customer-invoices/src/api/application/issued-invoices/services/issued-invoice-finder.ts @@ -4,7 +4,7 @@ import type { Collection, Result } from "@repo/rdx-utils"; import type { Transaction } from "sequelize"; import type { IssuedInvoice } from "../../../domain"; -import type { IssuedInvoiceListDTO } from "../dtos"; +import type { IssuedInvoiceSummary } from "../models"; import type { IIssuedInvoiceRepository } from "../repositories"; export interface IIssuedInvoiceFinder { @@ -24,7 +24,7 @@ export interface IIssuedInvoiceFinder { companyId: UniqueID, criteria: Criteria, transaction?: Transaction - ): Promise, Error>>; + ): Promise, Error>>; } export class IssuedInvoiceFinder implements IIssuedInvoiceFinder { @@ -50,7 +50,7 @@ export class IssuedInvoiceFinder implements IIssuedInvoiceFinder { companyId: UniqueID, criteria: Criteria, transaction?: Transaction - ): Promise, Error>> { + ): Promise, Error>> { return this.repository.findByCriteriaInCompany(companyId, criteria, transaction); } } diff --git a/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/list/issued-invoice-list-item-snapshot-builder.ts b/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/list/issued-invoice-list-item-snapshot-builder.ts index 7ba4f346..22743b80 100644 --- a/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/list/issued-invoice-list-item-snapshot-builder.ts +++ b/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/list/issued-invoice-list-item-snapshot-builder.ts @@ -1,15 +1,15 @@ import type { ISnapshotBuilder } from "@erp/core/api"; import { maybeToEmptyString } from "@repo/rdx-ddd"; -import type { IssuedInvoiceListDTO } from "../../dtos"; +import type { IssuedInvoiceSummary } from "../../models"; import type { IIssuedInvoiceListItemSnapshot } from "./issued-invoice-list-item-snapshot.interface"; export interface IIssuedInvoiceListItemSnapshotBuilder - extends ISnapshotBuilder {} + extends ISnapshotBuilder {} export class IssuedInvoiceListItemSnapshotBuilder implements IIssuedInvoiceListItemSnapshotBuilder { - toOutput(invoice: IssuedInvoiceListDTO): IIssuedInvoiceListItemSnapshot { + toOutput(invoice: IssuedInvoiceSummary): IIssuedInvoiceListItemSnapshot { const recipient = invoice.recipient.toObjectString(); const verifactu = invoice.verifactu.match( diff --git a/modules/customer-invoices/src/api/application/proformas/application-models/index.ts b/modules/customer-invoices/src/api/application/proformas/application-models/index.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/modules/customer-invoices/src/api/application/proformas/dtos/index.ts b/modules/customer-invoices/src/api/application/proformas/dtos/index.ts deleted file mode 100644 index 4d243ca9..00000000 --- a/modules/customer-invoices/src/api/application/proformas/dtos/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./proforma-list.dto"; diff --git a/modules/customer-invoices/src/api/application/proformas/index.ts b/modules/customer-invoices/src/api/application/proformas/index.ts index 680f4d36..b68ea0dc 100644 --- a/modules/customer-invoices/src/api/application/proformas/index.ts +++ b/modules/customer-invoices/src/api/application/proformas/index.ts @@ -1,7 +1,6 @@ -export * from "./application-models"; export * from "./di"; -export * from "./dtos"; export * from "./mappers"; +export * from "./models"; export * from "./repositories"; export * from "./services"; export * from "./snapshot-builders"; diff --git a/modules/customer-invoices/src/api/application/proformas/mappers/proforma-list-mapper.interface.ts b/modules/customer-invoices/src/api/application/proformas/mappers/proforma-list-mapper.interface.ts index d2dc4668..c98fddf8 100644 --- a/modules/customer-invoices/src/api/application/proformas/mappers/proforma-list-mapper.interface.ts +++ b/modules/customer-invoices/src/api/application/proformas/mappers/proforma-list-mapper.interface.ts @@ -1,7 +1,7 @@ import type { MapperParamsType } from "@erp/core/api"; import type { Result } from "@repo/rdx-utils"; -import type { ProformaListDTO } from "../dtos"; +import type { ProformaListDTO } from "../models"; export interface IProformaListMapper { mapToDTO(raw: unknown, params?: MapperParamsType): Result; diff --git a/modules/customer-invoices/src/api/application/proformas/models/index.ts b/modules/customer-invoices/src/api/application/proformas/models/index.ts new file mode 100644 index 00000000..f1197467 --- /dev/null +++ b/modules/customer-invoices/src/api/application/proformas/models/index.ts @@ -0,0 +1 @@ +export * from "./proforma-resume"; diff --git a/modules/customer-invoices/src/api/application/proformas/dtos/proforma-list.dto.ts b/modules/customer-invoices/src/api/application/proformas/models/proforma-resume.ts similarity index 100% rename from modules/customer-invoices/src/api/application/proformas/dtos/proforma-list.dto.ts rename to modules/customer-invoices/src/api/application/proformas/models/proforma-resume.ts diff --git a/modules/customer-invoices/src/api/application/proformas/repositories/proforma-repository.interface.ts b/modules/customer-invoices/src/api/application/proformas/repositories/proforma-repository.interface.ts index aefc9ffe..53b9c524 100644 --- a/modules/customer-invoices/src/api/application/proformas/repositories/proforma-repository.interface.ts +++ b/modules/customer-invoices/src/api/application/proformas/repositories/proforma-repository.interface.ts @@ -3,7 +3,7 @@ import type { UniqueID } from "@repo/rdx-ddd"; import type { Collection, Result } from "@repo/rdx-utils"; import type { InvoiceStatus, Proforma } from "../../../domain"; -import type { ProformaListDTO } from "../dtos"; +import type { ProformaListDTO } from "../models"; export interface IProformaRepository { create(proforma: Proforma, transaction?: unknown): Promise>; diff --git a/modules/customer-invoices/src/api/application/proformas/services/proforma-finder.ts b/modules/customer-invoices/src/api/application/proformas/services/proforma-finder.ts index 83f0e53b..d2c9e54a 100644 --- a/modules/customer-invoices/src/api/application/proformas/services/proforma-finder.ts +++ b/modules/customer-invoices/src/api/application/proformas/services/proforma-finder.ts @@ -4,7 +4,7 @@ import type { Collection, Result } from "@repo/rdx-utils"; import type { Transaction } from "sequelize"; import type { Proforma } from "../../../domain"; -import type { ProformaListDTO } from "../dtos"; +import type { ProformaListDTO } from "../models"; import type { IProformaRepository } from "../repositories"; export interface IProformaFinder { diff --git a/modules/customer-invoices/src/api/application/proformas/snapshot-builders/list/proforma-list-item-snapshot-builder.ts b/modules/customer-invoices/src/api/application/proformas/snapshot-builders/list/proforma-list-item-snapshot-builder.ts index 62cfedba..c2bd5dfe 100644 --- a/modules/customer-invoices/src/api/application/proformas/snapshot-builders/list/proforma-list-item-snapshot-builder.ts +++ b/modules/customer-invoices/src/api/application/proformas/snapshot-builders/list/proforma-list-item-snapshot-builder.ts @@ -1,7 +1,7 @@ import type { ISnapshotBuilder } from "@erp/core/api"; import { maybeToEmptyString } from "@repo/rdx-ddd"; -import type { ProformaListDTO } from "../../dtos"; +import type { ProformaListDTO } from "../../models"; import type { IProformaListItemSnapshot } from "./proforma-list-item-snapshot.interface"; diff --git a/modules/customer-invoices/src/api/domain/aggregates/customer-invoice.aggregate.ts b/modules/customer-invoices/src/api/domain/aggregates/customer-invoice.aggregate.ts index a65f1e79..9eb46685 100644 --- a/modules/customer-invoices/src/api/domain/aggregates/customer-invoice.aggregate.ts +++ b/modules/customer-invoices/src/api/domain/aggregates/customer-invoice.aggregate.ts @@ -192,6 +192,7 @@ export class CustomerInvoice } // Method to get the complete list of line items + public get items(): CustomerInvoiceItems { return this._items; } diff --git a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/list/sequelize-issued-invoice-recipient.list.mapper.ts b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/list/sequelize-issued-invoice-recipient.list.mapper.ts index 47e0d596..ade5b2f3 100644 --- a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/list/sequelize-issued-invoice-recipient.list.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/list/sequelize-issued-invoice-recipient.list.mapper.ts @@ -14,7 +14,7 @@ import { } from "@repo/rdx-ddd"; import { Result } from "@repo/rdx-utils"; -import type { IssuedInvoiceListDTO } from "../../../../../../application"; +import type { IssuedInvoiceSummary } from "../../../../../../application"; import { InvoiceRecipient } from "../../../../../../domain"; import type { CustomerInvoiceModel } from "../../../../../common"; @@ -32,7 +32,7 @@ export class SequelizeIssuedInvoiceRecipientListMapper extends SequelizeQueryMap const { errors, attributes } = params as { errors: ValidationErrorDetail[]; - attributes: Partial; + attributes: Partial; }; const { isProforma } = attributes; diff --git a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/list/sequelize-issued-invoice.list.mapper.ts b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/list/sequelize-issued-invoice.list.mapper.ts index 60d011ac..ac8e2856 100644 --- a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/list/sequelize-issued-invoice.list.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/list/sequelize-issued-invoice.list.mapper.ts @@ -11,7 +11,10 @@ import { } from "@repo/rdx-ddd"; import { Maybe, Result } from "@repo/rdx-utils"; -import type { IIssuedInvoiceListMapper, IssuedInvoiceListDTO } from "../../../../../../application"; +import type { + IIssuedInvoiceSummaryMapper, + IssuedInvoiceSummary, +} from "../../../../../../application"; import { InvoiceAmount, InvoiceNumber, @@ -25,8 +28,8 @@ import { SequelizeIssuedInvoiceRecipientListMapper } from "./sequelize-issued-in import { SequelizeVerifactuRecordListMapper } from "./sequelize-verifactu-record.list.mapper"; export class SequelizeIssuedInvoiceListMapper - extends SequelizeQueryMapper - implements IIssuedInvoiceListMapper + extends SequelizeQueryMapper + implements IIssuedInvoiceSummaryMapper { private _recipientMapper: SequelizeIssuedInvoiceRecipientListMapper; private _verifactuMapper: SequelizeVerifactuRecordListMapper; @@ -37,14 +40,14 @@ export class SequelizeIssuedInvoiceListMapper this._verifactuMapper = new SequelizeVerifactuRecordListMapper(); } - public mapToDTO( + public mapToReadModel( raw: CustomerInvoiceModel, params?: MapperParamsType - ): Result { + ): Result { const errors: ValidationErrorDetail[] = []; // 1) Valores escalares (atributos generales) - const attributes = this.mapAttributesToDTO(raw, { errors, ...params }); + const attributes = this._mapAttributesToReadModel(raw, { errors, ...params }); // 2) Recipient (snapshot en la factura o include) const recipientResult = this._recipientMapper.mapToDTO(raw, { @@ -111,7 +114,7 @@ export class SequelizeIssuedInvoiceListMapper }); } - private mapAttributesToDTO(raw: CustomerInvoiceModel, params?: MapperParamsType) { + private _mapAttributesToReadModel(raw: CustomerInvoiceModel, params?: MapperParamsType) { const { errors } = params as { errors: ValidationErrorDetail[]; }; diff --git a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/repositories/issued-invoice.repository.ts b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/repositories/issued-invoice.repository.ts index 7689bff3..41875bf8 100644 --- a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/repositories/issued-invoice.repository.ts +++ b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/repositories/issued-invoice.repository.ts @@ -4,7 +4,7 @@ import type { UniqueID } from "@repo/rdx-ddd"; import { type Collection, Result } from "@repo/rdx-utils"; import type { FindOptions, InferAttributes, OrderItem, Sequelize, Transaction } from "sequelize"; -import type { IIssuedInvoiceRepository, IssuedInvoiceListDTO } from "../../../../../application"; +import type { IIssuedInvoiceRepository, IssuedInvoiceSummary } from "../../../../../application"; import type { IssuedInvoice } from "../../../../../domain"; import { CustomerInvoiceItemModel, @@ -212,7 +212,7 @@ export class IssuedInvoiceRepository criteria: Criteria, transaction: Transaction, options: FindOptions> = {} - ): Promise, Error>> { + ): Promise, Error>> { const { CustomerModel } = this.database.models; try { @@ -301,7 +301,7 @@ export class IssuedInvoiceRepository }), ]); - return this.listMapper.mapToDTOCollection(rows, count); + return this.listMapper.mapToReadModelCollection(rows, count); } catch (err: unknown) { return Result.fail(translateSequelizeError(err)); } diff --git a/modules/customer-invoices/src/api/infrastructure/proformas/di/proforma-public-services.ts b/modules/customer-invoices/src/api/infrastructure/proformas/di/proforma-public-services.ts index 972eb3ab..97c0a20e 100644 --- a/modules/customer-invoices/src/api/infrastructure/proformas/di/proforma-public-services.ts +++ b/modules/customer-invoices/src/api/infrastructure/proformas/di/proforma-public-services.ts @@ -2,23 +2,23 @@ import type { ProformasInternalDeps } from "./proformas.di"; export type ProformasServicesDeps = { services: { - listIssuedInvoices: (filters: unknown, context: unknown) => null; - getIssuedInvoiceById: (id: unknown, context: unknown) => null; - generateIssuedInvoiceReport: (id: unknown, options: unknown, context: unknown) => null; + listProformas: (filters: unknown, context: unknown) => null; + getProformaById: (id: unknown, context: unknown) => null; + generateProformaReport: (id: unknown, options: unknown, context: unknown) => null; }; }; export function buildProformaServices(deps: ProformasInternalDeps): ProformasServicesDeps { return { services: { - listIssuedInvoices: (filters, context) => null, - //internal.useCases.listIssuedInvoices().execute(filters, context), + listProformas: (filters, context) => null, + //internal.useCases.listProformas().execute(filters, context), - getIssuedInvoiceById: (id, context) => null, - //internal.useCases.getIssuedInvoiceById().execute(id, context), + getProformaById: (id, context) => null, + //internal.useCases.getProformaById().execute(id, context), - generateIssuedInvoiceReport: (id, options, context) => null, - //internal.useCases.reportIssuedInvoice().execute(id, options, context), + generateProformaReport: (id, options, context) => null, + //internal.useCases.reportProforma().execute(id, options, context), }, }; } diff --git a/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/repositories/proforma.repository.ts b/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/repositories/proforma.repository.ts index b4ec2068..df19136c 100644 --- a/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/repositories/proforma.repository.ts +++ b/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/repositories/proforma.repository.ts @@ -368,10 +368,12 @@ export class ProformaRepository ? [options.include] : []; + console.log(query.where); + query.where = { ...query.where, ...(options.where ?? {}), - is_proforma: false, + is_proforma: true, company_id: companyId.toString(), deleted_at: null, }; @@ -422,7 +424,7 @@ export class ProformaRepository }), ]); - return this.listMapper.mapToDTOCollection(rows, count); + return this.listMapper.mapToReadModelCollection(rows, count); } catch (err: unknown) { return Result.fail(translateSequelizeError(err)); } diff --git a/modules/customer-invoices/src/web/customer-invoice-routes.tsx b/modules/customer-invoices/src/web/customer-invoice-routes.tsx index 1ebfef71..b6da56d9 100644 --- a/modules/customer-invoices/src/web/customer-invoice-routes.tsx +++ b/modules/customer-invoices/src/web/customer-invoice-routes.tsx @@ -2,29 +2,32 @@ import type { ModuleClientParams } from "@erp/core/client"; import { lazy } from "react"; import { Outlet, type RouteObject } from "react-router-dom"; +import { ProformaCreatePage } from "./proformas/create"; + const ProformaLayout = lazy(() => import("./proformas/ui").then((m) => ({ default: m.ProformaLayout })) ); -const IssuedInvoicesLayout = lazy(() => - import("./issued-invoices/ui").then((m) => ({ default: m.IssuedInvoicesLayout })) -); - const ProformasListPage = lazy(() => import("./proformas/list").then((m) => ({ default: m.ProformaListPage })) ); +const ProformasCreatePage = lazy(() => + import("./proformas/create").then((m) => ({ default: m.ProformaCreatePage })) +); + +/*const InvoiceUpdatePage = lazy(() => + import("./pages").then((m) => ({ default: m.InvoiceUpdatePage })) +);*/ + +const IssuedInvoicesLayout = lazy(() => + import("./issued-invoices/ui").then((m) => ({ default: m.IssuedInvoicesLayout })) +); + const IssuedInvoiceListPage = lazy(() => import("./issued-invoices/list").then((m) => ({ default: m.IssuedInvoiceListPage })) ); -/*const CustomerInvoiceAdd = lazy(() => - import("./pages").then((m) => ({ default: m.CustomerInvoiceCreate })) -); -const InvoiceUpdatePage = lazy(() => - import("./pages").then((m) => ({ default: m.InvoiceUpdatePage })) -);*/ - export const CustomerInvoiceRoutes = (params: ModuleClientParams): RouteObject[] => { return [ { @@ -37,7 +40,7 @@ export const CustomerInvoiceRoutes = (params: ModuleClientParams): RouteObject[] children: [ { path: "", index: true, element: }, // index { path: "list", element: }, - //{ path: "create", element: }, + { path: "create", element: }, //{ path: ":id/edit", element: }, ], }, diff --git a/modules/customer-invoices/src/web/issued-invoices/list/adapters/issued-invoice-summary-dto.adapter.ts b/modules/customer-invoices/src/web/issued-invoices/list/adapters/issued-invoice-summary-dto.adapter.ts index b3bb11c0..e1a441c6 100644 --- a/modules/customer-invoices/src/web/issued-invoices/list/adapters/issued-invoice-summary-dto.adapter.ts +++ b/modules/customer-invoices/src/web/issued-invoices/list/adapters/issued-invoice-summary-dto.adapter.ts @@ -1,4 +1,4 @@ -import { MoneyDTOHelper, PercentageDTOHelper, formatCurrency } from "@erp/core"; +import { MoneyDTOHelper, formatCurrency } from "@erp/core"; import type { IssuedInvoiceSummaryData, @@ -26,14 +26,14 @@ export const IssuedInvoiceSummaryDtoAdapter = { summaryDto.language_code ), - discount_percentage: PercentageDTOHelper.toNumber(summaryDto.discount_percentage), + /*discount_percentage: PercentageDTOHelper.toNumber(summaryDto.discount_percentage), discount_percentage_fmt: PercentageDTOHelper.toNumericString( summaryDto.discount_percentage - ), + ),*/ - discount_amount: MoneyDTOHelper.toNumber(summaryDto.discount_amount), + discount_amount: MoneyDTOHelper.toNumber(summaryDto.total_discount_amount), discount_amount_fmt: formatCurrency( - MoneyDTOHelper.toNumber(summaryDto.discount_amount), + MoneyDTOHelper.toNumber(summaryDto.total_discount_amount), Number(summaryDto.total_amount.scale || 2), summaryDto.currency_code, summaryDto.language_code diff --git a/modules/customer-invoices/src/web/proformas/create/index.ts b/modules/customer-invoices/src/web/proformas/create/index.ts new file mode 100644 index 00000000..4aedf593 --- /dev/null +++ b/modules/customer-invoices/src/web/proformas/create/index.ts @@ -0,0 +1 @@ +export * from "./ui"; diff --git a/modules/customer-invoices/src/web/proformas/create/ui/index.ts b/modules/customer-invoices/src/web/proformas/create/ui/index.ts new file mode 100644 index 00000000..c4e34b27 --- /dev/null +++ b/modules/customer-invoices/src/web/proformas/create/ui/index.ts @@ -0,0 +1 @@ +export * from "./pages"; diff --git a/modules/customer-invoices/src/web/proformas/create/ui/pages/index.ts b/modules/customer-invoices/src/web/proformas/create/ui/pages/index.ts new file mode 100644 index 00000000..6af8f18e --- /dev/null +++ b/modules/customer-invoices/src/web/proformas/create/ui/pages/index.ts @@ -0,0 +1 @@ +export * from "./proforma-create-page"; diff --git a/modules/customer-invoices/src/web/proformas/create/ui/pages/proforma-create-page.tsx b/modules/customer-invoices/src/web/proformas/create/ui/pages/proforma-create-page.tsx new file mode 100644 index 00000000..d8538824 --- /dev/null +++ b/modules/customer-invoices/src/web/proformas/create/ui/pages/proforma-create-page.tsx @@ -0,0 +1,47 @@ +import { PageHeader } from "@erp/core/components"; +import { AppContent, AppHeader } from "@repo/rdx-ui/components"; +import { Button } from "@repo/shadcn-ui/components"; +import { PlusIcon } from "lucide-react"; +import { useNavigate } from "react-router-dom"; + +import { useTranslation } from "../../../../i18n"; + +export const ProformaCreatePage = () => { + const { t } = useTranslation(); + const navigate = useNavigate(); + + return ( + <> + + navigate("/proformas/create")} + > + + {t("pages.proformas.create.title")} + + } + title={t("pages.proformas.list.title")} + /> + + + +
+
+

{t("pages.create.title")}

+

{t("pages.create.description")}

+
+
+ +
+
+
hola
+
+ + ); +}; diff --git a/modules/customer-invoices/src/web/proformas/list/ui/pages/proforma-list-page.tsx b/modules/customer-invoices/src/web/proformas/list/ui/pages/proforma-list-page.tsx index e8a10aa8..24826cfb 100644 --- a/modules/customer-invoices/src/web/proformas/list/ui/pages/proforma-list-page.tsx +++ b/modules/customer-invoices/src/web/proformas/list/ui/pages/proforma-list-page.tsx @@ -63,7 +63,6 @@ export const ProformaListPage = () => { rightSlot={ {selectedCustomer && ( - -
-
- -

{selectedCustomer.name}

+ +
+
+ +

{selectedCustomer.name}

{selectedCustomer.status}
- {selectedCustomer.company} + {selectedCustomer.company}
-

{selectedCustomer.email}

+

{selectedCustomer.email}

)} { - setSelectedCustomer(customer); - setOpen(false); - }} + isLoading={isLoading} + items={data?.items ?? []} onCreate={(e) => { e.preventDefault(); setOpen(true); console.log("Crear nuevo cliente"); }} + onOpenChange={setOpen} + onPageChange={setPageNumber} + onSearchChange={setSearch} + onSelect={(customer) => { + setSelectedCustomer(customer); + setOpen(false); + }} + open={open} page={pageNumber} perPage={pageSize} - onPageChange={setPageNumber} - renderItem={() => null} // No se usa con DataTable + refetch={refetch} renderContainer={(items) => ( setPageNumber(p)} onRowClicked={(item) => { setSelectedCustomer(item); setOpen(false); }} pagination - paginationServer paginationPerPage={pageSize} + paginationServer paginationTotalRows={data?.total_items ?? 0} - onChangePage={(p) => setPageNumber(p)} - highlightOnHover pointerOnHover - noDataComponent='No se encontraron resultados' /> )} + renderItem={() => null} + search={search} + title="Seleccionar cliente" // No se usa con DataTable + totalItems={data?.total_items ?? 0} /> - - + + - - + + Nuevo Cliente -

Formulario de creación pendiente…

+

Formulario de creación pendiente…

- @@ -246,33 +246,33 @@ export const ClientSelectorModal = () => { const CustomerCard = ({ customer }: { customer: Customer }) => ( - -
- - {customer.name} + +
+ + {customer.name} {customer.status}
-
-
- +
+
+ {customer.email}
-
- +
+ {customer.company}
-
- +
+ {customer.phone}
-
- +
+ {customer.address}
-
- +
+ {new Date(customer.createdAt).toLocaleDateString("es-ES")}
diff --git a/modules/customers/src/web/components/customer-modal-selector/customer-card.tsx b/modules/customers/src/web/components/customer-modal-selector/customer-card.tsx index 1c74913e..b2c85cff 100644 --- a/modules/customers/src/web/components/customer-modal-selector/customer-card.tsx +++ b/modules/customers/src/web/components/customer-modal-selector/customer-card.tsx @@ -1,19 +1,9 @@ -import { - Button, Item, - ItemContent, - ItemFooter, - ItemTitle -} from "@repo/shadcn-ui/components"; -import { cn } from '@repo/shadcn-ui/lib/utils'; -import { - EyeIcon, - MapPinIcon, - RefreshCwIcon, - UserPlusIcon -} from "lucide-react"; -import React, { useMemo } from 'react'; -import { CustomerSummary } from "../../schemas"; +import { Button, Item, ItemContent, ItemFooter, ItemTitle } from "@repo/shadcn-ui/components"; +import { cn } from "@repo/shadcn-ui/lib/utils"; +import { EyeIcon, MapPinIcon, RefreshCwIcon, UserPlusIcon } from "lucide-react"; +import React, { useMemo } from "react"; +import type { CustomerSummary } from "../../schemas"; interface CustomerCardProps { customer: CustomerSummary; @@ -57,42 +47,38 @@ export const CustomerCard = ({ const address = useMemo(() => buildAddress(customer), [customer]); return ( - + {customer.name} {/* Eye solo si onViewCustomer existe */} {onViewCustomer && ( )}
a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4", "text-sm text-muted-foreground" - )}> - {/* TIN en su propia línea si existe */} - {customer.tin && ( -
{customer.tin}
)} + data-slot="item-description" + > + {/* TIN en su propia línea si existe */} + {customer.tin &&
{customer.tin}
} {/* Dirección */} {address.has ? ( -
+
{/* Desktop/tablet: compacto en una línea (o dos por wrap natural) */}
@@ -101,7 +87,9 @@ export const CustomerCard = ({ {part} {i < address.stack.length - 1 && ( - · + + · + )} ))} @@ -129,29 +117,29 @@ export const CustomerCard = ({ {onChangeCustomer && ( )} {onAddNewCustomer && ( )} ); -}; \ No newline at end of file +}; diff --git a/modules/customers/src/web/components/customer-modal-selector/customer-create-modal.tsx b/modules/customers/src/web/components/customer-modal-selector/customer-create-modal.tsx index b48b13f5..dac6ec63 100644 --- a/modules/customers/src/web/components/customer-modal-selector/customer-create-modal.tsx +++ b/modules/customers/src/web/components/customer-modal-selector/customer-create-modal.tsx @@ -1,4 +1,3 @@ - import { UnsavedChangesProvider, useUnsavedChangesContext } from "@erp/core/hooks"; import { Button, @@ -10,12 +9,12 @@ import { DialogTitle, } from "@repo/shadcn-ui/components"; import { Plus } from "lucide-react"; -import { useCallback, useId } from 'react'; -import { useTranslation } from "../../i18n"; -import { useCustomerCreateController } from '../../pages/create/use-customer-create-controller'; -import { CustomerFormData } from "../../schemas"; -import { CustomerEditForm } from '../editor'; +import { useCallback, useId } from "react"; +import { useTranslation } from "../../i18n"; +import { useCustomerCreateController } from "../../pages/create/use-customer-create-controller"; +import type { CustomerFormData } from "../../schemas"; +import { CustomerEditForm } from "../editor"; type CustomerCreateModalProps = { open: boolean; @@ -25,62 +24,61 @@ type CustomerCreateModalProps = { onSubmit: () => void; // ← mantenemos tu firma (no se usa directamente aquí) }; -export function CustomerCreateModal({ - open, - onOpenChange, -}: CustomerCreateModalProps) { +export function CustomerCreateModal({ open, onOpenChange }: CustomerCreateModalProps) { const { t } = useTranslation(); const formId = useId(); const { requestConfirm } = useUnsavedChangesContext(); - const { - form, isCreating, isCreateError, createError, - handleSubmit, handleError, FormProvider - } = useCustomerCreateController(); + const { form, isCreating, isCreateError, createError, handleSubmit, handleError, FormProvider } = + useCustomerCreateController(); const { isDirty } = form.formState; - const guardClose = useCallback(async (nextOpen: boolean) => { - if (nextOpen) return onOpenChange(true); + const guardClose = useCallback( + async (nextOpen: boolean) => { + if (nextOpen) return onOpenChange(true); - if (isCreating) return; + if (isCreating) return; - if (!isDirty) { - return onOpenChange(false); - } + if (!isDirty) { + return onOpenChange(false); + } - if (await requestConfirm()) { - return onOpenChange(false); - } - }, [requestConfirm, isCreating, onOpenChange, isDirty]); + if (await requestConfirm()) { + return onOpenChange(false); + } + }, + [requestConfirm, isCreating, onOpenChange, isDirty] + ); - - const handleFormSubmit = (data: CustomerFormData) => handleSubmit(data /*, () => onOpenChange(false)*/); + const handleFormSubmit = (data: CustomerFormData) => + handleSubmit(data /*, () => onOpenChange(false)*/); return ( - - + {t("pages.create.title")} - {t("pages.create.description")} + + {t("pages.create.description")} +
{isCreateError && ( -

+

{(createError as Error)?.message}

)} @@ -88,16 +86,26 @@ export function CustomerCreateModal({
- -
-
); -} \ No newline at end of file +} diff --git a/modules/customers/src/web/components/customer-modal-selector/customer-modal-selector-field.tsx b/modules/customers/src/web/components/customer-modal-selector/customer-modal-selector-field.tsx index 78828f4a..e61fff2a 100644 --- a/modules/customers/src/web/components/customer-modal-selector/customer-modal-selector-field.tsx +++ b/modules/customers/src/web/components/customer-modal-selector/customer-modal-selector-field.tsx @@ -1,8 +1,9 @@ import { Field, FieldLabel } from "@repo/shadcn-ui/components"; +import { cn } from "@repo/shadcn-ui/lib/utils"; +import { type Control, Controller, type FieldPath, type FieldValues } from "react-hook-form"; + +import type { CustomerSummary } from "../../schemas"; -import { cn } from '@repo/shadcn-ui/lib/utils'; -import { Control, Controller, FieldPath, FieldValues } from "react-hook-form"; -import { CustomerSummary } from '../../schemas'; import { CustomerModalSelector } from "./customer-modal-selector"; type CustomerModalSelectorFieldProps = { @@ -12,7 +13,7 @@ type CustomerModalSelectorFieldProps = { label?: string; description?: string; - orientation?: "vertical" | "horizontal" | "responsive", + orientation?: "vertical" | "horizontal" | "responsive"; disabled?: boolean; required?: boolean; @@ -28,8 +29,7 @@ export function CustomerModalSelectorField({ label, description, - orientation = 'vertical', - + orientation = "vertical", disabled = false, required = false, @@ -49,25 +49,25 @@ export function CustomerModalSelectorField({ return ( {label && ( - + {label} )} ); }} /> ); -} \ No newline at end of file +} diff --git a/modules/customers/src/web/components/customer-modal-selector/customer-modal-selector.tsx b/modules/customers/src/web/components/customer-modal-selector/customer-modal-selector.tsx index 808a64c0..3ed2242d 100644 --- a/modules/customers/src/web/components/customer-modal-selector/customer-modal-selector.tsx +++ b/modules/customers/src/web/components/customer-modal-selector/customer-modal-selector.tsx @@ -1,11 +1,17 @@ import { useEffect, useId, useMemo, useState } from "react"; + import { useCustomerListQuery } from "../../hooks"; -import { CustomerFormData, CustomerSummary, defaultCustomerFormData } from "../../schemas"; +import { + type CustomerFormData, + type CustomerSummary, + defaultCustomerFormData, +} from "../../schemas"; + import { CustomerCard } from "./customer-card"; -import { CustomerCreateModal } from './customer-create-modal'; +import { CustomerCreateModal } from "./customer-create-modal"; import { CustomerEmptyCard } from "./customer-empty-card"; import { CustomerSearchDialog } from "./customer-search-dialog"; -import { CustomerViewDialog } from './customer-view-dialog'; +import { CustomerViewDialog } from "./customer-view-dialog"; // Debounce pequeño y tipado function useDebouncedValue(value: T, delay = 300) { @@ -17,7 +23,6 @@ function useDebouncedValue(value: T, delay = 300) { return debounced; } - type CustomerModalSelectorProps = { value?: string; onValueChange?: (id: string) => void; @@ -25,7 +30,7 @@ type CustomerModalSelectorProps = { readOnly?: boolean; // Ver ficha, pero no cambiar/crear initialCustomer?: CustomerSummary; className?: string; -} +}; export const CustomerModalSelector = ({ value, @@ -35,7 +40,6 @@ export const CustomerModalSelector = ({ initialCustomer, className, }: CustomerModalSelectorProps) => { - const dialogId = useId(); const [showSearch, setShowSearch] = useState(false); @@ -68,32 +72,28 @@ export const CustomerModalSelector = ({ isLoading, isError, error, - } = useCustomerListQuery( - { - enabled: showSearch, // <- evita llamadas innecesarias - criteria - } - ); + } = useCustomerListQuery({ + enabled: showSearch, // <- evita llamadas innecesarias + criteria, + }); // Combinar locales optimistas + remotos const customers: CustomerSummary[] = useMemo(() => { - const remoteCustomers = remoteCustomersPage ? remoteCustomersPage.items : [] + const remoteCustomers = remoteCustomersPage ? remoteCustomersPage.items : []; const byId = new Map(); [...localCreated, ...remoteCustomers].forEach((c) => byId.set(c.id, c as CustomerSummary)); return Array.from(byId.values()); }, [localCreated, remoteCustomersPage]); - // Sync con value e initialCustomer useEffect(() => { const found = customers.find((c) => c.id === value) ?? initialCustomer ?? null; setSelected(found ?? null); }, [value, customers, initialCustomer]); - // Crear cliente (optimista) mapeando desde CustomerDraft -> CustomerSummary const handleCreate = () => { - if (!newClient.name || !newClient.email_primary) return; + if (!(newClient.name && newClient.email_primary)) return; const newCustomer: CustomerSummary = defaultCustomerFormData as CustomerSummary; @@ -104,8 +104,8 @@ export const CustomerModalSelector = ({ }; // Handlers de tarjeta según modo - const canChange = !disabled && !readOnly; - const canCreate = !disabled && !readOnly; + const canChange = !(disabled || readOnly); + const canCreate = !(disabled || readOnly); const canView = !!selected && !disabled; return ( @@ -115,63 +115,65 @@ export const CustomerModalSelector = ({ setShowView(true) : undefined} - onChangeCustomer={canChange ? () => setShowSearch(true) : undefined} onAddNewCustomer={canCreate ? () => setShowNewForm(true) : undefined} + onChangeCustomer={canChange ? () => setShowSearch(true) : undefined} + onViewCustomer={canView ? () => setShowView(true) : undefined} /> ) : ( setShowSearch(true) : undefined} - onKeyDown={ - !disabled && !readOnly - ? (e) => { - if (e.key === "Enter" || e.key === " ") setShowSearch(true); - } - : undefined - } - aria-haspopup="dialog" aria-controls={dialogId} aria-disabled={disabled || readOnly} + aria-haspopup="dialog" + className={className} + onClick={disabled || readOnly ? undefined : () => setShowSearch(true)} + onKeyDown={ + disabled || readOnly + ? undefined + : (e) => { + if (e.key === "Enter" || e.key === " ") setShowSearch(true); + } + } /> )}
{ + setNewClient((prev) => ({ ...prev, name: name ?? "" })); + setShowNewForm(true); + }} + onOpenChange={setShowSearch} + onSearchQueryChange={setSearchQuery} onSelectClient={(c) => { setSelected(c); onValueChange?.(c.id); setShowSearch(false); }} - onCreateClient={(name) => { - setNewClient((prev) => ({ ...prev, name: name ?? "" })); - setShowNewForm(true); - }} - isLoading={isLoading} - isError={isError} - errorMessage={isError ? ((error as Error)?.message ?? "Error al cargar clientes") : undefined} + open={showSearch} + searchQuery={searchQuery} + selectedClient={selected} /> {/* Diálogo de alta rápida */} ); -}; \ No newline at end of file +}; diff --git a/modules/customers/src/web/components/customer-modal-selector/customer-search-dialog.tsx b/modules/customers/src/web/components/customer-modal-selector/customer-search-dialog.tsx index 5c6febb6..57e90487 100644 --- a/modules/customers/src/web/components/customer-modal-selector/customer-search-dialog.tsx +++ b/modules/customers/src/web/components/customer-modal-selector/customer-search-dialog.tsx @@ -24,7 +24,8 @@ import { UserIcon, UserPlusIcon, } from "lucide-react"; -import { CustomerSummary } from "../../schemas"; + +import type { CustomerSummary } from "../../schemas"; interface CustomerSearchDialogProps { open: boolean; @@ -53,45 +54,45 @@ export const CustomerSearchDialog = ({ isError, errorMessage, }: CustomerSearchDialogProps) => { - const isEmpty = !isLoading && !isError && customers && customers.length === 0; + const isEmpty = !(isLoading || isError) && customers && customers.length === 0; return ( - - - - - - + + + + + + Seleccionar Cliente Busca un cliente existente o crea uno nuevo. -
- +
+ - + -
- +
+ {isLoading &&

Cargando…

} - {isError &&

{errorMessage}

} - {!isLoading && !isError && ( + {isError &&

{errorMessage}

} + {!(isLoading || isError) && ( <>

No se encontraron clientes

{searchQuery && ( )} @@ -104,38 +105,38 @@ export const CustomerSearchDialog = ({ {customers.map((customer) => { return ( onSelectClient(customer)} - className='flex items-center gap-x-4 py-5 cursor-pointer' + value={customer.id} > -
- +
+
-
-
- {customer.name} +
+
+ {customer.name} {customer.trade_name && ( - + {customer.trade_name} )}
-
+
{customer.tin && ( -
- - {customer.tin} +
+ + {customer.tin}
)} {customer.email_primary && ( - - {customer.email_primary} + + {customer.email_primary} )} {customer.mobile_primary && ( - - {customer.mobile_primary} + + {customer.mobile_primary} )}
@@ -153,12 +154,12 @@ export const CustomerSearchDialog = ({
- + diff --git a/modules/customers/src/web/components/customer-modal-selector/customer-view-dialog.tsx b/modules/customers/src/web/components/customer-modal-selector/customer-view-dialog.tsx index 5c91937b..b39c7fe2 100644 --- a/modules/customers/src/web/components/customer-modal-selector/customer-view-dialog.tsx +++ b/modules/customers/src/web/components/customer-modal-selector/customer-view-dialog.tsx @@ -1,209 +1,224 @@ import { - Badge, Button, Card, CardContent, CardHeader, CardTitle, - Dialog, - DialogContent, - DialogDescription, - DialogHeader, - DialogTitle, + Badge, + Button, + Card, + CardContent, + CardHeader, + CardTitle, + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, } from "@repo/shadcn-ui/components"; import { Banknote, FileText, Languages, Mail, MapPin, Phone, Smartphone, X } from "lucide-react"; + // CustomerViewDialog.tsx import { useCustomerQuery } from "../../hooks"; type CustomerViewDialogProps = { - customerId: string | null; - open: boolean; - onOpenChange: (open: boolean) => void; -} - -export const CustomerViewDialog = ({ - customerId, - open, - onOpenChange, -}: CustomerViewDialogProps) => { - const { - data: customer, - isLoading, - isError, - error, - } = useCustomerQuery(customerId ?? "", { enabled: open && !!customerId }); - - return ( - - - - - - {customer?.name ?? "Cliente"} - {customer?.trade_name && ( - ({customer.trade_name}) - )} - - - - - {customer?.tin ? ( - {customer.tin} - ) : ( - Ficha del cliente - )} - - - -
- {isLoading &&

Cargando…

} - {isError && ( -

- {(error as Error)?.message ?? "No se pudo cargar el cliente"} -

- )} - - {!isLoading && !isError && customer && ( -
- - - - - Información Básica - - - -
-
Nombre
-
{customer.name}
-
- {customer.reference && ( -
-
Referencia
-
{customer.reference}
-
- )} - {customer.legal_record && ( -
-
Registro Legal
-
{customer.legal_record}
-
- )} - {!!customer.default_taxes?.length && ( -
-
Impuestos por defecto
-
- {customer.default_taxes.map((tax: string) => ( - {tax} - ))} -
-
- )} -
-
- - - - - - Dirección - - - -
-
Calle
-
- {customer.street} - {customer.street2 && (<>
{customer.street2})} -
-
-
-
-
Ciudad
-
{customer.city}
-
-
-
Código Postal
-
{customer.postal_code}
-
-
-
-
-
Provincia
-
{customer.province}
-
-
-
País
-
{customer.country}
-
-
-
-
- - - - - - Contacto y Preferencias - - - -
- {customer.email_primary && ( -
- -
-
Email
-
{customer.email_primary}
-
-
- )} - {customer.mobile_primary && ( -
- -
-
Móvil
-
{customer.mobile_primary}
-
-
- )} - {customer.phone_primary && ( -
- -
-
Teléfono
-
{customer.phone_primary}
-
-
- )} -
- -
-
- -
-
Idioma
-
{customer.language_code}
-
-
-
- -
-
Moneda
-
{customer.currency_code}
-
-
-
-
-
-
- )} -
-
-
- ); + customerId: string | null; + open: boolean; + onOpenChange: (open: boolean) => void; +}; + +export const CustomerViewDialog = ({ customerId, open, onOpenChange }: CustomerViewDialogProps) => { + const { + data: customer, + isLoading, + isError, + error, + } = useCustomerQuery(customerId ?? "", { enabled: open && !!customerId }); + + return ( + + + + + + {customer?.name ?? "Cliente"} + {customer?.trade_name && ( + ({customer.trade_name}) + )} + + + + + {customer?.tin ? ( + + {customer.tin} + + ) : ( + Ficha del cliente + )} + + + +
+ {isLoading && ( +

+ Cargando… +

+ )} + {isError && ( +

+ {(error as Error)?.message ?? "No se pudo cargar el cliente"} +

+ )} + + {!(isLoading || isError) && customer && ( +
+ + + + + Información Básica + + + +
+
Nombre
+
{customer.name}
+
+ {customer.reference && ( +
+
Referencia
+
{customer.reference}
+
+ )} + {customer.legal_record && ( +
+
Registro Legal
+
{customer.legal_record}
+
+ )} + {!!customer.default_taxes?.length && ( +
+
Impuestos por defecto
+
+ {customer.default_taxes.map((tax: string) => ( + + {tax} + + ))} +
+
+ )} +
+
+ + + + + + Dirección + + + +
+
Calle
+
+ {customer.street} + {customer.street2 && ( + <> +
+ {customer.street2} + + )} +
+
+
+
+
Ciudad
+
{customer.city}
+
+
+
Código Postal
+
{customer.postal_code}
+
+
+
+
+
Provincia
+
{customer.province}
+
+
+
País
+
{customer.country}
+
+
+
+
+ + + + + + Contacto y Preferencias + + + +
+ {customer.email_primary && ( +
+ +
+
Email
+
{customer.email_primary}
+
+
+ )} + {customer.mobile_primary && ( +
+ +
+
Móvil
+
{customer.mobile_primary}
+
+
+ )} + {customer.phone_primary && ( +
+ +
+
Teléfono
+
{customer.phone_primary}
+
+
+ )} +
+ +
+
+ +
+
Idioma
+
{customer.language_code}
+
+
+
+ +
+
Moneda
+
{customer.currency_code}
+
+
+
+
+
+
+ )} +
+
+
+ ); }; diff --git a/modules/customers/src/web/components/customers-layout.tsx b/modules/customers/src/web/components/customers-layout.tsx deleted file mode 100644 index 77d9a81c..00000000 --- a/modules/customers/src/web/components/customers-layout.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import type { PropsWithChildren } from "react"; - -import { CustomersProvider } from "../context"; - -export const CustomersLayout = ({ children }: PropsWithChildren) => { - return {children}; -}; diff --git a/modules/customers/src/web/components/editor/customer-additional-config-fields.tsx b/modules/customers/src/web/components/editor/customer-additional-config-fields.tsx index a9a5b5d9..a9b6a533 100644 --- a/modules/customers/src/web/components/editor/customer-additional-config-fields.tsx +++ b/modules/customers/src/web/components/editor/customer-additional-config-fields.tsx @@ -1,18 +1,24 @@ -import { Field, FieldDescription, FieldGroup, FieldLegend, FieldSet } from '@repo/shadcn-ui/components'; - import { SelectField } from "@repo/rdx-ui/components"; +import { + Field, + FieldDescription, + FieldGroup, + FieldLegend, + FieldSet, +} from "@repo/shadcn-ui/components"; import { useFormContext } from "react-hook-form"; + import { CURRENCY_OPTIONS, LANGUAGE_OPTIONS } from "../../constants"; import { useTranslation } from "../../i18n"; -import { CustomerFormData } from "../../schemas"; +import type { CustomerFormData } from "../../schemas"; interface CustomerAdditionalConfigFieldsProps { className?: string; } - export const CustomerAdditionalConfigFields = ({ - className, ...props + className, + ...props }: CustomerAdditionalConfigFieldsProps) => { const { t } = useTranslation(); const { control } = useFormContext(); @@ -21,28 +27,28 @@ export const CustomerAdditionalConfigFields = ({
{t("form_groups.preferences.title")} {t("form_groups.preferences.description")} - - + + - + diff --git a/modules/customers/src/web/components/editor/customer-address-fields.tsx b/modules/customers/src/web/components/editor/customer-address-fields.tsx index 8be4d7c3..2d9a5a7f 100644 --- a/modules/customers/src/web/components/editor/customer-address-fields.tsx +++ b/modules/customers/src/web/components/editor/customer-address-fields.tsx @@ -1,12 +1,16 @@ +import { SelectField, TextField } from "@repo/rdx-ui/components"; import { - SelectField, - TextField -} from "@repo/rdx-ui/components"; -import { Field, FieldDescription, FieldGroup, FieldLegend, FieldSet } from '@repo/shadcn-ui/components'; + Field, + FieldDescription, + FieldGroup, + FieldLegend, + FieldSet, +} from "@repo/shadcn-ui/components"; import { useFormContext } from "react-hook-form"; + import { COUNTRY_OPTIONS } from "../../constants"; import { useTranslation } from "../../i18n"; -import { CustomerFormData } from "../../schemas"; +import type { CustomerFormData } from "../../schemas"; interface CustomerAddressFieldsProps { className?: string; @@ -20,58 +24,58 @@ export const CustomerAddressFields = ({ className, ...props }: CustomerAddressFi
{t("form_groups.address.title")} {t("form_groups.address.description")} - + - + - + diff --git a/modules/customers/src/web/components/editor/customer-editor-skeleton.tsx b/modules/customers/src/web/components/editor/customer-editor-skeleton.tsx index 872650b0..2c9df64f 100644 --- a/modules/customers/src/web/components/editor/customer-editor-skeleton.tsx +++ b/modules/customers/src/web/components/editor/customer-editor-skeleton.tsx @@ -1,6 +1,7 @@ // components/CustomerSkeleton.tsx import { AppContent, BackHistoryButton } from "@repo/rdx-ui/components"; import { Button } from "@repo/shadcn-ui/components"; + import { useTranslation } from "../../i18n"; export const CustomerEditorSkeleton = () => { @@ -8,24 +9,24 @@ export const CustomerEditorSkeleton = () => { return ( <> -
-