Harden import and paste validation, fix duplicate exports and variable declarations
This commit is contained in:
@@ -5,6 +5,8 @@ import { bomToText, downloadBomCsv } from './csv';
|
||||
import { downloadBomPdf } from './pdf';
|
||||
import type { BomLine, CutList } from './types';
|
||||
import { exportToGLTF, exportToOBJ } from '../utils/cadExporter';
|
||||
import { useAuth } from '../auth/AuthContext';
|
||||
import { PaywallModal } from '../payments/PaywallModal';
|
||||
|
||||
/**
|
||||
* BomPanel — self-contained Bill of Materials drawer.
|
||||
@@ -18,11 +20,21 @@ import { exportToGLTF, exportToOBJ } from '../utils/cadExporter';
|
||||
* {bomOpen && <BomPanel onClose={() => setBomOpen(false)} />}
|
||||
*/
|
||||
export function BomPanel({ onClose }: { onClose: () => void }) {
|
||||
const { user } = useAuth();
|
||||
const [showPaywall, setShowPaywall] = useState(false);
|
||||
const parts = useBuilder((s) => s.parts);
|
||||
const activeRoomId = useBuilder((s) => s.activeRoomId);
|
||||
const projectName = useBuilder((s) => s.projectName);
|
||||
const scene = useBuilder((s) => s.scene);
|
||||
|
||||
const requirePremium = (action: () => void) => {
|
||||
if (!user || user.purchased_slots === 0) {
|
||||
setShowPaywall(true);
|
||||
} else {
|
||||
action();
|
||||
}
|
||||
};
|
||||
|
||||
const roomParts = useMemo(() => {
|
||||
return Object.values(parts).filter((p) => p.roomId === activeRoomId);
|
||||
}, [parts, activeRoomId]);
|
||||
@@ -126,11 +138,11 @@ export function BomPanel({ onClose }: { onClose: () => void }) {
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-1.5 justify-end">
|
||||
<ActionBtn onClick={() => downloadBomCsv(bom, projectName)} title="Download as CSV">
|
||||
Export CSV
|
||||
<ActionBtn onClick={() => requirePremium(() => downloadBomCsv(bom, projectName))} title="Download as CSV">
|
||||
Export CSV 🔒
|
||||
</ActionBtn>
|
||||
<ActionBtn onClick={() => downloadBomPdf(bom, projectName)} title="Download as PDF">
|
||||
Export PDF
|
||||
<ActionBtn onClick={() => requirePremium(() => downloadBomPdf(bom, projectName))} title="Download as PDF">
|
||||
Export PDF 🔒
|
||||
</ActionBtn>
|
||||
<ActionBtn onClick={handleCopy} title="Copy shopping list to clipboard">
|
||||
{copied ? 'Copied' : 'Copy as text'}
|
||||
@@ -139,18 +151,18 @@ export function BomPanel({ onClose }: { onClose: () => void }) {
|
||||
Print
|
||||
</ActionBtn>
|
||||
<ActionBtn
|
||||
onClick={() => scene && exportToGLTF(scene, `${projectName}.gltf`)}
|
||||
onClick={() => scene && requirePremium(() => exportToGLTF(scene, `${projectName}.gltf`))}
|
||||
title={scene ? "Export 3D layout as glTF" : "Scene loading..."}
|
||||
disabled={!scene}
|
||||
>
|
||||
Export glTF
|
||||
Export glTF 🔒
|
||||
</ActionBtn>
|
||||
<ActionBtn
|
||||
onClick={() => scene && exportToOBJ(scene, `${projectName}.obj`)}
|
||||
onClick={() => scene && requirePremium(() => exportToOBJ(scene, `${projectName}.obj`))}
|
||||
title={scene ? "Export 3D layout as OBJ" : "Scene loading..."}
|
||||
disabled={!scene}
|
||||
>
|
||||
Export OBJ
|
||||
Export OBJ 🔒
|
||||
</ActionBtn>
|
||||
</div>
|
||||
</div>
|
||||
@@ -242,6 +254,7 @@ export function BomPanel({ onClose }: { onClose: () => void }) {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{showPaywall && <PaywallModal onClose={() => setShowPaywall(false)} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user