🚀 Auto-deploy: BrainWind atualizado em 26/08/2026 10:57:31

This commit is contained in:
2026-08-26 10:57:31 +00:00
parent ddcb56d78b
commit b842d6009f
7 changed files with 204 additions and 9 deletions
+21 -2
View File
@@ -19,7 +19,7 @@ import { EducationalManual } from '@/components/EducationalManual';
import { WindParametersSummary } from '@/components/WindParametersSummary';
import { SaveModuleDialog } from '@/components/SaveModuleDialog';
import { exportGenericToPDF, type GenericPDFSection } from '../lib/export-generic-pdf';
import { Eye, Box, Layers, ArrowUpRight, CheckCircle2, Wind } from 'lucide-react';
import { Eye, Box, Layers, ArrowUpRight, CheckCircle2, Wind, AlertTriangle } from 'lucide-react';
import { cn } from '@/lib/utils';
const conditionLabels: Record<ShelterCondition, string> = {
@@ -41,6 +41,7 @@ const ShelterModule: React.FC = () => {
const [backRange, setBackRange] = useState<[number, number]>([0, 75]);
const [leftClosure, setLeftClosure] = useState(100);
const [rightClosure, setRightClosure] = useState(100);
const [surfaceMass, setSurfaceMass] = useState(15); // kg/m² para lona/telha leve
const [viewMode, setViewMode] = useState<'3d' | 'elevation' | 'airflow'>('3d');
// Determinação automática da posição da fresta/vão a partir dos cursores (base e topo)
@@ -100,6 +101,9 @@ const ShelterModule: React.FC = () => {
const effAreaRoof = depth * width;
const effAreaBack = (width * height) * (backClosure / 100);
const effAreaSideTotal = (depth * height) * ((leftClosure + rightClosure) / 100);
const gravityForce = (surfaceMass * effAreaRoof * 9.81) / 1000; // in kN
const isUpliftCritical = envelope.criticalUp.value > gravityForce;
const handleExportPDF = () => {
const angleLabel = windAngle === 0 ? '0° (Frontal)' : windAngle === 45 ? '45° (Oblíquo)' : '90° (Lateral)';
@@ -351,7 +355,7 @@ const ShelterModule: React.FC = () => {
</div>
<SaveModuleDialog
moduleType="shelter"
inputs={{ condition, depth, width, height, theta, backClosure, leftClosure, rightClosure, openingPos, windAngle }}
inputs={{ condition, depth, width, height, theta, backClosure, leftClosure, rightClosure, openingPos, windAngle, surfaceMass }}
/>
</CardHeader>
<CardContent className="space-y-5">
@@ -476,6 +480,21 @@ const ShelterModule: React.FC = () => {
</div>
<Slider min={0} max={30} step={1} value={[theta]} onValueChange={(v) => setTheta(v[0])} />
</div>
<div className="space-y-2 pt-2 border-t">
<div className="flex justify-between text-xs">
<span>Massa Superficial (kg/m²):</span>
<span className="font-mono font-medium">{surfaceMass} kg/m²</span>
</div>
<Slider min={2} max={100} step={1} value={[surfaceMass]} onValueChange={(v) => setSurfaceMass(v[0])} />
<p className="text-[10px] text-muted-foreground mt-1">Lonas ~3kg/m², Telhas Metálicas ~10-15kg/m²</p>
{isUpliftCritical && (
<div className="mt-2 p-2 bg-destructive/10 border border-destructive/20 rounded text-xs text-destructive flex gap-2 items-start">
<AlertTriangle className="w-4 h-4 shrink-0 mt-0.5" />
<p>Alerta de Arrancamento: Força () {envelope.criticalUp.value.toFixed(1)} kN &gt; Peso ({gravityForce.toFixed(1)} kN). Exige ancoragem/estaiamento.</p>
</div>
)}
</div>
</div>
</CardContent>
</Card>