({ showPreview, setShowPreview, track }: TrackPreviewProps)
| 21 | }; |
| 22 | |
| 23 | export function TrackPreview({ showPreview, setShowPreview, track }: TrackPreviewProps) { |
| 24 | const [isMediumOrLarger, setIsMediumOrLarger] = useState(false); |
| 25 | |
| 26 | const updateScreenSize = () => { |
| 27 | setIsMediumOrLarger(window.innerWidth >= 768); |
| 28 | }; |
| 29 | |
| 30 | useEffect(() => { |
| 31 | updateScreenSize(); // Set the initial state |
| 32 | window.addEventListener("resize", updateScreenSize); // Add resize listener |
| 33 | |
| 34 | return () => { |
| 35 | window.removeEventListener("resize", updateScreenSize); // Cleanup listener on unmount |
| 36 | }; |
| 37 | }, []); |
| 38 | |
| 39 | const truncatedDescription = isMediumOrLarger ? track.description : truncateDescription(track.description, 15); |
| 40 | |
| 41 | return ( |
| 42 | <Dialog open={showPreview} onOpenChange={() => setShowPreview(false)}> |
| 43 | <DialogContent className="flex items-center gap-4"> |
| 44 | <div className="flex flex-col gap-4 w-full"> |
| 45 | <img src={track.image} className="h-[25vh] w-full object-cover rounded-lg" /> |
| 46 | <div className="flex flex-col gap-4 bg-primary/5 rounded-lg p-4"> |
| 47 | <div className="flex flex-col gap-4"> |
| 48 | <h3 className="text-xl md:text-2xl font-semibold w-full tracking-tight">{track.title}</h3> |
| 49 | <div className="flex items-center gap-4"> |
| 50 | {track.categories.map((item: any, idx: number) => ( |
| 51 | <p |
| 52 | key={item.category.id} |
| 53 | className="bg-secondary/25 border border-primary/10 rounded-lg px-3 py-2 text-sm w-fit cursor-default" |
| 54 | > |
| 55 | {item.category.category}{" "} |
| 56 | </p> |
| 57 | ))} |
| 58 | </div> |
| 59 | </div> |
| 60 | <p className="md:text-lg tracking-tighter line-clamp-3 text-primary/60">{truncatedDescription}</p> |
| 61 | </div> |
| 62 | <div className="flex flex-col gap-4 w-full"> |
| 63 | <div className="flex gap-2 items-center"> |
| 64 | <p className="flex tracking-tighter gap-2 text-primary text-lg md:text-xl font-semibold"> |
| 65 | {track.problems.length} Chapters |
| 66 | </p> |
| 67 | <p className="flex tracking-tight gap-2 text-primary/60 md:text-lg"> |
| 68 | {formatDistanceToNow(new Date(track.createdAt), { addSuffix: true })} |
| 69 | </p> |
| 70 | </div> |
| 71 | <div className="max-h-[25vh] overflow-y-auto flex flex-col gap-3 w-full py-2"> |
| 72 | {track.problems.map((topic: any, idx: number) => ( |
| 73 | <Link key={topic.id} href={`/tracks/${track.id}/${track.problems[idx]?.id}`}> |
| 74 | <div className="cursor-pointer hover:-translate-y-1 flex items-center justify-between bg-primary/5 rounded-lg px-4 py-3 hover:bg-primary/10 transition-all duration-300 scroll-smooth w-full"> |
| 75 | {topic.title} |
| 76 | <ArrowRight className="size-4" /> |
| 77 | </div> |
| 78 | </Link> |
| 79 | ))} |
| 80 | </div> |
nothing calls this directly
no test coverage detected