Education
Class Participation Card - Engagement Metrics
Monitor student class participation and engagement levels. Track discussion participation and active learning metrics.
Class Participation Card
The Class Participation Card displays student participation and engagement scores with a visual progress bar.
Preview
Installation
npx shadcn@latest add https://vectormotion.vercel.app/registry/class-participation-card.jsonClass Participation Card
'use client'import React from 'react';import { Hand } from 'lucide-react';import { motion } from 'motion/react';import { clsx, type ClassValue } from "clsx";import { twMerge } from "tailwind-merge";import { ResponsiveContainer, AreaChart, Area, Tooltip } from 'recharts';function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs));}interface ParticipationData { session: number; score: number; [key: string]: any;}interface ClassParticipationCardProps { className?: string; title?: string; subtitle?: string; scoreLabel?: string; scoreValue?: string; scoreStatus?: string; data?: ParticipationData[];}const DEFAULT_DATA: ParticipationData[] = [ { session: 1, score: 65 }, { session: 2, score: 70 }, { session: 3, score: 68 }, { session: 4, score: 75 }, { session: 5, score: 85 }, { session: 6, score: 82 }, { session: 7, score: 88 },];const DEFAULT_TITLE = "Participation";const DEFAULT_SUBTITLE = "Engagement Trends";const DEFAULT_SCORE_VALUE = "85%";const DEFAULT_SCORE_STATUS = "High";export const ClassParticipationCard: React.FC<ClassParticipationCardProps> = ({ className = "", title = DEFAULT_TITLE, subtitle = DEFAULT_SUBTITLE, scoreValue = DEFAULT_SCORE_VALUE, scoreStatus = DEFAULT_SCORE_STATUS, data = DEFAULT_DATA,}) => { return ( <motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5, delay: 0.3 }} className={cn( "relative overflow-hidden rounded-2xl border border-border bg-card text-card-foreground shadow-sm transition-all hover:border-amber-300 dark:hover:border-amber-700 hover:shadow-md flex flex-col h-full", className )} > <div className="p-5 flex flex-col h-full relative z-10"> <div className="mb-4 flex items-start justify-between"> <div> <h3 className="font-bold text-lg text-foreground"> {title} </h3> <div className="flex items-center gap-2 mt-1"> <span className="text-2xl font-bold text-foreground">{scoreValue}</span> <span className="text-xs font-medium text-emerald-500 bg-emerald-500/10 px-1.5 py-0.5 rounded-full"> {scoreStatus} </span> </div> <p className="text-sm text-muted-foreground mt-1"> {subtitle} </p> </div> <div className="rounded-xl bg-amber-500/10 p-2.5 text-amber-500 dark:text-amber-400 flex items-center justify-center ring-1 ring-amber-100 dark:ring-amber-800"> <Hand className="h-5 w-5" /> </div> </div> <div className="flex-1 w-full min-h-[100px]"> <ResponsiveContainer width="100%" height="100%"> <AreaChart data={data}> <defs> <linearGradient id="participationGradient" x1="0" y1="0" x2="0" y2="1"> <stop offset="5%" stopColor="#f59e0b" stopOpacity={0.3} /> <stop offset="95%" stopColor="#f59e0b" stopOpacity={0} /> </linearGradient> </defs> <Tooltip cursor={false} content={() => null} /> <Area type="monotone" dataKey="score" stroke="#f59e0b" strokeWidth={2} fill="url(#participationGradient)" /> </AreaChart> </ResponsiveContainer> </div> </div> <div className="absolute -bottom-4 -right-4 z-0 opacity-5 pointer-events-none"> <Hand className="w-32 h-32 text-amber-500" /> </div> </motion.div> );};Usage
This component helps track and visualize student participation levels in class activities, encouraging active engagement.
Prop
Type