import { useEffect, useState } from "react"; import { Dialog, DialogContent, DialogHeader } from "../components/ui/dialog"; import { api } from "../utils/api"; import { useAuthStore } from "../stores/authStore"; import { Loader, X } from "lucide-react"; interface LessonModalProps { lessonId: string | null; open: boolean; onOpenChange: (open: boolean) => void; } const STYLES = ` @import url('https://fonts.googleapis.com/css2?family=Nunito:wght@400;700;800;900&family=Nunito+Sans:wght@400;600;700&display=swap'); /* Override Dialog defaults */ .lm-content { font-family: 'Nunito', sans-serif; background: #fffbf4; border: 2.5px solid #f3f4f6; border-radius: 28px !important; padding: 0; overflow: hidden; max-width: 680px; width: calc(100vw - 2rem); box-shadow: 0 20px 60px rgba(0,0,0,0.12); max-height: 90vh; display: flex; flex-direction: column; } /* Header bar */ .lm-header { display: flex; align-items: flex-start; justify-content: space-between; padding: 1.25rem 1.5rem 0; flex-shrink: 0; gap: 1rem; } .lm-title-wrap { display:flex;flex-direction:column;gap:0.2rem; flex:1; } .lm-eyebrow { font-size: 0.62rem; font-weight: 800; letter-spacing: 0.16em; text-transform: uppercase; color: #a855f7; } .lm-title { font-size: 1.2rem; font-weight: 900; color: #1e1b4b; letter-spacing: -0.01em; line-height: 1.25; } .lm-close-btn { width: 34px; height: 34px; flex-shrink: 0; border-radius: 50%; border: 2.5px solid #f3f4f6; background: white; cursor: pointer; display: flex; align-items: center; justify-content: center; box-shadow: 0 2px 8px rgba(0,0,0,0.06); transition: all 0.15s ease; } .lm-close-btn:hover { border-color: #fecdd3; background: #fff1f2; } /* Scrollable body */ .lm-body { overflow-y: auto; flex: 1; padding: 1rem 1.5rem 1.5rem; display: flex; flex-direction: column; gap: 1rem; -webkit-overflow-scrolling: touch; } /* Video player */ .lm-video { width: 100%; border-radius: 18px; aspect-ratio: 16/9; background: #1e1b4b; display: block; } /* Topic chip */ .lm-topic-chip { display: inline-flex; align-items: center; gap: 0.4rem; background: #f3e8ff; border: 2px solid #e9d5ff; border-radius: 100px; padding: 0.3rem 0.8rem; font-size: 0.7rem; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase; color: #9333ea; width: fit-content; } /* Description & content cards */ .lm-card { background: white; border: 2.5px solid #f3f4f6; border-radius: 18px; padding: 1rem 1.1rem; box-shadow: 0 3px 10px rgba(0,0,0,0.04); } .lm-card-label { font-size: 0.62rem; font-weight: 800; letter-spacing: 0.14em; text-transform: uppercase; color: #9ca3af; margin-bottom: 0.4rem; } .lm-card-text { font-family: 'Nunito Sans', sans-serif; font-size: 0.88rem; font-weight: 600; color: #374151; line-height: 1.6; } /* Loading state */ .lm-loading { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.75rem; padding: 3rem 1.5rem; flex: 1; } .lm-loading-spinner { animation: lmSpin 0.8s linear infinite; } @keyframes lmSpin { to { transform: rotate(360deg); } } .lm-loading-text { font-size: 0.85rem; font-weight: 700; color: #9ca3af; } `; export const LessonModal = ({ lessonId, open, onOpenChange, }: LessonModalProps) => { const user = useAuthStore((state) => state.user); const [loading, setLoading] = useState(false); const [lesson, setLesson] = useState(null); useEffect(() => { if (!open || !lessonId || !user) return; const fetchLesson = async () => { try { setLoading(true); const authStorage = localStorage.getItem("auth-storage"); if (!authStorage) return; const { state: { token }, } = JSON.parse(authStorage) as { state?: { token?: string } }; if (!token) return; const response = await api.fetchLessonById(token, lessonId); setLesson(response); } catch (err) { console.error("Failed to fetch lesson", err); } finally { setLoading(false); } }; fetchLesson(); }, [open, lessonId, user]); return ( {/* Header */}
📖 Lesson

{loading ? "Loading..." : (lesson?.title ?? "Lesson details")}

{/* Body */} {loading ? (

Loading lesson...

) : ( lesson && (
{lesson.video_url && (
) )}
); };