+
+
+
+ Export All
+ New Recording
+
+
+
+ {/* Search and Filter Bar */}
+
+
+
+ setSearchTerm(e.target.value)}
+ className="pl-10"
+ />
+
+
+
+ Filter
+
+
+
+ {/* Transcriptions Grid */}
+ {loading ? (
+
+
+
+
+
Loading transcriptions...
+
+
+
+ ) : filteredTranscriptions.length === 0 ? (
+
+
+
+
+
No transcriptions found
+
+ {searchTerm ? 'Try adjusting your search terms.' : 'Start recording to see your transcriptions here.'}
+
+ {!searchTerm && (
+
Start Recording
+ )}
+
+
+
+ ) : (
+
+ {filteredTranscriptions.map((transcription) => (
+
+
+
+
+
+
+ {getTitle(transcription.text)}
+
+
+
+ {getWordCount(transcription.text)} words
+
+ {format(new Date(transcription.timestamp), 'MMM d')}
+ {format(new Date(transcription.timestamp), 'h:mm a')}
+
+ {transcription.language?.toUpperCase() || 'EN'}
+
+
+
+
+
+
+
+
+
+ copyToClipboard(transcription.text)}
+ >
+
+
+
+ Copy transcription
+
+
+
+ {transcription.audioFile && (
+
+
+
+ handlePlayAudio(transcription.audioFile!)}
+ >
+
+
+
+ Play audio
+
+
+ )}
+
+
+
+
+
+
+
+
+ Actions
+ handleDownload(transcription)}>
+
+ Download
+
+
+ handleDelete(transcription.id)}
+ className="text-destructive"
+ >
+
+ Delete
+
+
+
+
+
+
+
+ ))}
+
+ )}
+
+ {!loading && filteredTranscriptions.length > 0 && (
+
+
+ Showing {filteredTranscriptions.length} of {totalCount} transcription{totalCount !== 1 ? 's' : ''}
+
+
+ Total: {transcriptions.reduce((acc, t) => acc + getWordCount(t.text), 0)} words
+
+
+ )}
+
+ );
+};
\ No newline at end of file
diff --git a/apps/electron/src/components/transcriptions-view.tsx b/apps/electron/src/components/transcriptions-view.tsx
new file mode 100644
index 0000000..b5c6f32
--- /dev/null
+++ b/apps/electron/src/components/transcriptions-view.tsx
@@ -0,0 +1,6 @@
+import React from 'react';
+import { TranscriptionsList } from './transcriptions-list';
+
+export function TranscriptionsView() {
+ return
+
+
+
+
+
+
+ Add Word
+
+
+
+
+ Add Custom Word
+
+
+
+ Word
+ setNewWord({ ...newWord, word: e.target.value })}
+ />
+
+
+ setIsAddDialogOpen(false)}>
+ Cancel
+
+
+ {createVocabularyMutation.isPending ? 'Adding...' : 'Add Word'}
+
+
+
+
+
+
+
+
+
+
+
+ Word
+ Date Added
+ Actions
+
+
+
+ {loading ? (
+
+
+
+
+
Loading vocabulary...
+
+
+
+ ) : vocabulary.length === 0 ? (
+
+
+
+
+
No custom vocabulary words yet.
+
Add your first word to get started.
+
+
+
+ ) : (
+ vocabulary.map((item) => (
+
+ {item.word}
+
+ {format(new Date(item.dateAdded), 'MMM d, yyyy')}
+
+
+
+
+
+ Edit word
+
+ handleDeleteWord(item.id)}
+ disabled={deleteVocabularyMutation.isPending}
+ >
+
+ Delete word
+
+
+
+
+ ))
+ )}
+
+
+
+
+ {!loading && vocabulary.length > 0 && (
+
+
+ Showing {vocabulary.length} of {totalCount} word{totalCount !== 1 ? 's' : ''}
+
+
+ Total: {totalCount} custom word{totalCount !== 1 ? 's' : ''}
+
+
+ )}
+
+ )
+}
\ No newline at end of file
diff --git a/apps/electron/src/components/vocabulary-view.tsx b/apps/electron/src/components/vocabulary-view.tsx
new file mode 100644
index 0000000..57b56d7
--- /dev/null
+++ b/apps/electron/src/components/vocabulary-view.tsx
@@ -0,0 +1,6 @@
+import React from 'react';
+import { VocabularyManager } from './vocabulary-manager';
+
+export function VocabularyView() {
+ return