🚀 Auto-deploy: BrainWind atualizado em 26/08/2026 10:41:48
This commit is contained in:
Generated
+5144
-6
File diff suppressed because it is too large
Load Diff
@@ -36,6 +36,7 @@
|
|||||||
"tailwind-merge": "^3.6.0",
|
"tailwind-merge": "^3.6.0",
|
||||||
"tailwindcss-animate": "^1.0.7",
|
"tailwindcss-animate": "^1.0.7",
|
||||||
"three": "^0.185.1",
|
"three": "^0.185.1",
|
||||||
|
"zundo": "^2.3.0",
|
||||||
"zustand": "^5.0.14"
|
"zustand": "^5.0.14"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -50,6 +51,7 @@
|
|||||||
"tailwindcss": "^4.3.2",
|
"tailwindcss": "^4.3.2",
|
||||||
"typescript": "~6.0.2",
|
"typescript": "~6.0.2",
|
||||||
"vite": "^8.1.1",
|
"vite": "^8.1.1",
|
||||||
|
"vite-plugin-pwa": "^1.3.0",
|
||||||
"vitest": "^4.1.10"
|
"vitest": "^4.1.10"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+21
-75
@@ -1,19 +1,20 @@
|
|||||||
import { BrowserRouter, Routes, Route, Link, useLocation } from 'react-router-dom';
|
import { BrowserRouter, Routes, Route, Link, useLocation } from 'react-router-dom';
|
||||||
import GalpaoModule from './pages/GalpaoModule';
|
// Lazy load modules to improve performance and code splitting
|
||||||
import CylinderModule from './pages/CylinderModule';
|
const GalpaoModule = lazy(() => import('./pages/GalpaoModule'));
|
||||||
import VaultModule from './pages/VaultModule';
|
const CylinderModule = lazy(() => import('./pages/CylinderModule'));
|
||||||
import DomeModule from './pages/DomeModule';
|
const VaultModule = lazy(() => import('./pages/VaultModule'));
|
||||||
import SignModule from './pages/SignModule';
|
const DomeModule = lazy(() => import('./pages/DomeModule'));
|
||||||
import IsolatedRoofModule from './pages/IsolatedRoofModule';
|
const SignModule = lazy(() => import('./pages/SignModule'));
|
||||||
import BarSelectorModule from './pages/BarSelectorModule';
|
const IsolatedRoofModule = lazy(() => import('./pages/IsolatedRoofModule'));
|
||||||
import BridgeModule from './pages/BridgeModule';
|
const BarSelectorModule = lazy(() => import('./pages/BarSelectorModule'));
|
||||||
import DynamicsModule from './pages/DynamicsModule';
|
const BridgeModule = lazy(() => import('./pages/BridgeModule'));
|
||||||
import CalcCaModule from './pages/CalcCaModule';
|
const DynamicsModule = lazy(() => import('./pages/DynamicsModule'));
|
||||||
import SettingsModule from './pages/SettingsModule';
|
const CalcCaModule = lazy(() => import('./pages/CalcCaModule'));
|
||||||
import TowerModule from './pages/TowerModule';
|
const SettingsModule = lazy(() => import('./pages/SettingsModule'));
|
||||||
import PiperackModule from './pages/PiperackModule';
|
const TowerModule = lazy(() => import('./pages/TowerModule'));
|
||||||
import ShelterModule from './pages/ShelterModule';
|
const PiperackModule = lazy(() => import('./pages/PiperackModule'));
|
||||||
import CertificatePage from './pages/CertificatePage';
|
const ShelterModule = lazy(() => import('./pages/ShelterModule'));
|
||||||
|
const CertificatePage = lazy(() => import('./pages/CertificatePage'));
|
||||||
import {
|
import {
|
||||||
Home, Settings, Menu, Cylinder, Church, CircleDot,
|
Home, Settings, Menu, Cylinder, Church, CircleDot,
|
||||||
Square, Layers, BarChart3, Activity, Warehouse,
|
Square, Layers, BarChart3, Activity, Warehouse,
|
||||||
@@ -26,7 +27,7 @@ import {
|
|||||||
DropdownMenuSeparator,
|
DropdownMenuSeparator,
|
||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from "@/components/ui/dropdown-menu";
|
} from "@/components/ui/dropdown-menu";
|
||||||
import { useState } from 'react';
|
import { useState, lazy, Suspense } from 'react';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { ThemeProvider, useTheme } from '@/lib/theme';
|
import { ThemeProvider, useTheme } from '@/lib/theme';
|
||||||
@@ -74,6 +75,8 @@ const TowerIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
|||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
import HomeMock from './pages/HomeMock';
|
||||||
|
|
||||||
function AppLayout({ children }: { children: React.ReactNode }) {
|
function AppLayout({ children }: { children: React.ReactNode }) {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const [isCollapsed, setIsCollapsed] = useState(false);
|
const [isCollapsed, setIsCollapsed] = useState(false);
|
||||||
@@ -347,66 +350,7 @@ function AppLayout({ children }: { children: React.ReactNode }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function HomeMock() {
|
|
||||||
const { t } = useI18n();
|
|
||||||
const modules = [
|
|
||||||
{ 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: 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).' },
|
|
||||||
{ to: '/piperack', icon: Frame, label: 'Pipe-Racks Industriais', desc: 'Estruturas reticuladas múltiplas, tubulações, fator η (Tab. 28).' },
|
|
||||||
{ to: '/abrigo', icon: Tent, label: 'Abrigos e Pórticos Fechados', desc: 'Marquises, abrigos e pórticos. 4 condições topológicas, frestas de alívio, corte A-A (Tab. 23-25, sec. 6.3).' },
|
|
||||||
{ to: '/calc-ca', icon: Calculator, label: 'Calculadora de C_a', desc: 'Coeficiente de arrasto (Fig. 4 e 5).' },
|
|
||||||
];
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="p-8 max-w-6xl mx-auto space-y-8">
|
|
||||||
<header className="text-center space-y-4 flex flex-col items-center mt-4 mb-6">
|
|
||||||
<div className="relative inline-block">
|
|
||||||
<img src="/logo_brainwind.png" alt="BrainWind" className="h-20 md:h-28 w-auto object-contain dark:drop-shadow-[0_0_15px_rgba(255,255,255,0.4)]" />
|
|
||||||
<span className="absolute -bottom-1 -right-2 md:-right-6 bg-primary text-primary-foreground text-[10px] md:text-xs font-bold px-2 py-0.5 rounded-full shadow-sm border border-primary-foreground/20">v1.0</span>
|
|
||||||
</div>
|
|
||||||
<p className="text-muted-foreground text-lg">
|
|
||||||
{t('app_subtitle')}
|
|
||||||
</p>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
||||||
{modules.map((m) => (
|
|
||||||
<Link key={m.to} to={m.to} className="block p-6 rounded-xl border bg-card hover:shadow-lg hover:border-primary transition-all">
|
|
||||||
<m.icon className="w-8 h-8 text-primary mb-3" />
|
|
||||||
<h2 className="font-semibold text-lg mb-1">{m.label}</h2>
|
|
||||||
<p className="text-sm text-muted-foreground">{m.desc}</p>
|
|
||||||
</Link>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="rounded-lg border bg-muted/40 p-4 text-sm text-muted-foreground">
|
|
||||||
<p className="font-medium text-foreground mb-2">{t('home_full_coverage')}</p>
|
|
||||||
<ul className="grid grid-cols-2 md:grid-cols-4 gap-1 text-xs">
|
|
||||||
<li>✓ Sec. 5 — V₀, S₁, S₂, S₃</li>
|
|
||||||
<li>✓ Sec. 6.1 — Paralelepipédicas</li>
|
|
||||||
<li>✓ Sec. 6.2 — Cilindros, abóbadas, cúpulas</li>
|
|
||||||
<li>✓ Sec. 6.3 — Pressão interna (Cpi)</li>
|
|
||||||
<li>✓ Sec. 6.4 — Vizinhança</li>
|
|
||||||
<li>✓ Sec. 7 — Muros, coberturas isoladas</li>
|
|
||||||
<li>✓ Sec. 8 — Barras e reticulados</li>
|
|
||||||
<li>✓ Sec. 9 — Efeitos dinâmicos</li>
|
|
||||||
<li>✓ Sec. 10 — Vórtices</li>
|
|
||||||
<li>✓ Sec. 11 — Pontes</li>
|
|
||||||
<li>✓ Anexo A — S₂(qualquer t)</li>
|
|
||||||
<li>✓ Anexo B — S₃(Pₘ, vida útil)</li>
|
|
||||||
<li>✓ Anexo C — 49 estações meteorológicas</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
@@ -414,6 +358,7 @@ function App() {
|
|||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<AppLayout>
|
<AppLayout>
|
||||||
|
<Suspense fallback={<div className="flex h-full w-full items-center justify-center text-muted-foreground">Carregando módulo...</div>}>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/" element={<HomeMock />} />
|
<Route path="/" element={<HomeMock />} />
|
||||||
<Route path="/galpao" element={<GalpaoModule />} />
|
<Route path="/galpao" element={<GalpaoModule />} />
|
||||||
@@ -432,6 +377,7 @@ function App() {
|
|||||||
<Route path="/settings" element={<SettingsModule />} />
|
<Route path="/settings" element={<SettingsModule />} />
|
||||||
<Route path="/certificado" element={<CertificatePage />} />
|
<Route path="/certificado" element={<CertificatePage />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
|
</Suspense>
|
||||||
</AppLayout>
|
</AppLayout>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
|
|||||||
@@ -0,0 +1,122 @@
|
|||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
import { Warehouse, Cylinder, Church, CircleDot, Square, Layers, BarChart3, Frame, Tent, Calculator } from 'lucide-react';
|
||||||
|
import { useI18n } from '../store/i18nStore';
|
||||||
|
import { useWindStore } from '../store/appStore';
|
||||||
|
|
||||||
|
// Mocked icons for bridge and tower to match App.tsx
|
||||||
|
const BridgeIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||||
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...props}>
|
||||||
|
<path d="M3 18V6l3-1 6 3 6-3 3 1v12" />
|
||||||
|
<path d="M3 10h18" />
|
||||||
|
<path d="M8 10v8M16 10v8" />
|
||||||
|
<path d="M3 14c4-2 6-2 10 0s6 2 8 0" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
|
||||||
|
const TowerIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||||
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...props}>
|
||||||
|
<path d="M6 22L10 2M18 22L14 2" />
|
||||||
|
<path d="M10 2h4" />
|
||||||
|
<path d="M8.5 7h7" />
|
||||||
|
<path d="M7.5 12h9" />
|
||||||
|
<path d="M6.5 17h11" />
|
||||||
|
<path d="M6 22h12" />
|
||||||
|
<path d="M10 2l4 5M12 7l-4 5" />
|
||||||
|
<path d="M10 12l5 5M14 12l-5 5" />
|
||||||
|
<path d="M9.5 17l5.5 5M14.5 17l-5.5 5" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default function HomeMock() {
|
||||||
|
const { t } = useI18n();
|
||||||
|
const { v0, s1, s2, s3, vk, q, locality } = useWindStore();
|
||||||
|
|
||||||
|
const modules = [
|
||||||
|
{ 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: 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).' },
|
||||||
|
{ to: '/piperack', icon: Frame, label: 'Pipe-Racks Industriais', desc: 'Estruturas reticuladas múltiplas, tubulações, fator η (Tab. 28).' },
|
||||||
|
{ to: '/abrigo', icon: Tent, label: 'Abrigos e Pórticos Fechados', desc: 'Marquises, abrigos e pórticos. 4 condições topológicas, frestas de alívio, corte A-A (Tab. 23-25, sec. 6.3).' },
|
||||||
|
{ to: '/calc-ca', icon: Calculator, label: 'Calculadora de C_a', desc: 'Coeficiente de arrasto (Fig. 4 e 5).' },
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="p-8 max-w-6xl mx-auto space-y-8 animate-in fade-in duration-500">
|
||||||
|
<header className="text-center space-y-4 flex flex-col items-center mt-4 mb-6">
|
||||||
|
<div className="relative inline-block">
|
||||||
|
<img src="/logo_brainwind.png" alt="BrainWind" className="h-20 md:h-28 w-auto object-contain dark:drop-shadow-[0_0_15px_rgba(255,255,255,0.4)]" />
|
||||||
|
<span className="absolute -bottom-1 -right-2 md:-right-6 bg-primary text-primary-foreground text-[10px] md:text-xs font-bold px-2 py-0.5 rounded-full shadow-sm border border-primary-foreground/20">v1.1</span>
|
||||||
|
</div>
|
||||||
|
<p className="text-muted-foreground text-lg">
|
||||||
|
{t('app_subtitle')}
|
||||||
|
</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
{/* Dashboard de Vento Básico */}
|
||||||
|
<div className="bg-card border rounded-xl p-6 shadow-sm">
|
||||||
|
<h3 className="font-semibold text-lg mb-4 text-card-foreground">Parâmetros Atuais do Vento {locality ? `(${locality})` : ''}</h3>
|
||||||
|
<div className="grid grid-cols-2 md:grid-cols-6 gap-4">
|
||||||
|
<div className="flex flex-col items-center justify-center p-3 bg-muted/50 rounded-lg border">
|
||||||
|
<span className="text-xs text-muted-foreground">V₀ (m/s)</span>
|
||||||
|
<span className="font-bold text-xl">{v0.toFixed(1)}</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col items-center justify-center p-3 bg-muted/50 rounded-lg border">
|
||||||
|
<span className="text-xs text-muted-foreground">S₁</span>
|
||||||
|
<span className="font-bold text-xl">{s1.toFixed(2)}</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col items-center justify-center p-3 bg-muted/50 rounded-lg border">
|
||||||
|
<span className="text-xs text-muted-foreground">S₂</span>
|
||||||
|
<span className="font-bold text-xl">{s2.toFixed(2)}</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col items-center justify-center p-3 bg-muted/50 rounded-lg border">
|
||||||
|
<span className="text-xs text-muted-foreground">S₃</span>
|
||||||
|
<span className="font-bold text-xl">{s3.toFixed(2)}</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col items-center justify-center p-3 bg-muted/50 rounded-lg border">
|
||||||
|
<span className="text-xs text-muted-foreground">Vₖ (m/s)</span>
|
||||||
|
<span className="font-bold text-xl text-primary">{vk.toFixed(1)}</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col items-center justify-center p-3 bg-primary/10 rounded-lg border border-primary/20">
|
||||||
|
<span className="text-xs text-primary/80 font-medium">q (kN/m²)</span>
|
||||||
|
<span className="font-bold text-2xl text-primary">{q.toFixed(3)}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||||
|
{modules.map((m) => (
|
||||||
|
<Link key={m.to} to={m.to} className="block p-6 rounded-xl border bg-card hover:shadow-lg hover:border-primary transition-all">
|
||||||
|
<m.icon className="w-8 h-8 text-primary mb-3" />
|
||||||
|
<h2 className="font-semibold text-lg mb-1">{m.label}</h2>
|
||||||
|
<p className="text-sm text-muted-foreground">{m.desc}</p>
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="rounded-lg border bg-muted/40 p-4 text-sm text-muted-foreground">
|
||||||
|
<p className="font-medium text-foreground mb-2">{t('home_full_coverage')}</p>
|
||||||
|
<ul className="grid grid-cols-2 md:grid-cols-4 gap-1 text-xs">
|
||||||
|
<li>✓ Sec. 5 — V₀, S₁, S₂, S₃</li>
|
||||||
|
<li>✓ Sec. 6.1 — Paralelepipédicas</li>
|
||||||
|
<li>✓ Sec. 6.2 — Cilindros, abóbadas, cúpulas</li>
|
||||||
|
<li>✓ Sec. 6.3 — Pressão interna (Cpi)</li>
|
||||||
|
<li>✓ Sec. 6.4 — Vizinhança</li>
|
||||||
|
<li>✓ Sec. 7 — Muros, coberturas isoladas</li>
|
||||||
|
<li>✓ Sec. 8 — Barras e reticulados</li>
|
||||||
|
<li>✓ Sec. 9 — Efeitos dinâmicos</li>
|
||||||
|
<li>✓ Sec. 10 — Vórtices</li>
|
||||||
|
<li>✓ Sec. 11 — Pontes</li>
|
||||||
|
<li>✓ Anexo A — S₂(qualquer t)</li>
|
||||||
|
<li>✓ Anexo B — S₃(Pₘ, vida útil)</li>
|
||||||
|
<li>✓ Anexo C — 49 estações</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import { create } from 'zustand';
|
import { create } from 'zustand';
|
||||||
|
import { temporal } from 'zundo';
|
||||||
import { getWallCpeOfficial as getWallCpe, getRoofCpeOfficial as getRoofCpe } from '../lib/coefficients';
|
import { getWallCpeOfficial as getWallCpe, getRoofCpeOfficial as getRoofCpe } from '../lib/coefficients';
|
||||||
import { useWindStore } from './appStore';
|
import { useWindStore } from './appStore';
|
||||||
import type { WallCoefficients, RoofCoefficients } from '../lib/coefficients';
|
import type { WallCoefficients, RoofCoefficients } from '../lib/coefficients';
|
||||||
@@ -40,7 +41,9 @@ const initHeight = 6;
|
|||||||
const initPitch = 10;
|
const initPitch = 10;
|
||||||
const initAngle: 0 | 90 = 0;
|
const initAngle: 0 | 90 = 0;
|
||||||
|
|
||||||
export const useGalpaoStore = create<GalpaoState>((set, get) => ({
|
export const useGalpaoStore = create<GalpaoState>()(
|
||||||
|
temporal(
|
||||||
|
(set, get) => ({
|
||||||
template: 'standard',
|
template: 'standard',
|
||||||
extraHeight: 1.5,
|
extraHeight: 1.5,
|
||||||
skirtHeight: 4.5,
|
skirtHeight: 4.5,
|
||||||
@@ -85,4 +88,4 @@ export const useGalpaoStore = create<GalpaoState>((set, get) => ({
|
|||||||
set({ roofPitch: val });
|
set({ roofPitch: val });
|
||||||
get().updateCoefficients();
|
get().updateCoefficients();
|
||||||
},
|
},
|
||||||
}));
|
})));
|
||||||
+34
-1
@@ -1,6 +1,7 @@
|
|||||||
import { defineConfig } from 'vite'
|
import { defineConfig } from 'vite'
|
||||||
import react from '@vitejs/plugin-react'
|
import react from '@vitejs/plugin-react'
|
||||||
import tailwindcss from '@tailwindcss/vite'
|
import tailwindcss from '@tailwindcss/vite'
|
||||||
|
import { VitePWA } from 'vite-plugin-pwa'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
|
|
||||||
@@ -24,7 +25,39 @@ try {
|
|||||||
|
|
||||||
// https://vite.dev/config/
|
// https://vite.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [react(), tailwindcss()],
|
plugins: [
|
||||||
|
react(),
|
||||||
|
tailwindcss(),
|
||||||
|
VitePWA({
|
||||||
|
registerType: 'autoUpdate',
|
||||||
|
includeAssets: ['favicon.ico', 'apple-touch-icon.png', 'logo_brainwind.svg'],
|
||||||
|
manifest: {
|
||||||
|
name: 'VentoApp - BrainWind',
|
||||||
|
short_name: 'VentoApp',
|
||||||
|
description: 'Cálculo de ação do vento NBR 6123:2023',
|
||||||
|
theme_color: '#020617', // slate-950
|
||||||
|
background_color: '#ffffff',
|
||||||
|
display: 'standalone',
|
||||||
|
icons: [
|
||||||
|
{
|
||||||
|
src: 'logo_brainwind.png',
|
||||||
|
sizes: '192x192',
|
||||||
|
type: 'image/png'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: 'logo_brainwind.png',
|
||||||
|
sizes: '512x512',
|
||||||
|
type: 'image/png',
|
||||||
|
purpose: 'any maskable'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
workbox: {
|
||||||
|
globPatterns: ['**/*.{js,css,html,ico,png,svg,json}'],
|
||||||
|
maximumFileSizeToCacheInBytes: 5000000 // 5MB limit for 3D assets
|
||||||
|
}
|
||||||
|
})
|
||||||
|
],
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
"@": path.resolve(__dirname, "./src"),
|
"@": path.resolve(__dirname, "./src"),
|
||||||
|
|||||||
Reference in New Issue
Block a user