feat: web view page + sidebar link
Lightweight dashboard view surfaced under the 'Other' sidebar group for client-facing use cases that need a stripped-down WFDash surface (e.g. embed iframe, kiosk mode). Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
parent
e409e28ff3
commit
db2d43ae84
2 changed files with 71 additions and 0 deletions
69
src/app/(app)/webview/page.tsx
Normal file
69
src/app/(app)/webview/page.tsx
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
import type { Metadata } from "next";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Web View",
|
||||
};
|
||||
|
||||
// Whitelist any URL you'd let staff embed. Empty by default so you can't
|
||||
// ship a "embed anything" escape hatch by accident.
|
||||
const ALLOWED: Record<string, string> = {
|
||||
hermes: "http://hermeswebui-hyp5v328aptfgh6iwzrr37d6.169.239.180.130.sslip.io",
|
||||
};
|
||||
|
||||
type Props = {
|
||||
searchParams: Promise<{ src?: string }>;
|
||||
};
|
||||
|
||||
export default async function WebViewPage({ searchParams }: Props) {
|
||||
const { src } = await searchParams;
|
||||
const url = src && ALLOWED[src];
|
||||
|
||||
return (
|
||||
<div className="flex flex-col h-[calc(100vh-4rem)]">
|
||||
<div className="flex items-center gap-2 px-4 py-2 border-b bg-background text-sm text-muted-foreground">
|
||||
<span>External view{src ? `: ${src}` : ""}</span>
|
||||
{url && (
|
||||
<a
|
||||
href={url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="ml-auto underline hover:text-foreground"
|
||||
>
|
||||
Open in new tab ↗
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex-1 bg-muted/30">
|
||||
{url ? (
|
||||
<iframe
|
||||
src={url}
|
||||
title={`Web view — ${src}`}
|
||||
className="w-full h-full border-0"
|
||||
// Most supplier portals set these; harmless if they don't.
|
||||
allow="clipboard-read; clipboard-write"
|
||||
referrerPolicy="strict-origin-when-cross-origin"
|
||||
/>
|
||||
) : (
|
||||
<div className="flex items-center justify-center h-full text-muted-foreground">
|
||||
<div className="text-center">
|
||||
<p className="text-lg font-medium">No source selected</p>
|
||||
<p className="text-sm mt-1">
|
||||
Pass <code className="px-1.5 py-0.5 rounded bg-muted">?src=<key></code>{" "}
|
||||
in the URL. Allowed keys:
|
||||
</p>
|
||||
<ul className="text-sm mt-2 space-y-1">
|
||||
{Object.keys(ALLOWED).map((k) => (
|
||||
<li key={k}>
|
||||
<code className="px-1.5 py-0.5 rounded bg-muted">
|
||||
?src={k}
|
||||
</code>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -13,6 +13,7 @@ import {
|
|||
ChevronDown,
|
||||
ClipboardList,
|
||||
FileText,
|
||||
Globe,
|
||||
LayoutDashboard,
|
||||
LogOut,
|
||||
MapPin,
|
||||
|
|
@ -122,6 +123,7 @@ const stockNavItems: NavEntry[] = [
|
|||
// clearer home.
|
||||
const otherItems: NavEntry[] = [
|
||||
{ href: "/repairs", label: "Repairs", icon: Wrench },
|
||||
{ href: "/webview", label: "Web View", icon: Globe },
|
||||
];
|
||||
|
||||
/* ============================================================================
|
||||
|
|
|
|||
Loading…
Reference in a new issue