Refactor pages to use RdxPageContent for consistent layout
- Updated IssuedInvoiceDetailPage to wrap PageErrorState in RdxPageContent. - Modified ProformaDetailPage to include RdxPageContent around PageErrorState. - Adjusted RecurringProformaDetailPage to utilize RdxPageContent for loading and error states. - Refactored CustomerViewPage to implement RdxPageContent for PageErrorState and main content. - Renamed SupplierDetailPage to SupplierViewPage and updated imports accordingly. - Removed SupplierDetailPage and created SupplierViewPage with similar functionality.
This commit is contained in:
parent
ba257fd489
commit
902f7806ed
@ -82,7 +82,7 @@ RdxPageContent
|
||||
→ composición de los hijos principales
|
||||
```
|
||||
|
||||
Regla: Las Pages no deben reconstruir estas responsabilidades con wrappers HTML locales. En Create/Update, la composición canónica es RdxPageFrame → RdxPageContainer → RdxPageContent: los errores inline y el editor son hijos directos de RdxPageContent; los dialogs son hermanos del frame; RdxPanel se reserva para secciones semánticas reales.
|
||||
Regla: Las Pages no deben reconstruir estas responsabilidades con wrappers HTML locales. En Create/Update y Detail/Show, la composición canónica es RdxPageFrame → RdxPageContainer → RdxPageContent: errores, alertas, secciones semánticas y contenido funcional son hijos directos de RdxPageContent; los dialogs son hermanos del frame; RdxPanel se reserva para secciones semánticas reales.
|
||||
|
||||
## 6. Identity y sesión
|
||||
|
||||
|
||||
@ -59,7 +59,7 @@ El error bloqueante conserva la misma jerarquía: RdxPageFrame → RdxPageContai
|
||||
|
||||
## 3. Detail
|
||||
|
||||
Un detalle normal usa `RdxPageFrame`, `RdxEditorHeader` cuando es fullscreen y el container apropiado.
|
||||
Un detalle normal usa `RdxPageFrame`, `RdxEditorHeader` cuando es fullscreen y la jerarquía `RdxPageContainer → RdxPageContent`; errores, alertas, secciones semánticas y contenido funcional viven dentro de `RdxPageContent`.
|
||||
|
||||
Un detalle documental especializado puede usar:
|
||||
|
||||
@ -69,7 +69,7 @@ RdxPageFrame content overflow-hidden
|
||||
└── inspector → scroll interno
|
||||
```
|
||||
|
||||
Solo se usa esta excepción cuando los panes necesitan permanecer visibles simultáneamente. No se crea un layout genérico de detalle si no existe repetición real.
|
||||
Solo se usa esta excepción cuando los panes necesitan permanecer visibles simultáneamente. Su scroll interno es parte del workspace documental, no el scroll estructural de la Page. No se crea un layout genérico de detalle si no existe repetición real.
|
||||
|
||||
## 4. Settings
|
||||
|
||||
|
||||
@ -78,7 +78,7 @@ Compone header, contenido y footer y es propietario del scroll principal. No con
|
||||
</RdxPageFrame>
|
||||
```
|
||||
|
||||
`contentClassName="overflow-hidden"` se reserva para layouts especializados con panes y scrolls internos.
|
||||
`contentClassName="overflow-hidden"` se reserva para layouts especializados con panes y scrolls internos; no desplaza la responsabilidad del scroll estructural de Page a wrappers locales.
|
||||
|
||||
### Headers
|
||||
|
||||
@ -134,7 +134,7 @@ AppMain (espacio disponible, sin scroll)
|
||||
|
||||
Una Page no debe usar `fixed inset-0`, `h-screen`, `h-dvh`, `overflow-y-auto` ni `overflow-auto` para reconstruir viewport o scroll principal.
|
||||
|
||||
Excepción: un detalle documental puede configurar el contenido del frame con `overflow-hidden` y delegar scroll interno a document panes o inspectors. Dialogs, sheets, drawers, overlays, viewers y paneles internos también pueden necesitar posicionamiento o scroll propios.
|
||||
Excepción: un detalle documental puede configurar el contenido del frame con `overflow-hidden` y delegar scroll interno a document panes o inspectors. Ese scroll es funcional al workspace —por ejemplo, `ProformaDetailContent` e `IssuedInvoiceDetailContent`— y no sustituye el scroll estructural de Page. Dialogs, sheets, drawers, overlays, viewers y paneles internos también pueden necesitar posicionamiento o scroll propios.
|
||||
|
||||
## 7. Superficies
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { PageErrorState } from "@erp/core/components";
|
||||
import { RdxPageContainer, RdxPageFrame } from "@repo/rdx-ui/components";
|
||||
import { RdxPageContainer, RdxPageContent, RdxPageFrame } from "@repo/rdx-ui/components";
|
||||
|
||||
import { useTranslation } from "../../../../i18n";
|
||||
import { useIssuedInvoiceDetailPageController } from "../../controllers";
|
||||
@ -23,6 +23,7 @@ export const IssuedInvoiceDetailPage = () => {
|
||||
return (
|
||||
<RdxPageFrame>
|
||||
<RdxPageContainer width="content">
|
||||
<RdxPageContent>
|
||||
<PageErrorState
|
||||
description={ctrl.state.pageError.description}
|
||||
primaryAction={ctrl.state.pageError.primaryAction}
|
||||
@ -31,6 +32,7 @@ export const IssuedInvoiceDetailPage = () => {
|
||||
title={ctrl.state.pageError.title}
|
||||
variant={ctrl.state.pageError.variant}
|
||||
/>
|
||||
</RdxPageContent>
|
||||
</RdxPageContainer>
|
||||
</RdxPageFrame>
|
||||
);
|
||||
@ -40,6 +42,7 @@ export const IssuedInvoiceDetailPage = () => {
|
||||
return (
|
||||
<RdxPageFrame>
|
||||
<RdxPageContainer width="content">
|
||||
<RdxPageContent>
|
||||
<PageErrorState
|
||||
description={t("pages.issued_invoices.detail.page_error.inconsistent.description")}
|
||||
secondaryAction={{
|
||||
@ -49,6 +52,7 @@ export const IssuedInvoiceDetailPage = () => {
|
||||
title={t("pages.issued_invoices.detail.page_error.unknown.title")}
|
||||
variant="unknown"
|
||||
/>
|
||||
</RdxPageContent>
|
||||
</RdxPageContainer>
|
||||
</RdxPageFrame>
|
||||
);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { PageErrorState } from "@erp/core/components";
|
||||
import { RdxPageFrame } from "@repo/rdx-ui/components";
|
||||
import { RdxPageContainer, RdxPageContent, RdxPageFrame } from "@repo/rdx-ui/components";
|
||||
|
||||
import { ChangeProformaStatusDialog } from "../../../change-status";
|
||||
import { IssueProformaDialog } from "../../../issue-proforma";
|
||||
@ -21,8 +21,9 @@ export const ProformaDetailPage = () => {
|
||||
|
||||
if (ctrl.state.pageError) {
|
||||
return (
|
||||
<div className="p-4 sm:p-6">
|
||||
<div className="mx-auto w-full max-w-3xl">
|
||||
<RdxPageFrame>
|
||||
<RdxPageContainer width="content">
|
||||
<RdxPageContent>
|
||||
<PageErrorState
|
||||
description={ctrl.state.pageError.description}
|
||||
primaryAction={ctrl.state.pageError.primaryAction}
|
||||
@ -31,8 +32,9 @@ export const ProformaDetailPage = () => {
|
||||
title={ctrl.state.pageError.title}
|
||||
variant={ctrl.state.pageError.variant}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</RdxPageContent>
|
||||
</RdxPageContainer>
|
||||
</RdxPageFrame>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -34,6 +34,14 @@ const DetailField = ({ label, value }: DetailFieldProps) => (
|
||||
</div>
|
||||
);
|
||||
|
||||
const RecurringProformaDetailSkeleton = ({ label }: { label: string }) => (
|
||||
<div aria-busy="true" className="space-y-6" role="status">
|
||||
<div className="h-8 w-64 animate-pulse rounded bg-muted" />
|
||||
<div className="h-48 animate-pulse rounded-lg bg-muted" />
|
||||
<span className="sr-only">{label}</span>
|
||||
</div>
|
||||
);
|
||||
|
||||
export const RecurringProformaDetailPage = () => {
|
||||
const { t, i18n } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
@ -48,17 +56,21 @@ export const RecurringProformaDetailPage = () => {
|
||||
|
||||
if (feedbackState === "loading") {
|
||||
return (
|
||||
<div aria-busy="true" className="space-y-6 p-4 sm:p-6" role="status">
|
||||
<div className="h-8 w-64 animate-pulse rounded bg-muted" />
|
||||
<div className="h-48 animate-pulse rounded-lg bg-muted" />
|
||||
<span className="sr-only">{t("recurring_proformas.detail.loading")}</span>
|
||||
</div>
|
||||
<RdxPageFrame>
|
||||
<RdxPageContainer width="wide">
|
||||
<RdxPageContent>
|
||||
<RecurringProformaDetailSkeleton label={t("recurring_proformas.detail.loading")} />
|
||||
</RdxPageContent>
|
||||
</RdxPageContainer>
|
||||
</RdxPageFrame>
|
||||
);
|
||||
}
|
||||
|
||||
if (feedbackState === "error") {
|
||||
return (
|
||||
<div className="p-4 sm:p-6">
|
||||
<RdxPageFrame>
|
||||
<RdxPageContainer width="content">
|
||||
<RdxPageContent>
|
||||
<PageErrorState
|
||||
description={t("recurring_proformas.detail.error.description")}
|
||||
primaryAction={{
|
||||
@ -70,7 +82,9 @@ export const RecurringProformaDetailPage = () => {
|
||||
title={t("recurring_proformas.detail.error.title")}
|
||||
variant="unknown"
|
||||
/>
|
||||
</div>
|
||||
</RdxPageContent>
|
||||
</RdxPageContainer>
|
||||
</RdxPageFrame>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { PageErrorState } from "@erp/core/components";
|
||||
import { useReturnToNavigation } from "@erp/core/hooks";
|
||||
import { RdxPageContainer, RdxPageFrame } from "@repo/rdx-ui/components";
|
||||
import { RdxPageContainer, RdxPageContent, RdxPageFrame } from "@repo/rdx-ui/components";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@repo/shadcn-ui/components";
|
||||
import {
|
||||
Banknote,
|
||||
@ -38,6 +38,7 @@ export const CustomerViewPage = () => {
|
||||
return (
|
||||
<RdxPageFrame>
|
||||
<RdxPageContainer width="content">
|
||||
<RdxPageContent>
|
||||
<PageErrorState
|
||||
description={ctrl.pageError.description}
|
||||
primaryAction={
|
||||
@ -71,6 +72,7 @@ export const CustomerViewPage = () => {
|
||||
title={ctrl.pageError.title}
|
||||
variant={ctrl.pageError.variant}
|
||||
/>
|
||||
</RdxPageContent>
|
||||
</RdxPageContainer>
|
||||
</RdxPageFrame>
|
||||
);
|
||||
@ -98,7 +100,8 @@ export const CustomerViewPage = () => {
|
||||
/>
|
||||
}
|
||||
>
|
||||
<RdxPageContainer className="space-y-6" width="content">
|
||||
<RdxPageContainer width="content">
|
||||
<RdxPageContent>
|
||||
{/* Información Básica */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
@ -109,7 +112,9 @@ export const CustomerViewPage = () => {
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div>
|
||||
<dt className="text-sm font-medium text-muted-foreground">{t("view.fields.name")}</dt>
|
||||
<dt className="text-sm font-medium text-muted-foreground">
|
||||
{t("view.fields.name")}
|
||||
</dt>
|
||||
<dd className="mt-1 text-base text-foreground" id="customer-view-name">
|
||||
{viewCtrl.customerData?.name}
|
||||
</dd>
|
||||
@ -185,7 +190,9 @@ export const CustomerViewPage = () => {
|
||||
<dt className="text-sm font-medium text-muted-foreground">
|
||||
{t("view.fields.country")}
|
||||
</dt>
|
||||
<dd className="mt-1 text-base text-foreground">{viewCtrl.customerData?.country}</dd>
|
||||
<dd className="mt-1 text-base text-foreground">
|
||||
{viewCtrl.customerData?.country}
|
||||
</dd>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
@ -374,6 +381,7 @@ export const CustomerViewPage = () => {
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</RdxPageContent>
|
||||
</RdxPageContainer>
|
||||
</RdxPageFrame>
|
||||
);
|
||||
|
||||
@ -6,7 +6,7 @@ const SuppliersListPage = lazy(() =>
|
||||
import("./list").then((module) => ({ default: module.SuppliersListPage }))
|
||||
);
|
||||
const SupplierDetailPage = lazy(() =>
|
||||
import("./view").then((module) => ({ default: module.SupplierDetailPage }))
|
||||
import("./view").then((module) => ({ default: module.SupplierViewPage }))
|
||||
);
|
||||
const SupplierCreatePage = lazy(() =>
|
||||
import("./create").then((module) => ({ default: module.SupplierCreatePage }))
|
||||
|
||||
@ -1 +1 @@
|
||||
export * from "./supplier-detail-page";
|
||||
export * from "./supplier-view-page";
|
||||
|
||||
@ -23,8 +23,13 @@ const DetailField = ({ label, value }: { label: ReactNode; value?: ReactNode })
|
||||
</div>
|
||||
);
|
||||
|
||||
export const SupplierDetailPage = () => {
|
||||
const SupplierViewContent = ({ children }: { children: ReactNode }) => (
|
||||
<div className="grid gap-4 lg:grid-cols-2">{children}</div>
|
||||
);
|
||||
|
||||
export const SupplierViewPage = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { id } = useParams();
|
||||
const navigate = useNavigate();
|
||||
const [searchParams] = useSearchParams();
|
||||
@ -40,6 +45,7 @@ export const SupplierDetailPage = () => {
|
||||
return (
|
||||
<RdxPageFrame>
|
||||
<RdxPageContainer width="content">
|
||||
<RdxPageContent>
|
||||
<PageErrorState
|
||||
description={t("detail.error.description")}
|
||||
primaryAction={{
|
||||
@ -52,6 +58,7 @@ export const SupplierDetailPage = () => {
|
||||
title={t("detail.error.title")}
|
||||
variant="notFound"
|
||||
/>
|
||||
</RdxPageContent>
|
||||
</RdxPageContainer>
|
||||
</RdxPageFrame>
|
||||
);
|
||||
@ -100,7 +107,7 @@ export const SupplierDetailPage = () => {
|
||||
>
|
||||
<RdxPageContainer width="full">
|
||||
<RdxPageContent spacing="default">
|
||||
<div className="grid gap-4 lg:grid-cols-2">
|
||||
<SupplierViewContent>
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2 text-lg">
|
||||
@ -185,7 +192,7 @@ export const SupplierDetailPage = () => {
|
||||
</dl>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</SupplierViewContent>
|
||||
</RdxPageContent>
|
||||
</RdxPageContainer>
|
||||
</RdxPageFrame>
|
||||
Loading…
Reference in New Issue
Block a user