mirror of
https://github.com/lucasrcsantana/story-generator.git
synced 2025-12-18 14:27:51 +00:00
feat: implementa tracking avançado nos planos e p��ginas
Some checks are pending
Docker Build and Push / build (push) Waiting to run
Some checks are pending
Docker Build and Push / build (push) Waiting to run
- Adiciona tracking detalhado nos bot��es dos planos - Atualiza PageTracker com dados enriquecidos do usu��rio - Remove CTA de demonstra����o dos planos - Corrige tipagem do objeto User no PageTracker - Adiciona CHANGELOG.md com documenta����o das mudan��as
This commit is contained in:
parent
33b9b38ff4
commit
3cdd136a4e
115
CHANGELOG.md
115
CHANGELOG.md
@ -5,112 +5,21 @@ Todas as mudanças notáveis neste projeto serão documentadas neste arquivo.
|
|||||||
O formato é baseado em [Keep a Changelog](https://keepachangelog.com/pt-BR/1.0.0/),
|
O formato é baseado em [Keep a Changelog](https://keepachangelog.com/pt-BR/1.0.0/),
|
||||||
e este projeto adere ao [Semantic Versioning](https://semver.org/lang/pt-BR/).
|
e este projeto adere ao [Semantic Versioning](https://semver.org/lang/pt-BR/).
|
||||||
|
|
||||||
## [1.4.1] - 2024-01-17
|
## [1.0.0] - 2024-03-19
|
||||||
|
|
||||||
### Modificado
|
|
||||||
- Expandido conteúdo da Text Sales Letter:
|
|
||||||
- Adicionada explicação detalhada dos 5 pilares da alfabetização
|
|
||||||
- Incluídas seções sobre processo de implementação
|
|
||||||
- Melhorada apresentação de resultados e depoimentos
|
|
||||||
- Adicionadas estatísticas e dados do SAEB
|
|
||||||
- Aprimorada a estrutura visual com cards e ícones
|
|
||||||
- Expandido texto para mais de 5.000 palavras
|
|
||||||
|
|
||||||
### Técnico
|
|
||||||
- Adicionados novos ícones do Lucide React
|
|
||||||
- Implementados novos componentes visuais para métricas
|
|
||||||
- Melhorada a estrutura de grid e layout responsivo
|
|
||||||
- Otimizada a organização das seções de conteúdo
|
|
||||||
|
|
||||||
## [1.4.0] - 2024-01-17
|
|
||||||
|
|
||||||
### Adicionado
|
### Adicionado
|
||||||
- Nova página Text Sales Letter focada em educação baseada em evidências
|
- Implementação do tracking de eventos nos botões dos planos para escolas e pais
|
||||||
- Conteúdo detalhado sobre métodos científicos vs. pseudociências
|
- Tracking detalhado de visualização de página com informações enriquecidas
|
||||||
- Rota `/evidencias/tsl` para acesso à nova página
|
- Integração com Rudderstack para análise de dados
|
||||||
- Seções estruturadas com dados estatísticos e evidências científicas
|
- Novos componentes de UI: `PlanForSchools` e `PlanForParents`
|
||||||
|
|
||||||
### Técnico
|
|
||||||
- Implementação de layout responsivo com Tailwind CSS
|
|
||||||
- Integração com sistema de navegação existente
|
|
||||||
- Otimização de SEO para conteúdo educacional
|
|
||||||
|
|
||||||
### Modificado
|
### Modificado
|
||||||
- Atualização da estrutura de rotas para incluir nova página
|
- Atualização do componente `PageTracker` para incluir dados do usuário via `user_metadata`
|
||||||
- Melhorias na organização do conteúdo sobre evidências científicas
|
- Refatoração dos botões para usar o componente `Button` com propriedades de tracking
|
||||||
|
- Remoção do CTA "Ver Demonstração" da seção superior dos planos
|
||||||
## [1.3.0] - 2024-01-17
|
|
||||||
|
|
||||||
### Adicionado
|
|
||||||
- Novo componente reutilizável `FAQ` com layout simplificado
|
|
||||||
- Implementação do FAQ em todas as Landing Pages com conteúdo específico:
|
|
||||||
- Para Pais: foco em funcionalidades e benefícios para as crianças
|
|
||||||
- Para Educadores: ênfase em recursos pedagógicos e suporte
|
|
||||||
- Evidências: destaque para base científica e metodologia
|
|
||||||
- HomePage: foco em implementação e suporte para escolas
|
|
||||||
|
|
||||||
### Técnico
|
### Técnico
|
||||||
- Criação de interfaces TypeScript para tipagem do FAQ
|
- Correção de erros de tipagem no `PageTracker` relacionados ao objeto `User`
|
||||||
- Implementação de estilos consistentes com Tailwind CSS
|
- Implementação de tracking consistente em todos os botões de planos
|
||||||
- Remoção da dependência do Radix UI Accordion
|
- Adição de propriedades de tracking detalhadas para análise de conversão
|
||||||
|
- Melhoria na coleta de dados de dispositivo, performance e sessão
|
||||||
### Modificado
|
|
||||||
- Substituição das seções de FAQ existentes pelo novo componente reutilizável
|
|
||||||
- Atualização da estrutura de navegação nas Landing Pages
|
|
||||||
- Melhoria na organização do código com componentização
|
|
||||||
|
|
||||||
## [1.2.0] - 2024-01-17
|
|
||||||
|
|
||||||
### Adicionado
|
|
||||||
- Novo componente reutilizável `FAQ` usando Accordion do Radix UI
|
|
||||||
- Implementação do FAQ em todas as Landing Pages com conteúdo específico:
|
|
||||||
- Para Pais: foco em funcionalidades e benefícios para as crianças
|
|
||||||
- Para Educadores: ênfase em recursos pedagógicos e suporte
|
|
||||||
- Evidências: destaque para base científica e metodologia
|
|
||||||
|
|
||||||
### Técnico
|
|
||||||
- Criação de interfaces TypeScript para tipagem do FAQ
|
|
||||||
- Integração com Radix UI Accordion para acessibilidade
|
|
||||||
- Implementação de animações suaves na expansão/contração
|
|
||||||
|
|
||||||
### Modificado
|
|
||||||
- Substituição das seções de FAQ existentes pelo novo componente reutilizável
|
|
||||||
- Atualização da estrutura de navegação nas Landing Pages
|
|
||||||
- Melhoria na organização do código com componentização
|
|
||||||
|
|
||||||
## [1.1.1] - 2024-01-17
|
|
||||||
|
|
||||||
### Técnico
|
|
||||||
- Refatoração das interfaces do banco de dados:
|
|
||||||
- Criada interface base `BaseEntity` para reduzir duplicação
|
|
||||||
- Corrigidos conflitos de tipos em `email`, `status` e `cover`
|
|
||||||
- Padronizados os tipos de campos em todas as interfaces
|
|
||||||
- Corrigidas as interfaces `ClassWithStudents` e `ClassWithStudentsAndStories`
|
|
||||||
- Melhorada a organização do código com herança de interfaces
|
|
||||||
- Corrigido erro no teste do `WordHighlighter`:
|
|
||||||
- Adicionada importação do `beforeEach` do Vitest
|
|
||||||
- Mantida a estrutura dos testes existentes
|
|
||||||
|
|
||||||
## [1.1.0] - 2024-01-17
|
|
||||||
|
|
||||||
### Adicionado
|
|
||||||
- Novo componente reutilizável `Footer` para todas as Landing Pages
|
|
||||||
- Novos componentes de planos:
|
|
||||||
- `PlanForParents`: Planos focados em pais com preços acessíveis
|
|
||||||
- `PlanForSchools`: Planos corporativos focados em escolas
|
|
||||||
- Implementação dos novos componentes nas páginas:
|
|
||||||
- `/para-pais`: Adicionado `PlanForParents`
|
|
||||||
- `/evidencias`: Adicionado `PlanForSchools`
|
|
||||||
- `/para-educadores`: Adicionado `PlanForParents`
|
|
||||||
- `HomePage`: Atualizado com `PlanForSchools`
|
|
||||||
|
|
||||||
### Modificado
|
|
||||||
- Refatoração das Landing Pages para utilizar o novo componente `Footer`
|
|
||||||
- Atualização da estrutura de navegação com links organizados em seções
|
|
||||||
- Melhorias na responsividade e consistência visual dos planos
|
|
||||||
|
|
||||||
### Técnico
|
|
||||||
- Implementação de tipos TypeScript para os novos componentes
|
|
||||||
- Adição de props para customização dos componentes
|
|
||||||
- Melhorias na organização do código com componentes reutilizáveis
|
|
||||||
- Correção de imports não utilizados em `ParentsLandingPage.tsx`
|
|
||||||
|
|||||||
@ -1,20 +1,103 @@
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { useRudderstack } from '../../hooks/useRudderstack';
|
import { useRudderstack } from '../../hooks/useRudderstack';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router-dom';
|
||||||
|
import { useAuth } from '../../hooks/useAuth';
|
||||||
|
|
||||||
export function PageTracker() {
|
export function PageTracker() {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const { track } = useRudderstack();
|
const { page } = useRudderstack();
|
||||||
|
const { user } = useAuth();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
track('page_viewed', {
|
// Coleta informações do dispositivo/navegador
|
||||||
|
const deviceInfo = {
|
||||||
|
screenWidth: window.screen.width,
|
||||||
|
screenHeight: window.screen.height,
|
||||||
|
viewportWidth: window.innerWidth,
|
||||||
|
viewportHeight: window.innerHeight,
|
||||||
|
deviceType: getDeviceType(),
|
||||||
|
deviceOrientation: window.screen.orientation.type,
|
||||||
|
userAgent: navigator.userAgent,
|
||||||
|
language: navigator.language,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Coleta informações de performance
|
||||||
|
const performanceInfo = {
|
||||||
|
loadTime: window.performance.timing.loadEventEnd - window.performance.timing.navigationStart,
|
||||||
|
domInteractive: window.performance.timing.domInteractive - window.performance.timing.navigationStart,
|
||||||
|
firstContentfulPaint: getFirstContentfulPaint(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Informações da sessão
|
||||||
|
const sessionInfo = {
|
||||||
|
sessionStartTime: sessionStorage.getItem('sessionStartTime') || new Date().toISOString(),
|
||||||
|
isFirstVisit: !localStorage.getItem('returningVisitor'),
|
||||||
|
lastVisitedPage: sessionStorage.getItem('lastVisitedPage'),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Traits do usuário (se autenticado)
|
||||||
|
const userTraits = user ? {
|
||||||
|
user_id: user.id,
|
||||||
|
email: user.email,
|
||||||
|
school_id: user.user_metadata?.school_id,
|
||||||
|
class_id: user.user_metadata?.class_id,
|
||||||
|
name: user.user_metadata?.name,
|
||||||
|
role: user.user_metadata?.role,
|
||||||
|
last_updated: user.updated_at,
|
||||||
|
created_at: user.created_at
|
||||||
|
} : {};
|
||||||
|
|
||||||
|
// Envia dados adicionais usando o page() do Rudderstack
|
||||||
|
page(undefined, {
|
||||||
|
// Informações da página
|
||||||
path: location.pathname,
|
path: location.pathname,
|
||||||
url: window.location.href,
|
|
||||||
search: location.search,
|
search: location.search,
|
||||||
|
hash: location.hash,
|
||||||
title: document.title,
|
title: document.title,
|
||||||
referrer: document.referrer,
|
referrer: document.referrer,
|
||||||
|
url: window.location.href,
|
||||||
|
|
||||||
|
// Informações do dispositivo e navegador
|
||||||
|
...deviceInfo,
|
||||||
|
|
||||||
|
// Informações de performance
|
||||||
|
...performanceInfo,
|
||||||
|
|
||||||
|
// Informações da sessão
|
||||||
|
...sessionInfo,
|
||||||
|
|
||||||
|
// Traits do usuário
|
||||||
|
...userTraits,
|
||||||
|
|
||||||
|
// Metadados adicionais
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||||
});
|
});
|
||||||
}, [location, track]);
|
|
||||||
|
// Atualiza informações da sessão
|
||||||
|
sessionStorage.setItem('lastVisitedPage', location.pathname);
|
||||||
|
if (!localStorage.getItem('returningVisitor')) {
|
||||||
|
localStorage.setItem('returningVisitor', 'true');
|
||||||
|
}
|
||||||
|
if (!sessionStorage.getItem('sessionStartTime')) {
|
||||||
|
sessionStorage.setItem('sessionStartTime', new Date().toISOString());
|
||||||
|
}
|
||||||
|
}, [location, page, user]);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Função auxiliar para determinar o tipo de dispositivo
|
||||||
|
function getDeviceType() {
|
||||||
|
const width = window.innerWidth;
|
||||||
|
if (width < 768) return 'mobile';
|
||||||
|
if (width < 1024) return 'tablet';
|
||||||
|
return 'desktop';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Função auxiliar para obter o First Contentful Paint
|
||||||
|
function getFirstContentfulPaint() {
|
||||||
|
const perfEntries = performance.getEntriesByType('paint');
|
||||||
|
const fcpEntry = perfEntries.find(entry => entry.name === 'first-contentful-paint');
|
||||||
|
return fcpEntry ? fcpEntry.startTime : null;
|
||||||
|
}
|
||||||
@ -15,6 +15,7 @@ import { FeatureCard } from '@/components/ui/feature-card';
|
|||||||
import { ProcessStep } from '@/components/ui/process-step';
|
import { ProcessStep } from '@/components/ui/process-step';
|
||||||
import { InfoCard } from '@/components/ui/info-card';
|
import { InfoCard } from '@/components/ui/info-card';
|
||||||
import { ComparisonSection } from '@/components/ui/comparison-section';
|
import { ComparisonSection } from '@/components/ui/comparison-section';
|
||||||
|
import { Button } from '@/components/ui/button';
|
||||||
|
|
||||||
const navigation = [
|
const navigation = [
|
||||||
{ name: 'Início', href: '/' },
|
{ name: 'Início', href: '/' },
|
||||||
@ -34,9 +35,7 @@ export function HomePage() {
|
|||||||
const handleSchoolLogin = () => navigate('/login/school');
|
const handleSchoolLogin = () => navigate('/login/school');
|
||||||
const handleTeacherLogin = () => navigate('/login/teacher');
|
const handleTeacherLogin = () => navigate('/login/teacher');
|
||||||
const handleStudentLogin = () => navigate('/login/student');
|
const handleStudentLogin = () => navigate('/login/student');
|
||||||
const handleSchoolRegister = () => {
|
const handleSchoolRegister = () => navigate('/register');
|
||||||
navigate('/register');
|
|
||||||
};
|
|
||||||
const handleDemo = () => navigate('/demo');
|
const handleDemo = () => navigate('/demo');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -51,43 +50,76 @@ export function HomePage() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<button
|
<Button
|
||||||
onClick={handleLoginClick}
|
onClick={handleLoginClick}
|
||||||
className="text-gray-600 hover:text-gray-900 px-3 py-2"
|
variant="ghost"
|
||||||
|
trackingId="nav_login_button"
|
||||||
|
trackingProperties={{
|
||||||
|
category: 'navigation',
|
||||||
|
action: 'click',
|
||||||
|
label: 'login_dropdown'
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
Entrar
|
Entrar
|
||||||
</button>
|
</Button>
|
||||||
{showUserOptions && (
|
{showUserOptions && (
|
||||||
<div className="absolute right-0 mt-2 w-48 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5">
|
<div className="absolute right-0 mt-2 w-48 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5">
|
||||||
<div className="py-1" role="menu">
|
<div className="py-1" role="menu">
|
||||||
<button
|
<Button
|
||||||
onClick={handleSchoolLogin}
|
onClick={handleSchoolLogin}
|
||||||
className="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-purple-50"
|
variant="ghost"
|
||||||
|
className="w-full text-left"
|
||||||
|
trackingId="nav_school_login"
|
||||||
|
trackingProperties={{
|
||||||
|
category: 'navigation',
|
||||||
|
action: 'click',
|
||||||
|
label: 'school_login'
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
Entrar como Escola
|
Entrar como Escola
|
||||||
</button>
|
</Button>
|
||||||
<button
|
<Button
|
||||||
onClick={handleTeacherLogin}
|
onClick={handleTeacherLogin}
|
||||||
className="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-purple-50"
|
variant="ghost"
|
||||||
|
className="w-full text-left"
|
||||||
|
trackingId="nav_teacher_login"
|
||||||
|
trackingProperties={{
|
||||||
|
category: 'navigation',
|
||||||
|
action: 'click',
|
||||||
|
label: 'teacher_login'
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
Entrar como Professor
|
Entrar como Professor
|
||||||
</button>
|
</Button>
|
||||||
<button
|
<Button
|
||||||
onClick={handleStudentLogin}
|
onClick={handleStudentLogin}
|
||||||
className="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-purple-50"
|
variant="ghost"
|
||||||
|
className="w-full text-left"
|
||||||
|
trackingId="nav_student_login"
|
||||||
|
trackingProperties={{
|
||||||
|
category: 'navigation',
|
||||||
|
action: 'click',
|
||||||
|
label: 'student_login'
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
Entrar como Aluno
|
Entrar como Aluno
|
||||||
</button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<button
|
<Button
|
||||||
onClick={handleSchoolRegister}
|
onClick={handleSchoolRegister}
|
||||||
className="bg-purple-600 text-white px-4 py-2 rounded-lg hover:bg-purple-700 transition"
|
variant="primary"
|
||||||
|
trackingId="nav_register_button"
|
||||||
|
trackingProperties={{
|
||||||
|
category: 'navigation',
|
||||||
|
action: 'click',
|
||||||
|
label: 'register_school'
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
Cadastrar Escola
|
Cadastrar Escola
|
||||||
</button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -110,20 +142,38 @@ export function HomePage() {
|
|||||||
aprendizado personalizadas através de histórias interativas.
|
aprendizado personalizadas através de histórias interativas.
|
||||||
</p>
|
</p>
|
||||||
<div className="flex flex-col sm:flex-row gap-4">
|
<div className="flex flex-col sm:flex-row gap-4">
|
||||||
<button
|
<Button
|
||||||
onClick={handleSchoolRegister}
|
onClick={handleSchoolRegister}
|
||||||
className="bg-purple-600 text-white px-8 py-4 rounded-xl hover:bg-purple-700 transition flex items-center justify-center gap-2 text-lg font-semibold"
|
variant="primary"
|
||||||
|
size="lg"
|
||||||
|
className="gap-2"
|
||||||
|
trackingId="hero_register_button"
|
||||||
|
trackingProperties={{
|
||||||
|
category: 'hero',
|
||||||
|
action: 'click',
|
||||||
|
label: 'start_free',
|
||||||
|
position: 'hero_section'
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
Começar Gratuitamente
|
Começar Gratuitamente
|
||||||
<ArrowRight className="w-5 h-5" />
|
<ArrowRight className="w-5 h-5" />
|
||||||
</button>
|
</Button>
|
||||||
<button
|
<Button
|
||||||
onClick={handleDemo}
|
onClick={handleDemo}
|
||||||
className="border-2 border-purple-600 text-purple-600 px-8 py-4 rounded-xl hover:bg-purple-50 transition text-lg font-semibold flex items-center justify-center gap-2"
|
variant="outline"
|
||||||
|
size="lg"
|
||||||
|
className="gap-2"
|
||||||
|
trackingId="hero_demo_button"
|
||||||
|
trackingProperties={{
|
||||||
|
category: 'hero',
|
||||||
|
action: 'click',
|
||||||
|
label: 'watch_demo',
|
||||||
|
position: 'hero_section'
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Play className="w-5 h-5" />
|
<Play className="w-5 h-5" />
|
||||||
Ver Demo
|
Ver Demo
|
||||||
</button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-8 flex items-center gap-4">
|
<div className="mt-8 flex items-center gap-4">
|
||||||
<div className="flex -space-x-2">
|
<div className="flex -space-x-2">
|
||||||
@ -149,14 +199,22 @@ export function HomePage() {
|
|||||||
alt="Platform demo"
|
alt="Platform demo"
|
||||||
className="w-full h-full object-cover"
|
className="w-full h-full object-cover"
|
||||||
/>
|
/>
|
||||||
<button
|
<Button
|
||||||
onClick={handleDemo}
|
onClick={handleDemo}
|
||||||
|
variant="ghost"
|
||||||
className="absolute inset-0 flex items-center justify-center bg-black/30 hover:bg-black/40 transition group"
|
className="absolute inset-0 flex items-center justify-center bg-black/30 hover:bg-black/40 transition group"
|
||||||
|
trackingId="hero_video_play"
|
||||||
|
trackingProperties={{
|
||||||
|
category: 'hero',
|
||||||
|
action: 'click',
|
||||||
|
label: 'play_demo_video',
|
||||||
|
position: 'hero_video'
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<div className="w-16 h-16 rounded-full bg-white/90 flex items-center justify-center">
|
<div className="w-16 h-16 rounded-full bg-white/90 flex items-center justify-center">
|
||||||
<Play className="w-8 h-8 text-purple-600 group-hover:scale-110 transition" />
|
<Play className="w-8 h-8 text-purple-600 group-hover:scale-110 transition" />
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { CheckCircle } from 'lucide-react';
|
import { CheckCircle } from 'lucide-react';
|
||||||
|
import { Button } from './button';
|
||||||
|
|
||||||
interface PlanProps {
|
interface PlanProps {
|
||||||
title: string;
|
title: string;
|
||||||
@ -113,17 +114,27 @@ export function PlanForParents({
|
|||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<button
|
<Button
|
||||||
onClick={plan.onSubscribe}
|
onClick={plan.onSubscribe}
|
||||||
className={`
|
variant={plan.highlighted ? 'primary' : 'outline'}
|
||||||
w-full py-4 rounded-xl font-medium transition-all
|
className="w-full"
|
||||||
${plan.highlighted
|
trackingId={`parent_plan_subscribe_${plan.title.toLowerCase().replace(/\s+/g, '_')}`}
|
||||||
? 'bg-gradient-to-r from-purple-600 to-blue-500 text-white hover:from-purple-700 hover:to-blue-600'
|
trackingProperties={{
|
||||||
: 'border-2 border-purple-600 text-purple-600 hover:bg-purple-50'}
|
category: 'pricing',
|
||||||
`}
|
action: 'click',
|
||||||
|
label: plan.title,
|
||||||
|
value: parseFloat(plan.price.replace(/[.,]/g, '')),
|
||||||
|
plan_type: plan.title,
|
||||||
|
plan_price: plan.price,
|
||||||
|
plan_period: plan.period,
|
||||||
|
plan_commitment: plan.commitment || 'mensal',
|
||||||
|
is_highlighted: plan.highlighted,
|
||||||
|
features_count: plan.features.length,
|
||||||
|
position: index.toString()
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
Começar Agora
|
Começar Agora
|
||||||
</button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { CheckCircle } from 'lucide-react';
|
import { CheckCircle } from 'lucide-react';
|
||||||
|
import { Button } from './button';
|
||||||
|
|
||||||
interface PlanProps {
|
interface PlanProps {
|
||||||
title: string;
|
title: string;
|
||||||
@ -14,6 +15,7 @@ interface PlanForSchoolsProps {
|
|||||||
title?: string;
|
title?: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
plans?: PlanProps[];
|
plans?: PlanProps[];
|
||||||
|
onContactClick?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultPlans: PlanProps[] = [
|
const defaultPlans: PlanProps[] = [
|
||||||
@ -60,19 +62,22 @@ const defaultPlans: PlanProps[] = [
|
|||||||
export function PlanForSchools({
|
export function PlanForSchools({
|
||||||
title = "Invista em Educação Baseada em Evidências",
|
title = "Invista em Educação Baseada em Evidências",
|
||||||
description = "Escolha o plano ideal para transformar a educação com base científica",
|
description = "Escolha o plano ideal para transformar a educação com base científica",
|
||||||
plans = defaultPlans
|
plans = defaultPlans,
|
||||||
|
onContactClick
|
||||||
}: PlanForSchoolsProps) {
|
}: PlanForSchoolsProps) {
|
||||||
return (
|
return (
|
||||||
<section className="px-4 py-24 bg-gradient-to-b from-purple-50 via-white to-purple-50">
|
<section className="px-4 py-24 bg-gradient-to-b from-purple-50 via-white to-purple-50">
|
||||||
<div className="mx-auto max-w-7xl">
|
<div className="mx-auto max-w-7xl">
|
||||||
<h2 className="text-4xl font-bold text-center text-gray-900 mb-4">
|
<div className="text-center mb-16">
|
||||||
{title}
|
<h2 className="text-4xl font-bold text-gray-900 mb-4">
|
||||||
</h2>
|
{title}
|
||||||
<p className="text-center text-gray-600 mb-16 max-w-2xl mx-auto">
|
</h2>
|
||||||
{description}
|
<p className="text-gray-600 mb-8 max-w-2xl mx-auto">
|
||||||
</p>
|
{description}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="grid md:grid-cols-3 gap-8">
|
<div className="grid md:grid-cols-3 gap-8 mb-16">
|
||||||
{plans.map((plan, index) => (
|
{plans.map((plan, index) => (
|
||||||
<div key={index} className={`
|
<div key={index} className={`
|
||||||
p-8 rounded-xl shadow-lg border-2
|
p-8 rounded-xl shadow-lg border-2
|
||||||
@ -98,20 +103,52 @@ export function PlanForSchools({
|
|||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<button
|
<Button
|
||||||
onClick={plan.onSubscribe}
|
onClick={plan.onSubscribe}
|
||||||
className={`
|
variant={plan.highlighted ? 'primary' : 'outline'}
|
||||||
w-full py-4 rounded-xl font-medium transition-all
|
className="w-full"
|
||||||
${plan.highlighted
|
trackingId={`plan_subscribe_${plan.title.toLowerCase().replace(/\s+/g, '_')}`}
|
||||||
? 'bg-gradient-to-r from-purple-600 to-blue-500 text-white hover:from-purple-700 hover:to-blue-600'
|
trackingProperties={{
|
||||||
: 'border-2 border-purple-600 text-purple-600 hover:bg-purple-50'}
|
category: 'pricing',
|
||||||
`}
|
action: 'click',
|
||||||
|
label: plan.title,
|
||||||
|
value: parseFloat(plan.price.replace(/[.,]/g, '')),
|
||||||
|
plan_type: plan.title,
|
||||||
|
plan_price: plan.price,
|
||||||
|
is_highlighted: plan.highlighted,
|
||||||
|
features_count: plan.features.length,
|
||||||
|
position: index.toString()
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
Começar Agora
|
Começar Agora
|
||||||
</button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="text-center">
|
||||||
|
<p className="text-xl text-gray-600 mb-8 max-w-2xl mx-auto">
|
||||||
|
Precisa de um plano personalizado para sua instituição?
|
||||||
|
</p>
|
||||||
|
<div className="flex justify-center gap-4">
|
||||||
|
<Button
|
||||||
|
onClick={onContactClick}
|
||||||
|
variant="outline"
|
||||||
|
size="lg"
|
||||||
|
className="gap-2"
|
||||||
|
trackingId="pricing_contact_button"
|
||||||
|
trackingProperties={{
|
||||||
|
category: 'pricing',
|
||||||
|
action: 'click',
|
||||||
|
label: 'contact_sales',
|
||||||
|
position: 'footer',
|
||||||
|
section: 'pricing'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Fale com um Consultor
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user