"use client"; // Lightweight wrapper around . Used anywhere we want a // "Show 3D" toggle that reveals the in-browser STEP viewer on demand: // // - Assembly detail page (admin) // - Operator scan page (phone) // // Keeps the heavy occt / three.js / WASM out of the initial bundle via // next/dynamic + ssr:false, and only starts loading when the user taps // the toggle. // // Intentionally does NOT capture thumbnails — the part detail page has // its own richer variant for that. Here we just render the model. import dynamic from "next/dynamic"; import { useState } from "react"; const StepViewer = dynamic(() => import("@/components/StepViewer"), { ssr: false, loading: () => (
Loading viewer…
), }); interface Props { /** FileAsset id whose bytes will be streamed from /api/v1/files/:id/download. */ fileId: string; /** Human-friendly file name shown in the header. */ fileName: string; /** Panel heading, e.g. "3D viewer" or "Assembly 3D". */ title?: string; /** If true, the panel renders already open. Defaults to false — saves the * ~2 MB WASM download until the operator actually asks for it, which matters * on a phone. */ defaultOpen?: boolean; /** Height of the viewer canvas. Defaults to 360 (good for phones). Admin * pages can bump this to 480. */ height?: number; /** Extra tailwind classes for the outer
. */ className?: string; } export default function StepViewerPanel({ fileId, fileName, title = "3D viewer", defaultOpen = false, height = 360, className, }: Props) { const [open, setOpen] = useState(defaultOpen); const [edges, setEdges] = useState(true); const url = `/api/v1/files/${fileId}/download`; return (

{title}

{open ? ( ) : null}
{open ? (
Viewing: {fileName}

Drag to rotate · pinch / scroll to zoom · two-finger drag to pan. Rendered in your browser — the STEP file isn't downloaded to your device.

) : (

Interactive 3D preview. Tap Show 3D to load (~2 MB of viewer code fetched on first use).

)}
); }