메인페이지 더수정 homework
This commit is contained in:
BIN
public/uploads/1762349790327-56eucbsdkiy.webp
Normal file
BIN
public/uploads/1762349790327-56eucbsdkiy.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 279 KiB |
BIN
public/uploads/1762349798482-lg2199h4w0h.webp
Normal file
BIN
public/uploads/1762349798482-lg2199h4w0h.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 100 KiB |
@@ -117,8 +117,7 @@ export function BoardPanelClient({
|
||||
<button
|
||||
key={sb.id}
|
||||
onClick={() => setSelectedBoardId(sb.id)}
|
||||
className={`px-[16px] py-[8px] rounded-[14px] text-[14px] shrink-0 cursor-pointer ${
|
||||
sb.id === selectedBoardId ? "bg-[#5c5c5c] text-white border border-[#5c5c5c]" : "bg-white text-[#5c5c5c] border border-[#d5d5d5] hover:bg-[#5c5c5c] hover:text-white hover:border-[#5c5c5c] transition-colors"
|
||||
className={`px-[16px] py-[8px] rounded-[14px] text-[14px] shrink-0 cursor-pointer ${sb.id === selectedBoardId ? "bg-[#5c5c5c] text-white border border-[#5c5c5c]" : "bg-white text-[#5c5c5c] border border-[#d5d5d5] hover:bg-[#5c5c5c] hover:text-white hover:border-[#5c5c5c] transition-colors"
|
||||
}`}
|
||||
>
|
||||
{sb.name}
|
||||
@@ -128,45 +127,49 @@ export function BoardPanelClient({
|
||||
</div>
|
||||
<div className="rounded-xl overflow-hidden h-full min-h-0 flex flex-col">
|
||||
<div className="flex-1 min-h-0 overflow-hidden p-0">
|
||||
<div className="px-[0px] pt-[8px] pb-[16px]">
|
||||
<div className="flex flex-col gap-[16px]">
|
||||
<div className="px-[0px] pt-[6px] pb-[6px]">
|
||||
<div className="flex flex-col gap-[6px]">
|
||||
{selectedBoardData.specialRankUsers.map((user, idx) => {
|
||||
const rank = idx + 1;
|
||||
return (
|
||||
<Link href="/boards/ranking" key={user.userId} className="flex h-[150px] items-center rounded-[16px] overflow-hidden bg-white hover:bg-neutral-50">
|
||||
<div className="h-[150px] w-[160px] relative shrink-0 bg-[#d5d5d5] overflow-hidden">
|
||||
<Link href="/boards/ranking" key={user.userId} className=" mx-[4px] flex h-[72px] items-center rounded-[10px] overflow-hidden bg-white hover:bg-neutral-50 transition-shadow hover:[box-shadow:0_0_2px_0_var(--color-alpha-shadow2,_rgba(0,0,0,0.08)),_0_var(--shadow-y-3,_8px)_var(--shadow-blur-3,_16px)_0_var(--color-alpha-shadow3,_rgba(0,0,0,0.12))]">
|
||||
<div className="h-[72px] w-[90px] relative shrink-0 bg-[#d5d5d5] overflow-hidden">
|
||||
<UserAvatar
|
||||
src={user.profileImage}
|
||||
alt={user.nickname || "프로필"}
|
||||
width={160}
|
||||
height={150}
|
||||
width={90}
|
||||
height={72}
|
||||
className="w-full h-full object-cover rounded-none"
|
||||
/>
|
||||
<div className="absolute top-0 right-0 w-[40px] h-[40px] flex items-center justify-center">
|
||||
<GradeIcon grade={user.grade} width={40} height={40} />
|
||||
<div className="absolute top-0 right-0 w-[20px] h-[20px] flex items-center justify-center">
|
||||
<GradeIcon grade={user.grade} width={20} height={20} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-1 flex items-center gap-[10px] px-[24px] md: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="flex-1 flex items-center gap-[6px] px-[12px] md:px-[12px] py-[8px] min-w-0">
|
||||
<div className="flex flex-col gap-[4px] min-w-0 flex-1">
|
||||
<div className="flex items-center gap-[6px]">
|
||||
{
|
||||
(rank === 1 || rank === 2 || rank === 3) && (
|
||||
<div className="relative w-[22px] h-[22px] shrink-0">
|
||||
{rank === 1 && <RankIcon1st />}
|
||||
{rank === 2 && <RankIcon2nd />}
|
||||
{rank === 3 && <RankIcon3rd />}
|
||||
</div>
|
||||
<div className="bg-white border border-[#d5d5d5] px-[16px] py-[5px] rounded-[12px] text-[14px] text-[#5c5c5c] shrink-0">
|
||||
)
|
||||
}
|
||||
<div className="bg-white border border-[#d5d5d5] px-[8px] py-[2px] rounded-[8px] text-[11px] text-[#5c5c5c] shrink-0">
|
||||
{rank}위
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-[24px] font-medium text-[#5c5c5c] truncate leading-[22px]">
|
||||
<div className="text-[13px] font-medium text-[#5c5c5c] truncate leading-[16px]">
|
||||
{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">
|
||||
<div className="h-[16px] flex items-center gap-[4px] shrink-0">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" 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>
|
||||
<span className="text-[12px] font-semibold text-[#5c5c5c] leading-[16px]">{user.points.toLocaleString()}</span>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
@@ -201,8 +204,7 @@ export function BoardPanelClient({
|
||||
<button
|
||||
key={sb.id}
|
||||
onClick={() => setSelectedBoardId(sb.id)}
|
||||
className={`px-[16px] py-[8px] rounded-[14px] text-[14px] shrink-0 cursor-pointer ${
|
||||
sb.id === selectedBoardId ? "bg-[#5c5c5c] text-white border border-[#5c5c5c]" : "bg-white text-[#5c5c5c] border border-[#d5d5d5] hover:bg-[#5c5c5c] hover:text-white hover:border-[#5c5c5c] transition-colors"
|
||||
className={`px-[16px] py-[8px] rounded-[14px] text-[14px] shrink-0 cursor-pointer ${sb.id === selectedBoardId ? "bg-[#5c5c5c] text-white border border-[#5c5c5c]" : "bg-white text-[#5c5c5c] border border-[#d5d5d5] hover:bg-[#5c5c5c] hover:text-white hover:border-[#5c5c5c] transition-colors"
|
||||
}`}
|
||||
>
|
||||
{sb.name}
|
||||
@@ -212,14 +214,14 @@ export function BoardPanelClient({
|
||||
</div>
|
||||
<div className="rounded-xl overflow-hidden h-full min-h-0 flex flex-col">
|
||||
<div className="flex-1 min-h-0 overflow-hidden p-0">
|
||||
<div className="px-[0px] pt-[8px] pb-[16px]">
|
||||
<div className="flex flex-col gap-[16px]">
|
||||
<div className="px-[0px] pt-[6px] pb-[6px]">
|
||||
<div className="flex flex-col gap-[6px]">
|
||||
{selectedBoardData.previewPosts.map((post) => {
|
||||
// attachments에서 이미지를 먼저 찾고, 없으면 content에서 추출
|
||||
const firstImage = post.attachments?.[0]?.url || extractImageFromContent(post.content);
|
||||
return (
|
||||
<Link key={post.id} href={`/posts/${post.id}`} className="group flex h-[150px] items-start rounded-[16px] overflow-hidden bg-white">
|
||||
<div className="h-[150px] w-[214px] relative shrink-0 bg-[#ededed] overflow-hidden">
|
||||
<Link key={post.id} href={`/posts/${post.id}`} className="mx-[4px] group flex h-[72px] items-start rounded-[10px] overflow-hidden bg-white hover:bg-neutral-50 transition-shadow hover:[box-shadow:0_0_2px_0_var(--color-alpha-shadow2,_rgba(0,0,0,0.08)),_0_var(--shadow-y-3,_8px)_var(--shadow-blur-3,_16px)_0_var(--color-alpha-shadow3,_rgba(0,0,0,0.12))]">
|
||||
<div className="h-[72px] w-[90px] relative shrink-0 bg-[#ededed] overflow-hidden">
|
||||
{firstImage ? (
|
||||
<img
|
||||
src={firstImage}
|
||||
@@ -232,29 +234,27 @@ export function BoardPanelClient({
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex-1 flex items-center gap-[10px] px-[24px] md:px-[30px] py-[24px] min-w-0">
|
||||
<div className="flex flex-col gap-[12px] min-w-0 flex-1">
|
||||
<div className="bg-white border border-[#d5d5d5] px-[16px] py-[5px] rounded-[12px] text-[14px] text-[#5c5c5c] shrink-0 w-fit">
|
||||
<div className="flex-1 flex items-center gap-[6px] px-[10px] md:px-[10px] py-[6px] min-w-0">
|
||||
<div className="flex flex-col gap-[4px] min-w-0 flex-1">
|
||||
<div className="bg-white border border-[#d5d5d5] px-[8px] py-[2px] rounded-[8px] text-[11px] text-[#5c5c5c] shrink-0 w-fit">
|
||||
{board.name}
|
||||
</div>
|
||||
<div className="flex items-center gap-[4px] overflow-hidden">
|
||||
<div className="relative w-[16px] h-[16px] shrink-0">
|
||||
{isNewWithin1Hour(post.createdAt) && (
|
||||
<>
|
||||
<div className="relative w-[16px] h-[16px] shrink-0">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
|
||||
<path fillRule="evenodd" clipRule="evenodd" d="M1 8C1 4.5691 4.26184 2 8 2C11.7382 2 15 4.5691 15 8C15 11.4309 11.7382 14 8 14C7.57698 14 7.16215 13.9679 6.7588 13.9061C5.85852 14.4801 4.81757 14.8544 3.6995 14.9654C3.41604 14.9936 3.1411 14.8587 2.98983 14.6174C2.83857 14.376 2.83711 14.0698 2.98605 13.8269C3.21838 13.4482 3.38055 13.0221 3.45459 12.5659C1.97915 11.4858 1 9.86014 1 8Z" fill="#F45F00" />
|
||||
</svg>
|
||||
<div className="absolute inset-0 flex items-center justify-center text-[10px] text-white font-extrabold select-none">n</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<span className="text-[16px] leading-[22px] text-[#5c5c5c] truncate group-hover:text-[var(--red-50,#F94B37)] group-hover:font-[700]" style={{ fontFamily: "var(--font-family-Font-1, Pretendard)" }}>{stripHtml(post.title)}</span>
|
||||
)}
|
||||
<span className="text-[13px] leading-[18px] text-[#5c5c5c] truncate group-hover:text-[var(--red-50,#F94B37)] group-hover:font-[700]" style={{ fontFamily: "var(--font-family-Font-1, Pretendard)" }}>{stripHtml(post.title)}</span>
|
||||
{(post.stat?.commentsCount ?? 0) > 0 && (
|
||||
<span className="ml-1 text-[14px] text-[#f45f00] font-bold shrink-0">[{post.stat?.commentsCount}]</span>
|
||||
<span className="ml-1 text-[11px] text-[#f45f00] font-bold shrink-0">[{post.stat?.commentsCount}]</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="h-[16px] relative">
|
||||
<span className="absolute top-1/2 translate-y-[-50%] text-[12px] leading-[12px] tracking-[-0.24px] text-[#8c8c8c]">
|
||||
<span className="absolute top-1/2 translate-y-[-50%] text-[10px] leading-[10px] tracking-[-0.24px] text-[#8c8c8c]">
|
||||
{formatDateYmd(post.createdAt)}
|
||||
</span>
|
||||
</div>
|
||||
@@ -293,8 +293,7 @@ export function BoardPanelClient({
|
||||
<button
|
||||
key={sb.id}
|
||||
onClick={() => setSelectedBoardId(sb.id)}
|
||||
className={`px-[16px] py-[8px] rounded-[14px] text-[14px] shrink-0 cursor-pointer ${
|
||||
sb.id === selectedBoardId ? "bg-[#5c5c5c] text-white border border-[#5c5c5c]" : "bg-white text-[#5c5c5c] border border-[#d5d5d5] hover:bg-[#5c5c5c] hover:text-white hover:border-[#5c5c5c] transition-colors"
|
||||
className={`px-[16px] py-[8px] rounded-[14px] text-[14px] shrink-0 cursor-pointer ${sb.id === selectedBoardId ? "bg-[#5c5c5c] text-white border border-[#5c5c5c]" : "bg-white text-[#5c5c5c] border border-[#d5d5d5] hover:bg-[#5c5c5c] hover:text-white hover:border-[#5c5c5c] transition-colors"
|
||||
}`}
|
||||
>
|
||||
{sb.name}
|
||||
@@ -314,19 +313,17 @@ export function BoardPanelClient({
|
||||
<div className="bg-white px-[24px] pt-[8px] pb-[16px]">
|
||||
<ul className="min-h-[326px]">
|
||||
{selectedBoardData.textPosts.map((p) => (
|
||||
<li key={p.id} className="border-b border-[#ededed] h-[28px] pl-0 pr-[24px] pt-0 pb-0">
|
||||
<li key={p.id} className="border-b border-[#ededed] h-[28px] pl-0 pr-[4px] pt-0 pb-0">
|
||||
<div className="flex items-center justify-between w-full">
|
||||
<Link href={`/posts/${p.id}`} className="group flex items-center gap-[4px] h-[32px] overflow-hidden flex-1 min-w-0">
|
||||
<div className="relative w-[16px] h-[16px] shrink-0">
|
||||
{isNewWithin1Hour(p.createdAt) && (
|
||||
<>
|
||||
<div className="relative w-[16px] h-[16px] shrink-0">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
|
||||
<path fillRule="evenodd" clipRule="evenodd" d="M1 8C1 4.5691 4.26184 2 8 2C11.7382 2 15 4.5691 15 8C15 11.4309 11.7382 14 8 14C7.57698 14 7.16215 13.9679 6.7588 13.9061C5.85852 14.4801 4.81757 14.8544 3.6995 14.9654C3.41604 14.9936 3.1411 14.8587 2.98983 14.6174C2.83857 14.376 2.83711 14.0698 2.98605 13.8269C3.21838 13.4482 3.38055 13.0221 3.45459 12.5659C1.97915 11.4858 1 9.86014 1 8Z" fill="#F45F00" />
|
||||
</svg>
|
||||
<div className="absolute inset-0 flex items-center justify-center text-[10px] text-white font-extrabold select-none">n</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<span className="text-[14px] leading-[20px] text-[#5c5c5c] truncate max-w-[calc(100vw-280px)] group-hover:text-[var(--red-50,#F94B37)] group-hover:font-[700]" style={{ fontFamily: "var(--font-family-Font-1, Pretendard)" }}>{stripHtml(p.title)}</span>
|
||||
{(p.stat?.commentsCount ?? 0) > 0 && (
|
||||
<span className="text-[14px] text-[#f45f00] font-bold">[{p.stat?.commentsCount}]</span>
|
||||
|
||||
@@ -146,7 +146,7 @@ export default async function Home({ searchParams }: { searchParams: Promise<{ s
|
||||
select: { userId: true, nickname: true, points: true, profileImage: true, grade: true },
|
||||
where: { status: "active" },
|
||||
orderBy: { points: "desc" },
|
||||
take: 3,
|
||||
take: 6,
|
||||
});
|
||||
} else if (isPreview) {
|
||||
previewPosts = await prisma.post.findMany({
|
||||
@@ -165,7 +165,7 @@ export default async function Home({ searchParams }: { searchParams: Promise<{ s
|
||||
stat: { select: { commentsCount: true } },
|
||||
},
|
||||
orderBy: { createdAt: "desc" },
|
||||
take: 3,
|
||||
take: 6,
|
||||
});
|
||||
} else if (isTextMain) {
|
||||
textPosts = await prisma.post.findMany({
|
||||
|
||||
@@ -82,7 +82,7 @@ export default function NewPostPage() {
|
||||
className="h-16 rounded-2xl border border-neutral-300 px-6 text-base text-neutral-900 bg-white hover:bg-neutral-50"
|
||||
onClick={() => {/* 태그 선택 자리표시 */}}
|
||||
>
|
||||
테그선택
|
||||
태그선택
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user