Template genérico de checkout com ASAAS, parametrizado via env vars. Inclui fluxo completo: checkout → pedido → polling → webhook → admin. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
72 lines
2.5 KiB
TypeScript
72 lines
2.5 KiB
TypeScript
import { getProdutoById } from "@/lib/actions"
|
|
import { ProductBuyForm } from "@/components/product-buy-form"
|
|
import { notFound } from "next/navigation"
|
|
import type { Metadata } from "next"
|
|
import { appConfig } from "@/lib/config"
|
|
|
|
type Props = { params: Promise<{ id: string }> }
|
|
|
|
export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
|
try {
|
|
const { id } = await params
|
|
const produto = await getProdutoById(id)
|
|
if (!produto) return { title: "Produto não encontrado" }
|
|
return {
|
|
title: `${produto.nome} — ${appConfig.name}`,
|
|
description: produto.descricao ?? produto.nome,
|
|
}
|
|
} catch {
|
|
return { title: "Erro ao carregar produto" }
|
|
}
|
|
}
|
|
|
|
export default async function ProductPage({ params }: Props) {
|
|
const { id } = await params
|
|
const produto = await getProdutoById(id)
|
|
if (!produto) notFound()
|
|
|
|
const precoFormatado = (produto.preco_centavos / 100).toLocaleString("pt-BR", {
|
|
style: "currency",
|
|
currency: "BRL",
|
|
})
|
|
|
|
return (
|
|
<div className="bg-gradient-to-b from-gray-50 to-white min-h-screen">
|
|
<div className="container mx-auto py-16 px-4 sm:px-6 lg:px-8 max-w-5xl">
|
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-12">
|
|
{/* Detalhes do produto */}
|
|
<div>
|
|
<h1 className="text-3xl font-bold text-primary mb-4">{produto.nome}</h1>
|
|
{produto.descricao && (
|
|
<p className="text-gray-600 text-lg mb-6">{produto.descricao}</p>
|
|
)}
|
|
<div className="flex flex-wrap gap-3 text-sm text-gray-500">
|
|
{produto.tipo && (
|
|
<span className="bg-gray-100 px-3 py-1 rounded-full">
|
|
Tipo: <strong>{produto.tipo}</strong>
|
|
</span>
|
|
)}
|
|
{produto.validade && (
|
|
<span className="bg-gray-100 px-3 py-1 rounded-full">
|
|
Validade: <strong>{produto.validade}</strong>
|
|
</span>
|
|
)}
|
|
{produto.midia && (
|
|
<span className="bg-gray-100 px-3 py-1 rounded-full">
|
|
Mídia: <strong>{produto.midia}</strong>
|
|
</span>
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Formulário de compra */}
|
|
<div className="bg-white p-8 rounded-2xl shadow-lg">
|
|
<p className="text-4xl font-bold mb-6 text-primary">{precoFormatado}</p>
|
|
<ProductBuyForm produtoId={produto.id} />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|