Skip to content

Commit 92dd5bc

Browse files
committed
refactor: 검색 결과 강조 및 카드 UI 개선
- 검색 쿼리 텍스트 강조(highlight) 기능 추가 - TermCard에 첫 번째 동의어와 정의 미리보기 추가 - 카드 레이아웃 및 타이포그래피 개선 - 검색 페이지 반응형 디자인 강화
1 parent 5cbb39e commit 92dd5bc

8 files changed

Lines changed: 331 additions & 163 deletions

File tree

src/components/AlphabetNavigation.tsx

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,50 @@ import { Box, Chip } from '@mui/material'
22

33
interface AlphabetNavigationProps {
44
onLetterClick: (letter: string) => void
5+
onClearFilter: () => void
56
activeLetter: string | null
67
}
78

89
const ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('')
910

10-
export function AlphabetNavigation({ onLetterClick, activeLetter }: AlphabetNavigationProps) {
11+
export function AlphabetNavigation({ onLetterClick, onClearFilter, activeLetter }: AlphabetNavigationProps) {
1112
return (
1213
<Box
1314
role="navigation"
1415
aria-label="알파벳 탐색"
1516
sx={{
17+
position: 'sticky',
18+
top: 0,
19+
zIndex: 10,
20+
backgroundColor: 'rgba(250,250,250,0.9)',
21+
backdropFilter: 'blur(8px)',
22+
borderBottom: '1px solid rgba(0,0,0,0.08)',
23+
py: 1.5,
24+
px: 2,
1625
display: 'flex',
1726
gap: 1,
1827
justifyContent: { xs: 'flex-start', sm: 'center' },
1928
mb: 3,
2029
overflowX: { xs: 'auto', sm: 'visible' },
2130
flexWrap: { xs: 'nowrap', sm: 'wrap' },
22-
pb: { xs: 1, sm: 0 },
2331
'&::-webkit-scrollbar': { height: 4 },
2432
'&::-webkit-scrollbar-thumb': { backgroundColor: 'rgba(0,0,0,0.2)', borderRadius: 2 },
2533
}}
2634
>
35+
<Chip
36+
label="전체"
37+
onClick={onClearFilter}
38+
color={activeLetter === null ? 'primary' : 'default'}
39+
variant={activeLetter === null ? 'filled' : 'outlined'}
40+
aria-label="전체 용어 보기"
41+
aria-pressed={activeLetter === null}
42+
sx={{
43+
minWidth: 44,
44+
cursor: 'pointer',
45+
fontWeight: activeLetter === null ? 700 : 400,
46+
flexShrink: 0,
47+
}}
48+
/>
2749
{ALPHABET.map((letter) => (
2850
<Chip
2951
key={letter}
@@ -34,7 +56,7 @@ export function AlphabetNavigation({ onLetterClick, activeLetter }: AlphabetNavi
3456
aria-label={`${letter}로 시작하는 용어 필터`}
3557
aria-pressed={activeLetter === letter}
3658
sx={{
37-
minWidth: 40,
59+
minWidth: 44,
3860
cursor: 'pointer',
3961
fontWeight: activeLetter === letter ? 700 : 400,
4062
flexShrink: 0,

src/components/HeroSection.tsx

Lines changed: 54 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,81 @@
1-
import { Box, Typography, Container, Button } from '@mui/material'
2-
import { useNavigate } from 'react-router-dom'
1+
import { Box, Typography, Container, TextField, InputAdornment, IconButton } from '@mui/material'
2+
import SearchIcon from '@mui/icons-material/Search'
3+
import CloseIcon from '@mui/icons-material/Close'
34

45
interface HeroSectionProps {
56
totalTerms: number
67
totalMeanings: number
8+
query: string
9+
onQueryChange: (query: string) => void
710
}
811

9-
export function HeroSection({ totalTerms, totalMeanings }: HeroSectionProps) {
10-
const navigate = useNavigate()
11-
12+
export function HeroSection({ totalTerms, totalMeanings, query, onQueryChange }: HeroSectionProps) {
1213
return (
1314
<Box
1415
sx={{
15-
background: 'linear-gradient(135deg, #ee4c2c 0%, #262626 100%)',
16+
background: 'linear-gradient(135deg, #ee4c2c 0%, #1a1a1a 100%)',
1617
color: 'white',
17-
py: 8,
18+
pt: { xs: 10, md: 11 },
19+
pb: { xs: 4, md: 5 },
1820
mb: 4,
1921
}}
2022
>
2123
<Container maxWidth="md">
2224
<Typography
23-
variant="h2"
25+
variant="h3"
2426
component="h1"
2527
align="center"
2628
gutterBottom
2729
sx={{ fontWeight: 700 }}
2830
>
2931
AI/ML 용어집
3032
</Typography>
31-
<Typography variant="h6" align="center" sx={{ mb: 3, opacity: 0.95 }}>
32-
인공지능과 머신러닝 용어의 한국어 번역을 표준화합니다
33+
<Typography variant="h6" align="center" sx={{ mb: 2, opacity: 0.95 }}>
34+
AI/ML 한국어 번역 표준화
3335
</Typography>
34-
<Box
35-
sx={{
36-
display: 'flex',
37-
justifyContent: 'center',
38-
gap: { xs: 3, sm: 4 },
39-
flexDirection: { xs: 'column', sm: 'row' },
40-
alignItems: 'center',
41-
}}
42-
>
43-
<Box sx={{ textAlign: 'center' }}>
44-
<Typography variant="h4" sx={{ fontWeight: 700 }}>
45-
{totalTerms}
46-
</Typography>
47-
<Typography variant="body2" sx={{ opacity: 0.9 }}>
48-
총 용어 수
49-
</Typography>
50-
</Box>
51-
<Box sx={{ textAlign: 'center' }}>
52-
<Typography variant="h4" sx={{ fontWeight: 700 }}>
53-
{totalMeanings}
54-
</Typography>
55-
<Typography variant="body2" sx={{ opacity: 0.9 }}>
56-
총 의미 수
57-
</Typography>
58-
</Box>
59-
</Box>
60-
<Box sx={{ display: 'flex', justifyContent: 'center' }}>
61-
<Button
36+
<Typography variant="body2" align="center" sx={{ mb: 3, opacity: 0.85 }}>
37+
{totalTerms} 용어 · {totalMeanings} 의미
38+
</Typography>
39+
<Box sx={{ maxWidth: 600, mx: 'auto' }}>
40+
<TextField
41+
fullWidth
6242
variant="outlined"
63-
onClick={() => navigate('/about')}
64-
sx={{ mt: 3, color: 'white', borderColor: 'rgba(255,255,255,0.5)', '&:hover': { borderColor: 'white', backgroundColor: 'rgba(255,255,255,0.1)' } }}
65-
>
66-
프로젝트 소개
67-
</Button>
43+
placeholder="영어 용어 또는 한글 번역으로 검색하세요..."
44+
aria-label="용어 검색"
45+
value={query}
46+
onChange={(e) => onQueryChange(e.target.value)}
47+
slotProps={{
48+
input: {
49+
startAdornment: (
50+
<InputAdornment position="start">
51+
<SearchIcon sx={{ color: 'text.secondary' }} />
52+
</InputAdornment>
53+
),
54+
endAdornment: query ? (
55+
<InputAdornment position="end">
56+
<IconButton
57+
size="small"
58+
onClick={() => onQueryChange('')}
59+
aria-label="검색어 지우기"
60+
>
61+
<CloseIcon fontSize="small" />
62+
</IconButton>
63+
</InputAdornment>
64+
) : null,
65+
},
66+
}}
67+
sx={{
68+
'& .MuiOutlinedInput-root': {
69+
backgroundColor: 'white',
70+
borderRadius: '28px',
71+
boxShadow: '0 4px 20px rgba(0,0,0,0.15)',
72+
'& fieldset': { border: 'none' },
73+
},
74+
'& .MuiOutlinedInput-input': {
75+
py: 1.5,
76+
},
77+
}}
78+
/>
6879
</Box>
6980
</Container>
7081
</Box>

src/components/Layout.tsx

Lines changed: 53 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from 'react'
22
import { AppBar, Toolbar, Typography, Container, Box, IconButton, Link, Button } from '@mui/material'
33
import GitHubIcon from '@mui/icons-material/GitHub'
4+
import SearchIcon from '@mui/icons-material/Search'
45
import { useNavigate, useLocation } from 'react-router-dom'
56

67
interface LayoutProps {
@@ -12,34 +13,51 @@ export function Layout({ children }: LayoutProps): React.ReactNode {
1213
const location = useLocation()
1314
const isHomePage = location.pathname === '/' || location.pathname === ''
1415

16+
const handleSearchClick = () => {
17+
if (isHomePage) {
18+
window.scrollTo({ top: 0, behavior: 'smooth' })
19+
} else {
20+
navigate('/')
21+
}
22+
}
23+
1524
return (
1625
<Box sx={{ display: 'flex', flexDirection: 'column', minHeight: '100vh' }}>
17-
{!isHomePage && (
18-
<AppBar position="static" elevation={2}>
19-
<Toolbar>
20-
<Typography
21-
variant="h6"
22-
component="div"
23-
sx={{ flexGrow: 1, cursor: 'pointer', fontWeight: 600 }}
24-
onClick={() => navigate('/')}
25-
>
26-
AI/ML 용어집
27-
</Typography>
28-
<Button color="inherit" onClick={() => navigate('/about')} sx={{ mr: 1 }}>
29-
소개
30-
</Button>
31-
<IconButton
32-
color="inherit"
33-
href="https://github.com/PyTorchKorea/kr-terms-poc"
34-
target="_blank"
35-
rel="noopener noreferrer"
36-
aria-label="GitHub 저장소"
37-
>
38-
<GitHubIcon />
39-
</IconButton>
40-
</Toolbar>
41-
</AppBar>
42-
)}
26+
<AppBar
27+
position={isHomePage ? 'absolute' : 'static'}
28+
elevation={isHomePage ? 0 : 2}
29+
sx={{
30+
backgroundColor: isHomePage ? 'transparent' : '#262626',
31+
width: '100%',
32+
zIndex: isHomePage ? 20 : undefined,
33+
}}
34+
>
35+
<Toolbar>
36+
<Typography
37+
variant="h6"
38+
component="div"
39+
sx={{ flexGrow: 1, cursor: 'pointer', fontWeight: 600 }}
40+
onClick={() => navigate('/')}
41+
>
42+
AI/ML 용어집
43+
</Typography>
44+
<IconButton color="inherit" onClick={handleSearchClick} aria-label="검색" sx={{ mr: 0.5 }}>
45+
<SearchIcon />
46+
</IconButton>
47+
<Button color="inherit" onClick={() => navigate('/about')} sx={{ mr: 1 }}>
48+
소개
49+
</Button>
50+
<IconButton
51+
color="inherit"
52+
href="https://github.com/PyTorchKorea/kr-terms-poc"
53+
target="_blank"
54+
rel="noopener noreferrer"
55+
aria-label="GitHub 저장소"
56+
>
57+
<GitHubIcon />
58+
</IconButton>
59+
</Toolbar>
60+
</AppBar>
4361

4462
<Box component="main" sx={{ flex: 1 }}>
4563
{isHomePage ? (
@@ -52,7 +70,7 @@ export function Layout({ children }: LayoutProps): React.ReactNode {
5270
<Box
5371
component="footer"
5472
sx={{
55-
py: 4,
73+
py: 3,
5674
px: 2,
5775
mt: 'auto',
5876
bgcolor: '#262626',
@@ -68,21 +86,26 @@ export function Layout({ children }: LayoutProps): React.ReactNode {
6886
href="https://github.com/PyTorchKorea/kr-terms-poc"
6987
target="_blank"
7088
rel="noopener noreferrer"
71-
sx={{ color: '#ee4c2c', '&:hover': { color: '#f26849' } }}
89+
sx={{ color: '#ee4c2c', '&:hover': { color: '#f26849' }, minHeight: 44, display: 'inline-flex', alignItems: 'center' }}
7290
underline="hover"
7391
>
7492
GitHub에서 기여하기
7593
</Link>
7694
{' · '}
77-
<Link component="button" onClick={() => navigate('/about')} sx={{ color: '#ee4c2c', '&:hover': { color: '#f26849' } }} underline="hover">
95+
<Link
96+
component="button"
97+
onClick={() => navigate('/about')}
98+
sx={{ color: '#ee4c2c', '&:hover': { color: '#f26849' }, minHeight: 44, display: 'inline-flex', alignItems: 'center' }}
99+
underline="hover"
100+
>
78101
프로젝트 소개
79102
</Link>
80103
{' · '}
81104
<Link
82105
href="https://github.com/PyTorchKorea/kr-terms-poc/issues"
83106
target="_blank"
84107
rel="noopener noreferrer"
85-
sx={{ color: '#ee4c2c', '&:hover': { color: '#f26849' } }}
108+
sx={{ color: '#ee4c2c', '&:hover': { color: '#f26849' }, minHeight: 44, display: 'inline-flex', alignItems: 'center' }}
86109
underline="hover"
87110
>
88111
이슈 제기

0 commit comments

Comments
 (0)