Code edited in Lovable Code Editor

Edited UI in Lovable
This commit is contained in:
gpt-engineer-app[bot]
2026-02-27 03:15:10 +00:00
parent 5c98b53fe1
commit 1e3911ba0a
+28 -83
View File
@@ -1,46 +1,25 @@
import { useNavigate } from 'react-router-dom'; import { useNavigate } from "react-router-dom";
import { ArrowLeft, Glasses, Box, Ruler, FileText, Columns2, Download } from 'lucide-react'; import { ArrowLeft, Glasses, Box, Ruler, FileText } from "lucide-react";
import { Button } from '@/components/ui/button'; import { Button } from "@/components/ui/button";
import { useModelStore } from '@/stores/useModelStore'; import { useModelStore } from "@/stores/useModelStore";
import { ModelViewerCanvas } from '@/components/three/ModelViewer'; import { ModelViewerCanvas } from "@/components/three/ModelViewer";
import { ViewerControls } from '@/components/ViewerControls'; import { ViewerControls } from "@/components/ViewerControls";
import { InspectionChecklist } from '@/components/InspectionChecklist'; import { InspectionChecklist } from "@/components/InspectionChecklist";
import { FineTuningControls } from '@/components/FineTuningControls'; import { FineTuningControls } from "@/components/FineTuningControls";
import { MeasurementsList } from '@/components/MeasurementsList'; import { MeasurementsList } from "@/components/MeasurementsList";
import { ScreenshotGallery } from '@/components/ScreenshotGallery'; import { ScreenshotGallery } from "@/components/ScreenshotGallery";
import { ComparePanel } from '@/components/ComparePanel'; import { useEffect } from "react";
import { useEffect, useCallback } from 'react'; import { toast } from "sonner";
import { toast } from 'sonner'; import { ScrollArea } from "@/components/ui/scroll-area";
import { ScrollArea } from '@/components/ui/scroll-area'; import { Separator } from "@/components/ui/separator";
import { Separator } from '@/components/ui/separator';
import { generateInspectionReport } from '@/lib/generateReport';
const Viewer = () => { const Viewer = () => {
const navigate = useNavigate(); const navigate = useNavigate();
const { model, xrSupported, compareMode, setCompareMode, checklist, measurements, screenshots, fineTuning } = useModelStore(); const { model, xrSupported } = useModelStore();
const handleExportPDF = useCallback(async () => {
if (!model) return;
toast.info('Gerando relatório PDF…');
try {
await generateInspectionReport({
fileName: model.fileName,
fileSize: model.fileSize,
fineTuning,
checklist,
measurements,
screenshots,
});
toast.success('Relatório exportado com sucesso!');
} catch (err) {
console.error(err);
toast.error('Erro ao gerar o relatório.');
}
}, [model, fineTuning, checklist, measurements, screenshots]);
useEffect(() => { useEffect(() => {
if (!model) { if (!model) {
navigate('/'); navigate("/");
} }
}, [model, navigate]); }, [model, navigate]);
@@ -48,10 +27,10 @@ const Viewer = () => {
const handleEnterXR = async () => { const handleEnterXR = async () => {
if (!xrSupported) { if (!xrSupported) {
toast.error('WebXR não é suportado neste navegador. Use o navegador do Meta Quest 3.'); toast.error("WebXR não é suportado neste navegador. Use o navegador do Meta Quest 3.");
return; return;
} }
navigate('/xr'); navigate("/xr");
}; };
return ( return (
@@ -59,61 +38,30 @@ const Viewer = () => {
{/* Top bar */} {/* Top bar */}
<header className="flex items-center justify-between border-b bg-card px-4 py-3"> <header className="flex items-center justify-between border-b bg-card px-4 py-3">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<Button variant="ghost" size="icon" onClick={() => navigate('/')}> <Button variant="ghost" size="icon" onClick={() => navigate("/")}>
<ArrowLeft className="h-5 w-5" /> <ArrowLeft className="h-5 w-5" />
</Button> </Button>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Box className="h-5 w-5 text-primary" /> <Box className="h-5 w-5 text-primary" />
<h1 className="font-mono text-sm font-semibold text-foreground"> <h1 className="font-mono text-sm font-semibold text-foreground">
TrackkSteel<span className="text-primary">XR</span> TrackSteel<span className="text-primary">XR</span>
</h1> </h1>
</div> </div>
</div> </div>
<div className="flex items-center gap-2"> <Button className="gap-2 glow-primary" disabled={!xrSupported} onClick={handleEnterXR}>
<Button <Glasses className="h-4 w-4" />
variant="outline" Entrar em Modo XR
size="sm" </Button>
className="gap-2"
onClick={handleExportPDF}
>
<Download className="h-4 w-4" />
Exportar PDF
</Button>
<Button
variant={compareMode ? 'default' : 'outline'}
size="sm"
className="gap-2"
onClick={() => setCompareMode(!compareMode)}
>
<Columns2 className="h-4 w-4" />
Comparar
</Button>
<Button
className="gap-2 glow-primary"
disabled={!xrSupported}
onClick={handleEnterXR}
>
<Glasses className="h-4 w-4" />
Entrar em Modo XR
</Button>
</div>
</header> </header>
<div className="flex flex-1 overflow-hidden"> <div className="flex flex-1 overflow-hidden">
{/* 3D Canvas with floating controls */} {/* 3D Canvas with floating controls */}
<div className={`relative ${compareMode ? 'w-1/2' : 'flex-1'}`}> <div className="relative flex-1">
<ModelViewerCanvas url={model.url} /> <ModelViewerCanvas url={model.url} />
<ViewerControls /> <ViewerControls />
</div> </div>
{/* Compare panel */}
{compareMode && (
<div className="w-1/2 border-l">
<ComparePanel />
</div>
)}
{/* Side panel */} {/* Side panel */}
<aside className="w-80 shrink-0 border-l bg-card"> <aside className="w-80 shrink-0 border-l bg-card">
<ScrollArea className="h-full"> <ScrollArea className="h-full">
@@ -124,11 +72,7 @@ const Viewer = () => {
</h2> </h2>
<div className="space-y-3"> <div className="space-y-3">
<InfoItem icon={FileText} label="Arquivo" value={model.fileName} /> <InfoItem icon={FileText} label="Arquivo" value={model.fileName} />
<InfoItem <InfoItem icon={Box} label="Tamanho" value={`${(model.fileSize / (1024 * 1024)).toFixed(2)} MB`} />
icon={Box}
label="Tamanho"
value={`${(model.fileSize / (1024 * 1024)).toFixed(2)} MB`}
/>
<InfoItem icon={Ruler} label="Escala" value="1:1 (mm)" /> <InfoItem icon={Ruler} label="Escala" value="1:1 (mm)" />
</div> </div>
</div> </div>
@@ -150,7 +94,8 @@ const Viewer = () => {
<ScreenshotGallery /> <ScreenshotGallery />
<div className="rounded-lg border bg-muted/50 p-3"> <div className="rounded-lg border bg-muted/50 p-3">
<p className="font-mono text-xs text-muted-foreground"> <p className="font-mono text-xs text-muted-foreground">
Use o mouse para orbitar, scroll para zoom. Controle a opacidade e o modo de renderização nos controles flutuantes. Use o mouse para orbitar, scroll para zoom. Controle a opacidade e o modo de renderização nos
controles flutuantes.
</p> </p>
</div> </div>
</div> </div>