import React from 'react'; import { Link } from 'react-router-dom'; import { ArrowRight, Check, Sparkles } from 'lucide-react'; import { cn } from '@/lib/utils'; import { Badge, Drawer } from '@/components/ds'; import { DIFF_TONE, owliverCriteria, statusOf, STATUS_TONE, trainingKinds, trainingOutline, TYPE_HINT, TYPE_LABEL, typeOf, } from './challengeMeta'; /** * One skill, read end to end: what it teaches, how it is proven, what Owliver * checks, what passing means, and how the workforce has done with it. * * A drawer rather than a route, because this is the managing view of a record * whose route already belongs to something else — `/admin/university/:id` runs * the challenge itself, which is the worker's experience and stays untouched. * The link out to it is offered at the bottom for an admin who wants to see what * the workforce sees. * * Sections appear only when the record has something to put in them. Reading a * heading with nothing under it teaches the reader to distrust the rest. */ export function SkillDetail({ course, open, onOpenChange, usage }) { if (!course) return null; const status = statusOf(course); const type = typeOf(course); const criteria = owliverCriteria(course); const outline = trainingOutline(course); const kinds = trainingKinds(course); const rubric = course.challenge?.rubric || []; return (
{status} {course.difficulty && ( {course.difficulty} )} {course.estimated_minutes > 0 && ( {course.estimated_minutes} min )} {course.proof_skill && ( · Verifies {course.proof_skill} )}
{course.description && (

{course.description}

)} {outline.length > 0 ? (
    {outline.map((step, i) => (
  1. {i + 1} {step}
  2. ))}
) : (

This skill carries no written outline. It teaches through {' '} {kinds.length ? kinds.join(' and ').toLowerCase() : 'the challenge itself'}.

)} {course.quiz?.length > 0 && (

Includes a {course.quiz.length}-question knowledge check.

)}
{course.challenge && (

{TYPE_LABEL[type]}

{TYPE_HINT[type]}

{course.challenge.prompt && (

“{course.challenge.prompt}”

)}
)} {criteria.length > 0 && (
    {rubric.map((r) => (
  • {r.weight != null && ( {r.weight}% )}
  • ))}
)} {course.pass_score > 0 && (

A submission verifies the skill at{' '} {course.pass_score} or above {course.badge_reward ? <>, and earns the {course.badge_reward} badge. : '.'}

)} {/* Usage is counted from worker profiles. Assignment and "in progress" have no field behind them, so the two states the records do carry are the two states shown. */} {usage && (usage.completed > 0 || usage.verified > 0) && (
{[ { label: 'Completed', value: usage.completed }, { label: 'Verified', value: usage.verified }, ].map((row) => (
{row.label}
{row.value}
))}
)} Open the challenge as the workforce sees it
); } /** A titled region of the record. */ /** @param {any} props */ function Block({ title, meta, icon: Icon, children }) { return (

{Icon &&

{meta && {meta}}
{children}
); }