page.tsx 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. 'use client';
  2. import { useSession } from 'next-auth/react';
  3. import { useEffect, useState } from 'react';
  4. import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
  5. import { Button } from '@/components/ui/button';
  6. import { Users, GraduationCap, BookOpen, Calendar, FileText, School, Building, Clock } from 'lucide-react';
  7. import Link from 'next/link';
  8. import { DashboardLayout } from '@/components/dashboard-layout';
  9. import { Spinner } from '@/components/ui/spinner'
  10. interface DashboardStats {
  11. teachers: number;
  12. students: number;
  13. classes: number;
  14. sections: number;
  15. periods: number;
  16. partials: number;
  17. }
  18. export default function AdminDashboard() {
  19. const { data: session } = useSession();
  20. const [stats, setStats] = useState<DashboardStats>({
  21. teachers: 0,
  22. students: 0,
  23. classes: 0,
  24. sections: 0,
  25. periods: 0,
  26. partials: 0,
  27. });
  28. const [loading, setLoading] = useState(true);
  29. useEffect(() => {
  30. fetchStats();
  31. }, []);
  32. const fetchStats = async () => {
  33. try {
  34. const response = await fetch('/api/admin/stats');
  35. if (response.ok) {
  36. const data = await response.json();
  37. setStats(data);
  38. }
  39. } catch (error) {
  40. console.error('Error fetching stats:', error);
  41. } finally {
  42. setLoading(false);
  43. }
  44. };
  45. const statCards = [
  46. {
  47. title: 'Profesores',
  48. value: stats.teachers,
  49. icon: Users,
  50. color: 'text-blue-600',
  51. bgColor: 'bg-blue-50',
  52. href: '/admin/teachers',
  53. },
  54. {
  55. title: 'Estudiantes',
  56. value: stats.students,
  57. icon: GraduationCap,
  58. color: 'text-green-600',
  59. bgColor: 'bg-green-50',
  60. href: '/admin/students',
  61. },
  62. {
  63. title: 'Clases',
  64. value: stats.classes,
  65. icon: BookOpen,
  66. color: 'text-purple-600',
  67. bgColor: 'bg-purple-50',
  68. href: '/admin/classes',
  69. },
  70. {
  71. title: 'Paralelos',
  72. value: stats.sections,
  73. icon: School,
  74. color: 'text-orange-600',
  75. bgColor: 'bg-orange-50',
  76. href: '/admin/sections',
  77. },
  78. {
  79. title: 'Periodos',
  80. value: stats.periods,
  81. icon: Calendar,
  82. color: 'text-red-600',
  83. bgColor: 'bg-red-50',
  84. href: '/admin/periods',
  85. },
  86. {
  87. title: 'Parciales',
  88. value: stats.partials,
  89. icon: FileText,
  90. color: 'text-indigo-600',
  91. bgColor: 'bg-indigo-50',
  92. href: '/admin/partials',
  93. },
  94. ];
  95. if (loading) {
  96. return (
  97. <div className="min-h-screen flex items-center justify-center">
  98. <Spinner size="lg" />
  99. </div>
  100. );
  101. }
  102. const breadcrumbs = [
  103. { label: "Dashboard" }
  104. ]
  105. return (
  106. <DashboardLayout breadcrumbs={breadcrumbs}>
  107. <div className="space-y-6">
  108. <div>
  109. <h1 className="text-3xl font-bold">
  110. Dashboard Administrativo
  111. </h1>
  112. <p>
  113. Bienvenido, {session?.user?.firstName} {session?.user?.lastName}
  114. </p>
  115. </div>
  116. <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8">
  117. {statCards.map((card) => {
  118. const Icon = card.icon;
  119. return (
  120. <Link key={card.title} href={card.href}>
  121. <Card className="hover:shadow-lg transition-shadow cursor-pointer">
  122. <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
  123. <CardTitle className="text-sm font-medium">
  124. {card.title}
  125. </CardTitle>
  126. <div className={`p-2 rounded-full ${card.bgColor}`}>
  127. <Icon className={`h-4 w-4 ${card.color}`} />
  128. </div>
  129. </CardHeader>
  130. <CardContent>
  131. <div className="text-2xl font-bold">{card.value}</div>
  132. <p className="text-xs text-muted-foreground">
  133. Total registrado
  134. </p>
  135. </CardContent>
  136. </Card>
  137. </Link>
  138. );
  139. })}
  140. </div>
  141. {/* <div className="mb-8">
  142. <h2 className="text-2xl font-bold text-gray-900 mb-6">Gestión del Sistema</h2>
  143. <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
  144. <Link href="/admin/teachers">
  145. <Card className="hover:shadow-md transition-shadow cursor-pointer">
  146. <CardContent className="p-6">
  147. <div className="flex items-center gap-4">
  148. <Users className="h-8 w-8 text-blue-600" />
  149. <div>
  150. <h3 className="font-semibold">Gestionar Profesores</h3>
  151. <p className="text-sm text-gray-600">Crear, editar y eliminar profesores</p>
  152. </div>
  153. </div>
  154. </CardContent>
  155. </Card>
  156. </Link>
  157. <Link href="/admin/students">
  158. <Card className="hover:shadow-md transition-shadow cursor-pointer">
  159. <CardContent className="p-6">
  160. <div className="flex items-center gap-4">
  161. <GraduationCap className="h-8 w-8 text-green-600" />
  162. <div>
  163. <h3 className="font-semibold">Gestionar Estudiantes</h3>
  164. <p className="text-sm text-gray-600">Crear, editar y eliminar estudiantes</p>
  165. </div>
  166. </div>
  167. </CardContent>
  168. </Card>
  169. </Link>
  170. <Link href="/admin/periods">
  171. <Card className="hover:shadow-md transition-shadow cursor-pointer">
  172. <CardContent className="p-6">
  173. <div className="flex items-center gap-4">
  174. <Calendar className="h-8 w-8 text-purple-600" />
  175. <div>
  176. <h3 className="font-semibold">Períodos Académicos</h3>
  177. <p className="text-sm text-gray-600">Gestionar períodos académicos</p>
  178. </div>
  179. </div>
  180. </CardContent>
  181. </Card>
  182. </Link>
  183. <Link href="/admin/classes">
  184. <Card className="hover:shadow-md transition-shadow cursor-pointer">
  185. <CardContent className="p-6">
  186. <div className="flex items-center gap-4">
  187. <BookOpen className="h-8 w-8 text-orange-600" />
  188. <div>
  189. <h3 className="font-semibold">Gestionar Clases</h3>
  190. <p className="text-sm text-gray-600">Crear y administrar clases</p>
  191. </div>
  192. </div>
  193. </CardContent>
  194. </Card>
  195. </Link>
  196. <Link href="/admin/sections">
  197. <Card className="hover:shadow-md transition-shadow cursor-pointer">
  198. <CardContent className="p-6">
  199. <div className="flex items-center gap-4">
  200. <Building className="h-8 w-8 text-indigo-600" />
  201. <div>
  202. <h3 className="font-semibold">Gestionar Paralelos</h3>
  203. <p className="text-sm text-gray-600">Crear y administrar paralelos</p>
  204. </div>
  205. </div>
  206. </CardContent>
  207. </Card>
  208. </Link>
  209. <Link href="/admin/partials">
  210. <Card className="hover:shadow-md transition-shadow cursor-pointer">
  211. <CardContent className="p-6">
  212. <div className="flex items-center gap-4">
  213. <Clock className="h-8 w-8 text-red-600" />
  214. <div>
  215. <h3 className="font-semibold">Gestionar Parciales</h3>
  216. <p className="text-sm text-gray-600">Configurar períodos de parciales</p>
  217. </div>
  218. </div>
  219. </CardContent>
  220. </Card>
  221. </Link>
  222. </div>
  223. </div> */}
  224. </div>
  225. </DashboardLayout>
  226. );
  227. }