Files
clarity-helper/components/ScenarioCard.tsx
T

113 lines
4.3 KiB
TypeScript

import React from 'react';
import { Scenario } from '../types';
import { Mic, MessageSquare, Trash2 } from 'lucide-react';
import Tooltip from './Tooltip';
import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from './ui/card';
import { Button } from './ui/button';
import { Badge } from './ui/badge';
interface ScenarioCardProps {
scenario: Scenario;
onSelect: (scenario: Scenario, mode: 'text' | 'voice') => void;
onDelete?: (id: string) => void;
}
const ScenarioCard: React.FC<ScenarioCardProps> = ({ scenario, onSelect, onDelete }) => {
const getDifficultyVariant = (diff: string): "default" | "secondary" | "destructive" | "outline" => {
switch (diff) {
case 'Beginner': return 'default';
case 'Intermediate': return 'secondary';
case 'Advanced': return 'destructive';
default: return 'outline';
}
};
const difficultyExplanations: Record<string, string> = {
'Beginner': 'Low-stakes environment with highly structured feedback and clear cognitive distortions.',
'Intermediate': 'Moderate social friction requiring nuanced responses and identifying subtle distortions.',
'Advanced': 'High-trigger environment with resistant AI personas to test deep emotional regulation.'
};
return (
<Card className="hover:border-teal-200 hover:shadow-md transition-all flex flex-col h-full group relative overflow-hidden">
{onDelete && (
<Button
variant="ghost"
size="icon"
onClick={(e) => {
e.stopPropagation();
onDelete(scenario.id);
}}
className="absolute top-2 right-2 text-slate-300 hover:text-rose-500 hover:bg-rose-50 opacity-0 group-hover:opacity-100 transition-all z-10"
title="Delete custom scenario"
>
<Trash2 size={16} />
</Button>
)}
<CardHeader className="pb-2">
<div className="flex justify-between items-start mb-2">
<Tooltip content={difficultyExplanations[scenario.difficulty] || ""}>
<div className="cursor-help">
<Badge variant={getDifficultyVariant(scenario.difficulty)} className="text-[10px] uppercase tracking-wider">
{scenario.difficulty}
</Badge>
</div>
</Tooltip>
{!onDelete && (
<span className="text-[10px] font-bold text-slate-400 uppercase tracking-widest">
{scenario.category}
</span>
)}
</div>
<CardTitle className="text-lg group-hover:text-teal-700 transition-colors pr-6">
{scenario.title}
</CardTitle>
<CardDescription className="text-sm flex-grow leading-relaxed font-light">
{scenario.description}
</CardDescription>
</CardHeader>
<CardContent className="flex-grow">
<div className="flex flex-wrap gap-1.5 mt-2">
{scenario.cbtFocus.map(focus => (
<Tooltip key={focus} content={`Specific CBT protocol targeting: ${focus}`}>
<Badge variant="outline" className="text-[10px] font-medium bg-slate-50 text-slate-500 cursor-help">
{focus}
</Badge>
</Tooltip>
))}
</div>
</CardContent>
<CardFooter className="pt-0">
<div className="grid grid-cols-2 gap-3 w-full">
<Tooltip content="Engage in a structured text-based roleplay with real-time feedback." position="bottom">
<Button
variant="outline"
size="sm"
onClick={() => onSelect(scenario, 'text')}
className="w-full text-slate-600 font-semibold text-xs"
>
<MessageSquare size={14} className="mr-2" />
Chat
</Button>
</Tooltip>
<Tooltip content="Practice verbal emotional regulation and vocal expression in real-time." position="bottom">
<Button
size="sm"
onClick={() => onSelect(scenario, 'voice')}
className="w-full bg-teal-600 hover:bg-teal-700 text-white font-semibold text-xs shadow-sm shadow-teal-100"
>
<Mic size={14} className="mr-2" />
Voice
</Button>
</Tooltip>
</div>
</CardFooter>
</Card>
);
};
export default React.memo(ScenarioCard);