From 9fe03a66cbf0cb20c3a48cb8588937db237682d3 Mon Sep 17 00:00:00 2001 From: hbyang Date: Mon, 9 Mar 2026 13:10:55 +0900 Subject: [PATCH 1/2] =?UTF-8?q?url=20=EB=B6=99=ED=98=80=EB=84=A3=EA=B8=B0?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=20.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/Dashboard/UrlInputContent.tsx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/pages/Dashboard/UrlInputContent.tsx b/src/pages/Dashboard/UrlInputContent.tsx index 2329fdc..12dec9c 100644 --- a/src/pages/Dashboard/UrlInputContent.tsx +++ b/src/pages/Dashboard/UrlInputContent.tsx @@ -124,6 +124,17 @@ const UrlInputContent: React.FC = ({ onAnalyze, onAutocomp } }; + // 붙여넣기 시 URL만 추출 + const handlePaste = (e: React.ClipboardEvent) => { + if (searchType !== 'url') return; + const pasted = e.clipboardData.getData('text'); + const urlMatch = pasted.match(/https?:\/\/[^\s]+/); + if (urlMatch) { + e.preventDefault(); + setInputValue(urlMatch[0]); + } + }; + // 폼 제출 처리 const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); @@ -212,6 +223,7 @@ const UrlInputContent: React.FC = ({ onAnalyze, onAutocomp }, 300); } }} + onPaste={handlePaste} onFocus={() => { if (searchType === 'name' && autocompleteResults.length > 0) { setShowAutocomplete(true); From 937ef7a57614ca153cc4a81f5f608287e2674b4a Mon Sep 17 00:00:00 2001 From: hbyang Date: Mon, 9 Mar 2026 13:46:54 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=95=84=EC=9B=83=20loca?= =?UTF-8?q?l=20storage=20=20=EC=A0=95=EB=A6=AC=20.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/api.ts | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/utils/api.ts b/src/utils/api.ts index 11f313a..2c980a4 100644 --- a/src/utils/api.ts +++ b/src/utils/api.ts @@ -596,14 +596,28 @@ export async function refreshAccessToken(): Promise { return data; } +// 로컬 스토리지 전체 정리 +function clearAllLocalData() { + clearTokens(); + localStorage.removeItem('castad_view_mode'); + localStorage.removeItem('castad_analysis_data'); + localStorage.removeItem('castad_wizard_step'); + localStorage.removeItem('castad_active_item'); + localStorage.removeItem('castad_song_task_id'); + localStorage.removeItem('castad_image_task_id'); + localStorage.removeItem('castad_song_generation'); + localStorage.removeItem('castad_video_generation'); + localStorage.removeItem('castad_video_ratio'); +} + // 로그아웃 export async function logout(): Promise { const response = await authenticatedFetch(`${API_URL}/user/auth/logout`, { method: 'POST', }); - // 응답과 관계없이 로컬 토큰 삭제 - clearTokens(); + // 응답과 관계없이 로컬 데이터 전체 삭제 + clearAllLocalData(); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); @@ -616,8 +630,8 @@ export async function logoutAll(): Promise { method: 'POST', }); - // 응답과 관계없이 로컬 토큰 삭제 - clearTokens(); + // 응답과 관계없이 로컬 데이터 전체 삭제 + clearAllLocalData(); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`);