fix(dictionary): let an edit clear the pronunciation and report duplicate renames

This commit is contained in:
Yun Chan 2026-09-28 00:53:46 +09:00
parent 9d5d043e8b
commit de1e8a82a4
6 changed files with 350 additions and 24 deletions

View file

@ -9,6 +9,11 @@ import { PageHeader, SearchInput, EmptyStateCard } from '../components/shared'
import { d3roPalette, d3roFontSans, d3roTypo, d3roRadius, d3roShadow } from '@d3ro/ui/theme'
import { useI18n } from '@d3ro/i18n'
import type { DictionaryEntry, DictionaryPage as DictPageData } from '@d3ro/core/types'
import {
dictionarySaveErrorKey,
toDictionaryAddParams,
toDictionaryUpdateParams,
} from '@d3ro/core/dictionary-policy'
export function DictionaryPage(): React.ReactElement {
const { t } = useI18n()
@ -20,6 +25,7 @@ export function DictionaryPage(): React.ReactElement {
const [formWord, setFormWord] = useState('')
const [formPronunciation, setFormPronunciation] = useState('')
const [saving, setSaving] = useState(false)
const [formError, setFormError] = useState<string | null>(null)
const isSavingRef = useRef(false)
const [ioBusy, setIoBusy] = useState(false)
const [ioMessage, setIoMessage] = useState<string | null>(null)
@ -47,6 +53,7 @@ export function DictionaryPage(): React.ReactElement {
setEditId(null)
setFormWord('')
setFormPronunciation('')
setFormError(null)
setDialogOpen(true)
}
@ -55,6 +62,7 @@ export function DictionaryPage(): React.ReactElement {
setEditId(entry.id)
setFormWord(entry.word)
setFormPronunciation(entry.pronunciation ?? '')
setFormError(null)
setDialogOpen(true)
}
@ -62,18 +70,16 @@ export function DictionaryPage(): React.ReactElement {
if (!formWord.trim() || saving || isSavingRef.current) return
isSavingRef.current = true
setSaving(true)
setFormError(null)
try {
if (editId) {
await window.electronAPI.dictionary.update({
id: editId,
word: formWord.trim(),
pronunciation: formPronunciation.trim() || undefined,
})
} else {
await window.electronAPI.dictionary.add({
word: formWord.trim(),
pronunciation: formPronunciation.trim() || undefined,
})
const form = { word: formWord, pronunciation: formPronunciation }
const result = editId
? await window.electronAPI.dictionary.update(toDictionaryUpdateParams(editId, form))
: await window.electronAPI.dictionary.add(toDictionaryAddParams(form))
if (!result.success) {
// 다이얼로그를 유지해 사용자가 입력을 고칠 수 있게 한다 (예: 같은 단어로 이름 변경).
setFormError(t(dictionarySaveErrorKey(result.error.code)))
return
}
setDialogOpen(false)
loadData()
@ -308,7 +314,11 @@ export function DictionaryPage(): React.ReactElement {
<TextField
label={t('dictionary.word')}
value={formWord}
onChange={(e) => setFormWord(e.target.value)}
onChange={(e) => {
setFormWord(e.target.value)
setFormError(null)
}}
error={formError !== null}
fullWidth
autoFocus
sx={{ mt: 1.5 }}
@ -321,13 +331,18 @@ export function DictionaryPage(): React.ReactElement {
sx={{ mt: 2.5 }}
helperText="e.g. 디쓰리오"
/>
{formError && (
<PhosphorText variant="meta" role="alert" sx={{ display: 'block', mt: 1.5, color: d3roPalette.tag.red }}>
{formError}
</PhosphorText>
)}
</DialogContent>
<DialogActions sx={{ px: 2.5, pb: 2, pt: 1, gap: 1 }}>
<PhysicalButton tone="glass" onClick={() => setDialogOpen(false)}>
{t('common.cancel')}
</PhysicalButton>
<PhysicalButton tone="accent" onClick={handleSave} disabled={!formWord.trim() || saving}>
{saving ? t('common.saving') || '저장 중...' : t('common.save')}
{saving ? t('common.saving') : t('common.save')}
</PhysicalButton>
</DialogActions>
</Dialog>