90 lines
3.1 KiB
TypeScript
90 lines
3.1 KiB
TypeScript
'use client';
|
|
|
|
import { calculateSelfControlResults } from '../../test/private/SelfControlCalculator';
|
|
|
|
interface SelfControlResultProps {
|
|
answers: string[];
|
|
}
|
|
|
|
const levelText = {
|
|
low: '自控力偏低',
|
|
moderate: '自控力中等',
|
|
high: '自控力较高',
|
|
};
|
|
|
|
const levelDescription = {
|
|
low: '你可能比较容易受到诱惑、情绪或即时满足影响。比起责备自己,更有效的方向通常是减少诱因、降低开始成本,并把计划拆得更具体。',
|
|
moderate: '你具备一定的自控能力,但在压力、疲劳或诱惑较强的场景中可能会波动。环境设计和习惯系统会很有帮助。',
|
|
high: '你通常能较好地管理冲动、抵抗诱惑并推进计划。继续注意休息和目标弹性,能避免把自律变成过度紧绷。',
|
|
};
|
|
|
|
function width(value: number) {
|
|
return `${Math.max(0, Math.min(100, ((value - 1) / 4) * 100))}%`;
|
|
}
|
|
|
|
export function SelfControlResult({ answers }: SelfControlResultProps) {
|
|
const results = calculateSelfControlResults(answers);
|
|
|
|
return (
|
|
<div className="mt-6 space-y-6">
|
|
<div className="border bg-white p-6 shadow-sm">
|
|
<h3 className="text-lg font-semibold mb-4">自控力量表结果</h3>
|
|
<div className="grid grid-cols-1 gap-4 md:grid-cols-3">
|
|
<MetricCard title="总分" value={`${results.total}/65`} />
|
|
<MetricCard title="平均分" value={`${results.average.toFixed(2)}/5`} />
|
|
<MetricCard title="结果水平" value={levelText[results.level]} />
|
|
</div>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
|
|
<BarCard title="冲动管理" value={results.impulseAverage} />
|
|
<BarCard title="计划执行" value={results.executionAverage} />
|
|
</div>
|
|
|
|
<div className="border bg-blue-50 p-6 text-blue-900 shadow-sm">
|
|
<h3 className="text-lg font-semibold mb-3">结果解释</h3>
|
|
<p className="text-sm">{levelDescription[results.level]}</p>
|
|
</div>
|
|
|
|
<div className="border bg-gray-50 p-4 text-sm text-gray-700">
|
|
注:自控力会受睡眠、压力、环境和任务设计影响。结果适合用于自我观察,不应作为能力或人格优劣判断。
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
interface MetricCardProps {
|
|
title: string;
|
|
value: string;
|
|
}
|
|
|
|
function MetricCard({ title, value }: MetricCardProps) {
|
|
return (
|
|
<div className="rounded-lg bg-gray-50 p-4 text-center">
|
|
<div className="text-sm text-muted-foreground">{title}</div>
|
|
<div className="mt-1 text-2xl font-semibold text-indigo-600">
|
|
{value}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function BarCard({ title, value }: { title: string; value: number }) {
|
|
return (
|
|
<div className="rounded-lg border bg-white p-5 shadow-sm">
|
|
<div className="mb-3 flex items-center justify-between">
|
|
<h4 className="font-semibold">{title}</h4>
|
|
<span className="text-sm text-muted-foreground">
|
|
{value.toFixed(2)} / 5
|
|
</span>
|
|
</div>
|
|
<div className="h-2 overflow-hidden rounded-full bg-gray-100">
|
|
<div
|
|
className="h-full rounded-full bg-emerald-500"
|
|
style={{ width: width(value) }}
|
|
/>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|