Skip to content

Commit 48bed78

Browse files
committed
refactor : app 디렉토리 구조에서 page 디렉토리 구조로 변경
1 parent 2f85c74 commit 48bed78

15 files changed

+777
-15
lines changed

next.config.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
/** @type {import('next').NextConfig} */
33
const nextConfig = {
44
experimental: {
5-
instrumentationHooks: true,
6-
serverActions: true,
5+
appDir: false,
6+
pageExtensions: ['page.tsx', 'page.ts', 'api.tsx', 'api.ts'],
77
},
88
images: {
99
remotePatterns: [

panda.config.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export default defineConfig({
99
preflight: true,
1010
jsxFramework: 'react',
1111
// Where to look for your css declarations
12-
include: ['./src/**/*.{js,jsx,ts,tsx}', './src/app/**/*.{ts,tsx,js,jsx}', './stories/**/*.{js,jsx,ts,tsx}'],
12+
include: ['./src/**/*.{js,jsx,ts,tsx}', './src/pages/**/*.{ts,tsx,js,jsx}', './stories/**/*.{js,jsx,ts,tsx}'],
1313

1414
// Files to exclude
1515
exclude: [],

src/components/SEO/SEO.tsx

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import Head from 'next/head';
2+
3+
interface Props {
4+
title?: string;
5+
description?: string;
6+
ogImage?: string;
7+
keywords?: string;
8+
}
9+
10+
const BASE_URL = 'https://10mm.today';
11+
const DEFAULT_OG_IMAGE = 'https://www.10mm.today/og-image.png';
12+
13+
/**
14+
* @description next/head를 사용하는 SEO 컴포넌트입니다. title, og, twitter 등 SEO에 필요한 태그를 렌더링 합니다.
15+
*/
16+
const SEO = ({ title, description, ogImage, keywords }: Props) => {
17+
const TITLE = title || '10MM';
18+
const DESCRIPTION = description || '10MM';
19+
20+
const IMAGE = ogImage || DEFAULT_OG_IMAGE;
21+
22+
return (
23+
<Head>
24+
<title>{TITLE}</title>
25+
<link rel="canonical" href={BASE_URL} />
26+
<meta name="description" content={DESCRIPTION} />
27+
<meta name="keywords" content={keywords} />
28+
29+
<meta property="og:title" content={TITLE} />
30+
<meta property="og:description" content={DESCRIPTION} />
31+
<meta property="og:image" content={IMAGE} />
32+
<meta property="og:url" content={BASE_URL} />
33+
34+
<meta name="twitter:title" content={TITLE} />
35+
<meta name="twitter:description" content={DESCRIPTION} />
36+
<meta name="twitter:image" content={IMAGE} />
37+
</Head>
38+
);
39+
};
40+
41+
export default SEO;

src/components/TempleteComponent.tsx

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { useAuth } from '@/hooks/useAuth';
2+
import useForegroundNotification from '@/hooks/useForegroundNotification';
3+
4+
function TemplateComponent({ children }: { children: React.ReactNode }) {
5+
useAuth();
6+
useForegroundNotification();
7+
return children;
8+
}
9+
10+
export default TemplateComponent;

src/instrumentation.ts

-12
This file was deleted.

src/pages/_app.tsx

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { Suspense } from 'react';
2+
import type { AppProps } from 'next/app';
3+
import MonitoringInitializer from '@/components/MonitoringInitializer';
4+
import NotificationSnackBarProvider from '@/components/NotificationSnackBar/NotificationSnackBarProvider';
5+
import SnackBarProvider from '@/components/SnackBar/SnackBarProvider';
6+
import TemplateComponent from '@/components/TempleteComponent';
7+
import { QueryProvider } from '@/hooks/query';
8+
import { useAuth } from '@/hooks/useAuth';
9+
import { MSWInitComponent } from '@/msw';
10+
import { css } from '@styled-system/css';
11+
12+
import './globals.css';
13+
14+
export default function App({ Component, pageProps }: AppProps) {
15+
useAuth();
16+
return (
17+
<>
18+
<MonitoringInitializer />
19+
<MSWInitComponent />
20+
<QueryProvider>
21+
<NotificationSnackBarProvider>
22+
<SnackBarProvider>
23+
<Suspense>
24+
<TemplateComponent>
25+
<div className={css(containerCss)}>
26+
<Component {...pageProps} />
27+
</div>
28+
</TemplateComponent>
29+
</Suspense>
30+
</SnackBarProvider>
31+
</NotificationSnackBarProvider>
32+
</QueryProvider>
33+
</>
34+
);
35+
}
36+
37+
const containerCss = {
38+
maxWidth: 'maxWidth',
39+
margin: '0 auto',
40+
minHeight: '100vh',
41+
backgroundColor: 'bg.surface2',
42+
};

src/pages/_document.tsx

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { Head, Html, Main, NextScript } from 'next/document';
2+
import SEO from '@/components/SEO/SEO';
3+
4+
export const metadata = {
5+
title: '10MM',
6+
description: '10MM',
7+
keywords: '10mm, 10분만, 10분, 10MM, 10mm, 하루 10분, 10분 단위, 생환습관',
8+
openGraph: {
9+
type: 'website',
10+
url: 'https://www.10mm.today',
11+
title: '10MM',
12+
description: '당신의 인생을 바꿀 10분',
13+
siteName: '10MM',
14+
images: [
15+
{
16+
url: 'https://www.10mm.today/og-image.png',
17+
},
18+
],
19+
},
20+
viewport: 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0',
21+
};
22+
23+
export default function _document() {
24+
return (
25+
<Html lang="ko" suppressHydrationWarning>
26+
<Head>
27+
<link
28+
rel="preload"
29+
as="style"
30+
crossOrigin=""
31+
href="https://cdn.jsdelivr.net/gh/orioncactus/[email protected]/dist/web/static/pretendard-dynamic-subset.min.css"
32+
/>
33+
<SEO {...metadata} />
34+
</Head>
35+
<body>
36+
<Main />
37+
<NextScript />
38+
</body>
39+
</Html>
40+
);
41+
}
+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { useEffect } from 'react';
2+
import { useRouter, useSearchParams } from 'next/navigation';
3+
import { useSocialLogin } from '@/apis/auth';
4+
import Loading from '@/components/Loading';
5+
import { AUTH_PROVIDER } from '@/constants/common';
6+
import { ROUTER } from '@/constants/router';
7+
import { eventLogger } from '@/utils';
8+
9+
export default function KakaoCallbackPage() {
10+
const router = useRouter();
11+
const params = useSearchParams();
12+
const { mutateAsync } = useSocialLogin();
13+
14+
useEffect(() => {
15+
(async () => {
16+
const code = params.get('code');
17+
await fetch('https://kauth.kakao.com/oauth/token', {
18+
method: 'POST',
19+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
20+
body: `grant_type=authorization_code&client_id=ada9b0c9e6fe56fcea00ebe8eccc2e20&redirect_uri=${process.env.NEXT_PUBLIC_KAKAO_LOGIN_REDIRECT_URI}&code=${code}&client_secret=29kEX8301Z514wfSmUFNENNKKjxCVGvB`,
21+
}).then((res) => {
22+
res.json().then((data) => {
23+
mutateAsync(
24+
{
25+
provider: AUTH_PROVIDER.KAKAO,
26+
idToken: data.id_token,
27+
},
28+
{
29+
onSuccess: (successData) => {
30+
if (successData?.memberId) {
31+
eventLogger.identify(successData.memberId.toString());
32+
}
33+
34+
router.push(params.get('state') ?? ROUTER.HOME);
35+
},
36+
},
37+
);
38+
});
39+
});
40+
})();
41+
}, []);
42+
43+
return (
44+
<main>
45+
<Loading />
46+
</main>
47+
);
48+
}

0 commit comments

Comments
 (0)