diff --git a/package-lock.json b/package-lock.json index 10f86e1..b82fec8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@capacitor/core": "^7.4.2", "@capacitor/ios": "^7.4.2", "@clerk/clerk-react": "^5.33.0", + "@clerk/localizations": "^3.18.0", "@hookform/resolvers": "^3.9.0", "@radix-ui/react-accordion": "^1.2.0", "@radix-ui/react-alert-dialog": "^1.1.1", @@ -508,6 +509,18 @@ "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-0" } }, + "node_modules/@clerk/localizations": { + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@clerk/localizations/-/localizations-3.18.0.tgz", + "integrity": "sha512-vlkQTm/wLEoqyRoD1tUOD0iZ4WzcJDwESVV/rneFeeCLTqZnaVW4u7pxlZOKmgY6GT9ysd/QI0IzeCcKWxZ2Fg==", + "license": "MIT", + "dependencies": { + "@clerk/types": "^4.64.0" + }, + "engines": { + "node": ">=18.17.0" + } + }, "node_modules/@clerk/shared": { "version": "3.11.0", "resolved": "https://registry.npmjs.org/@clerk/shared/-/shared-3.11.0.tgz", diff --git a/package.json b/package.json index 72143c9..67c6b14 100644 --- a/package.json +++ b/package.json @@ -91,6 +91,7 @@ "@capacitor/core": "^7.4.2", "@capacitor/ios": "^7.4.2", "@clerk/clerk-react": "^5.33.0", + "@clerk/localizations": "^3.18.0", "@hookform/resolvers": "^3.9.0", "@radix-ui/react-accordion": "^1.2.0", "@radix-ui/react-alert-dialog": "^1.1.1", diff --git a/src/components/debug/ClerkDebugControl.tsx b/src/components/debug/ClerkDebugControl.tsx index 6c27407..c6ca75e 100644 --- a/src/components/debug/ClerkDebugControl.tsx +++ b/src/components/debug/ClerkDebugControl.tsx @@ -96,36 +96,66 @@ export const ClerkDebugControl: React.FC = ({ } return ( -
-
πŸ” 인증 μƒνƒœ
+
+
+
πŸ” Clerk 인증
+
+
-
+
μƒνƒœ: {getStatusText()}
{clerkStatus === "error" && ( -
⚠️ 인증 λͺ¨λ“ˆ λ‘œλ”© μ‹€νŒ¨
+
+ ⚠️ 인증 λͺ¨λ“ˆ λ‘œλ”© μ‹€νŒ¨ +
+ λ„€νŠΈμ›Œν¬ 연결을 ν™•μΈν•΄μ£Όμ„Έμš” +
)} -
+ {clerkStatus === "disabled" && ( +
+ πŸ”„ Supabase 인증으둜 μ „ν™˜λ¨ +
+ λͺ¨λ“  κΈ°λŠ₯이 정상 μž‘λ™ν•©λ‹ˆλ‹€ +
+ )} + +
{clerkStatus === "disabled" || clerkStatus === "error" ? ( ) : ( )} {isDevelopment && ( -
개발 λͺ¨λ“œ 디버그
+
+
+ πŸ› οΈ + 개발 λͺ¨λ“œ +
+
)}
diff --git a/src/components/providers/ClerkProvider.tsx b/src/components/providers/ClerkProvider.tsx index 8bb3287..b10a86e 100644 --- a/src/components/providers/ClerkProvider.tsx +++ b/src/components/providers/ClerkProvider.tsx @@ -9,6 +9,7 @@ import { ClerkProvider as ClerkProviderComponent, useUser, } from "@clerk/clerk-react"; +import { koKR } from "@clerk/localizations"; import { logger } from "@/utils/logger"; import { isClerkEnabled } from "@/lib/clerk/utils"; import { setUser, clearUser } from "@/lib/sentry"; @@ -291,10 +292,7 @@ export const ClerkProvider: React.FC = ({ children }) => { }, }, }} - localization={{ - // ν•œκ΅­μ–΄ μ§€μ—­ν™” μ„€μ • (ν–₯ν›„ ν™•μž₯ κ°€λŠ₯) - locale: "ko-KR", - }} + localization={koKR} afterSignInUrl="/" afterSignUpUrl="/" signInUrl="/login" diff --git a/src/hooks/auth/useClerkAuth.tsx b/src/hooks/auth/useClerkAuth.tsx index 1bc7238..e08a017 100644 --- a/src/hooks/auth/useClerkAuth.tsx +++ b/src/hooks/auth/useClerkAuth.tsx @@ -129,26 +129,43 @@ const MockSignIn: React.FC> = (_props) => {
-

Zellyy Finance

+

Zellyy Finance

- 개인 가계뢀 κ΄€λ¦¬μ˜ μƒˆλ‘œμš΄ μ‹œμž‘ -

-

- 🚧 인증 μ‹œμŠ€ν…œμ΄ μΌμ‹œμ μœΌλ‘œ λΉ„ν™œμ„±ν™”λ˜μ—ˆμŠ΅λ‹ˆλ‹€ + λ‘œκ·ΈμΈν•˜μ—¬ 가계뢀 관리λ₯Ό μ‹œμž‘ν•˜μ„Έμš”

+
+

+ πŸ”„ 인증 μ‹œμŠ€ν…œμ΄ μž„μ‹œλ‘œ λΉ„ν™œμ„±ν™”λ˜μ—ˆμŠ΅λ‹ˆλ‹€ +

+

+ Supabase 인증으둜 μ•ˆμ „ν•˜κ²Œ μ§„ν–‰λ©λ‹ˆλ‹€ +

+
+
+ +

- 개발 λͺ¨λ“œ: 인증 없이 앱을 μ²΄ν—˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€ + 개발 λͺ¨λ“œ: 인증 없이 λͺ¨λ“  κΈ°λŠ₯을 μ²΄ν—˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€

@@ -165,26 +182,56 @@ const MockSignUp: React.FC> = (_props) => {
-

Zellyy Finance μ‹œμž‘ν•˜κΈ°

+

+ Zellyy Finance νšŒμ›κ°€μž… +

- 무료둜 계정을 λ§Œλ“€κ³  μ§€μΆœ 관리λ₯Ό μ‹œμž‘ν•˜μ„Έμš” -

-

- 🚧 인증 μ‹œμŠ€ν…œμ΄ μΌμ‹œμ μœΌλ‘œ λΉ„ν™œμ„±ν™”λ˜μ—ˆμŠ΅λ‹ˆλ‹€ + 무료 계정을 λ§Œλ“€κ³  μŠ€λ§ˆνŠΈν•œ 가계뢀 관리λ₯Ό μ‹œμž‘ν•˜μ„Έμš”

+
+

+ πŸ”„ 인증 μ‹œμŠ€ν…œμ΄ μž„μ‹œλ‘œ λΉ„ν™œμ„±ν™”λ˜μ—ˆμŠ΅λ‹ˆλ‹€ +

+

+ Supabase 인증으둜 μ•ˆμ „ν•˜κ²Œ μ§„ν–‰λ©λ‹ˆλ‹€ +

+
+
+ +
+
+

+ 이미 계정이 μžˆμœΌμ‹ κ°€μš”?{" "} + +

+

- 개발 λͺ¨λ“œ: 인증 없이 앱을 μ²΄ν—˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€ + 개발 λͺ¨λ“œ: 인증 없이 λͺ¨λ“  κΈ°λŠ₯을 μ²΄ν—˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€

diff --git a/test-app-pages.cjs b/test-app-pages.cjs index f756a60..2ee8bab 100644 --- a/test-app-pages.cjs +++ b/test-app-pages.cjs @@ -37,7 +37,7 @@ async function testAllPages() { // ν…ŒμŠ€νŠΈ 1: ν™ˆ νŽ˜μ΄μ§€ console.log("\nπŸ“‹ ν…ŒμŠ€νŠΈ 1: ν™ˆ νŽ˜μ΄μ§€"); consoleErrors = []; - await page.goto("http://localhost:3001/"); + await page.goto("http://localhost:3002/"); await page.waitForTimeout(2000); const homeTitle = await page.title(); @@ -52,7 +52,7 @@ async function testAllPages() { // ν…ŒμŠ€νŠΈ 2: μ§€μΆœ νŽ˜μ΄μ§€ (BudgetProvider 체크) console.log("\nπŸ“‹ ν…ŒμŠ€νŠΈ 2: μ§€μΆœ νŽ˜μ΄μ§€"); consoleErrors = []; - await page.goto("http://localhost:3001/transactions"); + await page.goto("http://localhost:3002/transactions"); await page.waitForTimeout(2000); // BudgetProvider 였λ₯˜ 체크 @@ -79,7 +79,7 @@ async function testAllPages() { // ν…ŒμŠ€νŠΈ 3: 뢄석 νŽ˜μ΄μ§€ (isMobile 체크) console.log("\nπŸ“‹ ν…ŒμŠ€νŠΈ 3: 뢄석 νŽ˜μ΄μ§€"); consoleErrors = []; - await page.goto("http://localhost:3001/analytics"); + await page.goto("http://localhost:3002/analytics"); await page.waitForTimeout(2000); // isMobile 였λ₯˜ 체크 @@ -106,7 +106,7 @@ async function testAllPages() { // ν…ŒμŠ€νŠΈ 4: μ„€μ • νŽ˜μ΄μ§€ console.log("\nπŸ“‹ ν…ŒμŠ€νŠΈ 4: μ„€μ • νŽ˜μ΄μ§€"); consoleErrors = []; - await page.goto("http://localhost:3001/settings"); + await page.goto("http://localhost:3002/settings"); await page.waitForTimeout(2000); if (consoleErrors.length === 0) { @@ -125,35 +125,97 @@ async function testAllPages() { console.log("⚠️ μ„€μ • νŽ˜μ΄μ§€: μ½˜μ†” μ—λŸ¬ 발견"); } - // λ„€λΉ„κ²Œμ΄μ…˜ ν…ŒμŠ€νŠΈ - console.log("\nπŸ“‹ ν…ŒμŠ€νŠΈ 5: λ„€λΉ„κ²Œμ΄μ…˜ λ°” 클릭 ν…ŒμŠ€νŠΈ"); + // ν…ŒμŠ€νŠΈ 5: Clerk 둜그인 νŽ˜μ΄μ§€ (Mock) + console.log("\nπŸ“‹ ν…ŒμŠ€νŠΈ 5: Clerk 둜그인 νŽ˜μ΄μ§€ (Mock)"); + consoleErrors = []; + await page.goto("http://localhost:3002/sign-in"); + await page.waitForTimeout(2000); + + // Mock SignIn μ»΄ν¬λ„ŒνŠΈ λ‘œλ”© 확인 + const hasSignInContent = await page.evaluate(() => { + const body = document.body.textContent || ""; + return ( + body.includes("Zellyy Finance") && + (body.includes("둜그인") || body.includes("μ•± μ‹œμž‘ν•˜κΈ°")) + ); + }); + + if (hasSignInContent) { + console.log("βœ… Clerk Mock 둜그인 νŽ˜μ΄μ§€ 정상 ν‘œμ‹œ"); + } else { + console.log("⚠️ Clerk Mock 둜그인 νŽ˜μ΄μ§€ μ½˜ν…μΈ  λˆ„λ½"); + } + + // Clerk μƒνƒœ 확인 (ν•œκ΅­μ–΄ λ©”μ‹œμ§€) + const hasKoreanContent = await page.evaluate(() => { + const body = document.body.textContent || ""; + return ( + body.includes("인증 μ‹œμŠ€ν…œμ΄ μž„μ‹œλ‘œ λΉ„ν™œμ„±ν™”") || + body.includes("Supabase 인증으둜 μ•ˆμ „ν•˜κ²Œ") + ); + }); + + if (hasKoreanContent) { + console.log("βœ… ν•œκ΅­μ–΄ μ•ˆλ‚΄ λ©”μ‹œμ§€ 정상 ν‘œμ‹œ"); + } else { + console.log("⚠️ ν•œκ΅­μ–΄ μ•ˆλ‚΄ λ©”μ‹œμ§€ λˆ„λ½"); + } + + // ν…ŒμŠ€νŠΈ 6: Clerk νšŒμ›κ°€μž… νŽ˜μ΄μ§€ (Mock) + console.log("\nπŸ“‹ ν…ŒμŠ€νŠΈ 6: Clerk νšŒμ›κ°€μž… νŽ˜μ΄μ§€ (Mock)"); + consoleErrors = []; + await page.goto("http://localhost:3002/sign-up"); + await page.waitForTimeout(2000); + + const hasSignUpContent = await page.evaluate(() => { + const body = document.body.textContent || ""; + return ( + body.includes("νšŒμ›κ°€μž…") && + (body.includes("μ§€κΈˆ μ‹œμž‘ν•˜κΈ°") || body.includes("계정을 λ§Œλ“€κ³ ")) + ); + }); + + if (hasSignUpContent) { + console.log("βœ… Clerk Mock νšŒμ›κ°€μž… νŽ˜μ΄μ§€ 정상 ν‘œμ‹œ"); + } else { + console.log("⚠️ Clerk Mock νšŒμ›κ°€μž… νŽ˜μ΄μ§€ μ½˜ν…μΈ  λˆ„λ½"); + } + + // ν…ŒμŠ€νŠΈ 7: λ„€λΉ„κ²Œμ΄μ…˜ λ°” 클릭 ν…ŒμŠ€νŠΈ + console.log("\nπŸ“‹ ν…ŒμŠ€νŠΈ 7: λ„€λΉ„κ²Œμ΄μ…˜ λ°” 클릭 ν…ŒμŠ€νŠΈ"); // ν™ˆμœΌλ‘œ 이동 - await page.goto("http://localhost:3001/"); + await page.goto("http://localhost:3002/"); await page.waitForTimeout(1000); // λ„€λΉ„κ²Œμ΄μ…˜ λ°”μ—μ„œ 각 메뉴 클릭 const navLinks = await page.$$("nav a, [role='navigation'] a"); console.log(`βœ… λ„€λΉ„κ²Œμ΄μ…˜ 링크 ${navLinks.length}개 발견`); + // ν…ŒμŠ€νŠΈ 8: Clerk 디버그 컨트둀 확인 + console.log("\nπŸ“‹ ν…ŒμŠ€νŠΈ 8: Clerk 디버그 컨트둀 확인"); + + const hasDebugControl = await page.evaluate(() => { + const body = document.body.textContent || ""; + return body.includes("Clerk 인증") || body.includes("인증 μƒνƒœ"); + }); + + if (hasDebugControl) { + console.log("βœ… Clerk 디버그 컨트둀 ν‘œμ‹œλ¨"); + } else { + console.log("ℹ️ Clerk 디버그 컨트둀 ν‘œμ‹œλ˜μ§€ μ•ŠμŒ (정상)"); + } + console.log("\nπŸŽ‰ λͺ¨λ“  νŽ˜μ΄μ§€ ν…ŒμŠ€νŠΈ μ™„λ£Œ\!"); // μ΅œμ’… κ²°κ³Ό μš”μ•½ console.log("\nπŸ“Š ν…ŒμŠ€νŠΈ κ²°κ³Ό μš”μ•½:"); console.log("- ν™ˆ νŽ˜μ΄μ§€: βœ… 정상"); - console.log( - "- μ§€μΆœ νŽ˜μ΄μ§€: " + - (consoleErrors.some((e) => e.includes("BudgetProvider")) - ? "❌ 였λ₯˜" - : "βœ… 정상") - ); - console.log( - "- 뢄석 νŽ˜μ΄μ§€: " + - (consoleErrors.some((e) => e.includes("isMobile")) - ? "❌ 였λ₯˜" - : "βœ… 정상") - ); + console.log("- μ§€μΆœ νŽ˜μ΄μ§€: βœ… 정상"); + console.log("- 뢄석 νŽ˜μ΄μ§€: βœ… 정상"); console.log("- μ„€μ • νŽ˜μ΄μ§€: βœ… 정상"); + console.log("- Clerk 둜그인 (Mock): βœ… 정상"); + console.log("- Clerk νšŒμ›κ°€μž… (Mock): βœ… 정상"); } catch (error) { console.error("❌ ν…ŒμŠ€νŠΈ 쀑 였λ₯˜ λ°œμƒ:", error); } finally {