Skip to content

Commit

Permalink
Merge pull request #58 from biud436:app-router
Browse files Browse the repository at this point in the history
feat: App Router 적용
  • Loading branch information
biud436 authored Nov 20, 2023
2 parents 27d2c1c + 3d64439 commit 2e4f775
Show file tree
Hide file tree
Showing 73 changed files with 551 additions and 528 deletions.
148 changes: 59 additions & 89 deletions .pnp.cjs

Large diffs are not rendered by default.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
13 changes: 4 additions & 9 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,10 @@ const withMDX = require('@next/mdx')({

/** @type {import('next').NextConfig} */
const nextConfig = withMDX({
reactStrictMode: true,
// reactStrictMode: true,
swcMinify: true,
async redirects() {
return [
{
source: '/login',
destination: '/',
permanent: true,
},
{
source: '/edit',
destination: '/',
Expand All @@ -42,9 +37,9 @@ const nextConfig = withMDX({
},
];
},
publicRuntimeConfig: {
backendUrl: process.env.NEXT_PUBLIC_SERVER_URL,
},
// publicRuntimeConfig: {
// backendUrl: process.env.NEXT_PUBLIC_SERVER_URL,
// },
crossOrigin: 'anonymous',
output: 'standalone',
pageExtensions: ['js', 'jsx', 'ts', 'tsx', 'md', 'mdx'],
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,14 @@
"react-router": "^6.3.0",
"react-router-dom": "^6.3.0",
"react-syntax-highlighter": "^15.5.0",
"react-toastify": "^8.2.0",
"react-toastify": "^9.1.3",
"react-toc": "^3.1.0",
"react-use": "^17.3.2",
"recoil": "^0.7.7",
"rimraf": "3.0.2",
"sass": "^1.56.0",
"serve": "13.0.2",
"styled-components": "^5.3.5",
"styled-components": "^6.1.1",
"stylelint": "14.2.0",
"stylelint-config-recommended": "6.0.0",
"stylelint-config-styled-components": "0.1.1",
Expand Down
File renamed without changes.
8 changes: 5 additions & 3 deletions src/pages/edit/index.tsx → src/app/edit2/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
'use client';

import React from 'react';
import { PostEditorContainer } from '@/containers/PostEditorContainer';
import { useRouter } from 'next/router';
import { useSearchParams } from 'next/navigation';

export default function Editor() {
const router = useRouter();
const { mode } = router.query;
const searchParams = useSearchParams();
const mode = searchParams?.get('mode');

return <PostEditorContainer editorMode={mode as string} />;
}
3 changes: 3 additions & 0 deletions src/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
50 changes: 50 additions & 0 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
'use client';

import React from 'react';
// import type { Metadata } from 'next';
import StyledJsxRegistry from '../lib/registry';
import { RecoilRoot, RecoilEnv } from 'recoil';
// These styles apply to every route in the application
import './globals.css';
import { Noto_Sans_KR } from 'next/font/google';
import { GlobalStyle } from '@/styles/global-styles';
import { CssBaseline, ThemeProvider } from '@mui/material';
import { RootProvider } from '@/blog/components/common/RootProvider';
import { ToastContainer } from 'react-toastify';
import { rootStore } from '@/store';

// export const metadata: Metadata = {
// title: 'Create Next App',
// description: 'Generated by create next app',
// };

const notoSansKR = Noto_Sans_KR({
weight: '100',
display: 'swap',
subsets: ['latin'],
});

RecoilEnv.RECOIL_DUPLICATE_ATOM_KEY_CHECKING_ENABLED = false;

export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en" className={notoSansKR.className}>
<body>
<StyledJsxRegistry>
<RecoilRoot>
<ThemeProvider theme={rootStore.themeStore.main}>
<CssBaseline />
<GlobalStyle />
<RootProvider>{children}</RootProvider>
</ThemeProvider>
<ToastContainer />
</RecoilRoot>
</StyledJsxRegistry>
</body>
</html>
);
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
'use client';

import React from 'react';
import { CategoryTreeEditorContainer } from '@/blog/components/manage/category/CategoryTreeEditorContainer';
import { ManageLayout } from '@/layouts/ManageLayout';
Expand Down
2 changes: 2 additions & 0 deletions src/pages/manage/index.tsx → src/app/manage/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
'use client';

import React from 'react';
import { ManagePresent } from '@/blog/components/manage/ManagePresent';
import { ManageLayout } from '@/layouts/ManageLayout';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
'use client';

import React, { useEffect, useRef } from 'react';
import {
Box,
Expand All @@ -16,12 +18,11 @@ import {
} from '@mui/material';
import { observer } from 'mobx-react-lite';
import { ManageLayout } from '@/layouts/ManageLayout';
import { useRouter } from 'next/router';
import { useAdminPost } from '@/hooks/api/useAdminPost';
import MyBlogError from '@/pages/_error';
import { postsStore } from '@/store';
import { SelectInputProps } from '@mui/material/Select/SelectInput';
import Swal from 'sweetalert2';
import { notFound, useRouter } from 'next/navigation';

const theme = createTheme({
palette: {},
Expand Down Expand Up @@ -75,7 +76,7 @@ const ManagePost = observer(() => {
}, []);

if (error) {
return <MyBlogError />;
return notFound();
}

return (
Expand Down
4 changes: 3 additions & 1 deletion src/pages/404.tsx → src/app/not-found.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
'use client';

import React from 'react';
import { NotFoundPage } from '@/containers/NotFoundPage';

export default function MyBlogError() {
export default function NotFound() {
return <NotFoundPage />;
}
5 changes: 5 additions & 0 deletions src/pages/index.tsx → src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import React from 'react';
import { PostsPage } from '@/blog/pages/posts';

export const metadata = {
title: '어진석의 블로그',
description: '블로그',
};

export default function MyMain() {
return <PostsPage />;
}
17 changes: 17 additions & 0 deletions src/app/posts/[id]/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use client';

import React from 'react';
import { MainLayout } from '@/layouts/BlogMainLayout';
import { PostServiceProvider } from '@/services/PostService';

interface PostLayoutProps {
children: React.ReactNode;
}

export default function PostLayout({ children }: PostLayoutProps) {
return (
<PostServiceProvider>
<MainLayout name={''}>{children}</MainLayout>
</PostServiceProvider>
);
}
151 changes: 151 additions & 0 deletions src/app/posts/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable @typescript-eslint/no-non-null-assertion */
/* eslint-disable @typescript-eslint/no-explicit-any */
import React from 'react';
import { cookies, headers } from 'next/headers';
import { API_URL, CacheControl } from '@/blog/api/request';
import { Post } from '@/models/Post';
import { ErrorBoundary } from '@/blog/components/error/ErrorBoundary';
import { PostPage } from '@/blog/pages/post';
import { Metadata, ResolvingMetadata } from 'next';

type Props = {
params: { id: string };
searchParams: { [key: string]: string | string[] | undefined };
};

export async function generateMetadata(
{ params, searchParams }: Props,
parent: ResolvingMetadata,
): Promise<Metadata> {
// read route params
const id = params.id;

const headersList = headers();
const cookie = headersList.getSetCookie();
let post = {} as Post;
let error: any | null = null;

/**
* Extract thumbnail from post.images
* @param post
*/
const extractThumbnail = (post: Post) => {
if (post.images && post.images.length > 0) {
post.thumbnail = post.images[0].path;
}
};

const requestDataUsingFetch = async () => {
const hasCookie = !!cookie;

try {
const res = await fetch(API_URL + '/posts/' + id, {
method: 'GET',
credentials: 'include',
// headers: {
// ...CacheControl.NoCache,
// ...(hasCookie ? { Cookie: cookie } : {}),
// },
headers: {
...CacheControl.NoCache,
},
});

if (res.ok) {
const data = await res.json();
post = data.data as Post;
extractThumbnail(post);
}
} catch (e: any) {
error = {
message: 'Error occurred while fetching data',
status: 500,
};
}

return post;
};

const postEntity = await requestDataUsingFetch();

return {
title: `${postEntity.title} - 어진석의 블로그`,
description: postEntity.previewContent ?? '',
openGraph: {
images: [postEntity.thumbnail ?? ''],
},
};
}

async function getPost(id: string) {
const headersList = headers();
const cookieStore = cookies();
const cookie = headersList.getSetCookie();
let post = {} as Post;
let error: any | null = null;

/**
* Extract thumbnail from post.images
* @param post
*/
const extractThumbnail = (post: Post) => {
if (post.images && post.images.length > 0) {
post.thumbnail = post.images[0].path;
}
};

const requestDataUsingFetch = async () => {
const hasCookie = !!cookie;

try {
const res = await fetch(API_URL + '/posts/' + id, {
method: 'GET',
credentials: 'include',
// headers: {
// ...CacheControl.NoCache,
// ...(hasCookie ? { Cookie: cookie } : {}),
// },
headers: {
...CacheControl.NoCache,
},
});

if (res.ok) {
const data = await res.json();
post = data.data as Post;
extractThumbnail(post);
}
} catch (e: any) {
error = {
message: 'Error occurred while fetching data',
status: 500,
};
}
};

await requestDataUsingFetch();

return {
post,
error,
};
}

export default async function PostsPage({ params }: Props) {
const { post, error } = await getPost(params.id);

if (error) {
return <div>{error}</div>;
}

return (
<PostPage
{...{
post: post,
id: String(post.id),
error: error!,
}}
/>
);
}
19 changes: 19 additions & 0 deletions src/app/secret/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
'use client';

import SecretPostWrapper from '@/blog/components/post/SecretPostWrapper2';
import React from 'react';

export interface SecretPostProps {
id: number;
}

export default function SecretPost({
params,
}: {
params: {
id: string;
};
}) {
return <SecretPostWrapper id={Number(params.id)} />;
}
6 changes: 3 additions & 3 deletions src/blog/api/request.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { IRequestHandler } from '@/types/IRequest';
import getConfig from 'next/config';
// import getConfig from 'next/config';

const { publicRuntimeConfig: config } = getConfig();
// const { publicRuntimeConfig: config } = getConfig();

export const API_URL = config.backendUrl;
export const API_URL = process.env.NEXT_PUBLIC_SERVER_URL;

export type HttpRawHeader = Record<string, string>;
export interface ICacheControl {
Expand Down
Loading

0 comments on commit 2e4f775

Please sign in to comment.