Skip to content

Commit 1a03be0

Browse files
authored
Merge pull request #56 from basilry/dev
[fix] 포스팅 상세 타이틀 범위 조정, 포스팅 목록 패딩 조정, 페이지네이션 오류 확인 후 수정
2 parents 079c6b0 + 4c7d4c4 commit 1a03be0

4 files changed

Lines changed: 144 additions & 55 deletions

File tree

src/app/(contents)/post/PostList.tsx

Lines changed: 46 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { useRouter } from "next-nprogress-bar"
55
import dayjs from "dayjs"
66
import Image from "next/image"
77
import Link from "next/link"
8-
import { usePathname } from "next/navigation"
8+
import { useSearchParams } from "next/navigation"
99
import classNames from "classnames"
1010
import ButtonBasic from "@components/atom/ButtonBasic"
1111
import LineBasic from "@components/atom/LineBasic"
@@ -25,11 +25,12 @@ const PostList = (): ReactElement => {
2525
const { loginUser, loginState } = useLoginStore()
2626

2727
const router = useRouter()
28-
const pathname = usePathname()
29-
const page = pathname.split("/")[2] || 1
28+
const searchParams = useSearchParams()
29+
const page = searchParams.get("page") || 1
3030

3131
const [postList, setPostList] = useState<IPost[]>([])
3232
const [pagination, setPagination] = useState<IPagination<IPost>>({} as IPagination<IPost>)
33+
const [failedImages, setFailedImages] = useState<Record<string, boolean>>({})
3334

3435
const getPosts = (page = 1): void => {
3536
if (page < 1) {
@@ -75,9 +76,18 @@ const PostList = (): ReactElement => {
7576
}
7677
}
7778

79+
const handleImageError = (postId: number): void => {
80+
setFailedImages((prev) => ({
81+
...prev,
82+
[postId]: true,
83+
}))
84+
85+
console.error("썸네일 로드 실패:", postId)
86+
}
87+
7888
useEffect(() => {
7989
getPosts(Number(page))
80-
}, [pathname])
90+
}, [page])
8191

8292
return (
8393
<Wrapper>
@@ -105,6 +115,7 @@ const PostList = (): ReactElement => {
105115
{postList.length > 0 ? (
106116
postList.map((post, index) => {
107117
const diff = dayjs().diff(dayjs(post.createdAt), "hour")
118+
const imageLoadFailed = failedImages[post.id]
108119

109120
return (
110121
<Link
@@ -123,36 +134,38 @@ const PostList = (): ReactElement => {
123134
)}
124135
>
125136
<div className={styles.thumbnailWrapper}>
126-
<Image
127-
className={styles.thumbnail}
128-
src={handlePostThumbnail(post.thumbnail)}
129-
alt={"thumbnail"}
130-
fill
131-
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
132-
style={{ objectFit: "cover" }}
133-
loading="eager"
134-
placeholder="blur"
135-
blurDataURL={
136-
darkMode ? "/loading-placeholder-dark.svg" : "/loading-placeholder.svg"
137-
}
138-
onError={(e) => {
139-
const target = e.target as HTMLImageElement
140-
target.style.display = "none"
141-
console.error("썸네일 로드 실패:", target.src)
142-
if (target.src.includes("/proxy/")) {
143-
console.log(
144-
"프록시 URL 로드 실패, 환경 변수 확인 필요:",
145-
target.src,
146-
)
147-
console.log("환경 변수:", {
148-
NEXT_PUBLIC_IP: process.env.NEXT_PUBLIC_IP,
149-
})
137+
{!imageLoadFailed ? (
138+
<Image
139+
className={styles.thumbnail}
140+
src={handlePostThumbnail(post.thumbnail)}
141+
alt={"thumbnail"}
142+
fill
143+
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
144+
style={{ objectFit: "cover" }}
145+
loading="eager"
146+
placeholder="blur"
147+
blurDataURL={
148+
darkMode
149+
? "/loading-placeholder-dark.svg"
150+
: "/loading-placeholder.svg"
150151
}
151-
target.parentElement!.innerHTML = `<div style="display:flex;align-items:center;justify-content:center;width:100%;height:100%;background-color:${
152-
darkMode ? "#333" : "#f5f5f5"
153-
};color:${darkMode ? "#ccc" : "#666"};">이미지 없음</div>`
154-
}}
155-
/>
152+
onError={() => handleImageError(post.id)}
153+
/>
154+
) : (
155+
<div
156+
style={{
157+
display: "flex",
158+
alignItems: "center",
159+
justifyContent: "center",
160+
width: "100%",
161+
height: "100%",
162+
backgroundColor: darkMode ? "#333" : "#f5f5f5",
163+
color: darkMode ? "#ccc" : "#666",
164+
}}
165+
>
166+
이미지 없음
167+
</div>
168+
)}
156169
</div>
157170
<div className={styles.itemLeft}>
158171
<div className={styles.itemTitle}>

src/app/(contents)/post/[detailId]/PostDetail.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -235,10 +235,8 @@ const PostDetail = (): ReactElement => {
235235
className={classNames(styles.titleWrapper, {
236236
[styles.titleScrolled]: isScrolled,
237237
[styles.dark]: darkMode && isScrolled,
238+
[styles.hasThumbnail]: postDetail.thumbnail,
238239
})}
239-
style={{
240-
minHeight: postDetail.thumbnail && !isScrolled ? "300px" : "150px",
241-
}}
242240
>
243241
{postDetail.thumbnail && (
244242
<Image
@@ -268,7 +266,9 @@ const PostDetail = (): ReactElement => {
268266
<TextBasic
269267
size={isScrolled ? "xx-large" : "xxx-large"}
270268
bold="bold"
271-
className={styles.titleText}
269+
className={classNames(styles.titleText, {
270+
[styles["long-text"]]: postDetail.title && postDetail.title.length > 50,
271+
})}
272272
>
273273
{parse(postDetail.title || "")}
274274
</TextBasic>
@@ -317,7 +317,7 @@ const PostDetail = (): ReactElement => {
317317
</div>
318318

319319
{/* 스크롤 시 타이틀 영역만큼 여백 추가 (타이틀이 fixed 포지션일 때) */}
320-
{isScrolled && <div style={{ height: "70px" }} />}
320+
{isScrolled && <div style={{ height: "110px" }} />}
321321

322322
<LineBasic />
323323
<br />

src/styles/pages/postDetail.module.scss

Lines changed: 73 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,64 +13,111 @@
1313
justify-content: space-between;
1414
transition: all 0.3s ease;
1515
z-index: 10;
16+
17+
&.hasThumbnail:not(.titleScrolled) {
18+
min-height: 300px;
19+
20+
@include TABLET {
21+
min-height: 250px;
22+
}
23+
24+
@include MOBILE {
25+
min-height: 200px;
26+
}
27+
28+
@include S-MOBILE {
29+
min-height: 180px;
30+
}
31+
}
32+
33+
&:not(.hasThumbnail), &.titleScrolled {
34+
min-height: 150px;
35+
36+
@include S-MOBILE {
37+
min-height: 120px;
38+
}
39+
}
1640
}
1741

42+
// 스크롤 시 타이틀 고정
1843
.titleScrolled {
1944
position: fixed;
2045
top: 86px;
2146
left: 0;
2247
right: 0;
23-
height: 70px !important;
48+
height: auto !important;
49+
min-height: 70px;
50+
max-height: 110px;
2451
padding: 10px 20px;
2552
background-color: rgba(255, 255, 255, 0.95);
2653
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
2754
display: flex;
28-
align-items: center;
55+
align-items: flex-start;
2956
z-index: 1000;
57+
overflow: hidden;
3058

3159
img {
3260
border-radius: 0 !important;
3361
}
3462

35-
// 다크모드 대응
3663
&.dark {
3764
background-color: rgba(30, 30, 30, 0.95);
3865
}
3966

4067
.titleTopWrapper {
4168
width: 100%;
4269
padding: 0;
43-
display: flex;
44-
justify-content: space-between;
45-
align-items: center;
70+
align-items: flex-start;
71+
flex-wrap: nowrap;
4672
}
4773

4874
.titleLeftWrapper {
49-
display: flex;
50-
align-items: center;
75+
flex: 1;
76+
max-width: 75%;
77+
78+
@include TABLET {
79+
max-width: 70%;
80+
}
81+
82+
@include MOBILE {
83+
max-width: 65%;
84+
}
5185
}
5286

5387
.titleText {
54-
transition: font-size 0.3s ease;
55-
white-space: nowrap;
88+
white-space: normal;
89+
overflow: visible;
90+
word-break: break-word;
91+
display: -webkit-box;
92+
-webkit-line-clamp: 2;
93+
-webkit-box-orient: vertical;
5694
overflow: hidden;
57-
text-overflow: ellipsis;
58-
max-width: 70%;
95+
96+
font-size: 1.2rem !important;
97+
line-height: 1.3;
5998
}
6099

61100
.btnWrapper {
101+
display: flex;
102+
flex-shrink: 0;
103+
gap: 5px;
104+
margin-left: 5px;
105+
62106
button {
63-
padding: 5px 10px;
107+
padding: 5px 8px;
64108
font-size: 12px;
109+
white-space: nowrap;
110+
}
111+
112+
@include MOBILE {
113+
flex-direction: column;
114+
gap: 3px;
65115
}
66116
}
67117

68118
.titleBottom {
69119
width: 100%;
70-
display: flex;
71-
align-items: center;
72120
margin-left: 15px;
73-
gap: 10px;
74121
}
75122
}
76123

@@ -114,6 +161,16 @@
114161

115162
.titleText {
116163
transition: font-size 0.3s ease;
164+
white-space: normal;
165+
overflow: visible;
166+
word-break: break-word;
167+
max-width: 100%;
168+
169+
&.long-text {
170+
white-space: nowrap;
171+
overflow: hidden;
172+
text-overflow: ellipsis;
173+
}
117174
}
118175

119176
.titleBottom {

src/styles/pages/postList.module.scss

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,17 @@
2323
display: flex;
2424
flex-direction: column;
2525
padding: 12px 15px;
26-
margin-top: 25px;
26+
// margin-top: 25px;
2727
min-height: 70vh;
2828

29+
@include TABLET {
30+
padding: 10px 15px;
31+
}
32+
33+
@include MOBILE {
34+
padding: 7px 8px;
35+
}
36+
2937
.noData {
3038
display: flex;
3139
flex-direction: column;
@@ -51,6 +59,17 @@
5159
border-top: 1px solid $black-400;
5260
}
5361

62+
// 사이즈 조절 필요
63+
@include TABLET {
64+
height: 120px;
65+
padding: 10px 15px;
66+
}
67+
68+
@include MOBILE {
69+
height: 100px;
70+
padding: 7px 8px;
71+
}
72+
5473
.thumbnailWrapper {
5574
position: relative;
5675
overflow: auto;

0 commit comments

Comments
 (0)