Prepara versao dev 1.0

This commit is contained in:
Erik Silva
2025-12-08 21:47:38 -03:00
parent 512287698e
commit 190fde20c3
85 changed files with 7755 additions and 2317 deletions

View File

@@ -0,0 +1,181 @@
"use client";
import { useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import { getUser } from "@/lib/auth";
import {
ChartBarIcon,
UserGroupIcon,
FolderIcon,
CurrencyDollarIcon,
ArrowTrendingUpIcon,
ArrowTrendingDownIcon
} from '@heroicons/react/24/outline';
interface StatCardProps {
title: string;
value: string | number;
icon: React.ComponentType<React.SVGProps<SVGSVGElement>>;
trend?: number;
color: 'blue' | 'purple' | 'gray' | 'green';
}
const colorClasses = {
blue: {
iconBg: 'bg-blue-50 dark:bg-blue-900/20',
iconColor: 'text-blue-600 dark:text-blue-400',
trend: 'text-blue-600 dark:text-blue-400'
},
purple: {
iconBg: 'bg-purple-50 dark:bg-purple-900/20',
iconColor: 'text-purple-600 dark:text-purple-400',
trend: 'text-purple-600 dark:text-purple-400'
},
gray: {
iconBg: 'bg-gray-50 dark:bg-gray-900/20',
iconColor: 'text-gray-600 dark:text-gray-400',
trend: 'text-gray-600 dark:text-gray-400'
},
green: {
iconBg: 'bg-emerald-50 dark:bg-emerald-900/20',
iconColor: 'text-emerald-600 dark:text-emerald-400',
trend: 'text-emerald-600 dark:text-emerald-400'
}
};
function StatCard({ title, value, icon: Icon, trend, color }: StatCardProps) {
const colors = colorClasses[color];
const isPositive = trend && trend > 0;
return (
<div className="bg-white dark:bg-gray-800 rounded-xl p-6 border border-gray-200 dark:border-gray-700 hover:shadow-lg transition-shadow">
<div className="flex items-center justify-between">
<div className="flex-1">
<p className="text-sm font-medium text-gray-600 dark:text-gray-400">{title}</p>
<p className="text-3xl font-semibold text-gray-900 dark:text-white mt-2">{value}</p>
{trend !== undefined && (
<div className="flex items-center mt-2">
{isPositive ? (
<ArrowTrendingUpIcon className="w-4 h-4 text-emerald-500" />
) : (
<ArrowTrendingDownIcon className="w-4 h-4 text-red-500" />
)}
<span className={`text-sm font-medium ml-1 ${isPositive ? 'text-emerald-600 dark:text-emerald-400' : 'text-red-600 dark:text-red-400'}`}>
{Math.abs(trend)}%
</span>
<span className="text-xs text-gray-500 dark:text-gray-400 ml-1">vs mês anterior</span>
</div>
)}
</div>
<div className={`${colors.iconBg} p-3 rounded-xl`}>
<Icon className={`w-8 h-8 ${colors.iconColor}`} />
</div>
</div>
</div>
);
}
export default function DashboardPage() {
const router = useRouter();
const [stats, setStats] = useState({
clientes: 0,
projetos: 0,
tarefas: 0,
faturamento: 0
});
useEffect(() => {
// Verificar se é SUPERADMIN e redirecionar
const user = getUser();
if (user && user.role === 'SUPERADMIN') {
router.push('/superadmin');
return;
}
// Simulando carregamento de dados
setTimeout(() => {
setStats({
clientes: 127,
projetos: 18,
tarefas: 64,
faturamento: 87500
});
}, 300);
}, [router]);
return (
<div className="p-6 max-w-7xl mx-auto">
{/* Header */}
<div className="mb-8">
<h1 className="text-2xl font-bold text-gray-900 dark:text-white mb-2">
Dashboard
</h1>
<p className="text-gray-600 dark:text-gray-400">
Bem-vindo ao seu painel de controle
</p>
</div>
{/* Stats Grid */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
<StatCard
title="Clientes Ativos"
value={stats.clientes}
icon={UserGroupIcon}
trend={12.5}
color="blue"
/>
<StatCard
title="Projetos em Andamento"
value={stats.projetos}
icon={FolderIcon}
trend={8.2}
color="purple"
/>
<StatCard
title="Tarefas Pendentes"
value={stats.tarefas}
icon={ChartBarIcon}
trend={-3.1}
color="gray"
/>
<StatCard
title="Faturamento"
value={new Intl.NumberFormat('pt-BR', {
style: 'currency',
currency: 'BRL',
minimumFractionDigits: 0
}).format(stats.faturamento)}
icon={CurrencyDollarIcon}
trend={25.3}
color="green"
/>
</div>
{/* Coming Soon Card */}
<div className="bg-linear-to-br from-gray-50 to-gray-100 dark:from-gray-800 dark:to-gray-900 rounded-2xl border border-gray-200 dark:border-gray-700 p-12">
<div className="max-w-2xl mx-auto text-center">
<div className="inline-flex items-center justify-center w-16 h-16 rounded-2xl mb-6" style={{ background: 'var(--gradient-primary)' }}>
<ChartBarIcon className="w-8 h-8 text-white" />
</div>
<h2 className="text-3xl font-bold text-gray-900 dark:text-white mb-3">
Em Desenvolvimento
</h2>
<p className="text-lg text-gray-600 dark:text-gray-400 mb-8">
Estamos construindo recursos incríveis de CRM e ERP para sua agência.
Em breve você terá acesso a análises detalhadas, gestão completa de clientes e muito mais.
</p>
<div className="flex flex-wrap items-center justify-center gap-3">
{['CRM', 'ERP', 'Projetos', 'Pagamentos', 'Documentos', 'Suporte', 'Contratos'].map((item) => (
<span
key={item}
className="inline-flex items-center px-4 py-2 rounded-full text-sm font-medium bg-white dark:bg-gray-800 text-gray-700 dark:text-gray-300 border border-gray-200 dark:border-gray-700"
>
{item}
</span>
))}
</div>
</div>
</div>
</div>
);
}