Updated ABACATEPAY_SETUP.md with comprehensive setup guide, including environment variables, API key instructions, webhook configuration, donation flow, and field details for better integration clarity. Added required fields (phone, CPF/CNPJ) to the donation form in app/[locale]/apoiar/page.tsx to collect essential donor information and improve compliance. This ensures smoother setup and more robust donation processing.
245 lines
7.8 KiB
TypeScript
245 lines
7.8 KiB
TypeScript
import Header from "@/components/Header";
|
|
import { DonationCard } from "@/components/donation-card";
|
|
import { BlurFade } from "@/components/ui/blur-fade";
|
|
import { NumberTicker } from "@/components/ui/number-ticker";
|
|
import { Badge } from "@/components/ui/badge";
|
|
import { Button } from "@/components/ui/button";
|
|
import {
|
|
Accordion,
|
|
AccordionContent,
|
|
AccordionItem,
|
|
AccordionTrigger,
|
|
} from "@/components/ui/accordion";
|
|
import { Heart } from "lucide-react";
|
|
import { getTranslations } from "next-intl/server";
|
|
import Link from "next/link";
|
|
import { ShareButton } from "@/components/share-button";
|
|
|
|
export async function generateMetadata({
|
|
params,
|
|
}: {
|
|
params: Promise<{ locale: string }>;
|
|
}) {
|
|
const { locale } = await params;
|
|
const t = await getTranslations({ locale, namespace: "donation" });
|
|
return {
|
|
title: t("title"),
|
|
description: t("subtitle"),
|
|
};
|
|
}
|
|
|
|
export default async function SupportPage({
|
|
params,
|
|
}: {
|
|
params: Promise<{ locale: string }>;
|
|
}) {
|
|
const { locale } = await params;
|
|
const t = await getTranslations({ locale, namespace: "donation" });
|
|
|
|
// Dados REAIS para demonstração
|
|
const stats = {
|
|
monthsOnline: 1,
|
|
uptime: 100,
|
|
};
|
|
|
|
// Custos mensais REAIS
|
|
const monthlyCosts = {
|
|
vps: 69, // R$ 69/mês
|
|
devHours: 40, // média horas/mês
|
|
devRate: 50, // R$ 50/hora
|
|
total: 2069, // R$ 69 + (40 * 50)
|
|
};
|
|
|
|
const faqItems = [
|
|
{
|
|
question: t("faq.q1"),
|
|
answer: t("faq.a1"),
|
|
},
|
|
{
|
|
question: t("faq.q2"),
|
|
answer: t("faq.a2"),
|
|
},
|
|
{
|
|
question: t("faq.q3"),
|
|
answer: t("faq.a3"),
|
|
},
|
|
{
|
|
question: t("faq.q4"),
|
|
answer: t("faq.a4"),
|
|
},
|
|
{
|
|
question: t("faq.q5"),
|
|
answer: t("faq.a5"),
|
|
},
|
|
];
|
|
|
|
return (
|
|
<div className="min-h-screen">
|
|
<Header />
|
|
|
|
<div className="container mx-auto px-4 py-20">
|
|
{/* Hero Section */}
|
|
<BlurFade delay={0.1}>
|
|
<div className="text-center mb-16">
|
|
<div className="flex justify-center mb-6">
|
|
<div className="p-4 rounded-full bg-primary/10 border border-primary/20">
|
|
<Heart className="w-12 h-12 text-primary" />
|
|
</div>
|
|
</div>
|
|
<h1 className="text-4xl md:text-5xl font-bold mb-4">
|
|
{t("title")}
|
|
</h1>
|
|
<p className="text-xl text-muted-foreground max-w-2xl mx-auto">
|
|
{t("subtitle")}
|
|
</p>
|
|
</div>
|
|
</BlurFade>
|
|
|
|
{/* História & Missão */}
|
|
<BlurFade delay={0.2}>
|
|
<div className="mb-20">
|
|
<h2 className="text-3xl font-bold text-center mb-8">
|
|
{t("story.title")}
|
|
</h2>
|
|
<div className="max-w-4xl mx-auto">
|
|
<div className="p-8 rounded-2xl border border-border/50 bg-card backdrop-blur-lg">
|
|
<p className="text-lg leading-relaxed text-muted-foreground whitespace-pre-line">
|
|
{t("story.text")}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</BlurFade>
|
|
|
|
{/* Custos Reais */}
|
|
<BlurFade delay={0.3}>
|
|
<div className="mb-20">
|
|
<h2 className="text-3xl font-bold text-center mb-8">
|
|
{t("costs.title")}
|
|
</h2>
|
|
<div className="max-w-2xl mx-auto space-y-4">
|
|
<div className="flex justify-between items-center p-4 rounded-lg bg-card border">
|
|
<span className="text-lg">{t("costs.vps")}</span>
|
|
<Badge variant="secondary" className="text-lg">
|
|
{t("costs.vpsValue")}
|
|
</Badge>
|
|
</div>
|
|
<div className="flex justify-between items-center p-4 rounded-lg bg-card border">
|
|
<span className="text-lg">{t("costs.dev")}</span>
|
|
<Badge variant="secondary" className="text-lg">
|
|
{t("costs.devValue")}
|
|
</Badge>
|
|
</div>
|
|
<div className="flex justify-between items-center p-6 rounded-lg bg-primary/10 border-2 border-primary">
|
|
<span className="text-xl font-bold">{t("costs.total")}</span>
|
|
<Badge className="text-xl bg-primary">
|
|
{t("costs.totalValue")}
|
|
</Badge>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</BlurFade>
|
|
|
|
{/* Estatísticas Simplificadas */}
|
|
<BlurFade delay={0.4}>
|
|
<div className="mb-20">
|
|
<div className="grid grid-cols-2 gap-8 text-center max-w-md mx-auto">
|
|
<div>
|
|
<p className="text-3xl font-bold text-primary mb-2">
|
|
<NumberTicker value={stats.monthsOnline} />
|
|
</p>
|
|
<p className="text-sm text-muted-foreground">
|
|
{t("social.months")}
|
|
</p>
|
|
</div>
|
|
<div>
|
|
<p className="text-3xl font-bold text-primary mb-2">
|
|
<NumberTicker value={stats.uptime} />%
|
|
</p>
|
|
<p className="text-sm text-muted-foreground">
|
|
{t("social.uptime")}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</BlurFade>
|
|
|
|
{/* Opções de Doação */}
|
|
<BlurFade delay={0.5}>
|
|
<div className="mb-20">
|
|
<h2 className="text-3xl font-bold text-center mb-8">
|
|
Escolha como apoiar
|
|
</h2>
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 max-w-4xl mx-auto">
|
|
<DonationCard
|
|
id="coffee"
|
|
amount={5}
|
|
title={t("tiers.coffee.title")}
|
|
description={t("tiers.coffee.description")}
|
|
icon="coffee"
|
|
badge={t("tiers.coffee.badge")}
|
|
/>
|
|
<DonationCard
|
|
id="snack"
|
|
amount={10}
|
|
title="Um Lanche"
|
|
description="Equivale a ~20 minutos de desenvolvimento"
|
|
icon="pizza"
|
|
badge="Popular"
|
|
highlighted
|
|
/>
|
|
<DonationCard
|
|
id="lunch"
|
|
amount={25}
|
|
title={t("tiers.lunch.title")}
|
|
description={t("tiers.lunch.description")}
|
|
icon="pizza"
|
|
badge={t("tiers.lunch.badge")}
|
|
/>
|
|
</div>
|
|
</div>
|
|
</BlurFade>
|
|
|
|
{/* FAQ */}
|
|
<BlurFade delay={0.6}>
|
|
<div className="mb-20">
|
|
<h2 className="text-3xl font-bold text-center mb-8">
|
|
{t("faq.title")}
|
|
</h2>
|
|
<Accordion type="single" collapsible className="max-w-3xl mx-auto">
|
|
{faqItems.map((item, idx) => (
|
|
<AccordionItem key={idx} value={`item-${idx}`}>
|
|
<AccordionTrigger className="text-left">
|
|
{item.question}
|
|
</AccordionTrigger>
|
|
<AccordionContent className="text-muted-foreground">
|
|
{item.answer}
|
|
</AccordionContent>
|
|
</AccordionItem>
|
|
))}
|
|
</Accordion>
|
|
</div>
|
|
</BlurFade>
|
|
|
|
{/* CTA Final */}
|
|
<BlurFade delay={0.7}>
|
|
<div className="text-center">
|
|
<div className="p-12 rounded-2xl border border-border/50 bg-card backdrop-blur-sm">
|
|
<h3 className="text-3xl font-bold mb-4">{t("cta.final")}</h3>
|
|
<p className="text-lg text-muted-foreground mb-8 max-w-2xl mx-auto">
|
|
{t("cta.subtitle")}
|
|
</p>
|
|
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
|
<Button size="lg" className="bg-primary hover:bg-primary/90">
|
|
{t("cta.support")}
|
|
</Button>
|
|
<ShareButton />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</BlurFade>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|