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 */}