feat(i18n): Replace hardcoded strings with translation keys in support and donation components
Replaced hardcoded Portuguese text with next-intl translation keys in the support page, header, and donation card components to enable internationalization and support multiple languages. This improves the app's accessibility and localization capabilities.
This commit is contained in:
1 parent
5ccc9120c4
commit
bb6b320d1f
5 files changed
+196
-63
No files matched your search
@@ -23,7 +23,7 @@ export default function Header() {
|
||||
{ href: `/${locale}/market`, label: t("market") },
|
||||
{ href: `/${locale}/sobre`, label: t("about") },
|
||||
{ href: `/${locale}/precos`, label: t("prices") },
|
||||
{ href: `/${locale}/apoiar`, label: "Apoiar", highlight: true },
|
||||
{ href: `/${locale}/apoiar`, label: t("support"), highlight: true },
|
||||
];
|
||||
|
||||
return (
|
||||
|
||||
@@ -26,6 +26,7 @@ import {
|
||||
DialogTitle,
|
||||
} from "@/components/ui/dialog";
|
||||
import { DonationTier, DonationResponse } from "@/types/donation";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
interface DonationCardProps extends DonationTier {}
|
||||
|
||||
@@ -63,6 +64,8 @@ export function DonationCard({
|
||||
const [paymentConfirmed, setPaymentConfirmed] = useState(false);
|
||||
const [showThankYouModal, setShowThankYouModal] = useState(false);
|
||||
|
||||
const t = useTranslations("donation");
|
||||
|
||||
const icons = {
|
||||
coffee: Coffee,
|
||||
pizza: Pizza,
|
||||
@@ -440,27 +443,31 @@ export function DonationCard({
|
||||
htmlFor="customAmount"
|
||||
className="text-sm text-muted-foreground"
|
||||
>
|
||||
Valor (R$)
|
||||
{t("form.value")}
|
||||
</label>
|
||||
<Input
|
||||
id="customAmount"
|
||||
type="text"
|
||||
inputMode="decimal"
|
||||
placeholder="Ex: 15,50 ou 15.50"
|
||||
placeholder={t("form.chooseAmount")}
|
||||
value={customAmount}
|
||||
onChange={handleCustomAmountChange}
|
||||
className="text-lg text-center"
|
||||
/>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Mín: R$ {customProduct.minAmount.toFixed(2)} | Máx: R${" "}
|
||||
{customProduct.maxAmount.toFixed(2)}
|
||||
{t("form.min")}: R$ {customProduct.minAmount.toFixed(2)} |{" "}
|
||||
{t("form.max")}: R$ {customProduct.maxAmount.toFixed(2)}
|
||||
</p>
|
||||
</div>
|
||||
{customAmount && !isValidCustomAmount() && (
|
||||
<p className="text-xs text-red-500">
|
||||
{parseFloat(customAmount) < customProduct.minAmount
|
||||
? `Mínimo é R$ ${customProduct.minAmount.toFixed(2)}`
|
||||
: `Máximo é R$ ${customProduct.maxAmount.toFixed(2)}`}
|
||||
? `${t(
|
||||
"form.minAmount"
|
||||
)} ${customProduct.minAmount.toFixed(2)}`
|
||||
: `${t(
|
||||
"form.maxAmount"
|
||||
)} ${customProduct.maxAmount.toFixed(2)}`}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
@@ -474,12 +481,14 @@ export function DonationCard({
|
||||
{loading ? (
|
||||
<>
|
||||
<Loader2 className="mr-2 h-5 w-5 animate-spin" />
|
||||
Processando...
|
||||
{t("form.processing")}
|
||||
</>
|
||||
) : customAmount ? (
|
||||
`Doar R$ ${parseFloat(customAmount || "0").toFixed(2)}`
|
||||
`${t("form.donate")} ${parseFloat(
|
||||
customAmount || "0"
|
||||
).toFixed(2)}`
|
||||
) : (
|
||||
"Escolha o valor"
|
||||
t("form.chooseAmount")
|
||||
)}
|
||||
</Button>
|
||||
</>
|
||||
@@ -500,10 +509,10 @@ export function DonationCard({
|
||||
{loading ? (
|
||||
<>
|
||||
<Loader2 className="mr-2 h-5 w-5 animate-spin" />
|
||||
Processando...
|
||||
{t("form.processing")}
|
||||
</>
|
||||
) : (
|
||||
"Apoiar com PIX"
|
||||
t("form.supportWithPix")
|
||||
)}
|
||||
</Button>
|
||||
</>
|
||||
@@ -516,7 +525,7 @@ export function DonationCard({
|
||||
<DialogContent className="max-w-4xl">
|
||||
<DialogHeader>
|
||||
<DialogTitle className="text-center text-2xl">
|
||||
Como deseja contribuir?
|
||||
{t("form.howToContribute")}
|
||||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
|
||||
@@ -530,13 +539,15 @@ export function DonationCard({
|
||||
<div className="p-2 rounded-full bg-muted">
|
||||
<Lock className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className="text-xl font-bold">Doação Anônima</h3>
|
||||
<h3 className="text-xl font-bold">
|
||||
{t("form.anonymousTitle")}
|
||||
</h3>
|
||||
</div>
|
||||
<p className="text-muted-foreground mb-4">
|
||||
Rápido e sem cadastro. Gere o PIX imediatamente.
|
||||
{t("form.anonymousDesc")}
|
||||
</p>
|
||||
<Button className="w-full" variant="outline" disabled={loading}>
|
||||
Continuar Anônimo
|
||||
{t("form.anonymousButton")}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -546,35 +557,37 @@ export function DonationCard({
|
||||
onClick={handleIdentifiedClick}
|
||||
>
|
||||
<Badge className="absolute -top-3 right-6 bg-primary">
|
||||
Recomendado
|
||||
{t("form.recommended")}
|
||||
</Badge>
|
||||
<div className="flex items-center gap-3 mb-3">
|
||||
<div className="p-2 rounded-full bg-primary/10">
|
||||
<User className="h-5 w-5 text-primary" />
|
||||
</div>
|
||||
<h3 className="text-xl font-bold">Quero me Identificar</h3>
|
||||
<h3 className="text-xl font-bold">
|
||||
{t("form.identifiedTitle")}
|
||||
</h3>
|
||||
</div>
|
||||
<p className="text-muted-foreground mb-4">
|
||||
Ajude-nos a agradecer e oferecer benefícios
|
||||
{t("form.identifiedDesc")}
|
||||
</p>
|
||||
|
||||
<div className="space-y-2 mb-4">
|
||||
<div className="flex items-center gap-2 text-sm text-muted-foreground">
|
||||
<CheckCircle className="h-4 w-4 text-primary" />
|
||||
<span>Agradecimento personalizado por email</span>
|
||||
<span>{t("form.thankByEmail")}</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 text-sm text-muted-foreground">
|
||||
<CheckCircle className="h-4 w-4 text-primary" />
|
||||
<span>Acesso antecipado a novos recursos</span>
|
||||
<span>{t("form.earlyAccess")}</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 text-sm text-muted-foreground">
|
||||
<CheckCircle className="h-4 w-4 text-primary" />
|
||||
<span>Histórico de suas contribuições</span>
|
||||
<span>{t("form.contributionHistory")}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Button className="w-full" disabled={loading}>
|
||||
Identificar-me
|
||||
{t("form.identifyMe")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -585,7 +598,7 @@ export function DonationCard({
|
||||
<Dialog open={showDonorForm} onOpenChange={setShowDonorForm}>
|
||||
<DialogContent className="max-w-md">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Informações para Doação</DialogTitle>
|
||||
<DialogTitle>{t("form.donorInfo")}</DialogTitle>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="space-y-4">
|
||||
@@ -597,47 +610,51 @@ export function DonationCard({
|
||||
|
||||
<div>
|
||||
<label className="text-sm font-medium mb-2 block">
|
||||
Nome *{" "}
|
||||
{t("form.name")}{" "}
|
||||
<span className="text-muted-foreground text-xs">
|
||||
(min. 3 caracteres)
|
||||
({t("form.nameHint")})
|
||||
</span>
|
||||
</label>
|
||||
<Input
|
||||
value={donorName}
|
||||
onChange={(e) => setDonorName(e.target.value)}
|
||||
placeholder="Seu nome ou apelido"
|
||||
placeholder={t("form.namePlaceholder")}
|
||||
maxLength={50}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="text-sm font-medium mb-2 block">Email *</label>
|
||||
<label className="text-sm font-medium mb-2 block">
|
||||
{t("form.email")}
|
||||
</label>
|
||||
<Input
|
||||
type="email"
|
||||
value={donorEmail}
|
||||
onChange={(e) => setDonorEmail(e.target.value)}
|
||||
placeholder="[email protected]"
|
||||
placeholder={t("form.emailPlaceholder")}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="text-sm font-medium mb-2 block">
|
||||
Telefone *{" "}
|
||||
<span className="text-muted-foreground text-xs">(com DDD)</span>
|
||||
{t("form.phone")}{" "}
|
||||
<span className="text-muted-foreground text-xs">
|
||||
({t("form.phoneHint")})
|
||||
</span>
|
||||
</label>
|
||||
<Input
|
||||
value={donorPhone}
|
||||
onChange={(e) => setDonorPhone(formatPhone(e.target.value))}
|
||||
placeholder="(11) 98888-7777"
|
||||
placeholder={t("form.phonePlaceholder")}
|
||||
maxLength={15}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="text-sm font-medium mb-2 block">
|
||||
CPF/CNPJ *{" "}
|
||||
{t("form.taxId")}{" "}
|
||||
<span className="text-muted-foreground text-xs">
|
||||
(formato automático)
|
||||
({t("form.taxIdHint")})
|
||||
</span>
|
||||
</label>
|
||||
<Input
|
||||
@@ -650,16 +667,16 @@ export function DonationCard({
|
||||
setDonorTaxId(formatCNPJ(value));
|
||||
}
|
||||
}}
|
||||
placeholder="000.000.000-00 ou 00.000.000/0000-00"
|
||||
placeholder={t("form.taxIdPlaceholder")}
|
||||
maxLength={18}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="text-sm font-medium mb-2 block">
|
||||
Mensagem{" "}
|
||||
{t("form.message")}{" "}
|
||||
<span className="text-muted-foreground text-xs">
|
||||
(opcional, máx. 280 chars)
|
||||
({t("form.messageHint")})
|
||||
</span>
|
||||
</label>
|
||||
<Textarea
|
||||
@@ -669,7 +686,7 @@ export function DonationCard({
|
||||
setDonorMessage(e.target.value);
|
||||
}
|
||||
}}
|
||||
placeholder="Deixe uma mensagem para a equipe..."
|
||||
placeholder={t("form.messagePlaceholder")}
|
||||
rows={3}
|
||||
maxLength={280}
|
||||
/>
|
||||
@@ -689,7 +706,7 @@ export function DonationCard({
|
||||
className="flex-1"
|
||||
disabled={loading}
|
||||
>
|
||||
Voltar
|
||||
{t("form.close")}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={handleSubmitForm}
|
||||
@@ -699,10 +716,10 @@ export function DonationCard({
|
||||
{loading ? (
|
||||
<>
|
||||
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
||||
Processando...
|
||||
{t("form.processing")}
|
||||
</>
|
||||
) : (
|
||||
"Gerar PIX"
|
||||
t("form.generatePix")
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
@@ -715,7 +732,7 @@ export function DonationCard({
|
||||
<DialogContent className="max-w-md">
|
||||
<DialogHeader>
|
||||
<DialogTitle className="text-center">
|
||||
Escaneie o QR Code para Pagar
|
||||
{t("form.qrTitle")}
|
||||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
|
||||
@@ -731,7 +748,7 @@ export function DonationCard({
|
||||
|
||||
<div className="space-y-2">
|
||||
<p className="text-sm text-muted-foreground text-center">
|
||||
Ou copie o código PIX:
|
||||
{t("form.copyCode")}
|
||||
</p>
|
||||
<div className="flex gap-2">
|
||||
<Input
|
||||
@@ -747,12 +764,12 @@ export function DonationCard({
|
||||
{copied ? (
|
||||
<>
|
||||
<Check className="h-4 w-4" />
|
||||
Copiado!
|
||||
{t("form.copied")}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Copy className="h-4 w-4" />
|
||||
Copiar
|
||||
{t("form.copy")}
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
@@ -761,7 +778,7 @@ export function DonationCard({
|
||||
|
||||
{timeRemaining && (
|
||||
<p className="text-xs text-center text-muted-foreground">
|
||||
⏱️ Tempo restante: {timeRemaining}
|
||||
⏱️ {t("form.remainingTime")} {timeRemaining}
|
||||
</p>
|
||||
)}
|
||||
|
||||
@@ -771,13 +788,13 @@ export function DonationCard({
|
||||
variant="outline"
|
||||
className="flex-1"
|
||||
>
|
||||
Fechar
|
||||
{t("form.close")}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => (window.location.href = "/apoiar/obrigado")}
|
||||
className="flex-1"
|
||||
>
|
||||
Já Paguei
|
||||
{t("form.paid")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -802,19 +819,17 @@ export function DonationCard({
|
||||
{/* Título e mensagem */}
|
||||
<div>
|
||||
<h2 className="text-2xl font-bold mb-2">
|
||||
Pagamento Confirmado! 🎉
|
||||
{t("form.paymentConfirmed")} 🎉
|
||||
</h2>
|
||||
<p className="text-muted-foreground">
|
||||
Obrigado pela sua contribuição! Cada doação nos ajuda a manter o
|
||||
projeto funcionando.
|
||||
{t("form.paymentConfirmedDesc")}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Mensagem especial */}
|
||||
<div className="p-4 rounded-lg bg-primary/5 border border-primary/20">
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Sua doação faz toda a diferença para nossa comunidade. Muito
|
||||
obrigado pelo apoio! ❤️
|
||||
{t("form.contributionMatters")} ❤️
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -828,7 +843,7 @@ export function DonationCard({
|
||||
className="flex-1"
|
||||
size="lg"
|
||||
>
|
||||
Ver Página de Agradecimento
|
||||
{t("form.viewThankYouPage")}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
@@ -839,7 +854,7 @@ export function DonationCard({
|
||||
className="flex-1"
|
||||
size="lg"
|
||||
>
|
||||
Voltar ao Início
|
||||
{t("form.backToHome")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user