This commit is contained in:
mota
2025-11-02 11:01:18 +09:00
parent e0aacab1d1
commit 9ff08d3e58
4 changed files with 84 additions and 20 deletions

View File

@@ -78,7 +78,7 @@ export function HeroBanner({ subItems, activeSubId }: { subItems?: SubItem[]; ac
<section className="relative w-full overflow-hidden rounded-xl bg-neutral-900 text-white" aria-roledescription="carousel"> <section className="relative w-full overflow-hidden rounded-xl bg-neutral-900 text-white" aria-roledescription="carousel">
<SelectedBanner className="h-56 sm:h-72 md:h-[264px]" /> <SelectedBanner className="h-56 sm:h-72 md:h-[264px]" />
{/* 분리된 하단 블랙 바: 높이 58px, 중앙 서브카테고리 (스켈레톤 상태에서도 동일 레이아웃 유지) */} {/* 분리된 하단 블랙 바: 높이 58px, 중앙 서브카테고리 (스켈레톤 상태에서도 동일 레이아웃 유지) */}
<div className="mt-2 h-[58px] bg-black rounded-xl flex items-center justify-center px-2"> <div className="h-[58px] bg-black rounded-xl flex items-center justify-center px-2">
{Array.isArray(subItems) && subItems.length > 0 && ( {Array.isArray(subItems) && subItems.length > 0 && (
<div className="flex flex-wrap items-center gap-[8px]"> <div className="flex flex-wrap items-center gap-[8px]">
{subItems.map((s) => ( {subItems.map((s) => (
@@ -151,7 +151,7 @@ export function HeroBanner({ subItems, activeSubId }: { subItems?: SubItem[]; ac
</div> </div>
{/* 분리된 하단 블랙 바: 높이 58px, 중앙 서브카테고리 */} {/* 분리된 하단 블랙 바: 높이 58px, 중앙 서브카테고리 */}
<div className="mt-2 h-[58px] bg-black rounded-xl flex items-center justify-center px-2"> <div className="h-[58px] bg-black rounded-xl flex items-center justify-center px-2">
{Array.isArray(subItems) && subItems.length > 0 && ( {Array.isArray(subItems) && subItems.length > 0 && (
<div className="flex flex-wrap items-center gap-[8px]"> <div className="flex flex-wrap items-center gap-[8px]">
{subItems.map((s) => ( {subItems.map((s) => (

File diff suppressed because one or more lines are too long

View File

@@ -67,6 +67,72 @@ export default async function Home({ searchParams }: { searchParams: Promise<{ s
}) })
: []; : [];
const isTextMain = board.mainTypeKey === "main_text"; const isTextMain = board.mainTypeKey === "main_text";
const isSpecialRank = board.mainTypeKey === "main_special_rank";
// 특수 랭킹 타입 처리
if (isSpecialRank) {
const topUsers = await prisma.user.findMany({
select: { userId: true, nickname: true, points: true, profileImage: true },
where: { status: "active" },
orderBy: { points: "desc" },
take: 3,
});
return (
<div key={board.id} className="h-full min-h-0 flex flex-col">
<div className="flex-1 min-h-0 overflow-hidden p-0">
<div className="px-[24px] pt-[8px] pb-[16px]">
<div className="flex flex-col gap-[16px]">
{topUsers.map((user, idx) => {
const rank = idx + 1;
return (
<div key={user.userId} className="flex h-[140px] items-center rounded-[16px] overflow-hidden">
<div className="h-[140px] w-[160px] relative shrink-0 bg-[#d5d5d5] overflow-hidden">
<img
src={user.profileImage || "https://picsum.photos/seed/profile/200/200"}
alt={user.nickname || "프로필"}
className="w-full h-full object-cover"
/>
<div className="absolute left-[calc(50%+49.25px)] top-0 translate-x-[-50%] w-[31.25px] h-[31.25px] flex items-center justify-center pointer-events-none">
<div className="w-[62.5px] h-[62.5px] flex items-center justify-center">
<img src="https://picsum.photos/seed/badge/200/200" alt="뱃지" className="w-[51px] h-[53px] object-contain" />
</div>
</div>
</div>
<div className="flex-1 flex items-center gap-[10px] px-[30px] py-[24px] min-w-0">
<div className="flex flex-col gap-[12px] min-w-0 flex-1">
<div className="flex items-center gap-[12px]">
<div className="relative w-[20px] h-[20px] shrink-0">
{/* 순위 배지 아이콘 자리 - 피그마 디자인에 맞게 이미지로 대체 필요 */}
<div className="absolute inset-0 flex items-center justify-center">
<span className="text-[12px]"></span>
</div>
</div>
<div className="bg-white border border-[#d5d5d5] px-[16px] py-[5px] rounded-[12px] text-[14px] text-[#5c5c5c] shrink-0">
{rank}
</div>
</div>
<div className="text-[24px] font-medium text-[#5c5c5c] truncate leading-[22px]">
{user.nickname || "익명"}
</div>
</div>
<div className="h-[24px] flex items-center gap-[4px] shrink-0">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none" className="shrink-0">
<path d="M8.17377 0.0481988C8.1834 0.0326271 8.19596 0.0201252 8.21037 0.0117499C8.22478 0.00337451 8.24062 -0.000628204 8.25656 7.99922e-05C8.2725 0.000788189 8.28806 0.0061865 8.30194 0.0158187C8.31582 0.0254509 8.3276 0.0390338 8.33629 0.0554196L11.3323 5.55973C11.3575 5.60512 11.4038 5.62472 11.4468 5.60718L15.8683 3.80198C15.9441 3.77104 16.0174 3.85666 15.9963 3.95053L14.2584 16H1.74226L0.00344328 3.95156C-0.00125237 3.93019 -0.0011435 3.90765 0.00375838 3.88635C0.00866025 3.86505 0.0181727 3.84576 0.0312889 3.83054C0.0444051 3.81532 0.0606369 3.80472 0.0782661 3.79988C0.0958953 3.79503 0.114266 3.79612 0.131434 3.80302L4.55889 5.61131C4.59846 5.62678 4.64309 5.61131 4.66835 5.57005L8.17461 0.0481988H8.17377Z" fill="#FFB625"/>
</svg>
<span className="text-[20px] font-semibold text-[#5c5c5c] leading-[22px]">{user.points.toLocaleString()}</span>
</div>
</div>
</div>
);
})}
</div>
</div>
</div>
</div>
);
}
if (!isTextMain) { if (!isTextMain) {
return ( return (
<div key={board.id} className="h-full min-h-0 flex flex-col"> <div key={board.id} className="h-full min-h-0 flex flex-col">
@@ -105,7 +171,7 @@ export default async function Home({ searchParams }: { searchParams: Promise<{ s
where: { boardId: board.id, status: "published" }, where: { boardId: board.id, status: "published" },
select: { id: true, title: true, createdAt: true, stat: { select: { recommendCount: true } } }, select: { id: true, title: true, createdAt: true, stat: { select: { recommendCount: true } } },
orderBy: { createdAt: "desc" }, orderBy: { createdAt: "desc" },
take: 8, take: 7,
}); });
return ( return (
@@ -195,9 +261,9 @@ export default async function Home({ searchParams }: { searchParams: Promise<{ s
{/* 1행: 프로필 + 선택된 보드 2개 (최대 2개) */} {/* 1행: 프로필 + 선택된 보드 2개 (최대 2개) */}
{(firstTwo.length > 0) && ( {(firstTwo.length > 0) && (
<section className="min-h-[410px] overflow-hidden"> <section className="min-h-[395px] overflow-hidden">
<div className="grid grid-cols-1 md:grid-cols-2 xl:[grid-template-columns:1fr_2fr_2fr] gap-4 h-full min-h-0"> <div className="grid grid-cols-1 md:grid-cols-2 xl:flex xl:gap-[23px] gap-4 h-full min-h-0">
<div className="hidden xl:grid relative overflow-hidden rounded-xl bg-white px-[25px] py-[34px] grid-rows-[120px_120px_1fr] gap-y-[32px] h-full w-full md:min-w-[350px]"> <div className="hidden xl:grid relative overflow-hidden rounded-xl bg-white px-[25px] py-[34px] grid-rows-[120px_120px_1fr] gap-y-[32px] h-[514px] w-[350px] shrink-0">
<div className="absolute inset-x-0 top-0 h-[56px] bg-[#d5d5d5] z-0" /> <div className="absolute inset-x-0 top-0 h-[56px] bg-[#d5d5d5] z-0" />
<div className="h-[120px] flex items-center justify-center relative z-10"> <div className="h-[120px] flex items-center justify-center relative z-10">
<div className="flex items-center justify-center gap-[8px]"> <div className="flex items-center justify-center gap-[8px]">
@@ -263,7 +329,7 @@ export default async function Home({ searchParams }: { searchParams: Promise<{ s
</div> </div>
</div> </div>
{(await Promise.all(firstTwo.map((b) => renderBoardPanel(b)))).map((panel, idx) => ( {(await Promise.all(firstTwo.map((b) => renderBoardPanel(b)))).map((panel, idx) => (
<div key={firstTwo[idx].id} className="rounded-xl overflow-hidden h-full min-h-0 flex flex-col"> <div key={firstTwo[idx].id} className="rounded-xl overflow-hidden xl:h-[514px] h-full min-h-0 flex flex-col flex-1">
{panel} {panel}
</div> </div>
))} ))}
@@ -277,7 +343,7 @@ export default async function Home({ searchParams }: { searchParams: Promise<{ s
{Array.from({ length: Math.ceil(restBoards.length / 2) }).map(async (_, i) => { {Array.from({ length: Math.ceil(restBoards.length / 2) }).map(async (_, i) => {
const pair = restBoards.slice(i * 2, i * 2 + 2); const pair = restBoards.slice(i * 2, i * 2 + 2);
return ( return (
<section key={`rest-${i}`} className="min-h-[410px] md:h-[510px] overflow-hidden"> <section key={`rest-${i}`} className="min-h-[395px] md:h-[495px] overflow-hidden">
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 h-full min-h-0"> <div className="grid grid-cols-1 md:grid-cols-2 gap-4 h-full min-h-0">
{(await Promise.all(pair.map((b) => renderBoardPanel(b)))).map((panel, idx) => ( {(await Promise.all(pair.map((b) => renderBoardPanel(b)))).map((panel, idx) => (
<div key={pair[idx].id} className="rounded-xl overflow-hidden h-full min-h-0 flex flex-col"> <div key={pair[idx].id} className="rounded-xl overflow-hidden h-full min-h-0 flex flex-col">

BIN
src/fonts/Jalnan2TTF.ttf Normal file

Binary file not shown.