diff --git a/src/components/dashboard/CategoryChart.tsx b/src/components/dashboard/CategoryChart.tsx index 73428df..3e5af21 100644 --- a/src/components/dashboard/CategoryChart.tsx +++ b/src/components/dashboard/CategoryChart.tsx @@ -12,26 +12,6 @@ interface CategoryChartProps { const CategoryChart: React.FC = ({ categories, isLoading = false }) => { const validCategories = categories.filter(cat => cat.valor > 0); - const renderCustomizedLabel = ({ cx, cy, midAngle, innerRadius, outerRadius, percent, index }: any) => { - if (percent < 0.05) return null; - const radius = innerRadius + (outerRadius - innerRadius) * 0.7; - const x = cx + radius * Math.cos(-midAngle * Math.PI / 180); - const y = cy + radius * Math.sin(-midAngle * Math.PI / 180); - - return ( - cx ? 'start' : 'end'} - dominantBaseline="central" - className="text-xs font-bold drop-shadow-lg" - > - {`${(percent * 100).toFixed(0)}%`} - - ); - }; - const formatCurrency = (value: number) => { return new Intl.NumberFormat('pt-BR', { style: 'currency', @@ -49,7 +29,9 @@ const CategoryChart: React.FC = ({ categories, isLoading = f className="w-3 h-3 mr-2 rounded-full shadow" style={{ backgroundColor: entry.color }} /> - {entry.value} + + {entry.value} ({(entry.payload.percentage * 100).toFixed(0)}%) + ))} @@ -94,8 +76,6 @@ const CategoryChart: React.FC = ({ categories, isLoading = f data={validCategories} cx="50%" cy="45%" - labelLine={false} - label={renderCustomizedLabel} outerRadius={90} innerRadius={40} fill="#8884d8" diff --git a/src/components/layout/Layout.tsx b/src/components/layout/Layout.tsx index 70bb6ec..1d9bb74 100644 --- a/src/components/layout/Layout.tsx +++ b/src/components/layout/Layout.tsx @@ -4,6 +4,7 @@ import { useIsMobile } from '@/hooks/use-mobile'; import Header from './Header'; import Sidebar from './Sidebar'; import OnboardingTour from '@/components/onboarding/OnboardingTour'; +import HelpIcon from '@/components/help/HelpIcon'; import { useOnboardingTour } from '@/hooks/useOnboardingTour'; interface LayoutProps { @@ -62,6 +63,9 @@ export default function Layout({ children }: LayoutProps) { + {/* Help Icon */} + + {/* Tour de Onboarding */} Dashboard + getNavLinkClass(isActive)} + onClick={isMobile ? onClose : undefined} + > + + Assinatura + getNavLinkClass(isActive)} diff --git a/src/pages/Assinatura.tsx b/src/pages/Assinatura.tsx new file mode 100644 index 0000000..2ca129f --- /dev/null +++ b/src/pages/Assinatura.tsx @@ -0,0 +1,163 @@ + +import { useState } from "react"; +import { Button } from "@/components/ui/button"; +import { ArrowLeft, Check } from "lucide-react"; +import { Link } from "react-router-dom"; +import { + Card, + CardContent, + CardDescription, + CardFooter, + CardHeader, + CardTitle, +} from "@/components/ui/card"; +import { format } from "date-fns"; +import { ptBR } from "date-fns/locale"; +import { toast } from "sonner"; +import { supabase } from "@/integrations/supabase/client"; + +const Assinatura = () => { + const [isSubscribing, setIsSubscribing] = useState(false); + const [subscription] = useState({ + active: true, + planName: "Plano Mensal Finance Home", + expires_at: new Date(new Date().getFullYear(), new Date().getMonth() + 1, 15), + }); + + const handleSubscribe = async () => { + setIsSubscribing(true); + try { + // Puxa os dados mais atuais do usuário logado NO MOMENTO do click! + const { data: { user } } = await supabase.auth.getUser(); + + if (!user || !user.id || !user.email) { + toast.error("Sessão inválida. Por favor, faça login novamente."); + setIsSubscribing(false); + return; + } + + // log para debug - remova depois de testar! + console.log("Assinatura MercadoPago - email enviado:", user.email, "id:", user.id); + + const { data, error } = await supabase.functions.invoke('mercado-pago-subscribe', { + body: { email: user.email, userId: user.id }, + }); + + if (error) { + throw new Error(`Erro de comunicação: ${error.message}`); + } + + if (data.error) { + throw new Error(data.error); + } + + if (data.init_point) { + window.location.href = data.init_point; + } else { + throw new Error("Não foi possível obter a URL de checkout. Tente novamente."); + } + + } catch (error: any) { + console.error("Erro ao criar a assinatura:", error); + toast.error(error.message || "Ocorreu um erro inesperado. Por favor, tente mais tarde."); + } finally { + setIsSubscribing(false); + } + }; + + return ( +
+
+ +

Assinatura

+
+ +
+ + + + Plano Mensal Finance Home + + + R$14,99 + + /mês + + + + +
    +
  • + + + Acesso total ao Finance Home + +
  • +
  • + + + Relatórios ilimitados + +
  • +
  • + + + Integração com WhatsApp + +
  • +
+
+ + + + +
+ + {subscription.active && ( + + + Sua Assinatura Atual + + Obrigado por ser um assinante! + + + +

+ Plano:{" "} + + {subscription.planName} + +

+

+ Vence em:{" "} + + {format(subscription.expires_at, "dd 'de' MMMM 'de' yyyy", { + locale: ptBR, + })} + +

+
+ + + +
+ )} +
+
+ ); +}; + +export default Assinatura; diff --git a/src/pages/Configuracoes.tsx b/src/pages/Configuracoes.tsx index 1f0ce14..a07bccb 100644 --- a/src/pages/Configuracoes.tsx +++ b/src/pages/Configuracoes.tsx @@ -1,71 +1,13 @@ + import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs"; import MeuCadastroForm from "@/components/settings/MeuCadastroForm"; import { useState } from "react"; import { Button } from "@/components/ui/button"; -import { ArrowLeft, Check } from "lucide-react"; +import { ArrowLeft } from "lucide-react"; import { Link } from "react-router-dom"; -import { - Card, - CardContent, - CardDescription, - CardFooter, - CardHeader, - CardTitle, -} from "@/components/ui/card"; -import { format } from "date-fns"; -import { ptBR } from "date-fns/locale"; -import { toast } from "sonner"; -import { supabase } from "@/integrations/supabase/client"; const Configuracoes = () => { const [tab, setTab] = useState("visao-geral"); - const [isSubscribing, setIsSubscribing] = useState(false); - const [subscription] = useState({ - active: true, - planName: "Plano Mensal Finance Home", - expires_at: new Date(new Date().getFullYear(), new Date().getMonth() + 1, 15), - }); - - const handleSubscribe = async () => { - setIsSubscribing(true); - try { - // Puxa os dados mais atuais do usuário logado NO MOMENTO do click! - const { data: { user } } = await supabase.auth.getUser(); - - if (!user || !user.id || !user.email) { - toast.error("Sessão inválida. Por favor, faça login novamente."); - setIsSubscribing(false); - return; - } - - // log para debug - remova depois de testar! - console.log("Assinatura MercadoPago - email enviado:", user.email, "id:", user.id); - - const { data, error } = await supabase.functions.invoke('mercado-pago-subscribe', { - body: { email: user.email, userId: user.id }, - }); - - if (error) { - throw new Error(`Erro de comunicação: ${error.message}`); - } - - if (data.error) { - throw new Error(data.error); - } - - if (data.init_point) { - window.location.href = data.init_point; - } else { - throw new Error("Não foi possível obter a URL de checkout. Tente novamente."); - } - - } catch (error: any) { - console.error("Erro ao criar a assinatura:", error); - toast.error(error.message || "Ocorreu um erro inesperado. Por favor, tente mais tarde."); - } finally { - setIsSubscribing(false); - } - }; return (
@@ -83,98 +25,16 @@ const Configuracoes = () => { Visão Geral Meu cadastro - Assinatura
Bem-vindo à página de Configurações!
-
Aqui você pode gerenciar suas informações, assinatura e muito mais.
+
Aqui você pode gerenciar suas informações pessoais e configurações da conta.
- -
- - - - Plano Mensal Finance Home - - - R$14,99 - - /mês - - - - -
    -
  • - - - Acesso total ao Finance Home - -
  • -
  • - - - Relatórios ilimitados - -
  • -
  • - - - Integração com WhatsApp - -
  • -
-
- - - - -
- - {subscription.active && ( - - - Sua Assinatura Atual - - Obrigado por ser um assinante! - - - -

- Plano:{" "} - - {subscription.planName} - -

-

- Vence em:{" "} - - {format(subscription.expires_at, "dd 'de' MMMM 'de' yyyy", { - locale: ptBR, - })} - -

-
- - - -
- )} -
-
);