From e2b4bced4519930b93c3e8a1a9622a6cafd67eb8 Mon Sep 17 00:00:00 2001 From: HarrySeop Date: Mon, 4 Aug 2025 21:57:40 +0900 Subject: [PATCH 1/6] =?UTF-8?q?=F0=9F=8E=A8=20[#258]=20Style:=20=ED=94=8C?= =?UTF-8?q?=EB=A1=9C=ED=8C=85=20=EB=B2=84=ED=8A=BC=20=EB=94=94=EC=9E=90?= =?UTF-8?q?=EC=9D=B8=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/what-today/src/components/FlagIcon.tsx | 3 ++- .../src/components/FloatingTranslateButton.tsx | 14 ++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/apps/what-today/src/components/FlagIcon.tsx b/apps/what-today/src/components/FlagIcon.tsx index 44be7551..f4db9d18 100644 --- a/apps/what-today/src/components/FlagIcon.tsx +++ b/apps/what-today/src/components/FlagIcon.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { twMerge } from 'tailwind-merge'; interface FlagIconProps { flagCode: string; @@ -19,7 +20,7 @@ const FlagIcon: React.FC = ({ flagCode, alt = 'Flag', className = return ( {alt} { // 이미지 로드 실패 시 기본 아이콘으로 대체 diff --git a/apps/what-today/src/components/FloatingTranslateButton.tsx b/apps/what-today/src/components/FloatingTranslateButton.tsx index 59026a51..21c86dbd 100644 --- a/apps/what-today/src/components/FloatingTranslateButton.tsx +++ b/apps/what-today/src/components/FloatingTranslateButton.tsx @@ -276,9 +276,9 @@ const FloatingTranslateButton: React.FC = ({ class
{/* 언어 선택 드롭다운 */} {isOpen && ( -
-
언어 선택
-
+
+
언어 선택
+
{languages.map((language) => ( ))} @@ -301,13 +301,11 @@ const FloatingTranslateButton: React.FC = ({ class {/* 플로팅 버튼 */}
From 29e460b556d068e29842df41f8b931a215c3aba1 Mon Sep 17 00:00:00 2001 From: HarrySeop Date: Mon, 4 Aug 2025 22:04:56 +0900 Subject: [PATCH 2/6] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20[#258]=20Refactor:=20?= =?UTF-8?q?=EA=B5=AC=EA=B8=80=20=EB=B2=88=EC=97=AD=20=ED=86=A0=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EB=A9=94=EC=84=B8=EC=A7=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/FloatingTranslateButton.tsx | 50 ++++++++++++++----- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/apps/what-today/src/components/FloatingTranslateButton.tsx b/apps/what-today/src/components/FloatingTranslateButton.tsx index 21c86dbd..414b9cf2 100644 --- a/apps/what-today/src/components/FloatingTranslateButton.tsx +++ b/apps/what-today/src/components/FloatingTranslateButton.tsx @@ -1,4 +1,5 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ +import { useToast } from '@what-today/design-system'; import React, { useCallback, useEffect, useRef, useState } from 'react'; import { twMerge } from 'tailwind-merge'; @@ -15,6 +16,7 @@ interface FloatingTranslateButtonProps { } const FloatingTranslateButton: React.FC = ({ className }) => { + const { toast } = useToast(); const [selectedLanguage, setSelectedLanguage] = useState(languages[0]); const [isReady, setIsReady] = useState(false); const [currentTranslatedLang, setCurrentTranslatedLang] = useState('ko'); @@ -88,11 +90,15 @@ const FloatingTranslateButton: React.FC = ({ class detectCurrentLanguage(); }, 300); } - } catch (error) { - console.error('Google Translate 초기화 실패:', error); + } catch { + toast({ + title: '번역 오류', + description: '번역 중 오류가 발생했습니다. 새로고침 부탁드려요', + type: 'error', + }); initializationAttempted.current = false; } - }, [detectCurrentLanguage]); + }, [detectCurrentLanguage, toast]); // Google Translate 스크립트 로드 useEffect(() => { @@ -123,12 +129,16 @@ const FloatingTranslateButton: React.FC = ({ class script.src = 'https://translate.google.com/translate_a/element.js?cb=googleTranslateElementInit'; script.async = true; script.onerror = () => { - console.error('Google Translate 스크립트 로드 실패'); + toast({ + title: '번역 오류', + description: '번역 중 오류가 발생했습니다. 새로고침 부탁드려요', + type: 'error', + }); isGoogleTranslateLoading = false; }; document.head.appendChild(script); } - }, [initializeGoogleTranslate]); + }, [initializeGoogleTranslate, toast]); // URL 변경 감지 (번역 후 URL이 변경되므로) useEffect(() => { @@ -165,7 +175,11 @@ const FloatingTranslateButton: React.FC = ({ class const changeLanguage = useCallback( (language: Language) => { if (!isReady) { - console.warn('Google Translate가 아직 준비되지 않았습니다.'); + toast({ + title: '번역 오류', + description: '번역 중 오류가 발생했습니다. 새로고침 부탁드려요', + type: 'error', + }); return; } @@ -221,8 +235,12 @@ const FloatingTranslateButton: React.FC = ({ class // ✅ 최종: URL 파라미터 제거 & 페이지 새로고침 const newUrl = window.location.origin + window.location.pathname; window.location.href = newUrl; - } catch (error) { - console.error('원문 복귀 실패:', error); + } catch { + toast({ + title: '번역 오류', + description: '번역 중 오류가 발생했습니다. 새로고침 부탁드려요', + type: 'error', + }); } return; @@ -250,16 +268,24 @@ const FloatingTranslateButton: React.FC = ({ class setIsOpen(false); } } else { - console.error('Google Translate select 요소를 찾을 수 없습니다.'); + toast({ + title: '번역 오류', + description: '번역 중 오류가 발생했습니다. 새로고침 부탁드려요', + type: 'error', + }); // 초기화 재시도 initializationAttempted.current = false; setTimeout(() => initializeGoogleTranslate(), 500); } - } catch (error) { - console.error('언어 변경 중 오류:', error); + } catch { + toast({ + title: '번역 오류', + description: '번역 중 오류가 발생했습니다. 새로고침 부탁드려요', + type: 'error', + }); } }, - [isReady, currentTranslatedLang, initializeGoogleTranslate], + [isReady, currentTranslatedLang, initializeGoogleTranslate, toast], ); // 버튼 클릭 핸들러 From 6e659a72f1aba2529a759147bda37ac69e26e24e Mon Sep 17 00:00:00 2001 From: HarrySeop Date: Mon, 4 Aug 2025 22:15:48 +0900 Subject: [PATCH 3/6] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20[#258]=20Refactor:=20?= =?UTF-8?q?=EC=83=88=EB=A1=9C=EA=B3=A0=EC=B9=A8=ED=95=B4=EB=8F=84=20?= =?UTF-8?q?=ED=94=8C=EB=A1=9C=ED=8C=85=20=EB=B2=84=ED=8A=BC=20=EA=B5=AD?= =?UTF-8?q?=EA=B0=80=20=EC=9C=A0=EC=A7=80=EB=90=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/FloatingTranslateButton.tsx | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/apps/what-today/src/components/FloatingTranslateButton.tsx b/apps/what-today/src/components/FloatingTranslateButton.tsx index 414b9cf2..ddfc1d2a 100644 --- a/apps/what-today/src/components/FloatingTranslateButton.tsx +++ b/apps/what-today/src/components/FloatingTranslateButton.tsx @@ -27,11 +27,21 @@ const FloatingTranslateButton: React.FC = ({ class // 현재 번역된 언어 감지 const detectCurrentLanguage = useCallback(() => { try { - // URL에서 현재 번역 언어 감지 + // 우선 googtrans 쿠키 확인 + const match = document.cookie.match(/(?:^|;\s*)googtrans=\/[a-z]+\/([a-z]+)/); + if (match && match[1]) { + const detectedLang = match[1]; + setCurrentTranslatedLang(detectedLang); + const foundLang = findLanguageByCode(detectedLang); + if (foundLang) { + setSelectedLanguage(foundLang); + } + return; + } + + // fallback: URL 파라미터 확인 const urlParams = new URLSearchParams(window.location.search); const langFromUrl = urlParams.get('lang'); - - // Google Translate가 URL에 추가하는 언어 코드 확인 if (langFromUrl) { setCurrentTranslatedLang(langFromUrl); const foundLang = findLanguageByCode(langFromUrl); @@ -41,7 +51,7 @@ const FloatingTranslateButton: React.FC = ({ class return; } - // body 클래스에서 번역 상태 확인 + // fallback: body class 확인 const bodyClasses = document.body.className; if (bodyClasses.includes('translated-')) { const matches = bodyClasses.match(/translated-(\w+)/); @@ -54,10 +64,14 @@ const FloatingTranslateButton: React.FC = ({ class } } } - } catch (error) { - console.warn('언어 감지 중 오류:', error); + } catch { + toast({ + title: '번역 오류', + description: '언어 감지 중 오류가 발생했습니다. 새로고침 부탁드려요', + type: 'error', + }); } - }, []); + }, [toast]); // Google Translate 위젯 초기화 const initializeGoogleTranslate = useCallback(() => { From 2e9332627edcd25caa493dbc511e38c20d7a255c Mon Sep 17 00:00:00 2001 From: HarrySeop Date: Mon, 4 Aug 2025 22:28:53 +0900 Subject: [PATCH 4/6] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20[#258]=20Refactor:=20?= =?UTF-8?q?=EB=B2=88=EC=97=AD=20=EC=98=A4=EB=A5=98=20=EB=B0=9C=EC=83=9D?= =?UTF-8?q?=EC=8B=9C=20=EC=9E=90=EB=8F=99=EC=9C=BC=EB=A1=9C=20=EC=83=88?= =?UTF-8?q?=EB=A1=9C=EA=B3=A0=EC=B9=A8=20=EB=90=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/FloatingTranslateButton.tsx | 46 ++++++++++++------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/apps/what-today/src/components/FloatingTranslateButton.tsx b/apps/what-today/src/components/FloatingTranslateButton.tsx index ddfc1d2a..c3c3f27a 100644 --- a/apps/what-today/src/components/FloatingTranslateButton.tsx +++ b/apps/what-today/src/components/FloatingTranslateButton.tsx @@ -67,9 +67,11 @@ const FloatingTranslateButton: React.FC = ({ class } catch { toast({ title: '번역 오류', - description: '언어 감지 중 오류가 발생했습니다. 새로고침 부탁드려요', - type: 'error', + description: '언어 감지 오류로 새로고침합니다.', }); + setTimeout(() => { + window.location.reload(); + }, 1000); } }, [toast]); @@ -107,9 +109,11 @@ const FloatingTranslateButton: React.FC = ({ class } catch { toast({ title: '번역 오류', - description: '번역 중 오류가 발생했습니다. 새로고침 부탁드려요', - type: 'error', + description: '번역 오류로 새로고침합니다.', }); + setTimeout(() => { + window.location.reload(); + }, 1000); initializationAttempted.current = false; } }, [detectCurrentLanguage, toast]); @@ -145,9 +149,11 @@ const FloatingTranslateButton: React.FC = ({ class script.onerror = () => { toast({ title: '번역 오류', - description: '번역 중 오류가 발생했습니다. 새로고침 부탁드려요', - type: 'error', + description: '번역 오류로 새로고침합니다.', }); + setTimeout(() => { + window.location.reload(); + }, 1000); isGoogleTranslateLoading = false; }; document.head.appendChild(script); @@ -191,9 +197,11 @@ const FloatingTranslateButton: React.FC = ({ class if (!isReady) { toast({ title: '번역 오류', - description: '번역 중 오류가 발생했습니다. 새로고침 부탁드려요', - type: 'error', + description: '번역 오류로 새로고침합니다.', }); + setTimeout(() => { + window.location.reload(); + }, 1000); return; } @@ -252,9 +260,11 @@ const FloatingTranslateButton: React.FC = ({ class } catch { toast({ title: '번역 오류', - description: '번역 중 오류가 발생했습니다. 새로고침 부탁드려요', - type: 'error', + description: '번역 오류로 새로고침합니다.', }); + setTimeout(() => { + window.location.reload(); + }, 1000); } return; @@ -284,9 +294,11 @@ const FloatingTranslateButton: React.FC = ({ class } else { toast({ title: '번역 오류', - description: '번역 중 오류가 발생했습니다. 새로고침 부탁드려요', - type: 'error', + description: '번역 오류로 새로고침합니다.', }); + setTimeout(() => { + window.location.reload(); + }, 1000); // 초기화 재시도 initializationAttempted.current = false; setTimeout(() => initializeGoogleTranslate(), 500); @@ -294,9 +306,11 @@ const FloatingTranslateButton: React.FC = ({ class } catch { toast({ title: '번역 오류', - description: '번역 중 오류가 발생했습니다. 새로고침 부탁드려요', - type: 'error', + description: '번역 오류로 새로고침합니다.', }); + setTimeout(() => { + window.location.reload(); + }, 1000); } }, [isReady, currentTranslatedLang, initializeGoogleTranslate, toast], @@ -313,10 +327,10 @@ const FloatingTranslateButton: React.FC = ({ class
{/* 플로팅 번역 버튼 */} -
+
{/* 언어 선택 드롭다운 */} {isOpen && ( -
+
언어 선택
{languages.map((language) => ( From 59e22d863bfc4c33b2ef63cf4277e485173c976a Mon Sep 17 00:00:00 2001 From: HarrySeop Date: Mon, 4 Aug 2025 23:56:37 +0900 Subject: [PATCH 5/6] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20[#258]=20Refactor:=20?= =?UTF-8?q?=ED=85=9C=ED=94=8C=EB=A6=BF=20=EB=AC=B8=EC=9E=90=EC=97=B4=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/what-today/src/components/FlagIcon.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/what-today/src/components/FlagIcon.tsx b/apps/what-today/src/components/FlagIcon.tsx index f4db9d18..785de77a 100644 --- a/apps/what-today/src/components/FlagIcon.tsx +++ b/apps/what-today/src/components/FlagIcon.tsx @@ -20,7 +20,7 @@ const FlagIcon: React.FC = ({ flagCode, alt = 'Flag', className = return ( {alt} { // 이미지 로드 실패 시 기본 아이콘으로 대체 From 4903ec6c0cfe1c591090948966bfb3db8204147a Mon Sep 17 00:00:00 2001 From: HarrySeop Date: Tue, 5 Aug 2025 00:53:05 +0900 Subject: [PATCH 6/6] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20[#258]=20Refactor:=20?= =?UTF-8?q?=EC=96=B8=EC=96=B4=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EC=9E=AC?= =?UTF-8?q?=EB=B0=B0=EC=B9=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/what-today/src/constants/languages.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/what-today/src/constants/languages.ts b/apps/what-today/src/constants/languages.ts index 573b9053..a29796fb 100644 --- a/apps/what-today/src/constants/languages.ts +++ b/apps/what-today/src/constants/languages.ts @@ -7,16 +7,16 @@ export interface Language { export const languages: Language[] = [ { code: 'ko', name: '한국어', flag: 'kr' }, // 한국어 { code: 'en', name: 'English', flag: 'us' }, // 영어 - { code: 'fr', name: 'Français', flag: 'fr' }, // 프랑스어 + { code: 'ja', name: '日本語', flag: 'jp' }, // 일본어 { code: 'de', name: 'Deutsch', flag: 'de' }, // 독일어 + { code: 'hi', name: 'हिन्दी', flag: 'in' }, // 힌디어 + { code: 'fr', name: 'Français', flag: 'fr' }, // 프랑스어 { code: 'zh-TW', name: '中文(繁體)', flag: 'tw' }, // 중국어(번체, 대만) - { code: 'ja', name: '日本語', flag: 'jp' }, // 일본어 { code: 'es', name: 'Español', flag: 'es' }, // 스페인어 { code: 'ru', name: 'Русский', flag: 'ru' }, // 러시아어 { code: 'it', name: 'Italiano', flag: 'it' }, // 이탈리아어 { code: 'pt', name: 'Português', flag: 'pt' }, // 포르투갈어 { code: 'ar', name: 'العربية', flag: 'sa' }, // 아랍어 - { code: 'hi', name: 'हिन्दी', flag: 'in' }, // 힌디어 { code: 'th', name: 'ไทย', flag: 'th' }, // 태국어 { code: 'tr', name: 'Türkçe', flag: 'tr' }, // 터키어 { code: 'el', name: 'Ελληνικά', flag: 'gr' }, // 그리스어