mirror of
https://github.com/lucasrcsantana/story-generator.git
synced 2025-12-18 06:17:56 +00:00
Compare commits
16 Commits
1ea1b3e841
...
33b9b38ff4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
33b9b38ff4 | ||
|
|
1bcb0a9c37 | ||
|
|
d2567ac478 | ||
|
|
953b7a78d0 | ||
|
|
21f7aa7c40 | ||
|
|
6e9d847c77 | ||
|
|
1542572be4 | ||
|
|
75d9d4635b | ||
|
|
a7612879bf | ||
|
|
00cd9edb1c | ||
|
|
a45ebd2719 | ||
|
|
6398e2ac81 | ||
|
|
0ccea7c7b9 | ||
|
|
9fa7b9732d | ||
|
|
6478d20d62 | ||
|
|
0e2215b6ad |
73
CHANGELOG.md
73
CHANGELOG.md
@ -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/),
|
||||
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
|
||||
|
||||
### Técnico
|
||||
|
||||
30
netlify.toml
30
netlify.toml
@ -21,7 +21,35 @@
|
||||
X-XSS-Protection = "1; mode=block"
|
||||
X-Content-Type-Options = "nosniff"
|
||||
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]
|
||||
command = "npm run dev"
|
||||
|
||||
108
package-lock.json
generated
108
package-lock.json
generated
@ -14,6 +14,7 @@
|
||||
"@radix-ui/react-dialog": "^1.1.4",
|
||||
"@radix-ui/react-tabs": "^1.1.2",
|
||||
"@radix-ui/react-toast": "^1.2.4",
|
||||
"@sentry/react": "^8.48.0",
|
||||
"@supabase/supabase-js": "^2.39.7",
|
||||
"@tanstack/react-query": "^5.62.8",
|
||||
"@testing-library/react": "^16.1.0",
|
||||
@ -2556,6 +2557,98 @@
|
||||
"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": {
|
||||
"version": "0.27.8",
|
||||
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
|
||||
@ -5565,6 +5658,21 @@
|
||||
"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": {
|
||||
"version": "9.0.5",
|
||||
"resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-9.0.5.tgz",
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
"@radix-ui/react-dialog": "^1.1.4",
|
||||
"@radix-ui/react-tabs": "^1.1.2",
|
||||
"@radix-ui/react-toast": "^1.2.4",
|
||||
"@sentry/react": "^8.48.0",
|
||||
"@supabase/supabase-js": "^2.39.7",
|
||||
"@tanstack/react-query": "^5.62.8",
|
||||
"@testing-library/react": "^16.1.0",
|
||||
|
||||
39
src/components/analytics/GoogleTagManager.tsx
Normal file
39
src/components/analytics/GoogleTagManager.tsx
Normal 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;
|
||||
}
|
||||
20
src/components/analytics/PageTracker.tsx
Normal file
20
src/components/analytics/PageTracker.tsx
Normal 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;
|
||||
}
|
||||
83
src/components/analytics/RudderstackAnalytics.tsx
Normal file
83
src/components/analytics/RudderstackAnalytics.tsx
Normal 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;
|
||||
}
|
||||
@ -57,6 +57,12 @@ export function AudioUploader({
|
||||
as="span"
|
||||
disabled={isProcessing}
|
||||
className="cursor-pointer"
|
||||
trackingId="audio-upload-button"
|
||||
trackingProperties={{
|
||||
category: 'audio',
|
||||
action: 'upload_click',
|
||||
label: 'audio_uploader'
|
||||
}}
|
||||
>
|
||||
{isProcessing ? 'Processando...' : 'Enviar Áudio'}
|
||||
</Button>
|
||||
|
||||
@ -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 { useAuth } from '../../hooks/useAuth';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
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 {
|
||||
userType: 'school' | 'teacher' | 'student';
|
||||
@ -30,6 +34,20 @@ export function LoginForm({ userType, onLogin, onRegisterClick }: LoginFormProps
|
||||
const [loading, setLoading] = useState(false);
|
||||
const { signIn } = useAuth();
|
||||
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) => {
|
||||
e.preventDefault();
|
||||
@ -46,10 +64,21 @@ export function LoginForm({ userType, onLogin, onRegisterClick }: LoginFormProps
|
||||
|
||||
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) {
|
||||
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;
|
||||
@ -58,9 +87,24 @@ export function LoginForm({ userType, onLogin, onRegisterClick }: LoginFormProps
|
||||
console.log('Role atual:', userRole);
|
||||
|
||||
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) {
|
||||
case 'school':
|
||||
navigate('/dashboard');
|
||||
@ -75,18 +119,36 @@ export function LoginForm({ userType, onLogin, onRegisterClick }: LoginFormProps
|
||||
throw new Error('Tipo de usuário inválido');
|
||||
}
|
||||
|
||||
trackEvent('auth', 'login_success', 'form');
|
||||
} catch (err) {
|
||||
console.error('Erro no login:', err);
|
||||
if (err instanceof Error) {
|
||||
setError(err.message);
|
||||
} else {
|
||||
setError('Email ou senha incorretos');
|
||||
}
|
||||
const errorMessage = err instanceof Error ? err.message : 'Email ou senha incorretos';
|
||||
setError(errorMessage);
|
||||
|
||||
formTracking.trackFormSubmitted(false, {
|
||||
error_type: err instanceof Error ? 'validation_error' : 'unknown_error',
|
||||
error_message: errorMessage
|
||||
});
|
||||
trackEvent('auth', 'login_error', errorMessage);
|
||||
} finally {
|
||||
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 (
|
||||
<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">
|
||||
@ -119,7 +181,9 @@ export function LoginForm({ userType, onLogin, onRegisterClick }: LoginFormProps
|
||||
type="email"
|
||||
required
|
||||
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"
|
||||
/>
|
||||
</div>
|
||||
@ -134,7 +198,9 @@ export function LoginForm({ userType, onLogin, onRegisterClick }: LoginFormProps
|
||||
type={showPassword ? 'text' : 'password'}
|
||||
required
|
||||
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"
|
||||
/>
|
||||
<button
|
||||
@ -151,32 +217,49 @@ export function LoginForm({ userType, onLogin, onRegisterClick }: LoginFormProps
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
<Button
|
||||
type="submit"
|
||||
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 ? (
|
||||
'Entrando...'
|
||||
) : (
|
||||
<>
|
||||
<LogIn className="h-5 w-5" />
|
||||
<LogIn className="h-5 w-5 mr-2" />
|
||||
Entrar
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
</Button>
|
||||
</form>
|
||||
|
||||
{onRegisterClick && (
|
||||
<div className="mt-6 text-center">
|
||||
<p className="text-sm text-gray-600">
|
||||
Ainda não tem uma conta?{' '}
|
||||
<button
|
||||
<Button
|
||||
trackingId="register-link"
|
||||
variant="link"
|
||||
size="sm"
|
||||
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
|
||||
</button>
|
||||
</Button>
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@ -4,53 +4,17 @@ import {
|
||||
BookOpen, ArrowRight, School, Users, Shield,
|
||||
Sparkles, BookCheck, Play, CheckCircle, Star,
|
||||
GraduationCap, BarChart, Brain, X, Check,
|
||||
Pencil,
|
||||
Wand,
|
||||
Mic,
|
||||
Share2
|
||||
Pencil, Wand, Mic, Share2
|
||||
} from 'lucide-react';
|
||||
import { Footer } from '@/components/ui/footer';
|
||||
import { PlanForSchools } from '@/components/ui/plan-for-schools';
|
||||
|
||||
// Components
|
||||
const FeatureCard = ({ icon, title, description }: {
|
||||
icon: React.ReactNode;
|
||||
title: string;
|
||||
description: string;
|
||||
}) => (
|
||||
<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>
|
||||
);
|
||||
import { FAQ } from '@/components/ui/faq';
|
||||
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';
|
||||
|
||||
const navigation = [
|
||||
{ name: 'Início', href: '/' },
|
||||
@ -130,7 +94,7 @@ export function HomePage() {
|
||||
</nav>
|
||||
|
||||
{/* 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="grid lg:grid-cols-2 gap-12 items-center">
|
||||
<div>
|
||||
@ -200,7 +164,7 @@ export function HomePage() {
|
||||
</div>
|
||||
|
||||
{/* 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="text-center mb-16">
|
||||
<h2 className="text-3xl font-bold text-gray-900 mb-4">
|
||||
@ -211,136 +175,77 @@ export function HomePage() {
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="relative">
|
||||
{/* Timeline Line */}
|
||||
<div className="hidden md:block absolute left-1/2 transform -translate-x-1/2 h-full w-0.5 bg-purple-200" />
|
||||
<div className="space-y-12">
|
||||
<ProcessStep
|
||||
number={1}
|
||||
title="Escolha o tema da aventura"
|
||||
description="Selecione entre diversos temas educativos alinhados com a BNCC e adequados à idade."
|
||||
/>
|
||||
|
||||
{/* Timeline Items */}
|
||||
{[
|
||||
{
|
||||
icon: <Pencil className="w-6 h-6" />,
|
||||
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>
|
||||
<ProcessStep
|
||||
number={2}
|
||||
title="Personalize os personagens"
|
||||
description="Crie personagens que seu filho vai adorar, com características únicas e cativantes."
|
||||
/>
|
||||
|
||||
{/* Timeline Marker */}
|
||||
<div className="hidden md:flex items-center justify-center">
|
||||
<div className="w-12 h-12 rounded-full bg-purple-600 text-white flex items-center justify-center font-bold">
|
||||
{index + 1}
|
||||
</div>
|
||||
</div>
|
||||
<ProcessStep
|
||||
number={3}
|
||||
title="A IA cria a história mágica"
|
||||
description="Nossa IA educacional gera uma história personalizada em segundos."
|
||||
/>
|
||||
|
||||
{/* Image Side */}
|
||||
<div className="flex-1 hidden md:block">
|
||||
<img
|
||||
src={item.image}
|
||||
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>
|
||||
<ProcessStep
|
||||
number={4}
|
||||
title="A aventura educativa começa"
|
||||
description="Seu filho mergulha em uma jornada mágica de aprendizado e diversão."
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Features Grid */}
|
||||
<div className="py-20 bg-white">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="text-center mb-16">
|
||||
{/* Results Summary */}
|
||||
<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-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">
|
||||
Tecnologia e Educação em Harmonia
|
||||
</h2>
|
||||
@ -350,148 +255,152 @@ export function HomePage() {
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
<FeatureCard
|
||||
icon={<Brain />}
|
||||
<FeatureCard
|
||||
icon={Brain}
|
||||
title="IA Adaptativa"
|
||||
description="Conteúdo que se adapta ao ritmo e estilo de aprendizagem de cada aluno"
|
||||
/>
|
||||
<FeatureCard
|
||||
icon={<BookOpen />}
|
||||
<FeatureCard
|
||||
icon={BookOpen}
|
||||
title="Histórias Interativas"
|
||||
description="Narrativas envolventes que tornam o aprendizado mais divertido e eficaz"
|
||||
/>
|
||||
<FeatureCard
|
||||
icon={<BarChart />}
|
||||
<FeatureCard
|
||||
icon={BarChart}
|
||||
title="Analytics Avançado"
|
||||
description="Insights detalhados sobre o progresso e engajamento dos alunos"
|
||||
/>
|
||||
<FeatureCard
|
||||
icon={<Users />}
|
||||
<FeatureCard
|
||||
icon={Users}
|
||||
title="Colaboração"
|
||||
description="Ferramentas para professores trabalharem juntos e compartilharem recursos"
|
||||
/>
|
||||
<FeatureCard
|
||||
icon={<Shield />}
|
||||
<FeatureCard
|
||||
icon={Shield}
|
||||
title="Ambiente Seguro"
|
||||
description="Proteção de dados e conteúdo adequado para todas as idades"
|
||||
/>
|
||||
<FeatureCard
|
||||
icon={<GraduationCap />}
|
||||
<FeatureCard
|
||||
icon={GraduationCap}
|
||||
title="Suporte Pedagógico"
|
||||
description="Recursos e orientações para maximizar o potencial de aprendizagem"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Before & After Section */}
|
||||
<div className="py-20 bg-white">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="text-center mb-16">
|
||||
<h2 className="text-3xl font-bold text-gray-900 mb-4">
|
||||
Transforme a Experiência de Aprendizagem
|
||||
</h2>
|
||||
<p className="text-gray-600 max-w-2xl mx-auto">
|
||||
Veja como o Histórias Mágicas revoluciona o ensino
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid md:grid-cols-2 gap-16">
|
||||
{/* Before */}
|
||||
<div className="rounded-2xl bg-red-50 p-8">
|
||||
<div className="flex items-center gap-3 mb-6">
|
||||
<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>
|
||||
</div>
|
||||
<ul className="space-y-4">
|
||||
{[
|
||||
'Conteúdo padronizado que não atende necessidades individuais',
|
||||
'Alunos desmotivados com material didático tradicional',
|
||||
'Professores sobrecarregados com correções manuais',
|
||||
'Dificuldade em acompanhar o progresso individual',
|
||||
'Baixo engajamento nas atividades de leitura e escrita',
|
||||
'Falta de dados para tomada de decisão pedagógica'
|
||||
].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" />
|
||||
</div>
|
||||
<span className="text-gray-600">{item}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* After */}
|
||||
<div className="rounded-2xl bg-green-50 p-8">
|
||||
<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>
|
||||
{/* Before & After Section */}
|
||||
<div className="mt-24">
|
||||
<ComparisonSection
|
||||
title="Compare a Transformação"
|
||||
items={[
|
||||
{
|
||||
title: "Personalização",
|
||||
without: [
|
||||
"Conteúdo padronizado que não atende necessidades individuais",
|
||||
"Material didático tradicional e pouco envolvente",
|
||||
"Mesma abordagem para todos os alunos"
|
||||
],
|
||||
with: [
|
||||
"Histórias adaptativas que evoluem com cada aluno",
|
||||
"Conteúdo personalizado e envolvente",
|
||||
"Experiência única para cada estudante"
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Engajamento",
|
||||
without: [
|
||||
"Alunos desmotivados com atividades repetitivas",
|
||||
"Baixo interesse nas atividades de leitura",
|
||||
"Dificuldade em manter a atenção dos alunos"
|
||||
],
|
||||
with: [
|
||||
"Estudantes engajados e participativos",
|
||||
"Aumento de 300% no engajamento com leitura",
|
||||
"Alunos ansiosos pela próxima atividade"
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Acompanhamento",
|
||||
without: [
|
||||
"Professores sobrecarregados com correções manuais",
|
||||
"Dificuldade em acompanhar o progresso individual",
|
||||
"Falta de dados para decisões pedagógicas"
|
||||
],
|
||||
with: [
|
||||
"Correção automática com feedback instantâneo",
|
||||
"Dashboard em tempo real do progresso individual",
|
||||
"Insights precisos para intervenções pedagógicas"
|
||||
]
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Pricing */}
|
||||
<div className="py-20 bg-gray-50">
|
||||
<PlanForSchools />
|
||||
</div>
|
||||
{/* Testimonials */}
|
||||
<div className="mt-24 grid md:grid-cols-2 gap-8">
|
||||
<TestimonialCard
|
||||
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 */}
|
||||
<div className="py-20">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="bg-gradient-to-r from-purple-600 to-indigo-600 rounded-2xl p-8 md:p-16 text-center text-white">
|
||||
<h2 className="text-3xl md:text-4xl font-bold mb-4">
|
||||
{/* Pricing Section */}
|
||||
<div className="mt-24">
|
||||
<PlanForSchools />
|
||||
</div>
|
||||
|
||||
{/* 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?
|
||||
</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 já estão revolucionando a educação
|
||||
</p>
|
||||
<button
|
||||
onClick={handleSchoolRegister}
|
||||
className="bg-white text-purple-600 px-8 py-4 rounded-xl hover:bg-purple-50 transition text-lg font-semibold"
|
||||
<button
|
||||
onClick={() => navigate('/register')}
|
||||
className="bg-white text-purple-600 px-8 py-3 rounded-lg font-semibold hover:bg-purple-50 transition"
|
||||
>
|
||||
Começar Gratuitamente
|
||||
</button>
|
||||
@ -503,4 +412,6 @@ export function HomePage() {
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default HomePage;
|
||||
@ -1,27 +1,76 @@
|
||||
import React from 'react';
|
||||
import { useButtonTracking } from '../../hooks/useButtonTracking';
|
||||
import { cn } from '../../lib/utils';
|
||||
|
||||
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
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',
|
||||
className = '',
|
||||
children,
|
||||
...props
|
||||
}: ButtonProps): JSX.Element {
|
||||
className = '',
|
||||
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 (
|
||||
<Component
|
||||
className={`
|
||||
inline-flex items-center justify-center px-4 py-2
|
||||
text-sm font-medium text-white
|
||||
bg-purple-600 hover:bg-purple-700
|
||||
rounded-md shadow-sm
|
||||
transition-colors duration-200
|
||||
disabled:opacity-50 disabled:cursor-not-allowed
|
||||
${className}
|
||||
`}
|
||||
type={Component === 'button' ? type : undefined}
|
||||
className={baseStyles}
|
||||
onClick={handleClick}
|
||||
disabled={disabled}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
|
||||
81
src/components/ui/comparison-section.tsx
Normal file
81
src/components/ui/comparison-section.tsx
Normal 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
49
src/components/ui/faq.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
41
src/components/ui/feature-card.tsx
Normal file
41
src/components/ui/feature-card.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
67
src/components/ui/info-card.tsx
Normal file
67
src/components/ui/info-card.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
34
src/components/ui/process-step.tsx
Normal file
34
src/components/ui/process-step.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
33
src/components/ui/stat-card.tsx
Normal file
33
src/components/ui/stat-card.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
67
src/components/ui/testimonial-card.tsx
Normal file
67
src/components/ui/testimonial-card.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
50
src/hooks/useButtonTracking.ts
Normal file
50
src/hooks/useButtonTracking.ts
Normal 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
60
src/hooks/useDataLayer.ts
Normal 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,
|
||||
};
|
||||
}
|
||||
114
src/hooks/useErrorTracking.ts
Normal file
114
src/hooks/useErrorTracking.ts
Normal 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,
|
||||
};
|
||||
}
|
||||
83
src/hooks/useFormTracking.ts
Normal file
83
src/hooks/useFormTracking.ts
Normal 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,
|
||||
};
|
||||
}
|
||||
55
src/hooks/useRudderstack.ts
Normal file
55
src/hooks/useRudderstack.ts
Normal 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,
|
||||
};
|
||||
}
|
||||
61
src/main.tsx
61
src/main.tsx
@ -1,11 +1,44 @@
|
||||
import { StrictMode } from 'react';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
import { RouterProvider } from 'react-router-dom';
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import * as Sentry from "@sentry/react";
|
||||
import { router } from './routes';
|
||||
import { Toaster } from './components/ui/toaster';
|
||||
import { GoogleTagManager } from './components/analytics/GoogleTagManager';
|
||||
import { RudderstackAnalytics } from './components/analytics/RudderstackAnalytics';
|
||||
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({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
@ -16,15 +49,19 @@ const queryClient = new QueryClient({
|
||||
},
|
||||
});
|
||||
|
||||
function Root() {
|
||||
return (
|
||||
<StrictMode>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<RouterProvider router={router} />
|
||||
<Toaster />
|
||||
</QueryClientProvider>
|
||||
</StrictMode>
|
||||
);
|
||||
}
|
||||
const rootElement = document.getElementById('root');
|
||||
if (!rootElement) throw new Error('Failed to find the root element');
|
||||
|
||||
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>
|
||||
);
|
||||
@ -1,410 +1,265 @@
|
||||
import React from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import {
|
||||
ArrowRight, Wand2, Shield, Star, BookOpen,
|
||||
Brain, Target, Users, Award, CheckCircle,
|
||||
Clock, Heart, Sparkles, ScrollText, Lock, X,
|
||||
Facebook, Instagram, Twitter, Youtube
|
||||
import {
|
||||
ArrowRight,
|
||||
Brain,
|
||||
BookOpen,
|
||||
Target,
|
||||
Wand2,
|
||||
Star,
|
||||
Shield,
|
||||
Sparkles,
|
||||
ScrollText,
|
||||
Lock,
|
||||
Heart,
|
||||
Facebook,
|
||||
Instagram,
|
||||
Twitter,
|
||||
Youtube,
|
||||
CheckCircle,
|
||||
LineChart,
|
||||
Clock
|
||||
} 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 { FAQ } from '@/components/ui/faq';
|
||||
import { Footer } from '@/components/ui/footer';
|
||||
|
||||
export function EducationalForParents(): JSX.Element {
|
||||
const navigate = useNavigate();
|
||||
|
||||
export function EducationalForParents() {
|
||||
return (
|
||||
<div className="min-h-screen">
|
||||
{/* 1. Hero Section */}
|
||||
<section className="relative overflow-hidden bg-gradient-to-b from-purple-50 via-white to-purple-50">
|
||||
<div className="absolute inset-0 bg-[url('/patterns/magic.svg')] opacity-5" />
|
||||
<div className="px-4 py-24 mx-auto max-w-7xl relative">
|
||||
{/* Reading Time */}
|
||||
<div className="absolute top-8 right-8 flex items-center gap-2 text-sm text-gray-500">
|
||||
<Clock className="h-4 w-4" />
|
||||
<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 className="min-h-screen bg-white">
|
||||
{/* Hero Section */}
|
||||
<div className="relative isolate overflow-hidden bg-gradient-to-b from-purple-100/20">
|
||||
<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="mx-auto max-w-2xl lg:mx-0 flex-shrink-0 lg:pt-8">
|
||||
<div className="absolute right-4 top-4 text-gray-600 flex items-center gap-2">
|
||||
<Clock className="w-4 h-4" />
|
||||
<span className="text-sm">Tempo de leitura: 5 minutos</span>
|
||||
</div>
|
||||
|
||||
<div className="flex-1">
|
||||
<div className="relative">
|
||||
<div className="absolute -inset-4 bg-gradient-to-r from-purple-600 to-blue-500
|
||||
rounded-2xl blur-lg opacity-20" />
|
||||
<img
|
||||
src="/images/magic-book.webp"
|
||||
alt="Crianças mergulhadas em um livro mágico"
|
||||
className="relative rounded-2xl shadow-2xl transform hover:scale-[1.02]
|
||||
transition-transform"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* 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"
|
||||
|
||||
<h1 className="mt-10 text-4xl font-bold tracking-tight text-gray-900 sm:text-6xl">
|
||||
Transforme o<br />
|
||||
Aprendizado em<br />
|
||||
Uma <span className="text-purple-600">Aventura Mágica</span>
|
||||
</h1>
|
||||
|
||||
<p className="mt-6 text-lg leading-8 text-gray-600 max-w-xl">
|
||||
Histórias educativas personalizadas que encantam e ensinam,
|
||||
criadas especialmente para o desenvolvimento único do seu filho.
|
||||
</p>
|
||||
|
||||
<div className="mt-10">
|
||||
<button
|
||||
onClick={() => window.location.href = '/cadastro'}
|
||||
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"
|
||||
>
|
||||
<div className="flex flex-col items-center text-center gap-4">
|
||||
<div className="w-16 h-16 flex items-center justify-center
|
||||
bg-gradient-to-r from-purple-600 to-blue-500 rounded-full">
|
||||
<benefit.icon className="h-8 w-8 text-white" />
|
||||
</div>
|
||||
<h3 className="text-xl font-bold text-gray-900">{benefit.title}</h3>
|
||||
<p className="text-gray-600">{benefit.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
Comece Sua Aventura Mágica Grátis
|
||||
<ArrowRight className="w-5 h-5" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Preview do Portal */}
|
||||
<div className="relative mt-20">
|
||||
<div className="absolute -inset-4 bg-gradient-to-r from-purple-600 to-blue-500
|
||||
rounded-2xl blur-lg opacity-20" />
|
||||
<div className="relative bg-white p-8 rounded-xl shadow-xl">
|
||||
<div className="grid md:grid-cols-2 gap-12 items-center">
|
||||
<div>
|
||||
<h3 className="text-2xl font-bold text-gray-900 mb-6">
|
||||
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 className="mt-10 flex items-center gap-x-8 text-sm text-gray-600">
|
||||
<div className="flex items-center gap-x-2">
|
||||
<BookOpen className="w-5 h-5 text-purple-600" />
|
||||
<span>Mais de 10.000 histórias mágicas criadas</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-x-2">
|
||||
<Target className="w-5 h-5 text-purple-600" />
|
||||
<span>5.000 pequenos leitores encantados</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* 6. Testimoniais */}
|
||||
<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">
|
||||
<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">
|
||||
<div className="max-w-3xl flex-none sm:max-w-5xl lg:max-w-none">
|
||||
<img
|
||||
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
|
||||
</h2>
|
||||
|
||||
<div className="grid md:grid-cols-3 gap-8">
|
||||
{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 className="mt-4 text-lg leading-8 text-gray-600">
|
||||
Veja como o Histórias Mágicas está transformando a vida de famílias por todo o Brasil.
|
||||
</p>
|
||||
</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 já 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 />
|
||||
</div>
|
||||
);
|
||||
@ -413,18 +268,18 @@ export function EducationalForParents(): JSX.Element {
|
||||
const challenges = [
|
||||
{
|
||||
icon: Brain,
|
||||
title: "Manter as crianças interessadas em aprender",
|
||||
description: "É difícil competir com jogos e vídeos para capturar a atenção das crianças."
|
||||
title: 'Dificuldade de Concentração',
|
||||
description: 'Crianças têm dificuldade em manter o foco em métodos tradicionais de leitura.'
|
||||
},
|
||||
{
|
||||
icon: BookOpen,
|
||||
title: "Encontrar conteúdo educativo de qualidade",
|
||||
description: "Muito conteúdo disponível, mas pouco realmente educativo e envolvente."
|
||||
title: 'Falta de Engajamento',
|
||||
description: 'Livros convencionais nem sempre capturam a imaginação das crianças modernas.'
|
||||
},
|
||||
{
|
||||
icon: Target,
|
||||
title: "Acompanhar o desenvolvimento da criança",
|
||||
description: "Falta de ferramentas para monitorar o progresso de forma clara e objetiva."
|
||||
title: 'Progresso Lento',
|
||||
description: 'Pais têm dificuldade em acompanhar e estimular o desenvolvimento da leitura.'
|
||||
}
|
||||
];
|
||||
|
||||
@ -453,147 +308,152 @@ const benefits = [
|
||||
|
||||
const magicSteps = [
|
||||
{
|
||||
title: "Escolha o tema da aventura",
|
||||
description: "Selecione entre diversos temas educativos alinhados com a BNCC e adequados à idade."
|
||||
title: 'Escolha do Tema',
|
||||
description: 'Selecione entre diversos temas educativos que despertam o interesse do seu filho.'
|
||||
},
|
||||
{
|
||||
title: "Personalize os personagens",
|
||||
description: "Crie personagens que seu filho vai adorar, com características únicas e cativantes."
|
||||
title: 'Personalização Mágica',
|
||||
description: 'Crie personagens que se conectam com a realidade e interesses da criança.'
|
||||
},
|
||||
{
|
||||
title: "A IA cria a história mágica",
|
||||
description: "Nossa IA educacional gera uma história personalizada em segundos."
|
||||
title: 'Geração da História',
|
||||
description: 'Nossa IA cria uma narrativa única, adaptada ao nível de leitura do seu filho.'
|
||||
},
|
||||
{
|
||||
title: "A aventura educativa começa",
|
||||
description: "Seu filho mergulha em uma jornada mágica de aprendizado e diversão."
|
||||
title: 'Aventura Educativa',
|
||||
description: 'Acompanhe o progresso enquanto seu filho se diverte aprendendo.'
|
||||
}
|
||||
];
|
||||
|
||||
const comparisonData = [
|
||||
{
|
||||
title: "Tempo & Diversão",
|
||||
title: 'Tempo & Diversão',
|
||||
without: [
|
||||
"Horas procurando conteúdo educativo adequado",
|
||||
"Crianças entediadas com leituras tradicionais",
|
||||
"Histórias que não capturam a imaginação",
|
||||
"Dificuldade em acompanhar o progresso"
|
||||
'Horas procurando conteúdo educativo adequado',
|
||||
'Crianças entediadas com leituras tradicionais',
|
||||
'Histórias que não capturam a imaginação',
|
||||
'Dificuldade em acompanhar o progresso'
|
||||
],
|
||||
with: [
|
||||
"Histórias mágicas personalizadas em minutos",
|
||||
"Crianças fascinadas por aventuras únicas",
|
||||
"Mundos mágicos que educam e encantam",
|
||||
"Portal mágico de acompanhamento do progresso"
|
||||
'Histórias mágicas personalizadas em minutos',
|
||||
'Crianças fascinadas por aventuras únicas',
|
||||
'Mundos mágicos que educam e encantam',
|
||||
'Portal mágico de acompanhamento do progresso'
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Qualidade do Aprendizado",
|
||||
title: 'Qualidade do Aprendizado',
|
||||
without: [
|
||||
"Conteúdo genérico e previsível",
|
||||
"Falta de conexão emocional com a leitura",
|
||||
"Dificuldade em manter o interesse",
|
||||
"Aprendizado fragmentado"
|
||||
'Conteúdo genérico e previsível',
|
||||
'Falta de conexão emocional com a leitura',
|
||||
'Dificuldade em manter o interesse',
|
||||
'Aprendizado fragmentado'
|
||||
],
|
||||
with: [
|
||||
"Histórias que evoluem com cada criança",
|
||||
"Conexão emocional com personagens únicos",
|
||||
"Aventuras que mesclam diversão e educação",
|
||||
"Jornada de aprendizado mágica e integrada"
|
||||
'Histórias que evoluem com cada criança',
|
||||
'Conexão emocional com personagens únicos',
|
||||
'Aventuras que mesclam diversão e educação',
|
||||
'Jornada de aprendizado mágica e integrada'
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Resultados",
|
||||
title: 'Resultados',
|
||||
without: [
|
||||
"Progresso lento e desmotivador",
|
||||
"Resistência à leitura e aprendizado",
|
||||
"Rotina de estudos cansativa",
|
||||
"Pais preocupados com desenvolvimento"
|
||||
'Progresso lento e desmotivador',
|
||||
'Resistência à leitura e aprendizado',
|
||||
'Rotina de estudos cansativa',
|
||||
'Pais preocupados com desenvolvimento'
|
||||
],
|
||||
with: [
|
||||
"Evolução visível e empolgante",
|
||||
"Amor natural pela leitura e conhecimento",
|
||||
"Aventuras diárias de aprendizado",
|
||||
"Pais confiantes no desenvolvimento mágico"
|
||||
'Evolução visível e empolgante',
|
||||
'Amor natural pela leitura e conhecimento',
|
||||
'Aventuras diárias de aprendizado',
|
||||
'Pais confiantes no desenvolvimento mágico'
|
||||
]
|
||||
}
|
||||
];
|
||||
];
|
||||
|
||||
const detailedBenefits = [
|
||||
{
|
||||
icon: Wand2,
|
||||
title: "Aprendizado Através de Aventuras",
|
||||
description: "Histórias que se adaptam ao nível e interesses do seu filho, tornando o aprendizado natural e divertido."
|
||||
title: 'Histórias Personalizadas',
|
||||
description: 'Narrativas únicas que se adaptam aos interesses e nível de leitura do seu filho.'
|
||||
},
|
||||
{
|
||||
icon: ScrollText,
|
||||
title: "Portal dos Pais",
|
||||
description: "Acompanhe em tempo real o progresso de leitura, compreensão e desenvolvimento do seu filho."
|
||||
icon: Star,
|
||||
title: 'Aprendizado Divertido',
|
||||
description: 'Transformamos o processo de leitura em uma aventura mágica e envolvente.'
|
||||
},
|
||||
{
|
||||
icon: Shield,
|
||||
title: "Proteção Mágica",
|
||||
description: "Conteúdo 100% seguro e adequado, com moderação constante e controles parentais."
|
||||
title: 'Ambiente Seguro',
|
||||
description: 'Conteúdo apropriado para a idade e monitoramento constante do progresso.'
|
||||
},
|
||||
{
|
||||
icon: BookOpen,
|
||||
title: "Alinhamento com BNCC",
|
||||
description: "Histórias criadas seguindo as diretrizes da Base Nacional Comum Curricular."
|
||||
icon: Sparkles,
|
||||
title: 'Recompensas Mágicas',
|
||||
description: 'Sistema de conquistas que motiva e celebra o progresso da criança.'
|
||||
},
|
||||
{
|
||||
icon: Brain,
|
||||
title: "IA Educacional",
|
||||
description: "Nossa inteligência artificial analisa o perfil do seu filho para criar histórias personalizadas e adaptativas."
|
||||
icon: ScrollText,
|
||||
title: 'Relatórios Detalhados',
|
||||
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 = [
|
||||
{
|
||||
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",
|
||||
text: "Minha filha passou de resistente à leitura para não querer parar de ler! As histórias personalizadas fizeram toda a diferença.",
|
||||
name: "Ana Silva",
|
||||
role: "Mãe da Maria, 8 anos",
|
||||
magicMoment: "Primeira história completa lida sozinha"
|
||||
magicMoment: "Sofia leu sua primeira história sozinha após 2 semanas"
|
||||
},
|
||||
{
|
||||
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",
|
||||
text: "Como pai, é incrível ver o progresso do Pedro. O portal dos pais me ajuda a entender exatamente onde ele precisa de apoio.",
|
||||
name: "Carlos Santos",
|
||||
role: "Pai do Pedro, 10 anos",
|
||||
magicMoment: "Superou a dificuldade com palavras complexas"
|
||||
magicMoment: "Lucas aumentou seu vocabulário em 40% em 3 meses"
|
||||
},
|
||||
{
|
||||
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",
|
||||
text: "As histórias são tão envolventes que meu filho pede para ler mais uma toda noite. O aprendizado acontece naturalmente!",
|
||||
name: "Juliana Costa",
|
||||
role: "Mãe do Lucas, 7 anos",
|
||||
magicMoment: "Começou a criar suas próprias histórias"
|
||||
magicMoment: "Laura passou de leitora básica para avançada"
|
||||
}
|
||||
];
|
||||
|
||||
const faqItems = [
|
||||
{
|
||||
question: "Como a magia da IA funciona?",
|
||||
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."
|
||||
question: "Como a plataforma auxilia no trabalho do professor?",
|
||||
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?",
|
||||
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."
|
||||
question: "A plataforma se integra ao currículo escolar?",
|
||||
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?",
|
||||
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."
|
||||
question: "Como acompanhar o progresso da turma?",
|
||||
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?",
|
||||
answer: "Você pode cancelar sua assinatura a qualquer momento, sem multas. Oferecemos garantia de 30 dias - se não estiver satisfeito, devolvemos seu dinheiro."
|
||||
question: "Vocês oferecem treinamento para os professores?",
|
||||
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?",
|
||||
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."
|
||||
question: "Como a plataforma lida com diferentes níveis de leitura na mesma turma?",
|
||||
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?",
|
||||
answer: "Oferecemos suporte via chat, email e telefone, com especialistas em educação prontos para ajudar. Planos premium incluem acesso a pedagogos."
|
||||
question: "Quais recursos estão disponíveis para planejamento de aulas?",
|
||||
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."
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@ -24,6 +24,7 @@ import {
|
||||
} from 'lucide-react';
|
||||
import { Footer } from '@/components/ui/footer';
|
||||
import { PlanForSchools } from '@/components/ui/plan-for-schools';
|
||||
import { FAQ } from '@/components/ui/faq';
|
||||
|
||||
// Meta tags e SEO
|
||||
const meta = {
|
||||
@ -189,7 +190,7 @@ export function EvidenceBased(): JSX.Element {
|
||||
<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">
|
||||
Evidências vs. Pseudociência
|
||||
Pseudociência vs. Evidências
|
||||
</h2>
|
||||
|
||||
<div className="grid md:grid-cols-2 gap-8">
|
||||
@ -316,22 +317,36 @@ export function EvidenceBased(): JSX.Element {
|
||||
<PlanForSchools />
|
||||
|
||||
{/* 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 Frequentes
|
||||
</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>
|
||||
<FAQ
|
||||
title="Dúvidas Frequentes sobre Educação Baseada em Evidências"
|
||||
description="Entenda como nossa plataforma aplica métodos cientificamente comprovados"
|
||||
items={[
|
||||
{
|
||||
question: "O que é educação baseada em evidências?",
|
||||
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."
|
||||
},
|
||||
{
|
||||
question: "Como vocês aplicam a ciência da leitura na prática?",
|
||||
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."
|
||||
},
|
||||
{
|
||||
question: "Quais são as evidências que suportam seus métodos?",
|
||||
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."
|
||||
},
|
||||
{
|
||||
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 */}
|
||||
<section className="px-4 py-24 bg-gradient-to-br from-purple-600 to-blue-500 text-white">
|
||||
|
||||
@ -4,6 +4,7 @@ import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContai
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { Footer } from '@/components/ui/footer';
|
||||
import { PlanForParents } from '@/components/ui/plan-for-parents';
|
||||
import { FAQ } from '@/components/ui/faq';
|
||||
|
||||
export function ParentsLandingPage(): JSX.Element {
|
||||
const navigate = useNavigate();
|
||||
@ -403,10 +404,42 @@ export function ParentsLandingPage(): JSX.Element {
|
||||
{/* 5. Planos */}
|
||||
<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 */}
|
||||
<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="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">
|
||||
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">
|
||||
|
||||
463
src/pages/landing/TextSalesLetter.tsx
Normal file
463
src/pages/landing/TextSalesLetter.tsx
Normal 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 há 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 só 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 há 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 já descobriram o poder da
|
||||
educação baseada em evidências com a Histórias Mágicas.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -31,11 +31,22 @@ import { EducationalForParents } from './pages/landing/EducationalForParents';
|
||||
import { TestWordHighlighter } from './pages/TestWordHighlighter';
|
||||
import { ExercisePage } from './pages/student-dashboard/ExercisePage';
|
||||
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([
|
||||
{
|
||||
path: '/',
|
||||
element: <HomePage />,
|
||||
element: <RootLayout><HomePage /></RootLayout>,
|
||||
},
|
||||
{
|
||||
path: '/teste',
|
||||
@ -49,6 +60,10 @@ export const router = createBrowserRouter([
|
||||
path: '/evidencias',
|
||||
element: <EvidenceBased />,
|
||||
},
|
||||
{
|
||||
path: '/evidencias/tsl',
|
||||
element: <TextSalesLetter />,
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
children: [
|
||||
|
||||
@ -5,7 +5,11 @@ name = "Histórias Mágicas"
|
||||
[auth]
|
||||
enabled = true
|
||||
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
|
||||
enable_refresh_token_rotation = true
|
||||
refresh_token_reuse_interval = 10
|
||||
@ -18,7 +22,7 @@ verify_enabled = true
|
||||
enable_signup = true
|
||||
double_confirm_changes = true
|
||||
enable_confirmations = true
|
||||
secure_password_change = false
|
||||
secure_password_change = true
|
||||
max_frequency = "1m0s"
|
||||
otp_length = 6
|
||||
otp_expiry = 86400
|
||||
@ -38,9 +42,25 @@ enabled = true
|
||||
file_size_limit = "50MB"
|
||||
|
||||
[storage.cors]
|
||||
allowed_origins = ["*"]
|
||||
allowed_origins = [
|
||||
"https://historiasmagicas.netlify.app",
|
||||
"http://localhost:5173",
|
||||
"http://localhost:3000"
|
||||
]
|
||||
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"]
|
||||
max_age = 3600
|
||||
|
||||
@ -53,9 +73,25 @@ max_rows = 1000
|
||||
|
||||
[api.cors]
|
||||
enabled = true
|
||||
allowed_origins = ["*"]
|
||||
allowed_origins = [
|
||||
"https://historiasmagicas.netlify.app",
|
||||
"http://localhost:5173",
|
||||
"http://localhost:3000"
|
||||
]
|
||||
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"]
|
||||
max_age = 3600
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user