Spaces:
Running
on
A100
Running
on
A100
| import React from "react"; | |
| import {useTranscriptionStore} from "../stores/transcriptionStore"; | |
| interface QuickGuideProps { | |
| currentStep?: string; // Optional override for current step | |
| } | |
| type GuideStep = { | |
| id: string; | |
| text: string; | |
| icon?: string; | |
| isActive: (state: any) => boolean; | |
| isCompleted: (state: any) => boolean; | |
| }; | |
| const QuickGuide: React.FC<QuickGuideProps> = ({currentStep}) => { | |
| const { | |
| file, | |
| transcription, | |
| isLoading, | |
| selectedSegmentIndex, | |
| currentSegments, | |
| currentTime | |
| } = useTranscriptionStore(); | |
| // Define all the steps with their conditions | |
| const steps: GuideStep[] = [ | |
| { | |
| id: "upload", | |
| text: "Upload or record audio", | |
| icon: "π", | |
| isActive: (state) => !state.file, | |
| isCompleted: (state) => !!state.file, | |
| }, | |
| { | |
| id: "transcribe", | |
| text: "Click transcribe to process", | |
| icon: "π―", | |
| isActive: (state) => | |
| !!state.file && !state.transcription && !state.isLoading, | |
| isCompleted: (state) => !!state.transcription || state.isLoading, | |
| }, | |
| { | |
| id: "play", | |
| text: "Play media", | |
| icon: "βΆοΈ", | |
| isActive: (state) => !!state.transcription, | |
| isCompleted: () => (currentTime ?? 0) > 0, // Always in progress when transcription available | |
| }, | |
| // { | |
| // id: "jump", | |
| // text: "Click segments to jump", | |
| // icon: "π΅", | |
| // isActive: (state) => !!state.transcription, | |
| // isCompleted: () => false, // Always in progress when transcription available | |
| // }, | |
| // { | |
| // id: "drag", | |
| // text: "Drag segments to move/resize", | |
| // icon: "βοΈ", | |
| // isActive: (state) => !!state.transcription, | |
| // isCompleted: () => false, // Always in progress when transcription available | |
| // }, | |
| // { | |
| // id: "combine", | |
| // text: "Use slider to combine segments", | |
| // icon: "π", | |
| // isActive: (state) => !!state.transcription, | |
| // isCompleted: () => false, // Always in progress when transcription available | |
| // }, | |
| // { | |
| // id: "download", | |
| // text: "Download subtitles", | |
| // icon: "πΎ", | |
| // isActive: (state) => !!state.transcription, | |
| // isCompleted: () => false, // Always in progress when transcription available | |
| // }, | |
| ]; | |
| // Create state object for condition checking | |
| const storeState = { | |
| file, | |
| transcription, | |
| isLoading, | |
| selectedSegmentIndex, | |
| currentSegments, | |
| }; | |
| // Determine step states | |
| const getStepState = (step: GuideStep) => { | |
| // Override with currentStep prop if provided | |
| if (currentStep) { | |
| if (step.id === currentStep) return "active"; | |
| if (step.isCompleted(storeState)) return "completed"; | |
| return "inactive"; | |
| } | |
| // Default logic based on store state | |
| if (step.isCompleted(storeState)) return "completed"; | |
| if (step.isActive(storeState)) return "active"; | |
| return "inactive"; | |
| }; | |
| // Get the appropriate CSS classes for each step state | |
| const getStepClasses = (stepState: string) => { | |
| switch (stepState) { | |
| case "active": | |
| return "text-blue-300 bg-blue-900/30 border-blue-500/50 font-medium"; | |
| case "completed": | |
| return "text-green-300 bg-green-900/20 border-green-500/30"; | |
| default: | |
| return "text-gray-400 bg-transparent border-transparent"; | |
| } | |
| }; | |
| // Get icon for step state | |
| const getStepIcon = (step: GuideStep, stepState: string) => { | |
| if (stepState === "completed") return "β"; | |
| if (stepState === "active") return "β"; | |
| return step.icon || "β’"; | |
| }; | |
| return ( | |
| <div className="border-t border-gray-700 py-3"> | |
| <h3 className="text-xs font-semibold mb-2 text-gray-200">Quick Guide</h3> | |
| <div className="space-y-1"> | |
| {steps.map((step) => { | |
| const stepState = getStepState(step); | |
| const stepClasses = getStepClasses(stepState); | |
| const icon = getStepIcon(step, stepState); | |
| return ( | |
| <div | |
| key={step.id} | |
| className={`text-xs px-2 py-1 rounded border transition-all duration-200 ${stepClasses}`} | |
| > | |
| <span | |
| className="inline-block w-4 text-center mr-1" | |
| aria-label={`Step ${step.id}`} | |
| > | |
| {icon} | |
| </span> | |
| {step.text} | |
| </div> | |
| ); | |
| })} | |
| </div> | |
| {/* Progress indicator */} | |
| {transcription && ( | |
| <div className="mt-2 pt-2 border-t border-gray-600"> | |
| <div className="text-xs text-gray-400"> | |
| {selectedSegmentIndex !== null ? ( | |
| <span className="text-yellow-400">βοΈ Editing mode active</span> | |
| ) : ( | |
| <span className="text-green-400"> | |
| β Ready for playback & editing | |
| </span> | |
| )} | |
| </div> | |
| </div> | |
| )} | |
| {/* Loading indicator */} | |
| {isLoading && ( | |
| <div className="mt-2 pt-2 border-t border-gray-600"> | |
| <div className="text-xs text-blue-400 animate-pulse"> | |
| β³ Processing... Please wait | |
| </div> | |
| </div> | |
| )} | |
| </div> | |
| ); | |
| }; | |
| export default QuickGuide; | |