diff --git a/src/app/auth/callback/page.tsx b/src/app/auth/callback/page.tsx
index 5eb3675..0a2f8af 100644
--- a/src/app/auth/callback/page.tsx
+++ b/src/app/auth/callback/page.tsx
@@ -1,35 +1,51 @@
'use client';
import { useEffect } from 'react';
-import { useRouter } from 'next/navigation';
+import { useRouter, useSearchParams } from 'next/navigation';
import { supabase } from '@/lib/supabase';
+import { Suspense } from 'react';
-export default function AuthCallback() {
+function AuthCallbackInner() {
const router = useRouter();
+ const searchParams = useSearchParams();
useEffect(() => {
+ // 카카오 로그인 취소 시 error=access_denied 쿼리가 붙어서 돌아옴
+ const errorParam = searchParams.get('error');
+ if (errorParam) {
+ router.replace('/');
+ return;
+ }
+
const handleAuth = async () => {
- // 1. URL에 포함된 토큰을 이용해 세션을 가져옵니다.
- // 이 과정에서 Supabase 라이브러리가 브라우저 쿠키/로컬스토리지에 로그인 정보를 저장합니다.
const { data, error } = await supabase.auth.getSession();
if (data.session) {
- // 2. 로그인이 확인되면 메인 페이지('/')로 이동시킵니다.
- // router.replace를 쓰면 주소창이 깔끔하게 '/'로 바뀌고 뒤로가기가 방지됩니다.
router.replace('/');
} else if (error) {
console.error('로그인 처리 중 오류:', error.message);
router.replace('/');
+ } else {
+ // session도 error도 없으면 (ex. 직접 URL 접근) 홈으로
+ router.replace('/');
}
};
handleAuth();
- }, [router]);
+ }, [router, searchParams]);
return (
-
카카오로그인 중...
+
카카오 로그인 중...
);
}
+
+export default function AuthCallback() {
+ return (
+
+
+
+ );
+}
diff --git a/src/app/page.tsx b/src/app/page.tsx
index acd9a57..b9536f4 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -13,8 +13,8 @@ export default async function Home() {
{/* 헤더 */}
- {/* 지도 */}
-
+ {/* 지도 — contain-layout으로 내부 레이아웃이 외부에 영향주지 않도록 격리 */}
+
diff --git a/src/app/sitemap.ts b/src/app/sitemap.ts
index 3d92a83..3fb8ae4 100644
--- a/src/app/sitemap.ts
+++ b/src/app/sitemap.ts
@@ -1,28 +1,42 @@
import { MetadataRoute } from 'next';
+import { supabase } from '@/lib/supabase';
export default async function sitemap(): Promise {
const baseUrl = 'https://gachamap.vercel.app';
- const routes: MetadataRoute.Sitemap = [
+ const staticRoutes: MetadataRoute.Sitemap = [
{
url: baseUrl,
- lastModified: new Date(),
+ lastModified: new Date('2025-01-01'),
changeFrequency: 'daily',
priority: 1,
},
{
url: `${baseUrl}/gacha-board`,
- lastModified: new Date(),
+ lastModified: new Date('2025-01-01'),
changeFrequency: 'daily',
priority: 0.9,
},
{
url: `${baseUrl}/about`,
- lastModified: new Date(),
+ lastModified: new Date('2025-01-01'),
changeFrequency: 'monthly',
priority: 0.5,
},
];
- return routes;
+ // 가챠보드 게시글 동적 포함
+ const { data: posts } = await supabase
+ .from('gacha_posts')
+ .select('id, created_at')
+ .order('created_at', { ascending: false });
+
+ const postRoutes: MetadataRoute.Sitemap = (posts ?? []).map((post) => ({
+ url: `${baseUrl}/gacha-board/${post.id}`,
+ lastModified: new Date(post.created_at),
+ changeFrequency: 'weekly' as const,
+ priority: 0.7,
+ }));
+
+ return [...staticRoutes, ...postRoutes];
}
diff --git a/src/components/Map.tsx b/src/components/Map.tsx
index d302202..1db3695 100644
--- a/src/components/Map.tsx
+++ b/src/components/Map.tsx
@@ -230,38 +230,36 @@ export default function KakaoMap({ shops }: MapProps) {
setIsSuggestionModalOpen(true);
};
- if (!isMapLoaded) {
- return (
-
-
-
-
지도를 불러오는 중...
-
-
- );
- }
-
return (
+ {/* 지도 로딩 오버레이 — 컨테이너 크기는 항상 유지해 CLS 방지 */}
+ {!isMapLoaded && (
+
+
+
+
지도를 불러오는 중...
+
+
+ )}
{/* 카테고리 필터 */}