Pending course, rest ready for launch
This commit is contained in:
97
components/courses/CourseProgressCard.tsx
Normal file
97
components/courses/CourseProgressCard.tsx
Normal file
@@ -0,0 +1,97 @@
|
||||
import Link from "next/link";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
type CourseAction = {
|
||||
label: string;
|
||||
href?: string;
|
||||
disabled?: boolean;
|
||||
};
|
||||
|
||||
type CourseProgressCardProps = {
|
||||
progressPercent: number;
|
||||
completedLessons: number;
|
||||
totalLessons: number;
|
||||
instructor: string;
|
||||
durationLabel: string;
|
||||
stageLabel: string;
|
||||
availabilityLabel: string;
|
||||
primaryAction: CourseAction;
|
||||
secondaryAction?: CourseAction;
|
||||
helperText?: string;
|
||||
};
|
||||
|
||||
function ActionButton({ action, secondary = false }: { action: CourseAction; secondary?: boolean }) {
|
||||
const classes = cn(
|
||||
"inline-flex w-full items-center justify-center rounded-xl px-4 py-3 text-sm font-semibold transition-colors",
|
||||
secondary
|
||||
? "border border-border bg-card text-foreground hover:bg-accent"
|
||||
: "acve-button-primary hover:brightness-105",
|
||||
action.disabled && "cursor-not-allowed opacity-55 hover:brightness-100",
|
||||
);
|
||||
|
||||
if (!action.href || action.disabled) {
|
||||
return (
|
||||
<button className={classes} disabled type="button">
|
||||
{action.label}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Link className={classes} href={action.href}>
|
||||
{action.label}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
export default function CourseProgressCard({
|
||||
progressPercent,
|
||||
completedLessons,
|
||||
totalLessons,
|
||||
instructor,
|
||||
durationLabel,
|
||||
stageLabel,
|
||||
availabilityLabel,
|
||||
primaryAction,
|
||||
secondaryAction,
|
||||
helperText,
|
||||
}: CourseProgressCardProps) {
|
||||
return (
|
||||
<aside className="acve-panel p-5 md:p-6">
|
||||
<p className="text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground">Seguimiento</p>
|
||||
<p className="mt-3 text-3xl font-semibold text-foreground">{progressPercent}%</p>
|
||||
<p className="mt-1 text-sm text-muted-foreground">
|
||||
{completedLessons}/{totalLessons} lecciones completadas
|
||||
</p>
|
||||
<div className="mt-3 h-2 w-full rounded-full bg-primary/15">
|
||||
<div className="h-2 rounded-full bg-primary transition-all" style={{ width: `${Math.max(0, Math.min(100, progressPercent))}%` }} />
|
||||
</div>
|
||||
|
||||
<dl className="mt-5 space-y-3 border-t border-border/70 pt-4 text-sm">
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<dt className="text-muted-foreground">Instructor</dt>
|
||||
<dd className="text-right font-medium text-foreground">{instructor}</dd>
|
||||
</div>
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<dt className="text-muted-foreground">Duración</dt>
|
||||
<dd className="text-right font-medium text-foreground">{durationLabel}</dd>
|
||||
</div>
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<dt className="text-muted-foreground">Etapa</dt>
|
||||
<dd className="text-right font-medium text-foreground">{stageLabel}</dd>
|
||||
</div>
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<dt className="text-muted-foreground">Disponibilidad</dt>
|
||||
<dd className="text-right font-medium text-foreground">{availabilityLabel}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
|
||||
<div className="mt-5 space-y-2">
|
||||
<ActionButton action={primaryAction} />
|
||||
{secondaryAction ? <ActionButton action={secondaryAction} secondary /> : null}
|
||||
</div>
|
||||
|
||||
{helperText ? <p className="mt-3 text-xs leading-relaxed text-muted-foreground">{helperText}</p> : null}
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user