omniasr-transcriptions / frontend /src /components /TranscriptionSideBar.tsx
jeanma's picture
Omnilingual ASR transcription demo
ae238b3 verified
import React, {useRef, useState} from "react";
import {useTranscriptionStore} from "../stores/transcriptionStore";
import ServerStatusIndicator from "./ServerStatusIndicator";
import FeedbackCard from "./FeedbackCard";
import TipsNotice from "./TipsNotice";
import QuickGuide from "./QuickGuide";
import {
TOSModalComponent,
AUPModalComponent,
ModelReadmeModalComponent,
} from "./TermsModal";
const TranscriptionSideBar: React.FC = () => {
const fileInputRef = useRef<HTMLInputElement>(null);
const [isTOSModalOpen, setIsTOSModalOpen] = useState(false);
const [isAUPModalOpen, setIsAUPModalOpen] = useState(false);
const [isModelReadmeModalOpen, setIsModelReadmeModalOpen] = useState(false);
const {
file,
transcription,
error,
isRecording,
handleFileSelect,
startRecording,
} = useTranscriptionStore();
const handleFileInputChange = (
event: React.ChangeEvent<HTMLInputElement>
) => {
const selectedFile = event.target.files?.[0];
if (selectedFile) {
handleFileSelect(selectedFile);
}
};
return (
<div className="h-full p-4 overflow-y-auto">
<h2 className="text-lg font-bold mb-4">
Omnilingual ASR Media Transcription
</h2>
{/* Server Status Indicator */}
<div className="mb-4 p-3 bg-gray-900 rounded-lg border border-gray-600">
<ServerStatusIndicator />
</div>
{/* File Upload */}
<div className="mb-4">
<h3 className="text-sm font-semibold mb-2">Upload Media</h3>
<input
ref={fileInputRef}
type="file"
accept="audio/*"
onChange={handleFileInputChange}
className="hidden"
/>
{!isRecording && (
<>
<button
onClick={() => fileInputRef.current?.click()}
className="w-full p-2 bg-blue-600 hover:bg-blue-700 rounded text-sm transition-colors mb-2 flex items-center justify-center gap-2"
>
<svg className="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
<path
fillRule="evenodd"
d="M3 17a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm3.293-7.707a1 1 0 011.414 0L9 10.586V3a1 1 0 112 0v7.586l1.293-1.293a1 1 0 111.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z"
clipRule="evenodd"
/>
</svg>
{file ? "Choose Different File" : "Choose File"}
</button>
{/* Recording Buttons */}
<div className="space-y-2">
<button
onClick={() => startRecording("audio")}
className="w-full p-2 bg-red-700 hover:bg-red-800 rounded text-sm transition-colors flex items-center justify-center gap-2"
>
<svg
className="w-4 h-4"
fill="currentColor"
viewBox="0 0 20 20"
>
<path
fillRule="evenodd"
d="M7 4a3 3 0 016 0v4a3 3 0 11-6 0V4zm4 10.93A7.001 7.001 0 0017 8a1 1 0 10-2 0A5 5 0 015 8a1 1 0 00-2 0 7.001 7.001 0 006 6.93V17H6a1 1 0 100 2h8a1 1 0 100-2h-3v-2.07z"
clipRule="evenodd"
/>
</svg>
Record Audio
</button>
{/* <button
onClick={() => startRecording("video")}
className="w-full p-2 bg-red-700 hover:bg-red-800 rounded text-sm transition-colors flex items-center justify-center gap-2"
>
<svg
className="w-4 h-4"
fill="currentColor"
viewBox="0 0 20 20"
>
<path d="M2 6a2 2 0 012-2h6a2 2 0 012 2v8a2 2 0 01-2 2H4a2 2 0 01-2-2V6zM14.553 7.106A1 1 0 0014 8v4a1 1 0 00.553.894l2 1A1 1 0 0018 13V7a1 1 0 00-1.447-.894l-2 1z" />
</svg>
Record Video
</button> */}
</div>
</>
)}
{file && !isRecording && (
<div className="mt-2 p-2 bg-gray-700 rounded">
<div className="text-xs font-medium truncate">{file.name}</div>
<div className="text-xs text-gray-400">
{(file.size / 1024 / 1024).toFixed(1)} MB
</div>
</div>
)}
</div>
{/* Error Display */}
{error && transcription && (
<div className="mb-4 p-2 bg-red-600 rounded">
<div className="text-xs font-medium">Error</div>
<div className="text-xs">{error}</div>
</div>
)}
<QuickGuide />
<TipsNotice />
<FeedbackCard />
{/* Terms and Policy Buttons */}
<div className="mt-4 space-y-2">
<button
onClick={() => setIsTOSModalOpen(true)}
className="w-full p-2 bg-green-200 hover:bg-green-300 text-gray-800 rounded text-sm transition-colors"
>
Terms of Service
</button>
<button
onClick={() => setIsAUPModalOpen(true)}
className="w-full p-2 bg-green-200 hover:bg-green-300 text-gray-800 rounded text-sm transition-colors"
>
Acceptable Use Policy
</button>
<button
onClick={() => setIsModelReadmeModalOpen(true)}
className="w-full p-2 bg-green-200 hover:bg-green-300 text-gray-800 rounded text-sm transition-colors"
>
Model Readme
</button>
</div>
{/* Modals */}
<TOSModalComponent
isOpen={isTOSModalOpen}
onClose={() => setIsTOSModalOpen(false)}
/>
<AUPModalComponent
isOpen={isAUPModalOpen}
onClose={() => setIsAUPModalOpen(false)}
/>
<ModelReadmeModalComponent
isOpen={isModelReadmeModalOpen}
onClose={() => setIsModelReadmeModalOpen(false)}
/>
</div>
);
};
export default TranscriptionSideBar;