fix: /simplify 리뷰 — UX/코드 품질 10건 수정

- EditableSegment: readOnly prop 추가, hover 배경색 효과
- MeetingDetailTabs: useMemo(parseSegments), 이중 debounce 제거, cleanup
- MeetingChatPanel: sessionId deps, 에러 표시, key=timestamp
- ExportMenu: i18n 위반 수정 (하드코딩 → t())
- MeetingModePage: 에러 Snackbar 피드백 (startRecording, viewDetail)
- TranscriptTab: polish 실패 피드백
- 12개 locale i18n 키 5개 추가
This commit is contained in:
Yun Chan 2026-04-08 11:34:50 +09:00
parent 403985e2cd
commit f0e221058d
18 changed files with 179 additions and 49 deletions

View file

@ -6,6 +6,8 @@ import {
Box,
LinearProgress,
TextField,
Snackbar,
Alert,
} from '@mui/material'
import AddIcon from '@mui/icons-material/Add'
import StopIcon from '@mui/icons-material/Stop'
@ -50,6 +52,7 @@ export function MeetingModePage(): React.ReactElement {
// 상세 뷰 상태
const [detail, setDetail] = useState<MeetingSessionDetail | null>(null)
const [snackbarMsg, setSnackbarMsg] = useState<string | null>(null)
// ── 세션 목록 로드 ──
const loadSessions = useCallback(async () => {
@ -140,8 +143,10 @@ export function MeetingModePage(): React.ReactElement {
setElapsedMs(0)
setProgress(null)
setView('recording')
} else {
setSnackbarMsg(t('meeting.startRecordingError'))
}
}, [])
}, [t])
const handleStopRecording = useCallback(async () => {
await window.electronAPI.meetingMode.stopRecording()
@ -171,8 +176,10 @@ export function MeetingModePage(): React.ReactElement {
if (resp.success) {
setDetail(resp.data)
setView('detail')
} else {
setSnackbarMsg(t('meeting.viewDetailError'))
}
}, [])
}, [t])
// ── 유틸 ──
@ -198,6 +205,19 @@ export function MeetingModePage(): React.ReactElement {
}
}
const snackbar = (
<Snackbar
open={snackbarMsg !== null}
autoHideDuration={4000}
onClose={() => setSnackbarMsg(null)}
anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}
>
<Alert severity="error" onClose={() => setSnackbarMsg(null)} sx={{ width: '100%' }}>
{snackbarMsg}
</Alert>
</Snackbar>
)
// ── 렌더: 목록 뷰 ──
if (view === 'list') {
return (
@ -263,6 +283,7 @@ export function MeetingModePage(): React.ReactElement {
))}
</Box>
)}
{snackbar}
</Box>
)
}
@ -328,7 +349,8 @@ export function MeetingModePage(): React.ReactElement {
timestamp={Math.max(0, seg.timestamp - (recordingStartRef.current || seg.timestamp))}
text={seg.text}
edited={false}
onEdit={() => { /* 녹음 중 편집 비활성 */ }}
onEdit={() => { /* no-op: readOnly=true */ }}
readOnly
/>
))}
</Box>
@ -403,6 +425,7 @@ export function MeetingModePage(): React.ReactElement {
</PhosphorText>
</Box>
)}
{snackbar}
</Box>
)
}