L7 Offline & PWA: Sync-Seite, Offline-Ansicht, Sync-Badge, Installationshinweis, Logout-Schutz
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
import { requireModule } from "@/server/modules";
|
||||
|
||||
/** Modul-Gate „field" für die Offline-Ansicht (Lane L7). */
|
||||
export default async function ModuleLayout({ children }: Readonly<{ children: React.ReactNode }>) {
|
||||
await requireModule("field");
|
||||
return <>{children}</>;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import { OfflineView } from "@/components/offline/offline-view";
|
||||
|
||||
/**
|
||||
* `/m/offline` — offline fallback (lane L7): order list/detail from the local bundle. Cached by the
|
||||
* service worker; the content is rendered on the client from IndexedDB, so the cached HTML stays
|
||||
* valid while offline.
|
||||
*/
|
||||
export default async function OfflinePage() {
|
||||
const t = await getTranslations("offline.view");
|
||||
return (
|
||||
<main className="space-y-4 p-4">
|
||||
<h1 className="text-[26px]">{t("title")}</h1>
|
||||
<OfflineView />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import { requireModule } from "@/server/modules";
|
||||
|
||||
/** Modul-Gate „field" für die Synchronisationsseite (Lane L7). */
|
||||
export default async function ModuleLayout({ children }: Readonly<{ children: React.ReactNode }>) {
|
||||
await requireModule("field");
|
||||
return <>{children}</>;
|
||||
}
|
||||
@@ -1,23 +1,17 @@
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import { OnlineBadge } from "@/components/field/online-badge";
|
||||
import { card } from "@/components/field/ui";
|
||||
import { SyncPanel } from "@/components/offline/sync-panel";
|
||||
|
||||
/**
|
||||
* PLACEHOLDER (lane L4) — `/m/sync` belongs to lane L7 (Offline/PWA), which replaces this page
|
||||
* with the outbox status, errors and conflicts. Until then it shows the connection state and that
|
||||
* ops are sent immediately (src/lib/field/client-ops.ts).
|
||||
* `/m/sync` (lane L7, Spec §22/§23.4, US-012): connection, last sync, pending changes and uploads
|
||||
* with progress, errors/conflicts in plain language (retry / discard), storage usage, reset. The
|
||||
* data lives on the device (IndexedDB), so the panel is a client component.
|
||||
*/
|
||||
export default async function SyncPlaceholderPage() {
|
||||
const t = await getTranslations("field.sync");
|
||||
export default async function SyncPage() {
|
||||
const t = await getTranslations("offline.sync");
|
||||
return (
|
||||
<main className="space-y-4 p-4">
|
||||
<h1 className="text-[26px]">{t("title")}</h1>
|
||||
<section className={`${card} space-y-3`}>
|
||||
<p className="text-[13px] font-semibold text-muted-foreground">{t("status")}</p>
|
||||
<OnlineBadge large />
|
||||
<p className="text-[15px]">{t("immediate")}</p>
|
||||
<p className="text-[14px] text-muted-foreground">{t("offlineHint")}</p>
|
||||
</section>
|
||||
<SyncPanel />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user