Update Owliver language and suggestions

This commit is contained in:
2026-10-07 19:15:44 +05:30
parent 8ac4e1ee88
commit 81e5979f8f
156 changed files with 7330 additions and 1755 deletions

View File

@@ -10,6 +10,7 @@ import MediaChallenge from './MediaChallenge';
import VideoRecorder from './VideoRecorder';
import HazardIdentifier from './HazardIdentifier';
import OwliverAvatar from '@/components/krow/OwliverAvatar';
import { useTranslation } from 'react-i18next';
/**
* The challenge itself: learn, demonstrate, verify, proof.
@@ -84,6 +85,7 @@ interface ChallengeRunnerProps {
}
export default function ChallengeRunner({ course, profile, onPassed }: ChallengeRunnerProps) {
const { t } = useTranslation();
const [step, setStep] = useState(0);
const [evaluating, setEvaluating] = useState(false);
const [result, setResult] = useState(null);
@@ -134,9 +136,9 @@ export default function ChallengeRunner({ course, profile, onPassed }: Challenge
{!lock.unlocked ? (
<>
<p className="flex items-center gap-2 text-body font-semibold text-ink-1">
<Lock className="h-4 w-4 text-warning" aria-hidden="true" /> Locked — earn this one
<Lock className="h-4 w-4 text-warning" aria-hidden="true" /> {t('challengeRunner.lockedEarnThisOne')}
</p>
<p className="mt-1 text-body-sm text-ink-3">Real work unlocks learning. Complete these first:</p>
<p className="mt-1 text-body-sm text-ink-3">{t('challengeRunner.realWorkUnlocksLearningCompleteThese')}</p>
<ul className="mt-2.5 space-y-1.5">
{lock.reasons.map((r, i) => (
<li key={i} className="flex items-start gap-2 text-body-sm text-ink-2">
@@ -153,7 +155,7 @@ export default function ChallengeRunner({ course, profile, onPassed }: Challenge
<Icon className="h-5 w-5" aria-hidden="true" />
</span>
<div className="min-w-0">
<p className="text-[11px] font-semibold uppercase tracking-wide text-ink-4">Demonstration</p>
<p className="text-[11px] font-semibold uppercase tracking-wide text-ink-4">{t('challengeRunner.demonstration')}</p>
<p className="text-body font-semibold text-ink-1">{TYPE_LABEL[type]}</p>
</div>
</div>
@@ -161,7 +163,7 @@ export default function ChallengeRunner({ course, profile, onPassed }: Challenge
{ch.prompt || course?.description}
</p>
<Button shape="rounded" className="mt-4 w-full" onClick={() => setStep(1)}>
Show me <ArrowRight aria-hidden="true" />
{t('challengeRunner.showMe')} <ArrowRight aria-hidden="true" />
</Button>
</>
)}
@@ -176,8 +178,8 @@ export default function ChallengeRunner({ course, profile, onPassed }: Challenge
<Stepper active={1} />
<div className="flex flex-col items-center gap-2 py-6">
<Spinner size="lg" />
<p className="text-body-sm font-medium text-ink-1">Owliver is evaluating your proof…</p>
<p className="text-caption text-ink-3">Measuring whether you can actually perform.</p>
<p className="text-body-sm font-medium text-ink-1">{t('challengeRunner.owliverIsEvaluatingYourProof')}</p>
<p className="text-caption text-ink-3">{t('challengeRunner.measuringWhetherYouCanActuallyPerform')}</p>
</div>
</Frame>
);
@@ -194,7 +196,7 @@ export default function ChallengeRunner({ course, profile, onPassed }: Challenge
<div className="mb-4 flex items-start gap-2.5 rounded-xl border border-border bg-surface-subtle p-3">
<OwliverAvatar className="h-7 w-7 shrink-0" rounded="rounded-full" />
<div className="min-w-0">
<p className="text-[11px] font-semibold text-krow-blue">Owliver</p>
<p className="text-[11px] font-semibold text-krow-blue">{t('challengeRunner.owliver')}</p>
<p className="text-body-sm leading-relaxed text-ink-2">{ch.prompt || course?.description}</p>
</div>
</div>
@@ -220,7 +222,7 @@ export default function ChallengeRunner({ course, profile, onPassed }: Challenge
<div className="min-w-0">
<p className="font-heading text-title text-ink-1">{passed ? 'Verified by Owliver' : 'Needs work'}</p>
<p className="text-caption tabular-nums text-ink-3">
AI confidence: {Math.round(evidence?.ai_score || 0)}/100
{t('challengeRunner.aiConfidence')} {Math.round(evidence?.ai_score || 0)}/100
</p>
</div>
</div>
@@ -276,11 +278,11 @@ export default function ChallengeRunner({ course, profile, onPassed }: Challenge
{passed ? (
<Button shape="rounded" className="mt-3 w-full" onClick={() => setStep(3)}>
See your proof <ArrowRight aria-hidden="true" />
{t('challengeRunner.seeYourProof')} <ArrowRight aria-hidden="true" />
</Button>
) : (
<Button variant="outline" shape="rounded" className="mt-3 w-full" onClick={() => setStep(1)}>
Try the demonstration again
{t('challengeRunner.tryTheDemonstrationAgain')}
</Button>
)}
</Frame>
@@ -296,8 +298,8 @@ export default function ChallengeRunner({ course, profile, onPassed }: Challenge
<Award className="h-5 w-5" aria-hidden="true" />
</span>
<div className="min-w-0">
<p className="text-body font-semibold text-ink-1">Proof stored</p>
<p className="text-caption text-ink-3">Capability: {course.proof_skill || course.title}</p>
<p className="text-body font-semibold text-ink-1">{t('challengeRunner.proofStored')}</p>
<p className="text-caption text-ink-3">{t('challengeRunner.capability')} {course.proof_skill || course.title}</p>
</div>
</div>
@@ -319,11 +321,11 @@ export default function ChallengeRunner({ course, profile, onPassed }: Challenge
<p className="mt-3 flex items-start gap-2 rounded-xl border border-border bg-krow-blue-tint px-3.5 py-3 text-caption leading-relaxed text-krow-blue">
<Eye className="mt-0.5 h-3.5 w-3.5 shrink-0" aria-hidden="true" />
Employers can now see this proof in your Career Wallet. Every skill is backed by evidence.
{t('challengeRunner.employersCanNowSeeThisProof')}
</p>
<Button variant="outline" shape="rounded" className="mt-3 w-full" onClick={() => setStep(0)}>
Back to start
{t('challengeRunner.backToStart')}
</Button>
</Frame>
);