Chame no Whatsapp

Post-IA-05: Uso de IA na Criação de um WebApp – Parte 3

Criando o Frontend PWA

Prompts em azul, meus comentários em verde, soluções da IA em preto, comentários da IA em marrom.

IAs Utilizadas neste Post

  • Copilot

No post parte-1 desta série, vimos as características recomendadas pela IA para um sistema de ponto inteligente bem como os requisitos legais necessários para tal sistema. enquanto que na parte-2 , concluímos que a melhor opção seria o uso de micro serviços para construir o sistema e a IA definiu a arquitetura desse sistema,listando os módulos necessários.


Neste post (parte-3), vamos pedir a IA começar a programar (UFA) . então criamos o seguinte prompt:

“Vamos começar criando o app frontend pwa. Uma vez que não teremos no começo o BackOffice, precisamos criar um fake de teste. Outra pergunta: que linguagem usaremos nesse pwa? React?.”

Excelente, Fabio! Vamos começar com o frontend PWA e sim — React é uma ótima escolha para esse projeto. Ele tem excelente suporte a PWA, uma comunidade enorme, e integra bem com bibliotecas de IA e APIs modernas como WebRTC (para câmera) e Geolocation.

🛠️ Linguagem e Stack Inicial

Frontend: React + Vite

React: para criar interfaces dinâmicas e responsivas.

Vite: para um ambiente de desenvolvimento rápido e leve (melhor que Create React App para PWAs).

Workbox: para configurar Service Workers e cache inteligente.

Tailwind CSS (opcional): para estilização rápida e moderna.


Fake BackOffice / Mock API

Como ainda não teremos o backend, vamos criar um mock de dados para simular:

Usuários cadastrados

Resultados de reconhecimento facial (simulado)

Localizações válidas

Registros de ponto

Podemos usar:

JSON Server ou MSW (Mock Service Worker) para simular chamadas HTTP

Ou simplesmente criar um arquivo local de dados e funções fake para testes


📦 Estrutura Inicial do Projeto

controle-ponto-pwa/
├── public/
│   └── manifest.json
├── src/
│   ├── assets/
│   ├── components/
│   ├── pages/
│   ├── services/         ← mock API aqui
│   ├── utils/
│   ├── App.jsx
│   └── main.jsx
├── service-worker.js     ← cache e offline
├── index.html
├── vite.config.js
└── package.json

🔮 Próximo Passo

Se quiser, posso gerar agora:

O comando para criar o projeto com Vite + React

O manifest.json inicial

E o mock de usuários e ponto para começarmos a testar a interface

Quer que eu prepare esse setup inicial agora?

Dando continuidade ao processo, criei o seguinte prompt , muito simples:

Sim. prepare esse setup inicial

Perfeito, Fabio! Vamos colocar a mão na massa e preparar o setup inicial do seu PWA com React + Vite, incluindo um mock de dados para simular o funcionamento do app enquanto o backoffice não está pronto

🧱 1. Criar o projeto com Vite + React

Abra o terminal e execute:

npm create vite@latest controle-ponto-pwa -- --template react
cd controle-ponto-pwa
npm install

📦 2. Estrutura de pastas sugerida

Dentro da pasta src/, crie a seguinte estrutura:

src/
├── assets/
├── components/
├── pages/
├── services/         ← mock API aqui
├── mocks/            ← dados simulados
├── utils/
├── App.jsx
└── main.jsx

📄 3. Manifesto do PWA (public/manifest.json)

Crie o arquivo manifest.json dentro da pasta public:

{
  "name": "Controle de Ponto Inteligente",
  "short_name": "PontoIA",
  "start_url": "/",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#0d9488",
  "icons": [
    {
      "src": "/icon-192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "/icon-512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ]
}

🧪 4. Mock de dados (src/mocks/fakeData.js)

export const fakeUsers = [
  { id: 1, name: "Ana Souza", faceId: "ana123", location: [-23.993, -46.256] },
  { id: 2, name: "Carlos Lima", faceId: "carlos456", location: [-23.994, -46.257] }
];

export const fakePoints = [
  { userId: 1, timestamp: "2025-10-06T08:00:00", location: [-23.993, -46.256] },
  { userId: 2, timestamp: "2025-10-06T08:05:00", location: [-23.994, -46.257] }
];

🔧 5. Mock API (src/services/mockApi.js)

import { fakeUsers, fakePoints } from "../mocks/fakeData";

export const getUserByFaceId = (faceId) => {
  return fakeUsers.find((user) => user.faceId === faceId);
};

export const registerPoint = (userId, location) => {
  const timestamp = new Date().toISOString();
  fakePoints.push({ userId, timestamp, location });
  return { success: true, timestamp };
};

export const getUserPoints = (userId) => {
  return fakePoints.filter((point) => point.userId === userId);
};

🧠 6. Próximo passo

Agora que temos o setup inicial, podemos criar:

A tela de registro de ponto com câmera e geolocalização

A lógica de simulação de reconhecimento facial

A interface para visualizar os registros

Quer que eu comece pela tela de registro com câmera e GPS?

Vamos então inicializar o react com os comandos indicados pela IA, criar a estrutura de arquivos sugerida ,criar o manifesto do pwa , o mock de dados e a api mock.


Apanhei um pouco pois meu node estava desatualizado. Tive então que instalar o nvm e instalar a nova versão do node:

Fiz o download do nvm e executei o setup

# Download from: https://github.com/coreybutler/nvm-windows/releases

Obtuve a versão 22.12 do node dei os comandos sugeridos pela AI:

npm create vite@latest controle-ponto-pwa -- --template react
cd controle-ponto-pwa
npm install

A seguir, criei a estrutura de arquivos proposta

Após isso pronto,emitimos um prompt pedindo a IA para criar a tela de registro com câmera e GPS.

“Crie a tela de registro de ponto com câmera e GPS”

“Vamos lá, Fabio! Aqui está a tela de registro de ponto para o seu PWA em React, com suporte a câmera (para simular reconhecimento facial) e geolocalização (para capturar a posição do usuário). Essa versão usa apenas APIs nativas do navegador e o mock que criamos anteriormente.”


No arquivo pages/RegistroPonto.jsx inclua o código

import { useState, useEffect, useRef } from "react";
import { getUserByFaceId, registerPoint } from "../services/mockApi";

const RegistroPonto = () => {
  const [location, setLocation] = useState(null);
  const [user, setUser] = useState(null);
  const [status, setStatus] = useState("");
  const videoRef = useRef(null);

  // Simula captura facial e localização
  const handleRegistro = async () => {
    setStatus("Capturando localização...");
    navigator.geolocation.getCurrentPosition(
      async (pos) => {
        const coords = [pos.coords.latitude, pos.coords.longitude];
        setLocation(coords);
        setStatus("Capturando imagem...");

        // Simula reconhecimento facial
        const fakeFaceId = "ana123"; // Simulação fixa
        const foundUser = getUserByFaceId(fakeFaceId);

        if (foundUser) {
          setUser(foundUser);
          const result = registerPoint(foundUser.id, coords);
          setStatus(`Ponto registrado às ${result.timestamp}`);
        } else {
          setStatus("Usuário não reconhecido.");
        }
      },
      (err) => {
        setStatus("Erro ao obter localização.");
      }
    );
  };

  // Ativa câmera
  useEffect(() => {
    navigator.mediaDevices
      .getUserMedia({ video: true })
      .then((stream) => {
        if (videoRef.current) {
          videoRef.current.srcObject = stream;
        }
      })
      .catch(() => {
        setStatus("Erro ao acessar câmera.");
      });
  }, []);

  return (
    <div className="p-4">
      <h2 className="text-xl font-bold mb-4">Registro de Ponto</h2>
      <video ref={videoRef} autoPlay className="w-full max-w-md mb-4 rounded shadow" />
      <button
        onClick={handleRegistro}
        className="bg-teal-600 text-white px-4 py-2 rounded hover:bg-teal-700"
      >
        Registrar Ponto
      </button>
      <div className="mt-4 text-sm text-gray-700">
        {status && <p>Status: {status}</p>}
        {user && (
          <p>
            Usuário: <strong>{user.name}</strong> <br />
            Localização: {location?.[0]}, {location?.[1]}
          </p>
        )}
      </div>
    </div>
  );
};

export default RegistroPonto;

No app.jsx inclua , substituindo o que foi colocado lá na instalação do vite

import RegistroPonto from "./pages/RegistroPonto";

function App() {
  return (
    <div className="min-h-screen bg-gray-100">
      <RegistroPonto />
    </div>
  );
}

export default App;

Isso vai fazer com que o app carregue diretamente a tela de registro de ponto ao iniciar.

Se quiser manter o conteúdo original como referência ou criar uma navegação entre páginas no futuro, podemos usar React Router. Mas para começar simples e direto, essa substituição funciona perfeitamente.

Quer que eu te ajude a configurar o RegistroPonto.jsx com estilos usando Tailwind ou seguir para a simulação do reconhecimento facial com uma biblioteca real?

O App PWA ControlePonto.jsx proposto pela IA está sem formatação de estilo e o Copilot está sugerindo formatar usando o tailwind antes de seguir para a simulação do reconhecimento facial.

O tailwind é mais simples que o CSS, pois é colocado diretamente no html, sendo uma forma rápida de criar uma formatação profissional.

No caso de programação com IA é preferível devido aos seguintes motivos:

  • Desenvolvimento Acelerado – Classes utilitárias permitem prototipagem rápida, ideal para iterações ágeis em projetos de IA.
  • Consistência Visual – Sistema de design integrado mantém a interface coesa durante mudanças frequentes.
  • Baixa Curva de Aprendizado – Sintaxe simples facilita a adoção por times multidisciplinares de IA/desenvolvimento.
  • Performance Nativa – CSS é purgado automaticamente, removendo estilos não utilizados.
  • Responsividade Intuitiva – Prefixos como md: e lg: simplificam designs adaptativos complexos.
  • Manutenção Simplificada – Elimina conflitos de CSS em aplicações dinâmicas com componentes mutáveis.
  • Customização Sistêmica – Configuração centralizada permite ajustes globais que se propagam consistentemente.
  • Interoperabilidade – Integra-se bem com principais frameworks JavaScript usados em projetos de IA.
  • Iteração Visual Rápida – Alterações de estilo diretas no HTML agilizam experimentações de UI/UX.
  • Documentação Rica – Referência completa acelera resolução de problemas de layout.
  • Community Support – Ecossistema ativo oferece soluções para desafios comuns de interface.
  • Acessibilidade Integrada – Utilitários para focus states, screen readers e contrastes.
  • Estado Dinâmico – Facilita estilização condicional baseada em estados da IA.
  • Escalabilidade – Gestão eficiente de estilos em aplicações que evoluem rapidamente.
  • Foco no Core – Reduz tempo em decisões de CSS para concentrar esforços na lógica de IA.

Dessa forma, usaremos tailwind ao invés de CSS. Mas como estou ansioso para ver o programa funcionar, vou inverter a sugestão da IA e no próximo post vou pôr para funcionar essa versão que está aí e só então instalar o tailwind e solicitar a AI nos ajudar, criando estilos de boa aparência.

Então pessoal até lá….

Referências