Skip to content

Commit 201596e

Browse files
authored
Merge pull request #196 from wafflestudio/design-memo
메모 페이지 리뉴얼
2 parents 85cae2b + e7401ec commit 201596e

15 files changed

Lines changed: 764 additions & 582 deletions

File tree

src/api/user.ts

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
import { transformEvent } from "@/util/calendar/transformEvent";
2-
import type { Category, EventDTO, Memo, MemoTag } from "@types";
1+
import {
2+
transformCategoryId,
3+
transformEvent,
4+
} from "@/util/calendar/transformEvent";
5+
import type { Category, EventDTO, Memo } from "@types";
36
import api from "./axios";
47

58
// --- Excluded Keywords ---
@@ -72,25 +75,25 @@ export const removeInterestCategory = async (categoryId: number) => {
7275
*/
7376

7477
// --- Memos ---
75-
interface MemoDTO {
76-
id: number;
77-
eventId: number;
78-
eventTitle: string;
79-
content: string;
80-
tags: MemoTag[];
81-
createdAt: string;
82-
updatedAt: string;
83-
}
78+
type MemoDTO = Omit<Memo, "createdAt" | "updatedAt" | "applyEnd"> & {
79+
createdAt?: string;
80+
updatedAt?: string;
81+
applyEnd?: string | null;
82+
};
8483

8584
// helper mapping func
86-
const mapMemoDTO = (m: MemoDTO) => {
85+
const mapMemoDTO = (m: MemoDTO): Memo => {
8786
return {
88-
id: m.id,
89-
eventId: m.eventId,
90-
eventTitle: m.eventTitle,
91-
content: m.content,
92-
tags: m.tags,
93-
createdAt: new Date(m.createdAt),
87+
...m,
88+
categoryId: transformCategoryId(m.categoryId),
89+
createdAt: m.createdAt ? new Date(m.createdAt) : undefined,
90+
updatedAt: m.updatedAt ? new Date(m.updatedAt) : undefined,
91+
applyEnd:
92+
m.applyEnd === null
93+
? null
94+
: m.applyEnd
95+
? new Date(m.applyEnd)
96+
: undefined,
9497
};
9598
};
9699

src/components/layout/sidePannel/DetailView.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ const DetailView = ({ eventId }: { eventId: number }) => {
102102
setIsBookmarked(!previousState);
103103

104104
try {
105-
await toggleBookmark(event);
105+
await toggleBookmark(event.id);
106106
} catch (e) {
107107
console.error("Failed to toggle bookmark", e);
108108
setIsBookmarked(previousState);

src/components/layout/sidePannel/EventCard.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ const EventCard = ({ event, onLoginPrompt, fullWidth = false }: { event: Event;
8080
setIsBookmarked(!previousState);
8181

8282
try {
83-
await toggleBookmark(event);
83+
await toggleBookmark(event.id);
8484
} catch (e) {
8585
console.error("Failed to toggle bookmark", e);
8686
setIsBookmarked(previousState);

src/contexts/UserDataContext.tsx

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ interface UserDataContextType {
2323
saveInterestPreferences: (categories: Category[]) => Promise<void>;
2424
addExcludedKeyword: (keyword: string) => Promise<void>;
2525
deleteExcludedKeyword: (id: number) => Promise<void>;
26-
toggleBookmark: (event: Event) => Promise<void>;
26+
toggleBookmark: (eventId: number) => Promise<void>;
2727
getMemoByTag: (tagId: number) => Promise<Memo[]>;
2828
addMemo: (
2929
eventId: number,
@@ -89,20 +89,41 @@ export const UserDataProvider = ({ children }: { children: ReactNode }) => {
8989
}
9090
}, [isAuthenticated, fetchAll]);
9191

92-
const toggleBookmark = async (event: Event) => {
93-
const isBookmarked = bookmarkedEvents.some((b) => b.id === event.id);
92+
// get interestCategories & update
93+
/*
94+
const fetchInterestCategories = async () => {
95+
try {
96+
const newInterestCategories = await userService.getInterestCategories();
97+
setInterestCategories(newInterestCategories);
98+
} catch (e) {
99+
console.error("error in fetching interest categories", e);
100+
}
101+
}
102+
*/
103+
104+
const toggleBookmark = async (eventId: number) => {
105+
const memo = eventMemos.find((memo) => memo.eventId === eventId);
106+
const isBookmarked =
107+
memo?.isBookmarked ?? bookmarkedEvents.some((event) => event.id === eventId);
94108
try {
95109
if (isBookmarked) {
96-
await userService.removeBookmark(event.id);
110+
await userService.removeBookmark(eventId);
97111
} else {
98-
await userService.addBookmark(event.id);
112+
await userService.addBookmark(eventId);
99113
}
100114

101115
const newBookmarks = await userService.getBookmarks(1);
102116
setBookmarkedEvents(newBookmarks);
103-
117+
setEventMemos((prevMemos) =>
118+
prevMemos.map((memo) =>
119+
memo.eventId === eventId
120+
? { ...memo, isBookmarked: !isBookmarked }
121+
: memo,
122+
),
123+
);
104124
} catch (error) {
105125
console.error(error);
126+
throw error;
106127
}
107128
};
108129

src/pages/bookmark/Bookmark.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export const BookmarkWidget = () => {
2121
<div className={styles.bookmarksHeader}>
2222
<div className={styles.headerLeft}>
2323
<span>내 찜 목록</span>
24-
<img src="/assets/Bookmarked.svg" alt="filled bookmark icon" />
24+
<img src="/assets/bookmark.svg" alt="bookmark icon" />
2525
</div>
2626
<FaChevronRight
2727
className={styles.backBtn}
@@ -82,7 +82,7 @@ const BookmarksPage = () => {
8282
/>
8383
<div className={styles.row}>
8484
<span>내 찜 목록</span>
85-
<img src="/assets/Bookmarked.svg" alt="filled bookmark icon" />
85+
<img src="/assets/bookmark.svg" alt="bookmark icon" />
8686
</div>
8787
</div>
8888
<div className={styles.cardsColumn}>

src/pages/memo/Memo.module.css

Lines changed: 92 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -4,80 +4,13 @@
44
sans-serif;
55
}
66

7-
/* --- Memo Cards ---*/
8-
.cardWrapper {
9-
display: flex;
10-
flex-direction: column;
11-
width: 220px;
12-
min-width: 220px;
13-
flex-shrink: 0;
14-
background-color: transparent;
15-
}
16-
177
.notFound {
188
display: flex;
199
justify-content: center;
2010
align-items: center;
2111
width: 100%;
2212
}
2313

24-
.memoContent {
25-
font-size: 15px;
26-
font-weight: 400;
27-
color: #111111;
28-
line-height: 1.5;
29-
30-
display: -webkit-box;
31-
-webkit-line-clamp: 4;
32-
line-clamp: 4;
33-
-webkit-box-orient: vertical;
34-
overflow: hidden;
35-
text-overflow: ellipsis;
36-
37-
height: 6em;
38-
margin-bottom: 12px;
39-
}
40-
41-
.memoTitle {
42-
font-size: 14px;
43-
font-weight: 700;
44-
color: #999999;
45-
margin-bottom: 4px;
46-
47-
white-space: nowrap;
48-
overflow: hidden;
49-
text-overflow: ellipsis;
50-
display: block;
51-
}
52-
53-
.memoDate {
54-
font-size: 13px;
55-
color: #999999;
56-
margin-bottom: 12px;
57-
display: block;
58-
}
59-
60-
.chips {
61-
display: flex;
62-
flex-direction: row;
63-
flex-wrap: wrap;
64-
gap: 6px;
65-
padding: 0;
66-
margin: 0;
67-
list-style: none;
68-
}
69-
70-
.chip {
71-
display: inline-block;
72-
padding: 4px 8px;
73-
background-color: #eaeaea;
74-
border-radius: 4px;
75-
76-
font-size: 12px;
77-
font-weight: 500;
78-
color: #666666;
79-
}
80-
8114
/*--Mypage start--*/
8215

8316
body {
@@ -130,8 +63,9 @@ body {
13063
}
13164

13265
.memosPage .memosHeader {
133-
width: 80%;
134-
justify-content: center;
66+
justify-content: flex-start;
67+
gap: 30px;
68+
width: 80%;
13569
}
13670

13771
.memosLeft {
@@ -154,20 +88,20 @@ body {
15488

15589
.row {
15690
display: flex;
157-
flex-grow: 1;
15891
flex-direction: row;
15992
align-items: center;
160-
justify-content: center;
93+
justify-content: flex-start;
16194
gap: 14px;
16295
}
16396

16497
.cardsColumn {
165-
display: flex;
166-
flex-direction: column;
167-
width: 80%;
168-
gap: 40px 45px;
169-
padding: 30px 0 60px 0;
170-
overflow-y: auto;
98+
display: grid;
99+
grid-template-columns: repeat(3, minmax(0, 1fr));
100+
column-gap: clamp(16px, 1.5625vw, 24px);
101+
row-gap: clamp(24px, 2.222vw, 32px);
102+
width: 70%;
103+
padding: 30px 0 60px 0;
104+
overflow-y: auto;
171105
-ms-overflow-style: none;
172106
scrollbar-width: none;
173107
}
@@ -176,6 +110,60 @@ body {
176110
display: none;
177111
}
178112

113+
.emptyCardsColumn {
114+
row-gap: 24px;
115+
}
116+
117+
.emptyMemoCard,
118+
.calendarShortcut {
119+
box-sizing: border-box;
120+
width: 100%;
121+
min-height: 230px;
122+
padding: 20px;
123+
}
124+
125+
.emptyMemoCard {
126+
display: flex;
127+
flex-direction: column;
128+
justify-content: center;
129+
gap: 10px;
130+
background: rgba(217, 217, 217, 0.5);
131+
color: #000000;
132+
}
133+
134+
.emptyMemoCard strong {
135+
font-size: 24px;
136+
font-weight: 600;
137+
line-height: 1.5;
138+
}
139+
140+
.emptyMemoCard span {
141+
font-size: 16px;
142+
font-weight: 500;
143+
line-height: 1.5;
144+
}
145+
146+
.calendarShortcut {
147+
display: flex;
148+
align-items: center;
149+
justify-content: center;
150+
gap: 10px;
151+
font: inherit;
152+
font-size: 24px;
153+
font-weight: 600;
154+
line-height: 1.5;
155+
color: #000000;
156+
text-align: left;
157+
background: rgba(255, 204, 0, 0.6);
158+
border: 0;
159+
cursor: pointer;
160+
transition: box-shadow 0.2s ease;
161+
}
162+
163+
.calendarShortcut:hover {
164+
box-shadow: 2px 4px 4px rgba(0, 0, 0, 0.2);
165+
}
166+
179167
.noneText {
180168
font-size: 14px;
181169
font-weight: 400;
@@ -235,6 +223,10 @@ body {
235223
.sidePanel {
236224
width: 340px;
237225
}
226+
227+
.cardsColumn {
228+
grid-template-columns: repeat(2, minmax(0, 1fr));
229+
}
238230
}
239231

240232
@media (max-width: 576px) {
@@ -254,9 +246,32 @@ body {
254246
.cardsColumn {
255247
gap: 0;
256248
}
249+
250+
.emptyCardsColumn {
251+
row-gap: 11px;
252+
}
253+
254+
.emptyMemoCard,
255+
.calendarShortcut {
256+
min-height: 180px;
257+
padding: 16px;
258+
}
259+
260+
.emptyMemoCard strong,
261+
.calendarShortcut {
262+
font-size: 20px;
263+
}
264+
265+
.emptyMemoCard span {
266+
font-size: 14px;
267+
}
257268
.cardsRow {
258269
padding-left: 0;
259270
}
271+
272+
.calendarShortcut:hover {
273+
box-shadow: none;
274+
}
260275
}
261276

262277
@media (max-width: 476px) {

0 commit comments

Comments
 (0)