From eb7d54666e0e87099fce287381cfe822e3121a91 Mon Sep 17 00:00:00 2001
From: Lucas Rayan
Date: Wed, 21 Jan 2026 12:57:18 -0300
Subject: [PATCH] feat: add intelligent selection tool for ESP32 series with
user-driven questions and recommendations
---
app/page.jsx | 15 +-
app/seletor/page.jsx | 467 ++++++++++++++++++++++++++++++++++++++++++
components/Header.jsx | 2 +
3 files changed, 481 insertions(+), 3 deletions(-)
create mode 100644 app/seletor/page.jsx
diff --git a/app/page.jsx b/app/page.jsx
index f9320ef..cb2a0d3 100644
--- a/app/page.jsx
+++ b/app/page.jsx
@@ -4,6 +4,7 @@ import Link from "next/link";
export default function Home() {
const resources = [
+ {name: "Seletor Inteligente", description: "Responda perguntas sobre seu projeto e descubra qual série ESP32 é ideal para você", icon: "🎯"},
{name: "Catálogo de Placas", description: "Encontre placas de desenvolvimento ESP32 verificadas com filtros avançados e links seguros para compra", icon: "🛒"},
{name: "Especificações Organizadas", description: "Especificações técnicas de cada série ESP32 organizadas em tabelas comparativas em português", icon: "🔧"},
{name: "Diagramas de Conexões", description: "Visualize diagramas interativos dos componentes e pinos de cada série ESP32", icon: "📊"},
@@ -37,15 +38,23 @@ export default function Home() {
+
+
🎯
+
Encontrar ESP32 Ideal
+
+
+
+
+
📚
Explorar Séries ESP32
-
-
-
{
+ setAnswers({ ...answers, [questionId]: value });
+ if (currentStep < questions.length - 1) {
+ setCurrentStep(currentStep + 1);
+ }
+ };
+
+ const resetQuiz = () => {
+ setCurrentStep(0);
+ setAnswers({
+ wifi: null,
+ bluetooth: null,
+ cores: null,
+ ai: null,
+ matter: null,
+ gpio: null,
+ usb: null,
+ lowPower: null,
+ });
+ };
+
+ const goBack = () => {
+ if (currentStep > 0) {
+ setCurrentStep(currentStep - 1);
+ }
+ };
+
+ const calculateRecommendations = () => {
+ const scores = {};
+
+ Object.keys(seriesData).forEach(key => {
+ scores[key] = 0;
+ const serie = seriesData[key];
+
+ // Wi-Fi
+ if (answers.wifi === "required" && serie.wifi && !String(serie.wifi).includes("Não")) {
+ scores[key] += 10;
+ } else if (answers.wifi === "no" && (!serie.wifi || String(serie.wifi).includes("Não"))) {
+ scores[key] += 5;
+ } else if (answers.wifi === "nice" && serie.wifi && !String(serie.wifi).includes("Não")) {
+ scores[key] += 3;
+ } else if (answers.wifi === "required" && (!serie.wifi || String(serie.wifi).includes("Não"))) {
+ scores[key] -= 100; // Desqualifica
+ }
+
+ // Bluetooth
+ if (answers.bluetooth === "required" && serie.bluetooth !== "Não") {
+ scores[key] += 10;
+ } else if (answers.bluetooth === "no" && serie.bluetooth === "Não") {
+ scores[key] += 5;
+ } else if (answers.bluetooth === "nice" && serie.bluetooth !== "Não") {
+ scores[key] += 3;
+ } else if (answers.bluetooth === "required" && serie.bluetooth === "Não") {
+ scores[key] -= 100; // Desqualifica
+ }
+
+ // Núcleos
+ if (answers.cores === "dual" && serie.nucleos.includes("2")) {
+ scores[key] += 8;
+ } else if (answers.cores === "single" && serie.nucleos.includes("1")) {
+ scores[key] += 5;
+ } else if (answers.cores === "dual" && !serie.nucleos.includes("2")) {
+ scores[key] -= 5;
+ }
+
+ // IA
+ if (answers.ai === "yes" && serie.aceleradores_ia) {
+ scores[key] += 15;
+ } else if (answers.ai === "yes" && !serie.aceleradores_ia) {
+ scores[key] -= 10;
+ }
+
+ // Matter/Zigbee/Thread
+ if (answers.matter === "yes" && serie.matter === "Sim") {
+ scores[key] += 12;
+ } else if (answers.matter === "yes" && serie.matter !== "Sim") {
+ scores[key] -= 8;
+ }
+
+ // GPIO
+ const gpioCount = parseInt(serie.gpio);
+ if (answers.gpio === "many" && gpioCount >= 35) {
+ scores[key] += 8;
+ } else if (answers.gpio === "medium" && gpioCount >= 20 && gpioCount < 35) {
+ scores[key] += 8;
+ } else if (answers.gpio === "few" && gpioCount < 20) {
+ scores[key] += 8;
+ } else if (answers.gpio === "many" && gpioCount < 35) {
+ scores[key] -= 5;
+ }
+
+ // USB
+ if (answers.usb === "yes" && serie.usb && serie.usb !== "Não") {
+ scores[key] += 10;
+ } else if (answers.usb === "nice" && serie.usb && serie.usb !== "Não") {
+ scores[key] += 5;
+ } else if (answers.usb === "yes" && (!serie.usb || serie.usb === "Não")) {
+ scores[key] -= 5;
+ }
+
+ // Baixo consumo
+ if (answers.lowPower === "critical") {
+ const deepSleep = serie.consumo_energia?.deep_sleep;
+ if (deepSleep && (deepSleep.includes("µA") || deepSleep.includes("5 µA") || deepSleep.includes("7 µA"))) {
+ scores[key] += 12;
+ }
+ }
+ });
+
+ // Ordenar por pontuação
+ const sortedSeries = Object.entries(scores)
+ .filter(([_, score]) => score > 0)
+ .sort(([, a], [, b]) => b - a)
+ .slice(0, 3);
+
+ return sortedSeries.map(([key]) => key);
+ };
+
+ const recommendations = currentStep === questions.length - 1 && Object.values(answers).every(a => a !== null)
+ ? calculateRecommendations()
+ : [];
+
+ const progress = ((currentStep + 1) / questions.length) * 100;
+
+ return (
+
+
+
+
+
+
+ 🎯
+ Ferramenta de Seleção Inteligente
+
+
+
+ Encontre seu ESP32 Ideal
+
+
+
+ Responda algumas perguntas sobre seu projeto e descubra qual série ESP32 é perfeita para você
+
+
+
+ {/* Progress Bar */}
+
+
+
+ Pergunta {currentStep + 1} de {questions.length}
+
+
+ {Math.round(progress)}%
+
+
+
+
+
+ {/* Question Card */}
+ {currentStep < questions.length && recommendations.length === 0 && (
+
+
+
+ {questions[currentStep].question}
+
+
+ {questions[currentStep].description}
+
+
+
+
+ {questions[currentStep].options.map((option) => (
+
handleAnswer(questions[currentStep].id, option.value)}
+ className="group bg-gray-50 hover:bg-purple-50 border-2 border-gray-200 hover:border-purple-500 rounded-2xl p-6 transition-all duration-300 transform hover:scale-105 hover:shadow-xl"
+ >
+
+ {option.icon}
+
+ {option.label}
+
+
+
+ ))}
+
+
+ {/* Navigation Buttons */}
+
+
+
+
+
+ Voltar
+
+
+
+ Recomeçar
+
+
+
+ )}
+
+ {/* Results */}
+ {recommendations.length > 0 && (
+
+
+
+
+ ✨
+
+
+ Recomendações para seu Projeto
+
+
+ Baseado nas suas respostas, estas são as melhores opções de ESP32 para você:
+
+
+
+
+ {recommendations.map((seriesKey, index) => {
+ const serie = seriesData[seriesKey];
+ const badges = ["🥇 Melhor Opção", "🥈 Segunda Opção", "🥉 Terceira Opção"];
+
+ return (
+
+
+
+
+ {badges[index]}
+
+
{serie.icone}
+
{seriesKey}
+
{serie.descricao}
+
+
+
+
+
+ Arquitetura:
+ {serie.arquitetura.split(' ')[0]}
+
+
+ Núcleos:
+ {serie.nucleos}
+
+
+ Frequência:
+ {serie.frequencia}
+
+
+ SRAM:
+ {serie.memoria_sram}
+
+
+ GPIO:
+ {serie.gpio}
+
+
+
+
+
+ Ver Detalhes
+
+
+
+ );
+ })}
+
+
+
+
+ 📊
+ Comparar Recomendações
+
+
+
+ 🔄
+ Fazer Novamente
+
+
+
+
+ {/* Additional Resources */}
+
+
+ Próximos Passos
+
+
+
+
🛒
+
+ Ver Catálogo de Placas
+
+
+ Encontre placas de desenvolvimento verificadas
+
+
+
+
+
⚡
+
+ Explorar Frameworks
+
+
+ Conheça ESP-IDF, Arduino, MicroPython e mais
+
+
+
+
+
📚
+
+ Consultar Glossário
+
+
+ Entenda termos técnicos e especificações
+
+
+
+
+
+ )}
+
+
+
+
+ );
+}
diff --git a/components/Header.jsx b/components/Header.jsx
index bb0cdab..9278ab5 100644
--- a/components/Header.jsx
+++ b/components/Header.jsx
@@ -17,6 +17,7 @@ import FrameworksIcon from "@mui/icons-material/Apps";
import CompareIcon from "@mui/icons-material/CompareArrows";
import ShoppingCartIcon from "@mui/icons-material/ShoppingCart";
import MenuBookIcon from "@mui/icons-material/MenuBook";
+import FindInPageIcon from "@mui/icons-material/FindInPage";
export default function Header() {
const [drawerOpen, setDrawerOpen] = useState(false);
@@ -27,6 +28,7 @@ export default function Header() {
{ text: "Sobre o Projeto", brief: "Sobre", href: "/sobre", icon:
},
{ text: "Glossário", href: "/glossario", icon:
},
{ text: "Séries", href: "/series", icon:
, featured: true },
+ { text: "Seletor de ESP32", brief: "Seletor", href: "/seletor", icon:
, featured: true },
{ text: "Frameworks", href: "/frameworks", icon:
, featured: true },
{ text: "Comparar Séries", brief: "Comparar", href: "/comparacao", icon:
, featured: true },
{ text: "Catálogo de Placas", brief: "Catálogo", href: "/catalogo", icon:
},