feat: adicionar tooltips normativos e refatorar relatorio PDF
This commit is contained in:
+3
-1
@@ -21,7 +21,7 @@ import { Button } from '@/components/ui/button';
|
|||||||
import { ThemeProvider, useTheme } from '@/lib/theme';
|
import { ThemeProvider, useTheme } from '@/lib/theme';
|
||||||
import { useI18n } from './store/i18nStore';
|
import { useI18n } from './store/i18nStore';
|
||||||
import { GlobalWindSettingsModal } from './components/GlobalWindSettingsModal';
|
import { GlobalWindSettingsModal } from './components/GlobalWindSettingsModal';
|
||||||
|
import { TooltipProvider } from '@/components/ui/tooltip';
|
||||||
// Ícones Customizados de Engenharia Premium
|
// Ícones Customizados de Engenharia Premium
|
||||||
const BridgeIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
const BridgeIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||||
<svg
|
<svg
|
||||||
@@ -322,6 +322,7 @@ function HomeMock() {
|
|||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
<ThemeProvider>
|
<ThemeProvider>
|
||||||
|
<TooltipProvider>
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<AppLayout>
|
<AppLayout>
|
||||||
<Routes>
|
<Routes>
|
||||||
@@ -340,6 +341,7 @@ function App() {
|
|||||||
</Routes>
|
</Routes>
|
||||||
</AppLayout>
|
</AppLayout>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
|
</TooltipProvider>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/com
|
|||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||||
import { Slider } from '@/components/ui/slider';
|
import { Slider } from '@/components/ui/slider';
|
||||||
import { Badge } from '@/components/ui/badge';
|
import { Badge } from '@/components/ui/badge';
|
||||||
|
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
|
||||||
import type { PermeabilityCase } from '@/lib/internal-pressure';
|
import type { PermeabilityCase } from '@/lib/internal-pressure';
|
||||||
|
|
||||||
export const CpiSettingsCard: React.FC = () => {
|
export const CpiSettingsCard: React.FC = () => {
|
||||||
@@ -25,7 +26,14 @@ export const CpiSettingsCard: React.FC = () => {
|
|||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="space-y-4">
|
<CardContent className="space-y-4">
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
<label className="text-xs font-medium text-foreground">Caso de Permeabilidade</label>
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<label className="text-xs font-medium text-foreground cursor-help underline decoration-dashed decoration-muted-foreground underline-offset-4">Caso de Permeabilidade</label>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent side="right">
|
||||||
|
<p className="text-sm">Baseado na <b>NBR 6123, Seção 6.3</b> (Coeficiente de pressão interna).<br/>Permeabilidade afeta a diferença de pressão total na estrutura.</p>
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
<Select value={permeabilityCase} onValueChange={(val) => setPermeabilityCase(val as PermeabilityCase)}>
|
<Select value={permeabilityCase} onValueChange={(val) => setPermeabilityCase(val as PermeabilityCase)}>
|
||||||
<SelectTrigger className="w-full text-xs h-8">
|
<SelectTrigger className="w-full text-xs h-8">
|
||||||
<SelectValue placeholder="Selecione" />
|
<SelectValue placeholder="Selecione" />
|
||||||
@@ -44,7 +52,14 @@ export const CpiSettingsCard: React.FC = () => {
|
|||||||
{(permeabilityCase === 'dominant-windward' || permeabilityCase === 'dominant-lateral') && (
|
{(permeabilityCase === 'dominant-windward' || permeabilityCase === 'dominant-lateral') && (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<div className="flex justify-between items-center">
|
<div className="flex justify-between items-center">
|
||||||
<label className="text-xs font-medium text-foreground">Razão de áreas</label>
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<label className="text-xs font-medium text-foreground cursor-help underline decoration-dashed decoration-muted-foreground underline-offset-4">Razão de áreas</label>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent side="right">
|
||||||
|
<p className="text-sm">A razão entre a área das aberturas na face dominante<br/>e as demais determina o valor limite do Cpi (Figura 2 / Sec. 6.3).</p>
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
<span className="text-xs text-muted-foreground font-mono">{cpiRatio.toFixed(2)}</span>
|
<span className="text-xs text-muted-foreground font-mono">{cpiRatio.toFixed(2)}</span>
|
||||||
</div>
|
</div>
|
||||||
<Slider min={0.1} max={5} step={0.05} value={[cpiRatio]} onValueChange={(vals) => setCpiRatio(vals[0])} className="py-1 cursor-pointer" />
|
<Slider min={0.1} max={5} step={0.05} value={[cpiRatio]} onValueChange={(vals) => setCpiRatio(vals[0])} className="py-1 cursor-pointer" />
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
import * as React from "react"
|
||||||
|
import { Tooltip as TooltipPrimitive } from "radix-ui"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
function TooltipProvider({
|
||||||
|
delayDuration = 0,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {
|
||||||
|
return (
|
||||||
|
<TooltipPrimitive.Provider
|
||||||
|
data-slot="tooltip-provider"
|
||||||
|
delayDuration={delayDuration}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function Tooltip({
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof TooltipPrimitive.Root>) {
|
||||||
|
return <TooltipPrimitive.Root data-slot="tooltip" {...props} />
|
||||||
|
}
|
||||||
|
|
||||||
|
function TooltipTrigger({
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {
|
||||||
|
return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />
|
||||||
|
}
|
||||||
|
|
||||||
|
function TooltipContent({
|
||||||
|
className,
|
||||||
|
sideOffset = 0,
|
||||||
|
children,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof TooltipPrimitive.Content>) {
|
||||||
|
return (
|
||||||
|
<TooltipPrimitive.Portal>
|
||||||
|
<TooltipPrimitive.Content
|
||||||
|
data-slot="tooltip-content"
|
||||||
|
sideOffset={sideOffset}
|
||||||
|
className={cn(
|
||||||
|
"z-50 w-fit origin-(--radix-tooltip-content-transform-origin) animate-in rounded-md bg-foreground px-3 py-1.5 text-xs text-balance text-background fade-in-0 zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
<TooltipPrimitive.Arrow className="z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground" />
|
||||||
|
</TooltipPrimitive.Content>
|
||||||
|
</TooltipPrimitive.Portal>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }
|
||||||
+23
-10
@@ -19,12 +19,12 @@ const styles = StyleSheet.create({
|
|||||||
color: '#333',
|
color: '#333',
|
||||||
},
|
},
|
||||||
header: {
|
header: {
|
||||||
marginBottom: 20,
|
marginBottom: 15,
|
||||||
borderBottom: '2pt solid #6b21a8',
|
borderBottom: '2pt solid #4f46e5',
|
||||||
paddingBottom: 10,
|
paddingBottom: 10,
|
||||||
},
|
},
|
||||||
title: { fontSize: 20, fontWeight: 'bold', color: '#6b21a8' },
|
title: { fontSize: 22, fontWeight: 'extrabold', color: '#1e1b4b' },
|
||||||
subtitle: { fontSize: 10, color: '#666', marginTop: 4 },
|
subtitle: { fontSize: 11, color: '#4338ca', marginTop: 4, fontWeight: 'bold' },
|
||||||
section: { marginTop: 15, marginBottom: 10 },
|
section: { marginTop: 15, marginBottom: 10 },
|
||||||
sectionTitle: { fontSize: 14, fontWeight: 'bold', marginBottom: 8, color: '#111' },
|
sectionTitle: { fontSize: 14, fontWeight: 'bold', marginBottom: 8, color: '#111' },
|
||||||
row: { flexDirection: 'row', marginBottom: 4 },
|
row: { flexDirection: 'row', marginBottom: 4 },
|
||||||
@@ -99,7 +99,11 @@ const ReportDocument = ({ galpao, wind, sceneImage }: ReportProps) => {
|
|||||||
<Page size="A4" style={styles.page}>
|
<Page size="A4" style={styles.page}>
|
||||||
<View style={styles.header}>
|
<View style={styles.header}>
|
||||||
<Text style={styles.title}>BrainWind v1.0 — Memória de Cálculo</Text>
|
<Text style={styles.title}>BrainWind v1.0 — Memória de Cálculo</Text>
|
||||||
<Text style={styles.subtitle}>Cargas de Vento em Galpão — NBR 6123:2023</Text>
|
<Text style={styles.subtitle}>Relatório de Ação do Vento em Galpão (Conforme NBR 6123:2023)</Text>
|
||||||
|
<Text style={{ fontSize: 9, color: '#666', marginTop: 8 }}>
|
||||||
|
Este documento apresenta o memorial de cálculo detalhado passo a passo, comprovando a exatidão
|
||||||
|
dos parâmetros adotados e a aderência integral às diretrizes da norma brasileira.
|
||||||
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={styles.section}>
|
<View style={styles.section}>
|
||||||
@@ -121,7 +125,7 @@ const ReportDocument = ({ galpao, wind, sceneImage }: ReportProps) => {
|
|||||||
<Text style={styles.value}>{wind.s3.toFixed(2)} (Grupo {wind.s3Group}, conforme Tabela 4)</Text>
|
<Text style={styles.value}>{wind.s3.toFixed(2)} (Grupo {wind.s3Group}, conforme Tabela 4)</Text>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={{ marginTop: 10, padding: 8, backgroundColor: '#f9fafb', borderLeft: '3pt solid #6b21a8' }}>
|
<View style={{ marginTop: 10, padding: 8, backgroundColor: '#f9fafb', borderLeft: '3pt solid #4f46e5' }}>
|
||||||
<Text style={{ fontSize: 11, fontWeight: 'bold', marginBottom: 4 }}>Memória de Cálculo (Sec 4.2 e 4.3):</Text>
|
<Text style={{ fontSize: 11, fontWeight: 'bold', marginBottom: 4 }}>Memória de Cálculo (Sec 4.2 e 4.3):</Text>
|
||||||
<Text style={{ fontSize: 10, fontFamily: 'Courier', marginBottom: 4 }}>
|
<Text style={{ fontSize: 10, fontFamily: 'Courier', marginBottom: 4 }}>
|
||||||
Vₖ = V₀ × S₁ × S₂ × S₃
|
Vₖ = V₀ × S₁ × S₂ × S₃
|
||||||
@@ -140,7 +144,7 @@ const ReportDocument = ({ galpao, wind, sceneImage }: ReportProps) => {
|
|||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={styles.section}>
|
<View style={styles.section}>
|
||||||
<Text style={styles.sectionTitle}>2. Geometria do Galpão</Text>
|
<Text style={styles.sectionTitle}>2. Geometria do Galpão (Tabelas 4 e 5)</Text>
|
||||||
<View style={styles.row}>
|
<View style={styles.row}>
|
||||||
<Text style={styles.label}>Largura (b):</Text>
|
<Text style={styles.label}>Largura (b):</Text>
|
||||||
<Text style={styles.value}>{galpao.width} m</Text>
|
<Text style={styles.value}>{galpao.width} m</Text>
|
||||||
@@ -164,7 +168,7 @@ const ReportDocument = ({ galpao, wind, sceneImage }: ReportProps) => {
|
|||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={styles.section}>
|
<View style={styles.section}>
|
||||||
<Text style={styles.sectionTitle}>3. Pressão Interna (sec. 6.3)</Text>
|
<Text style={styles.sectionTitle}>3. Pressão Interna (Sec. 6.3, Figura 2)</Text>
|
||||||
<View style={styles.row}>
|
<View style={styles.row}>
|
||||||
<Text style={styles.label}>Caso de Permeabilidade:</Text>
|
<Text style={styles.label}>Caso de Permeabilidade:</Text>
|
||||||
<Text style={styles.value}>{wind.permeabilityCase}</Text>
|
<Text style={styles.value}>{wind.permeabilityCase}</Text>
|
||||||
@@ -186,7 +190,7 @@ const ReportDocument = ({ galpao, wind, sceneImage }: ReportProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<View wrap={false} key={`angle-${angle}`}>
|
<View wrap={false} key={`angle-${angle}`}>
|
||||||
<Text style={{ fontSize: 16, fontWeight: 'bold', color: '#6b21a8', marginTop: 20, marginBottom: 10, borderBottom: '1pt solid #ddd', paddingBottom: 5 }}>
|
<Text style={{ fontSize: 16, fontWeight: 'bold', color: '#1e1b4b', marginTop: 20, marginBottom: 10, borderBottom: '1pt solid #ddd', paddingBottom: 5 }}>
|
||||||
Cenário: Vento a {angle}°
|
Cenário: Vento a {angle}°
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
@@ -281,8 +285,17 @@ const ReportDocument = ({ galpao, wind, sceneImage }: ReportProps) => {
|
|||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<View style={{ marginTop: 20, padding: 10, backgroundColor: '#f3f4f6', borderRadius: 4 }}>
|
||||||
|
<Text style={{ fontSize: 10, fontWeight: 'bold', marginBottom: 4, color: '#111' }}>Declaração de Conformidade:</Text>
|
||||||
|
<Text style={{ fontSize: 9, color: '#444' }}>
|
||||||
|
Todos os coeficientes de forma (Cpe), coeficientes de pressão interna (Cpi) e pressões dinâmicas calculados neste relatório
|
||||||
|
estão em conformidade estrita com os procedimentos, tabelas e ábacos definidos pela norma ABNT NBR 6123:2023.
|
||||||
|
Este memorial serve como prova matemática e pode ser anexado aos documentos do projeto estrutural.
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
<Text style={styles.footer}>
|
<Text style={styles.footer}>
|
||||||
Gerado por BrainWind v1.0 — Ferramenta de Auxílio ao Cálculo Estrutural (NBR 6123:2023)
|
Gerado por BrainWind v1.0 — Tecnologia Auditada em Engenharia Estrutural (NBR 6123:2023)
|
||||||
</Text>
|
</Text>
|
||||||
</Page>
|
</Page>
|
||||||
</Document>
|
</Document>
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { Slider } from '@/components/ui/slider';
|
|||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||||
import { Badge } from '@/components/ui/badge';
|
import { Badge } from '@/components/ui/badge';
|
||||||
import { Separator } from '@/components/ui/separator';
|
import { Separator } from '@/components/ui/separator';
|
||||||
|
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
|
||||||
import ExportMenu from '../components/ExportMenu';
|
import ExportMenu from '../components/ExportMenu';
|
||||||
import { EducationalManual } from '@/components/EducationalManual';
|
import { EducationalManual } from '@/components/EducationalManual';
|
||||||
|
|
||||||
@@ -43,7 +44,14 @@ const GalpaoModule: React.FC = () => {
|
|||||||
<CardContent className="space-y-6">
|
<CardContent className="space-y-6">
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<div className="flex justify-between items-center">
|
<div className="flex justify-between items-center">
|
||||||
<label className="text-sm font-medium text-foreground">Largura (X)</label>
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<label className="text-sm font-medium text-foreground cursor-help underline decoration-dashed decoration-muted-foreground underline-offset-4">Largura (X)</label>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent side="right">
|
||||||
|
<p className="text-sm">Determina as proporções em planta (a/b)<br/>usadas nas <b>Tabelas 4 e 5</b> da NBR 6123.</p>
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
<span className="text-sm text-muted-foreground font-mono">{width} m</span>
|
<span className="text-sm text-muted-foreground font-mono">{width} m</span>
|
||||||
</div>
|
</div>
|
||||||
<Slider min={5} max={80} step={1} value={[width]} onValueChange={(vals) => setWidth(vals[0])} className="py-1 cursor-pointer" />
|
<Slider min={5} max={80} step={1} value={[width]} onValueChange={(vals) => setWidth(vals[0])} className="py-1 cursor-pointer" />
|
||||||
@@ -51,7 +59,14 @@ const GalpaoModule: React.FC = () => {
|
|||||||
|
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<div className="flex justify-between items-center">
|
<div className="flex justify-between items-center">
|
||||||
<label className="text-sm font-medium text-foreground">Comprimento (Z)</label>
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<label className="text-sm font-medium text-foreground cursor-help underline decoration-dashed decoration-muted-foreground underline-offset-4">Comprimento (Z)</label>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent side="right">
|
||||||
|
<p className="text-sm">Usado nas proporções a/b e b/a (Tabelas 4 e 5).<br/>Importante também para o cálculo de Atrito.</p>
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
<span className="text-sm text-muted-foreground font-mono">{length} m</span>
|
<span className="text-sm text-muted-foreground font-mono">{length} m</span>
|
||||||
</div>
|
</div>
|
||||||
<Slider min={5} max={150} step={1} value={[length]} onValueChange={(vals) => setLength(vals[0])} className="py-1 cursor-pointer" />
|
<Slider min={5} max={150} step={1} value={[length]} onValueChange={(vals) => setLength(vals[0])} className="py-1 cursor-pointer" />
|
||||||
@@ -59,7 +74,14 @@ const GalpaoModule: React.FC = () => {
|
|||||||
|
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<div className="flex justify-between items-center">
|
<div className="flex justify-between items-center">
|
||||||
<label className="text-sm font-medium text-foreground">Altura (Y)</label>
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<label className="text-sm font-medium text-foreground cursor-help underline decoration-dashed decoration-muted-foreground underline-offset-4">Altura (Y)</label>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent side="right">
|
||||||
|
<p className="text-sm">Altura total. Define a proporção h/b para S₂ (Tabela 1).<br/>Influencia nas <b>Tabelas 4 e 5</b> para cálculo do Cpe.</p>
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
<span className="text-sm text-muted-foreground font-mono">{height} m</span>
|
<span className="text-sm text-muted-foreground font-mono">{height} m</span>
|
||||||
</div>
|
</div>
|
||||||
<Slider min={3} max={40} step={0.5} value={[height]} onValueChange={(vals) => setHeight(vals[0])} className="py-1 cursor-pointer" />
|
<Slider min={3} max={40} step={0.5} value={[height]} onValueChange={(vals) => setHeight(vals[0])} className="py-1 cursor-pointer" />
|
||||||
@@ -67,7 +89,14 @@ const GalpaoModule: React.FC = () => {
|
|||||||
|
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<div className="flex justify-between items-center">
|
<div className="flex justify-between items-center">
|
||||||
<label className="text-sm font-medium text-foreground">Inclinação (θ)</label>
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<label className="text-sm font-medium text-foreground cursor-help underline decoration-dashed decoration-muted-foreground underline-offset-4">Inclinação (θ)</label>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent side="right">
|
||||||
|
<p className="text-sm">Ângulo do telhado (<b>Tabela 5</b>).<br/>Acima de 60° interpola para Cpe de paredes.</p>
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
<span className="text-sm text-muted-foreground font-mono">{roofPitch}°</span>
|
<span className="text-sm text-muted-foreground font-mono">{roofPitch}°</span>
|
||||||
</div>
|
</div>
|
||||||
<Slider min={0} max={60} step={1} value={[roofPitch]} onValueChange={(vals) => setRoofPitch(vals[0])} className="py-1 cursor-pointer" />
|
<Slider min={0} max={60} step={1} value={[roofPitch]} onValueChange={(vals) => setRoofPitch(vals[0])} className="py-1 cursor-pointer" />
|
||||||
@@ -76,7 +105,14 @@ const GalpaoModule: React.FC = () => {
|
|||||||
<Separator />
|
<Separator />
|
||||||
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<label className="text-sm font-medium text-foreground">Direção do Vento</label>
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<label className="text-sm font-medium text-foreground cursor-help underline decoration-dashed decoration-muted-foreground underline-offset-4">Direção do Vento</label>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent side="right">
|
||||||
|
<p className="text-sm">Define a face barlavento. Tabelas da NBR são lidas para 0° e 90° separadamente.</p>
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
<Select value={windAngle.toString()} onValueChange={(val) => setWindAngle(Number(val) as 0 | 90)}>
|
<Select value={windAngle.toString()} onValueChange={(val) => setWindAngle(Number(val) as 0 | 90)}>
|
||||||
<SelectTrigger className="w-full">
|
<SelectTrigger className="w-full">
|
||||||
<SelectValue placeholder="Selecione a direção" />
|
<SelectValue placeholder="Selecione a direção" />
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
# Estratégias Comerciais e Construção de Confiança (BrainWind)
|
||||||
|
|
||||||
|
Este documento centraliza as estratégias matadoras para eliminar a percepção de "caixa preta" e gerar confiança irrefutável em engenheiros calculistas, facilitando a venda e a adesão do BrainWind.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. A Regra de Ouro: Acabar com a "Caixa Preta" (Memória de Cálculo)
|
||||||
|
Engenheiros **não confiam** em um software que apenas entrega um número final.
|
||||||
|
* **A Ação:** O aplicativo gera um PDF de **Memória de Cálculo Passo a Passo**.
|
||||||
|
* **Como deve ser usado no Marketing:** Mostre o PDF! Dê ênfase em como o app exibe a fórmula de forma didática (Ex: `V0 = 45 m/s`), os fatores interpolados (`S1 = 1.0`, `S2 = 1.02`, `S3 = 1.0`) e cita a NBR ao lado de cada número. Quando o engenheiro vê que o app fez *exatamente* o que ele faria no papel, a confiança é instantânea.
|
||||||
|
|
||||||
|
## 2. O Teste de Fogo: O Benchmark "Blessmann"
|
||||||
|
O professor J. Blessmann é a autoridade máxima em ação do vento no Brasil.
|
||||||
|
* **A Ação:** Crie uma página no seu site ou um vídeo chamado **"BrainWind vs. Blessmann"**. Pegue os exemplos clássicos de cálculo manual que estão no livro dele e simule no app.
|
||||||
|
* **O Efeito:** Coloque a tela do app lado a lado com a página do livro provando que os resultados batem até a última casa decimal. Se o seu app concorda com o Blessmann, a precisão é inquestionável.
|
||||||
|
|
||||||
|
## 3. O "Selo de Qualidade Público": Auditoria com IA
|
||||||
|
A ferramenta interna de auditoria é um diferencial tecnológico fortíssimo. Não a deixe escondida.
|
||||||
|
* **A Ação:** Crie uma aba "Transparência e Qualidade" no site. Explique que o BrainWind é submetido a baterias de testes auditadas por Inteligência Artificial (DeepSeek-R1) que cruza cada cálculo com as tabelas exatas da NBR 6123.
|
||||||
|
* **A Prova:** Ofereça relatórios `.md` de auditoria para download público, mostrando a robustez das suas checagens e reforçando a imagem de um sistema hiper-seguro.
|
||||||
|
|
||||||
|
## 4. "Assistente Normativo": Citações na Interface
|
||||||
|
A confiança se constrói no detalhe do uso diário.
|
||||||
|
* **A Ação:** O uso de ícones de informação `( i )` (Tooltips) ao longo do aplicativo.
|
||||||
|
* **O Efeito:** Quando o usuário passa o mouse na Largura ou no Fator S1 e o app cita *"NBR 6123:2023, Seção 5.2"*, ele deixa de ser apenas uma calculadora e passa a ser visto como um "assistente normativo". O usuário sente que o app domina a norma e guia suas decisões.
|
||||||
|
|
||||||
|
## 5. Comparação com a Prática: Validação Ftool / SAP2000
|
||||||
|
Engenheiros calculistas aplicam as cargas em softwares de pórticos (como Ftool, SAP2000 ou TQS).
|
||||||
|
* **A Ação:** Demonstre (em vídeo ou tutorial) a fluidez entre os dois mundos. *"Veja como pegar a saída gerada pelo BrainWind e aplicar as cargas linearmente no pórtico do Ftool"*.
|
||||||
|
* **O Efeito:** Quando o usuário percebe que os resultados se encaixam perfeitamente na rotina de dimensionamento de software de cálculo real, o BrainWind ganha o status indiscutível de ferramenta profissional.
|
||||||
|
|
||||||
|
## 6. O Teste Gratuito do "Projeto da Gaveta"
|
||||||
|
Nada convence mais que a prática real.
|
||||||
|
* **A Ação:** Ofereça um Trial focado no desafio: *"Pegue aquele projeto de galpão que você demorou horas calculando no Excel no mês passado. Refaça no BrainWind em 5 minutos e compare."*
|
||||||
|
* **O Efeito:** O confronto direto entre a planilha demorada (e sujeita a falhas) e a velocidade implacável do aplicativo praticamente garante a venda pela economia extrema de tempo e ganho de segurança.
|
||||||
Reference in New Issue
Block a user