import { headers } from "next/headers";
import prisma from "@/lib/prisma";
import Link from "next/link";
import { UserAvatar } from "@/app/components/UserAvatar";
import { GradeIcon, getGradeName } from "@/app/components/GradeIcon";
import { HeroBanner } from "@/app/components/HeroBanner";
import { PostList } from "@/app/components/PostList";
import ProfileLabelIcon from "@/app/svgs/profilelableicon";
export default async function MyPage({ searchParams }: { searchParams: Promise<{ tab?: string; page?: string; sort?: string; q?: string }> }) {
const sp = await searchParams;
const activeTab = sp?.tab || "posts";
const page = parseInt(sp?.page || "1", 10);
const sort = sp?.sort || "recent";
const q = sp?.q || "";
// 현재 로그인한 사용자 정보 가져오기
let currentUser: {
userId: string;
nickname: string;
profileImage: string | null;
points: number;
level: number;
grade: number;
} | null = null;
try {
const h = await headers();
const cookieHeader = h.get("cookie") || "";
const uid = cookieHeader
.split(";")
.map((s) => s.trim())
.find((pair) => pair.startsWith("uid="))
?.split("=")[1];
if (uid) {
const user = await prisma.user.findUnique({
where: { userId: decodeURIComponent(uid) },
select: { userId: true, nickname: true, profileImage: true, points: true, level: true, grade: true },
});
if (user) currentUser = user;
}
} catch (e) {
// 에러 무시
}
// 로그인되지 않은 경우 어드민 사용자 가져오기
if (!currentUser) {
const admin = await prisma.user.findUnique({
where: { nickname: "admin" },
select: { userId: true, nickname: true, profileImage: true, points: true, level: true, grade: true },
});
if (admin) currentUser = admin;
}
if (!currentUser) {
return
로그인이 필요합니다.
;
}
// 통계 정보 가져오기
const [postsCount, commentsCount, receivedMessagesCount, sentMessagesCount] = await Promise.all([
prisma.post.count({ where: { authorId: currentUser.userId } }),
prisma.comment.count({ where: { authorId: currentUser.userId } }),
prisma.message.count({ where: { receiverId: currentUser.userId } }),
prisma.message.count({ where: { senderId: currentUser.userId } }),
]);
// 등급 업그레이드에 필요한 포인트 계산 (예시: 다음 등급까지)
const nextGradePoints = (() => {
// 등급별 포인트 기준을 여기에 설정 (임시로 2M)
const gradeThresholds = [0, 200000, 400000, 800000, 1600000, 3200000, 6400000, 10000000];
const currentGradeIndex = Math.min(7, Math.max(0, currentUser.grade));
return gradeThresholds[currentGradeIndex + 1] || 2000000;
})();
const tabs = [
{ key: "posts", label: "내가 쓴 게시글", count: postsCount },
{ key: "comments", label: "내가 쓴 댓글", count: commentsCount },
{ key: "points", label: "포인트 히스토리", count: await prisma.pointTransaction.count({ where: { userId: currentUser.userId } }) },
{ key: "messages-received", label: "받은 쪽지함", count: receivedMessagesCount },
{ key: "messages-sent", label: "보낸 쪽지함", count: sentMessagesCount },
];
return (
{/* 히어로 배너 */}
{/* 프로필 섹션 (모바일 대응) */}
{/* 좌측: 프로필 이미지, 닉네임, 레벨/등급/포인트 */}
{/* 프로필 이미지 */}
{/* 닉네임 */}
{currentUser.nickname || "사용자"}
{/* 레벨/등급/포인트 정보 - 가로 배치 */}
레벨
Lv.{currentUser.level || 1}
등급
{getGradeName(currentUser.grade)}
포인트
{currentUser.points.toLocaleString()}
{/* 구분선 (모바일 숨김) */}
{/* 우측: 등급 배지 및 포인트 진행 상황 */}
{getGradeName(currentUser.grade)}
{(currentUser.points / 1000000).toFixed(1)}M
/ {(nextGradePoints / 1000000).toFixed(1)}M
{/* 탭 버튼 (모바일 가로 스크롤) */}
{tabs.map((tab) => (
{tab.label}
{tab.count.toLocaleString()}
))}
{/* 컨텐츠 영역 */}
{activeTab === "posts" && (
)}
{activeTab === "comments" && (async () => {
const pageSize = 20;
const comments = await prisma.comment.findMany({
where: { authorId: currentUser.userId },
orderBy: { createdAt: "desc" },
take: pageSize,
skip: (page - 1) * pageSize,
select: { id: true, postId: true, content: true, createdAt: true },
});
return (
{comments.map((c) => (
-
{c.content.slice(0, 80)}{c.content.length > 80 ? "…" : ""}
{new Date(c.createdAt).toLocaleString()}
))}
);
})()}
{activeTab === "points" && (async () => {
const pageSize = 20;
const txns = await prisma.pointTransaction.findMany({
where: { userId: currentUser.userId },
orderBy: { createdAt: "desc" },
take: pageSize,
skip: (page - 1) * pageSize,
select: { id: true, amount: true, reason: true, createdAt: true },
});
return (
);
})()}
{activeTab === "messages-received" && (
)}
{activeTab === "messages-sent" && (
)}
);
}