Files
FL-Akademie/components/course-card.tsx

67 lines
2.1 KiB
TypeScript

import Link from "next/link";
import type { Category, Course, CourseCategory } from "@prisma/client";
import { formatMoney, billingLabel } from "@/lib/format";
import { firstLessonPath } from "@/lib/course-queries";
type CourseWithCats = Course & {
categories: (CourseCategory & { category: Category })[];
modules: { lessons: { slug: string }[] }[];
};
export function CourseCard({
course,
enrolled,
}: {
course: CourseWithCats;
enrolled: boolean;
}) {
const cats = course.categories.map((c) => c.category.name).join(", ");
const first = firstLessonPath(course);
const isFree = course.priceCents === 0;
const priceSuffix = billingLabel(course.billingInterval);
return (
<article className="course-card">
<div className="course-card-body">
<h3>{course.title}</h3>
<p className="course-meta">
Von <strong>{course.authorName}</strong>
{cats ? <> · {cats}</> : null}
</p>
<div className="course-rating" aria-label="Bewertung">
{course.ratingCount > 0 ? (
<>
<span className="stars"></span> {course.ratingAverage.toFixed(2)} ({course.ratingCount})
</>
) : (
<span className="muted">Noch keine Bewertungen</span>
)}
</div>
{!isFree && (
<p className="course-price">
{formatMoney(course.priceCents, course.currency)}
{priceSuffix ? ` ${priceSuffix}` : ""}
</p>
)}
</div>
<div className="course-card-actions">
{enrolled && first ? (
<Link href={first} className="btn btn-primary">
Mit dem Lernen beginnen
</Link>
) : enrolled ? (
<span className="muted">Keine Lektionen</span>
) : isFree ? (
<Link href={`/kurse/${course.slug}`} className="btn btn-primary">
In diesen Kurs einschreiben
</Link>
) : (
<Link href={`/kurse/${course.slug}`} className="btn btn-primary">
Details &amp; Kauf
</Link>
)}
</div>
</article>
);
}