diff --git a/src/App.tsx b/src/App.tsx index 98a591b..3c1d150 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,101 +1,92 @@ -import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom'; -import { Suspense, lazy } from 'react'; import { Toaster } from "@/components/ui/sonner"; -import Auth from './pages/Auth'; -import Landing from './pages/Landing'; -import EmailConfirmation from './pages/EmailConfirmation'; -import CompleteProfile from './pages/CompleteProfile'; -import ProtectedRoute from './components/auth/ProtectedRoute'; -import { authStore } from './stores/authStore'; +import { TooltipProvider } from "@/components/ui/tooltip"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { BrowserRouter, Routes, Route } from "react-router-dom"; +import { useEffect } from "react"; +import { supabase } from "@/integrations/supabase/client"; +import { useAuthStore } from "@/stores/authStore"; +import ProtectedRoute from "@/components/auth/ProtectedRoute"; +import Layout from "@/components/layout/Layout"; -// Lazy-loaded components -const Dashboard = lazy(() => import('./pages/Index')); -const Transacoes = lazy(() => import('./pages/Transacoes')); -const Categorias = lazy(() => import('./pages/Categorias')); -const Metas = lazy(() => import('./pages/Metas')); -const Calendario = lazy(() => import('./pages/Calendario')); -const Assinatura = lazy(() => import('./pages/Assinatura')); -const WhatsApp = lazy(() => import('./pages/WhatsApp')); -const GruposWhatsApp = lazy(() => import('./pages/GruposWhatsApp')); -const NotFound = lazy(() => import('./pages/NotFound')); -const CartoesCredito = lazy(() => import('./pages/CartoesCredito')); -const Configuracoes = lazy(() => import('./pages/Configuracoes')); -const AdminFAQ = lazy(() => import('./pages/AdminFAQ')); +// Pages +import Index from "./pages/Index"; +import Auth from "./pages/Auth"; +import Landing from "./pages/Landing"; +import Transacoes from "./pages/Transacoes"; +import CartoesCredito from "./pages/CartoesCredito"; +import Configuracoes from "./pages/Configuracoes"; +import Metas from "./pages/Metas"; +import Calendario from "./pages/Calendario"; +import WhatsApp from "./pages/WhatsApp"; +import GruposWhatsApp from "./pages/GruposWhatsApp"; +import EmailConfirmation from "./pages/EmailConfirmation"; +import CompleteProfile from "./pages/CompleteProfile"; +import NotFound from "./pages/NotFound"; +import Categorias from "./pages/Categorias"; +import AdminFAQ from "./pages/AdminFAQ"; +import Assinatura from "./pages/Assinatura"; +import AvisosContas from "./pages/AvisosContas"; + +const queryClient = new QueryClient(); function App() { - const isLoggedIn = authStore((state) => state.isLoggedIn); - + const { setUser, setSession } = useAuthStore(); + + useEffect(() => { + // Verificar sessão inicial + supabase.auth.getSession().then(({ data: { session } }) => { + setSession(session); + setUser(session?.user ?? null); + }); + + // Escutar mudanças de autenticação + const { + data: { subscription }, + } = supabase.auth.onAuthStateChange((_event, session) => { + setSession(session); + setUser(session?.user ?? null); + }); + + return () => subscription.unsubscribe(); + }, [setUser, setSession]); + return ( - - - - - {/* Landing page - só mostra se não estiver logado */} - : } - /> - - {/* Auth route - redireciona para dashboard se já estiver logado */} - : } - /> - - {/* Email confirmation route */} - } - /> - - {/* Complete profile route - deve ser acessível para usuários logados */} - } - /> - - {/* Protected routes */} - - Carregando...}> - - - - } /> - - - Carregando...}> - - - - } /> - - Carregando...}>} /> - Carregando...}>} /> - Carregando...}>} /> - Carregando...}>} /> - Carregando...}>} /> - Carregando...}>} /> - Carregando...}>} /> - Carregando...}>} /> - - Carregando...}> - - - - } /> - - {/* Not found route */} - Carregando...}> - - - } /> - - + + + + + + {/* Rotas públicas */} + } /> + } /> + } /> + + {/* Rotas protegidas */} + }> + }> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + + + {/* Rota 404 */} + } /> + + + + ); } diff --git a/src/components/avisos/ContaRecorrenteForm.tsx b/src/components/avisos/ContaRecorrenteForm.tsx new file mode 100644 index 0000000..9d9e936 --- /dev/null +++ b/src/components/avisos/ContaRecorrenteForm.tsx @@ -0,0 +1,194 @@ + +import React from 'react'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; +import { Label } from '@/components/ui/label'; +import { Textarea } from '@/components/ui/textarea'; +import { X, Save } from 'lucide-react'; +import { useForm } from 'react-hook-form'; +import { supabase } from '@/integrations/supabase/client'; +import { toast } from 'sonner'; +import { useAuthStore } from '@/stores/authStore'; + +interface ContaRecorrenteFormProps { + onClose: () => void; + onSuccess: () => void; +} + +interface FormData { + nome_conta: string; + descricao: string; + valor: number; + dia_vencimento: number; + hora_aviso: string; + dias_antecedencia: number; +} + +const ContaRecorrenteForm = ({ onClose, onSuccess }: ContaRecorrenteFormProps) => { + const { user } = useAuthStore(); + const { register, handleSubmit, formState: { errors, isSubmitting } } = useForm({ + defaultValues: { + hora_aviso: '09:00', + dias_antecedencia: 1 + } + }); + + const onSubmit = async (data: FormData) => { + if (!user?.id) { + toast.error('Usuário não encontrado. Faça login novamente.'); + return; + } + + try { + const { error } = await supabase + .from('contas_recorrentes') + .insert([{ + ...data, + user_id: user.id, + valor: data.valor || null + }]); + + if (error) throw error; + + toast.success('Conta recorrente cadastrada com sucesso!'); + onSuccess(); + } catch (error) { + console.error('Erro ao cadastrar conta:', error); + toast.error('Erro ao cadastrar conta. Tente novamente.'); + } + }; + + return ( + + +
+
+ Nova Conta Recorrente + + Configure uma conta que será cobrada mensalmente no mesmo dia + +
+ +
+
+ +
+
+
+ + + {errors.nome_conta && ( +

{errors.nome_conta.message}

+ )} +
+ +
+ + + {errors.valor && ( +

{errors.valor.message}

+ )} +
+
+ +
+ +