From bf5fc05a25bed701844afb9f94ec8f4c9b19b24f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=84=B1=EA=B2=BD?= Date: Fri, 15 May 2026 09:17:15 +0900 Subject: [PATCH] =?UTF-8?q?=EC=97=90=EB=9F=AC=20=EB=A9=94=EC=8B=9C?= =?UTF-8?q?=EC=A7=80=20=ED=86=B5=EC=9D=BC=20=EB=B0=8F=20UX=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/google60b514c02fd6af4e.html | 1 - ...naver33dfe258205b0af1416aa0ac18c8c0b3.html | 1 - public/privacy.html | 71 ------------------- public/terms.html | 65 ----------------- src/App.tsx | 7 +- src/locales/en.json | 4 +- src/locales/ko.json | 4 +- src/pages/Dashboard/CompletionContent.tsx | 13 ++-- src/pages/Dashboard/GenerationFlow.tsx | 13 ++-- src/pages/Dashboard/UrlInputContent.tsx | 18 ++--- 10 files changed, 32 insertions(+), 165 deletions(-) delete mode 100644 public/google60b514c02fd6af4e.html delete mode 100644 public/naver33dfe258205b0af1416aa0ac18c8c0b3.html delete mode 100644 public/privacy.html delete mode 100644 public/terms.html diff --git a/public/google60b514c02fd6af4e.html b/public/google60b514c02fd6af4e.html deleted file mode 100644 index 968a1e3..0000000 --- a/public/google60b514c02fd6af4e.html +++ /dev/null @@ -1 +0,0 @@ -google-site-verification: google60b514c02fd6af4e.html \ No newline at end of file diff --git a/public/naver33dfe258205b0af1416aa0ac18c8c0b3.html b/public/naver33dfe258205b0af1416aa0ac18c8c0b3.html deleted file mode 100644 index e37cfc0..0000000 --- a/public/naver33dfe258205b0af1416aa0ac18c8c0b3.html +++ /dev/null @@ -1 +0,0 @@ -naver-site-verification: naver33dfe258205b0af1416aa0ac18c8c0b3.html \ No newline at end of file diff --git a/public/privacy.html b/public/privacy.html deleted file mode 100644 index 5e99ead..0000000 --- a/public/privacy.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - 개인정보처리방침 - ADO2 - - - -

개인정보처리방침 (Privacy Policy)

-

시행일: 2026년 5월 7일  |  최종 수정일: 2026년 5월 7일

- -

㈜에이아이오투오(이하 "회사")는 AI 마케팅 자동화 서비스 ADO2(이하 "서비스")를 제공함에 있어 사용자의 개인정보를 중요시하며, 「개인정보 보호법」 등 관련 법령을 성실히 준수합니다.

- -

1. 수집하는 개인정보 항목 및 수집 방법

-

회사는 서비스 제공을 위해 아래와 같은 개인정보를 수집합니다.

- - -

2. 개인정보의 수집 및 이용 목적

- - -
-

[Google API 서비스 사용자 데이터 정책 준수]

- ㈜에이아이오투오가 운영하는 ADO2 서비스가 Google API로부터 수신한 정보의 사용 및 타 앱으로의 전송은, - Google API 서비스 사용자 데이터 정책의 - 제한적 사용(Limited Use) 요건을 포함한 모든 정책을 엄격히 준수합니다.

-
- -

3. 개인정보의 보유 및 이용 기간

-

원칙적으로 회원 탈퇴 또는 개인정보 수집·이용 목적이 달성된 후에는 해당 정보를 지체 없이 파기합니다. 단, 관련 법령에 따라 보존이 필요한 경우 해당 기간 동안 보관합니다.

- - -

4. 개인정보의 제3자 제공

-

회사는 사용자의 사전 동의 없이 개인정보를 외부에 제공하지 않습니다. 다만, 법령에 의거한 수사기관 등의 적법한 요청이 있는 경우는 예외로 합니다.

- -

5. 정보주체의 권리 및 행사 방법

-

사용자는 언제든지 자신의 개인정보에 대한 열람, 수정, 삭제, 처리 정지를 요청할 수 있습니다. 서비스 내 계정 설정에서 직접 처리하거나 아래 문의처로 연락해 주시기 바랍니다.

- -

6. 개인정보 보호책임자 및 문의처

-

개인정보 보호와 관련된 불만 처리 및 피해 구제에 관한 사항은 아래로 문의해 주시기 바랍니다.

- - -

본 방침은 2026년 5월 7일부터 시행됩니다.

- - \ No newline at end of file diff --git a/public/terms.html b/public/terms.html deleted file mode 100644 index 3875de8..0000000 --- a/public/terms.html +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - 서비스 약관 - ADO2 - - - -

서비스 이용약관 (Terms of Service)

-

시행일: 2026년 5월 7일  |  최종 수정일: 2026년 5월 7일

- -

제 1 조 (목적)

-

본 약관은 ㈜에이아이오투오(이하 "회사")가 제공하는 AI 마케팅 자동화 서비스 ADO2(이하 "서비스")의 이용과 관련하여, 회사와 이용자(이하 "회원") 간의 권리, 의무 및 책임사항을 규정함을 목적으로 합니다.

- -

제 2 조 (용어의 정의)

- - -

제 3 조 (약관의 효력 및 변경)

-

회사는 본 약관의 내용을 서비스 화면에 게시하며, 관련 법령을 위배하지 않는 범위에서 약관을 개정할 수 있습니다. 약관이 변경되는 경우 시행일 7일 전부터 공지합니다.

- -

제 4 조 (서비스의 제공 및 변경)

-

회사는 AI 기반 마케팅 콘텐츠(가사, 이미지, 영상 등) 자동 생성, Google·YouTube 등 외부 플랫폼 연동, SNS 자동 배포 등의 서비스를 제공합니다. 운영상·기술상의 필요에 따라 서비스의 전부 또는 일부를 변경할 수 있습니다.

- -

제 5 조 (회원의 의무)

- - -

제 6 조 (외부 API 연동 및 데이터 활용)

-

서비스는 Google, YouTube, Naver 등의 제3자 API를 활용하여 마케팅 자동화 기능을 제공합니다. 회원은 각 외부 서비스의 이용약관 및 정책을 준수할 의무가 있으며, 외부 API 제공사의 정책 변경으로 인한 서비스 제한에 대해 회사는 면책됩니다.

- -

제 7 조 (AI 생성 콘텐츠의 권리)

-

서비스 내에서 AI가 생성한 콘텐츠에 대한 권리 관계는 관련 법령 및 회사의 별도 정책에 따릅니다. 회원이 직접 입력한 정보(매장 URL, 상호명 등)를 기반으로 생성된 콘텐츠에 대한 책임은 회원에게 있습니다.

- -

제 8 조 (책임 제한)

-

회사는 천재지변, 외부 플랫폼(Google, YouTube, Naver 등)의 장애, 통신 장애 등 불가항력으로 서비스를 제공할 수 없는 경우 책임이 면제됩니다.

- -

제 9 조 (준거법 및 재판관할)

-

본 약관과 관련된 분쟁은 대한민국 법을 준거법으로 하며, 소송은 회사의 소재지를 관할하는 법원에 제소합니다.

- -

문의처

- - -

본 약관은 2026년 5월 7일부터 시행됩니다.

- - \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx index 279fe8d..30953e8 100755 --- a/src/App.tsx +++ b/src/App.tsx @@ -275,8 +275,7 @@ const App: React.FC = () => { setIsAnalysisComplete(true); } catch (err) { console.error('Crawling failed:', err); - const errorMessage = err instanceof Error ? err.message : t('app.analysisError'); - setError(errorMessage); + setError(t('app.analysisError')); setViewMode('landing'); } }; @@ -301,9 +300,7 @@ const App: React.FC = () => { setIsAnalysisComplete(true); } catch (err) { console.error('Autocomplete failed:', err); - const is404 = err instanceof Error && err.message.includes('status: 404'); - const errorMessage = is404 ? t('app.autocompleteError') : (err instanceof Error ? err.message : t('app.autocompleteGeneralError')); - setError(errorMessage); + setError(t('app.autocompleteError')); setViewMode('landing'); } }; diff --git a/src/locales/en.json b/src/locales/en.json index 96ab94f..848bfa7 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -550,8 +550,8 @@ "kakaoLoginFailed": "Kakao login failed. Please try again.", "loginUrlFailed": "Failed to get login URL. Please try again.", "invalidUrl": "Invalid URL. Please enter a Naver Map URL.", - "analysisError": "An error occurred during analysis. Please try again.", - "autocompleteError": "Failed to retrieve business information. Please enter the URL directly.", + "analysisError": "No results found. Please check your input and try again.", + "autocompleteError": "No results found. Please check your input and try again.", "autocompleteGeneralError": "An error occurred while retrieving business information. Please try again.", "pageComingSoon": "{{page}} page is coming soon." } diff --git a/src/locales/ko.json b/src/locales/ko.json index 577d754..aee7f29 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -550,8 +550,8 @@ "kakaoLoginFailed": "카카오 로그인에 실패했습니다. 다시 시도해주세요.", "loginUrlFailed": "로그인 URL을 가져오는데 실패했습니다. 다시 시도해주세요.", "invalidUrl": "유효하지 않은 URL입니다. 네이버 지도 URL을 입력해주세요.", - "analysisError": "분석 중 오류가 발생했습니다. 다시 시도해주세요.", - "autocompleteError": "업체 정보 조회에 실패했습니다. URL을 직접 입력해주세요.", + "analysisError": "검색 정보를 찾을 수 없습니다. 입력 정보를 다시 확인해주세요.", + "autocompleteError": "검색 정보를 찾을 수 없습니다. 입력 정보를 다시 확인해주세요.", "autocompleteGeneralError": "업체 정보 조회 중 오류가 발생했습니다. 다시 시도해주세요.", "pageComingSoon": "{{page}} 페이지 준비 중입니다." } diff --git a/src/pages/Dashboard/CompletionContent.tsx b/src/pages/Dashboard/CompletionContent.tsx index 9315678..2322fc2 100755 --- a/src/pages/Dashboard/CompletionContent.tsx +++ b/src/pages/Dashboard/CompletionContent.tsx @@ -364,6 +364,7 @@ const CompletionContent: React.FC = ({ const handleCloseSocialConnect = () => { setShowSocialModal(false); + onVideoComplete?.(); }; const handleRetry = () => { @@ -484,13 +485,13 @@ const CompletionContent: React.FC = ({
{t('completion.lyrics')} {(() => { - const lyricsText = songCompletionData - ? (songCompletionData.lyrics || '') - : t('completion.sampleLyrics'); - if (!songCompletionData?.lyrics) { - return

{lyricsText}

; + if (!songCompletionData) { + return

{t('completion.sampleLyrics')}

; } - const lines = lyricsText.split('\n').filter((l: string) => l.trim()); + if (!songCompletionData.lyrics) { + return

{t('completion.noLyricsBGM')}

; + } + const lines = songCompletionData.lyrics.split('\n').filter((l: string) => l.trim()); const size = Math.ceil(lines.length / 3); const sections = [ { tag: '[Verse]', lines: lines.slice(0, size) }, diff --git a/src/pages/Dashboard/GenerationFlow.tsx b/src/pages/Dashboard/GenerationFlow.tsx index 0709821..5eb79c0 100755 --- a/src/pages/Dashboard/GenerationFlow.tsx +++ b/src/pages/Dashboard/GenerationFlow.tsx @@ -130,6 +130,13 @@ const GenerationFlow: React.FC = ({ } }, []); + // 사운드 스튜디오, 영상 완성 진입 시 크레딧 갱신 + useEffect(() => { + if (wizardStep === 2 || wizardStep === 3) { + refreshCredits(); + } + }, [wizardStep]); + // 로그인 직후 사용자 정보 + 크레딧 조회 useEffect(() => { const fetchUserInfo = async () => { @@ -248,8 +255,7 @@ const GenerationFlow: React.FC = ({ setIsAnalysisComplete(true); } catch (err) { console.error('Autocomplete error:', err); - const msg = err instanceof Error ? err.message : ''; - setAnalysisError(/^HTTP error!/.test(msg) ? t('app.autocompleteError') : (msg || t('app.autocompleteError'))); + setAnalysisError(t('app.autocompleteError')); goToWizardStep(-2); // URL 입력으로 돌아가기 } }; @@ -318,8 +324,7 @@ const GenerationFlow: React.FC = ({ setIsAnalysisComplete(true); } catch (err) { console.error('Crawling failed:', err); - const errorMessage = err instanceof Error ? err.message : t('app.analysisError'); - setAnalysisError(errorMessage); + setAnalysisError(t('app.analysisError')); goToWizardStep(-2); // URL 입력으로 돌아가기 } }; diff --git a/src/pages/Dashboard/UrlInputContent.tsx b/src/pages/Dashboard/UrlInputContent.tsx index 2d8f927..063524f 100644 --- a/src/pages/Dashboard/UrlInputContent.tsx +++ b/src/pages/Dashboard/UrlInputContent.tsx @@ -160,14 +160,16 @@ const UrlInputContent: React.FC = ({ onAnalyze, onAutocomp const handleAnalyzeClick = () => { if (!inputValue.trim()) return; - if (searchType === 'name' && selectedItem && onAutocomplete) { - // 업체명 검색인 경우 autocomplete API 호출 - const request: AutocompleteRequest = { - address: selectedItem.address, - roadAddress: selectedItem.roadAddress, - title: selectedItem.title, - }; - onAutocomplete(request); + if (searchType === 'name') { + if (selectedItem && onAutocomplete) { + const request: AutocompleteRequest = { + address: selectedItem.address, + roadAddress: selectedItem.roadAddress, + title: selectedItem.title, + }; + onAutocomplete(request); + } + // selectedItem 없으면 아무것도 하지 않음 (드롭다운에서 선택 필요) } else { // URL 검색인 경우 기존 로직 onAnalyze(inputValue.trim(), searchType);