feat: add vocabulary browser with filters, audio playback, and example sentences
- Add Vocabularies page with searchable, level-grouped grid - Implement multi-faceted filter system (word type, verb class, transitivity, reading ending, character count) - Add male/female voice audio playback via WaniKani pronunciation data - Display context sentences from WaniKani API - Collapsible mnemonics section in detail modal - Component kanji chips navigate to Collection with pre-filled search - Vocabulary sync uses upsert to keep data fresh (audio, sentences, normalized POS) - Add Vocabulary model, controller, service, and API route - Add seed data with 28 vocabulary entries including transitive/intransitive verb pairs - Full i18n support (EN, DE, JA) for all new UI elements
This commit is contained in:
@@ -10,6 +10,7 @@ const messages = {
|
||||
dashboard: 'Dashboard',
|
||||
review: 'Review',
|
||||
collection: 'Collection',
|
||||
vocabularies: 'Vocabularies',
|
||||
settings: 'Settings',
|
||||
sync: 'Sync',
|
||||
logout: 'Logout',
|
||||
@@ -99,6 +100,8 @@ const messages = {
|
||||
items: 'Items',
|
||||
language: 'Language',
|
||||
drawingTolerance: 'Drawing Tolerance',
|
||||
strokeStrictness: 'Stroke Strictness',
|
||||
advanced: 'Advanced',
|
||||
strict: 'Strict',
|
||||
loose: 'Loose',
|
||||
save: 'Save & Close',
|
||||
@@ -142,6 +145,32 @@ const messages = {
|
||||
startLesson: 'Start Lesson',
|
||||
redoLesson: 'Redo Lesson',
|
||||
},
|
||||
vocabulary: {
|
||||
searchLabel: 'Search Vocabulary...',
|
||||
placeholder: "e.g. '大人', 'otona', 'adult'",
|
||||
loading: 'Loading Vocabularies...',
|
||||
noMatches: 'No matches found',
|
||||
tryDifferent: 'Try searching for a different word or reading.',
|
||||
levelHeader: 'LEVEL',
|
||||
levelLabel: 'Level',
|
||||
primary: 'Primary',
|
||||
mnemonics: 'Mnemonics',
|
||||
meaningMnemonic: 'Meaning Mnemonic',
|
||||
readingMnemonic: 'Reading Mnemonic',
|
||||
components: 'Component Kanji',
|
||||
exampleSentences: 'Example Sentences',
|
||||
filters: 'Filters',
|
||||
filterType: 'Word Type',
|
||||
filterVerbClass: 'Verb Class',
|
||||
filterTransitivity: 'Transitivity',
|
||||
filterEnding: 'Reading Ending',
|
||||
filterLength: 'Character Count',
|
||||
clearAll: 'Clear All',
|
||||
matchCount: '{n} results',
|
||||
listenMale: 'Male',
|
||||
listenFemale: 'Female',
|
||||
close: 'Close',
|
||||
},
|
||||
},
|
||||
de: {
|
||||
common: {
|
||||
@@ -152,6 +181,7 @@ const messages = {
|
||||
dashboard: 'Übersicht',
|
||||
review: 'Lernen',
|
||||
collection: 'Sammlung',
|
||||
vocabularies: 'Vokabeln',
|
||||
settings: 'Einstellungen',
|
||||
sync: 'Sync',
|
||||
logout: 'Abmelden',
|
||||
@@ -241,6 +271,8 @@ const messages = {
|
||||
items: 'Einträge',
|
||||
language: 'Sprache',
|
||||
drawingTolerance: 'Zeichentoleranz',
|
||||
strokeStrictness: 'Strichgenauigkeit',
|
||||
advanced: 'Erweitert',
|
||||
strict: 'Strikt',
|
||||
loose: 'Locker',
|
||||
save: 'Speichern & Schließen',
|
||||
@@ -284,6 +316,32 @@ const messages = {
|
||||
startLesson: 'Lektion starten',
|
||||
redoLesson: 'Lektion wiederholen',
|
||||
},
|
||||
vocabulary: {
|
||||
searchLabel: 'Vokabel suchen...',
|
||||
placeholder: "z.B. '大人', 'otona', 'Erwachsener'",
|
||||
loading: 'Lade Vokabeln...',
|
||||
noMatches: 'Keine Treffer',
|
||||
tryDifferent: 'Versuche einen anderen Suchbegriff.',
|
||||
levelHeader: 'STUFE',
|
||||
levelLabel: 'Stufe',
|
||||
primary: 'Primär',
|
||||
mnemonics: 'Eselsbrücken',
|
||||
meaningMnemonic: 'Bedeutungs-Eselsbrücke',
|
||||
readingMnemonic: 'Lesungs-Eselsbrücke',
|
||||
components: 'Kanji-Bestandteile',
|
||||
exampleSentences: 'Beispielsätze',
|
||||
filters: 'Filter',
|
||||
filterType: 'Wortart',
|
||||
filterVerbClass: 'Verbklasse',
|
||||
filterTransitivity: 'Transitivität',
|
||||
filterEnding: 'Lesung-Endung',
|
||||
filterLength: 'Zeichenanzahl',
|
||||
clearAll: 'Zurücksetzen',
|
||||
matchCount: '{n} Ergebnisse',
|
||||
listenMale: 'Männlich',
|
||||
listenFemale: 'Weiblich',
|
||||
close: 'Schließen',
|
||||
},
|
||||
},
|
||||
ja: {
|
||||
common: {
|
||||
@@ -294,6 +352,7 @@ const messages = {
|
||||
dashboard: 'ダッシュボード',
|
||||
review: '復習',
|
||||
collection: 'コレクション',
|
||||
vocabularies: '単語',
|
||||
settings: '設定',
|
||||
sync: '同期',
|
||||
logout: 'ログアウト',
|
||||
@@ -383,6 +442,8 @@ const messages = {
|
||||
items: '個',
|
||||
language: '言語 (Language)',
|
||||
drawingTolerance: '描画許容範囲',
|
||||
strokeStrictness: '筆画の厳密さ',
|
||||
advanced: '詳細設定',
|
||||
strict: '厳しい',
|
||||
loose: '甘い',
|
||||
save: '保存して閉じる',
|
||||
@@ -426,6 +487,32 @@ const messages = {
|
||||
startLesson: 'レッスン開始',
|
||||
redoLesson: 'レッスンをやり直す',
|
||||
},
|
||||
vocabulary: {
|
||||
searchLabel: '単語を検索...',
|
||||
placeholder: "例: '大人', 'おとな', 'adult'",
|
||||
loading: '単語を読み込み中...',
|
||||
noMatches: '見つかりませんでした',
|
||||
tryDifferent: '別のキーワードで検索してください。',
|
||||
levelHeader: 'レベル',
|
||||
levelLabel: 'レベル',
|
||||
primary: '主要',
|
||||
mnemonics: '覚え方',
|
||||
meaningMnemonic: '意味の覚え方',
|
||||
readingMnemonic: '読みの覚え方',
|
||||
components: '構成漢字',
|
||||
exampleSentences: '例文',
|
||||
filters: 'フィルター',
|
||||
filterType: '品詞',
|
||||
filterVerbClass: '動詞の種類',
|
||||
filterTransitivity: '自他',
|
||||
filterEnding: '読みの語尾',
|
||||
filterLength: '文字数',
|
||||
clearAll: 'クリア',
|
||||
matchCount: '{n}件',
|
||||
listenMale: '男性',
|
||||
listenFemale: '女性',
|
||||
close: '閉じる',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user