Skip to content

Commit e9c9122

Browse files
authored
Merge pull request #127 from codeit-FE-18-part2/develop
v0.3.0 배포
2 parents e3faa1e + 176e6a9 commit e9c9122

File tree

7 files changed

+154
-39
lines changed

7 files changed

+154
-39
lines changed

src/features/rolling-paper/components/rolling-paper-list.jsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,8 +248,15 @@ function RollingPaperList({ cardData, totalPages, currentPage, onTurnCards }) {
248248
const navigate = useNavigate();
249249

250250
const handleCardClick = (cardId) => {
251+
if(!cardId) {
252+
navigate("*");
253+
return;
254+
}
255+
251256
navigate(`/post/${cardId}`);
252257
};
258+
259+
253260
const profileImages = useMemo(
254261
() =>
255262
cardData.flatMap((card) =>

src/hooks/use-image-loader.jsx

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,36 +29,51 @@ function useImageListLodeChecker(imageList = []) {
2929
useEffect(() => {
3030
if (!imageList.length) return;
3131

32+
let cancelled = false;
33+
3234
setImageLoadStates((prev) => {
3335
const nextStates = { ...prev };
3436
imageList.forEach(({ id }) => {
35-
if (nextStates[id] === undefined) {
36-
nextStates[id] = false;
37-
}
37+
if (nextStates[id] === undefined) nextStates[id] = false;
3838
});
3939
return nextStates;
4040
});
4141

42+
const imageMap = {};
43+
4244
imageList.forEach(({ id, backgroundImageURL }) => {
4345
setImageLoadStates((prev) => {
44-
if (prev[id]) return prev;
46+
if (prev[id] === true) return prev;
4547

46-
if (!backgroundImageURL) {
47-
return { ...prev, [id]: false };
48-
}
48+
if (!backgroundImageURL) return { ...prev, [id]: false };
4949

5050
const img = new Image();
51-
img.src = backgroundImageURL;
51+
imageMap[id] = img;
52+
5253
img.onload = () => {
53-
setImageLoadStates((p) => ({ ...p, [id]: true }));
54+
if (!cancelled) {
55+
setImageLoadStates((p) => ({ ...p, [id]: true }));
56+
}
5457
};
58+
5559
img.onerror = () => {
56-
setImageLoadStates((p) => ({ ...p, [id]: false }));
60+
if (!cancelled) {
61+
setImageLoadStates((p) => ({ ...p, [id]: false }));
62+
}
5763
};
5864

65+
img.src = backgroundImageURL;
5966
return prev;
6067
});
6168
});
69+
70+
return () => {
71+
cancelled = true;
72+
Object.values(imageMap).forEach((img) => {
73+
img.onload = null;
74+
img.onerror = null;
75+
});
76+
};
6277
}, [imageList]);
6378

6479
return imageLoadStates;

src/pages/404-page.jsx

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -45,20 +45,20 @@ const ErrorNumber = styled.h1`
4545
font-weight: 900;
4646
color: var(--color-purple-700);
4747
margin: 0;
48-
font-size: 200px;
48+
font-size: 150px;
4949
5050
${media.mobile} {
51-
font-size: 130px;
51+
font-size: 110px;
5252
}
5353
`;
5454

5555
const ErrorComment = styled.span`
56-
font-size: 80px;
56+
font-size: 70px;
5757
color: #6e6293;
5858
font-weight: 700;
5959
6060
em {
61-
font-size: 100px;
61+
font-size: 90px;
6262
font-weight: 800;
6363
font-style: normal;
6464
color: #240079;
@@ -72,24 +72,20 @@ const ErrorComment = styled.span`
7272
}
7373
7474
${media.mobile} {
75-
font-size: 50px;
75+
font-size: 40px;
7676
em {
77-
font-size: 60px;
77+
font-size: 50px;
7878
}
7979
}
8080
`;
8181

8282
const ErrorCommentSofter = styled.span`
83-
font-size: 50px;
83+
font-size: 25px;
8484
color: #6e6293;
8585
font-weight: 400;
8686
87-
${media.tablet} {
88-
font-size: 40px;
89-
}
90-
9187
${media.mobile} {
92-
font-size: 30px;
88+
font-size: 18px;
9389
}
9490
`;
9591

@@ -133,10 +129,10 @@ const Error404Page = () => {
133129
<AirplaneSVG src={logoImage} />
134130
<ErrorNumber>404</ErrorNumber>
135131
<ErrorComment>
136-
<em>Oops!</em> Page Not Found...
132+
<em>앗 이런!</em> 페이지를 찾을 수 없습니다.
137133
</ErrorComment>
138134
<ErrorCommentSofter>
139-
Don't worry, let's get you back on track.
135+
페이지의 주소가 올바르지 않거나, 삭제 또는 다른 페이지로 변경되었습니다.
140136
</ErrorCommentSofter>
141137
<HomeButton
142138
size={BUTTON_SIZE.large}

src/pages/create-post-page.jsx

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import BackgroundSelect from "../components/option/background-select";
1111
import TextField from "../components/text-field/text-field";
1212
import TEXT_FIELD_TYPE from "../components/text-field/text-field-type";
1313
import { media } from "../utils/media";
14+
import Toast from "../components/toast/toast";
15+
import { useToast } from "../hooks/use-toast";
1416

1517
const PostContainer = styled.div`
1618
display: flex;
@@ -77,8 +79,15 @@ function CreatePostPage() {
7779
const [selected, setSelected] = useState(0);
7880
const [backgroundUrls, setBackgroundUrls] = useState([]);
7981
const [loading, setLoading] = useState(false);
82+
const [toastMessage, setToastMessage] = useState();
8083
const navigate = useNavigate();
8184

85+
const { showsToast, isOpen, setShowsToast, onDismiss } = useToast({
86+
timeout: 5000,
87+
});
88+
89+
const handleToastCloseClick = () => setShowsToast(false);
90+
8291
const colorOptions = [
8392
{ label: "beige", color: BACKGROUND_COLOR.beige },
8493
{ label: "purple", color: BACKGROUND_COLOR.purple },
@@ -137,7 +146,8 @@ function CreatePostPage() {
137146
navigate(`/post/${newPostId}`);
138147
} catch (error) {
139148
console.error("게시물 생성 실패:", error);
140-
alert("게시물 생성에 실패했습니다. 다시 시도해 주세요");
149+
setToastMessage("게시물 생성에 실패했습니다. 다시 시도해 주세요.")
150+
setShowsToast(true);
141151
} finally {
142152
setLoading(false);
143153
}
@@ -189,6 +199,15 @@ function CreatePostPage() {
189199
onClick={handleCreate}
190200
/>
191201
</ButtonWrapper>
202+
203+
{showsToast&&
204+
<Toast
205+
isOpen={isOpen}
206+
message={`${toastMessage} 🚨`}
207+
onClose={handleToastCloseClick}
208+
onDismiss={onDismiss}
209+
/>
210+
}
192211
</PostContainer>
193212
);
194213
}

src/pages/messages-page.jsx

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ import { useMedia } from "../hooks/use-media";
2525
import { useModalDialog } from "../hooks/use-modal-dialog";
2626
import ContentLayout from "../layouts/content-layout";
2727
import { media } from "../utils/media";
28+
import Toast from "../components/toast/toast";
29+
import { useToast } from "../hooks/use-toast";
2830

2931
const Content = styled.div`
3032
& > div {
@@ -111,6 +113,8 @@ function MessagesPage() {
111113
onPrimaryAction,
112114
onDismissDialog,
113115
} = useModalDialog();
116+
const [toastMessage, setToastMessage] = useState();
117+
const [hasMoreMessages, setHasMoreMessages] = useState(true);
114118

115119
const isEditing = useMemo(
116120
() => location.pathname.includes("edit"),
@@ -121,6 +125,12 @@ function MessagesPage() {
121125
navigate("edit");
122126
};
123127

128+
const { showsToast, isOpen, setShowsToast, onDismiss } = useToast({
129+
timeout: 5000,
130+
});
131+
132+
const handleToastCloseClick = () => setShowsToast(false);
133+
124134
const handleRollingPaperDelete = () => {
125135
openDialog({
126136
title: `${recipient.name} 님의 롤링 페이퍼를 삭제할까요?`,
@@ -130,8 +140,9 @@ function MessagesPage() {
130140
await deleteRecipient({ id: recipient.id });
131141
navigate(`/list`);
132142
} catch (error) {
133-
// TODO: Error 처리
134143
console.log(error);
144+
setToastMessage(error);
145+
setShowsToast(true);
135146
}
136147
},
137148
});
@@ -152,8 +163,9 @@ function MessagesPage() {
152163
prev.filter((prevMessage) => prevMessage.id !== message.id)
153164
);
154165
} catch (error) {
155-
// TODO: Error 처리
156166
console.log(error);
167+
setToastMessage(error);
168+
setShowsToast(true);
157169
}
158170
},
159171
});
@@ -168,8 +180,11 @@ function MessagesPage() {
168180
};
169181

170182
const handleInfiniteScroll = async () => {
171-
const messages = await getNextPageMessages();
172-
if (!messages) return;
183+
if (!hasMoreMessages) return;
184+
185+
try {
186+
const messages = await getNextPageMessages();
187+
if (!messages) return;
173188

174189
setMessages((prev) => {
175190
const newMessages = [...prev];
@@ -181,6 +196,12 @@ function MessagesPage() {
181196

182197
return newMessages;
183198
});
199+
} catch(error) {
200+
console.error(error);
201+
setToastMessage(error);
202+
setShowsToast(true);
203+
setHasMoreMessages(false);
204+
}
184205
};
185206

186207
useEffect(() => {
@@ -196,11 +217,12 @@ function MessagesPage() {
196217
} catch (error) {
197218
// TODO: Error 처리 필요
198219
console.error(error);
220+
navigate("/notfound", { replace: true });
199221
}
200222
}
201223

202224
fetchRollingPaper();
203-
}, [id]);
225+
}, [id, navigate]);
204226

205227
const content = (
206228
<>
@@ -270,6 +292,15 @@ function MessagesPage() {
270292
}
271293
/>
272294
</Modal>
295+
296+
{showsToast&&
297+
<Toast
298+
isOpen={isOpen}
299+
message={`${toastMessage} 🚨`}
300+
onClose={handleToastCloseClick}
301+
onDismiss={onDismiss}
302+
/>
303+
}
273304
</ContentLayout>
274305
);
275306
}

src/pages/rolling-paper-list-page.jsx

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import BUTTON_SIZE from "../components/button/button-size";
77
import RollingPaperList from "../features/rolling-paper/components/rolling-paper-list";
88
import { useMedia } from "../hooks/use-media";
99
import { media } from "../utils/media";
10+
import Toast from "../components/toast/toast";
11+
import { useToast } from "../hooks/use-toast";
1012

1113
const TopContainer = styled.div`
1214
text-align: center;
@@ -71,16 +73,24 @@ function getCachedImage(url) {
7173
return cache[url].src;
7274
}
7375

74-
function RollingPaperListPage() {
75-
const navigate = useNavigate();
7676

77+
function RollingPaperListPage() {
7778
const [recipientsData, setRecipientsData] = useState([]);
7879
const [popularDataList, setPopularDataList] = useState([]);
7980
const [recentDataList, setRecentDataList] = useState([]);
8081
const [popularCurrentPage, setPopularCurrentPage] = useState(0);
8182
const [recentCurrentPage, setRecentCurrentPage] = useState(0);
8283
const [cardCount, setCardCount] = useState(4);
8384
const { isDesktop } = useMedia();
85+
const [isCalledApi, setIsCalledApi] = useState(true);
86+
const [toastMessage, setToastMessage] = useState();
87+
const navigate = useNavigate();
88+
89+
const { showsToast, isOpen, setShowsToast, onDismiss } = useToast({
90+
timeout: 5000,
91+
});
92+
93+
const handleToastCloseClick = () => setShowsToast(false);
8494

8595
useEffect(() => {
8696
isDesktop ? setCardCount(4) : setCardCount(null);
@@ -90,16 +100,24 @@ function RollingPaperListPage() {
90100
navigate("/post");
91101
};
92102

103+
93104
useEffect(() => {
94-
apiClient
95-
.get("/recipients/")
96-
.then((res) => {
105+
if (!isCalledApi) return;
106+
107+
const fetchData = async () => {
108+
try {
109+
const res = await apiClient.get("/recipients/");
97110
setRecipientsData(res.data.results);
98-
})
99-
.catch((err) => {
111+
} catch (err) {
100112
console.error("오류:", err);
101-
});
102-
}, []);
113+
setToastMessage("메시지를 가져오는 중 오류가 발생했어요.")
114+
setShowsToast(true);
115+
} finally {
116+
setIsCalledApi(false);
117+
}
118+
};
119+
fetchData();
120+
}, [isCalledApi, setShowsToast]);
103121

104122
useEffect(() => {
105123
recipientsData.forEach((data) => {
@@ -183,6 +201,15 @@ function RollingPaperListPage() {
183201
onClick={handleMakingButton}
184202
/>
185203
</ButtonFooter>
204+
205+
{showsToast&&
206+
<Toast
207+
isOpen={isOpen}
208+
message={`${toastMessage} 🚨`}
209+
onClose={handleToastCloseClick}
210+
onDismiss={onDismiss}
211+
/>
212+
}
186213
</TopContainer>
187214
);
188215
}

0 commit comments

Comments
 (0)