mirror of
https://github.com/lucasrcsantana/story-generator.git
synced 2025-12-19 23:07:51 +00:00
Compare commits
No commits in common. "1ea1b3e841830f11cf334de67ca7412330c5116e" and "b8562bfda180cd1185e8a5dc840c72bdbc80d85e" have entirely different histories.
1ea1b3e841
...
b8562bfda1
@ -1,24 +1,3 @@
|
|||||||
{
|
{
|
||||||
"template": "bolt-vite-react-ts",
|
"template": "bolt-vite-react-ts"
|
||||||
"version": "1.0.0",
|
|
||||||
"features": {
|
|
||||||
"tailwind": true,
|
|
||||||
"radix": true,
|
|
||||||
"shadcn": true,
|
|
||||||
"supabase": true,
|
|
||||||
"testing": true,
|
|
||||||
"i18n": true,
|
|
||||||
"pwa": true
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"react": "^18.2.0",
|
|
||||||
"react-dom": "^18.2.0",
|
|
||||||
"react-router-dom": "^6.11.2",
|
|
||||||
"@radix-ui/react-dialog": "^1.0.4",
|
|
||||||
"@radix-ui/react-accordion": "^1.1.2",
|
|
||||||
"@radix-ui/react-tabs": "^1.0.4",
|
|
||||||
"@supabase/supabase-js": "^2.26.0",
|
|
||||||
"lucide-react": "^0.259.0",
|
|
||||||
"tailwindcss": "^3.3.2"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,25 +7,17 @@
|
|||||||
"extends": [
|
"extends": [
|
||||||
"eslint:recommended",
|
"eslint:recommended",
|
||||||
"plugin:@typescript-eslint/recommended",
|
"plugin:@typescript-eslint/recommended",
|
||||||
"plugin:react-hooks/recommended",
|
"plugin:react-hooks/recommended"
|
||||||
"plugin:react/recommended",
|
|
||||||
"plugin:react/jsx-runtime"
|
|
||||||
],
|
],
|
||||||
"ignorePatterns": ["dist", ".eslintrc.json"],
|
"ignorePatterns": ["dist", ".eslintrc.json"],
|
||||||
"parser": "@typescript-eslint/parser",
|
"parser": "@typescript-eslint/parser",
|
||||||
"plugins": ["react-refresh", "@typescript-eslint", "react"],
|
"plugins": ["react-refresh"],
|
||||||
"rules": {
|
"rules": {
|
||||||
"react-refresh/only-export-components": [
|
"react-refresh/only-export-components": [
|
||||||
"warn",
|
"warn",
|
||||||
{ "allowConstantExport": true }
|
{ "allowConstantExport": true }
|
||||||
],
|
],
|
||||||
"@typescript-eslint/no-unused-vars": ["warn"],
|
"@typescript-eslint/no-unused-vars": "warn",
|
||||||
"react/prop-types": "off",
|
"no-unused-vars": "warn"
|
||||||
"no-console": "warn"
|
|
||||||
},
|
|
||||||
"settings": {
|
|
||||||
"react": {
|
|
||||||
"version": "detect"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
13
.prettierrc
13
.prettierrc
@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"semi": true,
|
|
||||||
"singleQuote": true,
|
|
||||||
"trailingComma": "es5",
|
|
||||||
"tabWidth": 2,
|
|
||||||
"printWidth": 100,
|
|
||||||
"bracketSpacing": true,
|
|
||||||
"arrowParens": "avoid",
|
|
||||||
"endOfLine": "lf",
|
|
||||||
"jsxSingleQuote": false,
|
|
||||||
"quoteProps": "as-needed",
|
|
||||||
"useTabs": false
|
|
||||||
}
|
|
||||||
40
CHANGELOG.md
40
CHANGELOG.md
@ -5,39 +5,19 @@ Todas as mudanças notáveis neste projeto serão documentadas neste arquivo.
|
|||||||
O formato é baseado em [Keep a Changelog](https://keepachangelog.com/pt-BR/1.0.0/),
|
O formato é baseado em [Keep a Changelog](https://keepachangelog.com/pt-BR/1.0.0/),
|
||||||
e este projeto adere ao [Semantic Versioning](https://semver.org/lang/pt-BR/).
|
e este projeto adere ao [Semantic Versioning](https://semver.org/lang/pt-BR/).
|
||||||
|
|
||||||
## [1.1.1] - 2024-01-17
|
## [1.1.0] - 2024-03-19
|
||||||
|
|
||||||
### Técnico
|
|
||||||
- Refatoração das interfaces do banco de dados:
|
|
||||||
- Criada interface base `BaseEntity` para reduzir duplicação
|
|
||||||
- Corrigidos conflitos de tipos em `email`, `status` e `cover`
|
|
||||||
- Padronizados os tipos de campos em todas as interfaces
|
|
||||||
- Corrigidas as interfaces `ClassWithStudents` e `ClassWithStudentsAndStories`
|
|
||||||
- Melhorada a organização do código com herança de interfaces
|
|
||||||
- Corrigido erro no teste do `WordHighlighter`:
|
|
||||||
- Adicionada importação do `beforeEach` do Vitest
|
|
||||||
- Mantida a estrutura dos testes existentes
|
|
||||||
|
|
||||||
## [1.1.0] - 2024-01-17
|
|
||||||
|
|
||||||
### Adicionado
|
### Adicionado
|
||||||
- Novo componente reutilizável `Footer` para todas as Landing Pages
|
- Nova aba "Interesses" nas configurações do aluno para capturar preferências
|
||||||
- Novos componentes de planos:
|
- Sistema de notificações toast usando Radix UI
|
||||||
- `PlanForParents`: Planos focados em pais com preços acessíveis
|
- Tabela `interests` no banco de dados para armazenar interesses dos alunos
|
||||||
- `PlanForSchools`: Planos corporativos focados em escolas
|
|
||||||
- Implementação dos novos componentes nas páginas:
|
|
||||||
- `/para-pais`: Adicionado `PlanForParents`
|
|
||||||
- `/evidencias`: Adicionado `PlanForSchools`
|
|
||||||
- `/para-educadores`: Adicionado `PlanForParents`
|
|
||||||
- `HomePage`: Atualizado com `PlanForSchools`
|
|
||||||
|
|
||||||
### Modificado
|
### Modificado
|
||||||
- Refatoração das Landing Pages para utilizar o novo componente `Footer`
|
- Menu lateral do dashboard agora é responsivo e colapsável
|
||||||
- Atualização da estrutura de navegação com links organizados em seções
|
- Menu lateral do dashboard do aluno agora é responsivo e colapsável
|
||||||
- Melhorias na responsividade e consistência visual dos planos
|
- Menus laterais agora colapsam automaticamente ao clicar em um item
|
||||||
|
|
||||||
### Técnico
|
### Técnico
|
||||||
- Implementação de tipos TypeScript para os novos componentes
|
- Implementação do hook `useToast` para gerenciamento de notificações
|
||||||
- Adição de props para customização dos componentes
|
- Correção dos caminhos de importação para compatibilidade com Vite
|
||||||
- Melhorias na organização do código com componentes reutilizáveis
|
- Adição de políticas de segurança RLS na tabela `interests`
|
||||||
- Correção de imports não utilizados em `ParentsLandingPage.tsx`
|
|
||||||
|
|||||||
@ -14,15 +14,6 @@
|
|||||||
to = "/index.html"
|
to = "/index.html"
|
||||||
status = 200
|
status = 200
|
||||||
|
|
||||||
[[headers]]
|
|
||||||
for = "/*"
|
|
||||||
[headers.values]
|
|
||||||
X-Frame-Options = "DENY"
|
|
||||||
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';"
|
|
||||||
|
|
||||||
[dev]
|
[dev]
|
||||||
command = "npm run dev"
|
command = "npm run dev"
|
||||||
port = 5173
|
port = 5173
|
||||||
|
|||||||
@ -4,15 +4,8 @@ const nextConfig = {
|
|||||||
images: {
|
images: {
|
||||||
domains: [
|
domains: [
|
||||||
'oaidalleapiprodscus.blob.core.windows.net',
|
'oaidalleapiprodscus.blob.core.windows.net',
|
||||||
'historiasmagicas.netlify.app',
|
// outros domínios necessários
|
||||||
'localhost',
|
|
||||||
],
|
],
|
||||||
formats: ['image/avif', 'image/webp'],
|
|
||||||
minimumCacheTTL: 60,
|
|
||||||
},
|
|
||||||
experimental: {
|
|
||||||
optimizeCss: true,
|
|
||||||
optimizeImages: true,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1 +0,0 @@
|
|||||||
data:image/webp;base64,UklGRlIAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAIAAAABBxAREYiI/gcAAABWUDggGAAAADABAJ0BKgEAAQABABwlpAADcAD+/gbQAA==
|
|
||||||
@ -1 +0,0 @@
|
|||||||
data:image/webp;base64,UklGRlIAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAIAAAABBxAREYiI/gcAAABWUDggGAAAADABAJ0BKgEAAQABABwlpAADcAD+/gbQAA==
|
|
||||||
@ -1 +0,0 @@
|
|||||||
data:image/webp;base64,UklGRlIAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAIAAAABBxAREYiI/gcAAABWUDggGAAAADABAJ0BKgEAAQABABwlpAADcAD+/gbQAA==
|
|
||||||
@ -1 +0,0 @@
|
|||||||
data:image/webp;base64,UklGRlIAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAIAAAABBxAREYiI/gcAAABWUDggGAAAADABAJ0BKgEAAQABABwlpAADcAD+/gbQAA==
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<circle cx="2" cy="2" r="2" fill="currentColor"/>
|
|
||||||
<circle cx="18" cy="2" r="2" fill="currentColor"/>
|
|
||||||
<circle cx="10" cy="10" r="2" fill="currentColor"/>
|
|
||||||
<circle cx="2" cy="18" r="2" fill="currentColor"/>
|
|
||||||
<circle cx="18" cy="18" r="2" fill="currentColor"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 408 B |
@ -9,8 +9,6 @@ import {
|
|||||||
Mic,
|
Mic,
|
||||||
Share2
|
Share2
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
import { Footer } from '@/components/ui/footer';
|
|
||||||
import { PlanForSchools } from '@/components/ui/plan-for-schools';
|
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
const FeatureCard = ({ icon, title, description }: {
|
const FeatureCard = ({ icon, title, description }: {
|
||||||
@ -52,12 +50,44 @@ const TestimonialCard = ({ quote, author, role, image }: {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
const navigation = [
|
const PriceCard = ({
|
||||||
{ name: 'Início', href: '/' },
|
plan,
|
||||||
{ name: 'Para Pais', href: '/para-pais' },
|
price,
|
||||||
{ name: 'Evidências', href: '/evidencias' },
|
description,
|
||||||
{ name: 'Para Educadores', href: '/para-educadores' },
|
features,
|
||||||
];
|
highlighted = false
|
||||||
|
}: {
|
||||||
|
plan: string;
|
||||||
|
price: string;
|
||||||
|
description: string;
|
||||||
|
features: string[];
|
||||||
|
highlighted?: boolean;
|
||||||
|
}) => (
|
||||||
|
<div className={`p-6 rounded-xl border ${
|
||||||
|
highlighted ? 'border-purple-600 shadow-lg' : 'border-gray-200'
|
||||||
|
}`}>
|
||||||
|
<div className="text-xl font-semibold text-gray-900 mb-2">{plan}</div>
|
||||||
|
<div className="text-3xl font-bold text-gray-900 mb-2">
|
||||||
|
R$ {price}<span className="text-sm font-normal text-gray-600">/mês</span>
|
||||||
|
</div>
|
||||||
|
<p className="text-gray-600 mb-6">{description}</p>
|
||||||
|
<ul className="space-y-3 mb-6">
|
||||||
|
{features.map((feature, index) => (
|
||||||
|
<li key={index} className="flex items-center gap-2">
|
||||||
|
<CheckCircle className="w-5 h-5 text-purple-600" />
|
||||||
|
<span className="text-gray-600">{feature}</span>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
<button className={`w-full py-2 px-4 rounded-lg transition ${
|
||||||
|
highlighted
|
||||||
|
? 'bg-purple-600 text-white hover:bg-purple-700'
|
||||||
|
: 'border border-purple-600 text-purple-600 hover:bg-purple-50'
|
||||||
|
}`}>
|
||||||
|
Começar agora
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
export function HomePage() {
|
export function HomePage() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@ -70,9 +100,7 @@ export function HomePage() {
|
|||||||
const handleSchoolLogin = () => navigate('/login/school');
|
const handleSchoolLogin = () => navigate('/login/school');
|
||||||
const handleTeacherLogin = () => navigate('/login/teacher');
|
const handleTeacherLogin = () => navigate('/login/teacher');
|
||||||
const handleStudentLogin = () => navigate('/login/student');
|
const handleStudentLogin = () => navigate('/login/student');
|
||||||
const handleSchoolRegister = () => {
|
const handleSchoolRegister = () => navigate('/register/school');
|
||||||
navigate('/register');
|
|
||||||
};
|
|
||||||
const handleDemo = () => navigate('/demo');
|
const handleDemo = () => navigate('/demo');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -476,7 +504,52 @@ export function HomePage() {
|
|||||||
|
|
||||||
{/* Pricing */}
|
{/* Pricing */}
|
||||||
<div className="py-20 bg-gray-50">
|
<div className="py-20 bg-gray-50">
|
||||||
<PlanForSchools />
|
<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">
|
||||||
|
Planos para Cada Necessidade
|
||||||
|
</h2>
|
||||||
|
<p className="text-gray-600 max-w-2xl mx-auto">
|
||||||
|
Escolha o plano ideal para sua escola
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid md:grid-cols-3 gap-8">
|
||||||
|
<PriceCard
|
||||||
|
plan="Básico"
|
||||||
|
price="497"
|
||||||
|
description="Ideal para escolas pequenas"
|
||||||
|
features={[
|
||||||
|
"Até 200 alunos",
|
||||||
|
"Histórias básicas",
|
||||||
|
"Suporte por email"
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
<PriceCard
|
||||||
|
plan="Profissional"
|
||||||
|
price="997"
|
||||||
|
description="Para escolas em crescimento"
|
||||||
|
features={[
|
||||||
|
"Até 1000 alunos",
|
||||||
|
"Histórias personalizadas",
|
||||||
|
"Suporte prioritário",
|
||||||
|
"Analytics avançado"
|
||||||
|
]}
|
||||||
|
highlighted
|
||||||
|
/>
|
||||||
|
<PriceCard
|
||||||
|
plan="Enterprise"
|
||||||
|
price="Consulte"
|
||||||
|
description="Para redes de ensino"
|
||||||
|
features={[
|
||||||
|
"Alunos ilimitados",
|
||||||
|
"Customização completa",
|
||||||
|
"Suporte 24/7",
|
||||||
|
"API dedicada"
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Final CTA */}
|
{/* Final CTA */}
|
||||||
@ -500,7 +573,22 @@ export function HomePage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Footer */}
|
{/* Footer */}
|
||||||
<Footer />
|
<footer className="bg-gray-900 text-white py-12">
|
||||||
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
|
<div className="grid md:grid-cols-4 gap-8">
|
||||||
|
<div>
|
||||||
|
<div className="flex items-center gap-2 mb-4">
|
||||||
|
<BookOpen className="h-8 w-8" />
|
||||||
|
<span className="text-xl font-bold">Histórias Mágicas</span>
|
||||||
|
</div>
|
||||||
|
<p className="text-gray-400">
|
||||||
|
Transformando a educação através de histórias interativas
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{/* Adicione mais seções do footer conforme necessário */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import { render, screen, fireEvent } from '@testing-library/react'
|
import { render, screen, fireEvent } from '@testing-library/react'
|
||||||
import { WordHighlighter } from './WordHighlighter'
|
import { WordHighlighter } from './WordHighlighter'
|
||||||
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
import { describe, it, expect, vi } from 'vitest'
|
||||||
import '@testing-library/jest-dom/vitest'
|
import '@testing-library/jest-dom/vitest'
|
||||||
|
|
||||||
describe('WordHighlighter', () => {
|
describe('WordHighlighter', () => {
|
||||||
|
|||||||
@ -1,178 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { Link } from 'react-router-dom';
|
|
||||||
import {
|
|
||||||
BookOpen,
|
|
||||||
Facebook,
|
|
||||||
Instagram,
|
|
||||||
Twitter,
|
|
||||||
Youtube,
|
|
||||||
Mail,
|
|
||||||
Phone,
|
|
||||||
MapPin
|
|
||||||
} from 'lucide-react';
|
|
||||||
|
|
||||||
interface FooterLink {
|
|
||||||
text: string;
|
|
||||||
href: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface FooterColumn {
|
|
||||||
title: string;
|
|
||||||
links: FooterLink[];
|
|
||||||
}
|
|
||||||
|
|
||||||
interface SocialLink {
|
|
||||||
icon: React.ElementType;
|
|
||||||
href: string;
|
|
||||||
label: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface FooterProps {
|
|
||||||
/** Links de navegação organizados em colunas */
|
|
||||||
columns?: FooterColumn[];
|
|
||||||
/** Links para redes sociais */
|
|
||||||
socialLinks?: SocialLink[];
|
|
||||||
/** Texto de direitos autorais */
|
|
||||||
copyrightText?: string;
|
|
||||||
/** Endereço da empresa */
|
|
||||||
address?: string;
|
|
||||||
/** Email de contato */
|
|
||||||
email?: string;
|
|
||||||
/** Telefone de contato */
|
|
||||||
phone?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const defaultColumns: FooterColumn[] = [
|
|
||||||
{
|
|
||||||
title: 'Produto',
|
|
||||||
links: [
|
|
||||||
{ text: 'Funcionalidades', href: '/funcionalidades' },
|
|
||||||
{ text: 'Planos', href: '/planos' },
|
|
||||||
{ text: 'Como Funciona', href: '/como-funciona' },
|
|
||||||
{ text: 'Histórias de Sucesso', href: '/historias-de-sucesso' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Recursos',
|
|
||||||
links: [
|
|
||||||
{ text: 'Base Científica', href: '/base-cientifica' },
|
|
||||||
{ text: 'Central de Ajuda', href: '/ajuda' },
|
|
||||||
{ text: 'Contato', href: '/contato' },
|
|
||||||
{ text: 'FAQ', href: '/faq' },
|
|
||||||
{ text: 'Tutoriais', href: '/tutoriais' },
|
|
||||||
{ text: 'Estudos', href: '/estudos' },
|
|
||||||
{ text: 'Blog', href: '/blog' },
|
|
||||||
{ text: 'Webinars', href: '/webinars' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Empresa',
|
|
||||||
links: [
|
|
||||||
{ text: 'Sobre', href: '/sobre' },
|
|
||||||
{ text: 'Carreiras', href: '/carreiras' },
|
|
||||||
{ text: 'Imprensa', href: '/imprensa' },
|
|
||||||
{ text: 'Termos de Uso', href: '/termos' },
|
|
||||||
{ text: 'Privacidade', href: '/privacidade' },
|
|
||||||
{ text: 'Segurança', href: '/seguranca' },
|
|
||||||
{ text: 'Cookies', href: '/cookies' }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
const defaultSocialLinks: SocialLink[] = [
|
|
||||||
{ icon: Facebook, href: 'https://facebook.com/historiasmagicas', label: 'Facebook' },
|
|
||||||
{ icon: Instagram, href: 'https://instagram.com/historiasmagicas', label: 'Instagram' },
|
|
||||||
{ icon: Twitter, href: 'https://twitter.com/historiasmagicas', label: 'Twitter' },
|
|
||||||
{ icon: Youtube, href: 'https://youtube.com/historiasmagicas', label: 'Youtube' }
|
|
||||||
];
|
|
||||||
|
|
||||||
export function Footer({
|
|
||||||
columns = defaultColumns,
|
|
||||||
socialLinks = defaultSocialLinks,
|
|
||||||
copyrightText = '© 2024 Histórias Mágicas. Todos os direitos reservados.',
|
|
||||||
address = 'Rua das Histórias, 123 - São Paulo, SP',
|
|
||||||
email = 'contato@historiasmagicas.com.br',
|
|
||||||
phone = '(11) 4002-8922'
|
|
||||||
}: FooterProps) {
|
|
||||||
return (
|
|
||||||
<footer className="bg-gray-900 text-gray-400">
|
|
||||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
|
|
||||||
{/* Logo e Informações de Contato + Links de Navegação */}
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8 pb-8 border-b border-gray-800">
|
|
||||||
{/* Logo e Informações - Ocupa 1 coluna em telas grandes */}
|
|
||||||
<div className="lg:col-span-1 space-y-4">
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<BookOpen className="h-8 w-8 text-purple-500" />
|
|
||||||
<span className="text-xl font-bold text-white">Histórias Mágicas</span>
|
|
||||||
</div>
|
|
||||||
<p className="text-sm">
|
|
||||||
Transformando a educação através de histórias interativas e métodos cientificamente comprovados
|
|
||||||
</p>
|
|
||||||
<div className="space-y-2">
|
|
||||||
<div className="flex items-center gap-2 text-sm">
|
|
||||||
<MapPin className="h-4 w-4" />
|
|
||||||
<span>{address}</span>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-2 text-sm">
|
|
||||||
<Mail className="h-4 w-4" />
|
|
||||||
<a href={`mailto:${email}`} className="hover:text-white transition-colors">
|
|
||||||
{email}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-2 text-sm">
|
|
||||||
<Phone className="h-4 w-4" />
|
|
||||||
<a href={`tel:${phone}`} className="hover:text-white transition-colors">
|
|
||||||
{phone}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Links de Navegação - Ocupa 3 colunas em telas grandes */}
|
|
||||||
<div className="lg:col-span-3 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8">
|
|
||||||
{columns.map((column, index) => (
|
|
||||||
<div key={index} className="space-y-4">
|
|
||||||
<h4 className="text-white font-bold">{column.title}</h4>
|
|
||||||
<ul className="space-y-2">
|
|
||||||
{column.links.map((link, idx) => (
|
|
||||||
<li key={idx}>
|
|
||||||
<Link
|
|
||||||
to={link.href}
|
|
||||||
className="text-sm hover:text-white transition-colors"
|
|
||||||
>
|
|
||||||
{link.text}
|
|
||||||
</Link>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Copyright e Redes Sociais */}
|
|
||||||
<div className="pt-8 flex flex-col md:flex-row justify-between items-center gap-4">
|
|
||||||
<p className="text-sm text-center md:text-left">{copyrightText}</p>
|
|
||||||
|
|
||||||
<div className="flex gap-6">
|
|
||||||
{socialLinks.map((social, index) => {
|
|
||||||
const Icon = social.icon;
|
|
||||||
return (
|
|
||||||
<a
|
|
||||||
key={index}
|
|
||||||
href={social.href}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="text-gray-400 hover:text-white transition-colors"
|
|
||||||
aria-label={social.label}
|
|
||||||
>
|
|
||||||
<Icon className="h-5 w-5" />
|
|
||||||
</a>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,133 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { CheckCircle } from 'lucide-react';
|
|
||||||
|
|
||||||
interface PlanProps {
|
|
||||||
title: string;
|
|
||||||
description: string;
|
|
||||||
price: string;
|
|
||||||
period: string;
|
|
||||||
features: string[];
|
|
||||||
highlighted?: boolean;
|
|
||||||
commitment?: string;
|
|
||||||
onSubscribe?: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PlanForParentsProps {
|
|
||||||
title?: string;
|
|
||||||
description?: string;
|
|
||||||
plans?: PlanProps[];
|
|
||||||
}
|
|
||||||
|
|
||||||
const defaultPlans: PlanProps[] = [
|
|
||||||
{
|
|
||||||
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"
|
|
||||||
],
|
|
||||||
highlighted: 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"
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
export function PlanForParents({
|
|
||||||
title = "Planos Mágicos",
|
|
||||||
description = "Escolha o plano perfeito para a jornada mágica do seu filho",
|
|
||||||
plans = defaultPlans
|
|
||||||
}: PlanForParentsProps) {
|
|
||||||
return (
|
|
||||||
<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">
|
|
||||||
{title}
|
|
||||||
</h2>
|
|
||||||
<p className="text-center text-gray-600 mb-16 max-w-2xl mx-auto">
|
|
||||||
{description}
|
|
||||||
</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
|
|
||||||
${plan.highlighted ? '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>
|
|
||||||
{plan.commitment && (
|
|
||||||
<div className="text-sm text-purple-600 mt-1">
|
|
||||||
Plano {plan.commitment}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</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={plan.onSubscribe}
|
|
||||||
className={`
|
|
||||||
w-full py-4 rounded-xl font-medium transition-all
|
|
||||||
${plan.highlighted
|
|
||||||
? '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>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,118 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { CheckCircle } from 'lucide-react';
|
|
||||||
|
|
||||||
interface PlanProps {
|
|
||||||
title: string;
|
|
||||||
description: string;
|
|
||||||
price: string;
|
|
||||||
features: string[];
|
|
||||||
highlighted?: boolean;
|
|
||||||
onSubscribe?: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PlanForSchoolsProps {
|
|
||||||
title?: string;
|
|
||||||
description?: string;
|
|
||||||
plans?: PlanProps[];
|
|
||||||
}
|
|
||||||
|
|
||||||
const defaultPlans: PlanProps[] = [
|
|
||||||
{
|
|
||||||
title: "Escola Iniciante",
|
|
||||||
description: "Para escolas começando a transformação",
|
|
||||||
price: "997",
|
|
||||||
features: [
|
|
||||||
"Até 100 alunos",
|
|
||||||
"Método fônico estruturado",
|
|
||||||
"Relatórios básicos",
|
|
||||||
"Suporte por email"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Escola Transformadora",
|
|
||||||
description: "Para escolas comprometidas",
|
|
||||||
price: "1.997",
|
|
||||||
features: [
|
|
||||||
"Até 500 alunos",
|
|
||||||
"Método fônico completo",
|
|
||||||
"Relatórios avançados",
|
|
||||||
"Suporte prioritário",
|
|
||||||
"Treinamento da equipe",
|
|
||||||
"Consultoria pedagógica"
|
|
||||||
],
|
|
||||||
highlighted: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Rede de Ensino",
|
|
||||||
description: "Para redes de escolas",
|
|
||||||
price: "4.997",
|
|
||||||
features: [
|
|
||||||
"Alunos ilimitados",
|
|
||||||
"Sistema completo",
|
|
||||||
"Relatórios personalizados",
|
|
||||||
"Suporte 24/7",
|
|
||||||
"Treinamento completo",
|
|
||||||
"Consultoria dedicada"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
export function PlanForSchools({
|
|
||||||
title = "Invista em Educação Baseada em Evidências",
|
|
||||||
description = "Escolha o plano ideal para transformar a educação com base científica",
|
|
||||||
plans = defaultPlans
|
|
||||||
}: PlanForSchoolsProps) {
|
|
||||||
return (
|
|
||||||
<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">
|
|
||||||
{title}
|
|
||||||
</h2>
|
|
||||||
<p className="text-center text-gray-600 mb-16 max-w-2xl mx-auto">
|
|
||||||
{description}
|
|
||||||
</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
|
|
||||||
${plan.highlighted
|
|
||||||
? '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">/mês</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={plan.onSubscribe}
|
|
||||||
className={`
|
|
||||||
w-full py-4 rounded-xl font-medium transition-all
|
|
||||||
${plan.highlighted
|
|
||||||
? '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>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -6,8 +6,6 @@ import {
|
|||||||
Clock, Heart, Sparkles, ScrollText, Lock, X,
|
Clock, Heart, Sparkles, ScrollText, Lock, X,
|
||||||
Facebook, Instagram, Twitter, Youtube
|
Facebook, Instagram, Twitter, Youtube
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
import { Footer } from '@/components/ui/footer';
|
|
||||||
import { PlanForParents } from '@/components/ui/plan-for-parents';
|
|
||||||
|
|
||||||
export function EducationalForParents(): JSX.Element {
|
export function EducationalForParents(): JSX.Element {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@ -349,7 +347,81 @@ export function EducationalForParents(): JSX.Element {
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* 7. Planos */}
|
{/* 7. Planos */}
|
||||||
<PlanForParents />
|
<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 */}
|
{/* 8. FAQ */}
|
||||||
<section className="px-4 py-24 bg-white">
|
<section className="px-4 py-24 bg-white">
|
||||||
@ -404,8 +476,51 @@ export function EducationalForParents(): JSX.Element {
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Footer */}
|
{/* 10. Rodapé */}
|
||||||
<Footer />
|
<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>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -570,6 +685,56 @@ const testimonials = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
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 = [
|
const faqItems = [
|
||||||
{
|
{
|
||||||
question: "Como a magia da IA funciona?",
|
question: "Como a magia da IA funciona?",
|
||||||
|
|||||||
@ -1,584 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { useNavigate } from 'react-router-dom';
|
|
||||||
import {
|
|
||||||
ArrowRight,
|
|
||||||
BookOpen,
|
|
||||||
Brain,
|
|
||||||
CheckCircle,
|
|
||||||
Clock,
|
|
||||||
FileText,
|
|
||||||
GraduationCap,
|
|
||||||
Heart,
|
|
||||||
LineChart,
|
|
||||||
Lock,
|
|
||||||
School,
|
|
||||||
Search,
|
|
||||||
Shield,
|
|
||||||
Star,
|
|
||||||
Users,
|
|
||||||
X,
|
|
||||||
Facebook,
|
|
||||||
Instagram,
|
|
||||||
Twitter,
|
|
||||||
Youtube
|
|
||||||
} from 'lucide-react';
|
|
||||||
import { Footer } from '@/components/ui/footer';
|
|
||||||
import { PlanForSchools } from '@/components/ui/plan-for-schools';
|
|
||||||
|
|
||||||
// Meta tags e SEO
|
|
||||||
const meta = {
|
|
||||||
title: 'Histórias Mágicas | Alfabetização Baseada em Evidências',
|
|
||||||
description: 'Plataforma educacional que utiliza métodos cientificamente comprovados para alfabetização, combinando tecnologia e pedagogia baseada em evidências para resultados reais.',
|
|
||||||
keywords: 'alfabetização, evidências científicas, educação baseada em ciência, phonics, consciência fonológica, literatura infantil',
|
|
||||||
security: {
|
|
||||||
contentSecurityPolicy: "default-src 'self'; img-src 'self' data: https:; script-src 'self'",
|
|
||||||
strictTransportSecurity: 'max-age=31536000; includeSubDomains',
|
|
||||||
xFrameOptions: 'DENY'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export function EvidenceBased(): JSX.Element {
|
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
// Atualiza as meta tags
|
|
||||||
document.title = meta.title;
|
|
||||||
const metaDescription = document.querySelector('meta[name="description"]');
|
|
||||||
if (metaDescription) {
|
|
||||||
metaDescription.setAttribute('content', meta.description);
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="min-h-screen">
|
|
||||||
{/* 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/dots.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: 7 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">
|
|
||||||
Alfabetização
|
|
||||||
<span className="block bg-gradient-to-r from-purple-600 to-blue-500 bg-clip-text text-transparent">
|
|
||||||
Baseada em Evidências
|
|
||||||
</span>
|
|
||||||
</h1>
|
|
||||||
|
|
||||||
<p className="text-xl text-gray-600 leading-relaxed">
|
|
||||||
Transforme a educação com métodos cientificamente comprovados.
|
|
||||||
Nossa plataforma combina tecnologia e pedagogia baseada em evidências
|
|
||||||
para resultados reais e mensuráveis.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div className="flex gap-4">
|
|
||||||
<button
|
|
||||||
onClick={() => navigate('/register')}
|
|
||||||
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 com Base na Ciência
|
|
||||||
<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">
|
|
||||||
<Search className="h-5 w-5 text-purple-600" />
|
|
||||||
<span>Baseado em +50 estudos científicos</span>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<Users className="h-5 w-5 text-blue-500" />
|
|
||||||
<span>+10.000 alunos beneficiados</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/evidence-based.webp"
|
|
||||||
alt="Crianças aprendendo com métodos científicos"
|
|
||||||
className="relative rounded-2xl shadow-2xl transform hover:scale-[1.02]
|
|
||||||
transition-transform"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* 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">
|
|
||||||
O Problema da Alfabetização no Brasil
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<div className="grid md:grid-cols-2 gap-12">
|
|
||||||
{/* Problema */}
|
|
||||||
<div className="space-y-6">
|
|
||||||
<h3 className="text-2xl font-bold text-red-600">O Cenário Atual</h3>
|
|
||||||
<ul className="space-y-4">
|
|
||||||
{problems.map((problem, index) => (
|
|
||||||
<li key={index} className="flex items-start gap-3">
|
|
||||||
<X className="h-5 w-5 text-red-500 flex-shrink-0 mt-1" />
|
|
||||||
<span className="text-gray-600">{problem}</span>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Solução */}
|
|
||||||
<div className="space-y-6">
|
|
||||||
<h3 className="text-2xl font-bold text-green-600">Nossa Solução Científica</h3>
|
|
||||||
<ul className="space-y-4">
|
|
||||||
{solutions.map((solution, index) => (
|
|
||||||
<li key={index} className="flex items-start gap-3">
|
|
||||||
<CheckCircle className="h-5 w-5 text-green-500 flex-shrink-0 mt-1" />
|
|
||||||
<span className="text-gray-600">{solution}</span>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* Métodos Científicos */}
|
|
||||||
<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">
|
|
||||||
Métodos Cientificamente Comprovados
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
|
|
||||||
{scientificMethods.map((method, 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 gap-4">
|
|
||||||
<div className="w-12 h-12 flex items-center justify-center
|
|
||||||
bg-gradient-to-r from-purple-600 to-blue-500 rounded-full">
|
|
||||||
<method.icon className="h-6 w-6 text-white" />
|
|
||||||
</div>
|
|
||||||
<h3 className="text-xl font-bold text-gray-900">{method.title}</h3>
|
|
||||||
<p className="text-gray-600">{method.description}</p>
|
|
||||||
<div className="mt-4 p-3 bg-purple-50 rounded-lg">
|
|
||||||
<p className="text-sm text-purple-600">
|
|
||||||
<strong>Evidência:</strong> {method.evidence}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* 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">
|
|
||||||
Evidências vs. Pseudociência
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<div className="grid md:grid-cols-2 gap-8">
|
|
||||||
{/* Métodos Tradicionais */}
|
|
||||||
<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">
|
|
||||||
Métodos Sem Evidências
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ul className="space-y-4">
|
|
||||||
{nonScientificMethods.map((method, index) => (
|
|
||||||
<li key={index} className="flex items-start gap-3">
|
|
||||||
<X className="h-5 w-5 text-red-500 flex-shrink-0 mt-1" />
|
|
||||||
<div>
|
|
||||||
<h4 className="font-bold text-gray-900">{method.title}</h4>
|
|
||||||
<p className="text-gray-600">{method.description}</p>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Métodos Baseados em Evidências */}
|
|
||||||
<div className="p-8 bg-gradient-to-br from-purple-50 to-blue-50 rounded-xl
|
|
||||||
border-2 border-purple-200">
|
|
||||||
<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">
|
|
||||||
Métodos Científicos
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ul className="space-y-4">
|
|
||||||
{scientificAdvantages.map((advantage, index) => (
|
|
||||||
<li key={index} className="flex items-start gap-3">
|
|
||||||
<CheckCircle className="h-5 w-5 text-green-500 flex-shrink-0 mt-1" />
|
|
||||||
<div>
|
|
||||||
<h4 className="font-bold text-gray-900">{advantage.title}</h4>
|
|
||||||
<p className="text-gray-600">{advantage.description}</p>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* Benefícios */}
|
|
||||||
<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 Comprovados
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<div className="grid lg:grid-cols-3 gap-8">
|
|
||||||
{benefits.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 className="mt-4 p-3 bg-purple-50 rounded-lg w-full">
|
|
||||||
<p className="text-sm text-purple-600">
|
|
||||||
<strong>Resultado:</strong> {benefit.result}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* Depoimentos */}
|
|
||||||
<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">
|
|
||||||
Resultados Comprovados
|
|
||||||
</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="flex flex-col gap-4">
|
|
||||||
<div className="flex items-center gap-4">
|
|
||||||
<img
|
|
||||||
src={testimonial.image}
|
|
||||||
alt={testimonial.name}
|
|
||||||
className="w-16 h-16 rounded-full object-cover"
|
|
||||||
/>
|
|
||||||
<div>
|
|
||||||
<h3 className="font-bold text-gray-900">{testimonial.name}</h3>
|
|
||||||
<p className="text-sm text-gray-500">{testimonial.role}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p className="text-gray-600 italic">"{testimonial.text}"</p>
|
|
||||||
<div className="mt-4 p-3 bg-white rounded-lg">
|
|
||||||
<p className="text-sm text-purple-600">
|
|
||||||
<strong>Resultado:</strong> {testimonial.result}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* Planos */}
|
|
||||||
<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>
|
|
||||||
|
|
||||||
{/* 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">
|
|
||||||
Transforme a Educação com Base em Evidências
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<p className="text-xl opacity-90 mb-12">
|
|
||||||
Junte-se a milhares de educadores que já descobriram o poder da ciência na educação
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<button
|
|
||||||
onClick={() => navigate('/register')}
|
|
||||||
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"
|
|
||||||
>
|
|
||||||
Comece Agora com Base na Ciência
|
|
||||||
<ArrowRight className="inline-block ml-2 h-6 w-6" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<div className="mt-8 flex justify-center gap-8">
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<Lock className="h-5 w-5" />
|
|
||||||
<span className="text-sm">Ambiente Seguro</span>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<Shield className="h-5 w-5" />
|
|
||||||
<span className="text-sm">Métodos Comprovados</span>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<Star className="h-5 w-5" />
|
|
||||||
<span className="text-sm">Resultados Garantidos</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* Footer */}
|
|
||||||
<Footer />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dados
|
|
||||||
const problems = [
|
|
||||||
"54% das crianças não são plenamente alfabetizadas até o 3º ano",
|
|
||||||
"Uso de métodos sem comprovação científica",
|
|
||||||
"Falta de acompanhamento sistemático do progresso",
|
|
||||||
"Desmotivação e frustração no processo de aprendizagem"
|
|
||||||
];
|
|
||||||
|
|
||||||
const solutions = [
|
|
||||||
"Método fônico comprovado por estudos científicos",
|
|
||||||
"Sistema de progressão baseado em evidências",
|
|
||||||
"Acompanhamento detalhado com métricas reais",
|
|
||||||
"Engajamento através de histórias personalizadas"
|
|
||||||
];
|
|
||||||
|
|
||||||
const scientificMethods = [
|
|
||||||
{
|
|
||||||
icon: BookOpen,
|
|
||||||
title: "Método Fônico",
|
|
||||||
description: "Ensino sistemático das relações entre letras e sons, comprovadamente eficaz.",
|
|
||||||
evidence: "National Reading Panel (2000)"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: Brain,
|
|
||||||
title: "Consciência Fonológica",
|
|
||||||
description: "Desenvolvimento estruturado da percepção dos sons da língua.",
|
|
||||||
evidence: "Goswami & Bryant (1990)"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: GraduationCap,
|
|
||||||
title: "Literatura Infantil",
|
|
||||||
description: "Uso de histórias para desenvolvimento da linguagem e compreensão.",
|
|
||||||
evidence: "Mol & Bus (2011)"
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
const nonScientificMethods = [
|
|
||||||
{
|
|
||||||
title: "Método Global",
|
|
||||||
description: "Memorização de palavras inteiras sem compreensão fonológica"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Adivinhação de Palavras",
|
|
||||||
description: "Uso de dicas contextuais em detrimento da decodificação"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Aprendizado Natural",
|
|
||||||
description: "Espera pela descoberta espontânea sem instrução sistemática"
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
const scientificAdvantages = [
|
|
||||||
{
|
|
||||||
title: "Progressão Sistemática",
|
|
||||||
description: "Desenvolvimento gradual e estruturado das habilidades"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Resultados Mensuráveis",
|
|
||||||
description: "Acompanhamento objetivo do progresso do aluno"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Base Neurológica",
|
|
||||||
description: "Alinhado com o funcionamento do cérebro na leitura"
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
const benefits = [
|
|
||||||
{
|
|
||||||
icon: LineChart,
|
|
||||||
title: "Progresso Acelerado",
|
|
||||||
description: "Desenvolvimento 40% mais rápido que métodos tradicionais",
|
|
||||||
result: "85% dos alunos alfabetizados no tempo esperado"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: Brain,
|
|
||||||
title: "Compreensão Profunda",
|
|
||||||
description: "Entendimento real do sistema alfabético",
|
|
||||||
result: "93% de precisão na decodificação de palavras"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: Heart,
|
|
||||||
title: "Motivação Elevada",
|
|
||||||
description: "Alunos engajados e confiantes",
|
|
||||||
result: "95% de satisfação entre pais e professores"
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
const testimonials = [
|
|
||||||
{
|
|
||||||
image: "/images/teacher-1.webp",
|
|
||||||
name: "Profa. Maria Silva",
|
|
||||||
role: "Professora há 15 anos",
|
|
||||||
text: "Finalmente um método que realmente funciona! Os resultados são visíveis desde as primeiras semanas.",
|
|
||||||
result: "Turma 100% alfabetizada em 8 meses"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: "/images/director-1.webp",
|
|
||||||
name: "Dr. João Santos",
|
|
||||||
role: "Diretor Pedagógico",
|
|
||||||
text: "A diferença entre este método e os anteriores é a base científica sólida e os resultados consistentes.",
|
|
||||||
result: "Melhoria de 60% nos índices de alfabetização"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: "/images/parent-1.webp",
|
|
||||||
name: "Ana Costa",
|
|
||||||
role: "Mãe de aluno",
|
|
||||||
text: "Ver meu filho progredindo com confiança e entusiasmo é incrível. A diferença é notável!",
|
|
||||||
result: "Filho lendo fluentemente em 6 meses"
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
const plans = [
|
|
||||||
{
|
|
||||||
title: "Escola Iniciante",
|
|
||||||
description: "Para escolas começando a transformação",
|
|
||||||
price: "997",
|
|
||||||
features: [
|
|
||||||
"Até 100 alunos",
|
|
||||||
"Método fônico estruturado",
|
|
||||||
"Relatórios básicos",
|
|
||||||
"Suporte por email"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Escola Transformadora",
|
|
||||||
description: "Para escolas comprometidas",
|
|
||||||
price: "1.997",
|
|
||||||
features: [
|
|
||||||
"Até 500 alunos",
|
|
||||||
"Método fônico completo",
|
|
||||||
"Relatórios avançados",
|
|
||||||
"Suporte prioritário",
|
|
||||||
"Treinamento da equipe",
|
|
||||||
"Consultoria pedagógica"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Rede de Ensino",
|
|
||||||
description: "Para redes de escolas",
|
|
||||||
price: "4.997",
|
|
||||||
features: [
|
|
||||||
"Alunos ilimitados",
|
|
||||||
"Sistema completo",
|
|
||||||
"Relatórios personalizados",
|
|
||||||
"Suporte 24/7",
|
|
||||||
"Treinamento completo",
|
|
||||||
"Consultoria dedicada"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
const faqItems = [
|
|
||||||
{
|
|
||||||
question: "Por que métodos baseados em evidências são superiores?",
|
|
||||||
answer: "Métodos baseados em evidências são fundamentados em pesquisas científicas rigorosas, com resultados comprovados em diversos contextos educacionais."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
question: "Como é feito o acompanhamento do progresso?",
|
|
||||||
answer: "Utilizamos métricas objetivas e avaliações sistemáticas, permitindo visualizar o progresso real de cada aluno em diferentes aspectos da alfabetização."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
question: "Qual é o papel da tecnologia no método?",
|
|
||||||
answer: "A tecnologia atua como facilitadora, permitindo personalização do ensino, coleta de dados precisos e adaptação contínua às necessidades de cada aluno."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
question: "Como os professores são preparados?",
|
|
||||||
answer: "Oferecemos treinamento completo baseado em evidências, com suporte contínuo e materiais estruturados para implementação eficaz do método."
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
const footerLinks = [
|
|
||||||
{
|
|
||||||
title: "Produto",
|
|
||||||
links: [
|
|
||||||
{ text: "Método Científico", href: "#metodo" },
|
|
||||||
{ text: "Resultados", href: "#resultados" },
|
|
||||||
{ text: "Planos", href: "#planos" },
|
|
||||||
{ text: "Cases", href: "#cases" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Recursos",
|
|
||||||
links: [
|
|
||||||
{ text: "Base Científica", href: "#ciencia" },
|
|
||||||
{ text: "Estudos", href: "#estudos" },
|
|
||||||
{ text: "Blog", href: "#blog" },
|
|
||||||
{ text: "Webinars", href: "#webinars" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Empresa",
|
|
||||||
links: [
|
|
||||||
{ text: "Sobre", href: "#sobre" },
|
|
||||||
{ text: "Contato", href: "#contato" },
|
|
||||||
{ text: "Carreiras", href: "#carreiras" },
|
|
||||||
{ text: "Imprensa", href: "#imprensa" }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
const socialLinks = [
|
|
||||||
{ icon: Facebook, href: "https://facebook.com" },
|
|
||||||
{ icon: Instagram, href: "https://instagram.com" },
|
|
||||||
{ icon: Twitter, href: "https://twitter.com" },
|
|
||||||
{ icon: Youtube, href: "https://youtube.com" }
|
|
||||||
];
|
|
||||||
@ -2,8 +2,6 @@ import React from 'react';
|
|||||||
import { ArrowRight, BookOpen, Brain, Target, Clock, Shield, Check, X } from 'lucide-react';
|
import { ArrowRight, BookOpen, Brain, Target, Clock, Shield, Check, X } from 'lucide-react';
|
||||||
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
|
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { Footer } from '@/components/ui/footer';
|
|
||||||
import { PlanForParents } from '@/components/ui/plan-for-parents';
|
|
||||||
|
|
||||||
export function ParentsLandingPage(): JSX.Element {
|
export function ParentsLandingPage(): JSX.Element {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@ -277,8 +275,6 @@ export function ParentsLandingPage(): JSX.Element {
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{/* 5. A Diferença que Faz */}
|
{/* 5. A Diferença que Faz */}
|
||||||
<section className="px-4 py-24">
|
<section className="px-4 py-24">
|
||||||
<div className="mx-auto max-w-7xl">
|
<div className="mx-auto max-w-7xl">
|
||||||
@ -400,9 +396,6 @@ export function ParentsLandingPage(): JSX.Element {
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* 5. Planos */}
|
|
||||||
<PlanForParents />
|
|
||||||
|
|
||||||
{/* 7. CTA Final */}
|
{/* 7. CTA Final */}
|
||||||
<section className="px-4 py-24 relative overflow-hidden">
|
<section className="px-4 py-24 relative overflow-hidden">
|
||||||
<div className="absolute inset-0 bg-gradient-to-b from-purple-50 to-purple-100 opacity-50" />
|
<div className="absolute inset-0 bg-gradient-to-b from-purple-50 to-purple-100 opacity-50" />
|
||||||
@ -430,9 +423,6 @@ export function ParentsLandingPage(): JSX.Element {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Footer */}
|
|
||||||
<Footer />
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,7 +30,6 @@ import { ParentsLandingPage } from './pages/landing/ParentsLandingPage';
|
|||||||
import { EducationalForParents } from './pages/landing/EducationalForParents';
|
import { EducationalForParents } from './pages/landing/EducationalForParents';
|
||||||
import { TestWordHighlighter } from './pages/TestWordHighlighter';
|
import { TestWordHighlighter } from './pages/TestWordHighlighter';
|
||||||
import { ExercisePage } from './pages/student-dashboard/ExercisePage';
|
import { ExercisePage } from './pages/student-dashboard/ExercisePage';
|
||||||
import { EvidenceBased } from './pages/landing/EvidenceBased';
|
|
||||||
|
|
||||||
export const router = createBrowserRouter([
|
export const router = createBrowserRouter([
|
||||||
{
|
{
|
||||||
@ -45,10 +44,6 @@ export const router = createBrowserRouter([
|
|||||||
path: '/para-pais',
|
path: '/para-pais',
|
||||||
element: <ParentsLandingPage />,
|
element: <ParentsLandingPage />,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: '/evidencias',
|
|
||||||
element: <EvidenceBased />,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: '/login',
|
path: '/login',
|
||||||
children: [
|
children: [
|
||||||
|
|||||||
@ -1,41 +1,37 @@
|
|||||||
// Interfaces Base
|
export interface School {
|
||||||
export interface BaseEntity {
|
|
||||||
id: string;
|
id: string;
|
||||||
|
name: string;
|
||||||
|
address?: string;
|
||||||
|
phone?: string;
|
||||||
|
email?: string;
|
||||||
created_at: string;
|
created_at: string;
|
||||||
updated_at: string;
|
updated_at: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface School extends BaseEntity {
|
export interface Teacher {
|
||||||
name: string;
|
id: string;
|
||||||
email: string;
|
|
||||||
phone?: string;
|
|
||||||
address?: string;
|
|
||||||
city?: string;
|
|
||||||
state?: string;
|
|
||||||
zip_code?: string;
|
|
||||||
director_name?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Teacher extends BaseEntity {
|
|
||||||
school_id: string;
|
school_id: string;
|
||||||
name: string;
|
name: string;
|
||||||
email: string;
|
email: string;
|
||||||
phone?: string;
|
phone?: string;
|
||||||
subject?: string;
|
subject?: string;
|
||||||
|
created_at: string;
|
||||||
|
updated_at: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Class extends BaseEntity {
|
export interface Class {
|
||||||
|
id: string;
|
||||||
school_id: string;
|
school_id: string;
|
||||||
name: string;
|
name: string;
|
||||||
grade: string;
|
grade: string;
|
||||||
year: number;
|
year: number;
|
||||||
period?: string;
|
period?: string;
|
||||||
students?: {
|
created_at: string;
|
||||||
count: number;
|
updated_at: string;
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Student extends BaseEntity {
|
export interface Student {
|
||||||
|
id: string;
|
||||||
class_id: string;
|
class_id: string;
|
||||||
school_id: string;
|
school_id: string;
|
||||||
name: string;
|
name: string;
|
||||||
@ -44,8 +40,11 @@ export interface Student extends BaseEntity {
|
|||||||
guardian_name?: string;
|
guardian_name?: string;
|
||||||
guardian_phone?: string;
|
guardian_phone?: string;
|
||||||
guardian_email?: string;
|
guardian_email?: string;
|
||||||
|
created_at: string;
|
||||||
|
updated_at: string;
|
||||||
|
status?: string;
|
||||||
avatar_url?: string;
|
avatar_url?: string;
|
||||||
status: 'active' | 'inactive';
|
// Relacionamentos
|
||||||
class?: {
|
class?: {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
@ -55,60 +54,13 @@ export interface Student extends BaseEntity {
|
|||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
};
|
};
|
||||||
interests?: Interest[];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TeacherClass extends BaseEntity {
|
export interface TeacherClass {
|
||||||
|
id: string;
|
||||||
teacher_id: string;
|
teacher_id: string;
|
||||||
class_id: string;
|
class_id: string;
|
||||||
}
|
created_at: string;
|
||||||
|
|
||||||
export interface StoryPage {
|
|
||||||
text: string;
|
|
||||||
image?: string;
|
|
||||||
audio?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Story extends BaseEntity {
|
|
||||||
student_id: string;
|
|
||||||
class_id: string;
|
|
||||||
school_id: string;
|
|
||||||
title: string;
|
|
||||||
theme: string;
|
|
||||||
content: {
|
|
||||||
pages: StoryPage[];
|
|
||||||
currentPage?: number;
|
|
||||||
lastModified?: string;
|
|
||||||
};
|
|
||||||
status: 'draft' | 'published' | 'archived';
|
|
||||||
cover: {
|
|
||||||
id: string;
|
|
||||||
image_url: string;
|
|
||||||
};
|
|
||||||
students?: {
|
|
||||||
name: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface StoryRecording extends BaseEntity {
|
|
||||||
fluency_score: number;
|
|
||||||
pronunciation_score: number;
|
|
||||||
accuracy_score: number;
|
|
||||||
comprehension_score: number;
|
|
||||||
words_per_minute: number;
|
|
||||||
pause_count: number;
|
|
||||||
error_count: number;
|
|
||||||
self_corrections: number;
|
|
||||||
strengths: string[];
|
|
||||||
improvements: string[];
|
|
||||||
suggestions: string;
|
|
||||||
processed_at: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Interest extends BaseEntity {
|
|
||||||
student_id: string;
|
|
||||||
category: string;
|
|
||||||
items: string[];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tipos para relacionamentos
|
// Tipos para relacionamentos
|
||||||
@ -125,15 +77,7 @@ export interface TeacherWithClassesAndStories extends Teacher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ClassWithStudents extends Class {
|
export interface ClassWithStudents extends Class {
|
||||||
students: Student[] & { count: number };
|
students: Student[];
|
||||||
}
|
|
||||||
|
|
||||||
export interface StudentWithStories extends Student {
|
|
||||||
stories: Story[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ClassWithStudentsAndStories extends Class {
|
|
||||||
students: StudentWithStories[] & { count: number };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interface base para School com relações
|
// Interface base para School com relações
|
||||||
@ -141,16 +85,144 @@ interface BaseSchoolWithRelations extends School {
|
|||||||
teachers: Teacher[];
|
teachers: Teacher[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Interface específica para School com Classes e Students
|
||||||
export interface SchoolWithClasses extends BaseSchoolWithRelations {
|
export interface SchoolWithClasses extends BaseSchoolWithRelations {
|
||||||
classes: ClassWithStudents[];
|
classes: ClassWithStudents[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Interface específica para School com Classes, Students e Stories
|
||||||
export interface SchoolWithClassesAndStories extends BaseSchoolWithRelations {
|
export interface SchoolWithClassesAndStories extends BaseSchoolWithRelations {
|
||||||
classes: ClassWithStudentsAndStories[];
|
classes: ClassWithStudentsAndStories[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Removendo a interface duplicada e usando as novas interfaces específicas
|
||||||
export type SchoolWithRelations = SchoolWithClasses | SchoolWithClassesAndStories;
|
export type SchoolWithRelations = SchoolWithClasses | SchoolWithClassesAndStories;
|
||||||
|
|
||||||
|
export interface StoryPage {
|
||||||
|
text: string;
|
||||||
|
image?: string;
|
||||||
|
audio?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Story {
|
||||||
|
cover: any;
|
||||||
|
id: string;
|
||||||
|
student_id: string;
|
||||||
|
class_id: string;
|
||||||
|
school_id: string;
|
||||||
|
title: string;
|
||||||
|
theme: string;
|
||||||
|
content: {
|
||||||
|
pages: StoryPage[];
|
||||||
|
currentPage?: number;
|
||||||
|
lastModified?: string;
|
||||||
|
};
|
||||||
|
status: 'draft' | 'published' | 'archived';
|
||||||
|
created_at: string;
|
||||||
|
updated_at: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Atualizando a interface Student para incluir histórias
|
||||||
|
export interface StudentWithStories extends Student {
|
||||||
|
stories: Story[];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Atualizando ClassWithStudents para incluir histórias dos alunos
|
||||||
|
export interface ClassWithStudentsAndStories extends Class {
|
||||||
|
students: StudentWithStories[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StoryRecording {
|
||||||
|
id: string;
|
||||||
|
fluency_score: number;
|
||||||
|
pronunciation_score: number;
|
||||||
|
accuracy_score: number;
|
||||||
|
comprehension_score: number;
|
||||||
|
words_per_minute: number;
|
||||||
|
pause_count: number;
|
||||||
|
error_count: number;
|
||||||
|
self_corrections: number;
|
||||||
|
strengths: string[];
|
||||||
|
improvements: string[];
|
||||||
|
suggestions: string;
|
||||||
|
created_at: string;
|
||||||
|
processed_at: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Interest {
|
||||||
|
id: string;
|
||||||
|
student_id: string;
|
||||||
|
category: string;
|
||||||
|
items: string[];
|
||||||
|
created_at: string;
|
||||||
|
updated_at: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Student {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
email: string;
|
||||||
|
avatar_url?: string;
|
||||||
|
class_id: string;
|
||||||
|
school_id: string;
|
||||||
|
status: 'active' | 'inactive';
|
||||||
|
created_at: string;
|
||||||
|
updated_at: string;
|
||||||
|
interests?: Interest[];
|
||||||
|
class?: {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
grade: string;
|
||||||
|
};
|
||||||
|
school?: {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Story {
|
||||||
|
id: string;
|
||||||
|
title: string;
|
||||||
|
content: string;
|
||||||
|
student_id: string;
|
||||||
|
status: 'draft' | 'published';
|
||||||
|
created_at: string;
|
||||||
|
updated_at: string;
|
||||||
|
cover?: {
|
||||||
|
id: string;
|
||||||
|
image_url: string;
|
||||||
|
};
|
||||||
|
students?: {
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Class {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
grade: string;
|
||||||
|
school_id: string;
|
||||||
|
created_at: string;
|
||||||
|
updated_at: string;
|
||||||
|
students?: {
|
||||||
|
count: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface School {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
email: string;
|
||||||
|
phone?: string;
|
||||||
|
address?: string;
|
||||||
|
city?: string;
|
||||||
|
state?: string;
|
||||||
|
zip_code?: string;
|
||||||
|
director_name?: string;
|
||||||
|
created_at: string;
|
||||||
|
updated_at: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface SchoolSettings {
|
export interface SchoolSettings {
|
||||||
name: string;
|
name: string;
|
||||||
email: string;
|
email: string;
|
||||||
|
|||||||
@ -1,6 +1,4 @@
|
|||||||
[project]
|
project_id = "bsjlbnyslxzsdwxvkaap"
|
||||||
id = "bsjlbnyslxzsdwxvkaap"
|
|
||||||
name = "Histórias Mágicas"
|
|
||||||
|
|
||||||
[auth]
|
[auth]
|
||||||
enabled = true
|
enabled = true
|
||||||
@ -22,65 +20,3 @@ secure_password_change = false
|
|||||||
max_frequency = "1m0s"
|
max_frequency = "1m0s"
|
||||||
otp_length = 6
|
otp_length = 6
|
||||||
otp_expiry = 86400
|
otp_expiry = 86400
|
||||||
|
|
||||||
[auth.external]
|
|
||||||
enabled = true
|
|
||||||
providers = ["google"]
|
|
||||||
|
|
||||||
[auth.external.google]
|
|
||||||
enabled = true
|
|
||||||
client_id = "your-client-id"
|
|
||||||
secret = "your-client-secret"
|
|
||||||
redirect_uri = "https://historiasmagicas.netlify.app/auth/callback"
|
|
||||||
|
|
||||||
[storage]
|
|
||||||
enabled = true
|
|
||||||
file_size_limit = "50MB"
|
|
||||||
|
|
||||||
[storage.cors]
|
|
||||||
allowed_origins = ["*"]
|
|
||||||
allowed_methods = ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
|
|
||||||
allowed_headers = ["*"]
|
|
||||||
exposed_headers = ["Content-Range", "Range"]
|
|
||||||
max_age = 3600
|
|
||||||
|
|
||||||
[api]
|
|
||||||
enabled = true
|
|
||||||
port = 54321
|
|
||||||
schemas = ["public", "storage", "auth"]
|
|
||||||
extra_search_path = ["public", "extensions"]
|
|
||||||
max_rows = 1000
|
|
||||||
|
|
||||||
[api.cors]
|
|
||||||
enabled = true
|
|
||||||
allowed_origins = ["*"]
|
|
||||||
allowed_methods = ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
|
|
||||||
allowed_headers = ["*"]
|
|
||||||
exposed_headers = ["Content-Range", "Range"]
|
|
||||||
max_age = 3600
|
|
||||||
|
|
||||||
[db]
|
|
||||||
port = 54322
|
|
||||||
shadow_port = 54320
|
|
||||||
major_version = 15
|
|
||||||
|
|
||||||
[db.pooler]
|
|
||||||
enabled = false
|
|
||||||
port = 54329
|
|
||||||
pool_mode = "transaction"
|
|
||||||
default_pool_size = 15
|
|
||||||
max_client_conn = 100
|
|
||||||
|
|
||||||
[studio]
|
|
||||||
enabled = true
|
|
||||||
port = 54323
|
|
||||||
api_url = "https://historiasmagicas.netlify.app"
|
|
||||||
|
|
||||||
[inbucket]
|
|
||||||
enabled = true
|
|
||||||
port = 54324
|
|
||||||
smtp_port = 54325
|
|
||||||
pop3_port = 54326
|
|
||||||
|
|
||||||
[storage.backend]
|
|
||||||
enabled = true
|
|
||||||
|
|||||||
@ -6,32 +6,6 @@ export default {
|
|||||||
fontFamily: {
|
fontFamily: {
|
||||||
sans: ['Inter', 'sans-serif'],
|
sans: ['Inter', 'sans-serif'],
|
||||||
},
|
},
|
||||||
colors: {
|
|
||||||
purple: {
|
|
||||||
50: '#f5f3ff',
|
|
||||||
100: '#ede9fe',
|
|
||||||
200: '#ddd6fe',
|
|
||||||
300: '#c4b5fd',
|
|
||||||
400: '#a78bfa',
|
|
||||||
500: '#8b5cf6',
|
|
||||||
600: '#7c3aed',
|
|
||||||
700: '#6d28d9',
|
|
||||||
800: '#5b21b6',
|
|
||||||
900: '#4c1d95',
|
|
||||||
},
|
|
||||||
blue: {
|
|
||||||
50: '#eff6ff',
|
|
||||||
100: '#dbeafe',
|
|
||||||
200: '#bfdbfe',
|
|
||||||
300: '#93c5fd',
|
|
||||||
400: '#60a5fa',
|
|
||||||
500: '#3b82f6',
|
|
||||||
600: '#2563eb',
|
|
||||||
700: '#1d4ed8',
|
|
||||||
800: '#1e40af',
|
|
||||||
900: '#1e3a8a',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
animation: {
|
animation: {
|
||||||
'in': 'in 200ms ease-in',
|
'in': 'in 200ms ease-in',
|
||||||
'out': 'out 200ms ease-out',
|
'out': 'out 200ms ease-out',
|
||||||
@ -40,8 +14,6 @@ export default {
|
|||||||
'slide-out-to-right': 'slide-out-to-right 200ms ease-out',
|
'slide-out-to-right': 'slide-out-to-right 200ms ease-out',
|
||||||
'fade-in': 'fade-in 200ms ease-in',
|
'fade-in': 'fade-in 200ms ease-in',
|
||||||
'fade-out': 'fade-out 200ms ease-out',
|
'fade-out': 'fade-out 200ms ease-out',
|
||||||
'scale-in': 'scale-in 200ms ease-out',
|
|
||||||
'scale-out': 'scale-out 200ms ease-in',
|
|
||||||
},
|
},
|
||||||
keyframes: {
|
keyframes: {
|
||||||
in: {
|
in: {
|
||||||
@ -72,14 +44,6 @@ export default {
|
|||||||
'0%': { opacity: 1 },
|
'0%': { opacity: 1 },
|
||||||
'100%': { opacity: 0 },
|
'100%': { opacity: 0 },
|
||||||
},
|
},
|
||||||
'scale-in': {
|
|
||||||
'0%': { transform: 'scale(0.95)', opacity: 0 },
|
|
||||||
'100%': { transform: 'scale(1)', opacity: 1 },
|
|
||||||
},
|
|
||||||
'scale-out': {
|
|
||||||
'0%': { transform: 'scale(1)', opacity: 1 },
|
|
||||||
'100%': { transform: 'scale(0.95)', opacity: 0 },
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -14,12 +14,9 @@
|
|||||||
"noUnusedLocals": false,
|
"noUnusedLocals": false,
|
||||||
"noUnusedParameters": false,
|
"noUnusedParameters": false,
|
||||||
"noFallthroughCasesInSwitch": true,
|
"noFallthroughCasesInSwitch": true,
|
||||||
"baseUrl": ".",
|
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": ["./src/*"]
|
"@/*": ["./src/*"]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"types": ["vite/client", "node"]
|
"include": ["src"]
|
||||||
},
|
|
||||||
"include": ["src"],
|
|
||||||
"references": [{ "path": "./tsconfig.node.json" }]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,13 +18,11 @@ export default defineConfig({
|
|||||||
input: {
|
input: {
|
||||||
main: path.resolve(__dirname, 'index.html')
|
main: path.resolve(__dirname, 'index.html')
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
assetsInlineLimit: 0,
|
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
'node-fetch': 'isomorphic-fetch',
|
'node-fetch': 'isomorphic-fetch'
|
||||||
'@': path.resolve(__dirname, './src'),
|
|
||||||
},
|
},
|
||||||
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json']
|
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json']
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,36 +1,9 @@
|
|||||||
import { defineConfig } from 'vitest/config'
|
import { defineConfig } from 'vitest/config'
|
||||||
import react from '@vitejs/plugin-react'
|
|
||||||
import path from 'path'
|
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [react()],
|
|
||||||
test: {
|
test: {
|
||||||
globals: true,
|
globals: true,
|
||||||
environment: 'jsdom',
|
environment: 'jsdom',
|
||||||
setupFiles: ['./src/test/setup.ts'],
|
setupFiles: ['./src/test/setup.ts'],
|
||||||
include: ['**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
|
||||||
exclude: ['node_modules', 'dist', '.idea', '.git', '.cache'],
|
|
||||||
coverage: {
|
|
||||||
provider: 'v8',
|
|
||||||
reporter: ['text', 'json', 'html'],
|
|
||||||
exclude: [
|
|
||||||
'coverage/**',
|
|
||||||
'dist/**',
|
|
||||||
'**/[.]**',
|
|
||||||
'packages/*/test{,s}/**',
|
|
||||||
'**/*.d.ts',
|
|
||||||
'test{,s}/**',
|
|
||||||
'test{,-*}.{js,cjs,mjs,ts,tsx,jsx}',
|
|
||||||
'**/*{.,-}test.{js,cjs,mjs,ts,tsx,jsx}',
|
|
||||||
'**/*{.,-}spec.{js,cjs,mjs,ts,tsx,jsx}',
|
|
||||||
'**/__tests__/**',
|
|
||||||
'**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress}.config.*',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
resolve: {
|
|
||||||
alias: {
|
|
||||||
'@': path.resolve(__dirname, './src'),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
Loading…
Reference in New Issue
Block a user