Skip to content

Commit 05cc262

Browse files
authored
fix: Quiz, Room 목록 검색 시, 원본 목록을 조작하는 문제 수정 (#7)
1 parent 442150d commit 05cc262

File tree

5 files changed

+194
-121
lines changed

5 files changed

+194
-121
lines changed

src/layout/main/Layout.module.scss

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,16 @@
1212
overflow: hidden; // 넘치는 부분 숨김
1313
}
1414

15+
html {
16+
scrollbar-gutter: stable;
17+
}
18+
19+
body {
20+
overflow-y: scroll; /* 스크롤바를 항상 보이게 해서 너비 변화 없음 */
21+
}
22+
23+
*,
24+
*::before,
25+
*::after {
26+
box-sizing: border-box;
27+
}

src/pages/quiz/QuizDetailModal.js

Lines changed: 66 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -48,81 +48,99 @@ const QuizDetailModal = ({ isOpen, onClose, quiz }) => {
4848
<Modal.Title className="fw-bold text-dark fs-4">
4949
{quiz.title}
5050
</Modal.Title>
51-
<span className="text-muted">
51+
<span className="text-muted fs-6">
5252
총 문제 수 : {quiz.numberOfQuestion} (개)
5353
</span>
5454
</div>
5555
</Modal.Header>
5656

5757
<Modal.Body className="px-4 py-3">
5858
{/* 퀴즈 설명 박스 */}
59-
<div
60-
className="border rounded-3 p-4 mb-4 bg-light"
61-
style={{
62-
minHeight: '120px',
63-
borderColor: '#dee2e6'
64-
}}
65-
>
66-
<div className="text-center text-muted mb-3 fw-medium">
59+
<div className="mb-4">
60+
<div
61+
className="text-muted mb-2 fw-medium d-flex align-items-center"
62+
style={{ fontSize: '0.9rem' }}
63+
>
64+
<span className="me-2">📝</span>
6765
퀴즈 설명
6866
</div>
69-
<div className="text-dark text-center">
70-
{quiz.description}
67+
<div
68+
className="border rounded-3 p-3 bg-white"
69+
style={{
70+
minHeight: '80px',
71+
borderColor: '#e9ecef',
72+
backgroundColor: '#f8f9fa !important'
73+
}}
74+
>
75+
<div className="text-dark" style={{ lineHeight: '1.5' }}>
76+
{quiz.description || '설명이 없습니다.'}
77+
</div>
7178
</div>
7279
</div>
7380

7481
{/* 퀴즈 썸네일 박스 */}
75-
<div
76-
className="border rounded-3 p-4 bg-light d-flex flex-column align-items-center justify-content-center"
77-
style={{
78-
minHeight: '200px',
79-
borderColor: '#dee2e6'
80-
}}
81-
>
82-
<div className="text-center text-muted mb-3 fw-medium">
82+
<div>
83+
<div
84+
className="text-muted mb-2 fw-medium d-flex align-items-center"
85+
style={{ fontSize: '0.9rem' }}
86+
>
87+
<span className="me-2">🖼️</span>
8388
퀴즈 썸네일
8489
</div>
85-
{quiz.thumbnailUrl ? (
86-
<Image
87-
src={quiz.thumbnailUrl}
88-
alt="퀴즈 썸네일"
89-
className="rounded"
90-
style={{
91-
maxWidth: '150px',
92-
maxHeight: '150px',
93-
objectFit: 'cover'
94-
}}
95-
/>
96-
) : (
97-
<div className="text-muted" style={{fontSize: '3rem'}}>
98-
📄
99-
</div>
100-
)}
90+
<div
91+
className="border rounded-3 p-3 bg-white d-flex flex-column align-items-center justify-content-center"
92+
style={{
93+
minHeight: '160px',
94+
borderColor: '#e9ecef',
95+
backgroundColor: '#f8f9fa !important'
96+
}}
97+
>
98+
{quiz.thumbnailUrl ? (
99+
<Image
100+
src={quiz.thumbnailUrl}
101+
alt="퀴즈 썸네일"
102+
className="rounded shadow-sm"
103+
style={{
104+
maxWidth: '120px',
105+
maxHeight: '120px',
106+
objectFit: 'cover'
107+
}}
108+
/>
109+
) : (
110+
<div className="text-center">
111+
<div className="text-muted mb-2" style={{fontSize: '2.5rem'}}>
112+
📄
113+
</div>
114+
<small className="text-muted">썸네일이 없습니다</small>
115+
</div>
116+
)}
117+
</div>
101118
</div>
102119
</Modal.Body>
103120

104121
<Modal.Footer className="border-0 d-flex justify-content-between align-items-center pt-2">
105-
<span className="text-dark">
106-
퀴즈 제작자 : {quiz.creatorNickname}
107-
</span>
108-
{isEditable && <Stack direction="horizontal" gap={3}>
122+
<div className="d-flex align-items-center">
123+
<span className="text-muted me-2" style={{ fontSize: '0.9rem' }}>👤</span>
124+
<span className="text-dark fw-medium">
125+
{quiz.creatorNickname}
126+
</span>
127+
</div>
128+
{isEditable && <Stack direction="horizontal" gap={2}>
109129
<Button
110130
variant="outline-primary"
111131
onClick={() => navigate(`${quiz.quizId}/edit`)}
112-
className="px-4 py-2 fw-medium rounded-3"
132+
className="px-3 py-2 fw-medium rounded-3"
133+
style={{ fontSize: '0.9rem' }}
113134
>
114-
퀴즈 수정
135+
수정
115136
</Button>
116137
<Button
117-
variant="dark"
138+
variant="danger"
118139
onClick={handleDeleteQuizClick}
119-
className="px-4 py-2 fw-medium rounded-3"
120-
style={{
121-
backgroundColor: '#ff1e1e',
122-
borderColor: '#ff1e1e'
123-
}}
140+
className="px-3 py-2 fw-medium rounded-3"
141+
style={{ fontSize: '0.9rem' }}
124142
>
125-
퀴즈 삭제
143+
삭제
126144
</Button>
127145
</Stack>}
128146
</Modal.Footer>

src/pages/quiz/QuizList.js

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,23 @@ const QuizList = () => {
4545

4646
// 검색 기능 구현
4747
const handleSearch = () => {
48-
if (isEmptyOrNull(keyword.trim())) { return; }
49-
if (selectedSearchType.value === 'title') {
50-
setQueryParams({ title: keyword, page: 1, size: 8, creator: '' });
51-
} else {
52-
setQueryParams({ title: '', page: 1, size: 8, creator: keyword });
53-
}
54-
};
48+
const trimmed = keyword.trim();
49+
if (isEmptyOrNull(trimmed)) {
50+
// 빈 검색어면 1페이지, 전체 목록으로 되돌림
51+
setQueryParams({
52+
page: 1,
53+
size: 8,
54+
title: '',
55+
creator: '',
56+
});
57+
return;
58+
}
59+
if (selectedSearchType.value === 'title') {
60+
setQueryParams({ title: trimmed, page: 1, size: 8, creator: '' });
61+
} else {
62+
setQueryParams({ title: '', page: 1, size: 8, creator: trimmed });
63+
}
64+
};
5565

5666
// 검색 버튼 클릭 이벤트
5767
const handleSearchClick = (e) => {
@@ -60,14 +70,33 @@ const QuizList = () => {
6070
handleSearch();
6171
};
6272

63-
// 엔터키 이벤트 처리
73+
// 엔터키 이벤트 처리 - IME 처리 추가
6474
const handleKeyDown = (e) => {
6575
if (e.key === "Enter") {
6676
e.preventDefault();
67-
handleSearch();
77+
// IME 조합 중이 아닐 때만 검색 실행
78+
if (!e.target.composing) {
79+
handleSearch();
80+
}
6881
}
6982
};
7083

84+
// 한글 입력 처리
85+
const handleCompositionStart = (e) => {
86+
e.target.composing = true;
87+
};
88+
89+
const handleCompositionEnd = (e) => {
90+
e.target.composing = false;
91+
// 조합이 끝난 후에는 별도 처리 없이 onChange가 자동으로 처리
92+
};
93+
94+
// 입력값 변경 처리
95+
const handleInputChange = (e) => {
96+
// 입력값은 항상 업데이트 (사용자가 입력하는 것을 볼 수 있도록)
97+
setKeyword(e.target.value);
98+
};
99+
71100
// 퀴즈 카드 클릭 이벤트
72101
const handleQuizCardClick = (quiz) => {
73102
setSelectedQuiz(quiz);
@@ -93,7 +122,6 @@ const QuizList = () => {
93122
title: '',
94123
creator: '',
95124
});
96-
// setSearchOn(false);
97125
};
98126

99127
return (
@@ -115,8 +143,10 @@ const QuizList = () => {
115143
type="text"
116144
placeholder="검색어를 입력하세요..."
117145
value={keyword}
118-
onChange={(e) => setKeyword(e.target.value)}
146+
onChange={handleInputChange}
119147
onKeyDown={handleKeyDown}
148+
onCompositionStart={handleCompositionStart}
149+
onCompositionEnd={handleCompositionEnd}
120150
className={`flex-fill ${styles.searchInput}`}
121151
/>
122152
{keyword && (
@@ -150,7 +180,7 @@ const QuizList = () => {
150180
)}
151181

152182
{/* 퀴즈 카드 그리드 */}
153-
{data?.quiz.length > 0 ? (
183+
{data?.quiz?.length > 0 ? (
154184
<div className="mb-5">
155185
{data?.quiz.reduce((rows, _, index, arr) => {
156186
if (index % 4 === 0) {
@@ -182,6 +212,7 @@ const QuizList = () => {
182212
<Button
183213
variant="outline-primary"
184214
onClick={() => {
215+
setKeyword('');
185216
setQueryParams({ title: '', page: 1, size: 8, creator: '' });
186217
}}
187218
style={{
@@ -196,11 +227,12 @@ const QuizList = () => {
196227
</Button>
197228
</div>
198229
)}
199-
<PaginationNavigator
230+
231+
<PaginationNavigator
200232
currentPage={data?.currentPage}
201233
totalPages={data?.totalPages}
202234
onPageChange={handlePageChange}
203-
/>
235+
/>
204236

205237
{/* 퀴즈 상세 모달 */}
206238
<QuizDetailModal

src/pages/rank/rank.module.scss

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,4 +533,12 @@
533533
font-size: 0.9rem;
534534
}
535535
}
536+
}
537+
538+
html {
539+
scrollbar-gutter: stable;
540+
}
541+
542+
body {
543+
overflow-y: scroll;
536544
}

0 commit comments

Comments
 (0)