feat: adicionar super manual didatico com fluxos 2d e sheet panel

This commit is contained in:
2026-07-09 23:40:06 +00:00
parent 9fece3f174
commit 40e73e734a
34 changed files with 1443 additions and 390 deletions
+4
View File
@@ -10,6 +10,7 @@ import { calculateCircleBarForce, reynoldsBar } from '@/lib/nbr-tables/table-27'
import Bar3DViewer from '@/components/three/Bar3D';
import SceneCapturePanel from '../components/SceneCapturePanel';
import ExportMenu from '../components/ExportMenu';
import { EducationalManual } from '@/components/EducationalManual';
import { exportGenericToPDF, type GenericPDFSection } from '../lib/export-generic-pdf';
const BarSelectorModule: React.FC = () => {
@@ -157,6 +158,9 @@ const BarSelectorModule: React.FC = () => {
<div className="absolute top-4 left-4 z-10 flex gap-2">
<Badge variant="secondary" className="bg-background/80 backdrop-blur-sm">α = {alpha}°</Badge>
</div>
<div className="absolute top-4 right-4 z-10">
<EducationalManual type="bar" params={{ barType, section, alpha }} />
</div>
<Bar3DViewer
barType={barType}
section={barType === 'flat' ? section : undefined}
+5
View File
@@ -9,6 +9,7 @@ import { classifyBridge, calculateBridgeDeckForces, flutterCheck, gallopingCheck
import Bridge3DViewer from '@/components/three/Bridge3D';
import SceneCapturePanel from '../components/SceneCapturePanel';
import ExportMenu from '../components/ExportMenu';
import { EducationalManual } from '@/components/EducationalManual';
import { exportGenericToPDF, type GenericPDFSection } from '../lib/export-generic-pdf';
const BridgeModule: React.FC = () => {
@@ -149,6 +150,9 @@ const BridgeModule: React.FC = () => {
Classe {classification.bridgeClass}
</Badge>
</div>
<div className="absolute top-4 right-4 z-10">
<EducationalManual type="bridge" params={{ alpha }} />
</div>
<Bridge3DViewer
lp={lp}
width={width}
@@ -158,6 +162,7 @@ const BridgeModule: React.FC = () => {
cz={forces.cz}
fxPerLength={forces.fxPerLength}
fzPerLength={forces.fzPerLength}
alpha={alpha}
/>
</div>
+4
View File
@@ -9,6 +9,7 @@ import { calculateCylinder, type CylinderEndType } from '@/lib/modules/cylinder'
import Cylinder3DViewer from '@/components/three/Cylinder3D';
import SceneCapturePanel from '../components/SceneCapturePanel';
import ExportMenu from '../components/ExportMenu';
import { EducationalManual } from '@/components/EducationalManual';
import { exportGenericToPDF, type GenericPDFSection } from '../lib/export-generic-pdf';
const CylinderModule: React.FC = () => {
@@ -140,6 +141,9 @@ const CylinderModule: React.FC = () => {
Re = {result.re.toExponential(2)}
</Badge>
</div>
<div className="absolute top-4 right-4 z-10">
<EducationalManual type="cylinder" params={{ roughness: surface }} />
</div>
<div className="w-full h-full bg-muted/20">
<Cylinder3DViewer
diameter={diameter}
+4
View File
@@ -9,6 +9,7 @@ import { calculateDome, type DomeType } from '@/lib/modules/dome';
import Dome3DViewer from '@/components/three/Dome3D';
import SceneCapturePanel from '../components/SceneCapturePanel';
import ExportMenu from '../components/ExportMenu';
import { EducationalManual } from '@/components/EducationalManual';
import { exportGenericToPDF, type GenericPDFSection } from '../lib/export-generic-pdf';
const DomeModule: React.FC = () => {
@@ -118,6 +119,9 @@ const DomeModule: React.FC = () => {
Cpi = {cpi.toFixed(2)}
</Badge>
</div>
<div className="absolute top-4 right-4 z-10">
<EducationalManual type="dome" params={{ rise, diameter }} />
</div>
<div className="w-full h-full bg-muted/20">
<Dome3DViewer
diameter={diameter}
+3 -1
View File
@@ -27,6 +27,7 @@ import { TABLE_32 } from '@/lib/nbr-tables/table-32';
import Dynamics3DViewer from '@/components/three/Dynamics3D';
import SceneCapturePanel from '../components/SceneCapturePanel';
import ExportMenu from '../components/ExportMenu';
import { EducationalManual } from '@/components/EducationalManual';
import { exportGenericToPDF, type GenericPDFSection } from '../lib/export-generic-pdf';
const DynamicsModule: React.FC = () => {
@@ -256,8 +257,9 @@ const DynamicsModule: React.FC = () => {
</div>
)}
<Card className="flex-1 min-h-[400px]">
<CardHeader className="pb-3">
<CardHeader className="pb-3 flex flex-row items-center justify-between">
<CardTitle className="text-base">Visualização 3D</CardTitle>
<EducationalManual type="dynamics" params={{ fn: freq }} />
</CardHeader>
<CardContent className="h-full">
<Dynamics3DViewer
+3 -1
View File
@@ -11,6 +11,7 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@
import { Badge } from '@/components/ui/badge';
import { Separator } from '@/components/ui/separator';
import ExportMenu from '../components/ExportMenu';
import { EducationalManual } from '@/components/EducationalManual';
const GalpaoModule: React.FC = () => {
const {
@@ -103,8 +104,9 @@ const GalpaoModule: React.FC = () => {
</Badge>
</div>
<div className="absolute top-4 right-4 z-10">
<div className="absolute top-4 right-4 z-10 flex gap-2">
<ExportMenu />
<EducationalManual type="warehouse" params={{ windAngle, cpi }} />
</div>
<div className="absolute bottom-4 left-4 z-10 flex gap-3 p-3 bg-background/90 backdrop-blur-md border border-border rounded-lg shadow-sm">
+5
View File
@@ -9,6 +9,7 @@ import { calculateIsolatedShedRoof, calculateIsolatedGableRoof, frictionForceIso
import IsolatedRoof3DViewer from '@/components/three/IsolatedRoof3D';
import SceneCapturePanel from '../components/SceneCapturePanel';
import ExportMenu from '../components/ExportMenu';
import { EducationalManual } from '@/components/EducationalManual';
import { exportGenericToPDF, type GenericPDFSection } from '../lib/export-generic-pdf';
const IsolatedRoofModule: React.FC = () => {
@@ -164,10 +165,14 @@ const IsolatedRoofModule: React.FC = () => {
<Badge variant="secondary" className="bg-background/80 backdrop-blur-sm">θ = {theta}°</Badge>
<Badge variant="secondary" className="bg-background/80 backdrop-blur-sm">{type === 'shed' ? 'Uma água' : 'Duas águas'}</Badge>
</div>
<div className="absolute top-4 right-4 z-10">
<EducationalManual type="isolated-roof" params={{ theta, type }} />
</div>
<IsolatedRoof3DViewer
type={type}
theta={theta}
height={height}
width={width}
depth={depth}
cpeWindward={cpeWindward}
cpeLeeward={cpeLeeward}
+4
View File
@@ -9,6 +9,7 @@ import { calculateSign } from '@/lib/nbr-tables/table-23';
import Sign3DViewer from '@/components/three/Sign3D';
import SceneCapturePanel from '../components/SceneCapturePanel';
import ExportMenu from '../components/ExportMenu';
import { EducationalManual } from '@/components/EducationalManual';
import { exportGenericToPDF, type GenericPDFSection } from '../lib/export-generic-pdf';
const SignModule: React.FC = () => {
@@ -118,6 +119,9 @@ const SignModule: React.FC = () => {
<Badge variant="secondary" className="bg-background/80 backdrop-blur-sm">F = {result.forceKN.toFixed(2)} kN</Badge>
<Badge variant="outline" className="bg-background/80 backdrop-blur-sm">Cf = {result.cf.toFixed(2)}</Badge>
</div>
<div className="absolute top-4 right-4 z-10">
<EducationalManual type="sign" params={{ length, height, alpha, hasEndPlates }} />
</div>
<Sign3DViewer
length={length}
+4
View File
@@ -8,6 +8,7 @@ import { calculateTower, type TowerSection, type TowerBarType } from '@/lib/modu
import Tower3DViewer from '@/components/three/Tower3D';
import SceneCapturePanel from '../components/SceneCapturePanel';
import ExportMenu from '../components/ExportMenu';
import { EducationalManual } from '@/components/EducationalManual';
import { exportGenericToPDF, type GenericPDFSection } from '../lib/export-generic-pdf';
const TowerModule: React.FC = () => {
@@ -141,6 +142,9 @@ const TowerModule: React.FC = () => {
<Badge variant="secondary" className="bg-background/80 backdrop-blur-sm">{section === 'square' ? 'Quadrada' : 'Triangular'}</Badge>
<Badge variant="secondary" className="bg-background/80 backdrop-blur-sm">α = {alphaWind}°</Badge>
</div>
<div className="absolute top-4 right-4 z-10">
<EducationalManual type="tower" params={{ section, alphaWind }} />
</div>
<Tower3DViewer
section={section}
barType={barType}
+4
View File
@@ -9,6 +9,7 @@ import { calculateVault, type VaultRegime } from '@/lib/modules/vault';
import Vault3DViewer from '@/components/three/Vault3D';
import SceneCapturePanel from '../components/SceneCapturePanel';
import ExportMenu from '../components/ExportMenu';
import { EducationalManual } from '@/components/EducationalManual';
import { exportGenericToPDF, type GenericPDFSection } from '../lib/export-generic-pdf';
const VaultModule: React.FC = () => {
@@ -126,6 +127,9 @@ const VaultModule: React.FC = () => {
Cpi = {localCpi > 0 ? `+${localCpi.toFixed(2)}` : localCpi.toFixed(2)}
</Badge>
</div>
<div className="absolute top-4 right-4 z-10">
<EducationalManual type="vault" params={{ rise, span }} />
</div>
<div className="w-full h-full bg-muted/20">
<Vault3DViewer span={span} length={length} rise={rise} cpi={localCpi} cpeProfile={{ ...result.windPerpendicular }} />
</div>