From 892409cee3e6e00deed65d76337c512010af9abe Mon Sep 17 00:00:00 2001 From: Marcos Date: Fri, 10 Jul 2026 14:43:01 +0000 Subject: [PATCH] fix: implement option A for Cpi, adjust LLM config fields stack layout on mobile, update main icons, and fix tests --- app/src/App.tsx | 58 ++++++++++++++++--- .../components/GlobalWindSettingsModal.tsx | 47 --------------- app/src/lib/__tests__/i18n.test.ts | 4 +- app/src/pages/CylinderModule.tsx | 2 + app/src/pages/DomeModule.tsx | 2 + 5 files changed, 56 insertions(+), 57 deletions(-) diff --git a/app/src/App.tsx b/app/src/App.tsx index a47aee2..579f53d 100644 --- a/app/src/App.tsx +++ b/app/src/App.tsx @@ -11,8 +11,8 @@ import DynamicsModule from './pages/DynamicsModule'; import SettingsModule from './pages/SettingsModule'; import TowerModule from './pages/TowerModule'; import { - Wind, Home, Settings, Menu, Cylinder, Church, CircleDot, - Square, Layers, BarChart3, Activity, Building2, + Home, Settings, Menu, Cylinder, Church, CircleDot, + Square, Layers, BarChart3, Activity, Warehouse, } from 'lucide-react'; import { useState } from 'react'; import { cn } from '@/lib/utils'; @@ -22,6 +22,48 @@ import { useI18n } from './store/i18nStore'; import LanguageSwitcher from './components/LanguageSwitcher'; import { GlobalWindSettingsModal } from './components/GlobalWindSettingsModal'; +// Ícones Customizados de Engenharia Premium +const BridgeIcon = (props: React.SVGProps) => ( + + + + + + + + +); + +const TowerIcon = (props: React.SVGProps) => ( + + + + + + + + + + + +); + function AppLayout({ children }: { children: React.ReactNode }) { const location = useLocation(); const [isCollapsed, setIsCollapsed] = useState(false); @@ -29,15 +71,15 @@ function AppLayout({ children }: { children: React.ReactNode }) { const navItems = [ { path: '/', icon: , labelKey: 'nav_home' as const }, - { path: '/galpao', icon: , labelKey: 'nav_warehouse' as const }, + { path: '/galpao', icon: , labelKey: 'nav_warehouse' as const }, { path: '/cilindro', icon: , labelKey: 'nav_cylinder' as const }, { path: '/abobada', icon: , labelKey: 'nav_vault' as const }, { path: '/cupula', icon: , labelKey: 'nav_dome' as const }, { path: '/muros', icon: , labelKey: 'nav_sign' as const }, { path: '/cobertura-isolada', icon: , labelKey: 'nav_isolated_roof' as const }, { path: '/barras', icon: , labelKey: 'nav_bar' as const }, - { path: '/pontes', icon: , labelKey: 'nav_bridge' as const }, - { path: '/torre', icon: , labelKey: 'nav_tower' as const }, + { path: '/pontes', icon: , labelKey: 'nav_bridge' as const }, + { path: '/torre', icon: , labelKey: 'nav_tower' as const }, { path: '/dinamica', icon: , labelKey: 'nav_dynamics' as const }, { path: '/settings', icon: , labelKey: 'nav_settings' as const }, ]; @@ -177,15 +219,15 @@ function AppLayout({ children }: { children: React.ReactNode }) { function HomeMock() { const { t } = useI18n(); const modules = [ - { to: '/galpao', icon: Wind, label: 'Galpão Retangular', desc: 'Paredes A/B/C/D, telhados E-J, excentricidade, atrito, alta turbulência.' }, + { to: '/galpao', icon: Warehouse, label: 'Galpão Retangular', desc: 'Paredes A/B/C/D, telhados E-J, excentricidade, atrito, alta turbulência.' }, { to: '/cilindro', icon: Cylinder, label: 'Cilindro Vertical', desc: 'Silos, reservatórios, chaminés. Cpe por ângulo (Tab. 13), Reynolds.' }, { to: '/abobada', icon: Church, label: 'Abóbada Cilíndrica', desc: 'Coberturas curvas em arco. Tab. 15-20, 6 zonas.' }, { to: '/cupula', icon: CircleDot, label: 'Cúpula', desc: 'Sobre terreno (Tab. 21) ou parede cilíndrica (Tab. 22).' }, { to: '/muros', icon: Square, label: 'Muros e Placas', desc: 'Cf para vento perpendicular e oblíquo (Tab. 23).' }, { to: '/cobertura-isolada', icon: Layers, label: 'Coberturas Isoladas', desc: 'Uma ou duas águas, abas perpendiculares (Tab. 24-25).' }, { to: '/barras', icon: BarChart3, label: 'Barras Prismáticas', desc: 'Faces planas (Tab. 26) ou circulares (Tab. 27).' }, - { to: '/pontes', icon: Activity, label: 'Pontes', desc: 'Pse, Cx/Cz do tabuleiro, flutter, galope (sec. 11).' }, - { to: '/torre', icon: Building2, label: 'Torres', desc: 'Torres treliçadas e mastros (sec. 8.4).' }, + { to: '/pontes', icon: BridgeIcon, label: 'Pontes', desc: 'Pse, Cx/Cz do tabuleiro, flutter, galope (sec. 11).' }, + { to: '/torre', icon: TowerIcon, label: 'Torres', desc: 'Torres treliçadas e mastros (sec. 8.4).' }, ]; return ( diff --git a/app/src/components/GlobalWindSettingsModal.tsx b/app/src/components/GlobalWindSettingsModal.tsx index 30653ee..ba70e18 100644 --- a/app/src/components/GlobalWindSettingsModal.tsx +++ b/app/src/components/GlobalWindSettingsModal.tsx @@ -14,7 +14,6 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@ import { Badge } from '@/components/ui/badge'; import { Input } from '@/components/ui/input'; import { searchStations } from '@/lib/stations-lookup'; -import type { PermeabilityCase } from '@/lib/internal-pressure'; import { Settings2 } from 'lucide-react'; import { Button } from '@/components/ui/button'; @@ -29,16 +28,11 @@ export function GlobalWindSettingsModal() { s2, vk, q, - permeabilityCase, - cpiRatio, - cpi, setV0, setS1, setS3, setS3Group, setTerrainCategory, - setPermeabilityCase, - setCpiRatio, } = useWindStore(); const [stationQuery, setStationQuery] = useState(''); @@ -63,7 +57,6 @@ export function GlobalWindSettingsModal() { NBR 6123 - Cpi Local @@ -133,46 +126,6 @@ export function GlobalWindSettingsModal() { - -
- - -
- - {(permeabilityCase === 'dominant-windward' || permeabilityCase === 'dominant-lateral') && ( -
-
- - {cpiRatio.toFixed(2)} -
- setCpiRatio(vals[0])} className="py-1 cursor-pointer" /> -

- Razão entre a área da abertura dominante e a área total das demais aberturas em faces com sucção externa. -

-
- )} - -
-
- Cpi calculado: - {cpi.toFixed(2)} -
-

- Limitado a ±0,9 conforme norma. A pressão final usada é p = q · (Cpe − Cpi). -

-
-
-
{ it('nav_cylinder = Cilindro', () => expect(t('nav_cylinder', 'pt-BR')).toBe('Cilindro')); it('nav_vault = Abóbada', () => expect(t('nav_vault', 'pt-BR')).toBe('Abóbada')); it('nav_dome = Cúpula', () => expect(t('nav_dome', 'pt-BR')).toBe('Cúpula')); - it('nav_settings = Configurações', () => expect(t('nav_settings', 'pt-BR')).toBe('Configurações')); + it('nav_settings = Preferências', () => expect(t('nav_settings', 'pt-BR')).toBe('Preferências')); }); describe('M9.8 — Chaves principais em en-US', () => { @@ -168,7 +168,7 @@ describe('M9.8 — Chaves principais em en-US', () => { it('nav_cylinder = Cylinder', () => expect(t('nav_cylinder', 'en-US')).toBe('Cylinder')); it('nav_vault = Vault', () => expect(t('nav_vault', 'en-US')).toBe('Vault')); it('nav_dome = Dome', () => expect(t('nav_dome', 'en-US')).toBe('Dome')); - it('nav_settings = Settings', () => expect(t('nav_settings', 'en-US')).toBe('Settings')); + it('nav_settings = Preferences', () => expect(t('nav_settings', 'en-US')).toBe('Preferences')); }); describe('M9.8 — Conteúdo dos módulos (M9.2-M9.4)', () => { diff --git a/app/src/pages/CylinderModule.tsx b/app/src/pages/CylinderModule.tsx index 28b4285..4619ce6 100644 --- a/app/src/pages/CylinderModule.tsx +++ b/app/src/pages/CylinderModule.tsx @@ -5,6 +5,7 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@ import { Badge } from '@/components/ui/badge'; import { Separator } from '@/components/ui/separator'; import { useWindStore } from '@/store/appStore'; +import { CpiSettingsCard } from '@/components/CpiSettingsCard'; import { calculateCylinder, type CylinderEndType } from '@/lib/modules/cylinder'; import Cylinder3DViewer from '@/components/three/Cylinder3D'; import SceneCapturePanel from '../components/SceneCapturePanel'; @@ -129,6 +130,7 @@ const CylinderModule: React.FC = () => {
+ {/* Coluna Central: 3D */} diff --git a/app/src/pages/DomeModule.tsx b/app/src/pages/DomeModule.tsx index 0ef7091..2d96b21 100644 --- a/app/src/pages/DomeModule.tsx +++ b/app/src/pages/DomeModule.tsx @@ -5,6 +5,7 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@ import { Badge } from '@/components/ui/badge'; import { Separator } from '@/components/ui/separator'; import { useWindStore } from '@/store/appStore'; +import { CpiSettingsCard } from '@/components/CpiSettingsCard'; import { calculateDome, type DomeType } from '@/lib/modules/dome'; import Dome3DViewer from '@/components/three/Dome3D'; import SceneCapturePanel from '../components/SceneCapturePanel'; @@ -109,6 +110,7 @@ const DomeModule: React.FC = () => { + {/* Coluna Central: 3D */}