diff --git a/src/components/transacoes/TransactionHeader.tsx b/src/components/transacoes/TransactionHeader.tsx index 4a135c4..c97d58a 100644 --- a/src/components/transacoes/TransactionHeader.tsx +++ b/src/components/transacoes/TransactionHeader.tsx @@ -1,43 +1,42 @@ - import React from 'react'; -import { Button } from '@/components/ui/button'; -import { PlusCircle, CreditCard } from 'lucide-react'; interface TransactionHeaderProps { onOpenDialog: (tipo: 'receita' | 'despesa') => void; onOpenCartaoCreditoDialog: () => void; + disableAdicionar?: boolean; } -export const TransactionHeader = ({ - onOpenDialog, - onOpenCartaoCreditoDialog -}: TransactionHeaderProps) => { +export function TransactionHeader({ + onOpenDialog, + onOpenCartaoCreditoDialog, + disableAdicionar = false, +}: TransactionHeaderProps) { return ( -
-

Todas as Transações

-
- - - -
+
+ + +
); -}; +} diff --git a/src/hooks/useAccessControl.ts b/src/hooks/useAccessControl.ts new file mode 100644 index 0000000..ab06e57 --- /dev/null +++ b/src/hooks/useAccessControl.ts @@ -0,0 +1,114 @@ + +import { useState, useEffect } from "react"; +import { supabase } from "@/integrations/supabase/client"; + +interface AccessControlResult { + loading: boolean; + podeAdicionarTransacao: boolean; + motivo: string | null; // mensagem para exibir ao usuário se bloqueado + diasRestantesTrial: number; + trialExpiraEm: Date | null; +} + +export function useAccessControl(): AccessControlResult { + const [result, setResult] = useState({ + loading: true, + podeAdicionarTransacao: false, + motivo: null, + diasRestantesTrial: 0, + trialExpiraEm: null, + }); + + useEffect(() => { + async function checkAccess() { + const userEmail = localStorage.getItem("userEmail"); + if (!userEmail) { + setResult({ + loading: false, + podeAdicionarTransacao: false, + motivo: "Erro ao identificar usuário. Faça login novamente.", + diasRestantesTrial: 0, + trialExpiraEm: null, + }); + return; + } + + // Buscar data de cadastro do usuário + const { data: usuarios, error: userError } = await supabase + .from("usuarios") + .select("created_at") + .eq("email", userEmail.trim().toLowerCase()); + + if (userError || !usuarios || usuarios.length === 0) { + setResult({ + loading: false, + podeAdicionarTransacao: false, + motivo: "Erro ao buscar dados do usuário. Tente novamente mais tarde.", + diasRestantesTrial: 0, + trialExpiraEm: null, + }); + return; + } + + const cadastro = new Date(usuarios[0].created_at); + const agora = new Date(); + const trialExpiraEm = new Date(cadastro.getTime()); + trialExpiraEm.setDate(trialExpiraEm.getDate() + 30); + const dentroTrial = agora < trialExpiraEm; + const diasRestantes = Math.ceil((trialExpiraEm.getTime() - agora.getTime()) / (1000 * 60 * 60 * 24)); + + if (dentroTrial) { + setResult({ + loading: false, + podeAdicionarTransacao: true, + motivo: null, + diasRestantesTrial: diasRestantes, + trialExpiraEm, + }); + return; + } + + // Busca pagamento aprovado na tabela de pagamentos_mercadopago + const { data: pagamentos, error: pagamentoError } = await supabase + .from("pagamentos_mercadopago") + .select("id, status, created_at, payer_email") + .eq("payer_email", userEmail.trim().toLowerCase()) + .eq("status", "approved"); + + if (pagamentoError) { + setResult({ + loading: false, + podeAdicionarTransacao: false, + motivo: "Erro ao verificar status de pagamento.", + diasRestantesTrial: 0, + trialExpiraEm, + }); + return; + } + + if (pagamentos && pagamentos.length > 0) { + setResult({ + loading: false, + podeAdicionarTransacao: true, + motivo: null, + diasRestantesTrial: 0, + trialExpiraEm, + }); + return; + } + + setResult({ + loading: false, + podeAdicionarTransacao: false, + motivo: + "Seu período de teste acabou. Para continuar adicionando transações realize o pagamento da assinatura.", + diasRestantesTrial: 0, + trialExpiraEm, + }); + } + + checkAccess(); + }, []); + + return result; +} diff --git a/src/pages/Transacoes.tsx b/src/pages/Transacoes.tsx index ff95294..2e031aa 100644 --- a/src/pages/Transacoes.tsx +++ b/src/pages/Transacoes.tsx @@ -1,5 +1,4 @@ - -import React, { useState } from 'react'; +import React from 'react'; import Layout from '@/components/layout/Layout'; import TransactionsTable from '@/components/dashboard/TransactionsTable'; import { useTransactions } from '@/hooks/useTransactions'; @@ -7,6 +6,7 @@ import { TransactionHeader } from '@/components/transacoes/TransactionHeader'; import { TransactionSummaryCards } from '@/components/transacoes/TransactionSummaryCards'; import { TransactionDialogs } from '@/components/transacoes/TransactionDialogs'; import { MonthFilter } from '@/components/filters/MonthFilter'; +import { useAccessControl } from '@/hooks/useAccessControl'; const TransacoesPage = () => { // Função para obter o mês atual no formato YYYY-MM @@ -17,6 +17,8 @@ const TransacoesPage = () => { const [selectedMonth, setSelectedMonth] = useState(getCurrentMonth()); + const access = useAccessControl(); + const { transactions, isLoading, @@ -59,6 +61,11 @@ const TransacoesPage = () => {

Dados de: {formatMonthDisplay(selectedMonth)}

+ {!access.loading && access.podeAdicionarTransacao && access.diasRestantesTrial > 0 && ( +
+ {`Você está em período gratuito. ${access.diasRestantesTrial} dia(s) restante(s) de teste.`} +
+ )}
{ /> + {!access.loading && !access.podeAdicionarTransacao && ( +
+ Atenção: {access.motivo} +
+ )} + + {/* Só passa as funções de adicionar se permitido */} {}} + onOpenCartaoCreditoDialog={access.podeAdicionarTransacao ? handleOpenCartaoCreditoDialog : () => {}} + disableAdicionar={!access.podeAdicionarTransacao} /> {/* Resumo em Cards */}