import type { Meta, StoryObj } from '@storybook/nextjs' import { useState } from 'react' // Mock component since VoiceInput requires browser APIs and service dependencies const VoiceInputMock = ({ onConverted, onCancel }: any) => { const [state, setState] = useState<'idle' | 'recording' | 'converting'>('recording') const [duration, setDuration] = useState(0) // Simulate recording useState(() => { const interval = setInterval(() => { setDuration(d => d + 1) }, 1000) return () => clearInterval(interval) }) const handleStop = () => { setState('converting') setTimeout(() => { onConverted('This is simulated transcribed text from voice input.') }, 2000) } const minutes = Math.floor(duration / 60) const seconds = duration % 60 return (
{/* Waveform visualization placeholder */}
{Array.from({ length: 40 }).map((_, i) => (
))}
{state === 'converting' && (
)}
{state === 'recording' && (
Speaking...
)} {state === 'converting' && (
Converting to text...
)}
{state === 'recording' && (
)} {state === 'converting' && (
×
)}
500 ? 'text-red-600' : 'text-gray-700'}`}> {`0${minutes}:${seconds >= 10 ? seconds : `0${seconds}`}`}
) } const meta = { title: 'Base/Data Entry/VoiceInput', component: VoiceInputMock, parameters: { layout: 'centered', docs: { description: { component: 'Voice input component for recording audio and converting speech to text. Features waveform visualization, recording timer (max 10 minutes), and audio-to-text conversion using js-audio-recorder.\n\n**Note:** This is a simplified mock for Storybook. The actual component requires microphone permissions and audio-to-text API.', }, }, }, tags: ['autodocs'], } satisfies Meta export default meta type Story = StoryObj // Basic demo const VoiceInputDemo = () => { const [isRecording, setIsRecording] = useState(false) const [transcription, setTranscription] = useState('') const handleStartRecording = () => { setIsRecording(true) setTranscription('') } const handleConverted = (text: string) => { setTranscription(text) setIsRecording(false) } const handleCancel = () => { setIsRecording(false) setTranscription('') } return (
{!isRecording && ( )} {isRecording && ( )} {transcription && (
Transcription:
{transcription}
)}
) } // Default state export const Default: Story = { render: () => , } // Recording state export const RecordingState: Story = { render: () => (
console.log('Converted')} onCancel={() => console.log('Cancelled')} />
Recording in progress with live waveform visualization
), } // Real-world example - Chat input with voice const ChatInputWithVoiceDemo = () => { const [message, setMessage] = useState('') const [isRecording, setIsRecording] = useState(false) return (

Chat Interface

{/* Existing messages */}
U
Hello! How can I help you today?
A
I can assist you with various tasks. What would you like to know?
{/* Input area */}
{!isRecording ? (
setMessage(e.target.value)} />
) : ( { setMessage(text) setIsRecording(false) }} onCancel={() => setIsRecording(false)} /> )}
) } export const ChatInputWithVoice: Story = { render: () => , } // Real-world example - Search with voice const SearchWithVoiceDemo = () => { const [searchQuery, setSearchQuery] = useState('') const [isRecording, setIsRecording] = useState(false) return (

Voice Search

{!isRecording ? (
setSearchQuery(e.target.value)} /> 🔍
) : ( { setSearchQuery(text) setIsRecording(false) }} onCancel={() => setIsRecording(false)} /> )} {searchQuery && !isRecording && (
Searching for: {searchQuery}
)}
) } export const SearchWithVoice: Story = { render: () => , } // Real-world example - Note taking const NoteTakingDemo = () => { const [notes, setNotes] = useState([]) const [isRecording, setIsRecording] = useState(false) return (

Voice Notes

{notes.length} notes
{!isRecording ? ( ) : ( { setNotes([...notes, text]) setIsRecording(false) }} onCancel={() => setIsRecording(false)} /> )}
{notes.length === 0 ? (
No notes yet. Click the button above to start recording.
) : ( notes.map((note, index) => (
Note {index + 1}
{note}
)) )}
) } export const NoteTaking: Story = { render: () => , } // Real-world example - Form with voice const FormWithVoiceDemo = () => { const [formData, setFormData] = useState({ name: '', description: '', }) const [activeField, setActiveField] = useState<'name' | 'description' | null>(null) return (

Create Product

{activeField === 'name' ? ( { setFormData({ ...formData, name: text }) setActiveField(null) }} onCancel={() => setActiveField(null)} /> ) : (
setFormData({ ...formData, name: e.target.value })} />
)}
{activeField === 'description' ? ( { setFormData({ ...formData, description: text }) setActiveField(null) }} onCancel={() => setActiveField(null)} /> ) : (