Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 46 additions & 24 deletions frontend/src/pages/learner/ChatRoomPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,16 @@ export default function ChatRoomPage() {
<DashboardHeader
title={scenarioTitle}
subtitle={`Threat Actor: ${threatActorName}`}
onLogoClick={() => hasMessages ? dispatch({ type: 'SET_SHOW_WARNING', show: true }) : navigate(ROUTES.LEARNER.SCENARIOS)}
onBack={() => hasMessages ? dispatch({ type: 'SET_SHOW_WARNING', show: true }) : navigate(ROUTES.LEARNER.SCENARIOS)}
onLogoClick={() =>
hasMessages
? dispatch({ type: 'SET_SHOW_WARNING', show: true })
: navigate(ROUTES.LEARNER.SCENARIOS)
}
onBack={() =>
hasMessages
? dispatch({ type: 'SET_SHOW_WARNING', show: true })
: navigate(ROUTES.LEARNER.SCENARIOS)
}
onLogout={() => {
logout();
navigate(ROUTES.LOGIN, { replace: true });
Expand All @@ -132,7 +140,8 @@ export default function ChatRoomPage() {
className={`flex-1 py-2 rounded-lg text-sm font-semibold transition-colors cursor-pointer ${mobileTab === 'tasks' ? 'bg-[#0f1c35] text-white' : 'bg-white border border-gray-200 text-gray-600'}`}
>
Investigation Tasks{' '}
{totalCompletedCount > 0 && `(${totalCompletedCount}/${totalTaskCount})`}
{totalCompletedCount > 0 &&
`(${totalCompletedCount}/${totalTaskCount})`}
</button>
</div>

Expand All @@ -148,14 +157,17 @@ export default function ChatRoomPage() {
Negotiation Chat
</div>
<div className='flex items-center gap-3'>
<div className={`flex items-center gap-1.5 px-3 py-1.5 rounded text-white text-sm font-mono font-semibold ${isOvertime ? 'bg-red-600' : 'bg-slate-800'}`}>
<div
className={`flex items-center gap-1.5 px-3 py-1.5 rounded text-white text-sm font-mono font-semibold ${isOvertime ? 'bg-red-600' : 'bg-slate-800'}`}
>
<Clock className='w-3.5 h-3.5' />
{isOvertime ? `+${formatTime(timeLeft)}` : formatTime(timeLeft)}
</div>
<button
onClick={() => hasMessages
? dispatch({ type: 'SET_SHOW_WARNING', show: true })
: navigate(ROUTES.LEARNER.SCENARIOS)
onClick={() =>
hasMessages
? dispatch({ type: 'SET_SHOW_WARNING', show: true })
: navigate(ROUTES.LEARNER.SCENARIOS)
}
className='px-4 py-1.5 rounded bg-red-500 hover:bg-red-600 text-white text-sm font-semibold transition-colors cursor-pointer'
>
Expand Down Expand Up @@ -287,22 +299,22 @@ export default function ChatRoomPage() {
>
{/* Tasks header */}
<div className='flex items-center justify-between px-5 py-4 border-b border-gray-200 shrink-0'>
<div className='flex items-center gap-2 text-gray-700 font-semibold text-sm'>
<ClipboardList className='w-4 h-4' />
Investigation Tasks
</div>
<div className='h-2 w-24 rounded-full bg-gray-100'>
<div
className={`h-2 rounded-full bg-green-500 transition-all`}
style={{
width: `${(totalCompletedCount / totalTaskCount) * 100}%`,
}}
/>
</div>
<span className='text-sm font-semibold text-gray-500'>
{totalCompletedCount}/{totalTaskCount}
</span>
<div className='flex items-center gap-2 text-gray-700 font-semibold text-sm'>
<ClipboardList className='w-4 h-4' />
Investigation Tasks
</div>
<div className='h-2 w-24 rounded-full bg-gray-100'>
<div
className={`h-2 rounded-full bg-green-500 transition-all`}
style={{
width: `${(totalCompletedCount / totalTaskCount) * 100}%`,
}}
/>
</div>
<span className='text-sm font-semibold text-gray-500'>
{totalCompletedCount}/{totalTaskCount}
</span>
</div>

{/* Tasks list */}
<div className='flex-1 overflow-y-auto px-5 py-4 space-y-5'>
Expand All @@ -328,7 +340,14 @@ export default function ChatRoomPage() {
idx={questions.length}
questionKey={DECRYPTION_KEY}
title='Decryption Key for Proof'
options={[{ answer_key: 'I have requested proof of decryption capability from the threat actor', title: 'Requested' }]}
options={[
{
answer_key:
'I have requested proof of decryption capability from the threat actor',
title:
'I have requested proof of decryption capability from the threat actor',
},
]}
selected={taskAnswers[DECRYPTION_KEY] ?? []}
inputType='checkbox'
onToggle={(questionKey, answerKey) =>
Expand Down Expand Up @@ -385,7 +404,10 @@ export default function ChatRoomPage() {
finalWarning='Are you sure you want to end the session?'
note='Extended time is recorded and included in your performance report.'
onConfirm={handleSessionEnd}
onCancel={() => { dispatch({ type: 'START_OVERTIME' }); setShowTimeoutModal(false); }}
onCancel={() => {
dispatch({ type: 'START_OVERTIME' });
setShowTimeoutModal(false);
}}
/>
)}
</div>
Expand Down