Mensagem Completa para o Programador (Parte 01)
Assunto: Integração Módulo de Autenticação, Trial e Pagamento — ROTAFÁCIL GPS (Parte 01)
Olá! Segue abaixo o contexto do projeto, a estrutura base e a lógica da Parte 01 do nosso sistema (ROTAFÁCIL GPS).
1. Contexto do Projeto & Integração das Partes
Nosso sistema está dividido em duas partes/módulos independentes que serão unificados:
- Parte 01 (Sua parte): Autenticação de usuários, controle do trial de 15 dias, gestão de assinaturas/bloqueio via InfinitePay e controle de sessão/dispositivos.
- Parte 02 (Desenvolvida em paralelo): O aplicativo do Roteirizador com GPS, navegação e manipulação de endereços.
Seu Objetivo de Integração: O seu código (Parte 01) deve atuar como a "camada de entrada e proteção" do sistema. Após o usuário fazer o login e ter o acesso validado (por estar no trial ou com a mensalidade em dia), ele deve ter o acesso liberado para a Parte 02 (o roteirizador).
2. Regras de Negócio e Diretrizes
- Branding: ROTAFÁCIL GPS — "De um entregador para entregadores. Simples e fácil de usar."
- Link de Pagamento (InfinitePay): [https://invoice.infinitepay.io/alexandre-morche/ITaZ64Sot8](https://invoice.infinitepay.io/alexandre-morche/ITaZ64Sot8)
- Valor da Assinatura: R$ 25,00 / mês.
- Período de Teste (Trial): Todo novo usuário cadastrado ganha 15 dias grátis a partir da data de criação da conta no banco de dados.
Sincronização e Regra de Dispositivos:
- Até 2 Dispositivos por Conta: A mesma conta pode estar logada em até 2 dispositivos (ex: celular do entregador no suporte e um segundo aparelho/tablet).
- Sincronização de Lista de Endereços: O usuário precisa conseguir cadastrar/carregar a lista de endereços em um celular e ter essa mesma lista atualizada e pronta para navegação na "rota atual" do outro celular (via banco de dados / Supabase Realtime).
- Trava de Navegação Ativa: Embora permita 2 aparelhos logados para carga de dados, a navegação ativa no GPS/rota deve funcionar em apenas 1 dispositivo por vez.
3. Lógica de Validação e Bloqueio
O fluxo da Parte 01 deve consultar no Supabase se:
- O usuário está dentro do prazo de 15 dias grátis (data_criacao + 15 dias >= data_atual); OU
- O usuário possui uma assinatura paga ativa (pago_ate >= data_atual).
- Se SIM: Concede permissão e redireciona/carrega a interface do Roteirizador (Parte 02).
- Se NÃO (Expirou): Oculta a interface principal e exibe a tela de bloqueio com o aviso de vencimento e o botão para pagamento de R$ 25,00 apontando para o link da InfinitePay.
4. Código Base de Referência (index.html)
Você pode usar a estrutura abaixo como ponto de partida para integrar com o Supabase:
Código Base da Parte 01 (index.html)
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ROTAFÁCIL GPS - Login & Acesso</title>
<!-- Supabase JS Client -->
<script src="https://cdn.jsdelivr.net/npm/@supabase/supabase-js@2"></script>
<style>
:root {
--bg-color: #121212;
--card-bg: #1e1e1e;
--primary: #22c55e;
--primary-hover: #16a34a;
--text: #ffffff;
--text-muted: #a1a1aa;
--danger: #ef4444;
}
* { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; }
body { background-color: var(--bg-color); color: var(--text); display: flex; align-items: center; justify-content: center; min-height: 100vh; padding: 20px; }
.container { background-color: var(--card-bg); width: 100%; max-width: 400px; padding: 30px; border-radius: 12px; box-shadow: 0 10px 25px rgba(0,0,0,0.5); text-align: center; }
.logo { font-size: 24px; font-weight: bold; color: var(--primary); margin-bottom: 8px; }
.slogan { font-size: 13px; color: var(--text-muted); margin-bottom: 24px; }
.input-group { margin-bottom: 16px; text-align: left; }
.input-group label { display: block; font-size: 12px; color: var(--text-muted); margin-bottom: 6px; }
.input-group input { width: 100%; padding: 12px; border-radius: 6px; border: 1px solid #333; background: #2a2a2a; color: var(--text); outline: none; }
.input-group input:focus { border-color: var(--primary); }
.btn { width: 100%; padding: 12px; border: none; border-radius: 6px; background-color: var(--primary); color: #000; font-weight: bold; cursor: pointer; transition: 0.2s; font-size: 15px; }
.btn:hover { background-color: var(--primary-hover); }
.btn-pay { background-color: #3b82f6; color: white; text-decoration: none; display: block; text-align: center; margin-top: 15px; }
.btn-pay:hover { background-color: #2563eb; }
.hidden { display: none; }
.status-box { padding: 12px; border-radius: 6px; margin-bottom: 16px; font-size: 14px; }
.status-expired { background-color: rgba(239, 68, 68, 0.1); border: 1px solid var(--danger); color: var(--danger); }
</style>
</head>
<body>
<div class="container" id="auth-card">
<div class="logo">ROTAFÁCIL GPS</div>
<div class="slogan">De um entregador para entregadores. Simples e fácil de usar.</div>
<!-- TELA DE LOGIN / REGISTO -->
<form id="login-form">
<div class="input-group">
<label for="email">E-mail</label>
<input type="email" id="email" placeholder="seu@email.com" required>
</div>
<div class="input-group">
<label for="password">Senha</label>
<input type="password" id="password" placeholder="******" required>
</div>
<button type="submit" class="btn">Entrar / Cadastrar</button>
</form>
<!-- TELA DE BLOQUEIO DE PAGAMENTO (EXIBIDA SE TRIAL/MENSALIDADE EXPIRAR) -->
<div id="payment-screen" class="hidden">
<div class="status-box status-expired">
Seu período de teste ou assinatura expirou!
</div>
<p style="font-size: 14px; color: var(--text-muted); margin-bottom: 15px;">
Para continuar utilizando o ROTAFÁCIL GPS por +30 dias, realize a renovação de R$ 25,00.
</p>
<a href="https://invoice.infinitepay.io/alexandre-morche/ITaZ64Sot8" target="_blank" class="btn btn-pay">
Pagar R$ 25,00 via InfinitePay
</a>
</div>
</div>
<script>
// 1. CONFIGURAÇÃO SUPABASE (O programador deve preencher as chaves)
const SUPABASE_URL = 'https://SEU-PROJETO.supabase.co';
const SUPABASE_ANON_KEY = 'SUA-CHAVE-ANONIMA';
const supabase = supabase.createClient(SUPABASE_URL, SUPABASE_ANON_KEY);
const loginForm = document.getElementById('login-form');
const paymentScreen = document.getElementById('payment-screen');
// 2. LÓGICA DE VALIDAÇÃO DE ACESSO E TRIAL
async function checkUserAccess(user) {
let { data: profile, error } = await supabase
.from('profiles')
.select('created_at, pago_ate')
.eq('id', user.id)
.single();
if (error || !profile) return false;
const now = new Date();
const createdAt = new Date(profile.created_at);
const trialEndDate = new Date(createdAt);
trialEndDate.setDate(trialEndDate.getDate() + 15); // +15 Dias de Trial
const paidUntil = profile.pago_ate ? new Date(profile.pago_ate) : null;
// Valida se está no Trial OU se a Assinatura está Paga
const isTrialValid = now <= trialEndDate;
const isSubscriptionValid = paidUntil && now <= paidUntil;
if (isTrialValid || isSubscriptionValid) {
// PERMISSÃO CONCEDIDA: Redireciona para a Parte 02 (Roteirizador)
// A rota ativa e a lista de endereços devem sincronizar via banco de dados Supabase
window.location.href = 'roteirizador.html';
} else {
// MENSALIDADE OU TRIAL VENCIDO: Exibe ecrã de pagamento
loginForm.classList.add('hidden');
paymentScreen.classList.remove('hidden');
}
}
// 3. SUBMIT DO FORMULÁRIO (LOGIN / AUTOCADASTRO)
loginForm.addEventListener('submit', async (e) => {
e.preventDefault();
const email = document.getElementById('email').value;
const password = document.getElementById('password').value;
// Tenta Fazer Login
let { data, error } = await supabase.auth.signInWithPassword({ email, password });
// Se o utilizador não existir, cria o registo automaticamente com os 15 dias grátis
if (error) {
const signUp = await supabase.auth.signUp({ email, password });
if (signUp.error) {
alert('Erro na autenticação: ' + signUp.error.message);
return;
}
data = signUp.data;
}
if (data.user) {
checkUserAccess(data.user);
}
});
</script>
</body>
</html>
Imagem da parte 01:

Comentários
Postar um comentário