Browse Source

we got spinners now

Matthew Trejo 3 months ago
parent
commit
cc56ba8386

+ 2 - 1
src/app/admin/classes/page.tsx

@@ -12,6 +12,7 @@ import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, D
 import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
 import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
 import { toast } from 'sonner';
 import { toast } from 'sonner';
 import { Plus, Search, Edit, Trash2, Users, Calendar, Clock } from 'lucide-react';
 import { Plus, Search, Edit, Trash2, Users, Calendar, Clock } from 'lucide-react';
+import { LoadingSpinner } from '@/components/ui/spinner';
 
 
 interface Period {
 interface Period {
   id: string;
   id: string;
@@ -190,7 +191,7 @@ export default function ClassesPage() {
     return (
     return (
       <MainLayout requiredRole="ADMIN" title="Gestión de Clases">
       <MainLayout requiredRole="ADMIN" title="Gestión de Clases">
         <div className="flex items-center justify-center h-64">
         <div className="flex items-center justify-center h-64">
-          <div className="text-lg">Cargando clases...</div>
+          <LoadingSpinner size="lg" />
         </div>
         </div>
       </MainLayout>
       </MainLayout>
     );
     );

+ 2 - 1
src/app/admin/periods/page.tsx

@@ -38,6 +38,7 @@ import { Badge } from '@/components/ui/badge';
 import { Switch } from '@/components/ui/switch';
 import { Switch } from '@/components/ui/switch';
 import { Plus, Pencil, Trash2, Search, Calendar } from 'lucide-react';
 import { Plus, Pencil, Trash2, Search, Calendar } from 'lucide-react';
 import { toast } from 'sonner';
 import { toast } from 'sonner';
+import { LoadingSpinner } from '@/components/ui/spinner';
 
 
 interface Period {
 interface Period {
   id: string;
   id: string;
@@ -317,7 +318,7 @@ export default function PeriodsPage() {
           <CardContent>
           <CardContent>
             {loading ? (
             {loading ? (
               <div className="flex items-center justify-center py-8">
               <div className="flex items-center justify-center py-8">
-                <div className="text-muted-foreground">Cargando periodos...</div>
+                <LoadingSpinner size="lg" />
               </div>
               </div>
             ) : (
             ) : (
               <Table>
               <Table>

+ 7 - 6
src/app/admin/reports/page.tsx

@@ -11,6 +11,7 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@
 import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
 import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
 import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
 import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
 import { toast } from 'sonner';
 import { toast } from 'sonner';
+import { LoadingSpinner } from '@/components/ui/spinner';
 import { 
 import { 
   BarChart3, 
   BarChart3, 
   Users, 
   Users, 
@@ -414,7 +415,7 @@ export default function ReportsPage() {
           <TabsContent value="overview">
           <TabsContent value="overview">
             {loading ? (
             {loading ? (
               <div className="flex items-center justify-center py-8">
               <div className="flex items-center justify-center py-8">
-                <div className="text-muted-foreground">Cargando reporte...</div>
+                <LoadingSpinner size="lg" />
               </div>
               </div>
             ) : overviewData ? (
             ) : overviewData ? (
               <div className="space-y-6">
               <div className="space-y-6">
@@ -499,7 +500,7 @@ export default function ReportsPage() {
           <TabsContent value="students">
           <TabsContent value="students">
             {loading ? (
             {loading ? (
               <div className="flex items-center justify-center py-8">
               <div className="flex items-center justify-center py-8">
-                <div className="text-muted-foreground">Cargando reporte...</div>
+                <LoadingSpinner size="lg" />
               </div>
               </div>
             ) : studentsData ? (
             ) : studentsData ? (
               <div className="space-y-6">
               <div className="space-y-6">
@@ -576,7 +577,7 @@ export default function ReportsPage() {
           <TabsContent value="teachers">
           <TabsContent value="teachers">
             {loading ? (
             {loading ? (
               <div className="flex items-center justify-center py-8">
               <div className="flex items-center justify-center py-8">
-                <div className="text-muted-foreground">Cargando reporte...</div>
+                <LoadingSpinner size="lg" />
               </div>
               </div>
             ) : teachersData ? (
             ) : teachersData ? (
               <div className="space-y-6">
               <div className="space-y-6">
@@ -647,7 +648,7 @@ export default function ReportsPage() {
           <TabsContent value="attendance">
           <TabsContent value="attendance">
             {loading ? (
             {loading ? (
               <div className="flex items-center justify-center py-8">
               <div className="flex items-center justify-center py-8">
-                <div className="text-muted-foreground">Cargando reporte...</div>
+                <LoadingSpinner size="lg" />
               </div>
               </div>
             ) : attendanceData ? (
             ) : attendanceData ? (
               <div className="space-y-6">
               <div className="space-y-6">
@@ -726,7 +727,7 @@ export default function ReportsPage() {
           <TabsContent value="enrollments">
           <TabsContent value="enrollments">
             {loading ? (
             {loading ? (
               <div className="flex items-center justify-center py-8">
               <div className="flex items-center justify-center py-8">
-                <div className="text-muted-foreground">Cargando reporte...</div>
+                <LoadingSpinner size="lg" />
               </div>
               </div>
             ) : enrollmentsData ? (
             ) : enrollmentsData ? (
               <div className="space-y-6">
               <div className="space-y-6">
@@ -808,7 +809,7 @@ export default function ReportsPage() {
           <TabsContent value="classes">
           <TabsContent value="classes">
             {loading ? (
             {loading ? (
               <div className="flex items-center justify-center py-8">
               <div className="flex items-center justify-center py-8">
-                <div className="text-muted-foreground">Cargando reporte...</div>
+                <LoadingSpinner size="lg" />
               </div>
               </div>
             ) : classesData ? (
             ) : classesData ? (
               <div className="space-y-6">
               <div className="space-y-6">

+ 2 - 1
src/app/admin/sections/page.tsx

@@ -12,6 +12,7 @@ import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, D
 import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
 import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
 import { toast } from 'sonner';
 import { toast } from 'sonner';
 import { Plus, Search, Edit, Trash2, Users, Clock, Calendar } from 'lucide-react';
 import { Plus, Search, Edit, Trash2, Users, Clock, Calendar } from 'lucide-react';
+import { LoadingSpinner } from '@/components/ui/spinner';
 
 
 interface Class {
 interface Class {
   id: string;
   id: string;
@@ -195,7 +196,7 @@ export default function SectionsPage() {
     return (
     return (
       <MainLayout requiredRole="ADMIN" title="Gestión de Secciones">
       <MainLayout requiredRole="ADMIN" title="Gestión de Secciones">
         <div className="flex items-center justify-center h-64">
         <div className="flex items-center justify-center h-64">
-          <div className="text-lg">Cargando secciones...</div>
+          <LoadingSpinner size="lg" />
         </div>
         </div>
       </MainLayout>
       </MainLayout>
     );
     );

+ 2 - 1
src/app/admin/student-enrollments/page.tsx

@@ -14,6 +14,7 @@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@
 import { Switch } from '@/components/ui/switch';
 import { Switch } from '@/components/ui/switch';
 import { toast } from 'sonner';
 import { toast } from 'sonner';
 import { Plus, Search, Edit, Trash2, Users, GraduationCap, BookOpen, UserCheck } from 'lucide-react';
 import { Plus, Search, Edit, Trash2, Users, GraduationCap, BookOpen, UserCheck } from 'lucide-react';
+import { LoadingSpinner } from '@/components/ui/spinner';
 
 
 interface Student {
 interface Student {
   id: string;
   id: string;
@@ -389,7 +390,7 @@ export default function StudentEnrollmentsPage() {
           <CardContent>
           <CardContent>
             {loading ? (
             {loading ? (
               <div className="flex items-center justify-center py-8">
               <div className="flex items-center justify-center py-8">
-                <div className="text-muted-foreground">Cargando inscripciones...</div>
+                <LoadingSpinner size="lg" />
               </div>
               </div>
             ) : (
             ) : (
               <Table>
               <Table>

+ 2 - 1
src/app/admin/teacher-assignments/page.tsx

@@ -14,6 +14,7 @@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@
 import { Switch } from '@/components/ui/switch';
 import { Switch } from '@/components/ui/switch';
 import { toast } from 'sonner';
 import { toast } from 'sonner';
 import { Plus, Search, Edit, Trash2, Users, GraduationCap, BookOpen } from 'lucide-react';
 import { Plus, Search, Edit, Trash2, Users, GraduationCap, BookOpen } from 'lucide-react';
+import { LoadingSpinner } from '@/components/ui/spinner';
 
 
 interface Teacher {
 interface Teacher {
   id: string;
   id: string;
@@ -383,7 +384,7 @@ export default function TeacherAssignmentsPage() {
           <CardContent>
           <CardContent>
             {loading ? (
             {loading ? (
               <div className="flex items-center justify-center py-8">
               <div className="flex items-center justify-center py-8">
-                <div className="text-muted-foreground">Cargando asignaciones...</div>
+                <LoadingSpinner size="lg" />
               </div>
               </div>
             ) : (
             ) : (
               <Table>
               <Table>

+ 2 - 1
src/app/admin/users/page.tsx

@@ -44,6 +44,7 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/com
 import { Badge } from '@/components/ui/badge';
 import { Badge } from '@/components/ui/badge';
 import { Plus, Pencil, Trash2, Search } from 'lucide-react';
 import { Plus, Pencil, Trash2, Search } from 'lucide-react';
 import { toast } from 'sonner';
 import { toast } from 'sonner';
+import { LoadingSpinner } from '@/components/ui/spinner';
 
 
 interface User {
 interface User {
   id: string;
   id: string;
@@ -480,7 +481,7 @@ export default function UsersPage() {
           <CardContent>
           <CardContent>
             {loading ? (
             {loading ? (
               <div className="flex items-center justify-center py-8">
               <div className="flex items-center justify-center py-8">
-                <div className="text-muted-foreground">Cargando usuarios...</div>
+                <LoadingSpinner />
               </div>
               </div>
             ) : (
             ) : (
               <Table>
               <Table>

+ 2 - 1
src/app/student/attendance/page.tsx

@@ -30,6 +30,7 @@ import {
 } from 'lucide-react';
 } from 'lucide-react';
 import { toast } from 'sonner';
 import { toast } from 'sonner';
 import { AttendanceStatus } from '@prisma/client';
 import { AttendanceStatus } from '@prisma/client';
+import { LoadingSpinner } from '@/components/ui/spinner';
 
 
 interface Teacher {
 interface Teacher {
   id: string;
   id: string;
@@ -291,7 +292,7 @@ export default function StudentAttendancePage() {
     return (
     return (
       <MainLayout requiredRole="STUDENT" title="Historial de Asistencia">
       <MainLayout requiredRole="STUDENT" title="Historial de Asistencia">
         <div className="flex items-center justify-center h-64">
         <div className="flex items-center justify-center h-64">
-          <div className="text-lg">Cargando historial de asistencia...</div>
+          <LoadingSpinner size="lg" />
         </div>
         </div>
       </MainLayout>
       </MainLayout>
     );
     );

+ 2 - 1
src/app/student/classes/page.tsx

@@ -24,6 +24,7 @@ import {
   GraduationCap
   GraduationCap
 } from 'lucide-react';
 } from 'lucide-react';
 import { toast } from 'sonner';
 import { toast } from 'sonner';
+import { LoadingSpinner } from '@/components/ui/spinner';
 
 
 interface Teacher {
 interface Teacher {
   id: string;
   id: string;
@@ -165,7 +166,7 @@ export default function StudentClassesPage() {
     return (
     return (
       <MainLayout requiredRole="STUDENT" title="Mis Clases">
       <MainLayout requiredRole="STUDENT" title="Mis Clases">
         <div className="flex items-center justify-center h-64">
         <div className="flex items-center justify-center h-64">
-          <div className="text-lg">Cargando clases matriculadas...</div>
+          <LoadingSpinner size="lg" />
         </div>
         </div>
       </MainLayout>
       </MainLayout>
     );
     );

+ 4 - 6
src/app/teacher/assignments/page.tsx

@@ -10,6 +10,7 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@
 import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
 import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
 import { CalendarDays, Users, BookOpen, Search, Filter, Eye } from 'lucide-react';
 import { CalendarDays, Users, BookOpen, Search, Filter, Eye } from 'lucide-react';
 import { toast } from 'sonner';
 import { toast } from 'sonner';
+import { LoadingSpinner } from '@/components/ui/spinner';
 
 
 interface Student {
 interface Student {
   id: string;
   id: string;
@@ -132,14 +133,11 @@ export default function TeacherAssignmentsPage() {
 
 
   if (loading) {
   if (loading) {
     return (
     return (
-      <div className="container mx-auto p-6">
+      <MainLayout requiredRole="TEACHER" title="Mis Asignaciones">
         <div className="flex items-center justify-center h-64">
         <div className="flex items-center justify-center h-64">
-          <div className="text-center">
-            <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary mx-auto mb-4"></div>
-            <p>Cargando asignaciones...</p>
-          </div>
+          <LoadingSpinner size="lg" />
         </div>
         </div>
-      </div>
+      </MainLayout>
     );
     );
   }
   }
 
 

+ 2 - 2
src/app/teacher/attendance/page.tsx

@@ -11,6 +11,7 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@
 import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
 import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
 import { Textarea } from '@/components/ui/textarea';
 import { Textarea } from '@/components/ui/textarea';
 import { CalendarDays, Users, BookOpen, Save, Download, Search, Filter, CheckCircle, XCircle, AlertCircle } from 'lucide-react';
 import { CalendarDays, Users, BookOpen, Save, Download, Search, Filter, CheckCircle, XCircle, AlertCircle } from 'lucide-react';
+import { LoadingSpinner } from '@/components/ui/spinner';
 import { toast } from 'sonner';
 import { toast } from 'sonner';
 
 
 interface Student {
 interface Student {
@@ -388,8 +389,7 @@ export default function AttendancePage() {
             <CardContent className="p-8">
             <CardContent className="p-8">
               <div className="flex items-center justify-center">
               <div className="flex items-center justify-center">
                 <div className="text-center">
                 <div className="text-center">
-                  <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary mx-auto mb-4"></div>
-                  <p>Cargando datos de asistencia...</p>
+                  <LoadingSpinner size="lg" />
                 </div>
                 </div>
               </div>
               </div>
             </CardContent>
             </CardContent>

+ 4 - 4
src/app/teacher/page.tsx

@@ -3,8 +3,9 @@
 import { useEffect, useState } from 'react'
 import { useEffect, useState } from 'react'
 import { MainLayout } from '@/components/layout/main-layout'
 import { MainLayout } from '@/components/layout/main-layout'
 import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
 import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
-import { BookOpen, Users, Calendar, ClipboardList, Clock, CheckCircle, Loader2 } from 'lucide-react'
-import { TeacherDashboardData } from '@/types/teacher'
+import { BookOpen, Users, Calendar, ClipboardList, Clock, CheckCircle } from 'lucide-react';
+import { TeacherDashboardData } from '@/types/teacher';
+import { LoadingSpinner } from '@/components/ui/spinner';
 
 
 export default function TeacherDashboard() {
 export default function TeacherDashboard() {
   const [dashboardData, setDashboardData] = useState<TeacherDashboardData | null>(null)
   const [dashboardData, setDashboardData] = useState<TeacherDashboardData | null>(null)
@@ -73,8 +74,7 @@ export default function TeacherDashboard() {
         requiredRole="TEACHER"
         requiredRole="TEACHER"
       >
       >
         <div className="flex items-center justify-center h-64">
         <div className="flex items-center justify-center h-64">
-          <Loader2 className="h-8 w-8 animate-spin" />
-          <span className="ml-2">Cargando datos del dashboard...</span>
+          <LoadingSpinner size="lg" />
         </div>
         </div>
       </MainLayout>
       </MainLayout>
     )
     )

+ 45 - 0
src/components/ui/spinner.tsx

@@ -0,0 +1,45 @@
+import { cn } from "@/lib/utils"
+import { Loader2 } from "lucide-react"
+
+interface SpinnerProps {
+  className?: string
+  size?: "sm" | "md" | "lg"
+}
+
+export function Spinner({ className, size = "md" }: SpinnerProps) {
+  const sizeClasses = {
+    sm: "h-4 w-4",
+    md: "h-6 w-6",
+    lg: "h-8 w-8"
+  }
+
+  return (
+    <Loader2 
+      className={cn(
+        "animate-spin", 
+        sizeClasses[size], 
+        className
+      )} 
+    />
+  )
+}
+
+// Componente de loading con texto opcional
+interface LoadingSpinnerProps {
+  text?: string
+  size?: "sm" | "md" | "lg"
+  className?: string
+}
+
+export function LoadingSpinner({ 
+  text, 
+  size = "md", 
+  className 
+}: LoadingSpinnerProps) {
+  return (
+    <div className={cn("flex items-center justify-center gap-2", className)}>
+      <Spinner size={size} />
+      {text && <span className="text-muted-foreground">{text}</span>}
+    </div>
+  )
+}