From 8aaff3af799790b47df44caa0f8b3f18eb9f94df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yuseon=20Kim=28=EC=8D=AC=EB=8D=B0=EC=9D=B4=29?= <74897720+useon@users.noreply.github.com> Date: Fri, 13 Mar 2026 20:20:19 +0900 Subject: [PATCH] =?UTF-8?q?[FIX]=20=ED=8C=80=20=EC=9D=B4=EB=A6=84=20?= =?UTF-8?q?=EA=B8=80=EC=9E=90=EC=88=98=20=EA=B2=80=EC=A6=9D=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=ED=95=B4=EA=B2=B0=20=EB=B0=8F=20=EC=9E=90=EB=8F=99?= =?UTF-8?q?=ED=99=94=20=EB=B2=94=EC=9C=84=20=EC=9D=B4=EC=99=B8=EC=9D=98=20?= =?UTF-8?q?=EC=83=81=EC=88=98=20=EB=B0=8F=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20?= =?UTF-8?q?=EB=B2=88=EC=97=AD=20=EC=9E=91=EC=97=85=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?(#429)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 타이머 오버뷰에서 토론자 순번 번역 추가 * feat: 헤더의 테이블정보와 타이틀 번역 추가 * refactor: 토론 정보 수정시 언어에 따른 기본 value 번역되도록 수정 * fix: 직접입력의 키가 불일치하여 번역이 적용되지 않는 문제 해결 * refactor: 찬성, 반대, 중립을 선택하는 드롭박스가 번역되도록 사용처에 번역 작업 추가 * refactor: 헤더 컴포넌트 내부에서 번역 작업하던 구조를 사용처에서 하도록 개선 * refactor: 팀 이름 키가 있는 경우 번역되도록 번역 작업 추가 * refactor: 기본 입력으로 생성된 각각의 타이머 경우에도 팀명이 번역되도록 번역 작업 추가 * refactor: Schedule -> Timetable로 수정 * refactor: 팀 이름 검증 규칙 번역키, 밸류 수정 * refactor: 팀 이름 15자 이내로 변경 * refactor: 번역 오류 수정 및 대소문자 수정 * refactor: 분과 초를 함께 쓰는 경우 기호 버전으로 min -> m 사용하도록 수정 * refactor: 이전차례, 다음차례 번역 수정 * refactor: 기본 템플릿에 설정된 발언 유형 번역 추가 * refactor: 1회당 발언 시간, 팀당 발언 시간 번역 수정 * refactor: 좌측 영역의 정보의 길이 때문에 레이아웃이 바뀌지 않도록 수정 * refactor: 새로운 템플릿 신청 관련 번역 수정 * refactor: 동사형으로 들어가야 하는 번역 수정 * refactor: 사용하지 않는 prop 삭제 * refactor: 번역 수정 --- public/locales/en/translation.json | 76 ++++++++++--------- public/locales/ko/translation.json | 12 ++- .../HeaderTableInfo/HeaderTableInfo.tsx | 5 +- src/components/HeaderTitle/HeaderTitle.tsx | 5 +- src/hooks/useFullscreen.ts | 2 +- .../TableNameAndType/TableNameAndType.tsx | 16 ++-- .../components/TimeBox/TimeBox.tsx | 2 +- .../components/TimeBoxStep/TimeBoxStep.tsx | 24 +++++- .../TimerCreationContent.tsx | 12 +-- .../TableOverviewPage/TableOverviewPage.tsx | 28 +++++-- src/page/TimerPage/TimerPage.tsx | 4 +- src/page/TimerPage/components/NormalTimer.tsx | 12 +-- .../TimerPage/components/TimeBasedTimer.tsx | 2 +- src/util/speechType.ts | 2 +- 14 files changed, 118 insertions(+), 84 deletions(-) diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json index 72bc24d0..4e77589f 100644 --- a/public/locales/en/translation.json +++ b/public/locales/en/translation.json @@ -24,12 +24,12 @@ "공유받은 데이터 처리에 실패했어요.": "Failed to process the shared data.", "팀 선정하기": "Select teams", "토론하기": "Start debate", - "토론 시간표를 선택해주세요": "Please select a debate schedule", + "토론 시간표를 선택해주세요": "Please select a debate timetable", "테이블 모드가 올바르지 않습니다.": "Invalid table mode.", - "시간표 1": "Schedule 1", + "시간표 1": "Timetable 1", "찬성": "Affirmative", "반대": "Negative", - "시간표 정보를 불러오지 못했어요.\n다시 시도할까요?": "Couldn't load the schedule.\nTry again?", + "시간표 정보를 불러오지 못했어요.\n다시 시도할까요?": "Couldn't load the timetable.\nTry again?", "무승부": "Tie", "유효하지 않은 투표 결과 링크입니다.": "Invalid vote result link.", "세부 결과 확인하기": "View detailed results", @@ -52,8 +52,8 @@ "링크가 클립보드에 복사됨": "Link copied to clipboard", "링크 준비 중": "Preparing link", "공유 링크 복사": "Copy share link", - "이전 차례": "Previous turn", - "다음 차례": "Next turn", + "이전 차례": "Previous", + "다음 차례": "Next", "토론 종료": "End debate", "알림 개수_one": "{{displayCount}} notification", "알림 개수_other": "{{displayCount}} notifications", @@ -81,7 +81,7 @@ "팀": "Team", "토론자": "Debater", "작전 시간 사용": "Use Prep Time", - "토론을 끝내셨군요!\n지금까지의 시간표를 로그인하고 저장할까요?": "You've finished the debate!\nLog in to save your schedule so far?", + "토론을 끝내셨군요!\n지금까지의 시간표를 로그인하고 저장할까요?": "You've finished the debate!\nLog in to save your timetable so far?", "자유토론 타이머 조작": "Open Debate Timer Controls", "재생 버튼을 눌러 타이머를 시작": "Press Play to start the timer", "타이머가 동작 중일 때, 일시정지 버튼을 눌러 타이머를 일시정지": "When the timer is running, press Pause to pause it", @@ -108,7 +108,7 @@ "+5분": "+5 min", "비회원 상태로 토론하기": "Debate as guest", "저장하기": "Save", - "공유받은 토론 시간표를 내 시간표 목록에 저장하시겠어요?": "Save the shared debate schedule to my schedules?", + "공유받은 토론 시간표를 내 시간표 목록에 저장하시겠어요?": "Save the shared debate timetable to my timetables?", "수정하기": "Edit", "삭제하기": "Delete", "공유하기": "Share", @@ -121,10 +121,10 @@ "토론자가 작전 시간을\n요청하면 <0/>\n버튼을 눌러 시간을 사용해요": "If a debater requests Prep Time\npress <0/>\nto use time", "작전 시간이 나타나면\n원하는 시간을 입력하세요!": "When Prep Time appears,\nenter the time you want!", "키보드 방향키로\n더 편리한 조작": "More convenient control\nwith arrow keys", - "시간표 설정화면": "Schedule setup screen", - "간편한 시간표 구성": "Simple schedule setup", - "시간표 추가": "Add schedule", - "시간표 추가 버튼": "Add schedule button", + "시간표 설정화면": "Timetable setup screen", + "간편한 시간표 구성": "Simple timetable setup", + "시간표 추가": "Add timetable", + "시간표 추가 버튼": "Add timetable button", "두가지 타이머": "Two timers", "일반형과 자유토론형 타이머로\n다양한 토론 방식을 지원해요.": "Support various debate formats\nwith Standard and Open Debate timers.", "종소리 설정": "Bell settings", @@ -133,15 +133,15 @@ "{{title}} 로고": "{{title}} logo", "{{label}} 토론하기": "Debate {{label}}", "템플릿 신청하기": "Request a template", - "새로운 템플릿도 신청해 볼까요?": "Want to request a new template too?", + "새로운 템플릿도 신청해 볼까요?": "Would you like to apply for a new template?", "신청하기": "Apply", "홈 | 설정": "Home | Settings", "토론 정보\n관리 및 기록": "Debate info\nManagement and records", "토론 기본 정보 설정": "Set debate basics", - "시간표 이름부터 주제까지!": "From schedule name to Topic!", - "시간표 목록": "Schedule list", - "내가 만든 시간표를 저장하고 싶나요?": "Want to save the schedules you made?", - "시간표를 저장하려면,\n디베이트 타이머에 로그인해 보세요!": "To save your schedule,\nplease log in to Debate Timer!", + "시간표 이름부터 주제까지!": "From timetable name to topic!", + "시간표 목록": "Timetable list", + "내가 만든 시간표를 저장하고 싶나요?": "Want to save the timetables you made?", + "시간표를 저장하려면,\n디베이트 타이머에 로그인해 보세요!": "To save your timetable,\nplease log in to Debate Timer!", "3초 로그인 하기": "3-second login", "아래로 스크롤": "Scroll down", "이미 많은 사람들이 디베이트 타이머로\n더 나은 토론환경을 만들고 있어요.": "Many people already use Debate Timer\nto create a better debate environment.", @@ -161,11 +161,11 @@ "투표 세부 결과": "Detailed vote results", "명_one": " person", "명_other": " people", - "시간표로 돌아가기": "Back to schedule", + "시간표로 돌아가기": "Back to timetable", "비회원 모드": "Guest mode", "홈으로 이동": "Go to Home", "로그인": "Log in", - "비회원으로 사용하던 시간표가 있습니다.\n로그인 후에도 이 시간표를 계속 사용하시겠습니까?": "You have schedules created in guest mode.\nDo you want to keep using them after you log in?", + "비회원으로 사용하던 시간표가 있습니다.\n로그인 후에도 이 시간표를 계속 사용하시겠습니까?": "You have timetables created in guest mode.\nDo you want to keep using them after you log in?", "언어 선택": "Select language", "팀별로\n동전의 앞 / 뒷면 중\n하나를 선택해 주세요.": "For each team,\nchoose heads or tails\non the coin.", "동전": "Coin", @@ -181,27 +181,29 @@ "작전시간": "Prep Time", "교차조사": "Cross Fire", "직접입력": "Custom", + "1번": "No.1", + "2번": "No.2", + "3번": "No.3", "발언 시간은 1초 이상이어야 해요.": "Speaking Time must be at least 1 second.", "종료 전 타종은 발언 시간보다 길 수 없어요.": "The bell before the end cannot be longer than the Speaking Time.", - "팀당 발언 시간은 1초 이상이어야 해요.": "Speaking Time per team must be at least 1 second.", - "1회당 발언 시간은 팀당 발언 시간을 초과할 수 없어요.": "Speaking Time per turn cannot exceed the team's total Speaking Time.", + "팀당 발언 시간은 1초 이상이어야 해요.": "Team time must be at least 1 second.", + "1회당 발언 시간은 팀당 발언 시간을 초과할 수 없어요.": "Turn time cannot exceed team time.", "발언 유형은 최대 10자까지 입력할 수 있습니다.": "Speech Type can be up to 10 characters.", "발언자는 최대 5자까지 입력할 수 있습니다.": "Speaker can be up to 5 characters.", - "1회당 발언 시간은 팀당 총 발언 시간보다 클 수 없습니다.": "Per-turn Speaking Time cannot exceed the total team Speaking Time.", "발언 유형을 입력해주세요.": "Please enter a Speech Type.", "자유토론": "Open Debate", - "중립은 발언 유형이 '직접 입력'일 경우에만 선택할 수 있습니다.": "Neutral can only be selected when Speech Type is 'Custom'.", + "중립은 발언 유형이 '직접입력'일 경우에만 선택할 수 있습니다.": "Neutral can only be selected when Speech Type is 'Custom'.", "중립": "Neutral", "일반 타이머": "Standard timer", "자유토론 타이머": "Open Debate timer", - "한 팀의 발언 시간이 세팅된 일반적인 타이머": "A standard timer with a single team's Speaking Time set", - "팀별 발언 시간과 1회당 발언 시간이 세팅된 타이머\n1회당 발언 시간이 지나면, 상대 팀으로 발언권이 넘어감": "A timer with team time and per-turn time set\nWhen a per-turn time ends, the turn passes to the other team", + "한 팀의 발언 시간이 세팅된 일반적인 타이머": "A standard timer with team time set", + "팀별 발언 시간과 1회당 발언 시간이 세팅된 타이머\n1회당 발언 시간이 지나면, 상대 팀으로 발언권이 넘어감": "A timer with team time and turn time.\nWhen the turn time ends, the turn passes to the other team.", "종류": "Type", "발언자": "Speaker", "N번 토론자": "Speaker N", "발언 시간": "Speaking Time", - "1회당\n발언 시간": "Per-turn\nSpeaking Time", - "팀당\n발언 시간": "Per-team\nSpeaking Time", + "1회당\n발언 시간": "Turn Time", + "팀당\n발언 시간": "Team Time", "발언 유형": "Speech Type", "주도권 토론 등": "e.g. Lead debate", "입론, 반론, 작전 시간 등": "e.g. Constructive, Rebuttal, Prep Time", @@ -219,19 +221,19 @@ "추가하기": "Add", "복사하기": "Copy", "이 타이머를 삭제하시겠습니까?": "Delete this timer?", - "{{minutes}}분 {{seconds}}초": "{{minutes}} min {{seconds}} sec", - "팀당 {{minutes}}분 {{seconds}}초": "{{minutes}} min {{seconds}} sec per team", - "발언당 {{minutes}}분 {{seconds}}초": "{{minutes}} min {{seconds}} sec per speech", + "{{minutes}}분 {{seconds}}초": "{{minutes}}m {{seconds}}s", + "팀당 {{minutes}}분 {{seconds}}초": "{{minutes}}m {{seconds}}s per team", + "발언당 {{minutes}}분 {{seconds}}초": "{{minutes}}m {{seconds}}s per speech", "위/아래로 드래그": "Drag up/down", " | {{speaker}} 토론자": " | {{speaker}} Debater", "토론 정보를 {{val0}}해주세요": "Please {{val0}} the debate info", - "수정": "Edit", - "설정": "Settings", - "토론 시간표 이름": "Debate schedule name", - "토론 주제": "Debate Topic", - "토론 주제를 입력해주세요": "Please enter a debate Topic", + "수정": "edit", + "설정": "configure", + "토론 시간표 이름": "Debate timetable name", + "토론 주제": "Debate topic", + "토론 주제를 입력해주세요": "Please enter a debate topic", "팀명": "Team name", - "팀명은 최대 8자까지 입력할 수 있습니다.": "Team name can be up to 8 characters.", + "팀명은 최대 15자까지 입력할 수 있습니다.": "Team name can be up to 15 characters.", "다음": "Next", "볼륨 조절": "Volume control", "투표 종료에 실패했습니다.": "Failed to end the vote.", @@ -250,5 +252,7 @@ "500 내부 서버 오류": "500 Internal Server Error", "502 게이트웨이 불량": "502 Bad Gateway", "503 서비스가 일시적으로 중단됨": "503 Service Unavailable", - "504 게이트웨이 시간 초과": "504 Gateway Timeout" + "504 게이트웨이 시간 초과": "504 Gateway Timeout", + "나의 토론 주제": "My Debate Topic", + "나의 시간표": "My Timetable" } diff --git a/public/locales/ko/translation.json b/public/locales/ko/translation.json index 2413d96e..21f5e08d 100644 --- a/public/locales/ko/translation.json +++ b/public/locales/ko/translation.json @@ -182,16 +182,18 @@ "작전시간": "작전시간", "교차조사": "교차조사", "직접입력": "직접입력", + "1번": "1번", + "2번": "2번", + "3번": "3번", "발언 시간은 1초 이상이어야 해요.": "발언 시간은 1초 이상이어야 해요.", "종료 전 타종은 발언 시간보다 길 수 없어요.": "종료 전 타종은 발언 시간보다 길 수 없어요.", "팀당 발언 시간은 1초 이상이어야 해요.": "팀당 발언 시간은 1초 이상이어야 해요.", "1회당 발언 시간은 팀당 발언 시간을 초과할 수 없어요.": "1회당 발언 시간은 팀당 발언 시간을 초과할 수 없어요.", "발언 유형은 최대 10자까지 입력할 수 있습니다.": "발언 유형은 최대 10자까지 입력할 수 있습니다.", "발언자는 최대 5자까지 입력할 수 있습니다.": "발언자는 최대 5자까지 입력할 수 있습니다.", - "1회당 발언 시간은 팀당 총 발언 시간보다 클 수 없습니다.": "1회당 발언 시간은 팀당 총 발언 시간보다 클 수 없습니다.", "발언 유형을 입력해주세요.": "발언 유형을 입력해주세요.", "자유토론": "자유토론", - "중립은 발언 유형이 '직접 입력'일 경우에만 선택할 수 있습니다.": "중립은 발언 유형이 '직접 입력'일 경우에만 선택할 수 있습니다.", + "중립은 발언 유형이 '직접입력'일 경우에만 선택할 수 있습니다.": "중립은 발언 유형이 '직접입력'일 경우에만 선택할 수 있습니다.", "일반 타이머": "일반 타이머", "자유토론 타이머": "자유토론 타이머", "한 팀의 발언 시간이 세팅된 일반적인 타이머": "한 팀의 발언 시간이 세팅된 일반적인 타이머", @@ -231,7 +233,7 @@ "토론 주제": "토론 주제", "토론 주제를 입력해주세요": "토론 주제를 입력해주세요", "팀명": "팀명", - "팀명은 최대 8자까지 입력할 수 있습니다.": "팀명은 최대 8자까지 입력할 수 있습니다.", + "팀명은 최대 15자까지 입력할 수 있습니다.": "팀명은 최대 15자까지 입력할 수 있습니다.", "다음": "다음", "볼륨 조절": "볼륨 조절", "투표 종료에 실패했습니다.": "투표 종료에 실패했습니다.", @@ -250,5 +252,7 @@ "500 내부 서버 오류": "500 내부 서버 오류", "502 게이트웨이 불량": "502 게이트웨이 불량", "503 서비스가 일시적으로 중단됨": "503 서비스가 일시적으로 중단됨", - "504 게이트웨이 시간 초과": "504 게이트웨이 시간 초과" + "504 게이트웨이 시간 초과": "504 게이트웨이 시간 초과", + "나의 토론 주제": "나의 토론 주제", + "나의 시간표": "나의 시간표" } diff --git a/src/components/HeaderTableInfo/HeaderTableInfo.tsx b/src/components/HeaderTableInfo/HeaderTableInfo.tsx index 2136e1be..7401405a 100644 --- a/src/components/HeaderTableInfo/HeaderTableInfo.tsx +++ b/src/components/HeaderTableInfo/HeaderTableInfo.tsx @@ -1,4 +1,3 @@ -import { useTranslation } from 'react-i18next'; import Skeleton from '../Skeleton/Skeleton'; interface HeaderTitleProps { @@ -7,9 +6,7 @@ interface HeaderTitleProps { } export default function HeaderTableInfo(props: HeaderTitleProps) { - const { t } = useTranslation(); const { name, skeletonEnabled: isLoading = false } = props; - const displayName = !name?.trim() ? t('테이블 이름 없음') : name.trim(); return ( <> @@ -21,7 +18,7 @@ export default function HeaderTableInfo(props: HeaderTitleProps) { )} {!isLoading && (
- {teamName && t('{{team}} 팀', { team: teamName })} +
+ {teamName && t('{{team}} 팀', { team: t(teamName) })} {item.speaker && - t(' | {{speaker}} 토론자', { speaker: item.speaker })} + t(' | {{speaker}} 토론자', { speaker: t(item.speaker) })}
)} @@ -130,7 +130,7 @@ export default function NormalTimer({ {/* 우측 영역 */} - + {/* 타이머 */}