feat(lesson): add lesson modal
This commit is contained in:
@ -1,4 +1,5 @@
|
||||
// import { useAuthStore } from "../../stores/authStore";
|
||||
import { useAuthStore } from "../../stores/authStore";
|
||||
import { useEffect, useState } from "react";
|
||||
import {
|
||||
Card,
|
||||
CardHeader,
|
||||
@ -12,9 +13,52 @@ import {
|
||||
TabsList,
|
||||
TabsTrigger,
|
||||
} from "../../components/ui/tabs";
|
||||
import { api } from "../../utils/api";
|
||||
import { type Lesson } from "../../types/lesson";
|
||||
import { LessonSkeleton } from "../../components/LessonSkeleton";
|
||||
import { LessonModal } from "../../components/LessonModal";
|
||||
|
||||
export const Lessons = () => {
|
||||
// const user = useAuthStore((state) => state.user);
|
||||
const user = useAuthStore((state) => state.user);
|
||||
const [lessons, setLessons] = useState<Lesson[]>([]);
|
||||
const [lessonLoading, setLessonlLoading] = useState(true);
|
||||
|
||||
const [selectedLessonId, setSelectedLessonId] = useState<string | null>(null);
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
|
||||
const handleLessonClick = (lessonId: string) => {
|
||||
setSelectedLessonId(lessonId);
|
||||
setIsModalOpen(true);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const fetchAllLessons = async () => {
|
||||
if (!user) return;
|
||||
|
||||
try {
|
||||
setLessonlLoading(true);
|
||||
const authStorage = localStorage.getItem("auth-storage");
|
||||
if (!authStorage) return;
|
||||
|
||||
const parsed = JSON.parse(authStorage) as {
|
||||
state?: { token?: string };
|
||||
};
|
||||
|
||||
const token = parsed.state?.token;
|
||||
if (!token) return;
|
||||
|
||||
const response = await api.fetchAllLessons(token);
|
||||
|
||||
setLessonlLoading(false);
|
||||
setLessons(response.data);
|
||||
} catch (error) {
|
||||
setLessonlLoading(false);
|
||||
console.error("Error fetching lessons:", error);
|
||||
}
|
||||
};
|
||||
|
||||
fetchAllLessons();
|
||||
}, [user]);
|
||||
|
||||
return (
|
||||
<main className="min-h-screen space-y-6 max-w-7xl mx-auto px-8 sm:px-6 lg:px-8 py-8">
|
||||
@ -43,61 +87,99 @@ export const Lessons = () => {
|
||||
</TabsList>
|
||||
<TabsContent value="rw" className="pt-4">
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<Card className="py-0 pb-5 rounded-4xl overflow-hidden">
|
||||
<CardHeader className="w-full py-0 px-0">
|
||||
<img
|
||||
src="https://placehold.co/600x400"
|
||||
alt="Video Thumbnail"
|
||||
className="w-full h-auto rounded"
|
||||
/>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-2">
|
||||
<CardTitle>Video Title</CardTitle>
|
||||
<CardDescription>Video Description</CardDescription>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card className="py-0 pb-5 rounded-4xl overflow-hidden">
|
||||
<CardHeader className="w-full py-0 px-0">
|
||||
<img
|
||||
src="https://placehold.co/600x400"
|
||||
alt="Video Thumbnail"
|
||||
className="w-full h-auto rounded"
|
||||
/>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-2">
|
||||
<CardTitle>Video Title</CardTitle>
|
||||
<CardDescription>Video Description</CardDescription>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card className="py-0 pb-5 rounded-4xl overflow-hidden">
|
||||
<CardHeader className="w-full py-0 px-0">
|
||||
<img
|
||||
src="https://placehold.co/600x400"
|
||||
alt="Video Thumbnail"
|
||||
className="w-full h-auto rounded"
|
||||
/>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-2">
|
||||
<CardTitle>Video Title</CardTitle>
|
||||
<CardDescription>Video Description</CardDescription>
|
||||
</CardContent>
|
||||
</Card>
|
||||
{lessonLoading && (
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
{Array.from({ length: 6 }).map((_, i) => (
|
||||
<LessonSkeleton key={i} />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
{!lessonLoading && lessons.length === 0 && (
|
||||
<div className="text-center text-muted-foreground py-12">
|
||||
No lessons available
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!lessonLoading && lessons.length > 0 && (
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
{lessons.map((lesson) => (
|
||||
<Card
|
||||
key={lesson.id}
|
||||
onClick={() => handleLessonClick(lesson.id)}
|
||||
className="py-0 pb-5 rounded-4xl overflow-hidden"
|
||||
>
|
||||
<CardHeader className="w-full py-0 px-0">
|
||||
<img
|
||||
src={lesson.thumbnail_url}
|
||||
alt={lesson.title}
|
||||
className="w-full h-auto"
|
||||
/>
|
||||
</CardHeader>
|
||||
|
||||
<CardContent className="space-y-2">
|
||||
<CardTitle>{lesson.title}</CardTitle>
|
||||
<CardDescription>{lesson.topic.name}</CardDescription>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
<LessonModal
|
||||
open={isModalOpen}
|
||||
lessonId={selectedLessonId}
|
||||
onOpenChange={(open) => {
|
||||
setIsModalOpen(open);
|
||||
if (!open) setSelectedLessonId(null);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</TabsContent>
|
||||
<TabsContent value="math" className="pt-4">
|
||||
<Card className="py-0 pb-8 rounded-4xl overflow-hidden">
|
||||
<CardHeader className="w-full py-0 px-0">
|
||||
<img
|
||||
src="https://placehold.co/600x400"
|
||||
alt="Video Thumbnail"
|
||||
className="w-full h-auto rounded"
|
||||
/>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-2">
|
||||
<CardTitle>Video Title</CardTitle>
|
||||
<CardDescription>Video Description</CardDescription>
|
||||
</CardContent>
|
||||
</Card>
|
||||
{lessonLoading && (
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
{Array.from({ length: 6 }).map((_, i) => (
|
||||
<LessonSkeleton key={i} />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
{!lessonLoading && lessons.length === 0 && (
|
||||
<div className="text-center text-muted-foreground py-12">
|
||||
No lessons available
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!lessonLoading && lessons.length > 0 && (
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
{lessons.map((lesson) => (
|
||||
<Card
|
||||
key={lesson.id}
|
||||
onClick={() => handleLessonClick(lesson.id)}
|
||||
className="py-0 pb-5 rounded-4xl overflow-hidden"
|
||||
>
|
||||
<CardHeader className="w-full py-0 px-0">
|
||||
<img
|
||||
src={lesson.thumbnail_url}
|
||||
alt={lesson.title}
|
||||
className="w-full h-auto"
|
||||
/>
|
||||
</CardHeader>
|
||||
|
||||
<CardContent className="space-y-2">
|
||||
<CardTitle>{lesson.title}</CardTitle>
|
||||
<CardDescription>{lesson.topic.name}</CardDescription>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
<LessonModal
|
||||
open={isModalOpen}
|
||||
lessonId={selectedLessonId}
|
||||
onOpenChange={(open) => {
|
||||
setIsModalOpen(open);
|
||||
if (!open) setSelectedLessonId(null);
|
||||
}}
|
||||
/>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</section>
|
||||
|
||||
Reference in New Issue
Block a user