63 lines
2.2 KiB
TypeScript
Executable File
63 lines
2.2 KiB
TypeScript
Executable File
'use client';
|
|
|
|
import { Button } from '@/components/ui/button';
|
|
import { Progress } from '@/components/ui/progress';
|
|
import { BookOpen, X } from 'lucide-react';
|
|
import { useGameContext } from '../GameContext';
|
|
import { formatStudyTime } from '../types';
|
|
import { SKILLS_DEF, SPELLS_DEF } from '@/lib/game/constants';
|
|
|
|
interface StudyProgressProps {
|
|
target: NonNullable<ReturnType<typeof useGameContext>['store']['currentStudyTarget']>;
|
|
showCancel?: boolean;
|
|
speedLabel?: string;
|
|
}
|
|
|
|
export function StudyProgress({ target, showCancel = true, speedLabel }: StudyProgressProps) {
|
|
const { store, studySpeedMult } = useGameContext();
|
|
|
|
const progressPct = Math.min(100, (target.progress / target.required) * 100);
|
|
const isSkill = target.type === 'skill';
|
|
const def = isSkill ? SKILLS_DEF[target.id] : SPELLS_DEF[target.id];
|
|
const currentLevel = isSkill ? store.skills[target.id] || 0 : 0;
|
|
|
|
const handleCancel = () => {
|
|
// Calculate retention bonus from knowledge retention skill
|
|
const retentionBonus = 0.2 * (store.skills.knowledgeRetention || 0);
|
|
store.cancelStudy(retentionBonus);
|
|
};
|
|
|
|
return (
|
|
<div className="p-3 rounded border border-purple-600/50 bg-purple-900/20">
|
|
<div className="flex items-center justify-between mb-2">
|
|
<div className="flex items-center gap-2">
|
|
<BookOpen className="w-4 h-4 text-purple-400" />
|
|
<span className="text-sm font-semibold text-purple-300">
|
|
{def?.name}
|
|
{isSkill && ` Lv.${currentLevel + 1}`}
|
|
</span>
|
|
</div>
|
|
{showCancel && (
|
|
<Button
|
|
variant="ghost"
|
|
size="sm"
|
|
className="h-6 w-6 p-0 text-gray-400 hover:text-white"
|
|
onClick={handleCancel}
|
|
>
|
|
<X className="w-4 h-4" />
|
|
</Button>
|
|
)}
|
|
</div>
|
|
<Progress value={progressPct} className="h-2 bg-gray-800" />
|
|
<div className="flex justify-between text-xs text-gray-400 mt-1">
|
|
<span>
|
|
{formatStudyTime(target.progress)} / {formatStudyTime(target.required)}
|
|
</span>
|
|
<span>{speedLabel ?? `${studySpeedMult.toFixed(1)}x speed`}</span>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
StudyProgress.displayName = "StudyProgress";
|