refactor(i18n): 사용자 문구 참조를 중앙화

This commit is contained in:
2026-03-10 13:32:37 +09:00
parent 92a509ebb6
commit 1717f335f0
44 changed files with 433 additions and 515 deletions

View File

@@ -2,6 +2,7 @@
import type { FormEvent } from 'react';
import { useEffect, useMemo, useRef, useState } from 'react';
import { copy } from '@/shared/i18n';
import { cn } from '@/shared/lib/cn';
interface GoalCompleteSheetProps {
@@ -12,12 +13,7 @@ interface GoalCompleteSheetProps {
onClose: () => void;
}
const GOAL_SUGGESTIONS = [
'리뷰 코멘트 2개 처리',
'문서 1문단 다듬기',
'이슈 1개 정리',
'메일 2개 회신',
];
const GOAL_SUGGESTIONS = copy.space.goalComplete.suggestions;
export const GoalCompleteSheet = ({
open,
@@ -53,10 +49,10 @@ export const GoalCompleteSheet = ({
const trimmed = currentGoal.trim();
if (!trimmed) {
return '다음 한 조각을 적어보세요';
return copy.space.goalComplete.placeholderFallback;
}
return `예: ${trimmed}`;
return copy.space.goalComplete.placeholderExample(trimmed);
}, [currentGoal]);
const canConfirm = draft.trim().length > 0;
@@ -82,14 +78,14 @@ export const GoalCompleteSheet = ({
<section className="pointer-events-auto w-[min(460px,94vw)] rounded-2xl border border-white/12 bg-black/26 px-3.5 py-3 text-white shadow-[0_14px_30px_rgba(2,6,23,0.28)] backdrop-blur-md">
<header className="flex items-start justify-between gap-2">
<div>
<h3 className="text-sm font-semibold text-white/92">. ?</h3>
<p className="mt-0.5 text-[11px] text-white/58"> , .</p>
<h3 className="text-sm font-semibold text-white/92">{copy.space.goalComplete.title}</h3>
<p className="mt-0.5 text-[11px] text-white/58">{copy.space.goalComplete.description}</p>
</div>
<button
type="button"
onClick={onClose}
className="inline-flex h-6 w-6 items-center justify-center rounded-full border border-white/16 bg-white/[0.05] text-[11px] text-white/72 transition-colors hover:bg-white/[0.12]"
aria-label="닫기"
aria-label={copy.space.goalComplete.closeAriaLabel}
>
</button>
@@ -120,17 +116,17 @@ export const GoalCompleteSheet = ({
<footer className="mt-3 flex items-center justify-end gap-2">
<button
type="button"
onClick={onRest}
className="rounded-full border border-white/18 bg-white/[0.05] px-3 py-1.5 text-xs text-white/74 transition-colors hover:bg-white/[0.11]"
>
</button>
onClick={onRest}
className="rounded-full border border-white/18 bg-white/[0.05] px-3 py-1.5 text-xs text-white/74 transition-colors hover:bg-white/[0.11]"
>
{copy.space.goalComplete.restButton}
</button>
<button
type="submit"
disabled={!canConfirm}
className="rounded-full border border-sky-200/42 bg-sky-300/84 px-3.5 py-1.5 text-xs font-semibold text-slate-900 transition-colors hover:bg-sky-300 disabled:cursor-not-allowed disabled:border-white/16 disabled:bg-white/[0.08] disabled:text-white/48"
>
{copy.space.goalComplete.confirmButton}
</button>
</footer>
</form>

View File

@@ -1,4 +1,5 @@
import { useEffect, useRef, useState } from 'react';
import { copy } from '@/shared/i18n';
import type { HudStatusLinePayload } from '@/shared/lib/useHudStatusLine';
import { SpaceTimerHudWidget } from '@/widgets/space-timer-hud';
import { GoalCompleteSheet } from './GoalCompleteSheet';
@@ -44,7 +45,7 @@ export const SpaceFocusHudWidget = ({
const visibleRef = useRef(false);
const playbackStateRef = useRef<'running' | 'paused'>(playbackState);
const restReminderTimerRef = useRef<number | null>(null);
const normalizedGoal = goal.trim().length > 0 ? goal.trim() : '집중을 시작해요.';
const normalizedGoal = goal.trim().length > 0 ? goal.trim() : copy.space.focusHud.goalFallback;
useEffect(() => {
return () => {
@@ -58,7 +59,7 @@ export const SpaceFocusHudWidget = ({
useEffect(() => {
if (visible && !visibleRef.current && playbackState === 'running') {
onStatusMessage({
message: `이번 한 조각 · ${normalizedGoal}`,
message: copy.space.focusHud.goalToast(normalizedGoal),
});
}
@@ -68,7 +69,7 @@ export const SpaceFocusHudWidget = ({
useEffect(() => {
if (playbackStateRef.current === 'paused' && playbackState === 'running' && visible) {
onStatusMessage({
message: `이번 한 조각 · ${normalizedGoal}`,
message: copy.space.focusHud.goalToast(normalizedGoal),
});
}
@@ -115,7 +116,7 @@ export const SpaceFocusHudWidget = ({
}
restReminderTimerRef.current = window.setTimeout(() => {
onStatusMessage({ message: '5분이 지났어요. 다음 한 조각으로 돌아와요.' });
onStatusMessage({ message: copy.space.focusHud.restReminder });
restReminderTimerRef.current = null;
}, 5 * 60 * 1000);
}}