Cases da SEV Moda Íntima e da Lavação 047; case no formato cliente, problema, entrega, mídia e contato, com detalhes técnicos recolhidos; sem GitHub, ressalvas e fontes de commit. /cases separa clientes e Laboratório. Serviços mostram o case de cliente certo e o bloco de investimento e prazo só aparece preenchido. Metadata social própria por página, not-found com noindex, sitemap com /ia.
711 lines
41 KiB
TypeScript
711 lines
41 KiB
TypeScript
import { portfolio } from "./portfolio-data";
|
|
import { isClientProject } from "./proof";
|
|
|
|
export const siteUrl = "https://evandro.dev.br";
|
|
export const siteName = "Evandro.dev.br";
|
|
|
|
export interface ServicePageContent {
|
|
slug: string;
|
|
navLabel: string;
|
|
eyebrow: string;
|
|
seoTitle: string;
|
|
metaDescription: string;
|
|
headline: string;
|
|
intro: string;
|
|
answer: string;
|
|
audience: string[];
|
|
outcomes: string[];
|
|
process: string[];
|
|
examples: string[];
|
|
technicalDetails: string[];
|
|
stack: string[];
|
|
ctaLabel: string;
|
|
/** Ids dos cases relacionados; os de cliente aparecem primeiro na página. */
|
|
relatedCaseIds: string[];
|
|
/** Oferta: preencha só com valores reais. O bloco "Investimento e prazo" só aparece quando algum campo existe. */
|
|
startingPrice?: string;
|
|
typicalTimeline?: string;
|
|
guarantee?: string;
|
|
faq?: { question: string; answer: string }[];
|
|
}
|
|
|
|
export interface CaseStudyContent {
|
|
id: string;
|
|
/** Nome do projeto ou do cliente. */
|
|
title: string;
|
|
/** Tipo do projeto, em poucas palavras. */
|
|
subtitle: string;
|
|
/** Título da página, em linguagem de negócio. */
|
|
headline: string;
|
|
/** Resumo de uma ou duas frases (cards, descrição de busca e abertura da página). */
|
|
summary: string;
|
|
/** O que muda para quem usa, em uma frase. */
|
|
impact: string;
|
|
/** Quem é o cliente e em que situação o projeto nasceu. */
|
|
context: string;
|
|
/** O problema que o projeto resolve. */
|
|
problem: string;
|
|
/** O que foi feito, escrito como benefício. */
|
|
deliveries: string[];
|
|
/** Resultado com dado real e autorizado. Sem dado, o campo fica de fora e a seção não aparece. */
|
|
result?: string[];
|
|
/** Detalhes técnicos: tecnologias e decisões de projeto (ficam recolhidos no fim da página). */
|
|
stack: string[];
|
|
decisions: string[];
|
|
demoUrl?: string | null;
|
|
/** Papel do autor quando o projeto não é só dele. */
|
|
role?: string;
|
|
}
|
|
|
|
export const servicePages: ServicePageContent[] = [
|
|
{
|
|
slug: "criacao-de-sites",
|
|
navLabel: "Sites profissionais",
|
|
eyebrow: "Presença digital",
|
|
seoTitle: "Criação de Sites para Empresas em Garuva e Joinville",
|
|
metaDescription:
|
|
"Site profissional para apresentar sua empresa e levar o cliente ao seu WhatsApp. Desenvolvido em Garuva-SC, com atendimento em Joinville, região e remoto no Brasil.",
|
|
headline: "Um site que explica seu negócio.",
|
|
answer:
|
|
"Crio sites para apresentar sua empresa, mostrar o que você oferece e facilitar o contato. O projeto considera leitura no celular e no computador, conteúdo, páginas e funcionalidades combinadas antes do desenvolvimento.",
|
|
intro:
|
|
"Apresente seu negócio na internet com um site profissional: serviços, produtos, portfólio e caminhos claros para entrar em contato.",
|
|
audience: [
|
|
"Empresas e profissionais que ainda não têm site ou precisam substituir uma presença desatualizada.",
|
|
"Negócios que querem explicar seus serviços sem depender apenas das redes sociais.",
|
|
"Equipes que precisam organizar páginas, conteúdo e contato em um endereço próprio.",
|
|
],
|
|
outcomes: [
|
|
"Páginas com uma sequência clara: o que você faz, para quem e como entrar em contato.",
|
|
"Layout adaptado a celular e computador, com atenção à leitura e à navegação.",
|
|
"Publicação do site e orientação de uso. Domínio, hospedagem, produção de conteúdo e manutenção são combinados à parte, na proposta.",
|
|
],
|
|
examples: [
|
|
"Um site institucional para uma prestadora de serviços, com apresentação, áreas de atuação e contato.",
|
|
"Um catálogo para mostrar produtos e receber consultas, sem assumir uma loja com pagamento on-line.",
|
|
"Uma página de campanha para explicar uma oferta e orientar o próximo passo.",
|
|
],
|
|
process: [
|
|
"Conversamos sobre o negócio, o público e o que o visitante precisa conseguir fazer.",
|
|
"Combinamos páginas, conteúdo, referências visuais, responsabilidades e orçamento.",
|
|
"Você acompanha a construção e revisa conteúdo e navegação em etapas.",
|
|
"Publicamos após a revisão e definimos o que entra em suporte ou evolução posterior.",
|
|
],
|
|
technicalDetails: [
|
|
"Implementação com Next.js e TypeScript, escolhendo renderização e carregamento conforme o conteúdo e as integrações.",
|
|
"HTML semântico, navegação por teclado, imagens dimensionadas e avaliação de carregamento orientam acessibilidade e performance.",
|
|
"Metadados, URLs canônicas, sitemap e dados estruturados ajudam os buscadores a entender o site.",
|
|
],
|
|
stack: ["Next.js", "TypeScript", "Tailwind CSS", "SEO técnico", "Vercel"],
|
|
ctaLabel: "Conversar sobre meu site",
|
|
relatedCaseIds: ["sev-modaintima", "lavacao-047", "sc-plus", "as-servicos"],
|
|
faq: [
|
|
{
|
|
question: "Quanto custa e o que preciso ter pronto?",
|
|
answer:
|
|
"O orçamento depende das páginas, conteúdo, funcionalidades e integrações. Podemos começar com uma conversa sobre seu negócio; nela definimos quem fornece textos, imagens e acessos, além dos custos de domínio e hospedagem.",
|
|
},
|
|
{
|
|
question: "O site também funciona no celular?",
|
|
answer:
|
|
"Sim. O site se adapta à tela e abre pelo navegador, no celular e no computador. Se você precisa de um aplicativo instalado no aparelho, conversamos sobre isso em um projeto à parte.",
|
|
},
|
|
{
|
|
question: "Posso contratar melhorias depois da publicação?",
|
|
answer:
|
|
"Sim. Ajustes de conteúdo, novas páginas, manutenção e novas funcionalidades podem ser combinados em continuidade. O que está incluído na entrega inicial e no suporte fica definido na proposta.",
|
|
},
|
|
],
|
|
},
|
|
{
|
|
slug: "engenharia-de-software",
|
|
navLabel: "Sistemas web e aplicativos mobile",
|
|
eyebrow: "Engenharia de software",
|
|
seoTitle: "Sistemas Web e Aplicativos sob Medida em Santa Catarina",
|
|
metaDescription:
|
|
"Sistema web ou aplicativo sob medida para organizar pedidos, clientes e rotinas em um só lugar. Desenvolvedor em Garuva-SC, com atendimento em Joinville e remoto no Brasil.",
|
|
headline: "Sistemas e apps para o seu trabalho.",
|
|
answer:
|
|
"Desenvolvo sistemas web, usados no navegador, e aplicativos mobile para celular. Também conecto ferramentas e evoluo sistemas existentes. Definimos juntos os usuários, as funções, as plataformas atendidas e a primeira entrega útil para o negócio.",
|
|
intro:
|
|
"Organize a operação com um sistema web ou aplicativo mobile sob medida. Conecte ferramentas, reduza tarefas repetidas ou melhore um sistema que já existe.",
|
|
audience: [
|
|
"Empresas que controlam processos em planilhas, mensagens e ferramentas que não conversam entre si.",
|
|
"Negócios que precisam de um sistema interno, área de clientes ou aplicativo para uso no celular.",
|
|
"Equipes com software em operação que precisam corrigir problemas e continuar evoluindo.",
|
|
],
|
|
outcomes: [
|
|
"Uma primeira versão com as funções prioritárias, em vez de tentar resolver toda a operação de uma vez.",
|
|
"Fluxos para consultar, registrar e compartilhar informações, com acessos definidos por perfil.",
|
|
"Web ou mobile, conforme o seu caso: dispositivos, sistemas operacionais, uso sem internet e distribuição são combinados na proposta.",
|
|
],
|
|
examples: [
|
|
"Um sistema web para acompanhar pedidos e atendimentos em uma única tela.",
|
|
"Um aplicativo mobile para uma equipe consultar tarefas e registrar visitas pelo celular.",
|
|
"Uma integração para transferir dados entre o sistema de vendas e outra ferramenta, sem digitação duplicada.",
|
|
],
|
|
process: [
|
|
"Entendemos a rotina atual, quem usa o sistema e onde estão as dificuldades.",
|
|
"Escolhemos o primeiro fluxo a entregar e combinamos plataformas, integrações e critérios de aceitação.",
|
|
"Construímos em etapas curtas, com demonstrações e revisão de quem vai usar.",
|
|
"Validamos no ambiente combinado e entregamos orientações para operação, manutenção e próximos passos.",
|
|
],
|
|
technicalDetails: [
|
|
"A arquitetura parte das regras do negócio, dos limites entre módulos e dos contratos de API. Migrações e integrações consideram os dados e o sistema já em uso.",
|
|
"Autorização por perfil, validação no servidor, tratamento de falhas e testes dos fluxos críticos entram conforme os riscos do projeto.",
|
|
"Em aplicativos mobile, a tecnologia é escolhida depois de avaliar os dispositivos e os recursos necessários, como câmera, notificações e uso sem internet.",
|
|
],
|
|
stack: ["Next.js", "TypeScript", "Node.js", "PostgreSQL", "APIs REST"],
|
|
ctaLabel: "Conversar sobre meu sistema ou app",
|
|
relatedCaseIds: ["sev-modaintima", "lavacao-047"],
|
|
faq: [
|
|
{
|
|
question: "Preciso saber qual tecnologia usar?",
|
|
answer:
|
|
"Não. Começamos pelo que as pessoas precisam fazer. Um sistema web pode resolver o uso pelo navegador; um aplicativo mobile pode fazer sentido quando a rotina exige recursos do celular. A escolha vem depois de entender o contexto.",
|
|
},
|
|
{
|
|
question: "Você também trabalha com sistemas que já existem?",
|
|
answer:
|
|
"Sim. Posso diagnosticar problemas, integrar ferramentas, corrigir fluxos e implementar novas funções. Primeiro avaliamos a base atual e os riscos para definir uma mudança que não dependa de reescrever tudo.",
|
|
},
|
|
{
|
|
question: "O aplicativo inclui publicação em lojas?",
|
|
answer:
|
|
"A forma de distribuição é definida no projeto. Plataformas, contas de desenvolvedor, requisitos das lojas e a publicação são combinados antes da contratação.",
|
|
},
|
|
],
|
|
},
|
|
{
|
|
slug: "consultoria-nextjs",
|
|
navLabel: "Melhorias em sites e sistemas Next.js",
|
|
eyebrow: "Consultoria Next.js",
|
|
seoTitle: "Consultoria Next.js para Melhorar Seu Site ou Sistema",
|
|
metaDescription:
|
|
"Descubra por que seu site ou sistema Next.js está lento ou com falhas e receba um plano de correção claro. Atendimento a partir de Garuva-SC, em Joinville e remoto no Brasil.",
|
|
headline: "Seu projeto Next.js pode funcionar melhor.",
|
|
answer:
|
|
"Analiso sites e sistemas feitos em Next.js para entender lentidão, falhas ou dificuldades de manutenção. Você recebe prioridades explicadas, um plano de correção e, quando contratado, a implementação das melhorias.",
|
|
intro:
|
|
"Seu site ou sistema Next.js está lento, apresenta falhas ou ficou difícil de manter? Identifique a causa e organize as melhorias antes de investir em mais mudanças.",
|
|
audience: [
|
|
"Empresas com um site ou sistema em Next.js que não está atendendo bem seus usuários.",
|
|
"Equipes que precisam de apoio para investigar falhas, carregamento ou indexação.",
|
|
"Responsáveis por um produto que precisam entender o que corrigir primeiro e por quê.",
|
|
],
|
|
outcomes: [
|
|
"Diagnóstico com problemas observados, impacto para o usuário e prioridades.",
|
|
"Plano de correção que distingue ajustes pontuais de mudanças maiores.",
|
|
"Implementação das correções ou acompanhamento do seu time, conforme a contratação. As metas de desempenho partem de medições do seu site.",
|
|
],
|
|
examples: [
|
|
"Investigar por que uma página demora a abrir no celular.",
|
|
"Corrigir navegação e informações de páginas que não são interpretadas corretamente pelos buscadores.",
|
|
"Ajudar uma equipe a incluir novas funções sem tornar o sistema mais difícil de manter.",
|
|
],
|
|
process: [
|
|
"Você apresenta os sintomas, o objetivo e os acessos necessários para a análise.",
|
|
"Investigo o projeto e explico as causas encontradas e suas consequências.",
|
|
"Combinamos prioridades e o formato: diagnóstico, correções ou apoio ao time.",
|
|
"Reavaliamos os fluxos alterados e registramos as orientações de continuidade.",
|
|
],
|
|
technicalDetails: [
|
|
"Revisão de App Router, fronteiras entre Server e Client Components, estratégias de renderização, cache e busca de dados.",
|
|
"Investigação de Core Web Vitals, tamanho do JavaScript, imagens e requisições; correções são comparadas com medições do cenário afetado.",
|
|
"Auditoria de metadados, canônicas, sitemap, dados estruturados e links internos, preservando URLs e requisitos de indexação nas mudanças.",
|
|
],
|
|
stack: ["Next.js", "React", "TypeScript", "Tailwind", "SEO técnico"],
|
|
ctaLabel: "Conversar sobre meu projeto Next.js",
|
|
relatedCaseIds: ["sev-modaintima", "lavacao-047", "sc-plus"],
|
|
faq: [
|
|
{
|
|
question: "Não sei se meu site usa Next.js. Posso conversar?",
|
|
answer:
|
|
"Sim. Traga o endereço do site e o problema percebido. Identificamos o contexto e se essa consultoria é adequada antes de combinar uma análise mais profunda.",
|
|
},
|
|
{
|
|
question: "A consultoria inclui corrigir o código?",
|
|
answer:
|
|
"Pode incluir. Um diagnóstico pontual, a implementação das correções e o acompanhamento de um time são formatos diferentes. A proposta informa quais deles entram e como a entrega será avaliada.",
|
|
},
|
|
{
|
|
question: "Precisa substituir o site inteiro?",
|
|
answer:
|
|
"Não necessariamente. A análise busca a causa do problema e o menor conjunto de mudanças que atende ao objetivo. Uma migração só é recomendada quando os benefícios e os riscos justificam o trabalho.",
|
|
},
|
|
],
|
|
},
|
|
{
|
|
slug: "tauri-rust",
|
|
navLabel: "Aplicativos desktop para Windows e Linux",
|
|
eyebrow: "Aplicativos desktop",
|
|
seoTitle: "Aplicativos Desktop para Windows e Linux com Tauri e Rust",
|
|
metaDescription:
|
|
"Aplicativo desktop para Windows e Linux que automatiza tarefas no computador da sua empresa. Desenvolvedor em Garuva-SC, com atendimento em Joinville e remoto no Brasil.",
|
|
headline: "Aplicativos para Windows e Linux.",
|
|
answer:
|
|
"Desenvolvo aplicativos desktop para trabalhar no computador, lidar com arquivos e integrar recursos locais. Windows e Linux são as plataformas atendidas; as versões e distribuições compatíveis são combinadas em cada projeto.",
|
|
intro:
|
|
"Crie uma ferramenta para Windows ou Linux: organize arquivos, execute rotinas locais ou conecte o computador aos sistemas da empresa.",
|
|
audience: [
|
|
"Empresas que precisam de uma ferramenta instalada, em vez de depender apenas do navegador.",
|
|
"Equipes que trabalham com arquivos, processamento local ou recursos do computador.",
|
|
"Produtos que precisam avaliar uma aplicação desktop nova ou a evolução de uma ferramenta existente.",
|
|
],
|
|
outcomes: [
|
|
"Uma interface para executar as tarefas locais prioritárias e entender o resultado de cada operação.",
|
|
"Compatibilidade combinada para Windows e/ou Linux, incluindo versões, distribuições e dependências necessárias.",
|
|
"Instalação, atualizações, permissões e uso sem internet combinados no projeto. Cada plataforma é testada separadamente.",
|
|
],
|
|
examples: [
|
|
"Um aplicativo para conferir e organizar arquivos antes de enviá-los a outro sistema.",
|
|
"Uma ferramenta interna que executa uma rotina no computador e mostra seu andamento.",
|
|
"Uma interface local para acessar dados ou recursos que não estão disponíveis em um site comum.",
|
|
],
|
|
process: [
|
|
"Entendemos a tarefa e confirmamos se um aplicativo instalado faz mais sentido que um sistema web.",
|
|
"Definimos Windows e/ou Linux, ambientes de uso, acesso a arquivos e integrações necessárias.",
|
|
"Construímos e demonstramos os fluxos principais nos ambientes combinados.",
|
|
"Validamos instalação e operação e entregamos as instruções e a estratégia de atualização acordadas.",
|
|
],
|
|
technicalDetails: [
|
|
"Tauri conecta uma interface web a comandos nativos em Rust. Permissões e acesso a arquivos devem ser limitados ao necessário, com validação na fronteira entre interface e sistema.",
|
|
"Empacotamento e dependências variam por sistema, então cada integração nativa é testada no Windows e no Linux.",
|
|
],
|
|
stack: [
|
|
"Tauri",
|
|
"Rust",
|
|
"TypeScript",
|
|
"Aplicativos desktop",
|
|
"Integração com o sistema",
|
|
],
|
|
ctaLabel: "Conversar sobre meu aplicativo desktop",
|
|
relatedCaseIds: [],
|
|
faq: [
|
|
{
|
|
question: "O mesmo aplicativo pode funcionar em Windows e Linux?",
|
|
answer:
|
|
"Sim, desde que os dois entrem no projeto. Versões do Windows, distribuições Linux, recursos locais e dependências são definidos e testados separadamente.",
|
|
},
|
|
{
|
|
question: "O aplicativo funciona sem internet?",
|
|
answer:
|
|
"As funções locais podem funcionar sem internet. Login remoto, sincronização e serviços externos continuam precisando de conexão. Vemos cada caso na conversa inicial.",
|
|
},
|
|
{
|
|
question: "Como o aplicativo é instalado e atualizado?",
|
|
answer:
|
|
"A forma de instalação e de atualização é combinada no projeto, conforme o ambiente de uso: Windows, Linux ou os dois.",
|
|
},
|
|
],
|
|
},
|
|
{
|
|
slug: "integracao-hardware-software-iot",
|
|
navLabel: "Integração de equipamentos e sistemas",
|
|
eyebrow: "Hardware, software e IoT",
|
|
seoTitle: "Integração de Equipamentos e Sistemas (IoT) em Santa Catarina",
|
|
metaDescription:
|
|
"Leve os dados dos seus equipamentos para um painel e acompanhe a operação sem anotações manuais. Desenvolvedor em Garuva-SC, com atendimento em Joinville e remoto no Brasil.",
|
|
headline: "Dados dos equipamentos no seu sistema.",
|
|
answer:
|
|
"Conecto equipamentos e software para transformar leituras e eventos em informação útil para a operação. Primeiro vemos o que cada dispositivo permite acessar; a integração segue essas interfaces e os requisitos de segurança e funcionamento.",
|
|
intro:
|
|
"Leve informações de equipamentos para um sistema ou painel. Acompanhe leituras e eventos sem depender apenas de registros manuais.",
|
|
audience: [
|
|
"Operações que registram manualmente informações disponíveis em sensores ou equipamentos.",
|
|
"Empresas que precisam reunir dados físicos e informações de seus sistemas.",
|
|
"Equipes que querem avaliar a viabilidade de um produto conectado antes de ampliar o projeto.",
|
|
],
|
|
outcomes: [
|
|
"Um caminho definido entre a informação do equipamento e a tela de quem precisa usá-la.",
|
|
"Tratamento combinado para falta de conexão, leituras inválidas e outras falhas relevantes.",
|
|
"O trabalho parte dos protocolos, da documentação e do acesso ao equipamento. Compra de hardware, instalação física e certificações são tratadas à parte.",
|
|
],
|
|
examples: [
|
|
"Um painel para consultar leituras de sensores compatíveis.",
|
|
"Um registro de eventos de uma máquina para apoiar o acompanhamento da operação.",
|
|
"Uma prova de conceito para verificar se um equipamento consegue trocar dados com o sistema existente.",
|
|
],
|
|
process: [
|
|
"Mapeamos equipamentos, dados disponíveis e a decisão que essas informações precisam apoiar.",
|
|
"Verificamos documentação, formas de conexão e limites do ambiente.",
|
|
"Implementamos um fluxo delimitado e avaliamos as falhas relevantes com os acessos combinados.",
|
|
"Entregamos instruções de operação, limites conhecidos e próximos passos.",
|
|
],
|
|
technicalDetails: [
|
|
"A descoberta identifica APIs, arquivos, portas seriais ou protocolos expostos pelo equipamento; a escolha depende da interface realmente disponível.",
|
|
"Contratos de dados, validação, persistência, reconexão e rastreamento de falhas organizam o fluxo entre dispositivo, backend e painel. WebSockets entram apenas quando há necessidade de atualização contínua.",
|
|
"O Twins Lab, protótipo de laboratório, simula um reator e envia o estado dele a um painel a cada dois segundos, por eventos do servidor.",
|
|
],
|
|
stack: ["IoT", "WebSockets", "APIs", "Painéis", "Integração de sistemas"],
|
|
ctaLabel: "Avaliar minha integração",
|
|
relatedCaseIds: ["twins-lab"],
|
|
faq: [
|
|
{
|
|
question: "Qualquer equipamento pode ser conectado?",
|
|
answer:
|
|
"Depende do equipamento. Precisamos saber quais dados e interfaces ele disponibiliza, se há documentação e quais restrições existem no ambiente. Fazemos essa avaliação antes de fechar o projeto.",
|
|
},
|
|
{
|
|
question: "É necessário trocar os sistemas existentes?",
|
|
answer:
|
|
"Nem sempre. Podemos avaliar uma camada de integração que aproveita o que já funciona. O caminho depende das interfaces disponíveis, da confiabilidade exigida e dos riscos para a operação.",
|
|
},
|
|
{
|
|
question: "É possível começar pequeno?",
|
|
answer:
|
|
"Sim. Um equipamento, uma leitura ou um fluxo já permite validar a ideia antes de ampliar o projeto. Os critérios dessa primeira etapa são combinados antes de começar.",
|
|
},
|
|
],
|
|
},
|
|
{
|
|
slug: "arquitetura-de-software",
|
|
navLabel: "Diagnóstico e arquitetura de software",
|
|
eyebrow: "Diagnóstico e decisão",
|
|
seoTitle:
|
|
"Diagnóstico e Arquitetura de Software para Decidir com Segurança",
|
|
metaDescription:
|
|
"Entenda por que seu sistema ficou difícil de mudar e decida o que corrigir, manter ou trocar. Diagnóstico com plano de ação, de Garuva-SC para Joinville e todo o Brasil.",
|
|
headline: "Entenda o problema antes de mudar tudo.",
|
|
answer:
|
|
"Analiso como um sistema está organizado e por que ficou difícil de manter ou evoluir. Você recebe um diagnóstico explicado, prioridades e um plano de mudança para decidir o que corrigir, preservar ou substituir.",
|
|
intro:
|
|
"Quando cada mudança no sistema vira um problema, obtenha um diagnóstico e um plano para evoluir sem decidir no escuro ou reescrever tudo por impulso.",
|
|
audience: [
|
|
"Empresas que dependem de um sistema e não conseguem entender o custo ou o risco das mudanças.",
|
|
"Equipes que enfrentam falhas recorrentes, integrações frágeis ou dificuldade para entregar novas funções.",
|
|
"Responsáveis por um produto que precisam comparar caminhos antes de investir numa migração.",
|
|
],
|
|
outcomes: [
|
|
"Um mapa dos problemas encontrados e de como afetam o produto e a operação.",
|
|
"Alternativas com benefícios, limitações e riscos explicados para apoiar a decisão.",
|
|
"Plano de execução por prioridades; implementar as mudanças ou acompanhar o time depende do formato contratado.",
|
|
],
|
|
examples: [
|
|
"Investigar por que alterar uma função provoca falhas em outras partes do sistema.",
|
|
"Comparar manter, modernizar aos poucos ou substituir uma ferramenta antiga.",
|
|
"Organizar um plano para conectar novos sistemas sem aumentar a confusão da operação.",
|
|
],
|
|
process: [
|
|
"Conversamos com quem usa e mantém o sistema e reunimos os acessos e materiais necessários.",
|
|
"Analiso a base e os fluxos relevantes para o problema, sem ampliar a investigação sem motivo.",
|
|
"Apresento o diagnóstico e comparo as alternativas com o time e os responsáveis pelo negócio.",
|
|
"Entrego o plano priorizado e, se combinado, acompanho sua execução.",
|
|
],
|
|
technicalDetails: [
|
|
"Análise de dependências, fronteiras entre módulos, contratos de API, fluxos de dados e pontos de falha para localizar acoplamento e riscos.",
|
|
"A arquitetura proposta considera carga, consistência de dados, operação, segurança e capacidade real do time, evitando distribuir um sistema sem necessidade.",
|
|
"Migrações são divididas em etapas verificáveis, com estratégia de transição e reversão quando aplicável. As decisões ficam registradas com seus prós e contras, não apenas em um diagrama final.",
|
|
],
|
|
stack: [
|
|
"Arquitetura de software",
|
|
"APIs",
|
|
"Desempenho",
|
|
"Integrações",
|
|
"Sistemas críticos",
|
|
],
|
|
ctaLabel: "Conversar sobre um diagnóstico",
|
|
relatedCaseIds: ["sev-modaintima"],
|
|
faq: [
|
|
{
|
|
question: "Preciso ter uma equipe técnica para contratar?",
|
|
answer:
|
|
"Não, mas a análise precisa de acesso ao sistema e às pessoas ou materiais que expliquem seu funcionamento. O resultado é apresentado com consequências para o negócio e detalhes que uma equipe técnica possa usar.",
|
|
},
|
|
{
|
|
question: "O diagnóstico sempre recomenda reescrever o sistema?",
|
|
answer:
|
|
"Não. Preservar o que funciona e mudar pontos específicos pode ser o caminho mais adequado. As alternativas são comparadas com base nos problemas observados, nos riscos e na capacidade de executar a mudança.",
|
|
},
|
|
{
|
|
question: "O que é entregue ao final?",
|
|
answer:
|
|
"Um diagnóstico documentado com problemas, prioridades, alternativas e plano de mudança para o escopo analisado. Profundidade, reuniões e eventual acompanhamento da implementação são definidos na proposta.",
|
|
},
|
|
],
|
|
},
|
|
];
|
|
|
|
export const caseStudies: CaseStudyContent[] = [
|
|
{
|
|
id: "sev-modaintima",
|
|
title: "SEV Moda Íntima",
|
|
subtitle: "Catálogo digital e loja virtual",
|
|
headline: "Loja virtual de moda íntima com pedido direto pelo WhatsApp",
|
|
summary:
|
|
"Catálogo digital e loja virtual de moda íntima. A cliente encontra o produto, escolhe o tamanho e envia o pedido pelo WhatsApp. A loja cuida de tudo em um painel próprio.",
|
|
impact:
|
|
"A cliente encontra o produto e envia o pedido pelo WhatsApp; a loja controla produtos, estoque e pedidos em um painel.",
|
|
context:
|
|
"A SEV Moda Íntima vende moda íntima pela internet. O site funciona como vitrine e loja virtual: apresenta os produtos, recebe os pedidos pelo WhatsApp e dá à loja um painel para cuidar do catálogo.",
|
|
problem:
|
|
"Uma loja de moda íntima tem muitos produtos, em vários modelos e tamanhos. A cliente precisa achar o que procura com facilidade e fechar o pedido sem complicação. A loja precisa manter catálogo, estoque e pedidos organizados.",
|
|
deliveries: [
|
|
"Uma vitrine com animações que dão destaque aos produtos e deixam a navegação agradável.",
|
|
"Filtros e busca inteligente: a cliente encontra o que procura e os itens mais relevantes aparecem primeiro.",
|
|
"Pedido pelo WhatsApp: a cliente escolhe os produtos no site e envia o pedido para a loja.",
|
|
"Frete calculado pela distância até o endereço da cliente.",
|
|
"Painel administrativo para a loja cadastrar produtos, acompanhar pedidos e controlar o estoque.",
|
|
"Estoque controlado por tamanho, para cada medida ter a sua quantidade.",
|
|
],
|
|
stack: [
|
|
"Next.js 16",
|
|
"TypeScript",
|
|
"PostgreSQL",
|
|
"Prisma",
|
|
"Tailwind CSS 4",
|
|
"Framer Motion",
|
|
],
|
|
decisions: [
|
|
"A busca usa ranking de relevância e vários filtros combinados.",
|
|
"O cálculo de frete usa geocodificação híbrida para chegar à distância entre loja e cliente.",
|
|
"A vitrine tem modo escuro e animações com Framer Motion.",
|
|
"A área administrativa cobre produtos, estoque e pedidos.",
|
|
],
|
|
demoUrl: "https://sevmodaintima.com.br",
|
|
},
|
|
{
|
|
id: "lavacao-047",
|
|
title: "Lavação 047",
|
|
subtitle: "Site e painel para lavação automotiva",
|
|
headline:
|
|
"Site com tabela de preços e pedido pelo WhatsApp para uma lavação em Garuva",
|
|
summary:
|
|
"Site da Lavação 047, em Garuva-SC. O cliente vê o preço pelo porte do veículo e pede o serviço pelo WhatsApp com a mensagem já pronta. O dono edita preços, textos e fotos sozinho.",
|
|
impact:
|
|
"O cliente descobre o preço e pede pelo WhatsApp; o dono atualiza o site sem depender de um desenvolvedor.",
|
|
context:
|
|
"A Lavação 047 é uma lavação automotiva em Garuva, Santa Catarina. O site apresenta os serviços, a tabela de preços e a localização, e leva o cliente direto para o WhatsApp.",
|
|
problem:
|
|
"Quem procura uma lavação quer saber quanto custa para o seu veículo e como chegar. O dono, por sua vez, precisa manter preços, textos e fotos em dia sem depender de alguém a cada mudança.",
|
|
deliveries: [
|
|
"Tabela de preços por porte do veículo: o cliente vê quanto paga pelo seu carro.",
|
|
"Pedido pelo WhatsApp com mensagem pronta: um toque abre a conversa já com o serviço escolhido.",
|
|
"Painel do dono: ele altera preços, textos, fotos e o mapa sozinho, e a mudança aparece no site sem nova publicação.",
|
|
"Galeria de trabalhos por serviço, para o cliente ver o resultado antes de chamar.",
|
|
"Mapa de localização, para o cliente achar a lavação.",
|
|
"Uma animação de rolagem que leva o carro do sujo ao brilho e perguntas frequentes montadas com os dados reais do negócio.",
|
|
"Informações organizadas para o Google e para assistentes de IA entenderem o que a lavação faz e onde fica.",
|
|
],
|
|
stack: [
|
|
"Next.js 16",
|
|
"React 19",
|
|
"TypeScript",
|
|
"Tailwind CSS 4",
|
|
"Motion",
|
|
"Upstash Redis",
|
|
"Vercel Blob",
|
|
],
|
|
decisions: [
|
|
"O conteúdo salvo no painel alimenta a página, os dados estruturados, o sitemap e o cartão de compartilhamento.",
|
|
"Conteúdo e imagens ficam guardados em Redis e em armazenamento privado, com arquivo local como alternativa.",
|
|
"A animação respeita a preferência do sistema por menos movimento.",
|
|
"O mapa de localização usa OpenStreetMap.",
|
|
],
|
|
demoUrl: "https://landing-page-lavacao047.vercel.app",
|
|
},
|
|
{
|
|
id: "nutriscan",
|
|
title: "NutriScan",
|
|
subtitle: "Consulta de produtos por nome e código de barras",
|
|
headline: "Consulta de alimentos por nome ou código de barras",
|
|
summary:
|
|
"Aplicação web para consultar produtos alimentícios por nome ou código de barras, combinando um cache próprio com a base pública Open Food Facts.",
|
|
impact:
|
|
"A consulta encontra o produto por nome ou código e só vai à base externa quando precisa.",
|
|
context:
|
|
"Projeto próprio, criado para estudar a integração com uma base pública de alimentos. Está no ar para quem quiser testar.",
|
|
problem:
|
|
"As informações dos produtos vêm de uma base pública externa. O desafio era não depender só dela a cada consulta e deixar claros dois caminhos: buscar pelo nome e consultar pelo código de barras.",
|
|
deliveries: [
|
|
"Busca por nome ou por código de barras.",
|
|
"As consultas passam primeiro pelo cache próprio e só vão à base externa quando faltam resultados, o que reduz a dependência dela.",
|
|
"O código de barras é validado (de 8 a 13 dígitos) antes da consulta, para evitar buscas inválidas.",
|
|
"Se a base externa demora mais de oito segundos, a consulta é cancelada e a pessoa não fica esperando.",
|
|
],
|
|
stack: ["Next.js", "TypeScript", "Cache JSON", "Open Food Facts"],
|
|
decisions: [
|
|
"A busca consulta o cache primeiro, tem um modo somente-cache e recorre ao Open Food Facts quando faltam resultados.",
|
|
"A consulta por código remove caracteres não numéricos, aceita de 8 a 13 dígitos, consulta o cache e usa a base externa se não achar.",
|
|
"A camada de acesso à base externa cancela requisições após oito segundos e separa a busca por nome da busca por código.",
|
|
],
|
|
demoUrl: "https://nutriscan.evandro.dev.br",
|
|
},
|
|
{
|
|
id: "twins-lab",
|
|
title: "Twins Lab",
|
|
subtitle: "Protótipo de laboratório de gêmeo digital industrial",
|
|
headline:
|
|
"Painel ao vivo para acompanhar a simulação de um reator industrial",
|
|
summary:
|
|
"Protótipo de gêmeo digital industrial: um simulador de reator envia seu estado a um painel com acesso por login, atualizado a cada dois segundos.",
|
|
impact:
|
|
"O estado do reator simulado chega ao painel sozinho, só para quem tem acesso, e o histórico fica guardado.",
|
|
context:
|
|
"Projeto próprio, um protótipo de laboratório para explorar como os dados de um processo físico chegam a uma tela. O reator é simulado.",
|
|
problem:
|
|
"Como levar o estado de um processo físico para uma tela, mostrar só a quem tem acesso e manter o histórico do que aconteceu?",
|
|
deliveries: [
|
|
"Acesso por login: só quem está autenticado abre o painel.",
|
|
"O estado do reator chega à tela sozinho, a cada dois segundos, sem recarregar a página.",
|
|
"Dados e estado do simulador ficam guardados no banco, o que mantém o histórico.",
|
|
"Quando a execução ou o cenário muda, todos os painéis abertos são avisados.",
|
|
],
|
|
stack: ["Next.js", "TypeScript", "NextAuth", "MongoDB", "SSE"],
|
|
decisions: [
|
|
"A rota exige sessão do NextAuth antes de abrir a transmissão de eventos.",
|
|
"A resposta usa text/event-stream (SSE), envia estados, dados e erros em intervalos de dois segundos e limita a conexão a dez minutos.",
|
|
"O simulador salva dados e estado no MongoDB e notifica os clientes quando a execução ou o cenário mudam.",
|
|
],
|
|
},
|
|
{
|
|
id: "reddit-explorer",
|
|
title: "Reddit Posts Explorer",
|
|
subtitle: "Posts do r/artificial em MongoDB, filtrados por período",
|
|
headline:
|
|
"Posts de um fórum de inteligência artificial, coletados e filtrados por período",
|
|
summary:
|
|
"Aplicação que coleta os posts em alta do r/artificial, guarda tudo no MongoDB sem duplicar e permite filtrar por período e ordenar por votos ou comentários.",
|
|
impact:
|
|
"Rodar a coleta de novo atualiza os posts que já existem, sem duplicar, e o histórico pode ser consultado por datas.",
|
|
context:
|
|
"Projeto próprio, feito para estudar a coleta de dados de uma API pública e a consulta por período.",
|
|
problem:
|
|
"Os posts em alta mudam o tempo todo. O desafio era coletar de novo sem duplicar o que já estava guardado e consultar o histórico por datas e por popularidade.",
|
|
deliveries: [
|
|
"Coleta dos posts em alta do r/artificial pela API pública do Reddit.",
|
|
"Cada post é guardado uma vez só: coletar de novo atualiza o que já existe em vez de duplicar.",
|
|
"Filtro por período e ordenação por votos ou comentários.",
|
|
"A consulta confere as datas e a ordenação e avisa quando os parâmetros estão errados.",
|
|
],
|
|
stack: ["Astro", "MongoDB", "Mongoose", "TypeScript", "API do Reddit"],
|
|
decisions: [
|
|
"O serviço consulta r/artificial/hot.json com identificação própria e limite de 15 segundos, e grava os posts em lote com atualização pelo id.",
|
|
"O endpoint de filtro valida as datas e o campo de ordenação (votos ou comentários) e responde com erro 400 quando faltam parâmetros ou eles são inválidos.",
|
|
"O Astro roda com saída de servidor e o adaptador Node em modo standalone.",
|
|
],
|
|
},
|
|
{
|
|
id: "sc-plus",
|
|
title: "SC Plus Aquicultura",
|
|
subtitle: "Página institucional",
|
|
headline:
|
|
"Página institucional para a SC Plus Aquicultura ser encontrada na internet",
|
|
summary:
|
|
"Página institucional da SC Plus Aquicultura, com apresentação da instituição, áreas e projetos, apoiadores e contato, preparada para os buscadores e para o compartilhamento.",
|
|
impact:
|
|
"A instituição ganhou uma página própria, preparada para ser encontrada nos buscadores.",
|
|
context:
|
|
"A SC Plus Aquicultura é uma instituição do setor de aquicultura. Ela precisava de uma página própria para se apresentar, mostrar suas áreas de atuação e seus projetos e receber contato.",
|
|
problem:
|
|
"Sem uma página própria, quem procura a SC Plus na internet não encontra uma apresentação clara do que a instituição faz. Faltava um endereço próprio, com as áreas, os projetos, os apoiadores e o contato.",
|
|
deliveries: [
|
|
"Uma página própria que apresenta a instituição, as áreas de atuação e os projetos.",
|
|
"Uma seção de apoiadores e de participação, para quem quer apoiar ou participar.",
|
|
"Contato direto na própria página.",
|
|
"Título, descrição e imagem de compartilhamento próprios, para o link aparecer bem nos buscadores e nas redes.",
|
|
"Dados estruturados que ajudam o Google a entender de quem é a página.",
|
|
],
|
|
stack: ["Next.js 15", "React 19", "Tailwind CSS 4", "TypeScript"],
|
|
decisions: [
|
|
"A página publica título, descrição, endereço canônico e imagem de compartilhamento.",
|
|
"Os dados estruturados descrevem a instituição para os buscadores.",
|
|
],
|
|
demoUrl: "https://scplus.evandro.dev.br",
|
|
},
|
|
{
|
|
id: "gcc-installer",
|
|
title: "MinGW GCC Installer",
|
|
subtitle: "Instalador gráfico de MinGW-w64/GCC para Windows",
|
|
headline: "Instalador do compilador GCC para Windows em uma única janela",
|
|
summary:
|
|
"Aplicativo para Windows que lista as versões do MinGW-w64, baixa a escolhida, instala em C:\\mingw64 e deixa o GCC pronto para uso, tudo em uma janela.",
|
|
impact:
|
|
"Escolher a versão, baixar, extrair e ajustar o PATH deixam de ser passos manuais: tudo acontece em uma janela.",
|
|
context:
|
|
"Projeto próprio, criado para resolver uma tarefa repetitiva de quem programa no Windows: instalar o compilador GCC.",
|
|
problem:
|
|
"Instalar o GCC no Windows exige vários passos manuais: escolher a versão, baixar, extrair os arquivos e configurar o PATH do sistema.",
|
|
deliveries: [
|
|
"Lista as versões publicadas do MinGW-w64 e destaca as mais usadas (ucrt e posix).",
|
|
"Baixa o pacote escolhido e instala na pasta C:\\mingw64.",
|
|
"Configura o PATH do usuário e avisa o Windows da mudança, para o GCC funcionar sem ajustes manuais.",
|
|
"Deixa o comando make disponível, renomeando o mingw32-make.exe.",
|
|
],
|
|
stack: ["Python", "Tkinter", "Win32 API", "GitHub API", "7-Zip"],
|
|
decisions: [
|
|
"A lista de versões vem da API de releases do repositório niXman/mingw-builds-binaries, e as versões com ucrt e posix aparecem em destaque na tabela.",
|
|
"A instalação extrai o pacote com o 7-Zip (no caminho padrão) em uma pasta temporária e move o resultado para C:\\mingw64.",
|
|
"Adicionar ao PATH grava em HKCU\\Environment e avisa o Windows com WM_SETTINGCHANGE.",
|
|
"Os 23 testes automatizados cobrem a lógica do núcleo, que não depende da plataforma.",
|
|
],
|
|
},
|
|
{
|
|
id: "as-servicos",
|
|
title: "AS Serviços",
|
|
subtitle: "Site institucional com cena 3D",
|
|
headline: "Site institucional com uma cena 3D que acompanha a rolagem",
|
|
summary:
|
|
"Site institucional da AS Serviços com uma cena 3D criada em código: uma casa e uma placa-mãe desenhadas em linhas que reagem à rolagem da página.",
|
|
impact:
|
|
"Engenharia física e software contados na mesma história visual, sem depender de um modelo 3D pronto.",
|
|
context:
|
|
"A AS Serviços reúne engenharia física e software. O site precisava mostrar as duas frentes na mesma história.",
|
|
problem:
|
|
"Como contar, em uma única página, duas frentes tão diferentes quanto a engenharia física e o software, de um jeito que prenda a atenção de quem rola a página?",
|
|
deliveries: [
|
|
"Uma cena 3D que acompanha a rolagem: casa, instalação elétrica e placa-mãe aparecem desenhadas em linhas.",
|
|
"As duas frentes da empresa, a física e a digital, aparecem na mesma história visual.",
|
|
"A qualidade da cena se ajusta ao aparelho: celulares, conexões mais simples e quem prefere menos movimento recebem uma versão mais leve.",
|
|
"Um painel para controle de projetos, desenvolvido junto com a primeira página do site.",
|
|
],
|
|
stack: ["Next.js 16", "Three.js", "TypeScript"],
|
|
decisions: [
|
|
"A cena é gerada em código, sem arquivo 3D pronto: o motor monta casa, instalação elétrica e placa-mãe com geometrias e linhas do Three.js.",
|
|
"O canvas converte a rolagem em um progresso de 0 a 1 e o entrega ao motor da cena.",
|
|
"A qualidade tem quatro níveis (estático, baixo, médio e alto), escolhidos conforme o WebGL, a preferência por menos movimento, a economia de dados, a conexão e a capacidade do dispositivo.",
|
|
],
|
|
demoUrl: null,
|
|
role: "Desenvolvimento da primeira landing page do site, com animações 3D, e de um painel para controle de projetos.",
|
|
},
|
|
];
|
|
|
|
/** Projetos feitos para clientes ficam à frente; os pessoais e de estudo vão para o Laboratório. */
|
|
export function isClientCase(caseStudy: { id: string }) {
|
|
const project = portfolio.projects.find(({ id }) => id === caseStudy.id);
|
|
return project ? isClientProject(project) : false;
|
|
}
|
|
|
|
export const clientCases = caseStudies.filter(isClientCase);
|
|
export const labCases = caseStudies.filter(
|
|
(caseStudy) => !isClientCase(caseStudy),
|
|
);
|
|
|
|
export const serviceHubLinks = servicePages.map((service) => ({
|
|
href: `/servicos/${service.slug}`,
|
|
label: service.navLabel,
|
|
description: service.intro,
|
|
}));
|
|
|
|
export function getServicePage(slug: string) {
|
|
return servicePages.find((service) => service.slug === slug);
|
|
}
|
|
|
|
/** Cases na ordem de `caseIds`, com os de cliente à frente dos de laboratório. */
|
|
export function getRelatedCases(caseIds: string[]) {
|
|
const cases = caseIds.flatMap((id) => {
|
|
const caseStudy = caseStudies.find((item) => item.id === id);
|
|
return caseStudy ? [caseStudy] : [];
|
|
});
|
|
return [
|
|
...cases.filter(isClientCase),
|
|
...cases.filter((caseStudy) => !isClientCase(caseStudy)),
|
|
];
|
|
}
|
|
|
|
export function getRelatedServices(caseId: string): ServicePageContent[] {
|
|
return servicePages.filter(({ relatedCaseIds }) =>
|
|
relatedCaseIds.includes(caseId),
|
|
);
|
|
}
|