느려도 한걸음씩

Next.js 토이 프로젝트 (7) - 내 게시물 페이지 구현하기 본문

토이프로젝트/find side(가제)

Next.js 토이 프로젝트 (7) - 내 게시물 페이지 구현하기

hoj0806 2025. 5. 8. 02:05

 

 

이번 포스트에서는 내가 게시한 포스트들을 볼 수 있는 페이지를 구현해 보겠습니다.


내 게시물은 게시물 작성자가 본인이므로, 사용자가 로그인한 상태에서 본인이 작성한 게시물만 조회하는 페이지입니다.

 

 

 

1. 내 게시물 조회 함수 만들기

먼저, 현재 사용자가 작성한 게시물만 가져오는 함수를 만들어야 합니다.
이를 위해 getMyPosts()라는 함수를 작성합니다.

export async function getMyPosts() {
  const supabase = await createClient();

  // 현재 로그인한 유저 정보 가져오기
  const {
    data: { user },
    error: userError,
  } = await supabase.auth.getUser();

  if (!user || userError) {
    console.error("❌ 로그인된 유저가 없습니다:", userError?.message);
    return [];
  }

  // 현재 유저가 작성한 게시물 조회
  const { data, error } = await supabase
    .from("posts")
    .select("*")
    .eq("user_id", user.id)
    .order("created_at", { ascending: false });

  if (error) {
    console.error("❌ 나의 게시물 조회 실패:", error.message);
    return [];
  }

  return data;
}

 

이 함수는 supabase를 사용하여 현재 로그인한 사용자의 ID를 가져온 뒤, posts 테이블에서 해당 사용자가 작성한 게시물만 조회합니다.
게시물들은 최신순으로 정렬되어 반환됩니다.

 

 

2. 내 게시물 페이지 구현하기

이제 내 게시물을 보여줄 페이지를 작성합니다.
이 페이지에서는 사용자가 작성한 게시물이 없을 경우 메시지를 보여주고, 게시물이 있을 경우 그리드 형태로 표시합니다.

 
import Link from "next/link";
import { getMyPosts } from "../actions";

const MyPostsPage = async () => {
  const myPosts = await getMyPosts();

  return (
    <main className='max-w-7xl mx-auto p-6'>
      <h1 className='text-2xl font-bold mb-6'>내 게시물</h1>

      {myPosts.length === 0 ? (
        <p className='text-gray-500'>아직 작성한 게시물이 없습니다.</p>
      ) : (
        <div className='grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6'>
          {myPosts.map((post) => (
            <div
              key={post.id}
              className='bg-white border border-gray-200 shadow-sm rounded-xl p-4 space-y-2 relative'
            >
              <Link href={`/study/${post.id}`}>
                <div>
                  <div className='text-sm text-gray-500'>{post.category}</div>
                  <h2 className='text-lg font-semibold truncate text-black'>
                    {post.title}
                  </h2>
                  <div className='text-sm text-gray-700 line-clamp-2'>
                    {post.content}
                  </div>
                  <div className='text-xs text-gray-400'>
                    모집 인원: {post.recruitment_count}
                  </div>
                  <div className='text-xs text-gray-400'>
                    마감일: {post.deadline}
                  </div>
                </div>
              </Link>
            </div>
          ))}
        </div>
      )}
    </main>
  );
};

export default MyPostsPage;

 

 

3. 핵심 포인트

  1. 게시물 조회:
    getMyPosts()를 호출하여 로그인한 사용자가 작성한 게시물을 가져옵니다.
  2. 조건부 렌더링:
    게시물이 없으면 "아직 작성한 게시물이 없습니다."라는 메시지를, 게시물이 있으면 그리드 형태로 게시물을 나열합니다.
  3. 링크:
    각 게시물 제목을 클릭하면 해당 게시물의 상세 페이지로 이동할 수 있도록 Link 컴포넌트를 사용했습니다.
  4. 스타일:
    게시물은 grid 레이아웃을 사용하여 카드 형태로 표시되며, 각 카드에는 게시물의 제목, 카테고리, 모집 인원, 마감일 등의 정보가 포함됩니다.

4. 결과 화면

  • 게시물이 없는 경우:
    아직 작성한 게시물이 없습니다.라는 문구가 표시됩니다.
  • 게시물이 있는 경우:
    게시물들이 그리드 형태로 표시되며, 각 카드에는 카테고리, 제목, 내용의 일부, 모집 인원, 마감일 등의 정보가 나타납니다.

이제 사용자는 내 게시물 페이지에서 자신이 작성한 게시물을 쉽게 확인할 수 있게 되었습니다.
추가적으로, 게시물 수정이나 삭제 기능을 구현하려면 각 게시물 카드에 수정 버튼삭제 버튼을 추가하는 방식으로 확장할 수 있습니다.

이로써 내 게시물 페이지가 완성되었습니다.