feat: Latest production version with interior scene and glass
Includes room interior with floor, walls, glass you can see through, and all uncommitted production changes that were running live. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import { Suspense } from "react";
|
||||
import { Suspense, useCallback } from "react";
|
||||
import { useConfiguratorStore } from "@/lib/store";
|
||||
import { Scene3D } from "./scene";
|
||||
import { Camera } from "lucide-react";
|
||||
|
||||
function LoadingFallback() {
|
||||
return (
|
||||
@@ -15,8 +16,31 @@ function LoadingFallback() {
|
||||
);
|
||||
}
|
||||
|
||||
function formatPrice(amount: number): string {
|
||||
return new Intl.NumberFormat("nl-NL", {
|
||||
style: "currency",
|
||||
currency: "EUR",
|
||||
minimumFractionDigits: 0,
|
||||
maximumFractionDigits: 0,
|
||||
}).format(amount);
|
||||
}
|
||||
|
||||
export function DoorVisualizer() {
|
||||
const { doorType, gridType, finish, handle } = useConfiguratorStore();
|
||||
const { doorType, gridType, finish, handle, priceBreakdown, setScreenshotDataUrl } =
|
||||
useConfiguratorStore();
|
||||
|
||||
const handleScreenshot = useCallback(() => {
|
||||
const canvas = document.querySelector("canvas");
|
||||
if (!canvas) return;
|
||||
const dataUrl = canvas.toDataURL("image/png");
|
||||
setScreenshotDataUrl(dataUrl);
|
||||
|
||||
// Also trigger download
|
||||
const link = document.createElement("a");
|
||||
link.download = "proinn-deur-configuratie.png";
|
||||
link.href = dataUrl;
|
||||
link.click();
|
||||
}, [setScreenshotDataUrl]);
|
||||
|
||||
return (
|
||||
<div className="relative h-full w-full overflow-hidden rounded-[2.5rem]">
|
||||
@@ -28,13 +52,36 @@ export function DoorVisualizer() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Screenshot Button */}
|
||||
<div className="absolute right-8 top-8 z-10">
|
||||
<button
|
||||
onClick={handleScreenshot}
|
||||
className="flex items-center gap-2 rounded-full bg-[#1A2E2E]/80 px-3 py-2 text-xs font-medium text-white shadow-lg backdrop-blur-sm transition-all hover:bg-[#1A2E2E]"
|
||||
>
|
||||
<Camera className="size-3.5" />
|
||||
Screenshot
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* 3D Scene */}
|
||||
<Suspense fallback={<LoadingFallback />}>
|
||||
<Scene3D />
|
||||
</Suspense>
|
||||
|
||||
{/* Live Price Badge */}
|
||||
<div className="absolute right-8 bottom-24 z-10 lg:bottom-8">
|
||||
<div className="rounded-2xl bg-[#1A2E2E] px-5 py-3 text-right shadow-lg">
|
||||
<div className="text-[10px] font-medium uppercase tracking-wider text-gray-400">
|
||||
Indicatieprijs
|
||||
</div>
|
||||
<div className="text-xl font-bold text-[#C4D668]">
|
||||
{formatPrice(priceBreakdown.totalPrice)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Configuration Info Card */}
|
||||
<div className="absolute bottom-8 left-8 right-8 z-10">
|
||||
<div className="absolute bottom-8 left-8 z-10">
|
||||
<div className="rounded-2xl bg-white/90 p-4 shadow-lg backdrop-blur-sm">
|
||||
<div className="grid grid-cols-2 gap-3 text-sm">
|
||||
<div>
|
||||
@@ -64,9 +111,9 @@ export function DoorVisualizer() {
|
||||
</div>
|
||||
|
||||
{/* Controls Hint */}
|
||||
<div className="absolute bottom-8 right-8 z-10 hidden lg:block">
|
||||
<div className="absolute bottom-8 right-8 z-10 hidden lg:hidden">
|
||||
<div className="rounded-xl bg-[#1A2E2E]/80 px-3 py-2 text-xs text-white backdrop-blur-sm">
|
||||
<p className="font-medium">🖱️ Drag to rotate • Scroll to zoom</p>
|
||||
<p className="font-medium">Drag to rotate - Scroll to zoom</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user