Update src/app/dashboard/page.tsx

This commit is contained in:
2026-03-11 20:53:12 +00:00
parent a9b28fe88f
commit 0ddac07cbe

View File

@@ -1,13 +1,13 @@
"use client";
import { useEffect, useState } from 'react';
import { useRouter } from 'next/navigation';
import { ThemeProvider } from '@/providers/themeProvider/ThemeProvider';
import { useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarStyleCentered from '@/components/navbar/NavbarStyleCentered/NavbarStyleCentered';
import FooterBase from '@/components/sections/footer/FooterBase';
import { LogOut, User, Settings } from 'lucide-react';
import { LogOut, User, Mail, Zap } from 'lucide-react';
interface User {
interface UserData {
id: string;
name: string;
email: string;
@@ -15,34 +15,48 @@ interface User {
export default function DashboardPage() {
const router = useRouter();
const [user, setUser] = useState<User | null>(null);
const [user, setUser] = useState<UserData | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState("");
useEffect(() => {
// Check if user is authenticated
const token = localStorage.getItem('token');
const userData = localStorage.getItem('user');
const checkAuth = async () => {
const token = localStorage.getItem("authToken");
const userData = localStorage.getItem("user");
if (!token) {
router.push('/auth');
return;
}
if (!token || !userData) {
router.push("/auth/login");
return;
}
if (userData) {
setUser(JSON.parse(userData));
}
setLoading(false);
try {
const response = await fetch("/api/auth/verify", {
headers: { Authorization: `Bearer ${token}` },
});
if (!response.ok) {
localStorage.removeItem("authToken");
localStorage.removeItem("user");
router.push("/auth/login");
return;
}
setUser(JSON.parse(userData));
} catch (err) {
setError("Erro ao verificar sessão");
console.error(err);
} finally {
setLoading(false);
}
};
checkAuth();
}, [router]);
const handleLogout = async () => {
try {
await fetch('/api/auth/logout', { method: 'POST' });
localStorage.removeItem('token');
localStorage.removeItem('user');
router.push('/');
} catch (error) {
console.error('Logout failed:', error);
}
const handleLogout = () => {
localStorage.removeItem("authToken");
localStorage.removeItem("user");
router.push("/");
};
if (loading) {
@@ -59,10 +73,33 @@ export default function DashboardPage() {
secondaryButtonStyle="glass"
headingFontWeight="extrabold"
>
<div className="flex items-center justify-center min-h-screen">
<div className="min-h-screen flex items-center justify-center">
<div className="text-center">
<div className="w-12 h-12 border-4 border-primary-cta border-t-transparent rounded-full animate-spin mx-auto mb-4" />
<p className="text-foreground/60">Carregando...</p>
<div className="inline-block animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-primary-cta"></div>
<p className="mt-4 text-foreground/60">Carregando...</p>
</div>
</div>
</ThemeProvider>
);
}
if (error) {
return (
<ThemeProvider
defaultButtonVariant="elastic-effect"
defaultTextAnimation="entrance-slide"
borderRadius="pill"
contentWidth="smallMedium"
sizing="mediumSizeLargeTitles"
background="blurBottom"
cardStyle="gradient-bordered"
primaryButtonStyle="flat"
secondaryButtonStyle="glass"
headingFontWeight="extrabold"
>
<div className="min-h-screen flex items-center justify-center">
<div className="text-center">
<p className="text-red-500">{error}</p>
</div>
</div>
</ThemeProvider>
@@ -91,92 +128,82 @@ export default function DashboardPage() {
{ name: "Comunidade", id: "community" },
{ name: "Perfil", id: "profile" }
]}
button={{ text: "Sair", onClick: handleLogout }}
button={{ text: "Sair", href: "/" }}
brandName="FitFlow Pro"
/>
</div>
<div className="min-h-screen bg-background py-12 px-4 sm:px-6 lg:px-8">
<div className="min-h-screen px-4 py-20">
<div className="max-w-4xl mx-auto">
{/* Welcome Section */}
<div className="mb-8">
<h1 className="text-4xl font-extrabold text-foreground mb-2">
Bem-vindo de volta, {user?.name}!
</h1>
<p className="text-foreground/60">Aqui está seu dashboard pessoal de fitness</p>
</div>
<h1 className="text-4xl font-bold mb-8">Dashboard</h1>
{/* Quick Stats Grid */}
<div className="grid grid-cols-1 md:grid-cols-4 gap-4 mb-8">
{[
{ label: 'Treinos', value: '24', icon: '💪' },
{ label: 'Calorias', value: '2.4k', icon: '🔥' },
{ label: 'Passos', value: '15.2k', icon: '👣' },
{ label: 'Sequência', value: '7 dias', icon: '🔥' },
].map((stat, idx) => (
<div key={idx} className="bg-card rounded-lg p-6 border border-background-accent">
<div className="text-3xl mb-2">{stat.icon}</div>
<p className="text-foreground/60 text-sm mb-1">{stat.label}</p>
<p className="text-2xl font-bold text-foreground">{stat.value}</p>
</div>
))}
</div>
{/* Main Content */}
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
{/* User Profile Card */}
<div className="lg:col-span-1">
<div className="bg-card rounded-lg p-6 border border-background-accent">
<div className="flex items-center justify-center w-16 h-16 rounded-full bg-primary-cta/10 mb-4">
<User className="w-8 h-8 text-primary-cta" />
</div>
<h2 className="text-xl font-bold text-foreground mb-1">{user?.name}</h2>
<p className="text-foreground/60 text-sm mb-6">{user?.email}</p>
<button className="w-full py-2 px-4 bg-secondary-cta text-foreground rounded-lg hover:opacity-90 transition flex items-center justify-center gap-2">
<Settings className="w-4 h-4" />
Configurações
</button>
</div>
</div>
{/* Recent Activity */}
<div className="lg:col-span-2">
<div className="bg-card rounded-lg p-6 border border-background-accent">
<h3 className="text-lg font-bold text-foreground mb-4">Atividade Recente</h3>
<div className="space-y-4">
{[
{ title: 'Treino de Perna', time: 'Hoje às 10:30', status: '✅' },
{ title: 'Corida Matinal', time: 'Ontem às 06:00', status: '✅' },
{ title: 'Treino de Costas', time: '2 dias atrás', status: '✅' },
].map((activity, idx) => (
<div key={idx} className="flex items-center justify-between pb-4 border-b border-background-accent last:border-0 last:pb-0">
{user && (
<div className="grid gap-6">
<div className="bg-card rounded-2xl p-8 shadow-lg border border-foreground/10">
<h2 className="text-2xl font-bold mb-6">Bem-vindo, {user.name}!</h2>
<div className="grid md:grid-cols-2 gap-8">
<div className="space-y-4">
<div className="flex items-center space-x-3">
<User className="w-6 h-6 text-primary-cta" />
<div>
<p className="font-medium text-foreground">{activity.title}</p>
<p className="text-sm text-foreground/60">{activity.time}</p>
<p className="text-sm text-foreground/60">Nome</p>
<p className="font-semibold">{user.name}</p>
</div>
<span className="text-lg">{activity.status}</span>
</div>
))}
<div className="flex items-center space-x-3">
<Mail className="w-6 h-6 text-primary-cta" />
<div>
<p className="text-sm text-foreground/60">Email</p>
<p className="font-semibold">{user.email}</p>
</div>
</div>
</div>
<div className="space-y-4">
<div className="bg-background rounded-lg p-4">
<p className="text-sm text-foreground/60 mb-2">Status da Sessão</p>
<div className="flex items-center space-x-2">
<div className="w-3 h-3 bg-green-500 rounded-full animate-pulse"></div>
<p className="font-semibold text-green-500">Conectado</p>
</div>
</div>
</div>
</div>
</div>
<div className="grid md:grid-cols-3 gap-6">
<div className="bg-gradient-to-br from-primary-cta/20 to-accent/20 rounded-2xl p-6 border border-primary-cta/20">
<Zap className="w-8 h-8 text-primary-cta mb-2" />
<h3 className="text-lg font-semibold mb-1">Treinos</h3>
<p className="text-3xl font-bold text-primary-cta">0</p>
<p className="text-sm text-foreground/60 mt-2">Treinos concluídos</p>
</div>
<div className="bg-gradient-to-br from-accent/20 to-secondary-cta/20 rounded-2xl p-6 border border-accent/20">
<Zap className="w-8 h-8 text-accent mb-2" />
<h3 className="text-lg font-semibold mb-1">Nutrição</h3>
<p className="text-3xl font-bold text-accent">0</p>
<p className="text-sm text-foreground/60 mt-2">Refeições rastreadas</p>
</div>
<div className="bg-gradient-to-br from-secondary-cta/20 to-primary-cta/20 rounded-2xl p-6 border border-secondary-cta/20">
<Zap className="w-8 h-8 text-secondary-cta mb-2" />
<h3 className="text-lg font-semibold mb-1">Cardio</h3>
<p className="text-3xl font-bold text-secondary-cta">0 km</p>
<p className="text-sm text-foreground/60 mt-2">Distância total</p>
</div>
</div>
</div>
</div>
{/* Action Buttons */}
<div className="mt-8 grid grid-cols-1 md:grid-cols-3 gap-4">
{[
{ label: 'Iniciar Treino', color: 'bg-primary-cta' },
{ label: 'Registrar Refeição', color: 'bg-accent' },
{ label: 'Ver Progresso', color: 'bg-secondary-cta' },
].map((btn, idx) => (
<button
key={idx}
className={`${btn.color} text-background font-semibold py-3 px-6 rounded-lg hover:opacity-90 transition`}
onClick={handleLogout}
className="w-full bg-red-500 hover:bg-red-600 text-white py-3 rounded-lg font-semibold transition flex items-center justify-center space-x-2"
>
{btn.label}
<LogOut className="w-5 h-5" />
<span>Sair da Conta</span>
</button>
))}
</div>
</div>
)}
</div>
</div>
@@ -185,7 +212,7 @@ export default function DashboardPage() {
columns={[
{
title: "Produto", items: [
{ label: "Dashboard", href: "dashboard" },
{ label: "Dashboard", href: "/dashboard" },
{ label: "Treino", href: "training" },
{ label: "Nutrição", href: "nutrition" },
{ label: "Cardio Hub", href: "cardio" }