feature: Clinical Review Mode: Charts, Replay Controls & Alert Reasoning

This commit is contained in:
voltsrage
2026-06-20 14:17:58 +08:00
parent 2ca0078223
commit ebd53f2df6
19 changed files with 939 additions and 9 deletions
@@ -0,0 +1,56 @@
<script setup>
import { useReplayControls } from '@/composables/useReplayControls'
import Button from '@/components/ui/Button.vue'
const { isPaused, speed, progress, formattedTime, pause, resume, setSpeed } = useReplayControls()
defineProps({ alerts: { type: Array, default: () => [] } })
const emit = defineEmits(['jump-to-alert'])
const speedPresets = [
{ label: '1×', value: 1 },
{ label: '60×', value: 60 },
{ label: '360×', value: 360 },
{ label: 'Instant', value: 0 },
]
</script>
<template>
<div class="flex w-full min-w-0 flex-col gap-4 rounded-lg border border-gray-200 bg-white p-4 dark:border-gray-700 dark:bg-gray-900 sm:flex-row sm:items-center">
<Button variant="ghost" size="sm" @click="isPaused ? resume() : pause()">
<span class="sr-only">{{ isPaused ? 'Resume' : 'Pause' }}</span>
{{ isPaused ? '▶' : '⏸' }}
</Button>
<div class="min-w-0 flex-1">
<div class="h-2 overflow-hidden rounded-full bg-gray-200 dark:bg-gray-700">
<div class="h-full rounded-full bg-blue-500 transition-all duration-300"
:style="{ width: `${progress}%` }" />
</div>
</div>
<span class="min-w-16 text-center text-sm font-mono text-gray-600 dark:text-gray-400">
{{ formattedTime }}
</span>
<div class="flex flex-wrap gap-2">
<button
v-for="preset in speedPresets"
:key="preset.value"
class="rounded px-2 py-2 text-xs transition"
:class="speed === preset.value
? 'bg-blue-500 text-white'
: 'bg-gray-100 text-gray-600 hover:bg-gray-200 dark:bg-gray-800 dark:text-gray-400'"
@click="setSpeed(preset.value)"
>
{{ preset.label }}
</button>
</div>
<div v-if="alerts.length" class="border-t border-gray-200 pt-4 sm:border-t-0 sm:border-l sm:pl-4 sm:pt-0 dark:border-gray-700">
<Button variant="ghost" size="sm" @click="$emit('jump-to-alert')">
Next Alert &rarr;
</Button>
</div>
</div>
</template>