SHL-02: PageContainer-Komponente, 16 kopierte Seiten-Container ersetzt #371
No files matched your search
@@ -3,10 +3,11 @@
|
||||
import { ExtractionReviewCard } from "./ExtractionReviewCard";
|
||||
import { getInvoiceExtraction } from "../lib/api";
|
||||
import { EXAMPLE_INVOICE } from "../lib/examples";
|
||||
import { PageContainer } from "@nexarch/shl";
|
||||
|
||||
export default function ExtractionReviewPage() {
|
||||
return (
|
||||
<main style={{ maxWidth: 800, margin: "0 auto", padding: 24 }}>
|
||||
<PageContainer maxWidth={800}>
|
||||
<h1>Extraktions-Korrektur</h1>
|
||||
<ExtractionReviewCard
|
||||
title={EXAMPLE_INVOICE.title}
|
||||
@@ -21,6 +22,6 @@ export default function ExtractionReviewPage() {
|
||||
console.log("Bestaetigte Werte:", values);
|
||||
}}
|
||||
/>
|
||||
</main>
|
||||
</PageContainer>
|
||||
);
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import { useState } from "react";
|
||||
import { SearchPanel } from "./SearchPanel";
|
||||
import { ChatPanel, ChatTurn } from "./ChatPanel";
|
||||
import { Hit } from "../lib/api";
|
||||
import { PageContainer } from "@nexarch/shl";
|
||||
|
||||
type Tab = "search" | "chat";
|
||||
|
||||
@@ -17,7 +18,7 @@ export default function SearchChatPage() {
|
||||
const [chatHistory, setChatHistory] = useState<ChatTurn[]>([]);
|
||||
|
||||
return (
|
||||
<main style={{ maxWidth: 800, margin: "0 auto", padding: 24 }}>
|
||||
<PageContainer maxWidth={800}>
|
||||
<h1>Suche und Chat</h1>
|
||||
|
||||
<div role="tablist" aria-label="Ansicht" style={{ marginBottom: 16 }}>
|
||||
@@ -59,6 +60,6 @@ export default function SearchChatPage() {
|
||||
onHistoryChange={setChatHistory}
|
||||
/>
|
||||
</div>
|
||||
</main>
|
||||
</PageContainer>
|
||||
);
|
||||
}
|
||||
@@ -3,10 +3,11 @@
|
||||
import { SummaryCard } from "./SummaryCard";
|
||||
import { getDocumentSummary, getThreadSummary } from "../lib/api";
|
||||
import { EXAMPLE_DOCUMENT, EXAMPLE_THREAD } from "../lib/examples";
|
||||
import { PageContainer } from "@nexarch/shl";
|
||||
|
||||
export default function SummariesPage() {
|
||||
return (
|
||||
<main style={{ maxWidth: 800, margin: "0 auto", padding: 24 }}>
|
||||
<PageContainer maxWidth={800}>
|
||||
<h1>Zusammenfassungen</h1>
|
||||
<SummaryCard
|
||||
title={EXAMPLE_DOCUMENT.title}
|
||||
@@ -20,6 +21,6 @@ export default function SummariesPage() {
|
||||
sourceLabel="Thread ansehen"
|
||||
load={async () => (await getThreadSummary(EXAMPLE_THREAD.id)).summary}
|
||||
/>
|
||||
</main>
|
||||
</PageContainer>
|
||||
);
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import { useState } from "react";
|
||||
import { fetchRecords, downloadExport, type AuditRecord, type AuditFilter } from "@/lib/api";
|
||||
import { PageContainer } from "@nexarch/shl";
|
||||
|
||||
const EMPTY_FILTER: AuditFilter = { tenant: "", actor: "", action: "", from: "", to: "" };
|
||||
|
||||
@@ -37,7 +38,7 @@ export default function Page() {
|
||||
}
|
||||
|
||||
return (
|
||||
<main style={{ maxWidth: 1000, margin: "0 auto", padding: "2rem 1rem" }}>
|
||||
<PageContainer maxWidth={1000} padding={"2rem 1rem"}>
|
||||
<h1>Audit-Log</h1>
|
||||
|
||||
<div style={{ display: "grid", gap: "0.5rem", gridTemplateColumns: "repeat(3, 1fr)", marginBottom: "1rem" }}>
|
||||
@@ -163,6 +164,6 @@ export default function Page() {
|
||||
<button onClick={() => setSelected(null)}>Schließen</button>
|
||||
</section>
|
||||
)}
|
||||
</main>
|
||||
</PageContainer>
|
||||
);
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
import { ControlSections } from "./ControlSections";
|
||||
import { PageContainer } from "@nexarch/shl";
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<main style={{ maxWidth: 1100, margin: "0 auto", padding: 24 }}>
|
||||
<PageContainer maxWidth={1100}>
|
||||
<h1>NEXARCH Core-Steuerung</h1>
|
||||
<ControlSections />
|
||||
</main>
|
||||
</PageContainer>
|
||||
);
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
import { UploadManager } from "../components/UploadManager";
|
||||
import { PageContainer } from "@nexarch/shl";
|
||||
|
||||
export default function IndexPage() {
|
||||
return (
|
||||
<main style={{ maxWidth: 720, margin: "0 auto", padding: "24px 16px" }}>
|
||||
<PageContainer maxWidth={720} padding={"24px 16px"}>
|
||||
<h1>Dokumente hochladen</h1>
|
||||
<UploadManager />
|
||||
</main>
|
||||
</PageContainer>
|
||||
);
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { Suspense } from "react";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import { TextField } from "@nexarch/shl";
|
||||
import { TextField, PageContainer } from "@nexarch/shl";
|
||||
import { ImportAssistant } from "./ImportAssistant";
|
||||
|
||||
function ImportPage() {
|
||||
@@ -11,7 +11,7 @@ function ImportPage() {
|
||||
const tenant = params.get("tenant") ?? "";
|
||||
|
||||
return (
|
||||
<main style={{ maxWidth: 1100, margin: "0 auto", padding: 24 }}>
|
||||
<PageContainer maxWidth={1100}>
|
||||
<h1>Import-Assistent fuer Drittsystem-Exporte</h1>
|
||||
{userId === "" || tenant === "" ? (
|
||||
<form
|
||||
@@ -32,7 +32,7 @@ function ImportPage() {
|
||||
) : (
|
||||
<ImportAssistant userId={userId} tenant={tenant} />
|
||||
)}
|
||||
</main>
|
||||
</PageContainer>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import { useState } from "react";
|
||||
import { fetchOverview, toggleFlag, type Overview } from "@/lib/api";
|
||||
import { PageContainer } from "@nexarch/shl";
|
||||
|
||||
const STATUS_LABEL: Record<string, string> = {
|
||||
ok: "In Ordnung",
|
||||
@@ -48,7 +49,7 @@ export default function Page() {
|
||||
}
|
||||
|
||||
return (
|
||||
<main style={{ maxWidth: 800, margin: "0 auto", padding: "2rem 1rem" }}>
|
||||
<PageContainer maxWidth={800} padding={"2rem 1rem"}>
|
||||
<h1>Lizenz- und Modulverwaltung</h1>
|
||||
|
||||
<div style={{ display: "flex", gap: "0.5rem", marginBottom: "1.5rem" }}>
|
||||
@@ -169,6 +170,6 @@ export default function Page() {
|
||||
</section>
|
||||
</>
|
||||
)}
|
||||
</main>
|
||||
</PageContainer>
|
||||
);
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { useState, useEffect, useCallback, useRef, type FormEvent } from "react";
|
||||
import Link from "next/link";
|
||||
import { TextField, useToast } from "@nexarch/shl";
|
||||
import { TextField, useToast, PageContainer } from "@nexarch/shl";
|
||||
import { search, facets, ApiError, type SearchHit, type AppliedFilter, type FacetsResponse } from "../lib/api";
|
||||
import { splitHighlighted } from "../lib/highlight";
|
||||
import { HIGHLIGHT_BG_LIGHT, HIGHLIGHT_FG_LIGHT } from "../lib/highlightColors";
|
||||
@@ -185,7 +185,7 @@ export default function SearchPage() {
|
||||
}, [hits, focusedIndex, focusResult, archiveFocused]);
|
||||
|
||||
return (
|
||||
<main style={{ maxWidth: 720, margin: "40px auto", padding: "0 16px" }}>
|
||||
<PageContainer maxWidth={720} margin={"40px auto"} padding={"0 16px"}>
|
||||
<h1>Mail-Suche</h1>
|
||||
<p style={{ color: "var(--shl-color-text-secondary, #4b5563)", fontSize: "0.875rem" }}>
|
||||
Tastenkürzel: <kbd>/</kbd> Suche fokussieren, <kbd>j</kbd>/<kbd>k</kbd> nächste/vorherige Nachricht,{" "}
|
||||
@@ -255,6 +255,6 @@ export default function SearchPage() {
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</main>
|
||||
</PageContainer>
|
||||
);
|
||||
}
|
||||
@@ -1,14 +1,14 @@
|
||||
"use client";
|
||||
|
||||
import { useI18n } from "@nexarch/shl";
|
||||
import { useI18n, PageContainer } from "@nexarch/shl";
|
||||
import "../lib/messages";
|
||||
|
||||
export default function IndexPage() {
|
||||
const { t } = useI18n();
|
||||
return (
|
||||
<main style={{ maxWidth: 720, margin: "40px auto", padding: "0 16px" }}>
|
||||
<PageContainer maxWidth={720} margin={"40px auto"} padding={"0 16px"}>
|
||||
<h1>{t("pdf.index.title", "NEXARCH Dokumentbetrachter")}</h1>
|
||||
<p>{t("pdf.index.hint", "Diese Anwendung wird über /viewer/<dokument-id> aufgerufen.")}</p>
|
||||
</main>
|
||||
</PageContainer>
|
||||
);
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { Suspense } from "react";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import { TextField } from "@nexarch/shl";
|
||||
import { TextField, PageContainer } from "@nexarch/shl";
|
||||
import { RuleEditor } from "./RuleEditor";
|
||||
|
||||
function RulesPage() {
|
||||
@@ -10,7 +10,7 @@ function RulesPage() {
|
||||
const userId = params.get("user") ?? "";
|
||||
|
||||
return (
|
||||
<main style={{ maxWidth: 1100, margin: "0 auto", padding: 24 }}>
|
||||
<PageContainer maxWidth={1100}>
|
||||
<h1>Routing-Regel-Editor</h1>
|
||||
{userId === "" ? (
|
||||
<form
|
||||
@@ -28,7 +28,7 @@ function RulesPage() {
|
||||
) : (
|
||||
<RuleEditor userId={userId} />
|
||||
)}
|
||||
</main>
|
||||
</PageContainer>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import type { CSSProperties, ReactNode } from "react";
|
||||
|
||||
export interface PageContainerProps {
|
||||
maxWidth?: CSSProperties["maxWidth"];
|
||||
margin?: CSSProperties["margin"];
|
||||
padding?: CSSProperties["padding"];
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
// Ersetzt den in 17 Seiten unabhaengig kopierten
|
||||
// `<main style={{ maxWidth, margin, padding }}>`-Container (Fable-Review
|
||||
// auf Code-Dopplung). margin/padding bleiben als Props einstellbar, da
|
||||
// die kopierten Varianten sich darin unterschieden (z. B. "0 auto" vs.
|
||||
// "40px auto", "24px" vs. "2rem 1rem").
|
||||
export function PageContainer({ maxWidth = 960, margin = "0 auto", padding = 24, children }: PageContainerProps) {
|
||||
return <main style={{ maxWidth, margin, padding }}>{children}</main>;
|
||||
}
|
||||
@@ -17,6 +17,9 @@ export type { ShellProps, ModuleLink } from "./components/Shell";
|
||||
export { ModuleNavShell, MODULE_REGISTRY, resolveModuleHref } from "./components/ModuleNavShell";
|
||||
export type { ModuleNavShellProps, ModuleRegistryEntry } from "./components/ModuleNavShell";
|
||||
|
||||
export { PageContainer } from "./components/PageContainer";
|
||||
export type { PageContainerProps } from "./components/PageContainer";
|
||||
|
||||
export { Dialog } from "./components/Dialog";
|
||||
export type { DialogProps } from "./components/Dialog";
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { fetchOverview, fetchHistory, type ModuleStatus, type HistoryEntry } from "@/lib/api";
|
||||
import { PageContainer } from "@nexarch/shl";
|
||||
|
||||
const POLL_INTERVAL_MS = 5000;
|
||||
|
||||
@@ -56,7 +57,7 @@ export default function Page() {
|
||||
const anyDown = modules.some((m) => m.status === "down");
|
||||
|
||||
return (
|
||||
<main style={{ maxWidth: 800, margin: "0 auto", padding: "2rem 1rem" }}>
|
||||
<PageContainer maxWidth={800} padding={"2rem 1rem"}>
|
||||
<h1>Systemstatus</h1>
|
||||
|
||||
{error && (
|
||||
@@ -120,6 +121,6 @@ export default function Page() {
|
||||
<button onClick={() => setSelected(null)}>Schließen</button>
|
||||
</section>
|
||||
)}
|
||||
</main>
|
||||
</PageContainer>
|
||||
);
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { PageContainer } from "@nexarch/shl";
|
||||
import {
|
||||
fetchTenants,
|
||||
fetchTenantDetail,
|
||||
@@ -97,7 +98,7 @@ export default function Page() {
|
||||
}
|
||||
|
||||
return (
|
||||
<main style={{ maxWidth: 900, margin: "0 auto", padding: "2rem 1rem" }}>
|
||||
<PageContainer maxWidth={900} padding={"2rem 1rem"}>
|
||||
<h1>Mandantenverwaltung</h1>
|
||||
|
||||
<div style={{ display: "flex", gap: "0.5rem", marginBottom: "1rem", flexWrap: "wrap" }}>
|
||||
@@ -222,6 +223,6 @@ export default function Page() {
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
</main>
|
||||
</PageContainer>
|
||||
);
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { Suspense } from "react";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import { TextField } from "@nexarch/shl";
|
||||
import { TextField, PageContainer } from "@nexarch/shl";
|
||||
import { ApprovalList } from "./ApprovalList";
|
||||
|
||||
function ApprovalsPage() {
|
||||
@@ -10,7 +10,7 @@ function ApprovalsPage() {
|
||||
const userId = params.get("user") ?? "";
|
||||
|
||||
return (
|
||||
<main style={{ maxWidth: 720, margin: "0 auto", padding: 24 }}>
|
||||
<PageContainer maxWidth={720}>
|
||||
<h1>Meine Freigaben</h1>
|
||||
{userId === "" ? (
|
||||
<form
|
||||
@@ -28,7 +28,7 @@ function ApprovalsPage() {
|
||||
) : (
|
||||
<ApprovalList userId={userId} />
|
||||
)}
|
||||
</main>
|
||||
</PageContainer>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { Suspense, useState } from "react";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import { TextField } from "@nexarch/shl";
|
||||
import { TextField, PageContainer } from "@nexarch/shl";
|
||||
import { CaseOverview } from "./CaseOverview";
|
||||
import { ReminderKanban } from "./ReminderKanban";
|
||||
|
||||
@@ -14,7 +14,7 @@ function CasesPage() {
|
||||
const [tab, setTab] = useState<Tab>("cases");
|
||||
|
||||
return (
|
||||
<main style={{ maxWidth: 1100, margin: "0 auto", padding: 24 }}>
|
||||
<PageContainer maxWidth={1100}>
|
||||
<h1>Akten & Wiedervorlagen</h1>
|
||||
{userId === "" ? (
|
||||
<form
|
||||
@@ -52,7 +52,7 @@ function CasesPage() {
|
||||
{tab === "cases" ? <CaseOverview userId={userId} /> : <ReminderKanban userId={userId} />}
|
||||
</>
|
||||
)}
|
||||
</main>
|
||||
</PageContainer>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { Suspense } from "react";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import { TextField } from "@nexarch/shl";
|
||||
import { TextField, PageContainer } from "@nexarch/shl";
|
||||
import { TaskBoard } from "./TaskBoard";
|
||||
|
||||
function TasksPage() {
|
||||
@@ -11,7 +11,7 @@ function TasksPage() {
|
||||
const tenantSlug = params.get("tenant") ?? "";
|
||||
|
||||
return (
|
||||
<main style={{ maxWidth: 1100, margin: "0 auto", padding: 24 }}>
|
||||
<PageContainer maxWidth={1100}>
|
||||
<h1>Aufgaben</h1>
|
||||
{userId === "" || tenantSlug === "" ? (
|
||||
<form
|
||||
@@ -31,7 +31,7 @@ function TasksPage() {
|
||||
) : (
|
||||
<TaskBoard userId={userId} tenantSlug={tenantSlug} />
|
||||
)}
|
||||
</main>
|
||||
</PageContainer>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user