mirror of
https://github.com/lucasrcsantana/story-generator.git
synced 2025-12-16 13:27:52 +00:00
feat: adiciona configuração docker e ci/cd
- Implementa Dockerfile com multi-stage build - Configura pipeline no Gitea Actions - Adiciona integração com Redis - Implementa healthchecks - Configura registry no Gitea minor: novas funcionalidades de infraestrutura
This commit is contained in:
parent
563a62a517
commit
521a99a5c2
9
.dockerignore
Normal file
9
.dockerignore
Normal file
@ -0,0 +1,9 @@
|
||||
node_modules
|
||||
.git
|
||||
.env*
|
||||
.dockerignore
|
||||
Dockerfile
|
||||
README.md
|
||||
.next
|
||||
build
|
||||
dist
|
||||
8
.gitea/config/registry.yml
Normal file
8
.gitea/config/registry.yml
Normal file
@ -0,0 +1,8 @@
|
||||
version: "1.0"
|
||||
registries:
|
||||
- name: seu-registry
|
||||
host: seu-registry.com
|
||||
type: container
|
||||
credentials:
|
||||
username: ${REGISTRY_USERNAME}
|
||||
password: ${REGISTRY_PASSWORD}
|
||||
58
.gitea/workflows/docker-build.yml
Normal file
58
.gitea/workflows/docker-build.yml
Normal file
@ -0,0 +1,58 @@
|
||||
name: Docker Build and Push
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
tags: [ 'v*' ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: seu-registry.com/historias-magicas
|
||||
tags: |
|
||||
type=ref,event=branch
|
||||
type=ref,event=pr
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=sha
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Login to Container Registry
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: seu-registry.com
|
||||
username: ${{ secrets.REGISTRY_USERNAME }}
|
||||
password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
context: .
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=registry,ref=seu-registry.com/historias-magicas:buildcache
|
||||
cache-to: type=registry,ref=seu-registry.com/historias-magicas:buildcache,mode=max
|
||||
|
||||
- name: Update Portainer stack
|
||||
if: github.ref == 'refs/heads/main'
|
||||
uses: appleboy/ssh-action@master
|
||||
with:
|
||||
host: ${{ secrets.DEPLOY_HOST }}
|
||||
username: ${{ secrets.DEPLOY_USER }}
|
||||
key: ${{ secrets.DEPLOY_KEY }}
|
||||
script: |
|
||||
cd /opt/portainer
|
||||
docker stack deploy -c portainer-stack.yml historias-magicas
|
||||
18
.github/workflows/deploy.yml
vendored
Normal file
18
.github/workflows/deploy.yml
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
name: Deploy
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Deploy to production
|
||||
env:
|
||||
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
|
||||
run: |
|
||||
echo "$DEPLOY_KEY" > deploy_key
|
||||
chmod 600 deploy_key
|
||||
ssh -i deploy_key user@seu-servidor.com 'cd /app && ./scripts/deploy.sh'
|
||||
164
CHANGELOG.md
164
CHANGELOG.md
@ -5,141 +5,43 @@ 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/).
|
||||
|
||||
## [0.1.0] - 2024-03-23
|
||||
## [0.2.0] - 2024-03-21
|
||||
|
||||
### Adicionado
|
||||
- Landing page para pais
|
||||
- Design moderno e atraente
|
||||
- Seções de benefícios e funcionalidades
|
||||
- Demonstração de métricas e análises
|
||||
- Gráficos interativos com recharts
|
||||
- Gráfico de evolução do aluno
|
||||
- Comparativo antes/depois
|
||||
- Depoimentos de usuários
|
||||
- CTAs estratégicos
|
||||
- Demonstração interativa
|
||||
- Copywriting focado em resultados
|
||||
- Imagens otimizadas e responsivas
|
||||
- Rota dedicada em /para-pais
|
||||
|
||||
- Edge function `generate-story` para geração de histórias com IA
|
||||
- Integração com OpenAI GPT para criação de texto
|
||||
- Integração com DALL-E para geração de imagens
|
||||
- Sistema de logs estruturados para monitoramento
|
||||
- Tratamento robusto de erros e validações
|
||||
|
||||
- Componente `StoryGenerator` para interface de criação
|
||||
- Fluxo de seleção de categorias (tema, disciplina, personagem, cenário)
|
||||
- Feedback visual do processo de geração
|
||||
- Validações de campos obrigatórios
|
||||
- Navegação automática entre etapas
|
||||
- Tratamento de erros com feedback visual
|
||||
|
||||
- Nova estrutura de dados para páginas de histórias
|
||||
- Tabela `story_pages` para melhor organização
|
||||
- Relacionamentos explícitos entre histórias e páginas
|
||||
- Suporte a ordenação por número da página
|
||||
|
||||
- Otimização de carregamento de imagens
|
||||
- Lazy loading com placeholders
|
||||
- Pré-carregamento da próxima imagem
|
||||
- Cache de imagens no frontend
|
||||
- Transformações de imagem no Supabase Storage
|
||||
- Múltiplas resoluções de imagem
|
||||
|
||||
- Sistema de cache de imagens no frontend
|
||||
- Implementação de imageCache.ts
|
||||
- Prevenção de recarregamento desnecessário
|
||||
- Melhor performance em navegação
|
||||
|
||||
### Modificado
|
||||
- Reorganização da landing page para pais
|
||||
- Reordenação das seções para melhor fluxo
|
||||
- Hero → Por que escolher → Como Funciona → Análise → Diferença → Depoimentos → CTA
|
||||
- Otimização da jornada do usuário
|
||||
- Melhor hierarquia de informações
|
||||
- Fluxo narrativo mais coerente
|
||||
- Progressão lógica de informações
|
||||
- Posicionamento estratégico do CTA
|
||||
|
||||
- Reorganização da estrutura de arquivos
|
||||
- Remoção da pasta /pages/story
|
||||
- Consolidação dos componentes de história em /pages/student-dashboard
|
||||
- Melhor organização hierárquica das rotas
|
||||
|
||||
- Otimização global de imagens
|
||||
- Conversão automática para WebP
|
||||
- Redimensionamento otimizado por contexto
|
||||
- Parâmetros de qualidade personalizados
|
||||
- Função utilitária centralizada
|
||||
- Implementação em todas as rotas
|
||||
- Otimização contextual por uso
|
||||
- Pré-carregamento otimizado
|
||||
|
||||
- Otimização de imagens de capa
|
||||
- Uso da primeira página como capa
|
||||
- Tamanho reduzido para thumbnails
|
||||
- Carregamento lazy para melhor performance
|
||||
- Refatoração da interface de capa
|
||||
- Tipagem específica para cover na interface Story
|
||||
- Padronização do uso da primeira página como capa
|
||||
- Otimização de queries para busca de capas
|
||||
- Parâmetros de transformação para thumbnails
|
||||
|
||||
- Padronização da interface de histórias
|
||||
- Consistência visual entre dashboard e lista
|
||||
- Cards de história com mesmo estilo e comportamento
|
||||
- Melhor experiência do usuário na navegação
|
||||
|
||||
- Atualização do schema do banco para suportar novas categorias
|
||||
- Adição de tabelas para temas, disciplinas, personagens e cenários
|
||||
- Relacionamentos entre histórias e categorias
|
||||
- Índices para otimização de consultas
|
||||
- Configuração Docker para ambiente de produção
|
||||
- Pipeline de CI/CD no Gitea Actions
|
||||
- Integração com Redis para cache
|
||||
- Healthcheck da aplicação
|
||||
- Adiciona seções:
|
||||
- Hero com CTA e social proof
|
||||
- Problemas e Soluções
|
||||
- Como a Magia Acontece
|
||||
- Comparação antes/depois
|
||||
- Benefícios Mágicos em layout horizontal
|
||||
- Testimoniais
|
||||
- Planos e preços
|
||||
- FAQ
|
||||
- CTA final
|
||||
- Footer
|
||||
|
||||
### Técnico
|
||||
- Melhorias no tratamento de imagens
|
||||
- Tratamento de URLs indefinidas
|
||||
- Imagem padrão para fallback
|
||||
- Otimização consistente em edge functions
|
||||
- Melhor tipagem para URLs
|
||||
- Prevenção de erros em runtime
|
||||
- Dockerfile com multi-stage build para otimização
|
||||
- Configuração de registry no Gitea
|
||||
- Cache de histórias com Redis
|
||||
- Scripts de deploy e monitoramento
|
||||
|
||||
- Implementação de logs estruturados com prefixos por contexto
|
||||
- Validações de dados em múltiplas camadas
|
||||
- Tratamento de respostas da IA com fallbacks
|
||||
- Otimização de queries no banco de dados
|
||||
- Feedback em tempo real do processo de geração
|
||||
- Queries otimizadas para nova estrutura de dados
|
||||
- Melhor tratamento de estados de loading e erro
|
||||
- Implementação de componente ImageWithLoading
|
||||
- Sistema de cache de imagens
|
||||
- Otimização de URLs de imagem
|
||||
|
||||
- Refatoração de componentes para melhor reuso
|
||||
- Separação de lógica de carregamento de imagens
|
||||
- Componentes mais modulares e reutilizáveis
|
||||
- Melhor organização do código
|
||||
### Modificado
|
||||
- Atualização do next.config.js para suporte standalone
|
||||
- Adaptação da API para usar Redis cache
|
||||
- Configuração de redes Docker
|
||||
- Otimiza UX/UI com:
|
||||
- Animações suaves
|
||||
- Gradientes modernos
|
||||
- Layout responsivo
|
||||
- Elementos interativos
|
||||
- Social proof estratégico
|
||||
|
||||
### Segurança
|
||||
- Validação de dados de entrada na edge function
|
||||
- Verificação de permissões do usuário
|
||||
- Sanitização de prompts para a IA
|
||||
- Proteção contra dados sensíveis nos logs
|
||||
|
||||
### Próximos Passos
|
||||
- [ ] Implementar cache de respostas da IA
|
||||
- [ ] Adicionar retry policy para falhas de geração
|
||||
- [ ] Melhorar prompts para histórias mais educativas
|
||||
- [ ] Adicionar métricas de uso e performance
|
||||
|
||||
- Melhorias na página de demonstração
|
||||
- Reorganização do layout e componentes
|
||||
- Priorização do conteúdo da história
|
||||
- Dashboard de métricas movido para baixo
|
||||
- Fluxo interativo de demonstração
|
||||
- Simulação de gravação e análise
|
||||
- CTAs personalizados para escolas e pais
|
||||
- Separação de dados mock
|
||||
- Feedback visual aprimorado
|
||||
- Estilos mais modernos e consistentes
|
||||
- Melhor experiência de demonstração
|
||||
- Implementação de healthchecks
|
||||
- Configuração de redes isoladas
|
||||
- Proteção de variáveis de ambiente
|
||||
40
Dockerfile
Normal file
40
Dockerfile
Normal file
@ -0,0 +1,40 @@
|
||||
# Build stage
|
||||
FROM node:18-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Adicionar dependência do Redis
|
||||
RUN apk add --no-cache redis
|
||||
|
||||
# Copiar arquivos de dependências
|
||||
COPY package*.json ./
|
||||
COPY yarn.lock ./
|
||||
|
||||
# Instalar dependências
|
||||
RUN yarn install --frozen-lockfile
|
||||
|
||||
# Copiar código fonte
|
||||
COPY . .
|
||||
|
||||
# Build da aplicação
|
||||
RUN yarn build
|
||||
|
||||
# Production stage
|
||||
FROM node:18-alpine AS runner
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Adicionar dependência do Redis
|
||||
RUN apk add --no-cache redis
|
||||
|
||||
# Copiar arquivos necessários do builder
|
||||
COPY --from=builder /app/next.config.js ./
|
||||
COPY --from=builder /app/public ./public
|
||||
COPY --from=builder /app/.next/standalone ./
|
||||
COPY --from=builder /app/.next/static ./.next/static
|
||||
|
||||
# Expor porta
|
||||
EXPOSE 3000
|
||||
|
||||
# Comando para rodar a aplicação
|
||||
CMD ["node", "server.js"]
|
||||
33
docker-compose.yml
Normal file
33
docker-compose.yml
Normal file
@ -0,0 +1,33 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
historias-magicas:
|
||||
image: ${REGISTRY}/historias-magicas:${TAG}
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- NEXT_PUBLIC_SUPABASE_URL=${NEXT_PUBLIC_SUPABASE_URL}
|
||||
- NEXT_PUBLIC_SUPABASE_ANON_KEY=${NEXT_PUBLIC_SUPABASE_ANON_KEY}
|
||||
- OPENAI_API_KEY=${OPENAI_API_KEY}
|
||||
- REDIS_URL=redis://redis:6379
|
||||
networks:
|
||||
- network_public
|
||||
deploy:
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.historias-magicas.rule=Host(`${DOMAIN}`)"
|
||||
- "traefik.http.routers.historias-magicas.entrypoints=websecure"
|
||||
- "traefik.http.routers.historias-magicas.tls.certresolver=letsencrypt"
|
||||
- "traefik.http.services.historias-magicas.loadbalancer.server.port=3000"
|
||||
- "traefik.docker.network=traefik-public"
|
||||
replicas: 1
|
||||
update_config:
|
||||
parallelism: 1
|
||||
delay: 10s
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
|
||||
networks:
|
||||
traefik-public:
|
||||
external: true
|
||||
redis-network:
|
||||
external: true
|
||||
12
next.config.js
Normal file
12
next.config.js
Normal file
@ -0,0 +1,12 @@
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
output: 'standalone',
|
||||
images: {
|
||||
domains: [
|
||||
'oaidalleapiprodscus.blob.core.windows.net',
|
||||
// outros domínios necessários
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
module.exports = nextConfig
|
||||
@ -9,7 +9,10 @@
|
||||
"preview": "vite preview",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
||||
"format": "prettier --write \"src/**/*.{ts,tsx}\""
|
||||
"format": "prettier --write \"src/**/*.{ts,tsx}\"",
|
||||
"docker:build": "docker build -t historias-magicas .",
|
||||
"docker:run": "docker run -p 3000:3000 historias-magicas",
|
||||
"deploy:prod": "docker-compose up -d --build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@radix-ui/react-accordion": "^1.2.2",
|
||||
|
||||
34
portainer-stack.yml
Normal file
34
portainer-stack.yml
Normal file
@ -0,0 +1,34 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
historias-magicas:
|
||||
image: ${REGISTRY}/historias-magicas:${TAG}
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- NEXT_PUBLIC_SUPABASE_URL=${NEXT_PUBLIC_SUPABASE_URL}
|
||||
- NEXT_PUBLIC_SUPABASE_ANON_KEY=${NEXT_PUBLIC_SUPABASE_ANON_KEY}
|
||||
- OPENAI_API_KEY=${OPENAI_API_KEY}
|
||||
- REDIS_URL=redis://redis:6379
|
||||
networks:
|
||||
- traefik-public
|
||||
- redis-network
|
||||
deploy:
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.historias-magicas.rule=Host(`${DOMAIN}`)"
|
||||
- "traefik.http.routers.historias-magicas.entrypoints=websecure"
|
||||
- "traefik.http.routers.historias-magicas.tls.certresolver=letsencrypt"
|
||||
- "traefik.http.services.historias-magicas.loadbalancer.server.port=3000"
|
||||
- "traefik.docker.network=traefik-public"
|
||||
replicas: 2
|
||||
update_config:
|
||||
parallelism: 1
|
||||
delay: 10s
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
|
||||
networks:
|
||||
traefik-public:
|
||||
external: true
|
||||
redis-network:
|
||||
external: true
|
||||
5
src/lib/redis.ts
Normal file
5
src/lib/redis.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { Redis } from 'ioredis';
|
||||
|
||||
const redis = new Redis(process.env.REDIS_URL || 'redis://localhost:6379');
|
||||
|
||||
export default redis;
|
||||
@ -1,3 +1,4 @@
|
||||
import { StoryPrompt } from '@/types/story-generator'
|
||||
import { createClient } from '@supabase/supabase-js'
|
||||
|
||||
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL
|
||||
@ -13,4 +14,26 @@ export const supabase = createClient(supabaseUrl, supabaseAnonKey, {
|
||||
persistSession: true,
|
||||
detectSessionInUrl: true
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
export const generateStoryFunction = async (prompt: StoryPrompt) => {
|
||||
const { data: { session } } = await supabase.auth.getSession()
|
||||
|
||||
const response = await fetch(
|
||||
'https://seu-project-ref.supabase.co/functions/v1/generate-story',
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${session?.access_token}`,
|
||||
},
|
||||
body: JSON.stringify(prompt),
|
||||
}
|
||||
)
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Falha ao gerar história')
|
||||
}
|
||||
|
||||
return response.json()
|
||||
}
|
||||
17
src/pages/api/health.ts
Normal file
17
src/pages/api/health.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import redis from '@/lib/redis';
|
||||
|
||||
export default async function handler(req, res) {
|
||||
try {
|
||||
// Verifica conexão com Redis
|
||||
await redis.ping();
|
||||
|
||||
// Verifica conexão com Supabase
|
||||
const { data, error } = await supabase.from('stories').select('id').limit(1);
|
||||
|
||||
if (error) throw error;
|
||||
|
||||
res.status(200).json({ status: 'healthy' });
|
||||
} catch (error) {
|
||||
res.status(500).json({ status: 'unhealthy', error: error.message });
|
||||
}
|
||||
}
|
||||
24
src/pages/api/stories/[id].ts
Normal file
24
src/pages/api/stories/[id].ts
Normal file
@ -0,0 +1,24 @@
|
||||
import redis from '@/lib/redis';
|
||||
import { supabase } from '@/lib/supabase';
|
||||
|
||||
export default async function handler(req, res) {
|
||||
const { id } = req.query;
|
||||
|
||||
// Tenta pegar do cache primeiro
|
||||
const cachedStory = await redis.get(`story:${id}`);
|
||||
if (cachedStory) {
|
||||
return res.json(JSON.parse(cachedStory));
|
||||
}
|
||||
|
||||
// Se não estiver no cache, busca do Supabase
|
||||
const { data: story } = await supabase
|
||||
.from('stories')
|
||||
.select('*')
|
||||
.eq('id', id)
|
||||
.single();
|
||||
|
||||
// Salva no cache por 1 hora
|
||||
await redis.setex(`story:${id}`, 3600, JSON.stringify(story));
|
||||
|
||||
return res.json(story);
|
||||
}
|
||||
807
src/pages/landing/EducationalForParents.tsx
Normal file
807
src/pages/landing/EducationalForParents.tsx
Normal file
@ -0,0 +1,807 @@
|
||||
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
|
||||
} from 'lucide-react';
|
||||
|
||||
export function EducationalForParents(): JSX.Element {
|
||||
const navigate = useNavigate();
|
||||
|
||||
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>
|
||||
|
||||
<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"
|
||||
>
|
||||
<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>
|
||||
|
||||
{/* 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>
|
||||
</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">
|
||||
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 */}
|
||||
<section className="px-4 py-24 bg-gradient-to-b from-purple-50 via-white to-purple-50">
|
||||
<div className="mx-auto max-w-7xl">
|
||||
<h2 className="text-4xl font-bold text-center text-gray-900 mb-4">
|
||||
Planos Mágicos
|
||||
</h2>
|
||||
<p className="text-center text-gray-600 mb-16 max-w-2xl mx-auto">
|
||||
Escolha o plano perfeito para a jornada mágica do seu filho
|
||||
</p>
|
||||
|
||||
<div className="grid md:grid-cols-3 gap-8">
|
||||
{plans.map((plan, index) => (
|
||||
<div key={index} className={`
|
||||
p-8 rounded-xl shadow-lg border-2
|
||||
${index === 1 ? 'bg-gradient-to-br from-purple-50 to-blue-50 border-purple-200 transform scale-105'
|
||||
: 'bg-white border-gray-100'}
|
||||
`}>
|
||||
<div className="text-center mb-8">
|
||||
<h3 className="text-2xl font-bold text-gray-900 mb-2">{plan.title}</h3>
|
||||
<p className="text-gray-600">{plan.description}</p>
|
||||
<div className="mt-4">
|
||||
<span className="text-4xl font-bold text-gray-900">R${plan.price}</span>
|
||||
<span className="text-gray-500">/{plan.period}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul className="space-y-4 mb-8">
|
||||
{plan.features.map((feature, 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">{feature}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<button
|
||||
onClick={() => navigate('/register/parent')}
|
||||
className={`
|
||||
w-full py-4 rounded-xl font-medium transition-all
|
||||
${index === 1
|
||||
? 'bg-gradient-to-r from-purple-600 to-blue-500 text-white hover:from-purple-700 hover:to-blue-600'
|
||||
: 'border-2 border-purple-600 text-purple-600 hover:bg-purple-50'}
|
||||
`}
|
||||
>
|
||||
Começar Agora
|
||||
</button>
|
||||
|
||||
{index === 1 && (
|
||||
<div className="mt-4 text-center">
|
||||
<span className="inline-block px-4 py-1 bg-purple-100 text-purple-600
|
||||
rounded-full text-sm font-medium">
|
||||
Mais Popular
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="mt-12 text-center">
|
||||
<p className="text-gray-600 mb-4">
|
||||
Garantia mágica de 30 dias ou seu dinheiro de volta
|
||||
</p>
|
||||
<div className="flex justify-center gap-4">
|
||||
{paymentMethods.map((method, index) => (
|
||||
<img
|
||||
key={index}
|
||||
src={method.icon}
|
||||
alt={method.name}
|
||||
className="h-8"
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* 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>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* 10. Rodapé */}
|
||||
<footer className="bg-gray-900 text-gray-400 py-16">
|
||||
<div className="mx-auto max-w-7xl px-4">
|
||||
<div className="grid md:grid-cols-4 gap-12">
|
||||
<div>
|
||||
<h4 className="text-white font-bold mb-4">Histórias Mágicas</h4>
|
||||
<p className="text-sm">
|
||||
Transformando a educação através da magia da leitura personalizada
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{footerLinks.map((column, index) => (
|
||||
<div key={index}>
|
||||
<h4 className="text-white font-bold mb-4">{column.title}</h4>
|
||||
<ul className="space-y-2">
|
||||
{column.links.map((link, idx) => (
|
||||
<li key={idx}>
|
||||
<a href={link.href} className="text-sm hover:text-white transition-colors">
|
||||
{link.text}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="mt-12 pt-8 border-t border-gray-800 text-sm">
|
||||
<div className="flex justify-between items-center">
|
||||
<p>© 2024 Histórias Mágicas. Todos os direitos reservados.</p>
|
||||
<div className="flex gap-4">
|
||||
{socialLinks.map((social, index) => (
|
||||
<a
|
||||
key={index}
|
||||
href={social.href}
|
||||
className="text-gray-400 hover:text-white transition-colors"
|
||||
>
|
||||
<social.icon className="h-5 w-5" />
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
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."
|
||||
},
|
||||
{
|
||||
icon: BookOpen,
|
||||
title: "Encontrar conteúdo educativo de qualidade",
|
||||
description: "Muito conteúdo disponível, mas pouco realmente educativo e envolvente."
|
||||
},
|
||||
{
|
||||
icon: Target,
|
||||
title: "Acompanhar o desenvolvimento da criança",
|
||||
description: "Falta de ferramentas para monitorar o progresso de forma clara e objetiva."
|
||||
}
|
||||
];
|
||||
|
||||
const benefits = [
|
||||
{
|
||||
icon: Wand2,
|
||||
title: "Personalização por IA",
|
||||
description: "Histórias únicas criadas especialmente para cada criança"
|
||||
},
|
||||
{
|
||||
icon: Star,
|
||||
title: "Monitoramento Educacional",
|
||||
description: "Acompanhe o progresso com métricas claras e objetivas"
|
||||
},
|
||||
{
|
||||
icon: Shield,
|
||||
title: "Segurança de Conteúdo",
|
||||
description: "Ambiente seguro e controlado para o aprendizado"
|
||||
},
|
||||
{
|
||||
icon: Sparkles,
|
||||
title: "Engajamento Garantido",
|
||||
description: "Histórias que prendem a atenção e estimulam a imaginação"
|
||||
}
|
||||
];
|
||||
|
||||
const magicSteps = [
|
||||
{
|
||||
title: "Escolha o tema da aventura",
|
||||
description: "Selecione entre diversos temas educativos alinhados com a BNCC e adequados à idade."
|
||||
},
|
||||
{
|
||||
title: "Personalize os personagens",
|
||||
description: "Crie personagens que seu filho vai adorar, com características únicas e cativantes."
|
||||
},
|
||||
{
|
||||
title: "A IA cria a história mágica",
|
||||
description: "Nossa IA educacional gera uma história personalizada em segundos."
|
||||
},
|
||||
{
|
||||
title: "A aventura educativa começa",
|
||||
description: "Seu filho mergulha em uma jornada mágica de aprendizado e diversão."
|
||||
}
|
||||
];
|
||||
|
||||
const comparisonData = [
|
||||
{
|
||||
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"
|
||||
],
|
||||
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"
|
||||
]
|
||||
},
|
||||
{
|
||||
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"
|
||||
],
|
||||
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"
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Resultados",
|
||||
without: [
|
||||
"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"
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
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."
|
||||
},
|
||||
{
|
||||
icon: ScrollText,
|
||||
title: "Portal dos Pais",
|
||||
description: "Acompanhe em tempo real o progresso de leitura, compreensão e desenvolvimento do seu filho."
|
||||
},
|
||||
{
|
||||
icon: Shield,
|
||||
title: "Proteção Mágica",
|
||||
description: "Conteúdo 100% seguro e adequado, com moderação constante e controles parentais."
|
||||
},
|
||||
{
|
||||
icon: BookOpen,
|
||||
title: "Alinhamento com BNCC",
|
||||
description: "Histórias criadas seguindo as diretrizes da Base Nacional Comum Curricular."
|
||||
},
|
||||
{
|
||||
icon: Brain,
|
||||
title: "IA Educacional",
|
||||
description: "Nossa inteligência artificial analisa o perfil do seu filho para criar histórias personalizadas e adaptativas."
|
||||
}
|
||||
];
|
||||
|
||||
const testimonials = [
|
||||
{
|
||||
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"
|
||||
},
|
||||
{
|
||||
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"
|
||||
},
|
||||
{
|
||||
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"
|
||||
}
|
||||
];
|
||||
|
||||
const plans = [
|
||||
{
|
||||
title: "Aprendiz de Mago",
|
||||
description: "Perfeito para começar",
|
||||
price: "49,90",
|
||||
period: "mês",
|
||||
features: [
|
||||
"5 histórias personalizadas por mês",
|
||||
"Análise básica de progresso",
|
||||
"Suporte por email",
|
||||
"Acesso ao portal dos pais",
|
||||
"Relatórios mensais"
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Mago Experiente",
|
||||
description: "Mais popular",
|
||||
price: "39,90",
|
||||
period: "mês",
|
||||
features: [
|
||||
"15 histórias personalizadas por mês",
|
||||
"Análise avançada de progresso",
|
||||
"Suporte prioritário",
|
||||
"Portal dos pais premium",
|
||||
"Relatórios semanais",
|
||||
"Histórias temáticas especiais",
|
||||
"Bônus: Kit de Atividades Mágicas"
|
||||
],
|
||||
highlight: true,
|
||||
commitment: "Semestral"
|
||||
},
|
||||
{
|
||||
title: "Grão-Mestre",
|
||||
description: "Melhor custo-benefício",
|
||||
price: "29,90",
|
||||
period: "mês",
|
||||
features: [
|
||||
"Histórias ilimitadas",
|
||||
"Análise completa de progresso",
|
||||
"Suporte VIP 24/7",
|
||||
"Portal dos pais premium",
|
||||
"Relatórios diários",
|
||||
"Histórias temáticas especiais",
|
||||
"Bônus: Kit de Atividades Mágicas",
|
||||
"Bônus: Sessões com pedagogo"
|
||||
],
|
||||
commitment: "Anual"
|
||||
}
|
||||
];
|
||||
|
||||
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 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: "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: "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: "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 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."
|
||||
}
|
||||
];
|
||||
|
||||
const footerLinks = [
|
||||
{
|
||||
title: "Produto",
|
||||
links: [
|
||||
{ text: "Recursos", href: "#recursos" },
|
||||
{ text: "Preços", href: "#precos" },
|
||||
{ text: "Como Funciona", href: "#como-funciona" },
|
||||
{ text: "Histórias de Sucesso", href: "#testimoniais" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Suporte",
|
||||
links: [
|
||||
{ text: "Central de Ajuda", href: "#ajuda" },
|
||||
{ text: "Contato", href: "#contato" },
|
||||
{ text: "FAQ", href: "#faq" },
|
||||
{ text: "Tutoriais", href: "#tutoriais" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Legal",
|
||||
links: [
|
||||
{ text: "Termos de Uso", href: "#termos" },
|
||||
{ text: "Privacidade", href: "#privacidade" },
|
||||
{ text: "Segurança", href: "#seguranca" },
|
||||
{ text: "Cookies", href: "#cookies" }
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
const socialLinks = [
|
||||
{ icon: Facebook, href: "https://facebook.com/historias-magicas" },
|
||||
{ icon: Instagram, href: "https://instagram.com/historias-magicas" },
|
||||
{ icon: Twitter, href: "https://twitter.com/historias-magicas" },
|
||||
{ icon: Youtube, href: "https://youtube.com/historias-magicas" }
|
||||
];
|
||||
|
||||
const paymentMethods = [
|
||||
{ name: "Cartão de Crédito", icon: "/icons/credit-card.svg" },
|
||||
{ name: "Boleto", icon: "/icons/boleto.svg" },
|
||||
{ name: "PIX", icon: "/icons/pix.svg" },
|
||||
{ name: "PayPal", icon: "/icons/paypal.svg" }
|
||||
];
|
||||
@ -27,6 +27,7 @@ import { AchievementsPage } from './pages/student-dashboard/AchievementsPage';
|
||||
import { StudentClassPage } from './pages/student-dashboard/StudentClassPage';
|
||||
import { DemoPage } from './pages/demo/DemoPage';
|
||||
import { ParentsLandingPage } from './pages/landing/ParentsLandingPage';
|
||||
import { EducationalForParents } from './pages/landing/EducationalForParents';
|
||||
|
||||
export const router = createBrowserRouter([
|
||||
{
|
||||
@ -187,5 +188,9 @@ export const router = createBrowserRouter([
|
||||
<UserManagementPage />
|
||||
</ProtectedRoute>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: '/para-educadores',
|
||||
element: <EducationalForParents />,
|
||||
}
|
||||
]);
|
||||
Loading…
Reference in New Issue
Block a user