diff --git a/frontend/src/pages/pirocheck/students/StudentList.module.css b/frontend/src/pages/pirocheck/students/StudentList.module.css index 4c17539..d00d43b 100644 --- a/frontend/src/pages/pirocheck/students/StudentList.module.css +++ b/frontend/src/pages/pirocheck/students/StudentList.module.css @@ -21,7 +21,6 @@ align-items: center; background: var(--gray600); border-radius: 10px; - overflow: hidden; width: 480px; max-width: calc(100vw - 56px); margin-bottom: 30px; @@ -31,6 +30,7 @@ .searchInput { flex: 1; + min-width: 0; background: transparent; border: none; outline: none; diff --git a/frontend/src/pages/qna/QnADetailPage.js b/frontend/src/pages/qna/QnADetailPage.js index f2b3a9f..bef7cfb 100644 --- a/frontend/src/pages/qna/QnADetailPage.js +++ b/frontend/src/pages/qna/QnADetailPage.js @@ -92,6 +92,7 @@ function QnADetailPage() { const [selectedImages, setSelectedImages] = useState([]); // 여러 장 const [imagePreviews, setImagePreviews] = useState([]); // 여러 장 미리보기 const fileInputRef = useRef(null); + const commentTextareaRef = useRef(null); // ── 댓글 수정 상태 ─────────────────────────────── const [commentMenuId, setCommentMenuId] = useState(null); @@ -420,6 +421,7 @@ function QnADetailPage() { setImagePreviews([]); // 로컬 상태에 blob URL을 직접 넣으면 새로고침 시 이미지가 깨지므로 // 등록 직후 fetchQuestion으로 서버의 정식 URL을 받아온다. + if (commentTextareaRef.current) commentTextareaRef.current.style.height = 'auto'; await fetchQuestion(); } } catch (err) { @@ -709,14 +711,25 @@ function QnADetailPage() { style={{ display: 'none' }} onChange={handleImageSelect} /> - setCommentText(e.target.value)} - onKeyDown={e => { if (e.key === 'Enter' && !e.nativeEvent.isComposing) handleCommentSubmit(); }} + onChange={e => { + setCommentText(e.target.value); + e.target.style.height = 'auto'; + e.target.style.height = `${Math.min(e.target.scrollHeight, 150)}px`; + }} + onKeyDown={e => { + if (e.key === 'Enter' && !e.shiftKey && !e.nativeEvent.isComposing) { + e.preventDefault(); + handleCommentSubmit(); + } + }} onPaste={handlePaste} + rows={1} disabled={isSubmitting} /> { questionGroupsRef.current = groups; @@ -519,6 +521,8 @@ function QnAListPage() { setCommentImages(prev => ({ ...prev, [questionId]: [] })); setCommentImagePreviews(prev => ({ ...prev, [questionId]: [] })); setCommentOpenId(null); + const textareaEl = commentTextareaRefs.current[questionId]; + if (textareaEl) textareaEl.style.height = 'auto'; } } catch (err) { console.error('댓글 등록 실패:', err); @@ -615,6 +619,7 @@ function QnAListPage() { setSelectedImages([]); setImagePreviews([]); fetchQuestions(understandingIndex); + if (newQuestionTextareaRef.current) newQuestionTextareaRef.current.style.height = 'auto'; } } catch (err) { console.error('질문 등록 실패:', err); @@ -641,6 +646,7 @@ function QnAListPage() { setNewQuestion(''); setUnderstandingIndex(0); fetchQuestions(0); + if (newQuestionTextareaRef.current) newQuestionTextareaRef.current.style.height = 'auto'; } } catch (err) { console.error('이해도 등록 실패:', err); @@ -842,7 +848,8 @@ function QnAListPage() { - {comment.content} + + {comment.content} {comment.hasImage && ( + - { commentTextareaRefs.current[question.questionId] = el; }} className={styles.commentInput} placeholder="댓글을 입력해주세요..." value={commentInputs[question.questionId] || ''} - onChange={e => handleCommentChange(question.questionId, e.target.value)} - onKeyDown={e => { if (e.key === 'Enter' && !e.nativeEvent.isComposing) handleCommentSubmit(e, question.questionId); }} + onChange={e => { + handleCommentChange(question.questionId, e.target.value); + e.target.style.height = 'auto'; + e.target.style.height = `${Math.min(e.target.scrollHeight, 120)}px`; + }} + onKeyDown={e => { + if (e.key === 'Enter' && !e.shiftKey && !e.nativeEvent.isComposing) { + e.preventDefault(); + handleCommentSubmit(e, question.questionId); + } + }} onPaste={e => handleCommentPaste(e, question.questionId)} + rows={1} autoFocus /> > )} - setNewQuestion(e.target.value)} + onChange={e => { + setNewQuestion(e.target.value); + e.target.style.height = 'auto'; + e.target.style.height = `${Math.min(e.target.scrollHeight, 150)}px`; + }} onKeyDown={e => { - if (e.key === 'Enter' && !e.nativeEvent.isComposing) isStaff ? handleNewUnderstandCheck() : handleNewQuestion(); + if (e.key === 'Enter' && !e.shiftKey && !e.nativeEvent.isComposing) { + e.preventDefault(); + isStaff ? handleNewUnderstandCheck() : handleNewQuestion(); + } }} onPaste={handleNewQuestionPaste} + rows={1} disabled={isSubmitting} />