diff --git a/src/app/_content.tsx b/src/app/_content.tsx index d8ccd4b..b766dcb 100644 --- a/src/app/_content.tsx +++ b/src/app/_content.tsx @@ -86,7 +86,7 @@ export default function HomeContent() { placeholder="Buscar cursos..." value={searchQuery} onChange={(e) => setSearchQuery(e.target.value)} - className={`w-full pl-9 pr-4 py-2.5 text-sm rounded-xl bg-transparent outline-none ${isDark ? "text-white placeholder:text-slate-500" : "text-slate-800 placeholder:text-slate-400"}`} + className={`w-full pl-9 pr-4 py-2.5 text-sm rounded-xl bg-transparent outline-none ${isDark ? "text-white" : "text-slate-800"}`} /> @@ -179,7 +179,7 @@ export default function HomeContent() { className={`flex items-center gap-1 ${isDark ? "text-slate-400" : "text-slate-500"}`} > - {inst.totalStudents.toLocaleString()} alumnos + {inst.totalStudents.toString()} alumnos diff --git a/src/app/instructor/analytics/page.tsx b/src/app/instructor/analytics/page.tsx new file mode 100644 index 0000000..ea6ccc2 --- /dev/null +++ b/src/app/instructor/analytics/page.tsx @@ -0,0 +1,48 @@ +import React from "react"; +import { FiBarChart2, FiDownload } from "react-icons/fi"; + +export default function AnalyticsPage() { + return ( + <> +
+
+
+

Ganancias y Pagos

+
+ +
+ +
+
+

Ingresos este mes

+

$1,240.00

+

+15% respecto al mes anterior

+
+ +
+

Próximo Pago

+

15 de Sep

+

Transferencia bancaria terminada en 4021

+
+
+ +
+

Analíticas

+

Métricas detalladas sobre el rendimiento de tus cursos.

+
+ +
+
+ +
+

Página de Analíticas en Construcción

+

+ Pronto podrás visualizar gráficos interactivos, retención de estudiantes y métricas detalladas aquí. +

+
+
+ + ); +} diff --git a/src/app/instructor/courses/[id]/page.tsx b/src/app/instructor/courses/[id]/page.tsx new file mode 100644 index 0000000..6d9b878 --- /dev/null +++ b/src/app/instructor/courses/[id]/page.tsx @@ -0,0 +1,582 @@ +"use client"; + +import React, { useState } from "react"; +import Link from "next/link"; +import { + FiArrowLeft, + FiUsers, + FiPlayCircle, + FiMessageSquare, + FiStar, + FiBookOpen, + FiVideo, + FiFileText, + FiChevronDown, + FiChevronRight, + FiSend, + FiCheck, +} from "react-icons/fi"; + +// ── Mock data ───────────────────────────────────────────────────────────────── + +const coursesData: Record< + string, + { + id: number; + title: string; + status: string; + price: string; + rating: number; + totalReviews: number; + students: { + id: number; + name: string; + email: string; + progress: number; + purchasedAt: string; + avatar: string; + }[]; + sections: { + id: number; + title: string; + lessons: { id: number; title: string; type: "video" | "article"; duration: string }[]; + }[]; + messages: { + id: number; + student: string; + avatar: string; + message: string; + date: string; + replied: boolean; + }[]; + reviews: { + id: number; + student: string; + avatar: string; + rating: number; + comment: string; + date: string; + }[]; + } +> = { + "1": { + id: 1, + title: "Desarrollo Web Fullstack con Next.js", + status: "Publicado", + price: "$49.99", + rating: 4.7, + totalReviews: 128, + students: [ + { id: 1, name: "Ana García", email: "ana.g@example.com", progress: 85, purchasedAt: "12 Ago 2026", avatar: "AG" }, + { id: 2, name: "Carlos López", email: "carlos.l@example.com", progress: 42, purchasedAt: "18 Ago 2026", avatar: "CL" }, + { id: 3, name: "María Rodríguez", email: "maria.r@example.com", progress: 100, purchasedAt: "5 Jul 2026", avatar: "MR" }, + { id: 4, name: "Juan Martínez", email: "juan.m@example.com", progress: 15, purchasedAt: "27 Ago 2026", avatar: "JM" }, + { id: 5, name: "Laura Sánchez", email: "laura.s@example.com", progress: 63, purchasedAt: "1 Sep 2026", avatar: "LS" }, + ], + sections: [ + { + id: 1, + title: "Introducción al curso", + lessons: [ + { id: 1, title: "Bienvenida y configuración del entorno", type: "video", duration: "8:24" }, + { id: 2, title: "¿Qué aprenderemos?", type: "article", duration: "3 min" }, + ], + }, + { + id: 2, + title: "Fundamentos de Next.js", + lessons: [ + { id: 3, title: "App Router vs Pages Router", type: "video", duration: "14:10" }, + { id: 4, title: "Server y Client Components", type: "video", duration: "18:45" }, + { id: 5, title: "Rutas dinámicas", type: "video", duration: "12:30" }, + { id: 6, title: "Resumen de fundamentos", type: "article", duration: "5 min" }, + ], + }, + { + id: 3, + title: "Base de datos con Prisma", + lessons: [ + { id: 7, title: "Instalación y schema", type: "video", duration: "10:15" }, + { id: 8, title: "Migraciones", type: "video", duration: "9:50" }, + { id: 9, title: "CRUD completo", type: "video", duration: "22:00" }, + ], + }, + ], + messages: [ + { id: 1, student: "Carlos López", avatar: "CL", message: "Hola, tengo un error al configurar Prisma con PostgreSQL. El schema no migra correctamente.", date: "Hace 2 horas", replied: false }, + { id: 2, student: "Juan Martínez", avatar: "JM", message: "¿Podrías subir el código fuente de la sección 3? No encuentro el repositorio.", date: "Hace 5 horas", replied: true }, + { id: 3, student: "Ana García", avatar: "AG", message: "Excelente curso, aprendí muchísimo. ¿Planeas hacer una parte 2?", date: "Ayer", replied: false }, + ], + reviews: [ + { id: 1, student: "María Rodríguez", avatar: "MR", rating: 5, comment: "El mejor curso de Next.js que he tomado. Muy claro y completo.", date: "28 Ago 2026" }, + { id: 2, student: "Ana García", avatar: "AG", rating: 5, comment: "Increíble. El instructor explica muy bien cada concepto.", date: "25 Ago 2026" }, + { id: 3, student: "Carlos López", avatar: "CL", rating: 4, comment: "Muy buen contenido. Me gustaría más ejercicios prácticos.", date: "20 Ago 2026" }, + ], + }, + "2": { + id: 2, + title: "Masterclass de UI/UX Design", + status: "Publicado", + price: "$39.99", + rating: 4.5, + totalReviews: 89, + students: [ + { id: 1, name: "Laura Sánchez", email: "laura.s@example.com", progress: 70, purchasedAt: "10 Ago 2026", avatar: "LS" }, + { id: 2, name: "Pedro Ruiz", email: "pedro.r@example.com", progress: 30, purchasedAt: "20 Ago 2026", avatar: "PR" }, + { id: 3, name: "Sofía Torres", email: "sofia.t@example.com", progress: 90, purchasedAt: "3 Ago 2026", avatar: "ST" }, + ], + sections: [ + { + id: 1, + title: "Principios de diseño", + lessons: [ + { id: 1, title: "Color, tipografía y espacio", type: "video", duration: "15:00" }, + { id: 2, title: "Sistemas de diseño", type: "article", duration: "6 min" }, + ], + }, + { + id: 2, + title: "Figma avanzado", + lessons: [ + { id: 3, title: "Auto-layout y componentes", type: "video", duration: "20:00" }, + { id: 4, title: "Prototipado interactivo", type: "video", duration: "17:30" }, + ], + }, + ], + messages: [ + { id: 1, student: "Pedro Ruiz", avatar: "PR", message: "¿Hay alguna plantilla de Figma disponible para descargar?", date: "Hace 1 día", replied: false }, + ], + reviews: [ + { id: 1, student: "Sofía Torres", avatar: "ST", rating: 5, comment: "Transformó por completo mi forma de diseñar.", date: "22 Ago 2026" }, + { id: 2, student: "Laura Sánchez", avatar: "LS", rating: 4, comment: "Muy buenas explicaciones de Figma.", date: "18 Ago 2026" }, + ], + }, + "3": { + id: 3, + title: "Python para Data Science", + status: "Borrador", + price: "$59.99", + rating: 0, + totalReviews: 0, + students: [], + sections: [ + { + id: 1, + title: "Introducción a Python", + lessons: [ + { id: 1, title: "Variables y tipos de datos", type: "video", duration: "12:00" }, + { id: 2, title: "Funciones y módulos", type: "video", duration: "10:30" }, + ], + }, + ], + messages: [], + reviews: [], + }, +}; + +// ── Avatar component ────────────────────────────────────────────────────────── + +const avatarColors = [ + "from-violet-500 to-indigo-500", + "from-emerald-500 to-teal-500", + "from-orange-500 to-amber-500", + "from-pink-500 to-rose-500", + "from-cyan-500 to-blue-500", +]; + +function Avatar({ initials, index = 0, size = "md" }: { initials: string; index?: number; size?: "sm" | "md" }) { + const sz = size === "sm" ? "w-8 h-8 text-xs" : "w-10 h-10 text-sm"; + return ( +
+ {initials} +
+ ); +} + +// ── Stars component ─────────────────────────────────────────────────────────── + +function Stars({ rating, size = "sm" }: { rating: number; size?: "sm" | "lg" }) { + const sz = size === "lg" ? "text-xl" : "text-sm"; + return ( +
+ {[1, 2, 3, 4, 5].map((s) => ( + + ))} +
+ ); +} + +// ── Tab: Estudiantes ────────────────────────────────────────────────────────── + +function StudentsTab({ students }: { students: (typeof coursesData)["1"]["students"] }) { + if (students.length === 0) { + return ( +
+ +

Aún no hay estudiantes inscritos

+

Aparecerán aquí cuando publiques el curso

+
+ ); + } + + return ( +
+
+ + + + + + + + + + {students.map((s, i) => ( + + + + + + ))} + +
EstudianteProgresoComprado
+
+ +
+

{s.name}

+

{s.email}

+
+
+
+
+
+
+
+ + {s.progress}% + + {s.progress === 100 && } +
+
{s.purchasedAt}
+
+
+ ); +} + +// ── Tab: Contenido ──────────────────────────────────────────────────────────── + +function ContentTab({ sections }: { sections: (typeof coursesData)["1"]["sections"] }) { + const [expanded, setExpanded] = useState([1]); + + const toggle = (id: number) => + setExpanded((prev) => (prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id])); + + const totalLessons = sections.reduce((a, s) => a + s.lessons.length, 0); + + return ( +
+
+

+ {sections.length} secciones · {totalLessons} lecciones +

+
+ + {sections.map((section) => { + const isOpen = expanded.includes(section.id); + return ( +
+ + + {isOpen && ( +
+ {section.lessons.map((lesson) => ( +
+
+ {lesson.type === "video" ? ( + + ) : ( + + )} +
+ {lesson.title} + {lesson.duration} +
+ ))} +
+ )} +
+ ); + })} +
+ ); +} + +// ── Tab: Mensajes ───────────────────────────────────────────────────────────── + +function MessagesTab({ messages }: { messages: (typeof coursesData)["1"]["messages"] }) { + const [replyingTo, setReplyingTo] = useState(null); + const [replyText, setReplyText] = useState(""); + + if (messages.length === 0) { + return ( +
+ +

No hay mensajes aún

+
+ ); + } + + return ( +
+ {messages.map((msg, i) => ( +
+
+ +
+
+
+ {msg.student} + {msg.replied ? ( + + Respondido + + ) : ( + + Pendiente + + )} +
+ {msg.date} +
+

{msg.message}

+ + {replyingTo === msg.id ? ( +
+ setReplyText(e.target.value)} + placeholder="Escribe tu respuesta..." + className="flex-1 text-sm px-3 py-2 rounded-xl border border-slate-200 dark:border-slate-700 bg-slate-50 dark:bg-slate-800 text-slate-900 dark:text-white placeholder-slate-400 focus:outline-none focus:ring-2 focus:ring-indigo-500/40" + /> + +
+ ) : ( + + )} +
+
+
+ ))} +
+ ); +} + +// ── Tab: Calificación ───────────────────────────────────────────────────────── + +function RatingTab({ course }: { course: (typeof coursesData)["1"] }) { + if (course.totalReviews === 0) { + return ( +
+ +

Aún no hay calificaciones

+

Aparecerán cuando los estudiantes dejen reseñas

+
+ ); + } + + const starDist = [5, 4, 3, 2, 1].map((star) => ({ + star, + count: course.reviews.filter((r) => r.rating === star).length, + })); + + return ( +
+ {/* Summary card */} +
+
+
+

{course.rating.toFixed(1)}

+ +

{course.totalReviews} calificaciones

+
+
+ {starDist.map(({ star, count }) => { + const pct = course.totalReviews > 0 ? (count / course.reviews.length) * 100 : 0; + return ( +
+ {star} + +
+
+
+ {count} +
+ ); + })} +
+
+
+ + {/* Reviews */} +
+ {course.reviews.map((rev, i) => ( +
+
+ +
+
+ {rev.student} + {rev.date} +
+ +

{rev.comment}

+
+
+
+ ))} +
+
+ ); +} + +// ── Main page ───────────────────────────────────────────────────────────────── + +const tabs = [ + { id: "students", label: "Estudiantes", icon: FiUsers }, + { id: "content", label: "Contenido", icon: FiPlayCircle }, + { id: "messages", label: "Mensajes", icon: FiMessageSquare }, + { id: "rating", label: "Calificación", icon: FiStar }, +]; + +export default function CourseDetailPage({ params }: { params: Promise<{ id: string }> }) { + const { id } = React.use(params); + const course = coursesData[id]; + const [activeTab, setActiveTab] = useState("students"); + + if (!course) { + return ( +
+ +

Curso no encontrado

+ + ← Volver a mis cursos + +
+ ); + } + + const pendingMessages = course.messages.filter((m) => !m.replied).length; + + return ( +
+ {/* Back + Header */} +
+ + Mis Cursos + + +
+
+
+ + {course.status} + + {course.rating > 0 && ( +
+ + {course.rating} +
+ )} +
+

{course.title}

+

+ {course.students.length} estudiantes · {course.price} +

+
+
+
+ + {/* Tabs */} +
+ {tabs.map((tab) => { + const Icon = tab.icon; + const isActive = activeTab === tab.id; + const badge = tab.id === "messages" && pendingMessages > 0 ? pendingMessages : null; + return ( + + ); + })} +
+ + {/* Tab content */} +
+ {activeTab === "students" && } + {activeTab === "content" && } + {activeTab === "messages" && } + {activeTab === "rating" && } +
+
+ ); +} diff --git a/src/app/instructor/courses/page.tsx b/src/app/instructor/courses/page.tsx new file mode 100644 index 0000000..3161236 --- /dev/null +++ b/src/app/instructor/courses/page.tsx @@ -0,0 +1,68 @@ +import React from "react"; +import Link from "next/link"; +import { FiPlus, FiBookOpen, FiUsers, FiStar } from "react-icons/fi"; + +const courses = [ + { id: 1, title: "Desarrollo Web Fullstack con Next.js", status: "Publicado", students: 342, price: "$49.99", rating: 4.7 }, + { id: 2, title: "Masterclass de UI/UX Design", status: "Publicado", students: 215, price: "$39.99", rating: 4.5 }, + { id: 3, title: "Python para Data Science", status: "Borrador", students: 0, price: "$59.99", rating: 0 }, +]; + +export default function CoursesPage() { + return ( +
+
+
+

Mis Cursos

+

Gestiona los cursos que has creado.

+
+ +
+ +
+ {courses.map((course) => ( + +
+ +
+
+
+ + {course.status} + + {course.rating > 0 && ( +
+ + {course.rating} +
+ )} +
+

+ {course.title} +

+
+
+ + {course.students} estudiantes +
+ {course.price} +
+
+ + ))} +
+
+ ); +} diff --git a/src/app/instructor/layout.tsx b/src/app/instructor/layout.tsx new file mode 100644 index 0000000..40871e0 --- /dev/null +++ b/src/app/instructor/layout.tsx @@ -0,0 +1,293 @@ +"use client"; + +import React, { useState, useRef, useEffect, useCallback } from "react"; +import { createPortal } from "react-dom"; +import Link from "next/link"; +import { usePathname } from "next/navigation"; +import { + FiHome, + FiBook, + FiPieChart, + FiSettings, + FiLogOut, + FiMenu, + FiX, + FiChevronDown, +} from "react-icons/fi"; +import { ThemeToggle } from "@/components/ui"; + +const navigation = [ + { name: "Dashboard", href: "/instructor", icon: FiHome }, + { name: "Mis Cursos", href: "/instructor/courses", icon: FiBook }, + { name: "Ingresos y Analíticas", href: "/instructor/analytics", icon: FiPieChart }, +]; + +// Bottom nav shows the most important items on mobile +const bottomNavItems = [ + { name: "Inicio", href: "/instructor", icon: FiHome }, + { name: "Cursos", href: "/instructor/courses", icon: FiBook }, + { name: "Ingresos y Analíticas", href: "/instructor/analytics", icon: FiPieChart }, +]; + +export default function InstructorLayout({ + children, +}: { + children: React.ReactNode; +}) { + const pathname = usePathname(); + const [sidebarOpen, setSidebarOpen] = useState(false); + const [profileMenuOpen, setProfileMenuOpen] = useState(false); + const [dropdownPos, setDropdownPos] = useState({ top: 0, right: 0 }); + const profileButtonRef = useRef(null); + const dropdownRef = useRef(null); + const [mounted, setMounted] = useState(false); + + useEffect(() => { + setMounted(true); + }, []); + + const handleProfileToggle = useCallback(() => { + if (!profileMenuOpen && profileButtonRef.current) { + const rect = profileButtonRef.current.getBoundingClientRect(); + setDropdownPos({ + top: rect.bottom + 8, + right: window.innerWidth - rect.right, + }); + } + setProfileMenuOpen((prev) => !prev); + }, [profileMenuOpen]); + + useEffect(() => { + function handleClickOutside(event: MouseEvent) { + const target = event.target as Node; + if ( + profileButtonRef.current && + !profileButtonRef.current.contains(target) && + dropdownRef.current && + !dropdownRef.current.contains(target) + ) { + setProfileMenuOpen(false); + } + } + if (profileMenuOpen) { + document.addEventListener("mousedown", handleClickOutside); + return () => document.removeEventListener("mousedown", handleClickOutside); + } + }, [profileMenuOpen]); + + const SidebarContent = () => ( + <> +
+ {/* Logo */} +
+
+
+ +
+ + Rynext Edu + +
+ {/* Close button — only visible on mobile */} + +
+ + {/* Navigation links */} + +
+ + {/* Bottom section */} +
+
+

Plan Pro

+

2/5 cursos publicados

+
+
+
+
+
+ + ); + + return ( +
+ + {/* ── MOBILE OVERLAY ── */} + {sidebarOpen && ( +
setSidebarOpen(false)} + aria-hidden="true" + /> + )} + + {/* ── SIDEBAR — slide-in drawer on mobile, always visible on md+ ── */} + + + {/* ── MAIN CONTENT ── */} +
+ + {/* Top Header */} +
+ + {/* Hamburger — only on mobile */} + + +

+ Panel de Instructor +

+ +
+ + + {/* Profile dropdown trigger */} +
+ +
+ + {/* Dropdown — rendered via portal in document.body to avoid overflow/stacking issues */} + {mounted && profileMenuOpen && createPortal( +
+ {/* User info header */} +
+

Instructor Name

+

instructor@rynext.com

+
+ + {/* Menu items */} +
+ setProfileMenuOpen(false)} + className="flex items-center gap-3 px-4 py-2.5 text-sm text-slate-700 dark:text-slate-300 hover:bg-slate-50 dark:hover:bg-slate-800 hover:text-indigo-600 dark:hover:text-indigo-400 transition-colors duration-150" + > + + Ajustes + + +
+ + +
+
, + document.body + )} +
+
+ + {/* Page Content — extra bottom padding on mobile for the bottom nav */} +
+ {children} +
+
+ + {/* ── BOTTOM NAVIGATION BAR — only on mobile ── */} + +
+ ); +} + diff --git a/src/app/instructor/page.tsx b/src/app/instructor/page.tsx new file mode 100644 index 0000000..0fdd13e --- /dev/null +++ b/src/app/instructor/page.tsx @@ -0,0 +1,219 @@ +import React from "react"; +import { + FiTrendingUp, + FiUsers, + FiBookOpen, + FiDollarSign, + FiArrowUpRight, + FiArrowDownRight, + FiClock, + FiStar +} from "react-icons/fi"; + +const stats = [ + { + name: "Ganancias Totales", + value: "$12,450.00", + change: "+12.5%", + trend: "up", + icon: FiDollarSign, + color: "from-emerald-500 to-emerald-600", + bgColor: "bg-emerald-50 dark:bg-emerald-500/10", + iconColor: "text-emerald-600 dark:text-emerald-500" + }, + { + name: "Cursos Activos", + value: "8", + change: "+2", + trend: "up", + icon: FiBookOpen, + color: "from-indigo-500 to-indigo-600", + bgColor: "bg-indigo-50 dark:bg-indigo-500/10", + iconColor: "text-indigo-600 dark:text-indigo-500" + }, + { + name: "Total Estudiantes", + value: "1,204", + change: "+18.2%", + trend: "up", + icon: FiUsers, + color: "from-blue-500 to-blue-600", + bgColor: "bg-blue-50 dark:bg-blue-500/10", + iconColor: "text-blue-600 dark:text-blue-500" + }, + { + name: "Calificación Promedio", + value: "4.8", + change: "-0.1", + trend: "down", + icon: FiStar, + color: "from-amber-500 to-amber-600", + bgColor: "bg-amber-50 dark:bg-amber-500/10", + iconColor: "text-amber-600 dark:text-amber-500" + } +]; + +const recentCourses = [ + { + id: 1, + title: "Desarrollo Web Fullstack con Next.js", + students: 342, + revenue: "$4,250", + status: "Activo", + rating: 4.9 + }, + { + id: 2, + title: "Masterclass de UI/UX Design", + students: 215, + revenue: "$2,890", + status: "Activo", + rating: 4.7 + }, + { + id: 3, + title: "Python para Data Science", + students: 189, + revenue: "$1,950", + status: "Borrador", + rating: 0 + }, +]; + +export default function InstructorDashboard() { + return ( +
+ + {/* Welcome Banner */} +
+
+
+ +
+

¡Hola de nuevo, Instructor! 👋

+

+ Tus cursos están teniendo un excelente rendimiento este mes. Has ganado $1,240.00 en los últimos 7 días. +

+
+ + +
+
+
+ + {/* Stats Grid */} +
+ {stats.map((stat, index) => ( +
+
+
+ +
+ + {stat.trend === 'up' ? : } + {stat.change} + +
+
+

{stat.name}

+

{stat.value}

+
+
+ ))} +
+ + {/* Charts & Lists Section */} +
+ {/* Recent Courses */} +
+
+

Cursos de Mayor Rendimiento

+ +
+ +
+ + + + + + + + + + + {recentCourses.map((course, idx) => ( + + + + + + + ))} + +
Nombre del CursoEstudiantesGananciasEstado
+
+
+ +
+
+

{course.title}

+
+ + {course.rating > 0 ? course.rating : 'N/A'} +
+
+
+
{course.students}{course.revenue} + + {course.status} + +
+
+
+ + {/* Quick Activity */} +
+

Actividad Reciente

+ +
+ {[1, 2, 3, 4].map((i) => ( +
+ {i !== 4 &&
} +
+ +
+
+

Nueva Venta Realizada

+

Alguien compró "Desarrollo Web Fullstack con Next.js"

+

+ Hace {i * 2} horas +

+
+
+ ))} +
+
+
+ +
+ ); +} diff --git a/src/app/instructor/settings/page.tsx b/src/app/instructor/settings/page.tsx new file mode 100644 index 0000000..3bf2652 --- /dev/null +++ b/src/app/instructor/settings/page.tsx @@ -0,0 +1,66 @@ +import React from "react"; +import { FiUser, FiBell, FiLock, FiCreditCard } from "react-icons/fi"; + +export default function SettingsPage() { + return ( +
+
+

Ajustes

+

Configura tu perfil de instructor y preferencias.

+
+ +
+
+ + + + +
+ +
+

Información del Perfil

+ +
+
+ IN +
+
+ +

Recomendado: 500x500px, JPG o PNG.

+
+
+ +
+
+
+ + +
+
+ + +
+
+
+ + +
+ +
+
+
+
+ ); +} diff --git a/src/components/buyer/CourseCard.tsx b/src/components/buyer/CourseCard.tsx index 98c0b4c..9296ee5 100644 --- a/src/components/buyer/CourseCard.tsx +++ b/src/components/buyer/CourseCard.tsx @@ -45,7 +45,7 @@ export const CourseCard: React.FC = ({ course }) => {
{course.title} -
+
{course.badge && ( @@ -123,11 +123,11 @@ export const CourseCard: React.FC = ({ course }) => {
- ({course.reviewsCount.toLocaleString()}) + ({course.reviewsCount.toString()}) • - {course.studentsCount.toLocaleString()} alumnos + {course.studentsCount.toString()} alumnos
diff --git a/src/components/layout/LayoutBase.tsx b/src/components/layout/LayoutBase.tsx index 316b0f4..c0e0d7b 100644 --- a/src/components/layout/LayoutBase.tsx +++ b/src/components/layout/LayoutBase.tsx @@ -11,7 +11,7 @@ export default function LayoutBase({ ...props }: IProps) { const { isDark } = useTheme(); return ( -
+