feat: adiciona react-router-dom, refatora App para router e cria pagina oculta de sucesso

This commit is contained in:
AI Studio Assistant 2026-05-09 16:06:27 +00:00
parent ab25fb0e5a
commit 31aed0d1b7
6 changed files with 237 additions and 44 deletions

58
package-lock.json generated
View file

@ -19,6 +19,7 @@
"motion": "^12.23.24",
"react": "^19.0.1",
"react-dom": "^19.0.1",
"react-router-dom": "^7.15.0",
"tailwind-merge": "^3.5.0",
"vite": "^6.2.3"
},
@ -3347,6 +3348,57 @@
"node": ">=0.10.0"
}
},
"node_modules/react-router": {
"version": "7.15.0",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.15.0.tgz",
"integrity": "sha512-HW9vYwuM8f4yx66Izy8xfrzCM+SBJluoZcCbww9A1TySax11S5Vgw6fi3ZjMONw9J4gQwngL7PzkyIpJJpJ7RQ==",
"license": "MIT",
"dependencies": {
"cookie": "^1.0.1",
"set-cookie-parser": "^2.6.0"
},
"engines": {
"node": ">=20.0.0"
},
"peerDependencies": {
"react": ">=18",
"react-dom": ">=18"
},
"peerDependenciesMeta": {
"react-dom": {
"optional": true
}
}
},
"node_modules/react-router-dom": {
"version": "7.15.0",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.15.0.tgz",
"integrity": "sha512-VcrVg64Fo8nwBvDscajG8gRTLIuTC6N50nb22l2HOOV4PTOHgoGp8mUjy9wLiHYoYTSYI36tUnXZgasSRFZorQ==",
"license": "MIT",
"dependencies": {
"react-router": "7.15.0"
},
"engines": {
"node": ">=20.0.0"
},
"peerDependencies": {
"react": ">=18",
"react-dom": ">=18"
}
},
"node_modules/react-router/node_modules/cookie": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz",
"integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==",
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/resolve-pkg-maps": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
@ -3505,6 +3557,12 @@
"node": ">= 0.8.0"
}
},
"node_modules/set-cookie-parser": {
"version": "2.7.2",
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz",
"integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==",
"license": "MIT"
},
"node_modules/setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",

View file

@ -22,6 +22,7 @@
"motion": "^12.23.24",
"react": "^19.0.1",
"react-dom": "^19.0.1",
"react-router-dom": "^7.15.0",
"tailwind-merge": "^3.5.0",
"vite": "^6.2.3"
},

View file

@ -0,0 +1,23 @@
import { execSync } from 'child_process';
async function pushUpdates() {
try {
console.log('\nAdicionando arquivos para página de sucesso/vendas...');
execSync('git add package.json package-lock.json src/App.tsx src/pages/LandingPage.tsx src/pages/SuccessPage.tsx scripts/push-success-page.ts', { stdio: 'inherit' });
try {
execSync('git commit -m "feat: adiciona react-router-dom, refatora App para router e cria pagina oculta de sucesso"', { stdio: 'inherit' });
} catch (e) {
console.log('Nada para commitar.');
}
console.log('\nFazendo push do código...');
execSync('git push origin main', { stdio: 'inherit' });
console.log(`\n🎉 Push concluído com sucesso!`);
} catch (error: any) {
console.error('\n❌ Ocorreu um erro:', error.message);
}
}
pushUpdates();

View file

@ -1,49 +1,14 @@
import { motion, useScroll, useSpring } from 'framer-motion';
import Navbar from './components/Navbar';
import Hero from './components/Hero';
import Problem from './components/Problem';
import HowItWorks from './components/HowItWorks';
import Benefits from './components/Benefits';
import Gallery from './components/Gallery';
import Offer from './components/Offer';
import FAQ from './components/FAQ';
import CTA from './components/CTA';
import Footer from './components/Footer';
import Results from './components/Results';
import StickyMobileCTA from './components/StickyMobileCTA';
import { useUTMForwarder } from './hooks/useUTMForwarder';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import LandingPage from './pages/LandingPage';
import SuccessPage from './pages/SuccessPage';
export default function App() {
const { scrollYProgress } = useScroll();
const scaleX = useSpring(scrollYProgress, {
stiffness: 100,
damping: 30,
restDelta: 0.001
});
// Ativa o repasse automático de UTMs para links de checkout
useUTMForwarder();
return (
<div className="min-h-screen bg-pink-50 text-indigo-900 selection:bg-pink-300 selection:text-indigo-950 font-sans overflow-x-hidden">
<motion.div
className="fixed top-0 left-0 right-0 h-1.5 bg-gradient-to-r from-pink-400 via-violet-400 to-amber-400 origin-left z-50"
style={{ scaleX }}
/>
<Navbar />
<main>
<Hero />
<Problem />
<HowItWorks />
<Benefits />
<Gallery />
<Results />
<Offer />
<FAQ />
<CTA />
</main>
<Footer />
<StickyMobileCTA />
</div>
<BrowserRouter>
<Routes>
<Route path="/" element={<LandingPage />} />
<Route path="/sucesso" element={<SuccessPage />} />
</Routes>
</BrowserRouter>
);
}

49
src/pages/LandingPage.tsx Normal file
View file

@ -0,0 +1,49 @@
import { motion, useScroll, useSpring } from 'framer-motion';
import Navbar from '../components/Navbar';
import Hero from '../components/Hero';
import Problem from '../components/Problem';
import HowItWorks from '../components/HowItWorks';
import Benefits from '../components/Benefits';
import Gallery from '../components/Gallery';
import Offer from '../components/Offer';
import FAQ from '../components/FAQ';
import CTA from '../components/CTA';
import Footer from '../components/Footer';
import Results from '../components/Results';
import StickyMobileCTA from '../components/StickyMobileCTA';
import { useUTMForwarder } from '../hooks/useUTMForwarder';
export default function LandingPage() {
const { scrollYProgress } = useScroll();
const scaleX = useSpring(scrollYProgress, {
stiffness: 100,
damping: 30,
restDelta: 0.001
});
// Ativa o repasse automático de UTMs para links de checkout
useUTMForwarder();
return (
<div className="min-h-screen bg-pink-50 text-indigo-900 selection:bg-pink-300 selection:text-indigo-950 font-sans overflow-x-hidden">
<motion.div
className="fixed top-0 left-0 right-0 h-1.5 bg-gradient-to-r from-pink-400 via-violet-400 to-amber-400 origin-left z-50"
style={{ scaleX }}
/>
<Navbar />
<main>
<Hero />
<Problem />
<HowItWorks />
<Benefits />
<Gallery />
<Results />
<Offer />
<FAQ />
<CTA />
</main>
<Footer />
<StickyMobileCTA />
</div>
);
}

97
src/pages/SuccessPage.tsx Normal file
View file

@ -0,0 +1,97 @@
import { CheckCircle, Clock, PlayCircle, Star, ArrowRight } from "lucide-react";
import Footer from "../components/Footer";
export default function SuccessPage() {
return (
<div className="min-h-screen bg-pink-50 text-indigo-900 selection:bg-pink-300 font-sans flex flex-col">
<main className="flex-1 py-12 px-4 md:px-6">
<div className="max-w-4xl mx-auto space-y-12">
{/* Success Banner */}
<section className="text-center bg-white rounded-3xl p-8 md:p-12 shadow-xl border border-pink-100">
<CheckCircle className="w-20 h-20 text-emerald-500 mx-auto mb-6" />
<h1 className="text-3xl md:text-5xl font-display font-bold text-indigo-950 mb-4">
Pagamento Confirmado!
</h1>
<p className="text-lg text-indigo-600 md:text-xl max-w-2xl mx-auto">
Seu acesso à plataforma Festa Mágica IA foi enviado para o seu e-mail.
Você pode começar a criar o seu kit exclusivo!
</p>
</section>
{/* Upsell Offer */}
<section className="relative bg-gradient-to-br from-indigo-950 via-indigo-900 to-violet-900 rounded-3xl p-1 md:p-1.5 shadow-2xl overflow-hidden">
{/* Animated border effect */}
<div className="absolute inset-0 bg-gradient-to-r from-amber-400 via-pink-500 to-violet-400 animate-pulse opacity-50" />
<div className="relative bg-white rounded-[1.4rem] md:rounded-[1.3rem] p-6 text-center shadow-inner">
<div className="inline-flex items-center gap-2 bg-amber-100 text-amber-700 px-4 py-1.5 rounded-full text-sm font-bold tracking-wide uppercase mb-6">
<Clock className="w-4 h-4" /> Oferta Única
</div>
<h2 className="text-2xl md:text-4xl font-display font-bold text-indigo-950 mb-4">
Espere! Leve também o <span className="text-pink-600">Convite Animado</span>
</h2>
<p className="text-indigo-600 mb-8 max-w-2xl mx-auto text-lg md:text-xl">
Quer impressionar ainda mais os convidados? Adicione ao seu pedido um convite em vídeo exclusivo com música, animações e o personagem do seu filho.
</p>
<div className="flex flex-col md:flex-row items-center justify-center gap-8 mb-8">
{/* Mockup ou Imagem - usando um placeholder criativo */}
<div className="relative w-full max-w-xs aspect-[9/16] bg-indigo-950 rounded-2xl p-2 shadow-2xl overflow-hidden border-4 border-indigo-100">
<img
src="https://images.unsplash.com/photo-1541701494587-cb58502866ab?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80"
alt="Exemplo Convite Animado"
className="w-full h-full object-cover rounded-xl opacity-80"
/>
<div className="absolute inset-0 flex items-center justify-center">
<PlayCircle className="w-16 h-16 text-white/90 drop-shadow-xl" />
</div>
</div>
<div className="text-left space-y-6 flex-1 max-w-sm">
<ul className="space-y-4">
<li className="flex items-start gap-3">
<Star className="w-6 h-6 text-amber-400 shrink-0" fill="currentColor" />
<span className="font-medium text-indigo-900">Perfeito para enviar pelo WhatsApp</span>
</li>
<li className="flex items-start gap-3">
<Star className="w-6 h-6 text-amber-400 shrink-0" fill="currentColor" />
<span className="font-medium text-indigo-900">Música e efeitos sonoros super divertidos</span>
</li>
<li className="flex items-start gap-3">
<Star className="w-6 h-6 text-amber-400 shrink-0" fill="currentColor" />
<span className="font-medium text-indigo-900">Mantém a mesma temática escolhida da festa</span>
</li>
</ul>
<div className="pt-4 border-t border-indigo-50">
<div className="text-sm text-indigo-500 line-through font-medium">De R$ 49,90 por apenas</div>
<div className="text-4xl font-black text-indigo-950">R$ 19,90</div>
</div>
<div className="space-y-3">
<a
href="#"
className="group flex w-full justify-center md:inline-flex items-center gap-2 bg-gradient-to-r from-pink-500 to-violet-500 text-white px-8 py-4 rounded-full font-bold text-lg hover:-translate-y-1 hover:shadow-xl hover:shadow-pink-500/20 transition-all"
>
Adicionar ao Pedido <ArrowRight className="w-5 h-5 group-hover:translate-x-1 transition-transform" />
</a>
<a
href="#"
className="block text-center text-sm font-medium text-indigo-400 hover:text-indigo-600 transition-colors uppercase tracking-wider"
>
Não, quero apenas o Kit Festa.
</a>
</div>
</div>
</div>
</div>
</section>
</div>
</main>
<Footer />
</div>
);
}