Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions app/admin/posts/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ const AdminPostListPage = () => {
setLoading(false);
};

const handleEdit = (postId: string) => {
const handleEdit = (slug: string) => {
toast.success('글 수정 페이지로 이동합니다.');
router.push(`/admin/write?postId=${postId}`);
router.push(`/admin/write?slug=${slug}`);
};

const handleDeleteClick = (postId: string) => {
Expand Down Expand Up @@ -68,7 +68,7 @@ const AdminPostListPage = () => {
<PostListItem
key={post._id}
post={post}
handleEdit={() => handleEdit(post._id)}
handleEdit={() => handleEdit(post.slug)}
handleDelete={() => handleDeleteClick(post._id)}
/>
))}
Expand Down
27 changes: 1 addition & 26 deletions app/admin/write/page.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,10 @@
'use client';
import BlogForm from '@/app/entities/post/write/BlogForm';
import axios from 'axios';
import { PostBody } from '@/app/types/Post';
import { useRouter, useSearchParams } from 'next/navigation';
import useToast from '@/app/hooks/useToast';

const BlogWritePage = () => {
const router = useRouter();
const params = useSearchParams();
const postId = params.get('postId');
const toast = useToast();

const postBlog = async (post: PostBody) => {
try {
const response = await axios.post('/api/posts', post);
const data = await response.data;
console.log('글 발행 결과', data);
if (response.status === 201) {
toast.success('글이 성공적으로 발행되었습니다.');
router.push('/posts');
}
} catch (e) {
toast.error('글 발행 중 오류 발생했습니다.');
console.error('글 발행 중 오류 발생', e);
}
};

return (
<section className={'pt-4'}>
<h1 className={'text-3xl text-center mb-4'}>글 작성</h1>
<BlogForm postBlog={postBlog} postId={postId || null} />
<BlogForm />
</section>
);
};
Expand Down
13 changes: 9 additions & 4 deletions app/api/posts/[slug]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import dbConnect from '@/app/lib/dbConnect';
import Post from '@/app/models/Post';
import { NextRequest } from 'next/server';
import { getThumbnailInMarkdown } from '@/app/lib/utils/parse';

export async function GET(
req: NextRequest,
Expand Down Expand Up @@ -36,10 +37,14 @@ export async function PUT(
await dbConnect();
const body = await req.json();

const updatedPost = await Post.findByIdAndUpdate(params.slug, body, {
new: true,
runValidators: true,
}).lean();
const updatedPost = await Post.findOneAndUpdate(
{ slug: params.slug },
{ ...body, thumbnailImage: getThumbnailInMarkdown(body.content) },
{
new: true,
runValidators: true,
}
).lean();

if (!updatedPost) {
return Response.json(
Expand Down
2 changes: 1 addition & 1 deletion app/entities/post/detail/PostTOC.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const PostTOC = ({ postContent }: { postContent: string }) => {
};

return (
<div className="fixed post-toc hidden lg:block w-[280px] top-1/2 -translate-y-1/2 left-[calc(50%+524px)] transition-all text-sm bg-gray-100/80 rounded-md p-4 text-black">
<div className="fixed post-toc hidden 2xl:block w-[280px] top-[calc(50%+100px)] -translate-y-1/2 left-[calc(50%+524px)] transition-all text-sm bg-gray-100/80 rounded-md p-4 text-black">
<h4 className={'text-xl font-bold mb-2'}>📌 Table of Contents</h4>
<ul className={'list-none'}>
{parseHeadings(postContent).map((heading) => {
Expand Down
55 changes: 41 additions & 14 deletions app/entities/post/write/BlogForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,21 @@
import '@uiw/react-md-editor/markdown-editor.css';
import '@uiw/react-markdown-preview/markdown.css';
import { useEffect, useState } from 'react';

import * as commands from '@uiw/react-md-editor/commands';
import dynamic from 'next/dynamic';
import Link from 'next/link';
import LoadingIndicator from '@/app/entities/common/Loading/LoadingIndicator';
import { PostBody } from '@/app/types/Post';
import { StaticImport } from 'next/dist/shared/lib/get-img-props';
import LoadingSpinner from '@/app/entities/common/Loading/LoadingSpinner';
import axios from 'axios';
import useToast from '@/app/hooks/useToast';
import { useBlockNavigate } from '@/app/hooks/useBlockNavigate';
import { useRouter, useSearchParams } from 'next/navigation';

const MDEditor = dynamic(() => import('@uiw/react-md-editor'), { ssr: false });

interface BlogFormProps {
postBlog: (post: PostBody) => Promise<void>;
postId: string | null;
}

const BlogForm = ({ postBlog, postId }: BlogFormProps) => {
const BlogForm = () => {
const params = useSearchParams();
const slug = params.get('slug');
const [submitLoading, setSubmitLoading] = useState<boolean>(false);
const [title, setTitle] = useState('');
const [subTitle, setSubTitle] = useState('');
Expand All @@ -30,16 +25,17 @@ const BlogForm = ({ postBlog, postId }: BlogFormProps) => {
const [thumbnailImage, setThumbnailImage] = useState<string | StaticImport>();
const [errors, setErrors] = useState<string[]>([]);
const toast = useToast();
const router = useRouter();
const buttonStyle = `font-bold py-2 px-4 rounded mr-2 disabled:bg-opacity-75 `;
const NICKNAME = '개발자 서정우';

useBlockNavigate({ title, content: content || '' });

useEffect(() => {
if (postId) {
if (slug) {
getPostDetail();
}
}, [postId]);
}, [slug]);

const postBody: PostBody = {
title,
Expand All @@ -50,6 +46,33 @@ const BlogForm = ({ postBlog, postId }: BlogFormProps) => {
thumbnailImage,
};

const postBlog = async (post: PostBody) => {
try {
const response = await axios.post('/api/posts', post);
const data = await response.data;
if (response.status === 201) {
toast.success('글이 성공적으로 발행되었습니다.');
router.push('/posts');
}
} catch (e) {
toast.error('글 발행 중 오류 발생했습니다.');
console.error('글 발행 중 오류 발생', e);
}
};

const updatePost = async (post: PostBody) => {
try {
const response = await axios.put(`/api/posts/${slug}`, post);
if (response.status === 200) {
toast.success('글이 성공적으로 수정되었습니다.');
router.push('/posts');
}
} catch (e) {
toast.error('글 수정 중 오류 발생했습니다.');
console.error('글 수정 중 오류 발생', e);
}
};

const validatePost = (
post: PostBody
): { isValid: boolean; errors: string[] } => {
Expand Down Expand Up @@ -101,7 +124,11 @@ const BlogForm = ({ postBlog, postId }: BlogFormProps) => {
return;
}

postBlog(post);
if (slug) {
updatePost(post);
} else {
postBlog(post);
}
} catch (e) {
console.error('글 발행 중 오류 발생', e);
setSubmitLoading(false);
Expand All @@ -110,7 +137,7 @@ const BlogForm = ({ postBlog, postId }: BlogFormProps) => {

const getPostDetail = async () => {
try {
const response = await axios.get(`/api/posts/${postId}`);
const response = await axios.get(`/api/posts/${slug}`);
const data = await response.data;
setTitle(data.post.title || 'dd');
setSubTitle(data.post.subTitle);
Expand Down Expand Up @@ -169,7 +196,7 @@ const BlogForm = ({ postBlog, postId }: BlogFormProps) => {
submitHandler(postBody);
}}
>
{submitLoading ? <LoadingSpinner /> : postId ? '글 수정' : '글 발행'}
{submitLoading ? <LoadingSpinner /> : slug ? '글 수정' : '글 발행'}
</button>
</div>
</div>
Expand Down