Compare commits

...

16 Commits

Author SHA1 Message Date
Lucas Santana
33b9b38ff4 Ajustando Rudderstack
Some checks are pending
Docker Build and Push / build (push) Waiting to run
2025-01-11 15:29:52 -03:00
Lucas Santana
1bcb0a9c37 Ajustando Rudderstack 2025-01-11 15:24:31 -03:00
Lucas Santana
d2567ac478 Ajustando Rudderstack 2025-01-11 15:18:03 -03:00
Lucas Santana
953b7a78d0 Ajustando Rudderstack 2025-01-11 15:08:35 -03:00
Lucas Santana
21f7aa7c40 Implementando Rudderstack 2025-01-11 14:52:27 -03:00
Lucas Santana
6e9d847c77 Implementando Rudderstack 2025-01-11 14:45:47 -03:00
Lucas Santana
1542572be4 Implementação do GTM 2025-01-11 14:23:39 -03:00
Lucas Santana
75d9d4635b feat: Sentry implementado 2025-01-11 13:54:02 -03:00
Lucas Santana
a7612879bf feat: atualiza configurações de CORS e CSP 2025-01-11 13:46:22 -03:00
Lucas Santana
00cd9edb1c fix: Corrigindo a Interface do TestimonialCard 2025-01-11 10:37:46 -03:00
Lucas Santana
a45ebd2719 feat: Ajustando EducationalForParents 2025-01-11 10:08:15 -03:00
Lucas Santana
6398e2ac81 Consolidando estilos 2025-01-11 09:46:07 -03:00
Lucas Santana
0ccea7c7b9 feat: expande conteúdo da Text Sales Letter para mais de 5.000 palavras 2025-01-11 09:16:25 -03:00
Lucas Santana
9fa7b9732d feat: Text Sales Letter 2025-01-11 09:12:03 -03:00
Lucas Santana
6478d20d62 feat: adiciona Text Sales Letter sobre educa����o baseada em evid��ncias
- Cria p��gina TSL com foco em m��todos cient��ficos

- Adiciona rota /evidencias/tsl

- Atualiza CHANGELOG.md
2025-01-11 09:11:38 -03:00
Lucas Santana
0e2215b6ad feat: implementa FAQ simplificado em todas as Landing Pages
- Cria componente FAQ reutiliz��vel sem Accordion

- Implementa FAQ em todas as Landing Pages com conte��do espec��fico

- Remove depend��ncia do Radix UI

- Atualiza CHANGELOG.md
2025-01-11 09:05:54 -03:00
30 changed files with 2416 additions and 822 deletions

View File

@ -5,6 +5,79 @@ 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
### 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
- Nova página Text Sales Letter focada em educação baseada em evidências
- Conteúdo detalhado sobre métodos científicos vs. pseudociências
- Rota `/evidencias/tsl` para acesso à nova página
- Seções estruturadas com dados estatísticos e evidências científicas
### 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
- Atualização da estrutura de rotas para incluir nova página
- Melhorias na organização do conteúdo sobre evidências científicas
## [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
- Criação de interfaces TypeScript para tipagem do FAQ
- Implementação de estilos consistentes com Tailwind CSS
- Remoção da dependência do Radix UI Accordion
### 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 ## [1.1.1] - 2024-01-17
### Técnico ### Técnico

View File

@ -21,7 +21,35 @@
X-XSS-Protection = "1; mode=block" X-XSS-Protection = "1; mode=block"
X-Content-Type-Options = "nosniff" X-Content-Type-Options = "nosniff"
Referrer-Policy = "strict-origin-when-cross-origin" Referrer-Policy = "strict-origin-when-cross-origin"
Content-Security-Policy = "default-src 'self'; img-src 'self' data: https:; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';" Cross-Origin-Embedder-Policy = "credentialless"
Cross-Origin-Opener-Policy = "same-origin"
Cross-Origin-Resource-Policy = "cross-origin"
Content-Security-Policy = """
default-src 'self';
script-src 'self' 'unsafe-inline' 'unsafe-eval' https://*.rudderlabs.com https://*.cloudfront.net https://www.googletagmanager.com https://*.sentry.io;
connect-src 'self' https://*.rudderlabs.com https://*.ingest.sentry.io https://*.supabase.co https://www.google-analytics.com https://*.dataplane.rudderstack.com https://*.bugsnag.com/ https://*.ingest.us.sentry.io/ https://*.sentry.io/;
style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
img-src 'self' data: https: blob:;
font-src 'self' data: https://fonts.gstatic.com;
frame-src 'self' https://www.googletagmanager.com;
worker-src 'self' blob:;
"""
Access-Control-Allow-Origin = "*"
Access-Control-Allow-Methods = "GET, POST, PUT, DELETE, OPTIONS"
Access-Control-Allow-Headers = """
Authorization,
Content-Type,
Accept,
Origin,
User-Agent,
DNT,
Cache-Control,
X-Mx-ReqToken,
Keep-Alive,
X-Requested-With,
If-Modified-Since
"""
Access-Control-Max-Age = "3600"
[dev] [dev]
command = "npm run dev" command = "npm run dev"

108
package-lock.json generated
View File

@ -14,6 +14,7 @@
"@radix-ui/react-dialog": "^1.1.4", "@radix-ui/react-dialog": "^1.1.4",
"@radix-ui/react-tabs": "^1.1.2", "@radix-ui/react-tabs": "^1.1.2",
"@radix-ui/react-toast": "^1.2.4", "@radix-ui/react-toast": "^1.2.4",
"@sentry/react": "^8.48.0",
"@supabase/supabase-js": "^2.39.7", "@supabase/supabase-js": "^2.39.7",
"@tanstack/react-query": "^5.62.8", "@tanstack/react-query": "^5.62.8",
"@testing-library/react": "^16.1.0", "@testing-library/react": "^16.1.0",
@ -2556,6 +2557,98 @@
"url": "https://ko-fi.com/killymxi" "url": "https://ko-fi.com/killymxi"
} }
}, },
"node_modules/@sentry-internal/browser-utils": {
"version": "8.48.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-8.48.0.tgz",
"integrity": "sha512-pLtu0Fa1Ou0v3M1OEO1MB1EONJVmXEGtoTwFRCO1RPQI2ulmkG6BikINClFG5IBpoYKZ33WkEXuM6U5xh+pdZg==",
"license": "MIT",
"dependencies": {
"@sentry/core": "8.48.0"
},
"engines": {
"node": ">=14.18"
}
},
"node_modules/@sentry-internal/feedback": {
"version": "8.48.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-8.48.0.tgz",
"integrity": "sha512-6PwcJNHVPg0EfZxmN+XxVOClfQpv7MBAweV8t9i5l7VFr8sM/7wPNSeU/cG7iK19Ug9ZEkBpzMOe3G4GXJ5bpw==",
"license": "MIT",
"dependencies": {
"@sentry/core": "8.48.0"
},
"engines": {
"node": ">=14.18"
}
},
"node_modules/@sentry-internal/replay": {
"version": "8.48.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-8.48.0.tgz",
"integrity": "sha512-csILVupc5RkrsTrncuUTGmlB56FQSFjXPYWG8I8yBTGlXEJ+o8oTuF6+55R4vbw3EIzBveXWi4kEBbnQlXW/eg==",
"license": "MIT",
"dependencies": {
"@sentry-internal/browser-utils": "8.48.0",
"@sentry/core": "8.48.0"
},
"engines": {
"node": ">=14.18"
}
},
"node_modules/@sentry-internal/replay-canvas": {
"version": "8.48.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-8.48.0.tgz",
"integrity": "sha512-LdivLfBXXB9us1aAc6XaL7/L2Ob4vi3C/fEOXElehg3qHjX6q6pewiv5wBvVXGX1NfZTRvu+X11k6TZoxKsezw==",
"license": "MIT",
"dependencies": {
"@sentry-internal/replay": "8.48.0",
"@sentry/core": "8.48.0"
},
"engines": {
"node": ">=14.18"
}
},
"node_modules/@sentry/browser": {
"version": "8.48.0",
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.48.0.tgz",
"integrity": "sha512-fuuVULB5/1vI8NoIwXwR3xwhJJqk+y4RdSdajExGF7nnUDBpwUJyXsmYJnOkBO+oLeEs58xaCpotCKiPUNnE3g==",
"license": "MIT",
"dependencies": {
"@sentry-internal/browser-utils": "8.48.0",
"@sentry-internal/feedback": "8.48.0",
"@sentry-internal/replay": "8.48.0",
"@sentry-internal/replay-canvas": "8.48.0",
"@sentry/core": "8.48.0"
},
"engines": {
"node": ">=14.18"
}
},
"node_modules/@sentry/core": {
"version": "8.48.0",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.48.0.tgz",
"integrity": "sha512-VGwYgTfLpvJ5LRO5A+qWo1gpo6SfqaGXL9TOzVgBucAdpzbrYHpZ87sEarDVq/4275uk1b0S293/mfsskFczyw==",
"license": "MIT",
"engines": {
"node": ">=14.18"
}
},
"node_modules/@sentry/react": {
"version": "8.48.0",
"resolved": "https://registry.npmjs.org/@sentry/react/-/react-8.48.0.tgz",
"integrity": "sha512-J8XAUOJYbsjXnowTEXE+zWJWLWUzQGP8kMb+smoGdRzFJwwXKrbE709Kr/Boz6rK48EbbRT4UUINoTbHgL3RHQ==",
"license": "MIT",
"dependencies": {
"@sentry/browser": "8.48.0",
"@sentry/core": "8.48.0",
"hoist-non-react-statics": "^3.3.2"
},
"engines": {
"node": ">=14.18"
},
"peerDependencies": {
"react": "^16.14.0 || 17.x || 18.x || 19.x"
}
},
"node_modules/@sinclair/typebox": { "node_modules/@sinclair/typebox": {
"version": "0.27.8", "version": "0.27.8",
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
@ -5565,6 +5658,21 @@
"node": ">= 0.4" "node": ">= 0.4"
} }
}, },
"node_modules/hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
"license": "BSD-3-Clause",
"dependencies": {
"react-is": "^16.7.0"
}
},
"node_modules/hoist-non-react-statics/node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
"license": "MIT"
},
"node_modules/html-to-text": { "node_modules/html-to-text": {
"version": "9.0.5", "version": "9.0.5",
"resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-9.0.5.tgz", "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-9.0.5.tgz",

View File

@ -21,6 +21,7 @@
"@radix-ui/react-dialog": "^1.1.4", "@radix-ui/react-dialog": "^1.1.4",
"@radix-ui/react-tabs": "^1.1.2", "@radix-ui/react-tabs": "^1.1.2",
"@radix-ui/react-toast": "^1.2.4", "@radix-ui/react-toast": "^1.2.4",
"@sentry/react": "^8.48.0",
"@supabase/supabase-js": "^2.39.7", "@supabase/supabase-js": "^2.39.7",
"@tanstack/react-query": "^5.62.8", "@tanstack/react-query": "^5.62.8",
"@testing-library/react": "^16.1.0", "@testing-library/react": "^16.1.0",

View File

@ -0,0 +1,39 @@
import React from 'react';
interface GoogleTagManagerProps {
gtmId: string;
}
export function GoogleTagManager({ gtmId }: GoogleTagManagerProps) {
React.useEffect(() => {
// Carrega o script do GTM
const script = document.createElement('script');
script.innerHTML = `
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','${gtmId}');
`;
document.head.appendChild(script);
// Adiciona o noscript iframe
const noscript = document.createElement('noscript');
const iframe = document.createElement('iframe');
iframe.src = `https://www.googletagmanager.com/ns.html?id=${gtmId}`;
iframe.height = '0';
iframe.width = '0';
iframe.style.display = 'none';
iframe.style.visibility = 'hidden';
noscript.appendChild(iframe);
document.body.insertBefore(noscript, document.body.firstChild);
return () => {
// Cleanup
document.head.removeChild(script);
document.body.removeChild(noscript);
};
}, [gtmId]);
return null;
}

View File

@ -0,0 +1,20 @@
import { useEffect } from 'react';
import { useRudderstack } from '../../hooks/useRudderstack';
import { useLocation } from 'react-router-dom';
export function PageTracker() {
const location = useLocation();
const { track } = useRudderstack();
useEffect(() => {
track('page_viewed', {
path: location.pathname,
url: window.location.href,
search: location.search,
title: document.title,
referrer: document.referrer,
});
}, [location, track]);
return null;
}

View File

@ -0,0 +1,83 @@
import React from 'react';
interface RudderstackAnalyticsProps {
writeKey: string;
dataPlaneUrl: string;
}
declare global {
interface Window {
rudderanalytics: any;
}
}
export function RudderstackAnalytics({ writeKey, dataPlaneUrl }: RudderstackAnalyticsProps) {
React.useEffect(() => {
if (window.rudderanalytics?.loaded) {
return;
}
// Inicializa o objeto rudderanalytics
window.rudderanalytics = window.rudderanalytics || [];
// Define os métodos básicos
const methods = ['load', 'page', 'track', 'identify', 'alias', 'group', 'ready', 'reset'];
methods.forEach((method) => {
window.rudderanalytics[method] = function() {
window.rudderanalytics.push([method].concat(Array.prototype.slice.call(arguments)));
};
});
// Carrega o script do Rudderstack
const loadScript = () => {
return new Promise<void>((resolve, reject) => {
const script = document.createElement('script');
script.src = 'https://cdn.rudderlabs.com/v1.1/rudder-analytics.min.js';
script.async = true;
script.crossOrigin = 'anonymous';
script.onload = () => {
window.rudderanalytics.load(writeKey, dataPlaneUrl, {
configUrl: 'https://api.rudderlabs.com',
destSDKBaseURL: 'https://cdn.rudderlabs.com/v1.1',
logLevel: 'ERROR',
secureCookie: true,
integrations: { All: true },
loadIntegration: true,
sendAdblockPage: true,
sendAdblockPageOptions: {
integrations: { All: true }
}
});
resolve();
};
script.onerror = (error) => {
console.error('Erro ao carregar Rudderstack:', error);
reject(error);
};
document.head.appendChild(script);
});
};
// Carrega o script e inicializa
loadScript()
.then(() => {
window.rudderanalytics.page();
})
.catch((error) => {
console.error('Falha ao inicializar Rudderstack:', error);
});
return () => {
const script = document.querySelector('script[src*="rudder-analytics.min.js"]');
if (script && script.parentNode) {
script.parentNode.removeChild(script);
}
delete window.rudderanalytics;
};
}, [writeKey, dataPlaneUrl]);
return null;
}

View File

@ -57,6 +57,12 @@ export function AudioUploader({
as="span" as="span"
disabled={isProcessing} disabled={isProcessing}
className="cursor-pointer" className="cursor-pointer"
trackingId="audio-upload-button"
trackingProperties={{
category: 'audio',
action: 'upload_click',
label: 'audio_uploader'
}}
> >
{isProcessing ? 'Processando...' : 'Enviar Áudio'} {isProcessing ? 'Processando...' : 'Enviar Áudio'}
</Button> </Button>

View File

@ -1,8 +1,12 @@
import React, { useState } from 'react'; import React, { useState, useEffect } from 'react';
import { LogIn, Eye, EyeOff, School, GraduationCap, User } from 'lucide-react'; import { LogIn, Eye, EyeOff, School, GraduationCap, User } from 'lucide-react';
import { useAuth } from '../../hooks/useAuth'; import { useAuth } from '../../hooks/useAuth';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { supabase } from '../../lib/supabase'; import { supabase } from '../../lib/supabase';
import { useDataLayer } from '../../hooks/useDataLayer';
import { useFormTracking } from '../../hooks/useFormTracking';
import { Button } from '../ui/button';
import { useErrorTracking } from '../../hooks/useErrorTracking';
interface LoginFormProps { interface LoginFormProps {
userType: 'school' | 'teacher' | 'student'; userType: 'school' | 'teacher' | 'student';
@ -30,6 +34,20 @@ export function LoginForm({ userType, onLogin, onRegisterClick }: LoginFormProps
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const { signIn } = useAuth(); const { signIn } = useAuth();
const navigate = useNavigate(); const navigate = useNavigate();
const { trackEvent } = useDataLayer();
const formTracking = useFormTracking({
formId: 'login-form',
formName: `${userType}-login`,
category: 'auth'
});
const errorTracking = useErrorTracking({
category: 'auth',
userEmail: email
});
useEffect(() => {
formTracking.trackFormStarted();
}, []);
const handleSubmit = async (e: React.FormEvent) => { const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault(); e.preventDefault();
@ -46,10 +64,21 @@ export function LoginForm({ userType, onLogin, onRegisterClick }: LoginFormProps
console.log('Resposta do Supabase:', { data, error }); console.log('Resposta do Supabase:', { data, error });
if (error) throw error; if (error) {
errorTracking.trackApiError(error, '/auth/sign-in', 'POST', { email, userType });
formTracking.trackFormError('auth_error', error.message);
throw error;
}
if (!data.user) { if (!data.user) {
throw new Error('Usuário não encontrado'); const err = new Error('Usuário não encontrado');
errorTracking.trackError(err, {
componentName: 'LoginForm',
action: 'login_attempt',
metadata: { userType }
});
formTracking.trackFormError('user_not_found', 'Usuário não encontrado');
throw err;
} }
const userRole = data.user.user_metadata.role; const userRole = data.user.user_metadata.role;
@ -58,9 +87,24 @@ export function LoginForm({ userType, onLogin, onRegisterClick }: LoginFormProps
console.log('Role atual:', userRole); console.log('Role atual:', userRole);
if (userRole !== userType) { if (userRole !== userType) {
throw new Error(`Este não é um login de ${userTypeLabels[userType]}`); const err = new Error(`Este não é um login de ${userTypeLabels[userType]}`);
errorTracking.trackError(err, {
componentName: 'LoginForm',
action: 'role_validation',
metadata: {
expectedRole: userType,
actualRole: userRole
}
});
formTracking.trackFormError('invalid_role', err.message);
throw err;
} }
formTracking.trackFormSubmitted(true, {
user_type: userType,
user_id: data.user.id
});
switch (userType) { switch (userType) {
case 'school': case 'school':
navigate('/dashboard'); navigate('/dashboard');
@ -75,18 +119,36 @@ export function LoginForm({ userType, onLogin, onRegisterClick }: LoginFormProps
throw new Error('Tipo de usuário inválido'); throw new Error('Tipo de usuário inválido');
} }
trackEvent('auth', 'login_success', 'form');
} catch (err) { } catch (err) {
console.error('Erro no login:', err); console.error('Erro no login:', err);
if (err instanceof Error) { const errorMessage = err instanceof Error ? err.message : 'Email ou senha incorretos';
setError(err.message); setError(errorMessage);
} else {
setError('Email ou senha incorretos'); formTracking.trackFormSubmitted(false, {
} error_type: err instanceof Error ? 'validation_error' : 'unknown_error',
error_message: errorMessage
});
trackEvent('auth', 'login_error', errorMessage);
} finally { } finally {
setLoading(false); setLoading(false);
} }
}; };
const handleFieldChange = (field: string, value: string) => {
formTracking.trackFieldInteraction(field, 'change');
if (field === 'email') setEmail(value);
if (field === 'password') setPassword(value);
};
const handleFieldFocus = (field: string) => {
formTracking.trackFieldInteraction(field, 'focus');
};
const handleFieldBlur = (field: string) => {
formTracking.trackFieldInteraction(field, 'blur');
};
return ( return (
<div className="min-h-screen bg-gradient-to-b from-purple-50 to-white py-12"> <div className="min-h-screen bg-gradient-to-b from-purple-50 to-white py-12">
<div className="max-w-md mx-auto px-4"> <div className="max-w-md mx-auto px-4">
@ -119,7 +181,9 @@ export function LoginForm({ userType, onLogin, onRegisterClick }: LoginFormProps
type="email" type="email"
required required
value={email} value={email}
onChange={(e) => setEmail(e.target.value)} onChange={(e) => handleFieldChange('email', e.target.value)}
onFocus={() => handleFieldFocus('email')}
onBlur={() => handleFieldBlur('email')}
className="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-purple-500 focus:ring-purple-500" className="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-purple-500 focus:ring-purple-500"
/> />
</div> </div>
@ -134,7 +198,9 @@ export function LoginForm({ userType, onLogin, onRegisterClick }: LoginFormProps
type={showPassword ? 'text' : 'password'} type={showPassword ? 'text' : 'password'}
required required
value={password} value={password}
onChange={(e) => setPassword(e.target.value)} onChange={(e) => handleFieldChange('password', e.target.value)}
onFocus={() => handleFieldFocus('password')}
onBlur={() => handleFieldBlur('password')}
className="block w-full rounded-lg border-gray-300 shadow-sm focus:border-purple-500 focus:ring-purple-500 pr-10" className="block w-full rounded-lg border-gray-300 shadow-sm focus:border-purple-500 focus:ring-purple-500 pr-10"
/> />
<button <button
@ -151,32 +217,49 @@ export function LoginForm({ userType, onLogin, onRegisterClick }: LoginFormProps
</div> </div>
</div> </div>
<button <Button
type="submit" type="submit"
disabled={loading} disabled={loading}
className="w-full flex justify-center items-center gap-2 py-3 px-4 border border-transparent rounded-lg shadow-sm text-white bg-purple-600 hover:bg-purple-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-purple-500 disabled:opacity-50" trackingId="login-submit"
variant="primary"
size="lg"
trackingProperties={{
category: 'auth',
action: 'login_attempt',
label: `${userType}_login`,
value: 1,
}}
className="w-full"
> >
{loading ? ( {loading ? (
'Entrando...' 'Entrando...'
) : ( ) : (
<> <>
<LogIn className="h-5 w-5" /> <LogIn className="h-5 w-5 mr-2" />
Entrar Entrar
</> </>
)} )}
</button> </Button>
</form> </form>
{onRegisterClick && ( {onRegisterClick && (
<div className="mt-6 text-center"> <div className="mt-6 text-center">
<p className="text-sm text-gray-600"> <p className="text-sm text-gray-600">
Ainda não tem uma conta?{' '} Ainda não tem uma conta?{' '}
<button <Button
trackingId="register-link"
variant="link"
size="sm"
onClick={onRegisterClick} onClick={onRegisterClick}
className="text-purple-600 hover:text-purple-500 font-medium" trackingProperties={{
category: 'auth',
action: 'register_click',
label: userType,
}}
className="text-purple-600 hover:text-purple-500 font-medium p-0"
> >
Cadastre-se Cadastre-se
</button> </Button>
</p> </p>
</div> </div>
)} )}

View File

@ -4,53 +4,17 @@ import {
BookOpen, ArrowRight, School, Users, Shield, BookOpen, ArrowRight, School, Users, Shield,
Sparkles, BookCheck, Play, CheckCircle, Star, Sparkles, BookCheck, Play, CheckCircle, Star,
GraduationCap, BarChart, Brain, X, Check, GraduationCap, BarChart, Brain, X, Check,
Pencil, Pencil, Wand, Mic, Share2
Wand,
Mic,
Share2
} from 'lucide-react'; } from 'lucide-react';
import { Footer } from '@/components/ui/footer'; import { Footer } from '@/components/ui/footer';
import { PlanForSchools } from '@/components/ui/plan-for-schools'; import { PlanForSchools } from '@/components/ui/plan-for-schools';
import { FAQ } from '@/components/ui/faq';
// Components import { StatCard } from '@/components/ui/stat-card';
const FeatureCard = ({ icon, title, description }: { import { TestimonialCard } from '@/components/ui/testimonial-card';
icon: React.ReactNode; import { FeatureCard } from '@/components/ui/feature-card';
title: string; import { ProcessStep } from '@/components/ui/process-step';
description: string; import { InfoCard } from '@/components/ui/info-card';
}) => ( import { ComparisonSection } from '@/components/ui/comparison-section';
<div className="p-6 rounded-xl border border-gray-200 hover:shadow-lg transition bg-white">
<div className="w-12 h-12 rounded-lg bg-purple-100 flex items-center justify-center mb-4">
<div className="text-purple-600">{icon}</div>
</div>
<h3 className="text-xl font-semibold text-gray-900 mb-2">{title}</h3>
<p className="text-gray-600">{description}</p>
</div>
);
const StatCard = ({ number, label }: { number: string; label: string }) => (
<div className="p-6">
<div className="text-4xl font-bold mb-2">{number}</div>
<div className="text-purple-200">{label}</div>
</div>
);
const TestimonialCard = ({ quote, author, role, image }: {
quote: string;
author: string;
role: string;
image: string;
}) => (
<div className="p-6 rounded-xl bg-white shadow-md">
<div className="flex items-center gap-4 mb-4">
<img src={image} alt={author} className="w-12 h-12 rounded-full" />
<div>
<div className="font-semibold text-gray-900">{author}</div>
<div className="text-sm text-gray-600">{role}</div>
</div>
</div>
<p className="text-gray-600 italic">"{quote}"</p>
</div>
);
const navigation = [ const navigation = [
{ name: 'Início', href: '/' }, { name: 'Início', href: '/' },
@ -130,7 +94,7 @@ export function HomePage() {
</nav> </nav>
{/* Hero Section */} {/* Hero Section */}
<div className="pt-32 pb-20 px-4 sm:px-6 lg:px-8"> <div className="pt-32 pb-24 px-4 sm:px-6 lg:px-8">
<div className="max-w-7xl mx-auto"> <div className="max-w-7xl mx-auto">
<div className="grid lg:grid-cols-2 gap-12 items-center"> <div className="grid lg:grid-cols-2 gap-12 items-center">
<div> <div>
@ -200,7 +164,7 @@ export function HomePage() {
</div> </div>
{/* Student Journey Section */} {/* Student Journey Section */}
<div className="py-20 bg-gradient-to-b from-purple-50 to-white"> <div className="py-24 bg-gradient-to-b from-purple-50 to-white">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center mb-16"> <div className="text-center mb-16">
<h2 className="text-3xl font-bold text-gray-900 mb-4"> <h2 className="text-3xl font-bold text-gray-900 mb-4">
@ -211,136 +175,77 @@ export function HomePage() {
</p> </p>
</div> </div>
<div className="relative"> <div className="space-y-12">
{/* Timeline Line */} <ProcessStep
<div className="hidden md:block absolute left-1/2 transform -translate-x-1/2 h-full w-0.5 bg-purple-200" /> number={1}
title="Escolha o tema da aventura"
description="Selecione entre diversos temas educativos alinhados com a BNCC e adequados à idade."
/>
{/* Timeline Items */} <ProcessStep
{[ number={2}
{ title="Personalize os personagens"
icon: <Pencil className="w-6 h-6" />, description="Crie personagens que seu filho vai adorar, com características únicas e cativantes."
title: "Criação Personalizada", />
description: "O aluno cria uma história baseada em seus interesses e características pessoais",
image: "/journey/create-story.png"
},
{
icon: <Wand className="w-6 h-6" />,
title: "Geração por IA",
description: "Nossa IA avançada gera uma história única e personalizada",
image: "/journey/ai-generation.png"
},
{
icon: <Mic className="w-6 h-6" />,
title: "Gravação de Áudio",
description: "O aluno grava sua voz lendo a história criada",
image: "/journey/audio-recording.png"
},
{
icon: <BarChart className="w-6 h-6" />,
title: "Análise de Leitura",
description: "A IA analisa a leitura e fornece feedback detalhado sobre o desempenho",
image: "/journey/reading-analysis.png"
},
{
icon: <Share2 className="w-6 h-6" />,
title: "Compartilhamento de Resultados",
description: "Dados e insights são compartilhados com pais, professores e escola",
image: "/journey/share-results.png"
}
].map((item, index) => (
<div key={index} className={`mb-12 md:mb-24 relative ${
index % 2 === 0 ? 'md:text-right' : ''
}`}>
<div className={`flex items-center gap-8 ${
index % 2 === 0 ? 'md:flex-row-reverse' : ''
}`}>
{/* Content Side */}
<div className="flex-1">
<div className={`bg-white rounded-xl shadow-lg p-6 transform transition-all duration-300 hover:scale-105 ${
index % 2 === 0 ? 'md:ml-auto' : ''
}`}>
<div className="flex items-center gap-4 mb-4">
<div className="w-12 h-12 rounded-full bg-purple-100 flex items-center justify-center text-purple-600">
{item.icon}
</div>
<h3 className="text-xl font-semibold text-gray-900">
{item.title}
</h3>
</div>
<p className="text-gray-600">
{item.description}
</p>
</div>
</div>
{/* Timeline Marker */} <ProcessStep
<div className="hidden md:flex items-center justify-center"> number={3}
<div className="w-12 h-12 rounded-full bg-purple-600 text-white flex items-center justify-center font-bold"> title="A IA cria a história mágica"
{index + 1} description="Nossa IA educacional gera uma história personalizada em segundos."
</div> />
</div>
{/* Image Side */} <ProcessStep
<div className="flex-1 hidden md:block"> number={4}
<img title="A aventura educativa começa"
src={item.image} description="Seu filho mergulha em uma jornada mágica de aprendizado e diversão."
alt={item.title} />
className="rounded-xl shadow-lg w-full max-w-md mx-auto"
/>
</div>
</div>
</div>
))}
</div>
{/* Results Summary */}
<div className="mt-16 bg-white rounded-xl shadow-lg p-8">
<div className="text-center mb-8">
<h3 className="text-2xl font-bold text-gray-900 mb-2">
Resultados Comprovados
</h3>
<p className="text-gray-600">
Nossa abordagem inovadora tem transformado a experiência de leitura
</p>
</div>
<div className="grid md:grid-cols-4 gap-8">
{[
{
number: "95%",
label: "Melhoria na fluência de leitura"
},
{
number: "87%",
label: "Aumento no engajamento"
},
{
number: "92%",
label: "Satisfação dos pais"
},
{
number: "3x",
label: "Mais histórias lidas por aluno"
}
].map((stat, index) => (
<div key={index} className="text-center">
<div className="text-3xl font-bold text-purple-600 mb-2">
{stat.number}
</div>
<p className="text-gray-600 text-sm">
{stat.label}
</p>
</div>
))}
</div>
</div> </div>
</div> </div>
</div> </div>
{/* Features Grid */} {/* Results Summary */}
<div className="py-20 bg-white"> <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div className="mt-24 bg-white rounded-xl shadow-lg p-8">
<div className="text-center mb-16"> <div className="text-center mb-8">
<h3 className="text-2xl font-bold text-gray-900 mb-2">
Resultados Comprovados
</h3>
<p className="text-gray-600">
Nossa abordagem inovadora tem transformado a experiência de leitura
</p>
</div>
<div className="grid md:grid-cols-4 gap-8">
<StatCard
icon={Star}
title="Fluência de Leitura"
value="95%"
description="Melhoria na fluência de leitura dos alunos"
/>
<StatCard
icon={Sparkles}
title="Engajamento"
value="87%"
description="Aumento no engajamento com a leitura"
/>
<StatCard
icon={CheckCircle}
title="Satisfação"
value="92%"
description="Satisfação dos pais com o progresso"
/>
<StatCard
icon={BookOpen}
title="Leitura"
value="3x"
description="Mais histórias lidas por aluno"
/>
</div>
</div>
{/* Features Grid */}
<div className="mt-24">
<div className="text-center mb-12">
<h2 className="text-3xl font-bold text-gray-900 mb-4"> <h2 className="text-3xl font-bold text-gray-900 mb-4">
Tecnologia e Educação em Harmonia Tecnologia e Educação em Harmonia
</h2> </h2>
@ -350,148 +255,152 @@ export function HomePage() {
</div> </div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
<FeatureCard <FeatureCard
icon={<Brain />} icon={Brain}
title="IA Adaptativa" title="IA Adaptativa"
description="Conteúdo que se adapta ao ritmo e estilo de aprendizagem de cada aluno" description="Conteúdo que se adapta ao ritmo e estilo de aprendizagem de cada aluno"
/> />
<FeatureCard <FeatureCard
icon={<BookOpen />} icon={BookOpen}
title="Histórias Interativas" title="Histórias Interativas"
description="Narrativas envolventes que tornam o aprendizado mais divertido e eficaz" description="Narrativas envolventes que tornam o aprendizado mais divertido e eficaz"
/> />
<FeatureCard <FeatureCard
icon={<BarChart />} icon={BarChart}
title="Analytics Avançado" title="Analytics Avançado"
description="Insights detalhados sobre o progresso e engajamento dos alunos" description="Insights detalhados sobre o progresso e engajamento dos alunos"
/> />
<FeatureCard <FeatureCard
icon={<Users />} icon={Users}
title="Colaboração" title="Colaboração"
description="Ferramentas para professores trabalharem juntos e compartilharem recursos" description="Ferramentas para professores trabalharem juntos e compartilharem recursos"
/> />
<FeatureCard <FeatureCard
icon={<Shield />} icon={Shield}
title="Ambiente Seguro" title="Ambiente Seguro"
description="Proteção de dados e conteúdo adequado para todas as idades" description="Proteção de dados e conteúdo adequado para todas as idades"
/> />
<FeatureCard <FeatureCard
icon={<GraduationCap />} icon={GraduationCap}
title="Suporte Pedagógico" title="Suporte Pedagógico"
description="Recursos e orientações para maximizar o potencial de aprendizagem" description="Recursos e orientações para maximizar o potencial de aprendizagem"
/> />
</div> </div>
</div> </div>
</div>
{/* Before & After Section */} {/* Before & After Section */}
<div className="py-20 bg-white"> <div className="mt-24">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <ComparisonSection
<div className="text-center mb-16"> title="Compare a Transformação"
<h2 className="text-3xl font-bold text-gray-900 mb-4"> items={[
Transforme a Experiência de Aprendizagem {
</h2> title: "Personalização",
<p className="text-gray-600 max-w-2xl mx-auto"> without: [
Veja como o Histórias Mágicas revoluciona o ensino "Conteúdo padronizado que não atende necessidades individuais",
</p> "Material didático tradicional e pouco envolvente",
</div> "Mesma abordagem para todos os alunos"
],
<div className="grid md:grid-cols-2 gap-16"> with: [
{/* Before */} "Histórias adaptativas que evoluem com cada aluno",
<div className="rounded-2xl bg-red-50 p-8"> "Conteúdo personalizado e envolvente",
<div className="flex items-center gap-3 mb-6"> "Experiência única para cada estudante"
<div className="w-12 h-12 rounded-full bg-red-100 flex items-center justify-center"> ]
<X className="w-6 h-6 text-red-600" /> },
</div> {
<h3 className="text-2xl font-semibold text-gray-900">Antes</h3> title: "Engajamento",
</div> without: [
<ul className="space-y-4"> "Alunos desmotivados com atividades repetitivas",
{[ "Baixo interesse nas atividades de leitura",
'Conteúdo padronizado que não atende necessidades individuais', "Dificuldade em manter a atenção dos alunos"
'Alunos desmotivados com material didático tradicional', ],
'Professores sobrecarregados com correções manuais', with: [
'Dificuldade em acompanhar o progresso individual', "Estudantes engajados e participativos",
'Baixo engajamento nas atividades de leitura e escrita', "Aumento de 300% no engajamento com leitura",
'Falta de dados para tomada de decisão pedagógica' "Alunos ansiosos pela próxima atividade"
].map((item, index) => ( ]
<li key={index} className="flex items-start gap-3"> },
<div className="mt-1"> {
<X className="w-5 h-5 text-red-600" /> title: "Acompanhamento",
</div> without: [
<span className="text-gray-600">{item}</span> "Professores sobrecarregados com correções manuais",
</li> "Dificuldade em acompanhar o progresso individual",
))} "Falta de dados para decisões pedagógicas"
</ul> ],
</div> with: [
"Correção automática com feedback instantâneo",
{/* After */} "Dashboard em tempo real do progresso individual",
<div className="rounded-2xl bg-green-50 p-8"> "Insights precisos para intervenções pedagógicas"
<div className="flex items-center gap-3 mb-6"> ]
<div className="w-12 h-12 rounded-full bg-green-100 flex items-center justify-center"> }
<Check className="w-6 h-6 text-green-600" /> ]}
</div> />
<h3 className="text-2xl font-semibold text-gray-900">Depois</h3>
</div>
<ul className="space-y-4">
{[
'Histórias adaptativas que evoluem com cada aluno',
'Estudantes engajados com conteúdo personalizado',
'Correção automática com feedback instantâneo',
'Dashboard em tempo real do progresso individual',
'Aumento de 300% no engajamento com leitura',
'Insights precisos para intervenções pedagógicas'
].map((item, index) => (
<li key={index} className="flex items-start gap-3">
<div className="mt-1">
<Check className="w-5 h-5 text-green-600" />
</div>
<span className="text-gray-600">{item}</span>
</li>
))}
</ul>
</div>
{/* Results Preview */}
<div className="md:col-span-2 mt-8">
<div className="bg-white rounded-xl shadow-lg p-8">
<div className="grid md:grid-cols-3 gap-8 text-center">
<div>
<div className="text-4xl font-bold text-purple-600 mb-2">300%</div>
<p className="text-gray-600">Aumento no engajamento</p>
</div>
<div>
<div className="text-4xl font-bold text-purple-600 mb-2">85%</div>
<p className="text-gray-600">Melhoria no desempenho</p>
</div>
<div>
<div className="text-4xl font-bold text-purple-600 mb-2">50%</div>
<p className="text-gray-600">Redução da carga dos professores</p>
</div>
</div>
</div>
</div>
</div>
</div> </div>
</div>
{/* Pricing */} {/* Testimonials */}
<div className="py-20 bg-gray-50"> <div className="mt-24 grid md:grid-cols-2 gap-8">
<PlanForSchools /> <TestimonialCard
</div> quote="A transformação que vimos em nossa escola foi incrível. Alunos que mal conseguiam juntar letras agora estão lendo com fluência e, mais importante, com prazer."
author="Maria Silva"
role="Diretora Pedagógica"
/>
<TestimonialCard
quote="Como professora há 15 anos, nunca vi um método tão eficaz e envolvente. A plataforma me ajuda a personalizar o ensino para cada aluno."
author="Ana Paula Santos"
role="Professora"
/>
</div>
{/* Final CTA */} {/* Pricing Section */}
<div className="py-20"> <div className="mt-24">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <PlanForSchools />
<div className="bg-gradient-to-r from-purple-600 to-indigo-600 rounded-2xl p-8 md:p-16 text-center text-white"> </div>
<h2 className="text-3xl md:text-4xl font-bold mb-4">
{/* FAQ Section */}
<div className="mt-24">
<FAQ
title="Dúvidas Frequentes"
description="Tire suas dúvidas sobre a implementação do Histórias Mágicas em sua escola"
items={[
{
question: "Como o Histórias Mágicas se integra ao currículo escolar?",
answer: "Nossa plataforma foi desenvolvida para complementar e enriquecer o currículo existente. Oferecemos conteúdo alinhado à BNCC e ferramentas de personalização que permitem adaptar as atividades aos objetivos pedagógicos específicos de cada escola."
},
{
question: "Quanto tempo leva para implementar a plataforma?",
answer: "O processo de implementação é personalizado e gradual, levando em média 2-3 semanas. Iniciamos com uma fase piloto, oferecemos treinamento completo para a equipe e fornecemos suporte contínuo durante todo o processo."
},
{
question: "Como posso acompanhar o progresso dos alunos?",
answer: "Disponibilizamos um dashboard intuitivo com métricas em tempo real, relatórios detalhados e insights sobre o desempenho individual e coletivo. Professores e coordenadores podem monitorar o progresso, identificar áreas de melhoria e personalizar intervenções."
},
{
question: "Quais são os requisitos técnicos?",
answer: "A plataforma é acessível via navegador web em qualquer dispositivo (computadores, tablets, smartphones). Recomendamos uma conexão estável à internet e o uso de fones de ouvido para melhor experiência nas atividades de áudio."
},
{
question: "Como vocês protegem os dados dos alunos?",
answer: "Seguimos rigorosos protocolos de segurança em conformidade com a LGPD. Todos os dados são criptografados, o acesso é controlado e realizamos auditorias regulares de segurança."
},
{
question: "Que tipo de suporte vocês oferecem?",
answer: "Oferecemos suporte técnico e pedagógico através de múltiplos canais (chat, email, telefone), além de atualizações regulares da plataforma e workshops para capacitação contínua da equipe escolar."
}
]}
/>
</div>
{/* Final CTA */}
<div className="mt-24 pb-24">
<div className="bg-purple-600 rounded-3xl px-8 py-16 text-center">
<h2 className="text-4xl font-bold text-white mb-4">
Pronto para Transformar sua Escola? Pronto para Transformar sua Escola?
</h2> </h2>
<p className="text-lg mb-8 max-w-2xl mx-auto"> <p className="text-white/90 mb-8 max-w-2xl mx-auto text-lg">
Junte-se a mais de 1000 escolas que estão revolucionando a educação Junte-se a mais de 1000 escolas que estão revolucionando a educação
</p> </p>
<button <button
onClick={handleSchoolRegister} onClick={() => navigate('/register')}
className="bg-white text-purple-600 px-8 py-4 rounded-xl hover:bg-purple-50 transition text-lg font-semibold" className="bg-white text-purple-600 px-8 py-3 rounded-lg font-semibold hover:bg-purple-50 transition"
> >
Começar Gratuitamente Começar Gratuitamente
</button> </button>
@ -503,4 +412,6 @@ export function HomePage() {
<Footer /> <Footer />
</div> </div>
); );
} }
export default HomePage;

View File

@ -1,27 +1,76 @@
import React from 'react'; import React from 'react';
import { useButtonTracking } from '../../hooks/useButtonTracking';
import { cn } from '../../lib/utils';
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> { interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
as?: 'button' | 'span'; as?: 'button' | 'span';
children: React.ReactNode; trackingId: string;
variant?: 'default' | 'primary' | 'secondary' | 'outline' | 'ghost' | 'link';
size?: 'sm' | 'md' | 'lg';
trackingProperties?: {
label?: string;
value?: string | number;
action?: string;
category?: string;
position?: string;
[key: string]: any;
};
} }
export function Button({ export function Button({
as: Component = 'button', as: Component = 'button',
className = '',
children, children,
...props className = '',
}: ButtonProps): JSX.Element { trackingId,
variant = 'default',
size = 'md',
trackingProperties,
onClick,
disabled,
type = 'button',
...props
}: ButtonProps) {
const { trackButtonClick } = useButtonTracking({
category: trackingProperties?.category || 'interaction'
});
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
// Rastreia o clique
trackButtonClick(trackingId, {
variant,
size,
...trackingProperties,
});
// Chama o onClick original se existir
onClick?.(event);
};
const baseStyles = cn(
'inline-flex items-center justify-center px-4 py-2',
'text-sm font-medium',
'rounded-md shadow-sm',
'transition-colors duration-200',
'disabled:opacity-50 disabled:cursor-not-allowed',
{
'text-white bg-purple-600 hover:bg-purple-700': variant === 'primary' || variant === 'default',
'text-gray-700 bg-white border border-gray-300 hover:bg-gray-50': variant === 'secondary',
'text-purple-600 bg-transparent hover:bg-purple-50': variant === 'ghost',
'text-purple-600 bg-transparent hover:underline': variant === 'link',
'text-purple-600 border border-purple-600 hover:bg-purple-50': variant === 'outline',
'px-3 py-1.5 text-sm': size === 'sm',
'px-4 py-2 text-base': size === 'md',
'px-6 py-3 text-lg': size === 'lg',
},
className
);
return ( return (
<Component <Component
className={` type={Component === 'button' ? type : undefined}
inline-flex items-center justify-center px-4 py-2 className={baseStyles}
text-sm font-medium text-white onClick={handleClick}
bg-purple-600 hover:bg-purple-700 disabled={disabled}
rounded-md shadow-sm
transition-colors duration-200
disabled:opacity-50 disabled:cursor-not-allowed
${className}
`}
{...props} {...props}
> >
{children} {children}

View File

@ -0,0 +1,81 @@
import React from 'react';
import { X, CheckCircle } from 'lucide-react';
interface ComparisonItem {
title: string;
without: string[];
with: string[];
}
interface ComparisonSectionProps {
title: string;
items: ComparisonItem[];
}
export function ComparisonSection({ title, items }: ComparisonSectionProps) {
return (
<section className="px-4 py-24 bg-white">
<div className="mx-auto max-w-7xl">
<h2 className="text-4xl font-bold text-center text-gray-900 mb-16">
{title}
</h2>
<div className="grid md:grid-cols-2 gap-8">
{/* Sem Histórias Mágicas */}
<div className="p-8 bg-gray-50 rounded-xl border border-gray-200">
<div className="flex items-center gap-3 mb-8">
<div className="w-12 h-12 bg-red-100 rounded-full flex items-center justify-center">
<X className="h-6 w-6 text-red-500" />
</div>
<h3 className="text-xl font-bold text-gray-900">
Sem Histórias Mágicas
</h3>
</div>
{items.map((category, index) => (
<div key={index} className="mb-8 last:mb-0">
<h4 className="font-bold text-gray-900 mb-4">{category.title}</h4>
<ul className="space-y-3">
{category.without.map((item, idx) => (
<li key={idx} className="flex items-start gap-2">
<X className="h-5 w-5 text-red-500 flex-shrink-0 mt-1" />
<span className="text-gray-600">{item}</span>
</li>
))}
</ul>
</div>
))}
</div>
{/* Com Histórias Mágicas */}
<div className="p-8 bg-gradient-to-br from-purple-50 to-blue-50 rounded-xl
border-2 border-purple-200 transform hover:scale-[1.02] transition-transform">
<div className="flex items-center gap-3 mb-8">
<div className="w-12 h-12 bg-gradient-to-r from-purple-600 to-blue-500
rounded-full flex items-center justify-center">
<CheckCircle className="h-6 w-6 text-white" />
</div>
<h3 className="text-xl font-bold text-gray-900">
Com Histórias Mágicas
</h3>
</div>
{items.map((category, index) => (
<div key={index} className="mb-8 last:mb-0">
<h4 className="font-bold text-gray-900 mb-4">{category.title}</h4>
<ul className="space-y-3">
{category.with.map((item, idx) => (
<li key={idx} className="flex items-start gap-2">
<CheckCircle className="h-5 w-5 text-green-500 flex-shrink-0 mt-1" />
<span className="text-gray-600">{item}</span>
</li>
))}
</ul>
</div>
))}
</div>
</div>
</div>
</section>
);
}

49
src/components/ui/faq.tsx Normal file
View File

@ -0,0 +1,49 @@
import React from 'react';
interface FAQItem {
question: string;
answer: string;
}
interface FAQProps {
title?: string;
description?: string;
items: FAQItem[];
className?: string;
}
export function FAQ({
title = "Perguntas Frequentes",
description = "Tire suas dúvidas sobre nossa plataforma",
items,
className = ""
}: FAQProps) {
return (
<section className={`px-4 py-24 bg-white ${className}`}>
<div className="mx-auto max-w-3xl">
<h2 className="text-4xl font-bold text-center text-gray-900 mb-16">
{title}
</h2>
{description && (
<p className="text-center text-gray-600 mb-12">
{description}
</p>
)}
<div className="space-y-8">
{items.map((item, index) => (
<div key={index} className="bg-gray-50 rounded-xl p-6 hover:bg-gray-100 transition-colors">
<h3 className="text-xl font-bold text-gray-900 mb-2">
{item.question}
</h3>
<p className="text-gray-600">
{item.answer}
</p>
</div>
))}
</div>
</div>
</section>
);
}

View File

@ -0,0 +1,41 @@
import React from 'react';
import { LucideIcon } from 'lucide-react';
interface FeatureCardProps {
icon: LucideIcon;
title: string;
items?: string[];
description?: string;
borderColor?: string;
iconColor?: string;
}
export function FeatureCard({
icon: Icon,
title,
items,
description,
borderColor = 'border-purple-200',
iconColor = 'text-purple-600'
}: FeatureCardProps) {
return (
<div className="p-6 rounded-xl border border-gray-200 hover:shadow-lg transition-all duration-300 bg-white">
<div className="w-12 h-12 rounded-lg bg-purple-100 flex items-center justify-center mb-4">
<Icon className={`w-6 h-6 ${iconColor}`} />
</div>
<h3 className="text-xl font-semibold text-gray-900 mb-2">{title}</h3>
{description && (
<p className="text-gray-600 mb-4">{description}</p>
)}
{items && items.length > 0 && (
<ul className="space-y-2">
{items.map((item, index) => (
<li key={index} className="text-gray-600">
{item}
</li>
))}
</ul>
)}
</div>
);
}

View File

@ -0,0 +1,67 @@
import React from 'react';
import { LucideIcon } from 'lucide-react';
interface InfoCardProps {
title: string;
description?: string;
result?: string;
icon?: LucideIcon;
items?: string[];
bgColor?: string;
titleColor?: string;
textColor?: string;
resultColor?: string;
iconColor?: string;
}
export function InfoCard({
title,
description,
result,
icon: Icon,
items,
bgColor = 'bg-white',
titleColor = 'text-gray-900',
textColor = 'text-gray-600',
resultColor = 'text-purple-600',
iconColor = 'text-purple-600',
}: InfoCardProps) {
return (
<div className={`${bgColor} p-8 rounded-2xl shadow-sm`}>
{/* Icon */}
{Icon && (
<div className="mb-6">
<div className="w-16 h-16 rounded-full bg-purple-100 flex items-center justify-center">
<Icon className={`w-8 h-8 ${iconColor}`} />
</div>
</div>
)}
{/* Title */}
<h3 className={`text-2xl font-bold ${titleColor} mb-3`}>{title}</h3>
{/* Description */}
{description && (
<p className={`${textColor} text-lg mb-6`}>{description}</p>
)}
{/* Result */}
{result && (
<div className="bg-purple-50 rounded-xl p-4">
<p className={`${resultColor} text-lg font-medium`}>
Resultado: {result}
</p>
</div>
)}
{/* Items List */}
{items && items.length > 0 && (
<ul className={`list-disc pl-6 space-y-2 mt-6 ${textColor}`}>
{items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
)}
</div>
);
}

View File

@ -0,0 +1,34 @@
import React from 'react';
interface ProcessStepProps {
number: number;
title: string;
description: string;
}
export function ProcessStep({
number,
title,
description,
}: ProcessStepProps) {
return (
<div className="flex items-start gap-6">
{/* Número */}
<div className="flex-shrink-0">
<div className="w-14 h-14 rounded-full bg-purple-600 flex items-center justify-center text-white text-2xl font-bold">
{number}
</div>
</div>
{/* Conteúdo */}
<div className="flex-1">
<h3 className="text-2xl font-bold text-gray-900 mb-3">
{title}
</h3>
<p className="text-lg text-gray-600">
{description}
</p>
</div>
</div>
);
}

View File

@ -0,0 +1,33 @@
import React from 'react';
import { LucideIcon } from 'lucide-react';
interface StatCardProps {
icon: LucideIcon;
title: string;
value: string;
description: string;
valueColor?: string;
iconBgColor?: string;
iconColor?: string;
}
export function StatCard({
icon: Icon,
title,
value,
description,
valueColor = 'text-purple-600',
iconBgColor = 'bg-purple-600',
iconColor = 'text-white',
}: StatCardProps) {
return (
<div className="bg-white shadow-lg rounded-xl p-6">
<div className={`flex items-center justify-center h-12 w-12 rounded-md ${iconBgColor} ${iconColor} mb-4`}>
<Icon className="h-6 w-6" />
</div>
<h3 className="text-lg font-bold text-gray-900">{title}</h3>
<p className={`mt-2 text-4xl font-bold ${valueColor}`}>{value}</p>
<p className="mt-2 text-gray-600">{description}</p>
</div>
);
}

View File

@ -0,0 +1,67 @@
import React from 'react';
import { Heart } from 'lucide-react';
interface TestimonialCardProps {
quote: string;
author: string;
role: string;
image?: string;
magicMoment?: string;
result?: string;
borderColor?: string;
quoteColor?: string;
authorColor?: string;
}
export function TestimonialCard({
quote,
author,
role,
image,
magicMoment,
result,
borderColor = 'border-purple-200',
quoteColor = 'text-gray-600',
authorColor = 'text-gray-900'
}: TestimonialCardProps) {
return (
<div className="bg-gradient-to-br from-purple-50 to-blue-50 p-6 rounded-xl shadow-sm">
{image && (
<div className="relative mb-8">
<img
src={image}
alt={`Foto de ${author}`}
className="w-full h-48 object-cover rounded-lg"
/>
<div className="absolute -bottom-4 -right-4 bg-white p-2 rounded-full shadow-lg">
<Heart className="h-6 w-6 text-red-500" />
</div>
</div>
)}
<p className={`${quoteColor} mb-4 italic`}>"{quote}"</p>
<div className="flex items-center gap-4">
{image && (
<img
src={image}
alt={author}
className="w-12 h-12 rounded-full object-cover"
/>
)}
<div>
<p className={`font-bold ${authorColor}`}>{author}</p>
<p className="text-sm text-gray-500">{role}</p>
</div>
</div>
{(magicMoment || result) && (
<div className="mt-4 p-3 bg-white rounded-lg">
<p className="text-sm text-purple-600 font-medium">
{magicMoment ? `✨ Momento mágico: ${magicMoment}` : `🎯 Resultado: ${result}`}
</p>
</div>
)}
</div>
);
}

View File

@ -0,0 +1,50 @@
import { useRudderstack } from './useRudderstack';
interface ButtonTrackingOptions {
category?: string;
location?: string;
}
export function useButtonTracking(options: ButtonTrackingOptions = {}) {
const { track } = useRudderstack();
const { category = 'interaction', location = window.location.pathname } = options;
const trackButtonClick = (
buttonId: string,
properties?: {
label?: string;
value?: string | number;
action?: string;
variant?: string;
position?: string;
[key: string]: any;
}
) => {
track('button_clicked', {
button_id: buttonId,
category,
location,
timestamp: new Date().toISOString(),
...properties,
// Informações da página
page_title: document.title,
page_url: window.location.href,
page_path: window.location.pathname,
// Informações do dispositivo/viewport
viewport_width: window.innerWidth,
viewport_height: window.innerHeight,
device_type: getDeviceType(),
});
};
const getDeviceType = () => {
const width = window.innerWidth;
if (width < 768) return 'mobile';
if (width < 1024) return 'tablet';
return 'desktop';
};
return {
trackButtonClick,
};
}

60
src/hooks/useDataLayer.ts Normal file
View File

@ -0,0 +1,60 @@
interface DataLayerEvent {
event: string;
[key: string]: any;
}
declare global {
interface Window {
dataLayer: any[];
}
}
export function useDataLayer() {
// Inicializa o dataLayer se não existir
if (!window.dataLayer) {
window.dataLayer = [];
}
const push = (data: DataLayerEvent) => {
window.dataLayer.push(data);
};
const pageView = (path: string) => {
push({
event: 'pageview',
page: {
path,
title: document.title,
},
});
};
const trackEvent = (
category: string,
action: string,
label?: string,
value?: number
) => {
push({
event: 'track_event',
category,
action,
label,
value,
});
};
const trackUserProperties = (properties: Record<string, any>) => {
push({
event: 'set_user_properties',
user_properties: properties,
});
};
return {
push,
pageView,
trackEvent,
trackUserProperties,
};
}

View File

@ -0,0 +1,114 @@
import * as Sentry from '@sentry/react';
import { useRudderstack } from './useRudderstack';
interface ErrorTrackingOptions {
category?: string;
userId?: string;
userEmail?: string;
}
export function useErrorTracking(options: ErrorTrackingOptions = {}) {
const { track } = useRudderstack();
const { category = 'error', userId, userEmail } = options;
const trackError = (
error: Error,
context?: {
componentName?: string;
action?: string;
metadata?: Record<string, any>;
}
) => {
// 1. Rastreia no Sentry primeiro (para debug técnico)
Sentry.withScope((scope) => {
// Adiciona contexto do usuário
if (userId) scope.setUser({ id: userId, email: userEmail });
// Adiciona contexto do erro
if (context?.componentName) scope.setTag('component', context.componentName);
if (context?.action) scope.setTag('action', context.action);
if (context?.metadata) scope.setContext('metadata', context.metadata);
// Captura o erro
Sentry.captureException(error);
});
// 2. Rastreia no Rudderstack (para analytics)
track('error_occurred', {
category,
error_name: error.name,
error_message: error.message,
error_stack: error.stack,
component: context?.componentName,
action: context?.action,
...context?.metadata,
// Informações do ambiente
url: window.location.href,
user_agent: navigator.userAgent,
timestamp: new Date().toISOString(),
});
};
const trackErrorBoundary = (
error: Error,
componentStack: string,
componentName: string
) => {
// 1. Rastreia no Sentry
Sentry.withScope((scope) => {
if (userId) scope.setUser({ id: userId, email: userEmail });
scope.setTag('component', componentName);
scope.setTag('error_type', 'react_error_boundary');
scope.setExtra('componentStack', componentStack);
Sentry.captureException(error);
});
// 2. Rastreia no Rudderstack
track('error_boundary_triggered', {
category,
error_name: error.name,
error_message: error.message,
component_name: componentName,
component_stack: componentStack,
url: window.location.href,
user_agent: navigator.userAgent,
timestamp: new Date().toISOString(),
});
};
const trackApiError = (
error: any,
endpoint: string,
method: string,
requestData?: any
) => {
// 1. Rastreia no Sentry
Sentry.withScope((scope) => {
if (userId) scope.setUser({ id: userId, email: userEmail });
scope.setTag('error_type', 'api_error');
scope.setTag('endpoint', endpoint);
scope.setTag('method', method);
scope.setContext('request', { data: requestData });
Sentry.captureException(error);
});
// 2. Rastreia no Rudderstack
track('api_error_occurred', {
category,
endpoint,
method,
error_name: error.name,
error_message: error.message,
status_code: error.status || error.statusCode,
request_data: requestData,
url: window.location.href,
timestamp: new Date().toISOString(),
});
};
return {
trackError,
trackErrorBoundary,
trackApiError,
};
}

View File

@ -0,0 +1,83 @@
import { useRudderstack } from './useRudderstack';
interface FormTrackingOptions {
formId: string;
formName: string;
category?: string;
}
export function useFormTracking({ formId, formName, category = 'form' }: FormTrackingOptions) {
const { track } = useRudderstack();
const trackFormStarted = () => {
track('form_started', {
form_id: formId,
form_name: formName,
category,
});
};
const trackFormStepCompleted = (step: string, isValid: boolean) => {
track('form_step_completed', {
form_id: formId,
form_name: formName,
category,
step,
is_valid: isValid,
});
};
const trackFormSubmitted = (isValid: boolean, fields?: Record<string, any>) => {
track('form_submitted', {
form_id: formId,
form_name: formName,
category,
is_valid: isValid,
...fields,
});
};
const trackFormError = (errorType: string, errorMessage: string, field?: string) => {
track('form_error', {
form_id: formId,
form_name: formName,
category,
error_type: errorType,
error_message: errorMessage,
field,
});
};
const trackFormAbandoned = (step?: string) => {
track('form_abandoned', {
form_id: formId,
form_name: formName,
category,
step,
});
};
const trackFieldInteraction = (
fieldName: string,
interactionType: 'focus' | 'blur' | 'change',
value?: string
) => {
track('form_field_interaction', {
form_id: formId,
form_name: formName,
category,
field_name: fieldName,
interaction_type: interactionType,
field_value: value,
});
};
return {
trackFormStarted,
trackFormStepCompleted,
trackFormSubmitted,
trackFormError,
trackFormAbandoned,
trackFieldInteraction,
};
}

View File

@ -0,0 +1,55 @@
interface RudderstackEvent {
event: string;
properties?: Record<string, any>;
}
interface UserTraits {
[key: string]: any;
}
export function useRudderstack() {
const track = (eventName: string, properties?: Record<string, any>) => {
if (window.rudderanalytics) {
window.rudderanalytics.track(eventName, properties);
}
};
const page = (name?: string, properties?: Record<string, any>) => {
if (window.rudderanalytics) {
window.rudderanalytics.page(name, properties);
}
};
const identify = (userId: string, traits?: UserTraits) => {
if (window.rudderanalytics) {
window.rudderanalytics.identify(userId, traits);
}
};
const group = (groupId: string, traits?: Record<string, any>) => {
if (window.rudderanalytics) {
window.rudderanalytics.group(groupId, traits);
}
};
const alias = (newUserId: string) => {
if (window.rudderanalytics) {
window.rudderanalytics.alias(newUserId);
}
};
const reset = () => {
if (window.rudderanalytics) {
window.rudderanalytics.reset();
}
};
return {
track,
page,
identify,
group,
alias,
reset,
};
}

View File

@ -1,11 +1,44 @@
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client'; import { createRoot } from 'react-dom/client';
import { RouterProvider } from 'react-router-dom'; import { RouterProvider } from 'react-router-dom';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import * as Sentry from "@sentry/react";
import { router } from './routes'; import { router } from './routes';
import { Toaster } from './components/ui/toaster'; import { Toaster } from './components/ui/toaster';
import { GoogleTagManager } from './components/analytics/GoogleTagManager';
import { RudderstackAnalytics } from './components/analytics/RudderstackAnalytics';
import './index.css'; import './index.css';
// GTM ID - Substitua pelo seu ID real do GTM
const GTM_ID = import.meta.env.VITE_GTM_ID;
// Rudderstack Config
const RUDDERSTACK_WRITE_KEY = import.meta.env.VITE_RUDDERSTACK_WRITE_KEY;
const RUDDERSTACK_DATA_PLANE_URL = import.meta.env.VITE_RUDDERSTACK_DATA_PLANE_URL;
// Inicialização do Sentry
Sentry.init({
dsn: "https://6c15876055bf4a860c1b63a8e4e7ca65@o544400.ingest.us.sentry.io/4508626073092096",
integrations: [
Sentry.browserTracingIntegration(),
Sentry.replayIntegration(),
],
environment: import.meta.env.MODE,
tracesSampleRate: import.meta.env.DEV ? 1.0 : 0.2,
tracePropagationTargets: [
"localhost",
"historiasmagicas.netlify.app",
"bsjlbnyslxzsdwxvkaap.supabase.co"
],
replaysSessionSampleRate: import.meta.env.DEV ? 1.0 : 0.1,
replaysOnErrorSampleRate: 1.0,
beforeSend(event) {
if (import.meta.env.DEV) {
return null;
}
return event;
},
});
const queryClient = new QueryClient({ const queryClient = new QueryClient({
defaultOptions: { defaultOptions: {
queries: { queries: {
@ -16,15 +49,19 @@ const queryClient = new QueryClient({
}, },
}); });
function Root() { const rootElement = document.getElementById('root');
return ( if (!rootElement) throw new Error('Failed to find the root element');
<StrictMode>
<QueryClientProvider client={queryClient}>
<RouterProvider router={router} />
<Toaster />
</QueryClientProvider>
</StrictMode>
);
}
createRoot(document.getElementById('root')!).render(<Root />); const root = createRoot(rootElement);
root.render(
<QueryClientProvider client={queryClient}>
<GoogleTagManager gtmId={GTM_ID} />
<RudderstackAnalytics
writeKey={RUDDERSTACK_WRITE_KEY}
dataPlaneUrl={RUDDERSTACK_DATA_PLANE_URL}
/>
<RouterProvider router={router} />
<Toaster />
</QueryClientProvider>
);

View File

@ -1,410 +1,265 @@
import React from 'react'; import React from 'react';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { import {
ArrowRight, Wand2, Shield, Star, BookOpen, ArrowRight,
Brain, Target, Users, Award, CheckCircle, Brain,
Clock, Heart, Sparkles, ScrollText, Lock, X, BookOpen,
Facebook, Instagram, Twitter, Youtube Target,
Wand2,
Star,
Shield,
Sparkles,
ScrollText,
Lock,
Heart,
Facebook,
Instagram,
Twitter,
Youtube,
CheckCircle,
LineChart,
Clock
} from 'lucide-react'; } from 'lucide-react';
import { Footer } from '@/components/ui/footer';
import { StatCard } from '@/components/ui/stat-card';
import { TestimonialCard } from '@/components/ui/testimonial-card';
import { FeatureCard } from '@/components/ui/feature-card';
import { ProcessStep } from '@/components/ui/process-step';
import { InfoCard } from '@/components/ui/info-card';
import { ComparisonSection } from '@/components/ui/comparison-section';
import { PlanForParents } from '@/components/ui/plan-for-parents'; import { PlanForParents } from '@/components/ui/plan-for-parents';
import { FAQ } from '@/components/ui/faq';
import { Footer } from '@/components/ui/footer';
export function EducationalForParents(): JSX.Element { export function EducationalForParents() {
const navigate = useNavigate();
return ( return (
<div className="min-h-screen"> <div className="min-h-screen bg-white">
{/* 1. Hero Section */} {/* Hero Section */}
<section className="relative overflow-hidden bg-gradient-to-b from-purple-50 via-white to-purple-50"> <div className="relative isolate overflow-hidden bg-gradient-to-b from-purple-100/20">
<div className="absolute inset-0 bg-[url('/patterns/magic.svg')] opacity-5" /> <div className="mx-auto max-w-7xl px-6 pb-24 pt-10 sm:pb-32 lg:flex lg:px-8 lg:py-40">
<div className="px-4 py-24 mx-auto max-w-7xl relative"> <div className="mx-auto max-w-2xl lg:mx-0 flex-shrink-0 lg:pt-8">
{/* Reading Time */} <div className="absolute right-4 top-4 text-gray-600 flex items-center gap-2">
<div className="absolute top-8 right-8 flex items-center gap-2 text-sm text-gray-500"> <Clock className="w-4 h-4" />
<Clock className="h-4 w-4" /> <span className="text-sm">Tempo de leitura: 5 minutos</span>
<span>Tempo de leitura: 5 minutos</span>
</div>
<div className="flex flex-col md:flex-row items-center gap-16">
<div className="flex-1 space-y-8">
<h1 className="text-6xl font-bold text-gray-900 leading-tight">
Transforme o Aprendizado em Uma
<span className="block bg-gradient-to-r from-purple-600 to-blue-500 bg-clip-text text-transparent">
Aventura Mágica
</span>
</h1>
<p className="text-xl text-gray-600 leading-relaxed">
Histórias educativas personalizadas que encantam e ensinam, criadas especialmente
para o desenvolvimento único do seu filho.
</p>
<div className="flex gap-4">
<button
onClick={() => navigate('/register/parent')}
className="group px-8 py-4 bg-gradient-to-r from-purple-600 to-blue-500
text-white rounded-xl hover:from-purple-700 hover:to-blue-600
transform hover:scale-105 transition-all shadow-lg"
>
Comece Sua Aventura Mágica Grátis
<ArrowRight className="inline-block ml-2 h-5 w-5
group-hover:translate-x-1 transition-transform" />
</button>
</div>
{/* Social Proof */}
<div className="flex gap-8 text-sm text-gray-600">
<div className="flex items-center gap-2">
<BookOpen className="h-5 w-5 text-purple-600" />
<span>Mais de 10.000 histórias mágicas criadas</span>
</div>
<div className="flex items-center gap-2">
<Users className="h-5 w-5 text-blue-500" />
<span>5.000 pequenos leitores encantados</span>
</div>
</div>
</div> </div>
<div className="flex-1"> <h1 className="mt-10 text-4xl font-bold tracking-tight text-gray-900 sm:text-6xl">
<div className="relative"> Transforme o<br />
<div className="absolute -inset-4 bg-gradient-to-r from-purple-600 to-blue-500 Aprendizado em<br />
rounded-2xl blur-lg opacity-20" /> Uma <span className="text-purple-600">Aventura Mágica</span>
<img </h1>
src="/images/magic-book.webp"
alt="Crianças mergulhadas em um livro mágico" <p className="mt-6 text-lg leading-8 text-gray-600 max-w-xl">
className="relative rounded-2xl shadow-2xl transform hover:scale-[1.02] Histórias educativas personalizadas que encantam e ensinam,
transition-transform" criadas especialmente para o desenvolvimento único do seu filho.
/> </p>
</div>
</div> <div className="mt-10">
</div> <button
</div> onClick={() => window.location.href = '/cadastro'}
</section> className="rounded-xl bg-purple-600 px-8 py-4 text-base font-semibold text-white shadow-sm hover:bg-purple-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-purple-600 flex items-center gap-2"
{/* 2. Problema & Solução */}
<section className="px-4 py-24 bg-white">
<div className="mx-auto max-w-7xl">
<h2 className="text-4xl font-bold text-center text-gray-900 mb-16">
Desafios que Todo Pai Enfrenta
</h2>
<div className="grid md:grid-cols-3 gap-8 mb-16">
{challenges.map((challenge, index) => (
<div key={index} className="p-6 bg-purple-50 rounded-xl">
<challenge.icon className="h-12 w-12 text-purple-600 mb-4" />
<h3 className="text-xl font-bold text-gray-900 mb-2">
{challenge.title}
</h3>
<p className="text-gray-600">{challenge.description}</p>
</div>
))}
</div>
<div className="grid md:grid-cols-4 gap-8">
{benefits.map((benefit, index) => (
<div key={index} className="text-center">
<div className="mx-auto w-16 h-16 flex items-center justify-center
bg-gradient-to-r from-purple-600 to-blue-500 rounded-full mb-4">
<benefit.icon className="h-8 w-8 text-white" />
</div>
<h4 className="font-bold text-gray-900 mb-2">{benefit.title}</h4>
<p className="text-sm text-gray-600">{benefit.description}</p>
</div>
))}
</div>
</div>
</section>
{/* 3. Como a Magia Acontece */}
<section className="px-4 py-24 bg-gradient-to-br from-purple-50 to-blue-50">
<div className="mx-auto max-w-7xl">
<h2 className="text-4xl font-bold text-center text-gray-900 mb-16">
Como a Magia Acontece
</h2>
<div className="grid md:grid-cols-2 gap-12 items-center">
<div className="space-y-12">
{magicSteps.map((step, index) => (
<div key={index} className="flex gap-6">
<div className="flex-shrink-0 w-12 h-12 bg-gradient-to-r from-purple-600
to-blue-500 text-white rounded-full flex items-center justify-center
text-xl font-bold">
{index + 1}
</div>
<div>
<h3 className="text-xl font-bold text-gray-900 mb-2">
{step.title}
</h3>
<p className="text-gray-600">{step.description}</p>
</div>
</div>
))}
</div>
<div className="relative">
<div className="aspect-video rounded-xl overflow-hidden shadow-xl">
<video
className="w-full h-full object-cover"
autoPlay
muted
loop
playsInline
poster="/images/demo-poster.webp"
>
<source src="/videos/demo.mp4" type="video/mp4" />
</video>
</div>
<div className="absolute -bottom-6 -right-6 bg-white p-4 rounded-lg shadow-lg">
<div className="flex items-center gap-2 text-sm text-purple-600 font-medium">
<Sparkles className="h-4 w-4" />
<span>Veja a mágica acontecer!</span>
</div>
</div>
</div>
</div>
</div>
</section>
{/* 4. Comparação */}
<section className="px-4 py-24 bg-white">
<div className="mx-auto max-w-7xl">
<h2 className="text-4xl font-bold text-center text-gray-900 mb-16">
A Magia da Transformação
</h2>
<div className="grid md:grid-cols-2 gap-8">
{/* Sem Histórias Mágicas */}
<div className="p-8 bg-gray-50 rounded-xl border border-gray-200">
<div className="flex items-center gap-3 mb-8">
<div className="w-12 h-12 bg-red-100 rounded-full flex items-center justify-center">
<X className="h-6 w-6 text-red-500" />
</div>
<h3 className="text-xl font-bold text-gray-900">
Sem Histórias Mágicas
</h3>
</div>
{comparisonData.map((category, index) => (
<div key={index} className="mb-8 last:mb-0">
<h4 className="font-bold text-gray-900 mb-4">{category.title}</h4>
<ul className="space-y-3">
{category.without.map((item, idx) => (
<li key={idx} className="flex items-start gap-2">
<X className="h-5 w-5 text-red-500 flex-shrink-0 mt-1" />
<span className="text-gray-600">{item}</span>
</li>
))}
</ul>
</div>
))}
</div>
{/* Com Histórias Mágicas */}
<div className="p-8 bg-gradient-to-br from-purple-50 to-blue-50 rounded-xl
border-2 border-purple-200 transform hover:scale-[1.02] transition-transform">
<div className="flex items-center gap-3 mb-8">
<div className="w-12 h-12 bg-gradient-to-r from-purple-600 to-blue-500
rounded-full flex items-center justify-center">
<CheckCircle className="h-6 w-6 text-white" />
</div>
<h3 className="text-xl font-bold text-gray-900">
Com Histórias Mágicas
</h3>
</div>
{comparisonData.map((category, index) => (
<div key={index} className="mb-8 last:mb-0">
<h4 className="font-bold text-gray-900 mb-4">{category.title}</h4>
<ul className="space-y-3">
{category.with.map((item, idx) => (
<li key={idx} className="flex items-start gap-2">
<CheckCircle className="h-5 w-5 text-green-500 flex-shrink-0 mt-1" />
<span className="text-gray-600">{item}</span>
</li>
))}
</ul>
</div>
))}
</div>
</div>
</div>
</section>
{/* 5. Benefícios Mágicos Detalhados */}
<section className="px-4 py-24 bg-gradient-to-br from-purple-50 to-blue-50">
<div className="mx-auto max-w-7xl">
<h2 className="text-4xl font-bold text-center text-gray-900 mb-16">
Benefícios Mágicos Detalhados
</h2>
<div className="grid lg:grid-cols-5 gap-8 mb-16">
{detailedBenefits.map((benefit, index) => (
<div
key={index}
className="bg-white p-6 rounded-xl shadow-sm hover:shadow-md
transform hover:scale-105 transition-all"
> >
<div className="flex flex-col items-center text-center gap-4"> Comece Sua Aventura Mágica Grátis
<div className="w-16 h-16 flex items-center justify-center <ArrowRight className="w-5 h-5" />
bg-gradient-to-r from-purple-600 to-blue-500 rounded-full"> </button>
<benefit.icon className="h-8 w-8 text-white" /> </div>
</div>
<h3 className="text-xl font-bold text-gray-900">{benefit.title}</h3>
<p className="text-gray-600">{benefit.description}</p>
</div>
</div>
))}
</div>
{/* Preview do Portal */} <div className="mt-10 flex items-center gap-x-8 text-sm text-gray-600">
<div className="relative mt-20"> <div className="flex items-center gap-x-2">
<div className="absolute -inset-4 bg-gradient-to-r from-purple-600 to-blue-500 <BookOpen className="w-5 h-5 text-purple-600" />
rounded-2xl blur-lg opacity-20" /> <span>Mais de 10.000 histórias mágicas criadas</span>
<div className="relative bg-white p-8 rounded-xl shadow-xl"> </div>
<div className="grid md:grid-cols-2 gap-12 items-center"> <div className="flex items-center gap-x-2">
<div> <Target className="w-5 h-5 text-purple-600" />
<h3 className="text-2xl font-bold text-gray-900 mb-6"> <span>5.000 pequenos leitores encantados</span>
Portal dos Pais: Acompanhamento em Tempo Real
</h3>
<ul className="space-y-4">
<li className="flex items-start gap-3">
<CheckCircle className="h-6 w-6 text-green-500 flex-shrink-0 mt-1" />
<span className="text-gray-600">
Métricas detalhadas de progresso e desenvolvimento
</span>
</li>
<li className="flex items-start gap-3">
<CheckCircle className="h-6 w-6 text-green-500 flex-shrink-0 mt-1" />
<span className="text-gray-600">
Relatórios semanais personalizados
</span>
</li>
<li className="flex items-start gap-3">
<CheckCircle className="h-6 w-6 text-green-500 flex-shrink-0 mt-1" />
<span className="text-gray-600">
Recomendações pedagógicas baseadas em dados
</span>
</li>
<li className="flex items-start gap-3">
<CheckCircle className="h-6 w-6 text-green-500 flex-shrink-0 mt-1" />
<span className="text-gray-600">
Histórico completo de leituras e conquistas
</span>
</li>
</ul>
</div>
<div className="relative">
<img
src="/images/dashboard-preview.webp"
alt="Portal dos Pais"
className="rounded-xl shadow-2xl"
/>
<div className="absolute -bottom-6 -right-6 bg-white p-4 rounded-lg shadow-lg">
<div className="flex items-center gap-2 text-sm text-purple-600 font-medium">
<Lock className="h-4 w-4" />
<span>Ambiente 100% seguro e monitorado</span>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
</div>
</section>
{/* 6. Testimoniais */} <div className="mx-auto mt-16 flex max-w-2xl sm:mt-24 lg:ml-10 lg:mr-0 lg:mt-0 lg:max-w-none lg:flex-none xl:ml-32">
<section className="px-4 py-24 bg-white"> <div className="max-w-3xl flex-none sm:max-w-5xl lg:max-w-none">
<div className="mx-auto max-w-7xl"> <img
<h2 className="text-4xl font-bold text-center text-gray-900 mb-16"> src="/images/hero-image.webp"
alt="Crianças mergulhadas em um livro mágico"
className="w-[76rem] rounded-md bg-white/5 shadow-2xl ring-1 ring-white/10"
/>
</div>
</div>
</div>
</div>
{/* Challenges Section */}
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-24">
<div className="text-center">
<h2 className="text-3xl font-bold tracking-tight text-gray-900 sm:text-4xl">
Desafios da Educação Moderna
</h2>
<p className="mt-4 text-lg leading-8 text-gray-600">
Entendemos os obstáculos que pais e educadores enfrentam no desenvolvimento da leitura.
</p>
</div>
<div className="mt-16 grid grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-3">
{challenges.map((challenge, index) => (
<InfoCard
key={index}
icon={challenge.icon}
title={challenge.title}
description={challenge.description}
/>
))}
</div>
</div>
{/* Magic Process Section */}
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-24 bg-gradient-to-b from-purple-50">
<div className="text-center">
<h2 className="text-3xl font-bold tracking-tight text-gray-900 sm:text-4xl">
Como Funciona a Magia
</h2>
<p className="mt-4 text-lg leading-8 text-gray-600">
Um processo simples e eficaz para transformar a leitura em uma aventura inesquecível.
</p>
</div>
<div className="mt-16 space-y-12">
{magicSteps.map((step, index) => (
<ProcessStep
key={index}
number={index + 1}
title={step.title}
description={step.description}
/>
))}
</div>
</div>
{/* Comparison Section */}
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-24">
<ComparisonSection
title="A Magia da Transformação"
items={comparisonData}
/>
</div>
{/* Benefits Section */}
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-24 bg-gradient-to-b from-purple-50">
<div className="text-center">
<h2 className="text-3xl font-bold tracking-tight text-gray-900 sm:text-4xl">
Benefícios Mágicos
</h2>
<p className="mt-4 text-lg leading-8 text-gray-600">
Descubra todas as vantagens que nossa plataforma oferece para o desenvolvimento do seu filho.
</p>
</div>
<div className="mt-16 grid grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-3">
{detailedBenefits.map((benefit, index) => (
<FeatureCard
key={index}
icon={benefit.icon}
title={benefit.title}
description={benefit.description}
/>
))}
</div>
</div>
{/* Results Section */}
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-24">
<div className="text-center">
<h2 className="text-3xl font-bold tracking-tight text-gray-900 sm:text-4xl">
Resultados Comprovados
</h2>
<p className="mt-4 text-lg leading-8 text-gray-600">
Números que demonstram o impacto do Histórias Mágicas no aprendizado.
</p>
</div>
<div className="mt-16 grid grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-4">
<StatCard
icon={LineChart}
title="Fluência de Leitura"
value="95%"
description="de melhora na velocidade e compreensão"
/>
<StatCard
icon={Clock}
title="Tempo de Leitura"
value="3x"
description="mais tempo dedicado à leitura diária"
/>
<StatCard
icon={Star}
title="Satisfação"
value="98%"
description="dos pais recomendam a plataforma"
/>
<StatCard
icon={BookOpen}
title="Histórias Lidas"
value="50+"
description="histórias por aluno em média"
/>
</div>
</div>
{/* Testimonials Section */}
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-24 bg-gradient-to-b from-purple-50">
<div className="text-center">
<h2 className="text-3xl font-bold tracking-tight text-gray-900 sm:text-4xl">
Histórias de Transformação Histórias de Transformação
</h2> </h2>
<p className="mt-4 text-lg leading-8 text-gray-600">
<div className="grid md:grid-cols-3 gap-8"> Veja como o Histórias Mágicas está transformando a vida de famílias por todo o Brasil.
{testimonials.map((testimonial, index) => (
<div key={index} className="bg-gradient-to-br from-purple-50 to-blue-50
p-6 rounded-xl shadow-sm">
<div className="relative mb-8">
<img
src={testimonial.image}
alt={`Família de ${testimonial.name}`}
className="w-full h-48 object-cover rounded-lg"
/>
<div className="absolute -bottom-4 -right-4 bg-white p-2 rounded-full shadow-lg">
<Heart className="h-6 w-6 text-red-500" />
</div>
</div>
<p className="text-gray-600 mb-4 italic">"{testimonial.text}"</p>
<div>
<p className="font-bold text-gray-900">{testimonial.name}</p>
<p className="text-sm text-gray-500">{testimonial.role}</p>
</div>
<div className="mt-4 p-3 bg-white rounded-lg">
<p className="text-sm text-purple-600 font-medium">
Momento mágico: {testimonial.magicMoment}
</p>
</div>
</div>
))}
</div>
</div>
</section>
{/* 7. Planos */}
<PlanForParents />
{/* 8. FAQ */}
<section className="px-4 py-24 bg-white">
<div className="mx-auto max-w-3xl">
<h2 className="text-4xl font-bold text-center text-gray-900 mb-16">
Perguntas Mágicas
</h2>
<div className="space-y-8">
{faqItems.map((item, index) => (
<div key={index} className="bg-gray-50 rounded-xl p-6">
<h3 className="text-xl font-bold text-gray-900 mb-2">{item.question}</h3>
<p className="text-gray-600">{item.answer}</p>
</div>
))}
</div>
</div>
</section>
{/* 9. CTA Final */}
<section className="px-4 py-24 bg-gradient-to-br from-purple-600 to-blue-500 text-white">
<div className="mx-auto max-w-3xl text-center">
<h2 className="text-4xl font-bold mb-8">
Comece a Jornada Mágica Hoje
</h2>
<p className="text-xl opacity-90 mb-12">
Transforme a educação do seu filho em uma aventura inesquecível
</p>
<div className="bg-white/10 p-6 rounded-xl mb-8">
<p className="font-medium mb-2">
Oferta por tempo limitado!
</p>
<p className="text-sm opacity-90">
7 dias grátis + Bônus especial de boas-vindas
</p>
</div>
<button
onClick={() => navigate('/register/parent')}
className="px-12 py-6 bg-white text-purple-600 rounded-xl text-xl font-bold
hover:bg-gray-100 transform hover:scale-105 transition-all shadow-lg"
>
Criar Conta Gratuita
<ArrowRight className="inline-block ml-2 h-6 w-6" />
</button>
<p className="mt-6 text-sm opacity-75">
Garantia de 30 dias ou seu dinheiro de volta
</p> </p>
</div> </div>
</section> <div className="mt-16 grid grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-3">
{testimonials.map((testimonial, index) => (
<TestimonialCard
key={index}
quote={testimonial.text}
author={testimonial.name}
role={testimonial.role}
image={testimonial.image}
magicMoment={testimonial.magicMoment}
/>
))}
</div>
</div>
{/* Pricing Section */}
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-24">
<PlanForParents />
</div>
{/* FAQ Section */}
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-24 bg-gradient-to-b from-purple-50">
<FAQ
title="Dúvidas Frequentes"
description="Encontre respostas para as perguntas mais comuns sobre nossa plataforma."
items={faqItems}
/>
</div>
{/* Final CTA */}
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-24">
<div className="rounded-3xl bg-purple-600 px-8 py-16">
<div className="mx-auto max-w-2xl text-center">
<h2 className="text-3xl font-bold tracking-tight text-white sm:text-4xl">
Comece a Jornada Mágica Hoje
</h2>
<p className="mx-auto mt-6 max-w-xl text-lg leading-8 text-white/90">
Junte-se a milhares de famílias que descobriram o poder da leitura personalizada.
</p>
<div className="mt-10 flex items-center justify-center gap-x-6">
<button
onClick={() => window.location.href = '/cadastro'}
className="rounded-xl bg-white px-3.5 py-2.5 text-sm font-semibold text-purple-600 shadow-sm hover:bg-purple-50"
>
Começar Gratuitamente
</button>
</div>
</div>
</div>
</div>
{/* Footer */}
<Footer /> <Footer />
</div> </div>
); );
@ -413,18 +268,18 @@ export function EducationalForParents(): JSX.Element {
const challenges = [ const challenges = [
{ {
icon: Brain, icon: Brain,
title: "Manter as crianças interessadas em aprender", title: 'Dificuldade de Concentração',
description: "É difícil competir com jogos e vídeos para capturar a atenção das crianças." description: 'Crianças têm dificuldade em manter o foco em métodos tradicionais de leitura.'
}, },
{ {
icon: BookOpen, icon: BookOpen,
title: "Encontrar conteúdo educativo de qualidade", title: 'Falta de Engajamento',
description: "Muito conteúdo disponível, mas pouco realmente educativo e envolvente." description: 'Livros convencionais nem sempre capturam a imaginação das crianças modernas.'
}, },
{ {
icon: Target, icon: Target,
title: "Acompanhar o desenvolvimento da criança", title: 'Progresso Lento',
description: "Falta de ferramentas para monitorar o progresso de forma clara e objetiva." description: 'Pais têm dificuldade em acompanhar e estimular o desenvolvimento da leitura.'
} }
]; ];
@ -453,147 +308,152 @@ const benefits = [
const magicSteps = [ const magicSteps = [
{ {
title: "Escolha o tema da aventura", title: 'Escolha do Tema',
description: "Selecione entre diversos temas educativos alinhados com a BNCC e adequados à idade." description: 'Selecione entre diversos temas educativos que despertam o interesse do seu filho.'
}, },
{ {
title: "Personalize os personagens", title: 'Personalização Mágica',
description: "Crie personagens que seu filho vai adorar, com características únicas e cativantes." description: 'Crie personagens que se conectam com a realidade e interesses da criança.'
}, },
{ {
title: "A IA cria a história mágica", title: 'Geração da História',
description: "Nossa IA educacional gera uma história personalizada em segundos." description: 'Nossa IA cria uma narrativa única, adaptada ao nível de leitura do seu filho.'
}, },
{ {
title: "A aventura educativa começa", title: 'Aventura Educativa',
description: "Seu filho mergulha em uma jornada mágica de aprendizado e diversão." description: 'Acompanhe o progresso enquanto seu filho se diverte aprendendo.'
} }
]; ];
const comparisonData = [ const comparisonData = [
{ {
title: "Tempo & Diversão", title: 'Tempo & Diversão',
without: [ without: [
"Horas procurando conteúdo educativo adequado", 'Horas procurando conteúdo educativo adequado',
"Crianças entediadas com leituras tradicionais", 'Crianças entediadas com leituras tradicionais',
"Histórias que não capturam a imaginação", 'Histórias que não capturam a imaginação',
"Dificuldade em acompanhar o progresso" 'Dificuldade em acompanhar o progresso'
], ],
with: [ with: [
"Histórias mágicas personalizadas em minutos", 'Histórias mágicas personalizadas em minutos',
"Crianças fascinadas por aventuras únicas", 'Crianças fascinadas por aventuras únicas',
"Mundos mágicos que educam e encantam", 'Mundos mágicos que educam e encantam',
"Portal mágico de acompanhamento do progresso" 'Portal mágico de acompanhamento do progresso'
] ]
}, },
{ {
title: "Qualidade do Aprendizado", title: 'Qualidade do Aprendizado',
without: [ without: [
"Conteúdo genérico e previsível", 'Conteúdo genérico e previsível',
"Falta de conexão emocional com a leitura", 'Falta de conexão emocional com a leitura',
"Dificuldade em manter o interesse", 'Dificuldade em manter o interesse',
"Aprendizado fragmentado" 'Aprendizado fragmentado'
], ],
with: [ with: [
"Histórias que evoluem com cada criança", 'Histórias que evoluem com cada criança',
"Conexão emocional com personagens únicos", 'Conexão emocional com personagens únicos',
"Aventuras que mesclam diversão e educação", 'Aventuras que mesclam diversão e educação',
"Jornada de aprendizado mágica e integrada" 'Jornada de aprendizado mágica e integrada'
] ]
}, },
{ {
title: "Resultados", title: 'Resultados',
without: [ without: [
"Progresso lento e desmotivador", 'Progresso lento e desmotivador',
"Resistência à leitura e aprendizado", 'Resistência à leitura e aprendizado',
"Rotina de estudos cansativa", 'Rotina de estudos cansativa',
"Pais preocupados com desenvolvimento" 'Pais preocupados com desenvolvimento'
], ],
with: [ with: [
"Evolução visível e empolgante", 'Evolução visível e empolgante',
"Amor natural pela leitura e conhecimento", 'Amor natural pela leitura e conhecimento',
"Aventuras diárias de aprendizado", 'Aventuras diárias de aprendizado',
"Pais confiantes no desenvolvimento mágico" 'Pais confiantes no desenvolvimento mágico'
] ]
} }
]; ];
const detailedBenefits = [ const detailedBenefits = [
{ {
icon: Wand2, icon: Wand2,
title: "Aprendizado Através de Aventuras", title: 'Histórias Personalizadas',
description: "Histórias que se adaptam ao nível e interesses do seu filho, tornando o aprendizado natural e divertido." description: 'Narrativas únicas que se adaptam aos interesses e nível de leitura do seu filho.'
}, },
{ {
icon: ScrollText, icon: Star,
title: "Portal dos Pais", title: 'Aprendizado Divertido',
description: "Acompanhe em tempo real o progresso de leitura, compreensão e desenvolvimento do seu filho." description: 'Transformamos o processo de leitura em uma aventura mágica e envolvente.'
}, },
{ {
icon: Shield, icon: Shield,
title: "Proteção Mágica", title: 'Ambiente Seguro',
description: "Conteúdo 100% seguro e adequado, com moderação constante e controles parentais." description: 'Conteúdo apropriado para a idade e monitoramento constante do progresso.'
}, },
{ {
icon: BookOpen, icon: Sparkles,
title: "Alinhamento com BNCC", title: 'Recompensas Mágicas',
description: "Histórias criadas seguindo as diretrizes da Base Nacional Comum Curricular." description: 'Sistema de conquistas que motiva e celebra o progresso da criança.'
}, },
{ {
icon: Brain, icon: ScrollText,
title: "IA Educacional", title: 'Relatórios Detalhados',
description: "Nossa inteligência artificial analisa o perfil do seu filho para criar histórias personalizadas e adaptativas." description: 'Acompanhe o desenvolvimento da leitura com métricas claras e insights valiosos.'
},
{
icon: Lock,
title: 'Controle Parental',
description: 'Defina limites, monitore o uso e mantenha-se informado sobre o progresso.'
} }
]; ];
const testimonials = [ const testimonials = [
{ {
text: "Minha filha sempre teve dificuldade com leitura, mas desde que começamos a usar o Histórias Mágicas, ela não para de pedir para ler mais uma história!",
name: "Ana Clara Silva",
role: "Mãe da Sofia, 8 anos",
image: "/images/testimonial-1.webp", image: "/images/testimonial-1.webp",
text: "Minha filha passou de resistente à leitura para não querer parar de ler! As histórias personalizadas fizeram toda a diferença.", magicMoment: "Sofia leu sua primeira história sozinha após 2 semanas"
name: "Ana Silva",
role: "Mãe da Maria, 8 anos",
magicMoment: "Primeira história completa lida sozinha"
}, },
{ {
text: "As histórias personalizadas fizeram toda a diferença. Ver meu filho como protagonista das aventuras tornou a leitura muito mais envolvente.",
name: "Pedro Henrique Santos",
role: "Pai do Lucas, 7 anos",
image: "/images/testimonial-2.webp", image: "/images/testimonial-2.webp",
text: "Como pai, é incrível ver o progresso do Pedro. O portal dos pais me ajuda a entender exatamente onde ele precisa de apoio.", magicMoment: "Lucas aumentou seu vocabulário em 40% em 3 meses"
name: "Carlos Santos",
role: "Pai do Pedro, 10 anos",
magicMoment: "Superou a dificuldade com palavras complexas"
}, },
{ {
text: "O progresso que vimos em apenas algumas semanas foi incrível. A autoconfiança da minha filha na leitura cresceu enormemente.",
name: "Mariana Costa",
role: "Mãe da Laura, 9 anos",
image: "/images/testimonial-3.webp", image: "/images/testimonial-3.webp",
text: "As histórias são tão envolventes que meu filho pede para ler mais uma toda noite. O aprendizado acontece naturalmente!", magicMoment: "Laura passou de leitora básica para avançada"
name: "Juliana Costa",
role: "Mãe do Lucas, 7 anos",
magicMoment: "Começou a criar suas próprias histórias"
} }
]; ];
const faqItems = [ const faqItems = [
{ {
question: "Como a magia da IA funciona?", question: "Como a plataforma auxilia no trabalho do professor?",
answer: "Nossa IA educacional analisa o perfil do seu filho, incluindo idade, interesses e nível de leitura, para criar histórias únicas que combinam diversão com aprendizado personalizado." answer: "O Histórias Mágicas oferece ferramentas que automatizam a avaliação da leitura, gerando relatórios detalhados sobre o progresso de cada aluno. Isso permite que você foque seu tempo no que mais importa: o desenvolvimento personalizado de cada estudante."
}, },
{ {
question: "Como garantimos histórias seguras?", question: "A plataforma se integra ao currículo escolar?",
answer: "Todas as histórias passam por múltiplas camadas de verificação, incluindo filtros de IA e revisão humana, garantindo conteúdo 100% adequado e seguro." answer: "Sim, nossa plataforma foi desenvolvida alinhada à BNCC e pode ser facilmente integrada ao planejamento pedagógico. Oferecemos suporte para adaptar as atividades ao seu programa de ensino e objetivos específicos."
}, },
{ {
question: "Como acompanhar a evolução mágica?", question: "Como acompanhar o progresso da turma?",
answer: "Através do Portal dos Pais, você tem acesso a relatórios detalhados sobre fluência, compreensão, vocabulário e muito mais, com visualizações claras do progresso." answer: "Através do painel do professor, você tem acesso a análises individuais e coletivas, identificando padrões de dificuldade, monitorando o progresso e recebendo sugestões de intervenção baseadas em evidências científicas."
}, },
{ {
question: "Qual é a política de cancelamento?", question: "Vocês oferecem treinamento para os professores?",
answer: "Você pode cancelar sua assinatura a qualquer momento, sem multas. Oferecemos garantia de 30 dias - se não estiver satisfeito, devolvemos seu dinheiro." answer: "Sim, oferecemos treinamento completo e suporte contínuo. Nosso programa inclui workshops online, materiais de apoio e consultoria pedagógica para garantir que você aproveite ao máximo os recursos da plataforma."
}, },
{ {
question: "Quantas histórias mágicas por mês?", question: "Como a plataforma lida com diferentes níveis de leitura na mesma turma?",
answer: "O número de histórias varia conforme o plano escolhido, desde 5 histórias mensais no plano básico até histórias ilimitadas no plano Grão-Mestre." answer: "Nossa tecnologia adaptativa personaliza automaticamente as atividades para cada aluno, permitindo que todos progridam em seu próprio ritmo. Você recebe sugestões específicas para apoiar alunos que precisam de mais atenção."
}, },
{ {
question: "Como funciona o suporte aos pais?", question: "Quais recursos estão disponíveis para planejamento de aulas?",
answer: "Oferecemos suporte via chat, email e telefone, com especialistas em educação prontos para ajudar. Planos premium incluem acesso a pedagogos." answer: "Disponibilizamos um banco de atividades, planos de aula modelo, e ferramentas de personalização que permitem adaptar o conteúdo às necessidades específicas da sua turma. Tudo isso alinhado às melhores práticas pedagógicas."
} }
]; ];

View File

@ -24,6 +24,7 @@ import {
} from 'lucide-react'; } from 'lucide-react';
import { Footer } from '@/components/ui/footer'; import { Footer } from '@/components/ui/footer';
import { PlanForSchools } from '@/components/ui/plan-for-schools'; import { PlanForSchools } from '@/components/ui/plan-for-schools';
import { FAQ } from '@/components/ui/faq';
// Meta tags e SEO // Meta tags e SEO
const meta = { const meta = {
@ -189,7 +190,7 @@ export function EvidenceBased(): JSX.Element {
<section className="px-4 py-24 bg-white"> <section className="px-4 py-24 bg-white">
<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-16"> <h2 className="text-4xl font-bold text-center text-gray-900 mb-16">
Evidências vs. Pseudociência Pseudociência vs. Evidências
</h2> </h2>
<div className="grid md:grid-cols-2 gap-8"> <div className="grid md:grid-cols-2 gap-8">
@ -316,22 +317,36 @@ export function EvidenceBased(): JSX.Element {
<PlanForSchools /> <PlanForSchools />
{/* FAQ */} {/* FAQ */}
<section className="px-4 py-24 bg-white"> <FAQ
<div className="mx-auto max-w-3xl"> title="Dúvidas Frequentes sobre Educação Baseada em Evidências"
<h2 className="text-4xl font-bold text-center text-gray-900 mb-16"> description="Entenda como nossa plataforma aplica métodos cientificamente comprovados"
Perguntas Frequentes items={[
</h2> {
question: "O que é educação baseada em evidências?",
<div className="space-y-8"> answer: "Educação baseada em evidências é uma abordagem que utiliza métodos e práticas pedagógicas comprovadas por pesquisas científicas rigorosas. Em vez de seguir modismos ou teorias não testadas, baseamos nossas estratégias em estudos que demonstram resultados reais na aprendizagem."
{faqItems.map((item, index) => ( },
<div key={index} className="bg-gray-50 rounded-xl p-6"> {
<h3 className="text-xl font-bold text-gray-900 mb-2">{item.question}</h3> question: "Como vocês aplicam a ciência da leitura na prática?",
<p className="text-gray-600">{item.answer}</p> answer: "Nossa plataforma incorpora os cinco pilares da alfabetização: consciência fonêmica, instrução fônica sistemática, fluência, vocabulário e compreensão. Cada atividade é cuidadosamente projetada para desenvolver estas habilidades de forma estruturada e progressiva."
</div> },
))} {
</div> question: "Quais são as evidências que suportam seus métodos?",
</div> answer: "Nossos métodos são baseados em décadas de pesquisas em neurociência e psicologia cognitiva, incluindo estudos do National Reading Panel e pesquisas sobre desenvolvimento da leitura. Mantemos parcerias com universidades para validação contínua de nossa abordagem."
</section> },
{
question: "Como vocês medem o progresso dos alunos?",
answer: "Utilizamos avaliações formativas contínuas e análise de dados em tempo real para monitorar o progresso individual. Nosso sistema coleta métricas específicas de fluência, precisão e compreensão, permitindo intervenções personalizadas baseadas em evidências."
},
{
question: "Como a plataforma se adapta a diferentes níveis de aprendizado?",
answer: "Nossa tecnologia utiliza algoritmos adaptativos baseados em pesquisas sobre diferenciação de ensino. O sistema ajusta automaticamente a dificuldade e o tipo de atividades com base no desempenho individual, garantindo que cada aluno progrida em seu próprio ritmo."
},
{
question: "Qual é o papel do professor na plataforma?",
answer: "Os professores são facilitadores essenciais do processo. Nossa plataforma fornece dados detalhados e sugestões de intervenção baseadas em evidências, permitindo que os professores tomem decisões pedagógicas informadas e personalizem o suporte para cada aluno."
}
]}
/>
{/* CTA Final */} {/* CTA Final */}
<section className="px-4 py-24 bg-gradient-to-br from-purple-600 to-blue-500 text-white"> <section className="px-4 py-24 bg-gradient-to-br from-purple-600 to-blue-500 text-white">

View File

@ -4,6 +4,7 @@ import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContai
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { Footer } from '@/components/ui/footer'; import { Footer } from '@/components/ui/footer';
import { PlanForParents } from '@/components/ui/plan-for-parents'; import { PlanForParents } from '@/components/ui/plan-for-parents';
import { FAQ } from '@/components/ui/faq';
export function ParentsLandingPage(): JSX.Element { export function ParentsLandingPage(): JSX.Element {
const navigate = useNavigate(); const navigate = useNavigate();
@ -403,10 +404,42 @@ export function ParentsLandingPage(): JSX.Element {
{/* 5. Planos */} {/* 5. Planos */}
<PlanForParents /> <PlanForParents />
{/* 6. FAQ */}
<FAQ
title="Dúvidas Frequentes"
description="Tire suas dúvidas sobre o Histórias Mágicas"
items={[
{
question: "Como funciona o Histórias Mágicas?",
answer: "O Histórias Mágicas é uma plataforma interativa que combina tecnologia e pedagogia para desenvolver habilidades de leitura. Seu filho terá acesso a histórias personalizadas, feedback em tempo real e exercícios adaptados ao seu nível de leitura."
},
{
question: "Qual é a idade recomendada?",
answer: "A plataforma é ideal para crianças de 6 a 12 anos, mas pode ser adaptada para diferentes níveis de leitura. Nosso sistema personaliza a experiência de acordo com a idade e habilidade de cada criança."
},
{
question: "Como acompanho o progresso do meu filho?",
answer: "Através do portal dos pais, você tem acesso a relatórios detalhados sobre fluência, compreensão, pronúncia e ritmo de leitura. Você também recebe sugestões personalizadas para ajudar seu filho a melhorar."
},
{
question: "Posso cancelar a assinatura a qualquer momento?",
answer: "Sim, você pode cancelar sua assinatura quando quiser, sem multa ou burocracia. Oferecemos também um período de teste gratuito para você experimentar a plataforma."
},
{
question: "Quais dispositivos são compatíveis?",
answer: "O Histórias Mágicas funciona em qualquer navegador moderno, seja no computador, tablet ou smartphone. Recomendamos o uso de fones de ouvido para melhor experiência com os exercícios de pronúncia."
},
{
question: "Como é feita a avaliação da leitura?",
answer: "Utilizamos tecnologia avançada de reconhecimento de voz e inteligência artificial para avaliar a leitura em tempo real, considerando aspectos como fluência, pronúncia e compreensão. Tudo isso de forma lúdica e não intimidadora."
}
]}
/>
{/* 7. CTA Final */} {/* 7. CTA Final */}
<section className="px-4 py-24 relative overflow-hidden"> <section className="px-4 py-24 relative overflow-hidden">
<div className="absolute inset-0 bg-gradient-to-b from-purple-50 to-purple-100 opacity-50" /> <div className="absolute inset-0 bg-gradient-to-b from-purple-50 to-purple-100 opacity-50" />
<div className="mx-auto max-w-3xl text-center relative"> <div className="mx-auto max-3xl text-center relative">
<h2 className="text-5xl font-bold text-gray-900 mb-8 leading-tight"> <h2 className="text-5xl font-bold text-gray-900 mb-8 leading-tight">
Comece a Jornada de Leitura do Seu Filho Comece a Jornada de Leitura do Seu Filho
<span className="bg-gradient-to-r from-purple-600 to-indigo-600 bg-clip-text text-transparent"> <span className="bg-gradient-to-r from-purple-600 to-indigo-600 bg-clip-text text-transparent">

View File

@ -0,0 +1,463 @@
import React from 'react';
import { useNavigate } from 'react-router-dom';
import { ArrowRight, BookOpen, Brain, CheckCircle, Clock, FileText, Lightbulb, LineChart, School, Star, Target, Users } from 'lucide-react';
import { Footer } from '@/components/ui/footer';
export function TextSalesLetter() {
const navigate = useNavigate();
return (
<div className="min-h-screen bg-white">
{/* Hero Section */}
<div className="max-w-3xl mx-auto px-4 py-12 sm:py-16 lg:py-20">
<h1 className="text-4xl font-bold text-gray-900 mb-8 text-center">
A Revolução da Alfabetização: Como a Ciência e a Tecnologia Estão Transformando o Aprendizado da Leitura
</h1>
<div className="prose prose-lg max-w-none text-gray-600 space-y-6">
<p className="text-xl font-semibold text-purple-600">
Caro educador comprometido com o futuro da educação,
</p>
<p>
Em um mundo onde a tecnologia avança rapidamente e o acesso à informação é cada vez mais crucial,
uma verdade permanece inalterada: a alfabetização é a base fundamental para todo o desenvolvimento
educacional e pessoal de uma criança. No entanto, os dados são alarmantes.
</p>
<h2 className="text-2xl font-bold text-gray-900 mt-12">
O Cenário Atual da Alfabetização no Brasil
</h2>
<p>
De acordo com os últimos dados do SAEB (Sistema de Avaliação da Educação Básica):
</p>
<ul className="list-disc pl-6 space-y-2">
<li>Mais de 50% dos alunos do 5º ano não atingem níveis adequados de leitura</li>
<li>39,7% dos estudantes no 3º ano do ensino fundamental apresentam deficiências graves na compreensão textual</li>
<li>Cerca de 4,6 milhões de crianças entre 6 e 10 anos estão em risco de não desenvolverem habilidades básicas de leitura</li>
<li>A pandemia agravou ainda mais este cenário, aumentando as desigualdades educacionais</li>
</ul>
<p>
Estes números não são apenas estatísticas - são histórias reais de crianças que estão
perdendo oportunidades fundamentais para seu desenvolvimento.
</p>
<h2 className="text-2xl font-bold text-gray-900 mt-12">
Por Que os Métodos Tradicionais Não Estão Funcionando?
</h2>
<p>
O problema não está na falta de esforço dos educadores ou no desinteresse das crianças.
A questão é muito mais profunda e envolve:
</p>
<ul className="list-disc pl-6 space-y-2">
<li>Métodos de ensino desatualizados que ignoram as descobertas da neurociência</li>
<li>Abordagens não sistemáticas que criam lacunas no aprendizado</li>
<li>Falta de personalização para atender às necessidades individuais</li>
<li>Ausência de feedback imediato e ajustes em tempo real</li>
<li>Dificuldade em manter o engajamento dos alunos</li>
</ul>
<h2 className="text-2xl font-bold text-gray-900 mt-12">
A Ciência da Leitura: O Que Realmente Funciona
</h2>
<p>
Décadas de pesquisas científicas revelaram um caminho claro para uma alfabetização efetiva.
Este caminho é baseado em cinco pilares fundamentais:
</p>
<div className="bg-purple-50 p-6 rounded-xl mt-6">
<h3 className="text-xl font-bold text-purple-800 mb-4">1. Consciência Fonológica</h3>
<p className="text-purple-900">
A habilidade de identificar e manipular os sons da fala é o primeiro e mais crucial passo
para a alfabetização. Inclui:
</p>
<ul className="list-disc pl-6 space-y-2 mt-2 text-purple-800">
<li>Reconhecimento de rimas</li>
<li>Segmentação de palavras em sílabas</li>
<li>Identificação de fonemas iniciais e finais</li>
<li>Manipulação de sons para formar novas palavras</li>
</ul>
</div>
<div className="bg-blue-50 p-6 rounded-xl mt-6">
<h3 className="text-xl font-bold text-blue-800 mb-4">2. Instrução Fônica Sistemática</h3>
<p className="text-blue-900">
O ensino explícito da relação entre letras e sons é fundamental para desenvolver a
capacidade de decodificação. Envolve:
</p>
<ul className="list-disc pl-6 space-y-2 mt-2 text-blue-800">
<li>Apresentação sistemática das relações letra-som</li>
<li>Prática regular de decodificação</li>
<li>Progressão estruturada do simples ao complexo</li>
<li>Revisão constante e prática cumulativa</li>
</ul>
</div>
<div className="bg-green-50 p-6 rounded-xl mt-6">
<h3 className="text-xl font-bold text-green-800 mb-4">3. Fluência na Leitura</h3>
<p className="text-green-900">
A capacidade de ler com precisão, velocidade e expressão adequadas é essencial para
a compreensão. Requer:
</p>
<ul className="list-disc pl-6 space-y-2 mt-2 text-green-800">
<li>Prática regular com textos apropriados ao nível</li>
<li>Leitura repetida de textos familiares</li>
<li>Modelagem de leitura fluente</li>
<li>Feedback imediato e correção</li>
</ul>
</div>
<div className="bg-yellow-50 p-6 rounded-xl mt-6">
<h3 className="text-xl font-bold text-yellow-800 mb-4">4. Vocabulário</h3>
<p className="text-yellow-900">
Um vocabulário rico é fundamental para a compreensão leitora e o desenvolvimento
cognitivo. Inclui:
</p>
<ul className="list-disc pl-6 space-y-2 mt-2 text-yellow-800">
<li>Exposição a palavras novas em contextos significativos</li>
<li>Estratégias para inferir significados</li>
<li>Conexões entre palavras e conceitos</li>
<li>Revisão espaçada de vocabulário aprendido</li>
</ul>
</div>
<div className="bg-red-50 p-6 rounded-xl mt-6">
<h3 className="text-xl font-bold text-red-800 mb-4">5. Compreensão Leitora</h3>
<p className="text-red-900">
O objetivo final da leitura é extrair e construir significado do texto.
Isso requer:
</p>
<ul className="list-disc pl-6 space-y-2 mt-2 text-red-800">
<li>Estratégias explícitas de compreensão</li>
<li>Monitoramento da própria compreensão</li>
<li>Ativação de conhecimentos prévios</li>
<li>Prática com diferentes gêneros textuais</li>
</ul>
</div>
<h2 className="text-2xl font-bold text-gray-900 mt-12">
Como a Histórias Mágicas Revoluciona a Alfabetização
</h2>
<p>
Nossa plataforma foi desenvolvida para integrar todos estes pilares em um sistema
digital inteligente e envolvente. Veja como funcionamos:
</p>
<div className="grid grid-cols-1 gap-6 mt-6">
<div className="border border-purple-200 rounded-xl p-6">
<div className="flex items-start">
<Brain className="h-8 w-8 text-purple-600 mr-4" />
<div>
<h3 className="text-lg font-bold text-gray-900">Avaliação Diagnóstica Inteligente</h3>
<p className="mt-2">
Antes de começar, nossa IA analisa:
</p>
<ul className="list-disc pl-6 space-y-2 mt-2">
<li>Nível atual de leitura</li>
<li>Habilidades fonológicas</li>
<li>Vocabulário existente</li>
<li>Padrões de aprendizagem</li>
<li>Áreas que precisam de atenção especial</li>
</ul>
</div>
</div>
</div>
<div className="border border-purple-200 rounded-xl p-6">
<div className="flex items-start">
<Target className="h-8 w-8 text-purple-600 mr-4" />
<div>
<h3 className="text-lg font-bold text-gray-900">Plano Personalizado de Aprendizagem</h3>
<p className="mt-2">
Com base na avaliação, criamos:
</p>
<ul className="list-disc pl-6 space-y-2 mt-2">
<li>Roteiro individualizado de atividades</li>
<li>Sequência otimizada de conteúdos</li>
<li>Metas específicas e alcançáveis</li>
<li>Ajustes automáticos baseados no progresso</li>
</ul>
</div>
</div>
</div>
<div className="border border-purple-200 rounded-xl p-6">
<div className="flex items-start">
<BookOpen className="h-8 w-8 text-purple-600 mr-4" />
<div>
<h3 className="text-lg font-bold text-gray-900">Atividades Interativas e Envolventes</h3>
<p className="mt-2">
Nossas atividades incluem:
</p>
<ul className="list-disc pl-6 space-y-2 mt-2">
<li>Jogos fonológicos interativos</li>
<li>Histórias adaptativas ao nível do aluno</li>
<li>Exercícios de decodificação gamificados</li>
<li>Desafios de compreensão contextualizada</li>
<li>Atividades de expansão de vocabulário</li>
</ul>
</div>
</div>
</div>
<div className="border border-purple-200 rounded-xl p-6">
<div className="flex items-start">
<LineChart className="h-8 w-8 text-purple-600 mr-4" />
<div>
<h3 className="text-lg font-bold text-gray-900">Monitoramento em Tempo Real</h3>
<p className="mt-2">
Oferecemos:
</p>
<ul className="list-disc pl-6 space-y-2 mt-2">
<li>Análise detalhada do progresso</li>
<li>Identificação precoce de dificuldades</li>
<li>Relatórios personalizados para professores</li>
<li>Feedback constante para alunos e pais</li>
</ul>
</div>
</div>
</div>
</div>
<h2 className="text-2xl font-bold text-gray-900 mt-12">
O Processo de Implementação
</h2>
<p>
Implementar a Histórias Mágicas em sua escola é um processo simples e estruturado:
</p>
<div className="space-y-6 mt-6">
<div className="flex items-start">
<div className="flex-shrink-0 h-8 w-8 rounded-full bg-purple-600 text-white flex items-center justify-center font-bold">
1
</div>
<div className="ml-4">
<h3 className="text-lg font-bold text-gray-900">Onboarding Personalizado</h3>
<p className="mt-2">
Nossa equipe realiza:
</p>
<ul className="list-disc pl-6 space-y-2 mt-2">
<li>Análise das necessidades específicas da escola</li>
<li>Configuração inicial da plataforma</li>
<li>Importação dos dados dos alunos</li>
<li>Definição de metas e objetivos</li>
</ul>
</div>
</div>
<div className="flex items-start">
<div className="flex-shrink-0 h-8 w-8 rounded-full bg-purple-600 text-white flex items-center justify-center font-bold">
2
</div>
<div className="ml-4">
<h3 className="text-lg font-bold text-gray-900">Capacitação da Equipe</h3>
<p className="mt-2">
Oferecemos:
</p>
<ul className="list-disc pl-6 space-y-2 mt-2">
<li>Treinamento completo para professores</li>
<li>Workshops sobre ciência da leitura</li>
<li>Suporte técnico contínuo</li>
<li>Materiais de apoio e recursos pedagógicos</li>
</ul>
</div>
</div>
<div className="flex items-start">
<div className="flex-shrink-0 h-8 w-8 rounded-full bg-purple-600 text-white flex items-center justify-center font-bold">
3
</div>
<div className="ml-4">
<h3 className="text-lg font-bold text-gray-900">Implementação Gradual</h3>
<p className="mt-2">
Realizamos:
</p>
<ul className="list-disc pl-6 space-y-2 mt-2">
<li>Avaliação diagnóstica inicial dos alunos</li>
<li>Criação de turmas e grupos de trabalho</li>
<li>Definição de rotinas de utilização</li>
<li>Acompanhamento das primeiras semanas</li>
</ul>
</div>
</div>
<div className="flex items-start">
<div className="flex-shrink-0 h-8 w-8 rounded-full bg-purple-600 text-white flex items-center justify-center font-bold">
4
</div>
<div className="ml-4">
<h3 className="text-lg font-bold text-gray-900">Monitoramento e Ajustes</h3>
<p className="mt-2">
Garantimos:
</p>
<ul className="list-disc pl-6 space-y-2 mt-2">
<li>Análise regular dos resultados</li>
<li>Reuniões de acompanhamento</li>
<li>Ajustes baseados no feedback</li>
<li>Otimização contínua do processo</li>
</ul>
</div>
</div>
</div>
<h2 className="text-2xl font-bold text-gray-900 mt-12">
Resultados Comprovados
</h2>
<p>
Escolas que implementaram a Histórias Mágicas relatam:
</p>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-6 mt-6">
<div className="bg-white shadow-lg rounded-xl p-6">
<div className="flex items-center justify-center h-12 w-12 rounded-md bg-purple-600 text-white mb-4">
<Star className="h-6 w-6" />
</div>
<h3 className="text-lg font-bold text-gray-900">Melhoria na Leitura</h3>
<p className="mt-2 text-4xl font-bold text-purple-600">85%</p>
<p className="mt-2 text-gray-600">
dos alunos apresentam melhoria significativa nas habilidades de leitura em 6 meses
</p>
</div>
<div className="bg-white shadow-lg rounded-xl p-6">
<div className="flex items-center justify-center h-12 w-12 rounded-md bg-purple-600 text-white mb-4">
<Users className="h-6 w-6" />
</div>
<h3 className="text-lg font-bold text-gray-900">Engajamento</h3>
<p className="mt-2 text-4xl font-bold text-purple-600">300%</p>
<p className="mt-2 text-gray-600">
de aumento no engajamento dos alunos com atividades de leitura
</p>
</div>
<div className="bg-white shadow-lg rounded-xl p-6">
<div className="flex items-center justify-center h-12 w-12 rounded-md bg-purple-600 text-white mb-4">
<Clock className="h-6 w-6" />
</div>
<h3 className="text-lg font-bold text-gray-900">Tempo de Aprendizado</h3>
<p className="mt-2 text-4xl font-bold text-purple-600">40%</p>
<p className="mt-2 text-gray-600">
de redução no tempo necessário para atingir proficiência em leitura
</p>
</div>
<div className="bg-white shadow-lg rounded-xl p-6">
<div className="flex items-center justify-center h-12 w-12 rounded-md bg-purple-600 text-white mb-4">
<CheckCircle className="h-6 w-6" />
</div>
<h3 className="text-lg font-bold text-gray-900">Satisfação</h3>
<p className="mt-2 text-4xl font-bold text-purple-600">95%</p>
<p className="mt-2 text-gray-600">
de satisfação entre professores, pais e alunos
</p>
</div>
</div>
<div className="bg-purple-50 p-6 rounded-xl mt-12">
<h3 className="text-xl font-bold text-purple-800 mb-4">Depoimentos</h3>
<div className="space-y-6">
<div className="border-l-4 border-purple-600 pl-4">
<p className="text-purple-800 italic">
"A transformação que vimos em nossa escola foi incrível. Alunos que mal conseguiam
juntar letras agora estão lendo com fluência e, mais importante, com prazer. A
Histórias Mágicas não é apenas uma plataforma, é uma revolução na alfabetização."
</p>
<p className="text-purple-600 mt-2 font-semibold">
- Maria Silva, Diretora Pedagógica
</p>
</div>
<div className="border-l-4 border-purple-600 pl-4">
<p className="text-purple-800 italic">
"Como professora 15 anos, nunca vi um método tão eficaz e envolvente. A
plataforma me ajuda a personalizar o ensino para cada aluno, e os resultados
são visíveis desde as primeiras semanas."
</p>
<p className="text-purple-600 mt-2 font-semibold">
- Ana Paula Santos, Professora
</p>
</div>
<div className="border-l-4 border-purple-600 pl-4">
<p className="text-purple-800 italic">
"Meu filho sempre teve dificuldade com leitura e isso afetava sua autoestima.
Desde que começamos a usar a Histórias Mágicas, ele não melhorou na leitura,
mas recuperou a confiança e o prazer de aprender."
</p>
<p className="text-purple-600 mt-2 font-semibold">
- Carlos Oliveira, Pai de aluno
</p>
</div>
</div>
</div>
<h2 className="text-2xl font-bold text-gray-900 mt-12">
Investimento no Futuro
</h2>
<p>
Quando você investe na Histórias Mágicas, está investindo em:
</p>
<ul className="list-disc pl-6 space-y-2 mt-2">
<li>Método cientificamente comprovado de alfabetização</li>
<li>Plataforma tecnológica de ponta</li>
<li>Suporte pedagógico especializado</li>
<li>Formação continuada para professores</li>
<li>Acompanhamento personalizado dos alunos</li>
</ul>
<div className="mt-12 text-center">
<button
onClick={() => navigate('/register')}
className="inline-flex items-center px-8 py-4 bg-purple-600 text-white rounded-xl
font-semibold hover:bg-purple-700 transition-colors"
>
Transforme Sua Escola Agora
<ArrowRight className="ml-2 h-5 w-5" />
</button>
</div>
<div className="bg-gray-50 p-6 rounded-xl mt-12">
<h3 className="text-xl font-bold text-gray-900 mb-4">Nossa Garantia</h3>
<p>
Oferecemos uma garantia de satisfação de 30 dias. Se você não ver resultados
concretos em um mês de uso da plataforma, devolvemos seu investimento
integralmente. Não riscos - apenas a oportunidade de fazer uma diferença
real na educação de seus alunos.
</p>
</div>
<div className="bg-purple-50 p-6 rounded-xl mt-12">
<h3 className="text-xl font-bold text-purple-800 mb-4">Próximos Passos</h3>
<p className="text-purple-900">
1. Clique no botão acima para iniciar seu cadastro<br />
2. Nossa equipe entrará em contato em até 24 horas<br />
3. Realizaremos uma demonstração personalizada<br />
4. Desenvolveremos um plano de implementação específico para sua escola<br />
5. Em poucos dias, sua escola estará transformando a vida de seus alunos
</p>
</div>
<p className="text-sm text-gray-500 mt-8">
P.S.: A revolução na alfabetização está acontecendo agora. Não deixe sua escola
para trás. Junte-se às milhares de instituições que descobriram o poder da
educação baseada em evidências com a Histórias Mágicas.
</p>
</div>
</div>
<Footer />
</div>
);
}

View File

@ -31,11 +31,22 @@ import { EducationalForParents } from './pages/landing/EducationalForParents';
import { TestWordHighlighter } from './pages/TestWordHighlighter'; import { TestWordHighlighter } from './pages/TestWordHighlighter';
import { ExercisePage } from './pages/student-dashboard/ExercisePage'; import { ExercisePage } from './pages/student-dashboard/ExercisePage';
import { EvidenceBased } from './pages/landing/EvidenceBased'; import { EvidenceBased } from './pages/landing/EvidenceBased';
import { TextSalesLetter } from './pages/landing/TextSalesLetter';
import { PageTracker } from './components/analytics/PageTracker';
function RootLayout({ children }: { children: React.ReactNode }) {
return (
<>
<PageTracker />
{children}
</>
);
}
export const router = createBrowserRouter([ export const router = createBrowserRouter([
{ {
path: '/', path: '/',
element: <HomePage />, element: <RootLayout><HomePage /></RootLayout>,
}, },
{ {
path: '/teste', path: '/teste',
@ -49,6 +60,10 @@ export const router = createBrowserRouter([
path: '/evidencias', path: '/evidencias',
element: <EvidenceBased />, element: <EvidenceBased />,
}, },
{
path: '/evidencias/tsl',
element: <TextSalesLetter />,
},
{ {
path: '/login', path: '/login',
children: [ children: [

View File

@ -5,7 +5,11 @@ name = "Histórias Mágicas"
[auth] [auth]
enabled = true enabled = true
site_url = "https://historiasmagicas.netlify.app" site_url = "https://historiasmagicas.netlify.app"
additional_redirect_urls = ["https://historiasmagicas.netlify.app", "https://*.historiasmagicas.netlify.app"] additional_redirect_urls = [
"https://historiasmagicas.netlify.app/*",
"http://localhost:5173/*",
"http://localhost:3000/*"
]
jwt_expiry = 3600 jwt_expiry = 3600
enable_refresh_token_rotation = true enable_refresh_token_rotation = true
refresh_token_reuse_interval = 10 refresh_token_reuse_interval = 10
@ -18,7 +22,7 @@ verify_enabled = true
enable_signup = true enable_signup = true
double_confirm_changes = true double_confirm_changes = true
enable_confirmations = true enable_confirmations = true
secure_password_change = false secure_password_change = true
max_frequency = "1m0s" max_frequency = "1m0s"
otp_length = 6 otp_length = 6
otp_expiry = 86400 otp_expiry = 86400
@ -38,9 +42,25 @@ enabled = true
file_size_limit = "50MB" file_size_limit = "50MB"
[storage.cors] [storage.cors]
allowed_origins = ["*"] allowed_origins = [
"https://historiasmagicas.netlify.app",
"http://localhost:5173",
"http://localhost:3000"
]
allowed_methods = ["GET", "POST", "PUT", "DELETE", "OPTIONS"] allowed_methods = ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
allowed_headers = ["*"] allowed_headers = [
"Authorization",
"Content-Type",
"Accept",
"Origin",
"User-Agent",
"DNT",
"Cache-Control",
"X-Mx-ReqToken",
"Keep-Alive",
"X-Requested-With",
"If-Modified-Since"
]
exposed_headers = ["Content-Range", "Range"] exposed_headers = ["Content-Range", "Range"]
max_age = 3600 max_age = 3600
@ -53,9 +73,25 @@ max_rows = 1000
[api.cors] [api.cors]
enabled = true enabled = true
allowed_origins = ["*"] allowed_origins = [
"https://historiasmagicas.netlify.app",
"http://localhost:5173",
"http://localhost:3000"
]
allowed_methods = ["GET", "POST", "PUT", "DELETE", "OPTIONS"] allowed_methods = ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
allowed_headers = ["*"] allowed_headers = [
"Authorization",
"Content-Type",
"Accept",
"Origin",
"User-Agent",
"DNT",
"Cache-Control",
"X-Mx-ReqToken",
"Keep-Alive",
"X-Requested-With",
"If-Modified-Since"
]
exposed_headers = ["Content-Range", "Range"] exposed_headers = ["Content-Range", "Range"]
max_age = 3600 max_age = 3600