diff --git a/public/assets/login/white-cheese-logo.svg b/public/assets/login/white-cheese-logo.svg
new file mode 100644
index 00000000..8f034014
--- /dev/null
+++ b/public/assets/login/white-cheese-logo.svg
@@ -0,0 +1,6 @@
+
diff --git a/public/assets/rending/new-swipe/1.png b/public/assets/rending/new-swipe/1.png
new file mode 100644
index 00000000..87167640
Binary files /dev/null and b/public/assets/rending/new-swipe/1.png differ
diff --git a/public/assets/rending/new-swipe/2.png b/public/assets/rending/new-swipe/2.png
new file mode 100644
index 00000000..b9a0cd06
Binary files /dev/null and b/public/assets/rending/new-swipe/2.png differ
diff --git a/public/assets/rending/new-swipe/3.png b/public/assets/rending/new-swipe/3.png
new file mode 100644
index 00000000..e285614e
Binary files /dev/null and b/public/assets/rending/new-swipe/3.png differ
diff --git a/public/assets/rending/new-swipe/4.png b/public/assets/rending/new-swipe/4.png
new file mode 100644
index 00000000..373587a9
Binary files /dev/null and b/public/assets/rending/new-swipe/4.png differ
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index 88afdd4b..4bfa0971 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -36,6 +36,13 @@ export const metadata: Metadata = {
},
};
+export const viewport = {
+ width: 'device-width',
+ initialScale: 1,
+ maximumScale: 1,
+ userScalable: false,
+};
+
export default function RootLayout({
children,
}: Readonly<{
diff --git a/src/app/page.tsx b/src/app/page.tsx
index 33cd9e1a..3457b604 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -1,5 +1,5 @@
-import ScreenRoot from '@/feature/root/components/ScreenRoot';
+import ScreenNewRoot from '@/feature/root/components/ScreenNewRoot';
export default function Page() {
- return ;
+ return ;
}
diff --git a/src/feature/root/components/FlashRending.tsx b/src/feature/root/components/FlashRending.tsx
new file mode 100644
index 00000000..896b44a3
--- /dev/null
+++ b/src/feature/root/components/FlashRending.tsx
@@ -0,0 +1,17 @@
+import Image from 'next/image';
+
+const FlashRending = () => {
+ return (
+
+
+
+ );
+};
+
+export default FlashRending;
diff --git a/src/feature/root/components/RendingBody.tsx b/src/feature/root/components/RendingBody.tsx
new file mode 100644
index 00000000..5841304e
--- /dev/null
+++ b/src/feature/root/components/RendingBody.tsx
@@ -0,0 +1,153 @@
+'use client';
+
+import {
+ Carousel,
+ CarouselContent,
+ CarouselItem,
+ type CarouselApi,
+} from '@/components/ui/carousel';
+import { buildQuery } from '@/global/utils/buildQuery';
+import Image from 'next/image';
+import { useSearchParams } from 'next/navigation';
+import { useEffect, useState } from 'react';
+
+const KAKAO_AUTH_URL = `https://dev.say-cheese.me/oauth2/authorization/kakao`;
+
+export const RendingBody = () => {
+ const [api, setApi] = useState();
+ const [current, setCurrent] = useState(0);
+ const searchParams = useSearchParams();
+ const redirect = searchParams.get('redirect');
+
+ const slides = [
+ {
+ src: '/assets/rending/new-swipe/1.png',
+ alt: '앨범 목록 화면',
+ width: 260,
+ height: 530,
+ title: '이벤트마다 만드는 공유앨범',
+ description: '감튀 모임부터 찐친 여행까지',
+ },
+ {
+ src: '/assets/rending/new-swipe/2.png',
+ alt: 'QR 코드 공유',
+ width: 260,
+ height: 530,
+ title: '이벤트마다 모인 자리에서 바로 공유',
+ description: '감튀 모임부터 앨범 만들고 초대까지 딱 10초',
+ },
+ {
+ src: '/assets/rending/new-swipe/3.png',
+ alt: '베스트컷',
+ width: 312.5,
+ height: 530.3,
+ title: '이벤트마다 한눈에 보는 베스트컷',
+ description: '사진 고르는 고민 이제 끝',
+ },
+ {
+ src: '/assets/rending/new-swipe/4.png',
+ alt: '네컷추억',
+ width: 289,
+ height: 530,
+ title: '딱 네컷으로 남는 추억',
+ description: '앨범이 닫히면 사라지는 원본 사진들',
+ },
+ ];
+
+ // 캐러셀 API를 통해 현재 슬라이드 추적
+ useEffect(() => {
+ if (!api) return;
+
+ api.on('select', () => {
+ setCurrent(api.selectedScrollSnap());
+ });
+ }, [api]);
+
+ const handleKakaoLogin = async () => {
+ try {
+ const kakaoUrl = redirect
+ ? `${KAKAO_AUTH_URL}${buildQuery({ redirect })}`
+ : KAKAO_AUTH_URL;
+
+ window.location.href = kakaoUrl;
+ } catch (err) {
+ console.error('카카오 인증 GET 요청 실패:', err);
+ }
+ };
+
+ return (
+
+ {/* 캐러셀 영역 */}
+
+
+
+ {slides.map((slide, index) => (
+
+
+
+
+
+ ))}
+
+
+
+
+ {/* 하단 흰색 배경 영역 - 이미지 위에 오버레이 */}
+
+ {/* 텍스트 영역 */}
+
+
+ {slides[current].title}
+
+
+ {slides[current].description}
+
+
+
+ {/* 인디케이터 점들 */}
+
+ {slides.map((_, index) => (
+
+
+ {/* 카카오 로그인 버튼 */}
+
+
+
+ 카카오 로그인
+
+
+
+
+ );
+};
diff --git a/src/feature/root/components/ScreenNewRoot.tsx b/src/feature/root/components/ScreenNewRoot.tsx
new file mode 100644
index 00000000..a8d9b308
--- /dev/null
+++ b/src/feature/root/components/ScreenNewRoot.tsx
@@ -0,0 +1,37 @@
+'use client';
+
+import { useCheckAuth } from '@/global/hooks/useCheckAuth';
+import { useEffect, useState } from 'react';
+import FlashRending from './FlashRending';
+import { RendingBody } from './RendingBody';
+
+const ScreenNewRoot = () => {
+ const { isAuthed } = useCheckAuth();
+ const [showSplash, setShowSplash] = useState(true);
+
+ console.log('ScreenNewRoot - isAuthed:', isAuthed, 'showSplash:', showSplash);
+
+ // 비로그인 상태일 때만 2초 후 스플래시 숨김
+ useEffect(() => {
+ if (isAuthed === false) {
+ const timer = setTimeout(() => {
+ setShowSplash(false);
+ }, 2000);
+ return () => clearTimeout(timer);
+ }
+ }, [isAuthed]);
+
+ // 인증 확인 중이거나 비로그인 상태에서 스플래시 표시 중일 때
+ if (isAuthed === null || (isAuthed === false && showSplash)) {
+ return ;
+ }
+
+ // 로그인 상태이거나 스플래시 시간이 지난 비로그인 사용자
+ return (
+
+
+
+ );
+};
+
+export default ScreenNewRoot;
diff --git a/src/feature/root/components/ScreenRoot.tsx b/src/feature/root/components/ScreenRoot.tsx
deleted file mode 100644
index 6a653ac8..00000000
--- a/src/feature/root/components/ScreenRoot.tsx
+++ /dev/null
@@ -1,147 +0,0 @@
-'use client';
-import LogoHeader from '@/global/components/header/LogoHeader';
-import LongButton from '@/global/components/LongButton';
-import { GA_EVENTS } from '@/global/constants/gaEvents';
-import { useCheckAuth } from '@/global/hooks/useCheckAuth';
-import { trackGaEvent } from '@/global/utils/trackGaEvent';
-import dynamic from 'next/dynamic';
-import Image from 'next/image';
-import { useRouter } from 'next/navigation';
-import { useCallback, useEffect, useState } from 'react';
-import SelectMenu from './SelectMenu';
-
-const RendingFooter = dynamic(() => import('./RendingFooter'), { ssr: false });
-const SelectedList = dynamic(() => import('./SelectedList'), { ssr: false });
-const SwipeList = dynamic(() => import('./SwipeList'), { ssr: false });
-
-export default function ScreenRoot() {
- const router = useRouter();
- const [selectedMenu, setSelectedMenu] = useState<
- 'first' | 'second' | 'third'
- >('first');
- const handleCreateAlbumClick = useCallback(() => {
- if (typeof document !== 'undefined') {
- document.cookie = 'entry=create-album; path=/;';
- }
-
- trackGaEvent(GA_EVENTS.click_login, { entry_source: 'landing_header' });
- router.push('/login');
- }, [router]);
-
- useCheckAuth({ onAuthed: () => router.push('/main') });
-
- useEffect(() => {
- trackGaEvent(GA_EVENTS.view_landing);
- }, []);
-
- return (
-
-
-
- 딱 7일만 열리는 특별한
- 공유 앨범 서비스
-
-
-
-
-
-
-
-
- 92개 모임에서 치이이즈를 사용했어요
-
-
-
-
-
-
-
-
- 일정의 마무리,
-
- 사진 주고받기도 가볍고 귀엽게
-
-
- 추억을 더 소중하게 만드는
- 치이이즈의 세 가지 방법
-
-
-
-
-
-
-
-
- 서비스에 그대로 담긴
- 사진 찍고 나눌 때의 감정
-
-
-
- 추억할 일이 있는 모든 곳에서
- 모두 함께 치이이즈
-
-
-
-
- );
-}
diff --git a/src/feature/root/components/RendingFooter.tsx b/src/feature/root/components/_previousRoot/RendingFooter.tsx
similarity index 100%
rename from src/feature/root/components/RendingFooter.tsx
rename to src/feature/root/components/_previousRoot/RendingFooter.tsx
diff --git a/src/feature/root/components/_previousRoot/ScreenRoot.tsx b/src/feature/root/components/_previousRoot/ScreenRoot.tsx
new file mode 100644
index 00000000..42b6e2b4
--- /dev/null
+++ b/src/feature/root/components/_previousRoot/ScreenRoot.tsx
@@ -0,0 +1,147 @@
+// 'use client';
+// import LogoHeader from '@/global/components/header/LogoHeader';
+// import LongButton from '@/global/components/LongButton';
+// import { GA_EVENTS } from '@/global/constants/gaEvents';
+// import { useCheckAuth } from '@/global/hooks/useCheckAuth';
+// import { trackGaEvent } from '@/global/utils/trackGaEvent';
+// import dynamic from 'next/dynamic';
+// import Image from 'next/image';
+// import { useRouter } from 'next/navigation';
+// import { useCallback, useEffect, useState } from 'react';
+// import SelectMenu from './SelectMenu';
+
+// const RendingFooter = dynamic(() => import('./RendingFooter'), { ssr: false });
+// const SelectedList = dynamic(() => import('./SelectedList'), { ssr: false });
+// const SwipeList = dynamic(() => import('./SwipeList'), { ssr: false });
+
+// export default function ScreenRoot() {
+// const router = useRouter();
+// const [selectedMenu, setSelectedMenu] = useState<
+// 'first' | 'second' | 'third'
+// >('first');
+// const handleCreateAlbumClick = useCallback(() => {
+// if (typeof document !== 'undefined') {
+// document.cookie = 'entry=create-album; path=/;';
+// }
+
+// trackGaEvent(GA_EVENTS.click_login, { entry_source: 'landing_header' });
+// router.push('/login');
+// }, [router]);
+
+// useCheckAuth({ onAuthed: () => router.push('/main') });
+
+// useEffect(() => {
+// trackGaEvent(GA_EVENTS.view_landing);
+// }, []);
+
+// return (
+//
+//
+//
+// 딱 7일만 열리는 특별한
+// 공유 앨범 서비스
+//
+
+//
+//
+//
+//
+
+//
+// 92개 모임에서 치이이즈를 사용했어요
+//
+//
+
+//
+//
+//
+//
+//
+// 일정의 마무리,
+//
+// 사진 주고받기도 가볍고 귀엽게
+//
+//
+// 추억을 더 소중하게 만드는
+// 치이이즈의 세 가지 방법
+//
+//
+//
+//
+//
+//
+//
+//
+// 서비스에 그대로 담긴
+// 사진 찍고 나눌 때의 감정
+//
+//
+//
+// 추억할 일이 있는 모든 곳에서
+// 모두 함께 치이이즈
+//
+//
+//
+//
+// );
+// }
diff --git a/src/feature/root/components/SelectMenu.tsx b/src/feature/root/components/_previousRoot/SelectMenu.tsx
similarity index 100%
rename from src/feature/root/components/SelectMenu.tsx
rename to src/feature/root/components/_previousRoot/SelectMenu.tsx
diff --git a/src/feature/root/components/SelectedList.tsx b/src/feature/root/components/_previousRoot/SelectedList.tsx
similarity index 100%
rename from src/feature/root/components/SelectedList.tsx
rename to src/feature/root/components/_previousRoot/SelectedList.tsx
diff --git a/src/feature/root/components/SwipeList.tsx b/src/feature/root/components/_previousRoot/SwipeList.tsx
similarity index 100%
rename from src/feature/root/components/SwipeList.tsx
rename to src/feature/root/components/_previousRoot/SwipeList.tsx
diff --git a/src/global/hooks/useCheckAuth.ts b/src/global/hooks/useCheckAuth.ts
index 4c4b1541..546006b4 100644
--- a/src/global/hooks/useCheckAuth.ts
+++ b/src/global/hooks/useCheckAuth.ts
@@ -47,11 +47,18 @@ export function useCheckAuth({
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
+ console.log('err 타입', err);
if (cancelled) return;
const status = err?.response?.status;
+ const code = err?.code;
- if (status === 401) {
+ // 401 에러 또는 refresh token 없음 에러 처리
+ if (
+ status === 401 ||
+ code === 401 ||
+ err?.message?.includes('No refresh token')
+ ) {
setIsAuthed(false);
setUserId(null);
onUnauthed?.();