Páginas - Frontend FinBoost+
Visão Geral
As páginas do FinBoost+ seguem arquitetura SPA com React Router, implementando lazy loading e padrões consistentes para melhor performance e manutenibilidade.
Estrutura de Roteamento
Rotas Públicas
/login
- Página de login/register
- Página de cadastro/forgot-password
- Recuperação de senha
Rotas Protegidas
/dashboard
- Dashboard principal/groups
- Listagem de grupos/groups/:groupId
- Detalhes do grupo/profile
- Perfil do usuário/expenses
- Todas as despesas
Páginas Principais
Propósito: Visão geral das finanças com resumos e gráficos.
Componentes: SummaryCards
, ChartSwitcher
, LatestExpenses
, UserGreeting
const Dashboard = () => {
const { user } = useAuth();
const { summary, loading } = useDashboardData();
if (loading) return <Loading />;
return (
<div className="dashboard-container">
<UserGreeting user={user} />
<SummaryCards data={summary} />
<div className="grid lg:grid-cols-2 gap-6">
<ChartSwitcher data={summary.chartData} />
<LatestExpenses limit={10} />
</div>
</div>
);
};
Login: Autenticação com validação em tempo real
// Validação
{
email: z.string().email("Email inválido"),
password: z.string().min(6, "Mínimo 6 caracteres")
}
Register: Cadastro com validação de senha forte - Senha: mínimo 8 caracteres, maiúscula, número, símbolo - Confirmação de senha obrigatória - Termos de uso (checkbox)
Propósito: Gestão de grupos de despesas
Features: Grid responsivo, filtros avançados, busca, ações rápidas
Estados: Ativo, Inativo, Arquivado
Componentes: GroupCard
, GroupForm
, GroupFilters
Profile: Informações pessoais, estatísticas, configurações
Expenses: Lista paginada com filtros (período, categoria, grupo, valor)
Padrões de Implementação
Lazy Loading & Suspense
// Lazy Loading
const Dashboard = lazy(() => import('../pages/Dashboard'));
// Suspense Boundary
<Suspense fallback={<Loading />}>
<Outlet />
</Suspense>
Data Fetching Padrão
const MyPage = () => {
const { data, loading, error } = usePageData();
if (loading) return <PageSkeleton />;
if (error) return <ErrorState error={error} />;
return <PageContent data={data} />;
};
React Router Loaders
Loader para dados pré-renderização
export const groupDetailsLoader = async ({ params }) => {
const groupId = params.groupId;
try {
const [group, members, expenses] = await Promise.all([
groupsService.getById(groupId),
groupsService.getMembers(groupId),
expensesService.getByGroup(groupId)
]);
return { group, members, expenses };
} catch (error) {
throw new Response("Grupo não encontrado", { status: 404 });
}
};
Actions para Formulários
export const loginAction = async ({ request }) => {
const formData = await request.formData();
const credentials = {
email: formData.get('email'),
password: formData.get('password')
};
try {
await authService.login(credentials);
return redirect('/dashboard');
} catch (error) {
return { error: error.message };
}
};
Layout e Templates
Layout Principal
const Layout = () => (
<div className="min-h-screen bg-gray-50 dark:bg-gray-900">
<Header />
<main className="container mx-auto px-4 py-8">
<Suspense fallback={<Loading />}>
<Outlet />
</Suspense>
</main>
<Toast />
</div>
);
Page Template Reutilizável
const PageTemplate = ({ title, actions, children }) => (
<div className="page-container">
<PageHeader title={title} actions={actions} />
<div className="page-content">
{children}
</div>
</div>
);
Otimizações
Performance
SEO e Acessibilidade
// Meta tags dinâmicas
useEffect(() => {
document.title = `${group.name} - FinBoost+`;
}, [group]);
// Estrutura semântica
<div>
<header>
<h1>Título da Página</h1>
<nav aria-label="Breadcrumb">
<Breadcrumb />
</nav>
</header>
<main>
<section aria-labelledby="main-content">
<h2 id="main-content">Conteúdo Principal</h2>
</section>
</main>
</div>
Testes
Padrão de Teste
Resumo
As páginas seguem padrões consistentes priorizando performance, acessibilidade e experiência do usuário. A arquitetura modular facilita manutenção e expansão.