feat(receipts): upload guide page + scanner head-tag fix
Adds /invoices/upload-receipts as the dedicated explainer for the mobile scanner PWA: install instructions for iOS/Android, direct deep-link button, and a walkthrough of the scan -> verify -> save flow. Sidebar entry replaces the old "Scan receipt" tab so the desktop side picks up the install steps before sending users to the mobile-only surface. Scanner layout moves PWA manifest + apple-* meta tags from inline JSX into Next.js's metadata/viewport exports so the App Router doesn't try to render a second <head>, fixing a hydration error that surfaced as two console warnings on the scan page. Scanner shell gains a centered Port Nimara logo header so the standalone PWA looks branded when launched from the home screen without the dashboard chrome. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
import type { Metadata } from 'next';
|
||||
|
||||
import { UploadReceiptsGuide } from '@/components/invoices/upload-receipts-guide';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'How to upload receipts',
|
||||
};
|
||||
|
||||
export default async function UploadReceiptsPage({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ portSlug: string }>;
|
||||
}) {
|
||||
const { portSlug } = await params;
|
||||
return <UploadReceiptsGuide portSlug={portSlug} />;
|
||||
}
|
||||
@@ -1,20 +1,51 @@
|
||||
import type { Metadata, Viewport } from 'next';
|
||||
import { redirect } from 'next/navigation';
|
||||
import { headers } from 'next/headers';
|
||||
import { eq } from 'drizzle-orm';
|
||||
|
||||
import { auth } from '@/lib/auth';
|
||||
import { db } from '@/lib/db';
|
||||
import { ports as portsTable } from '@/lib/db/schema/ports';
|
||||
import { QueryProvider } from '@/providers/query-provider';
|
||||
import { PortProvider } from '@/providers/port-provider';
|
||||
import { eq } from 'drizzle-orm';
|
||||
|
||||
/**
|
||||
* Minimal layout for the mobile receipt-scanner PWA. No sidebar, no
|
||||
* topbar — the scanner is its own contained surface. Adds the PWA
|
||||
* manifest link + theme color so iOS/Android pick up "Add to Home
|
||||
* Screen". Auth check matches the dashboard layout so unauthorized
|
||||
* users still bounce to /login.
|
||||
* topbar - the scanner is its own contained surface. PWA manifest +
|
||||
* iOS web-app meta tags are emitted via Next.js's metadata/viewport
|
||||
* exports so React doesn't try to render a second `<head>` mid-tree
|
||||
* (which throws hydration errors in the App Router). Auth check
|
||||
* matches the dashboard layout so unauthorized users still bounce.
|
||||
*/
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ portSlug: string }>;
|
||||
}): Promise<Metadata> {
|
||||
const { portSlug } = await params;
|
||||
return {
|
||||
manifest: `/${portSlug}/scan/manifest.webmanifest`,
|
||||
appleWebApp: {
|
||||
capable: true,
|
||||
title: 'PN Scanner',
|
||||
statusBarStyle: 'default',
|
||||
},
|
||||
other: {
|
||||
// Android/Chrome equivalent of the apple-* meta. metadata.appleWebApp
|
||||
// covers iOS only; this preserves the existing PWA hint for Chrome.
|
||||
'mobile-web-app-capable': 'yes',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export const viewport: Viewport = {
|
||||
themeColor: '#3a7bc8',
|
||||
width: 'device-width',
|
||||
initialScale: 1,
|
||||
viewportFit: 'cover',
|
||||
};
|
||||
|
||||
export default async function ScannerLayout({
|
||||
children,
|
||||
params,
|
||||
@@ -33,16 +64,7 @@ export default async function ScannerLayout({
|
||||
|
||||
return (
|
||||
<QueryProvider>
|
||||
<PortProvider ports={port ? [port] : []} defaultPortId={port?.id ?? null}>
|
||||
<head>
|
||||
<link rel="manifest" href={`/${portSlug}/scan/manifest.webmanifest`} />
|
||||
<meta name="theme-color" content="#3a7bc8" />
|
||||
<meta name="mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
|
||||
<meta name="apple-mobile-web-app-title" content="PN Scanner" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
</head>
|
||||
<PortProvider ports={[port]} defaultPortId={port.id}>
|
||||
<div className="min-h-[100dvh] bg-background">{children}</div>
|
||||
</PortProvider>
|
||||
</QueryProvider>
|
||||
|
||||
Reference in New Issue
Block a user