Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 32 additions & 16 deletions frontend/src/components/AirdropBanner/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { useState } from 'react';
import { motion, useMotionValue, AnimatePresence } from 'motion/react';
import { motion, AnimatePresence } from 'motion/react';
import { useTranslation, Trans } from 'react-i18next';
import { ChevronDownIcon } from '@heroicons/react/20/solid';
export const AirdropBanner = () => {
const { t } = useTranslation();
const [expanded, setExpanded] = useState(false);
const rotation = useMotionValue(0);

const toggleExpand = () => {
rotation.set(expanded ? 0 : 180);
setExpanded(!expanded);
setExpanded((state) => !state);
};

return (
Expand All @@ -20,17 +19,18 @@ export const AirdropBanner = () => {
transition={{ duration: 0.5, ease: 'easeOut' }}
whileHover={{ scale: 1.01 }}
>
<div className='flex flex-col items-center justify-center'>
<div className="flex items-center justify-between text-center">
<div>
<h1 className='text-xl'>🪂<strong> {t('components.airdropBanner.title')}</strong></h1>
<p className="font-medium">
{t('components.airdropBanner.description')}
</p>
</div>

<div className="flex flex-col items-center justify-center">
<div className="flex items-center justify-between text-center">
<div>
<h1 className="text-xl">
🪂<strong> {t('components.airdropBanner.title')}</strong>
</h1>
<p className="font-medium">{t('components.airdropBanner.description')}</p>
</div>
<div>
<ChevronDownIcon className={`w-6 h-6 transition-transform duration-300 ${expanded ? 'rotate-180' : ''}`} />
</div>
</div>
<button className="bg-[#000] text-white px-4 py-2 rounded-md mt-4 cursor-pointer">{t('components.airdropBanner.button')}</button>
</div>

<AnimatePresence>
Expand All @@ -57,15 +57,31 @@ export const AirdropBanner = () => {
animate={{ opacity: 1, x: 0 }}
transition={{ delay: 0.2 }}
>
<Trans i18nKey="components.airdropBanner.list.2">All eligible users get $10 USDT - <strong>the first 100 receive a 10 bonus, totaling 20 USDT.</strong> Rewards go to your wallet on Base or AssetHub.</Trans>
<Trans i18nKey="components.airdropBanner.list.2">
All eligible users get $10 USDT - <strong>the first 100 receive a 10 bonus, totaling 20 USDT.</strong>{' '}
Rewards go to your wallet on Base or AssetHub.
</Trans>
</motion.li>
<motion.li
className="mb-2"
initial={{ opacity: 0, x: -10 }}
animate={{ opacity: 1, x: 0 }}
transition={{ delay: 0.3 }}
>
{t('components.airdropBanner.list.3')}
<Trans i18nKey="components.airdropBanner.list.3">
One reward per person - Check
<a
className="underline hover:text-blue-700 transition"
href="https://github.com/pendulum-chain/vortex/blob/campaign-may-2025/eligible-users.csv"
target="_blank"
onClick={(e) => e.stopPropagation()}
rel="noreferrer"
>
{' '}
here
</a>{' '}
(Updates every 24hrs)
</Trans>
</motion.li>
</ul>
</motion.div>
Expand Down
14 changes: 7 additions & 7 deletions frontend/src/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -180,13 +180,13 @@
},
"components": {
"airdropBanner": {
"title": "Special offer",
"description": "Buy or Sell just R$5 or €10 - get 20 USDT for FREE",
"title": "Special offer until 15 May",
"description": "Buy or sell USDT/C from just R$5 - get 20 USDT for FREE",
"button": "More info",
"list": {
"1": "Buy or sell from just R$5 (PIX) or €10 (SEPA) - quick, easy, and no hidden fees.",
"2": "All eligible users get 10 USDT - <strong>the first 100 receive a 10 USDT bonus, totaling 20 USDT.</strong> Rewards go to your wallet on Base or AssetHub.",
"3": "One reward per user - we use KYC and on-chain checks to ensure fairness and prevent abuse."
"1": "Buy or sell USDT/C from just R$5 (PIX) - quick, easy, and no hidden fees.",
"2": "<1>All eligible users get 10 USDT</1> - the first 100 receive a 10 USDT bonus, totaling 20 USDT. Rewards go to your wallet on Base or AssetHub a week after campaign ends.",
"3": "One reward per person - Check <1>here</1> (Updates every 24hrs)"
}
},
"emailForm": {
Expand Down Expand Up @@ -432,8 +432,8 @@
"uploadFailed": "Upload failed. Please try again.",
"fields": {
"uploadSelfie": "Upload Selfie",
"rgFront": "RG Front",
"rgBack": "RG Back",
"rgFront": "RG Front",
"rgBack": "RG Back",
"cnhDocument": "CNH Document"
},
"buttons": {
Expand Down
44 changes: 22 additions & 22 deletions frontend/src/translations/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -180,13 +180,13 @@
},
"components": {
"airdropBanner": {
"title": "Oferta especial",
"description": "Compre ou venda apenas R$5 ou €10 - receba 20 USDT de graça!",
"title": "Oferta especial até 15 Maio",
"description": "Compre ou venda USDT/C por apenas R$5 - receba 20 USDT de graça!",
"button": "Mais informações",
"list": {
"1": "Compre ou venda de R$5 (PIX) ou €10 (SEPA) - rápido, fácil e sem taxas ocultas.",
"2": "Todos os usuários elegíveis recebem 10 USDT - <strong>os primeiros 100 recebem um bônus de 10 USDT, totalizando 20 USDT.</strong> Recompensas vão para sua carteira na Base ou AssetHub.",
"3": "Uma recompensa por utilizador - utilizamos verificações KYC e na cadeia para garantir a equidade e evitar abusos."
"1": "Compre ou venda USDT/C por apenas R$5 (PIX) - rápido, fácil e sem taxas ocultas.",
"2": "<1>Todos os usuários elegíveis recebem 10 USDT</1> - os primeiros 100 recebem um bônus de 10 USDT, totalizando 20 USDT. Recompensas vão para sua carteira na Base ou AssetHub após o término da campanha.",
"3": "Uma recompensa por pessoa - Verifique <1>aqui</1> (Atualiza a cada 24 horas)"
}
},
"emailForm": {
Expand Down Expand Up @@ -411,25 +411,25 @@
}
},
"documentUpload": {
"title": "Verificação Rápida",
"description": "Para garantir uma experiência segura e fluida, precisamos de uma rápida verificação de identidade. Por favor, envie uma imagem nítida do seu documento.",
"validation": {
"invalidFileType": "Tipo de arquivo inválido. Apenas PNG, JPEG ou PDF são permitidos.",
"fileSizeExceeded": "O tamanho do arquivo excede o limite de {{max}}.",
"validationError": "Todos os arquivos devem ser válidos antes de enviar."
"title": "Verificação Rápida",
"description": "Para garantir uma experiência segura e fluida, precisamos de uma rápida verificação de identidade. Por favor, envie uma imagem nítida do seu documento.",
"validation": {
"invalidFileType": "Tipo de arquivo inválido. Apenas PNG, JPEG ou PDF são permitidos.",
"fileSizeExceeded": "O tamanho do arquivo excede o limite de {{max}}.",
"validationError": "Todos os arquivos devem ser válidos antes de enviar."
},
"uploadBug": "Ocorreu um erro ao enviar os arquivos para verificação. Por favor, tente novamente mais tarde.",
"uploadFailed": "Falha no envio. Por favor, tente novamente.",
"fields": {
"uploadSelfie": "Enviar selfie",
"rgFront": "Frente do RG",
"rgBack": "Verso do RG",
"cnhDocument": "Documento CNH"
"uploadBug": "Ocorreu um erro ao enviar os arquivos para verificação. Por favor, tente novamente mais tarde.",
"uploadFailed": "Falha no envio. Por favor, tente novamente.",
"fields": {
"uploadSelfie": "Enviar selfie",
"rgFront": "Frente do RG",
"rgBack": "Verso do RG",
"cnhDocument": "Documento CNH"
},
"buttons": {
"back": "Voltar",
"uploading": "Enviando...",
"finish": "Concluir"
"buttons": {
"back": "Voltar",
"uploading": "Enviando...",
"finish": "Concluir"
}
},
"rating": {
Expand Down
Loading