{
  "$schema": "https://shadcn-vue.com/schema/registry-item.json",
  "name": "student-gradebook-table",
  "title": "Student Gradebook Table",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-vue/blocks/student-gradebook-table/StudentGradebookTable.vue",
      "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport {\n  CalendarCheck,\n  ClipboardCheck,\n  Download,\n  GraduationCap,\n  Mail,\n  MoreHorizontal,\n  Pencil,\n  Plus,\n  User,\n  Users,\n} from 'lucide-vue-next'\nimport { cn } from '@/lib/utils'\nimport { Avatar, AvatarFallback } from '@/components/ui/avatar'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent } from '@/components/ui/card'\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from '@/components/ui/dropdown-menu'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'\n\nexport type LetterGrade = 'A+' | 'A' | 'A-' | 'B+' | 'B' | 'B-'\n\nexport interface StudentGradeRecord {\n  id: string\n  name: string\n  studentId: string\n  homework: string\n  midterm: string\n  labProjects: string\n  finalProject: string\n  overallGrade: string\n  letterGrade: LetterGrade\n  attendanceRate: string\n  absences: number\n}\n\nconst props = defineProps<{\n  class?: HTMLAttributes['class']\n}>()\n\nconst metrics = [\n  {\n    title: 'Class GPA',\n    value: '3.62 / 4.0',\n    description: '+0.18 vs departmental target',\n    icon: GraduationCap,\n    iconClass: 'bg-success/10 text-success',\n    valueClass: 'text-success',\n  },\n  {\n    title: 'Total Enrolled Students',\n    value: '28 students',\n    description: '100% active roster',\n    icon: Users,\n    iconClass: 'bg-info/10 text-info',\n    valueClass: 'text-foreground',\n  },\n  {\n    title: 'Assignments Graded',\n    value: '12 / 14 assignments',\n    description: '2 pending final submissions',\n    icon: ClipboardCheck,\n    iconClass: 'bg-chart-1/10 text-chart-1',\n    valueClass: 'text-foreground',\n  },\n  {\n    title: 'Class Attendance Rate',\n    value: '96.2% average',\n    description: '36 lectures & labs logged',\n    icon: CalendarCheck,\n    iconClass: 'bg-warning/10 text-warning',\n    valueClass: 'text-foreground',\n  },\n]\n\nconst gradeBadgeConfig: Record<LetterGrade, { class: string }> = {\n  'A+': {\n    class: 'bg-success/10 text-success border-success/20 font-semibold',\n  },\n  A: {\n    class: 'bg-success/10 text-success border-success/20 font-semibold',\n  },\n  'A-': {\n    class: 'bg-success/10 text-success border-success/20 font-semibold',\n  },\n  'B+': {\n    class: 'bg-info/10 text-info border-info/20 font-semibold',\n  },\n  B: {\n    class: 'bg-warning/10 text-warning border-warning/20 font-semibold',\n  },\n  'B-': {\n    class: 'bg-warning/10 text-warning border-warning/20 font-semibold',\n  },\n}\n\nconst students: StudentGradeRecord[] = [\n  {\n    id: 's1',\n    name: 'Elena Rostova',\n    studentId: '#STU-84920',\n    homework: '95.0%',\n    midterm: '92.0%',\n    labProjects: '98.0%',\n    finalProject: '94.0%',\n    overallGrade: '94.5%',\n    letterGrade: 'A',\n    attendanceRate: '100%',\n    absences: 0,\n  },\n  {\n    id: 's2',\n    name: 'David Chen',\n    studentId: '#STU-84921',\n    homework: '88.0%',\n    midterm: '91.0%',\n    labProjects: '86.0%',\n    finalProject: '89.0%',\n    overallGrade: '88.6%',\n    letterGrade: 'B+',\n    attendanceRate: '96%',\n    absences: 1,\n  },\n  {\n    id: 's3',\n    name: 'Sarah Jenkins',\n    studentId: '#STU-84922',\n    homework: '98.0%',\n    midterm: '96.0%',\n    labProjects: '100.0%',\n    finalProject: '95.0%',\n    overallGrade: '97.1%',\n    letterGrade: 'A',\n    attendanceRate: '100%',\n    absences: 0,\n  },\n  {\n    id: 's4',\n    name: 'Marcus Vance',\n    studentId: '#STU-84923',\n    homework: '82.0%',\n    midterm: '79.0%',\n    labProjects: '85.0%',\n    finalProject: '80.0%',\n    overallGrade: '81.4%',\n    letterGrade: 'B',\n    attendanceRate: '92%',\n    absences: 2,\n  },\n  {\n    id: 's5',\n    name: 'Sofia Rossi',\n    studentId: '#STU-84924',\n    homework: '91.0%',\n    midterm: '88.0%',\n    labProjects: '94.0%',\n    finalProject: '90.0%',\n    overallGrade: '90.6%',\n    letterGrade: 'A-',\n    attendanceRate: '98%',\n    absences: 1,\n  },\n  {\n    id: 's6',\n    name: 'Alex Rivera',\n    studentId: '#STU-84925',\n    homework: '84.0%',\n    midterm: '86.0%',\n    labProjects: '82.0%',\n    finalProject: '85.0%',\n    overallGrade: '84.3%',\n    letterGrade: 'B',\n    attendanceRate: '94%',\n    absences: 2,\n  },\n]\n\nfunction initials(name: string) {\n  return name\n    .split(' ')\n    .map((part) => part[0])\n    .slice(0, 2)\n    .join('')\n    .toUpperCase()\n}\n</script>\n\n<template>\n  <div data-slot=\"student-gradebook-table\" :class=\"cn('w-full space-y-6', props.class)\">\n    <!-- Header -->\n    <div class=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n      <div>\n        <div class=\"flex flex-wrap items-center gap-2.5\">\n          <h2 class=\"text-2xl font-bold tracking-tight\">CS 301: Advanced Software Systems &amp; Compilers</h2>\n          <Badge variant=\"outline\" class=\"font-mono text-xs\">CS-301-B</Badge>\n        </div>\n        <div class=\"text-muted-foreground mt-1.5 flex flex-wrap items-center gap-2 text-sm\">\n          <span>Fall 2026 · Section B</span>\n          <span class=\"text-foreground inline-flex items-center gap-1 font-medium\">\n            Class Average: <span class=\"tabular-nums\">88.4%</span> · Grade B+\n          </span>\n        </div>\n      </div>\n      <div class=\"flex flex-wrap items-center gap-2.5\">\n        <Button aria-label=\"Download attachment\" variant=\"outline\">\n          <Download aria-hidden=\"true\" />\n          Export Grades CSV\n        </Button>\n        <Button>\n          <Plus aria-hidden=\"true\" />\n          New Grade Entry\n        </Button>\n      </div>\n    </div>\n\n    <!-- 4 Class Overview Metric Cards -->\n    <div class=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n      <Card v-for=\"metric in metrics\" :key=\"metric.title\" class=\"shadow-xs\">\n        <CardContent class=\"space-y-2 p-5\">\n          <div class=\"flex items-center justify-between\">\n            <p class=\"text-muted-foreground text-sm font-medium\">{{ metric.title }}</p>\n            <div :class=\"cn('flex size-8 items-center justify-center rounded-md', metric.iconClass)\">\n              <component :is=\"metric.icon\" aria-hidden=\"true\" class=\"size-4\" />\n            </div>\n          </div>\n          <div>\n            <p :class=\"cn('text-2xl font-bold tracking-tight tabular-nums', metric.valueClass)\">\n              {{ metric.value }}\n            </p>\n            <p class=\"text-muted-foreground mt-1 text-xs\">{{ metric.description }}</p>\n          </div>\n        </CardContent>\n      </Card>\n    </div>\n\n    <!-- Gradebook Table -->\n    <div class=\"bg-card overflow-x-auto rounded-lg border shadow-xs\">\n      <Table>\n        <TableHeader>\n          <TableRow>\n            <TableHead>Student</TableHead>\n            <TableHead class=\"text-right\">Homework (25%)</TableHead>\n            <TableHead class=\"text-right\">Midterm (30%)</TableHead>\n            <TableHead class=\"text-right\">Lab Projects (25%)</TableHead>\n            <TableHead class=\"text-right\">Final Project (20%)</TableHead>\n            <TableHead class=\"text-right font-semibold\">Overall Grade</TableHead>\n            <TableHead class=\"text-center\">Letter Grade</TableHead>\n            <TableHead>Attendance</TableHead>\n            <TableHead class=\"w-12 text-right\">\n              <span class=\"sr-only\">Actions</span>\n            </TableHead>\n          </TableRow>\n        </TableHeader>\n        <TableBody>\n          <TableRow v-for=\"student in students\" :key=\"student.id\" class=\"hover:bg-muted/50\">\n            <TableCell>\n              <div class=\"flex items-center gap-3\">\n                <Avatar class=\"size-8\">\n                  <AvatarFallback class=\"text-xs font-medium\">{{ initials(student.name) }}</AvatarFallback>\n                </Avatar>\n                <div class=\"min-w-0\">\n                  <p class=\"truncate text-sm font-semibold\">{{ student.name }}</p>\n                  <p class=\"text-muted-foreground font-mono text-xs\">{{ student.studentId }}</p>\n                </div>\n              </div>\n            </TableCell>\n            <TableCell class=\"text-right font-medium tabular-nums\">{{ student.homework }}</TableCell>\n            <TableCell class=\"text-right font-medium tabular-nums\">{{ student.midterm }}</TableCell>\n            <TableCell class=\"text-right font-medium tabular-nums\">{{ student.labProjects }}</TableCell>\n            <TableCell class=\"text-right font-medium tabular-nums\">{{ student.finalProject }}</TableCell>\n            <TableCell class=\"text-foreground text-right font-bold tabular-nums\">{{ student.overallGrade }}</TableCell>\n            <TableCell class=\"text-center\">\n              <Badge variant=\"outline\" :class=\"cn('font-semibold', gradeBadgeConfig[student.letterGrade].class)\">\n                {{ student.letterGrade }}\n              </Badge>\n            </TableCell>\n            <TableCell>\n              <div class=\"inline-flex items-center gap-1.5 text-xs\">\n                <span\n                  class=\"inline-block size-1.5 rounded-full\"\n                  :class=\"student.absences === 0 ? 'bg-success' : 'bg-warning'\"\n                  aria-hidden=\"true\"\n                />\n                <span class=\"text-foreground font-medium tabular-nums\">{{ student.attendanceRate }}</span>\n                <span class=\"text-muted-foreground\">\n                  ·\n                  {{\n                    student.absences === 0\n                      ? '0 absences'\n                      : `${student.absences} absence${student.absences > 1 ? 's' : ''}`\n                  }}\n                </span>\n              </div>\n            </TableCell>\n            <TableCell class=\"text-right\">\n              <DropdownMenu>\n                <DropdownMenuTrigger as-child>\n                  <Button variant=\"ghost\" size=\"icon-sm\" class=\"text-muted-foreground\">\n                    <MoreHorizontal aria-hidden=\"true\" />\n                    <span class=\"sr-only\">Open actions for {{ student.name }}</span>\n                  </Button>\n                </DropdownMenuTrigger>\n                <DropdownMenuContent align=\"end\" class=\"w-48\">\n                  <DropdownMenuItem>\n                    <Pencil aria-hidden=\"true\" />\n                    Edit Grades\n                  </DropdownMenuItem>\n                  <DropdownMenuItem>\n                    <User aria-hidden=\"true\" />\n                    View Student Profile\n                  </DropdownMenuItem>\n                  <DropdownMenuSeparator />\n                  <DropdownMenuItem>\n                    <Mail aria-hidden=\"true\" />\n                    Send Email Alert\n                  </DropdownMenuItem>\n                </DropdownMenuContent>\n              </DropdownMenu>\n            </TableCell>\n          </TableRow>\n        </TableBody>\n      </Table>\n    </div>\n\n    <!-- Table Footer / Pagination -->\n    <div class=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n      <p class=\"text-muted-foreground text-sm\">\n        Showing <span class=\"text-foreground font-medium\">6</span> of\n        <span class=\"text-foreground font-medium\">28</span> enrolled students\n      </p>\n      <div class=\"flex items-center gap-2\">\n        <Button variant=\"outline\" size=\"sm\" disabled> Previous </Button>\n        <Button variant=\"outline\" size=\"sm\"> Next </Button>\n      </div>\n    </div>\n  </div>\n</template>\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/StudentGradebookTable.vue"
    }
  ],
  "dependencies": [
    "lucide-vue-next"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/vue/avatar.json",
    "https://uipkge.dev/r/vue/badge.json",
    "https://uipkge.dev/r/vue/button.json",
    "https://uipkge.dev/r/vue/card.json",
    "https://uipkge.dev/r/vue/dropdown-menu.json",
    "https://uipkge.dev/r/vue/table.json"
  ],
  "description": "Academic gradebook ledger with course header, weighted assignment categories (homework, midterm, labs, final project), class GPA & enrollment metric cards, overall percentage, letter grade badges, attendance tags, and student action menus.",
  "categories": [
    "education",
    "app",
    "data",
    "dashboard"
  ]
}