Files
runvision_pro_web/src/sections/DeepDive.tsx

165 lines
6.3 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useEffect, useRef } from 'react';
import { Battery, Zap, Database, Clock } from 'lucide-react';
import { Badge } from '@/components/ui/badge';
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card';
const calculations = [
{
icon: Battery,
title: 'Energia Útil (Wh)',
formula: 'Capacidade (Ah) × Tensão (V)',
steps: [
'Capacidade: 500 mAh = 0,500 Ah',
'Tensão Nominal: 3,7 V',
'0,500 Ah × 3,7 V = 1,85 Wh'
],
result: '1,85 Wh de energia armazenada',
color: 'orange'
},
{
icon: Zap,
title: 'Consumo por Modo',
formula: 'Autonomia = mAh / mA',
modes: [
{ name: 'Standby', current: '6,94 mA', autonomy: '72,0 h' },
{ name: 'Otimizado (Light)', current: '60 mA', autonomy: '8,33 h' },
{ name: 'Uso Normal', current: '125 mA', autonomy: '4,0 h' },
{ name: 'Performance', current: '260 mA', autonomy: '1,92 h' }
],
color: 'teal'
},
{
icon: Database,
title: 'Armazenamento GPS',
formula: 'Flash / Sample Size',
steps: [
'Flash: 4 MB (4.194.304 bytes)',
'Sample: ~32 bytes (lat, lon, spd...)',
'Capacidade Bruta: 131.072 amostras',
'Realista (50% útil): ~18h @ 1Hz'
],
result: 'Espaço para múltiplas sessões locais',
color: 'blue'
},
{
icon: Clock,
title: 'Ciclo de Carga',
formula: 'Capacidade / Corrente de Carga',
steps: [
'Carga Típica (0,5C): 250 mA',
'Tempo Teórico: 2,0 h',
'Com Overhead (CC-CV): ~2,2 h',
'Carga Rápida (1C): ~1,2 h'
],
result: '2h para carga completa segura',
color: 'green'
}
];
export function DeepDive() {
const sectionRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const elements = entry.target.querySelectorAll('.reveal-dive');
elements.forEach((el, index) => {
setTimeout(() => {
el.classList.add('animate-fade-in-up');
}, index * 100);
});
observer.unobserve(entry.target);
}
});
},
{ threshold: 0.1 }
);
if (sectionRef.current) {
observer.observe(sectionRef.current);
}
return () => observer.disconnect();
}, []);
return (
<section id="deep-dive" ref={sectionRef} className="py-24 lg:py-32 bg-slate-900">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center mb-16 reveal-dive opacity-0">
<Badge className="mb-4 bg-orange-500/10 text-orange-400 border-orange-500/30 hover:bg-orange-500/20 px-4 py-1.5 text-xs font-semibold tracking-wider uppercase">
Deep Dive Técnico
</Badge>
<h2 className="font-display font-bold text-3xl sm:text-4xl lg:text-5xl text-white mb-4">
Cálculos e Estimativas Reais
</h2>
<div className="w-16 h-1 bg-gradient-to-r from-orange-500 to-teal-500 mx-auto rounded-full mb-6" />
<p className="text-slate-400 text-lg max-w-2xl mx-auto">
Transparência total: veja como chegamos às cifras de autonomia, carregamento e armazenamento do RunVision Pro.
</p>
</div>
<div className="grid md:grid-cols-2 gap-6 lg:gap-8">
{calculations.map((calc, index) => {
const Icon = calc.icon;
return (
<Card key={index} className="reveal-dive opacity-0 bg-slate-800/40 border-slate-700 hover:border-slate-500 transition-all duration-300">
<CardHeader className="flex flex-row items-center gap-4 space-y-0">
<div className={`w-12 h-12 rounded-lg bg-slate-700/50 flex items-center justify-center`}>
<Icon className="w-6 h-6 text-white" />
</div>
<div>
<CardTitle className="text-white text-xl">{calc.title}</CardTitle>
<p className="text-slate-500 text-sm font-mono">{calc.formula}</p>
</div>
</CardHeader>
<CardContent>
{calc.modes ? (
<div className="space-y-3">
<div className="grid grid-cols-3 text-xs font-semibold text-slate-500 uppercase tracking-wider pb-2 border-b border-slate-700/50">
<span>Modo</span>
<span>Corrente</span>
<span className="text-right">Autonomia</span>
</div>
{calc.modes.map((mode, mIdx) => (
<div key={mIdx} className="grid grid-cols-3 text-sm py-1">
<span className="text-slate-300">{mode.name}</span>
<span className="text-slate-400 font-mono">{mode.current}</span>
<span className="text-orange-400 font-mono text-right">{mode.autonomy}</span>
</div>
))}
</div>
) : (
<div className="space-y-4">
<ul className="space-y-2">
{calc.steps?.map((step, sIdx) => (
<li key={sIdx} className="flex items-center gap-2 text-sm text-slate-400">
<div className="w-1.5 h-1.5 rounded-full bg-slate-600" />
{step}
</li>
))}
</ul>
<div className="pt-4 border-t border-slate-700/50">
<p className="text-teal-400 font-semibold">{calc.result}</p>
</div>
</div>
)}
</CardContent>
</Card>
);
})}
</div>
<div className="mt-12 reveal-dive opacity-0">
<div className="bg-orange-500/5 border border-orange-500/20 rounded-2xl p-6 text-center">
<p className="text-slate-400 text-sm italic">
* Nota: 8h em modo otimizado (GPS 1 Hz, brilho reduzido). Em sessões com GPS em alta taxa de atualização e sincronização Wi-Fi contínua, a autonomia média é de 24 h.
</p>
</div>
</div>
</div>
</section>
);
}