95 lines
3.3 KiB
TypeScript
95 lines
3.3 KiB
TypeScript
import prisma from "@/lib/prisma";
|
|
import { notFound } from "next/navigation";
|
|
import { PostList } from "@/app/components/PostList";
|
|
import { HeroBanner } from "@/app/components/HeroBanner";
|
|
import { UserAvatar } from "@/app/components/UserAvatar";
|
|
import { GradeIcon, getGradeName } from "@/app/components/GradeIcon";
|
|
import { SendMessageButton } from "@/app/components/SendMessageButton";
|
|
import { headers } from "next/headers";
|
|
|
|
export default async function UserPublicProfile({ params }: { params: Promise<{ id: string }> }) {
|
|
const p = await params;
|
|
const userId = p.id;
|
|
|
|
// 현재 로그인한 사용자 식별 (uid 쿠키 기반)
|
|
const headerList = await headers();
|
|
const cookieHeader = headerList.get("cookie") || "";
|
|
const currentUid =
|
|
cookieHeader
|
|
.split(";")
|
|
.map((s) => s.trim())
|
|
.find((pair) => pair.startsWith("uid="))
|
|
?.split("=")[1] || "";
|
|
const currentUserId = currentUid ? decodeURIComponent(currentUid) : null;
|
|
|
|
const user = await prisma.user.findUnique({
|
|
where: { userId },
|
|
select: {
|
|
userId: true,
|
|
nickname: true,
|
|
profileImage: true,
|
|
level: true,
|
|
grade: true,
|
|
points: true,
|
|
},
|
|
});
|
|
if (!user) return notFound();
|
|
|
|
// 메인배너 표시 설정을 재사용(일관 UI)
|
|
const SETTINGS_KEY = "mainpage_settings" as const;
|
|
const settingRow = await prisma.setting.findUnique({ where: { key: SETTINGS_KEY } });
|
|
const parsed = settingRow ? JSON.parse(settingRow.value as string) : {};
|
|
const showBanner: boolean = parsed.showBanner ?? true;
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
{showBanner && (
|
|
<section>
|
|
<HeroBanner showPartnerCats={false} />
|
|
</section>
|
|
)}
|
|
|
|
<section className="bg-white rounded-[16px] px-4 py-6 md:px-8 md:py-8">
|
|
<div className="flex items-center gap-4">
|
|
<div className="w-[72px] h-[72px]">
|
|
<UserAvatar
|
|
src={user.profileImage}
|
|
alt={user.nickname || "프로필"}
|
|
width={72}
|
|
height={72}
|
|
className="rounded-full w-[72px] h-[72px] object-cover"
|
|
/>
|
|
</div>
|
|
<div className="flex-1 min-w-0">
|
|
<div className="flex items-center gap-2">
|
|
<h1 className="text-xl font-bold text-neutral-900 truncate">{user.nickname}</h1>
|
|
<GradeIcon grade={user.grade} width={20} height={20} />
|
|
{currentUserId && currentUserId !== user.userId && (
|
|
<SendMessageButton receiverId={user.userId} receiverNickname={user.nickname} />
|
|
)}
|
|
</div>
|
|
<div className="text-sm text-neutral-600 mt-1 flex items-center gap-3">
|
|
<span>Lv. {user.level}</span>
|
|
<span aria-hidden>•</span>
|
|
<span>{getGradeName(user.grade)}</span>
|
|
<span aria-hidden>•</span>
|
|
<span>{user.points.toLocaleString()} P</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section className="bg-white rounded-xl overflow-hidden">
|
|
<header className="px-4 py-3 border-b border-neutral-200">
|
|
<h2 className="text-lg font-bold text-neutral-900">작성한 게시글</h2>
|
|
</header>
|
|
<div className="p-0">
|
|
<PostList authorId={user.userId} variant="board" />
|
|
</div>
|
|
</section>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
|