From ec05933a5f447ba30c2167be6d7cc35a05f67eee Mon Sep 17 00:00:00 2001 From: lilyyang0077 Date: Fri, 19 Jun 2026 12:49:30 +0900 Subject: [PATCH 1/8] =?UTF-8?q?feat:=20=ED=95=B4=EA=B2=B0=EB=90=A8=20?= =?UTF-8?q?=EC=A7=88=EB=AC=B8=20=EC=96=B4=EB=91=A1=EA=B2=8C=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/qna/QnAListPage.js | 492 +++++++++--------- frontend/src/pages/qna/QnAListPage.module.css | 28 +- 2 files changed, 271 insertions(+), 249 deletions(-) diff --git a/frontend/src/pages/qna/QnAListPage.js b/frontend/src/pages/qna/QnAListPage.js index 7f0e696..621da1a 100644 --- a/frontend/src/pages/qna/QnAListPage.js +++ b/frontend/src/pages/qna/QnAListPage.js @@ -712,269 +712,273 @@ function QnAListPage() { }, []); return ( -
-

{sessionTitle}

- - {/* ── 필터 / 정렬 행 ── */} -
- {isStaff ? ( - - ) : ( - - )} -
- - {showSortMenu && ( -
    - {['기본', '최신순', '저도궁금해요순'].map(option => ( -
  • { setSortOrder(option); setShowSortMenu(false); }}> - {option} -
  • - ))} -
+
+
+

{sessionTitle}

+ + {/* ── 필터 / 정렬 행 ── */} +
+ {isStaff ? ( + + ) : ( + )} +
+ + {showSortMenu && ( +
    + {['기본', '최신순', '저도궁금해요순'].map(option => ( +
  • { setSortOrder(option); setShowSortMenu(false); }}> + {option} +
  • + ))} +
+ )} +
-
-
- - {/* ── 이해도 바 (이해도 체크가 없으면 숨김) ── */} - {understanding?.current?.checkId != null && ( -
- - - {understanding.current.content} - - ({understanding.current.respondedCount ?? 0}/ - {understanding.current.attendanceCount ?? 0}) +
+ + {/* ── 이해도 바 (이해도 체크가 없으면 숨김) ── */} + {understanding?.current?.checkId != null && ( +
+ + + {understanding.current.content} + + ({understanding.current.respondedCount ?? 0}/ + {understanding.current.attendanceCount ?? 0}) + - - - - -
- )} - - {/* ── 질문 목록 ── */} -
- {displayedQuestions.map(question => ( -
navigate(`/sessions/${sessionId}/questions/${question.questionId}`)}> - - {/* 질문 헤더 */} -
- Q. - {question.content} -
- - {!isPast && ( - - )} -
-
+ + + +
+ )} - {/* 질문 첨부 이미지 (여러 장) */} - {question.imageUrls?.length > 0 && ( -
e.stopPropagation()}> - {question.imageUrls.map((url, idx) => ( - {`첨부 - ))} + {/* ── 질문 목록 ── */} +
+ {displayedQuestions.map(question => ( +
navigate(`/sessions/${sessionId}/questions/${question.questionId}`)}> + + {/* 질문 헤더 */} +
+ Q. + {question.content} +
+ + {!isPast && ( + + )} +
- )} - {/* 댓글 미리보기 */} - {question.previewComments?.length > 0 && ( -
- {question.previewComments.slice(0, MAX_VISIBLE_COMMENTS).map(comment => ( -
- - {comment.displayName} - {comment.displayName?.startsWith('운영진') && ( - - )} - -
-
- {comment.content} + {/* 질문 첨부 이미지 (여러 장) */} + {question.imageUrls?.length > 0 && ( +
e.stopPropagation()}> + {question.imageUrls.map((url, idx) => ( + {`첨부 + ))} +
+ )} + + {/* 댓글 미리보기 */} + {question.previewComments?.length > 0 && ( +
+ {question.previewComments.slice(0, MAX_VISIBLE_COMMENTS).map(comment => ( +
+ + {comment.displayName} + {comment.displayName?.startsWith('운영진') && ( + + )} + +
+
+ {comment.content} +
+ {comment.hasImage && ( +
{ + e.stopPropagation(); + navigate(`/sessions/${sessionId}/questions/${question.questionId}`); + }} + > + 사진보기 +
+ )}
- {comment.hasImage && ( -
{ - e.stopPropagation(); - navigate(`/sessions/${sessionId}/questions/${question.questionId}`); - }} - > - 사진보기 +
+ ))} + {question.commentCount > MAX_VISIBLE_COMMENTS && ( + + 외 {question.commentCount - MAX_VISIBLE_COMMENTS}개 댓글 + + )} +
+ )} + + {/* 댓글 입력창 */} + {commentOpenId === question.questionId && ( +
e.stopPropagation()}> + {(commentImagePreviews[question.questionId] ?? []).length > 0 && ( +
+ {(commentImagePreviews[question.questionId] ?? []).map((preview, idx) => ( +
+ {`미리보기 +
- )} + ))}
+ )} +
+ + handleCommentChange(question.questionId, e.target.value)} + onKeyDown={e => { if (e.key === 'Enter') handleCommentSubmit(e, question.questionId); }} + onPaste={e => handleCommentPaste(e, question.questionId)} + autoFocus + /> + +
+
+ )} +
+ ))} +
+ +
+ + {/* ── 하단 입력바 (지난 세션이면 숨김) ── */} + {!isPast && ( +
+ {submitError &&

{submitError}

} + {imagePreviews.length > 0 && ( +
+ {imagePreviews.map((preview, idx) => ( +
+ {`미리보기 +
))} - {question.commentCount > MAX_VISIBLE_COMMENTS && ( - - 외 {question.commentCount - MAX_VISIBLE_COMMENTS}개 댓글 - - )}
)} - - {/* 댓글 입력창 */} - {commentOpenId === question.questionId && ( -
e.stopPropagation()}> - {(commentImagePreviews[question.questionId] ?? []).length > 0 && ( -
- {(commentImagePreviews[question.questionId] ?? []).map((preview, idx) => ( -
- {`미리보기 - -
- ))} -
- )} -
+
+ {/* 운영진일 때 + 버튼 숨김 */} + {!isStaff && ( + <> handleCommentChange(question.questionId, e.target.value)} - onKeyDown={e => { if (e.key === 'Enter') handleCommentSubmit(e, question.questionId); }} - onPaste={e => handleCommentPaste(e, question.questionId)} - autoFocus + type="file" + accept="image/*" + multiple + ref={fileInputRef} + style={{ display: 'none' }} + onChange={handleImageSelect} /> - -
-
- )} -
- ))} -
- -
- - {/* ── 하단 입력바 (지난 세션이면 숨김) ── */} - {!isPast && ( -
- {submitError &&

{submitError}

} - {imagePreviews.length > 0 && ( -
- {imagePreviews.map((preview, idx) => ( -
- {`미리보기 - -
- ))} + + )} + setNewQuestion(e.target.value)} + onKeyDown={e => { + if (e.key === 'Enter') isStaff ? handleNewUnderstandCheck() : handleNewQuestion(); + }} + onPaste={handleNewQuestionPaste} + disabled={isSubmitting} + /> +
- )} -
- {/* 운영진일 때 + 버튼 숨김 */} - {!isStaff && ( - <> - - - - )} - setNewQuestion(e.target.value)} - onKeyDown={e => { - if (e.key === 'Enter') isStaff ? handleNewUnderstandCheck() : handleNewQuestion(); - }} - onPaste={handleNewQuestionPaste} - disabled={isSubmitting} - /> -
-
- )} + )} +
); } diff --git a/frontend/src/pages/qna/QnAListPage.module.css b/frontend/src/pages/qna/QnAListPage.module.css index 95ffedf..e190d07 100644 --- a/frontend/src/pages/qna/QnAListPage.module.css +++ b/frontend/src/pages/qna/QnAListPage.module.css @@ -1,5 +1,11 @@ /* ── 페이지 레이아웃 ── */ +/* .pageWrapper { + background: var(--gray50); + min-height: 100vh; +} */ + .page { + /* background: var(--gray50); */ display: flex; flex-direction: column; min-height: 100vh; @@ -19,6 +25,7 @@ margin: 10px; color: var(--black); padding-top: 60px; + padding-bottom: 40px; font-weight: 700; line-height: normal; } @@ -108,15 +115,16 @@ /* ── 이해도 바 ── */ .understandBar { + padding: 8px 16px; margin-top: 20px; - margin-bottom: 20px; + margin-bottom: 30px; display: flex; align-items: center; justify-content: space-between; border-radius: 10px; border: 1px solid var(--dark); background: var(--white); - box-shadow: 1px 2px 3px 0 rgba(0, 0, 0, 0.25); + box-shadow: none; width: 100%; height: 56px; box-sizing: border-box; @@ -207,18 +215,28 @@ } .questionCard { - padding: 14px 16px; + padding: 16px 18px; cursor: pointer; transition: box-shadow 0.2s; - border-radius: 30px; + border-radius: 20px; background: var(--white); - box-shadow: 1px 2px 3px 0 rgba(0, 0, 0, 0.25); + box-shadow: + 0 1px 4px rgba(0,0,0,0.06), + 0 0 0 1px rgba(0,0,0,0.03); width: 95%; box-sizing: border-box; min-height: 40px; } +.resolvedCard { + background: #efefef; + box-shadow: + 0 1px 4px rgba(0,0,0,0.06), + 0 0 0 1px rgba(0,0,0,0.03); +} + .questionCard:hover { + transform: translateY(-1px); box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.15); } From 5e95c7c1c21665278f83520949594ead15664f5a Mon Sep 17 00:00:00 2001 From: lilyyang0077 Date: Fri, 19 Jun 2026 12:49:42 +0900 Subject: [PATCH 2/8] =?UTF-8?q?feat:=20UI=20=EB=94=94=ED=85=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/qna/QnAMainPage.js | 118 +++++++++--------- frontend/src/pages/qna/QnAMainPage.module.css | 45 ++++++- 2 files changed, 99 insertions(+), 64 deletions(-) diff --git a/frontend/src/pages/qna/QnAMainPage.js b/frontend/src/pages/qna/QnAMainPage.js index f799420..c2c650c 100644 --- a/frontend/src/pages/qna/QnAMainPage.js +++ b/frontend/src/pages/qna/QnAMainPage.js @@ -44,69 +44,71 @@ function QNAMainPage() { if (error) return
오류: {error}
; return ( -
+
+
- {/* ── 진행 중인 세션 ── */} - {activeSessions.length > 0 && ( - <> -
-

현재 세션

- {activeSessions.map(session => ( -
navigate(`/sessions/${session.sessionId}/questions`, { state: { status: 'IN_SESSION' } })} - > -

- {getIcon(session.dayPart)} - {session.title} -

-

- {session.week}주차 {DAY_OF_WEEK_KO[session.dayOfWeek]} {DAY_PART_KO[session.dayPart]} -

-

{formatDate(session.sessionDate)}

-

{getTime(session.dayPart)}

-
- ))} -
-
- - )} + {/* ── 진행 중인 세션 ── */} + {activeSessions.length > 0 && ( + <> +
+

현재 세션

+ {activeSessions.map(session => ( +
navigate(`/sessions/${session.sessionId}/questions`, { state: { status: 'IN_SESSION' } })} + > +

+ {getIcon(session.dayPart)} + {session.title} +

+

+ {session.week}주차 {DAY_OF_WEEK_KO[session.dayOfWeek]} {DAY_PART_KO[session.dayPart]} +

+

{formatDate(session.sessionDate)}

+

{getTime(session.dayPart)}

+
+ ))} +
+
+ + )} - {/* ── 지난 세션 ── */} - {pastSessions.length > 0 && ( -
-

지난 세션

-
- {pastSessions.map(session => ( -
navigate(`/sessions/${session.sessionId}/questions`, { state: { status: 'AFTER_SESSION' } })} - > - - {getIcon(session.dayPart)} - {session.title} - -  • {session.week}주차 {DAY_OF_WEEK_KO[session.dayOfWeek]} {DAY_PART_KO[session.dayPart]} + {/* ── 지난 세션 ── */} + {pastSessions.length > 0 && ( +
+

지난 세션

+
+ {pastSessions.map(session => ( +
navigate(`/sessions/${session.sessionId}/questions`, { state: { status: 'AFTER_SESSION' } })} + > + + {getIcon(session.dayPart)} + {session.title} + +  • {session.week}주차 {DAY_OF_WEEK_KO[session.dayOfWeek]} {DAY_PART_KO[session.dayPart]} + - - -
- ))} -
-
- )} + +
+ ))} +
+
+ )} - {/* ── 세션 없을 때 ── */} - {activeSessions.length === 0 && pastSessions.length === 0 && ( -
-

아직 생성된 Q&A가 없어요

-
- )} + {/* ── 세션 없을 때 ── */} + {activeSessions.length === 0 && pastSessions.length === 0 && ( +
+

아직 생성된 Q&A가 없어요

+
+ )} +
); } diff --git a/frontend/src/pages/qna/QnAMainPage.module.css b/frontend/src/pages/qna/QnAMainPage.module.css index 38d5103..006c275 100644 --- a/frontend/src/pages/qna/QnAMainPage.module.css +++ b/frontend/src/pages/qna/QnAMainPage.module.css @@ -1,10 +1,17 @@ /* ── 페이지 레이아웃 ── */ +.pageWrapper { + min-height: 100vh; + background: #f2f2f0; + padding-top: 1px; +} + .page { min-height: 100vh; max-width: 880px; margin: 0 auto; padding: 0 16px; box-sizing: border-box; + background: #f2f2f0; } /* ── 섹션 공통 ── */ @@ -27,13 +34,25 @@ background: var(--white); border-radius: 10px; padding: 16px; + padding-bottom: 24px; text-align: center; width: 356px; height: 148px; - box-shadow: 2px 2px 5px 0 rgba(0, 0, 0, 0.25); + + border: 1px solid rgba(0,0,0,0.04); + + box-shadow: + 0 1px 0 rgba(255,255,255,0.8) inset, + 0 6px 14px rgba(0,0,0,0.08), + 0 2px 4px rgba(0,0,0,0.04); + + cursor: pointer; - transition: box-shadow 0.2s; + transition: + transform 0.2s ease, + box-shadow 0.2s ease; margin: 0 auto; + margin-bottom: 40px; } .card:hover { @@ -78,6 +97,7 @@ /* ── 지난 세션 목록 ── */ .icon { margin-right: 20px; + transition: color 0.2s; } .list { @@ -93,27 +113,30 @@ display: flex; align-items: center; justify-content: space-between; - box-shadow: 2px 2px 5px 0 rgba(0, 0, 0, 0.25); + box-shadow: 0 1px 4px rgba(0,0,0,0.06), + 0 0 0 1px rgba(0,0,0,0.03); cursor: pointer; transition: box-shadow 0.2s; } .listItem:hover { - box-shadow: 4px 4px 10px 0 rgba(0, 0, 0, 0.2); + box-shadow: 0 3px 7px rgba(0, 0, 0, 0.1); } .listTitle { font-family: var(--font-main); - font-size: 24px; + font-size: 23px; font-weight: 500; color: var(--black); + transition: color 0.2s; } .listWeek { font-family: var(--font-main); - font-size: 18px; + font-size: 15px; font-weight: 500; color: var(--gray600); + transition: color 0.2s; } .enterBtn { @@ -128,6 +151,10 @@ color: var(--dark); } +.listItem:hover .icon { + color: var(--dark); +} + /* ── 빈 상태 ── */ .empty { text-align: center; @@ -135,6 +162,12 @@ margin-top: 40px; } +.listItem:hover .enterBtn, +.listItem:hover .listTitle, +.listItem:hover .listWeek { + color: var(--dark); +} + /* ════════════════════════════════════════ 반응형 — 태블릿 (768px 이하) From d7338dbab4242c4bab9e78274ba65c1bfbe27c34 Mon Sep 17 00:00:00 2001 From: kkw610 Date: Fri, 19 Jun 2026 14:16:44 +0900 Subject: [PATCH 3/8] =?UTF-8?q?fix:=20Q&A=20=EB=AA=A9=EB=A1=9D=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EC=9E=90=EB=8F=99=20=ED=95=B4=EA=B2=B0=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=EC=A0=9C=EA=B1=B0=20=EB=B0=8F=20=EB=8C=93?= =?UTF-8?q?=EA=B8=80=20=EC=A4=91=EB=B3=B5=20=EB=B2=84=EA=B7=B8=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/qna/QnAListPage.js | 27 ++++--------------- frontend/src/pages/qna/QnAListPage.module.css | 7 ++++- 2 files changed, 11 insertions(+), 23 deletions(-) diff --git a/frontend/src/pages/qna/QnAListPage.js b/frontend/src/pages/qna/QnAListPage.js index 7f0e696..3f40f45 100644 --- a/frontend/src/pages/qna/QnAListPage.js +++ b/frontend/src/pages/qna/QnAListPage.js @@ -528,27 +528,9 @@ function QnAListPage() { if (!res.ok) throw new Error(); const json = await res.json(); if (json.isSuccess) { - if (isStaff) { - await authFetch(`/api/questions/${questionId}/status`, { method: 'PATCH' }); - } - const newComment = { - commentId: json.result.commentId, - displayName: json.result.displayName, - content: json.result.content, - }; - const update = (list) => list.map(q => - q.questionId === questionId - ? { - ...q, - isResolved: isStaff ? true : q.isResolved, - previewComments: [...(q.previewComments ?? []), newComment], - commentCount: (q.commentCount ?? 0) + 1 - } - : q - ); - setPopularQuestions(update); - setUnresolvedQuestions(update); - setResolvedQuestions(update); + // NOTE: 댓글 작성으로 인한 '해결됨' 자동 전환 없음 (해결 처리는 운영진 수동 조작만 허용) + // previewComments / commentCount UI 갱신도 SSE comment-created 이벤트에서 단일 처리 + // 여기서 직접 상태를 업데이트하면 SSE 이벤트와 중복되어 댓글이 2개 표시되므로 제거 setCommentInputs(prev => ({ ...prev, [questionId]: '' })); setCommentImages(prev => ({ ...prev, [questionId]: [] })); setCommentImagePreviews(prev => ({ ...prev, [questionId]: [] })); @@ -790,7 +772,8 @@ function QnAListPage() { {/* ── 질문 목록 ── */}
{displayedQuestions.map(question => ( -
navigate(`/sessions/${sessionId}/questions/${question.questionId}`)}> {/* 질문 헤더 */} diff --git a/frontend/src/pages/qna/QnAListPage.module.css b/frontend/src/pages/qna/QnAListPage.module.css index 95ffedf..04e0e49 100644 --- a/frontend/src/pages/qna/QnAListPage.module.css +++ b/frontend/src/pages/qna/QnAListPage.module.css @@ -209,7 +209,7 @@ .questionCard { padding: 14px 16px; cursor: pointer; - transition: box-shadow 0.2s; + transition: box-shadow 0.2s, background-color 0.2s; border-radius: 30px; background: var(--white); box-shadow: 1px 2px 3px 0 rgba(0, 0, 0, 0.25); @@ -218,6 +218,11 @@ min-height: 40px; } +/* 해결된 질문: 미해결 질문과 한눈에 구분되도록 옅은 회색 배경 처리 */ +.questionCardResolved { + background: var(--gray50); +} + .questionCard:hover { box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.15); } From 64bd2e3feac2a156d9baf78910e54ae687f2e8df Mon Sep 17 00:00:00 2001 From: kkw610 Date: Fri, 19 Jun 2026 14:28:36 +0900 Subject: [PATCH 4/8] =?UTF-8?q?style:=20=EC=A7=88=EB=AC=B8=20=EB=B0=95?= =?UTF-8?q?=EC=8A=A4=20=ED=95=B4=EA=B2=B0/=EB=AF=B8=ED=95=B4=EA=B2=B0=20?= =?UTF-8?q?=EA=B5=AC=EB=B6=84=20=EA=B0=95=ED=99=94=20=EB=B0=8F=20=EC=9D=B4?= =?UTF-8?q?=ED=95=B4=EB=8F=84=20=EC=B2=B4=ED=81=AC=20=EB=B0=95=EC=8A=A4=20?= =?UTF-8?q?=EB=86=92=EC=9D=B4=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/qna/QnAListPage.module.css | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/frontend/src/pages/qna/QnAListPage.module.css b/frontend/src/pages/qna/QnAListPage.module.css index 04e0e49..7eb8264 100644 --- a/frontend/src/pages/qna/QnAListPage.module.css +++ b/frontend/src/pages/qna/QnAListPage.module.css @@ -113,12 +113,14 @@ display: flex; align-items: center; justify-content: space-between; + gap: 10px; border-radius: 10px; border: 1px solid var(--dark); background: var(--white); box-shadow: 1px 2px 3px 0 rgba(0, 0, 0, 0.25); width: 100%; - height: 56px; + min-height: 56px; + padding: 10px 16px; box-sizing: border-box; } @@ -129,6 +131,8 @@ color: var(--gray600); display: flex; align-items: center; + align-self: center; + flex-shrink: 0; padding: 0; line-height: 1; } @@ -145,12 +149,15 @@ font-size: 24px; font-weight: 500; color: var(--black); + line-height: 1.4; + word-break: keep-all; } .understandCount { font-weight: 300; color: var(--black); font-size: 18px; + white-space: nowrap; } /* ── O/X 버튼 ── */ @@ -209,21 +216,29 @@ .questionCard { padding: 14px 16px; cursor: pointer; - transition: box-shadow 0.2s, background-color 0.2s; + transition: box-shadow 0.2s, background-color 0.2s, opacity 0.2s; border-radius: 30px; background: var(--white); - box-shadow: 1px 2px 3px 0 rgba(0, 0, 0, 0.25); + border: 1px solid rgba(11, 236, 18, 0.45); + box-shadow: 1px 2px 3px 0 rgba(0, 0, 0, 0.25), 0 0 6px 0 rgba(11, 236, 18, 0.35); width: 95%; box-sizing: border-box; min-height: 40px; } -/* 해결된 질문: 미해결 질문과 한눈에 구분되도록 옅은 회색 배경 처리 */ +/* 해결된 질문: 미해결 질문과 한눈에 구분되도록 배경을 진하게 + 카드 전체를 흐리게 처리 (네온 테두리는 미해결 질문 전용이므로 제외) */ .questionCardResolved { - background: var(--gray50); + background: var(--gray200); + opacity: 0.6; + border-color: transparent; + box-shadow: 1px 2px 3px 0 rgba(0, 0, 0, 0.25); } .questionCard:hover { + box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.15), 0 0 6px 0 rgba(11, 236, 18, 0.35); +} + +.questionCardResolved:hover { box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.15); } @@ -666,10 +681,8 @@ /* ── 이해도 바 ── */ .understandBar { - height: auto; min-height: 48px; padding: 8px 10px; - flex-wrap: wrap; } .understandName { From 1b692a599402b20b27313115753f48a4bc54665e Mon Sep 17 00:00:00 2001 From: kkw610 Date: Fri, 19 Jun 2026 14:48:26 +0900 Subject: [PATCH 5/8] =?UTF-8?q?fix:=20=EB=8C=93=EA=B8=80=20=EC=A4=91?= =?UTF-8?q?=EB=B3=B5=20=EB=8B=AC=EB=A6=BC=20=EB=B0=A9=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/qna/QnADetailPage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pages/qna/QnADetailPage.js b/frontend/src/pages/qna/QnADetailPage.js index bb93229..8dbf4af 100644 --- a/frontend/src/pages/qna/QnADetailPage.js +++ b/frontend/src/pages/qna/QnADetailPage.js @@ -674,7 +674,7 @@ function QnADetailPage() { placeholder="댓글을 입력해주세요..." value={commentText} onChange={e => setCommentText(e.target.value)} - onKeyDown={e => { if (e.key === 'Enter') handleCommentSubmit(); }} + onKeyDown={e => { if (e.key === 'Enter' && !e.nativeEvent.isComposing) handleCommentSubmit(); }} onPaste={handlePaste} disabled={isSubmitting} /> From d44660f3e7cf2ee2181b2b13fca0809c0ccae7d5 Mon Sep 17 00:00:00 2001 From: kkw610 Date: Fri, 19 Jun 2026 14:49:29 +0900 Subject: [PATCH 6/8] =?UTF-8?q?style:=20=ED=95=B4=EA=B2=B0/=EB=AF=B8?= =?UTF-8?q?=ED=95=B4=EA=B2=B0=20=EC=A7=88=EB=AC=B8=20=EA=B5=AC=EB=B6=84=20?= =?UTF-8?q?=EB=AA=85=ED=99=95=ED=9E=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/qna/QnAListPage.js | 10 +++++----- frontend/src/pages/qna/QnAListPage.module.css | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/frontend/src/pages/qna/QnAListPage.js b/frontend/src/pages/qna/QnAListPage.js index 3f40f45..c0f0bf8 100644 --- a/frontend/src/pages/qna/QnAListPage.js +++ b/frontend/src/pages/qna/QnAListPage.js @@ -528,9 +528,9 @@ function QnAListPage() { if (!res.ok) throw new Error(); const json = await res.json(); if (json.isSuccess) { - // NOTE: 댓글 작성으로 인한 '해결됨' 자동 전환 없음 (해결 처리는 운영진 수동 조작만 허용) - // previewComments / commentCount UI 갱신도 SSE comment-created 이벤트에서 단일 처리 - // 여기서 직접 상태를 업데이트하면 SSE 이벤트와 중복되어 댓글이 2개 표시되므로 제거 + // NOTE: 댓글 작성으로 인한 '해결됨' 자동 전환 없음 (해결 처리는 운영진 수동 조작만 허용). + // previewComments / commentCount UI 갱신도 SSE comment-created 이벤트에서 단일 처리. + // 여기서 직접 상태를 업데이트하면 SSE 이벤트와 중복되어 댓글이 2개 표시되므로 제거. setCommentInputs(prev => ({ ...prev, [questionId]: '' })); setCommentImages(prev => ({ ...prev, [questionId]: [] })); setCommentImagePreviews(prev => ({ ...prev, [questionId]: [] })); @@ -885,7 +885,7 @@ function QnAListPage() { placeholder="댓글을 입력해주세요..." value={commentInputs[question.questionId] || ''} onChange={e => handleCommentChange(question.questionId, e.target.value)} - onKeyDown={e => { if (e.key === 'Enter') handleCommentSubmit(e, question.questionId); }} + onKeyDown={e => { if (e.key === 'Enter' && !e.nativeEvent.isComposing) handleCommentSubmit(e, question.questionId); }} onPaste={e => handleCommentPaste(e, question.questionId)} autoFocus /> @@ -943,7 +943,7 @@ function QnAListPage() { value={newQuestion} onChange={e => setNewQuestion(e.target.value)} onKeyDown={e => { - if (e.key === 'Enter') isStaff ? handleNewUnderstandCheck() : handleNewQuestion(); + if (e.key === 'Enter' && !e.nativeEvent.isComposing) isStaff ? handleNewUnderstandCheck() : handleNewQuestion(); }} onPaste={handleNewQuestionPaste} disabled={isSubmitting} diff --git a/frontend/src/pages/qna/QnAListPage.module.css b/frontend/src/pages/qna/QnAListPage.module.css index 7eb8264..2570c0e 100644 --- a/frontend/src/pages/qna/QnAListPage.module.css +++ b/frontend/src/pages/qna/QnAListPage.module.css @@ -216,26 +216,26 @@ .questionCard { padding: 14px 16px; cursor: pointer; - transition: box-shadow 0.2s, background-color 0.2s, opacity 0.2s; + transition: box-shadow 0.2s, background-color 0.2s, opacity 0.2s, border-color 0.2s; border-radius: 30px; background: var(--white); - border: 1px solid rgba(11, 236, 18, 0.45); - box-shadow: 1px 2px 3px 0 rgba(0, 0, 0, 0.25), 0 0 6px 0 rgba(11, 236, 18, 0.35); + border: 1px solid var(--main); + box-shadow: 1px 2px 3px 0 rgba(0, 0, 0, 0.25); width: 95%; box-sizing: border-box; min-height: 40px; } -/* 해결된 질문: 미해결 질문과 한눈에 구분되도록 배경을 진하게 + 카드 전체를 흐리게 처리 (네온 테두리는 미해결 질문 전용이므로 제외) */ +/* 해결된 질문: 미해결 질문과 한눈에 구분되도록 배경을 연한 회색으로 + 카드 전체를 흐리게 처리 (초록 테두리는 미해결 질문 전용이므로 제외) */ .questionCardResolved { - background: var(--gray200); + background: var(--gray50); opacity: 0.6; border-color: transparent; box-shadow: 1px 2px 3px 0 rgba(0, 0, 0, 0.25); } .questionCard:hover { - box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.15), 0 0 6px 0 rgba(11, 236, 18, 0.35); + box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.15); } .questionCardResolved:hover { From b7f50d21ea3bd9d6acec8b46c1c06cfb968805d5 Mon Sep 17 00:00:00 2001 From: lilyyang0077 Date: Fri, 19 Jun 2026 14:57:09 +0900 Subject: [PATCH 7/8] =?UTF-8?q?feat:=20=EB=B0=98=EC=9D=91=ED=98=95=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/qna/QnAListPage.js | 9 ++- frontend/src/pages/qna/QnAListPage.module.css | 61 +++++++++++++++++-- frontend/src/pages/qna/QnAMainPage.js | 2 +- frontend/src/pages/qna/QnAMainPage.module.css | 40 +++++++++--- package-lock.json | 60 ++++++++++++++++++ package.json | 5 ++ 6 files changed, 163 insertions(+), 14 deletions(-) create mode 100644 package-lock.json create mode 100644 package.json diff --git a/frontend/src/pages/qna/QnAListPage.js b/frontend/src/pages/qna/QnAListPage.js index 621da1a..33dfc9c 100644 --- a/frontend/src/pages/qna/QnAListPage.js +++ b/frontend/src/pages/qna/QnAListPage.js @@ -9,6 +9,7 @@ import { OBtn, XBtn, CommentCommentArraw, SumitBtn, StaffCheck, ImgPreview, DAY_PART_KO, DAY_OF_WEEK_KO, uploadImages, } from '../../utils/qnaUtils'; +import { motion, AnimatePresence } from 'framer-motion'; const MAX_VISIBLE_COMMENTS = 3; const POPULAR_LIKE_THRESHOLD = 5; @@ -758,7 +759,13 @@ function QnAListPage() { disabled={!understanding?.hasOlder}> - + 35 + ? styles.longText + : '' + }`} + > {understanding.current.content} ({understanding.current.respondedCount ?? 0}/ diff --git a/frontend/src/pages/qna/QnAListPage.module.css b/frontend/src/pages/qna/QnAListPage.module.css index e190d07..da0cc96 100644 --- a/frontend/src/pages/qna/QnAListPage.module.css +++ b/frontend/src/pages/qna/QnAListPage.module.css @@ -153,6 +153,11 @@ font-size: 24px; font-weight: 500; color: var(--black); + /* padding: 12px */ +} + +.longText { + font-size: 19px; } .understandCount { @@ -638,7 +643,13 @@ } .understandName { - font-size: 20px; + font-size: 18px; + } + + .longText { + font-size: 17px; + margin: 15px; + } .understandCount { @@ -655,6 +666,40 @@ } } +/* ════════════════════════════════════════ + 반응형 — (600px 이하) +════════════════════════════════════════ */ +@media (max-width: 600px) { + .understandBar { + padding: 10px 12px; + gap: 4px; + } + + .understandName { + font-size: 18px; + margin: 6px + } + + .longText { + font-size: 15px; + margin: 8px + } + + .understandCount { + font-size: 15px; + } + + .oxBtn { + width: 32px; + height: 32px; + } + + .arrowBtn svg { + width: 24px; + height: 24px; + } +} + /* ════════════════════════════════════════ 반응형 — 모바일 (480px 이하) @@ -681,12 +726,18 @@ .understandBar { height: auto; min-height: 48px; - padding: 8px 10px; + padding: 12px 12px; flex-wrap: wrap; } .understandName { - font-size: 17px; + font-size: 18px; + margin: 6px + } + + .longText { + font-size: 15px; + margin: 8px } .understandCount { @@ -694,8 +745,8 @@ } .oxBtn { - width: 30px; - height: 30px; + width: 29px; + height: 29px; font-size: 12px; margin: 0 2px; } diff --git a/frontend/src/pages/qna/QnAMainPage.js b/frontend/src/pages/qna/QnAMainPage.js index c2c650c..83b14db 100644 --- a/frontend/src/pages/qna/QnAMainPage.js +++ b/frontend/src/pages/qna/QnAMainPage.js @@ -93,7 +93,7 @@ function QNAMainPage() {
))} diff --git a/frontend/src/pages/qna/QnAMainPage.module.css b/frontend/src/pages/qna/QnAMainPage.module.css index 006c275..0d10f08 100644 --- a/frontend/src/pages/qna/QnAMainPage.module.css +++ b/frontend/src/pages/qna/QnAMainPage.module.css @@ -39,12 +39,12 @@ width: 356px; height: 148px; - border: 1px solid rgba(0,0,0,0.04); + border: 1px solid rgba(0,0,0,0.06); box-shadow: 0 1px 0 rgba(255,255,255,0.8) inset, - 0 6px 14px rgba(0,0,0,0.08), - 0 2px 4px rgba(0,0,0,0.04); + 0 3px 8px rgba(0,0,0,0.10), + 0 1px 3px rgba(0,0,0,0.06); cursor: pointer; @@ -56,7 +56,10 @@ } .card:hover { - box-shadow: 4px 4px 10px 0 rgba(0, 0, 0, 0.2); + box-shadow: + 0 1px 0 rgba(255,255,255,0.8) inset, + 0 6px 12px rgba(0,0,0,0.14), + 0 2px 5px rgba(0,0,0,0.08); } .card:hover .cardTitle { @@ -96,10 +99,18 @@ /* ── 지난 세션 목록 ── */ .icon { + display: inline-block; + position: relative; + top: -2px; + margin-right: 20px; transition: color 0.2s; } +.enterIcon { + font-size: 20px; +} + .list { display: flex; flex-direction: column; @@ -235,6 +246,7 @@ .card { width: min(356px, 80%); + min-height: 140px; padding: 14px 12px; } @@ -254,6 +266,10 @@ } .listItem { + width: 88%; + margin: 0 auto; + min-height: 40px; + padding: 12px; gap: 8px; } @@ -263,14 +279,24 @@ } .listWeek { - font-size: 13px; + font-size: 12px; } - .icon { - margin-right: 10px; + .cardTitle .icon { + margin-right: 6px; + } + + .listItem .icon { + margin-left: 8px; + margin-right: 12px; + margin-top: 2px; flex-shrink: 0; } + .enterIcon { + font-size: 18px; + } + .enterBtn { padding: 4px; } diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..542d230 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,60 @@ +{ + "name": "piroin", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "framer-motion": "^12.40.0" + } + }, + "node_modules/framer-motion": { + "version": "12.40.0", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.40.0.tgz", + "integrity": "sha512-uaBd3qC1v3KQqBEjwTUd183K6PbS+j0yR9w9VmEOLWA/tnUcSn8Xa3uck7t4dgpDoUss8xQTcj8W2L07lrnLFg==", + "license": "MIT", + "dependencies": { + "motion-dom": "^12.40.0", + "motion-utils": "^12.39.0", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/motion-dom": { + "version": "12.40.0", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.40.0.tgz", + "integrity": "sha512-HxU3ZaBwNPVQUBQf1xxgq+7JrPNZvjLVxgbpEZL7RrWJnsxOf0/OM+yrHG9ogLQ31Do/r57Oz2gQWPK+6q62mg==", + "license": "MIT", + "dependencies": { + "motion-utils": "^12.39.0" + } + }, + "node_modules/motion-utils": { + "version": "12.39.0", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.39.0.tgz", + "integrity": "sha512-8nadJAJjTtqRkmRF36FoJTrywK9nnFmnPwnSMyxaOCU7GDjN9RTMJIxx9De8ErM+vpPhMccr/6fo5WciyQLnMQ==", + "license": "MIT" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..00f24cb --- /dev/null +++ b/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "framer-motion": "^12.40.0" + } +} From 30d1bf80ef7e6520eb5ded872d9e55787317633d Mon Sep 17 00:00:00 2001 From: lilyyang0077 Date: Fri, 19 Jun 2026 16:13:03 +0900 Subject: [PATCH 8/8] =?UTF-8?q?feat:=20border=20radius=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/qna/QnAListPage.module.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pages/qna/QnAListPage.module.css b/frontend/src/pages/qna/QnAListPage.module.css index 0d7e421..10ea886 100644 --- a/frontend/src/pages/qna/QnAListPage.module.css +++ b/frontend/src/pages/qna/QnAListPage.module.css @@ -228,7 +228,7 @@ padding: 16px 18px; cursor: pointer; transition: box-shadow 0.2s; - border-radius: 30px; + border-radius: 20px; background: var(--white); box-shadow: 0 1px 4px rgba(0,0,0,0.06),