Skip to content

Commit

Permalink
Merge pull request #156 from jooyong-boo/develop
Browse files Browse the repository at this point in the history
merge develop
  • Loading branch information
jooyong-boo authored Oct 8, 2024
2 parents 86da902 + fe21188 commit 74a3407
Show file tree
Hide file tree
Showing 10 changed files with 233 additions and 92 deletions.
13 changes: 2 additions & 11 deletions src/app/(with-layout)/posts/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { headers } from 'next/headers';
import Link from 'next/link';
import Button from '@/components/Button';
import Viewer from '@/components/Editor/Viewer';
import Tags from '@/components/Tags';
import Title from '@/components/Title';
import CommentInput from '@/containers/post/CommentInput';
import CommentList from '@/containers/post/CommentList';
import LinkedPostCard from '@/containers/post/LinkedPostCard';
import LinkedProjectCard from '@/containers/post/LinkedProjectCard';
import PostMenu from '@/containers/post/PostMenu';
import InnerLayout from '@/layouts/InnerLayout';
import { getPostDetail, getPostDetailNavigation } from '@/services/posts';
import { formatDate } from '@/utils/convert';
Expand Down Expand Up @@ -50,10 +49,6 @@ const page = async ({ params }: { params: { id: string } }) => {

const postNavigation = await getPostDetailNavigation(id);

if (!postDetail) {
return <div>Loading...</div>;
}

return (
<InnerLayout className="gap-4">
<div className="flex flex-col gap-2 border-b border-slate-400 pb-3">
Expand All @@ -62,11 +57,7 @@ const page = async ({ params }: { params: { id: string } }) => {
</time>
<div className="flex items-center justify-between">
<Title size="large">{postDetail.title}</Title>
{isAdmin && (
<Link href={`/posts/${id}/edit`}>
<Button size="sm">수정하기</Button>
</Link>
)}
{isAdmin && <PostMenu id={id} />}
</div>
<Tags tagList={postDetail.postTag} />
<LinkedProjectCard
Expand Down
42 changes: 40 additions & 2 deletions src/app/api/posts/[id]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export async function GET(
const { id } = params;
// id로 글 조회
const postDetail = await prisma.posts.findUnique({
where: { id },
where: { id, published: true },
...postDetailQueryOptions,
});

Expand Down Expand Up @@ -238,4 +238,42 @@ export async function PATCH(req: NextRequest) {
}
}

export async function DELETE(req: NextRequest) {}
export async function DELETE(
req: NextRequest,
{ params }: { params: { id: string } },
) {
try {
const { id } = params;

const post = await prisma.posts.findUnique({
where: { id },
});

if (!post) {
return NextResponse.json(
{ message: '해당 글이 존재하지 않습니다.' },
{ status: 404 },
);
}

// deletedAt을 갱신하고 published를 false로 변경
await prisma.posts.update({
where: { id },
data: {
deletedAt: new Date(),
published: false,
},
});

return NextResponse.json(
{ message: '글이 삭제되었습니다.' },
{ status: 200 },
);
} catch (e) {
console.log('DELETE /api/posts error', e);
return NextResponse.json(
{ message: '글 삭제 중 오류가 발생했습니다.' },
{ status: 500 },
);
}
}
1 change: 1 addition & 0 deletions src/assets/svg/burger_menu.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/assets/svg/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ export { default as ArrowUp } from './arrow_up.svg';
export { default as Public } from './public.svg';
export { default as Lock } from './lock.svg';
export { default as Folder } from './folder.svg';
export { default as BurgerMenu } from './burger_menu.svg';
40 changes: 31 additions & 9 deletions src/auth.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { nanoid } from 'nanoid';
import NextAuth, { NextAuthConfig } from 'next-auth';
import NextAuth, { DefaultSession, NextAuthConfig } from 'next-auth';
import { JWT } from 'next-auth/jwt';
import Github from 'next-auth/providers/github';
import Google from 'next-auth/providers/google';
Expand All @@ -8,20 +8,36 @@ import prisma from '../prisma/client';
declare module 'next-auth' {
export interface User {
accessToken: string | JWT;
role: {
name: string;
};
oauthProvider: {
name: string;
};
nickname: string;
}
export interface Session {
user: User & {
name: string | null;
email: string | null;
image: string | null;
};
accessToken: string | JWT;
}
}

declare module 'next-auth/jwt' {
interface JWT {
accessToken: string;
role: {
name: string;
};
oauthProvider: {
name: string;
user: {
createdAt: string;
role: {
name: string;
};
oauthProvider: {
name: string;
};
nickname: string;
};
}
}
Expand Down Expand Up @@ -81,16 +97,22 @@ const authOptions: NextAuthConfig = {
},
});
if (user) {
Object.assign(token, user);
Object.assign(token, { user });
}
if (trigger === 'update' && session) {
Object.assign(token, session.user);
Object.assign(token, { user: session.user });
token.picture = session.user.image;
}
return token;
},
session: async ({ session, token }) => {
session = { ...session, ...token };
session = { ...session, ...token.user };
if (token) {
session.user.role = token.user.role;
session.user.oauthProvider = token.user.oauthProvider;
session.user.nickname = token.user.nickname;
session.accessToken = token.accessToken;
}
return session;
},
},
Expand Down
46 changes: 46 additions & 0 deletions src/containers/post/PostMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
'use client';

import { useState } from 'react';
import Link from 'next/link';
import { BurgerMenu } from '@/assets/svg/index';
import { deletePost } from '@/services/posts';

const PostMenu = ({ id }: { id: string }) => {
const [isMenuOpen, setIsMenuOpen] = useState(false);

const handleToggleMenu = () => {
setIsMenuOpen((prev) => !prev);
};

const handleDeletePost = async () => {
if (confirm('삭제하시겠습니까?')) {
await deletePost(id);
}
};

return (
<div className="relative">
<button onClick={handleToggleMenu}>
<BurgerMenu />
</button>
{isMenuOpen && (
<div className="absolute right-0 flex w-24 flex-col gap-2 rounded-md bg-slate-600 p-2 text-center">
<Link
className="hover:text-sky-600 dark:hover:text-orange-600"
href={`/posts/${id}/edit`}
>
수정하기
</Link>
<button
className="hover:text-sky-600 dark:hover:text-orange-600"
onClick={handleDeletePost}
>
삭제하기
</button>
</div>
)}
</div>
);
};

export default PostMenu;
117 changes: 68 additions & 49 deletions src/layouts/Header/components/MobileMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
'use client';

import { useState } from 'react';
import { useEffect, useState } from 'react';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { signIn, signOut, useSession } from 'next-auth/react';
import { Menu, Github, Google } from '@/assets/svg/index';
import Button from '@/components/Button';
import Profile from '@/components/Profile';
import { menus } from '@/layouts/Header/constants/menu';
import useActive from '@/layouts/Header/hooks/useActive';
Expand All @@ -30,61 +31,79 @@ function MobileMenu() {
signIn(type, { callbackUrl: pathname });
};

useEffect(() => {
setIsMenuOpen(false);
}, [pathname]);

return (
<div className="z-10 flex sm:hidden">
<button onClick={handleMenuOpen}>
<Menu className="h-6 w-6 fill-slate-900 dark:fill-slate-50" />
</button>
{isMenuOpen && (
<div className="absolute left-0 top-14 w-full bg-slate-100 shadow-lg dark:bg-slate-800">
<div className="mb-4 flex justify-center gap-4 border-b pb-4">
{session && (
<Profile>
<Profile.Info
src={session.user?.image || ''}
alt={session.user?.name || 'guest'}
name={session.user?.name || 'guest'}
/>
<Profile.Buttons>
<Profile.Button disabled>
<p>Change Profile</p>
</Profile.Button>
<Profile.Button onClick={() => signOut({ callbackUrl: '/' })}>
<p>Sign out</p>
</Profile.Button>
</Profile.Buttons>
</Profile>
)}
{!session && (
<>
<button
className="flex flex-col items-center gap-0.5 fill-slate-900 text-sm dark:fill-slate-50"
onClick={() => handleSignIn('github')}
<div
className="fixed left-0 top-0 h-full w-full bg-opacity-30"
onClick={handleMenuOpen}
>
<div className="absolute left-0 top-14 w-full bg-slate-100 shadow-lg dark:bg-slate-800">
<div className="flex justify-center gap-4 border-b border-slate-600 pb-4">
{session && (
<div className="flex flex-col gap-2">
<Profile>
<Profile.Info
src={session.user?.image || ''}
alt={session.user?.name || 'guest'}
name={session.user?.name || 'guest'}
/>
<Profile.Buttons>
<Profile.Button disabled>
<p>Change Profile</p>
</Profile.Button>
<Profile.Button
onClick={() => signOut({ callbackUrl: '/' })}
>
<p>Sign out</p>
</Profile.Button>
</Profile.Buttons>
</Profile>
{session.user.role.name === 'admin' && (
<Link href="/posts/write">
<Button size="full">새 글 작성</Button>
</Link>
)}
</div>
)}
{!session && (
<>
<button
className="flex flex-col items-center gap-0.5 fill-slate-900 text-sm dark:fill-slate-50"
onClick={() => handleSignIn('github')}
>
<Github width={40} height={40} />
<p>Github</p>
</button>
<button
className="flex flex-col items-center gap-0.5 fill-slate-900 text-sm dark:fill-slate-50"
onClick={() => handleSignIn('google')}
>
<Google width={40} height={40} />
<p>Google</p>
</button>
</>
)}
</div>
<div className="flex flex-col items-center gap-4 py-4">
{menus.map((menu) => (
<Link
key={menu.title}
href={menu.href}
className={` ${isActive(menu.href) ? 'font-semibold' : ''}`}
onClick={() => handleMenuClose()}
>
<Github width={40} height={40} />
<p>Github</p>
</button>
<button
className="flex flex-col items-center gap-0.5 fill-slate-900 text-sm dark:fill-slate-50"
onClick={() => handleSignIn('google')}
>
<Google width={40} height={40} />
<p>Google</p>
</button>
</>
)}
</div>
<div className="flex flex-col items-center gap-4 py-4">
{menus.map((menu) => (
<Link
key={menu.title}
href={menu.href}
className={` ${isActive(menu.href) ? 'font-semibold' : ''}`}
onClick={() => handleMenuClose()}
>
{menu.title}
</Link>
))}
{menu.title}
</Link>
))}
</div>
</div>
</div>
)}
Expand Down
Loading

0 comments on commit 74a3407

Please sign in to comment.