Skip to content

Commit c5d74bd

Browse files
committed
improve paper card layout
1 parent c8d8bff commit c5d74bd

File tree

1 file changed

+224
-103
lines changed

1 file changed

+224
-103
lines changed

src/components/PaperCard.jsx

Lines changed: 224 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import {
88
Box,
99
IconButton,
1010
Tooltip,
11-
Badge,
11+
useMediaQuery,
12+
useTheme,
1213
} from '@mui/material';
1314
import { ContentCopy } from '@mui/icons-material';
1415
import { styled } from '@mui/material/styles';
@@ -30,16 +31,10 @@ const StyledCard = styled(Card)(({ theme }) => ({
3031
const PaperTitle = styled(Typography)(({ theme }) => ({
3132
fontWeight: 600,
3233
lineHeight: 1.1,
33-
marginBottom: theme.spacing(0.25),
34+
marginBottom: theme.spacing(0.1),
3435
fontSize: '1rem',
3536
}));
3637

37-
const AuthorText = styled(Typography)(({ theme }) => ({
38-
color: theme.palette.text.secondary,
39-
fontSize: '0.8rem',
40-
fontWeight: 500,
41-
}));
42-
4338
const openInNewTab = url => {
4439
// Only run in client-side environment
4540
if (typeof window !== 'undefined') {
@@ -73,6 +68,9 @@ const getLabelColor = label => {
7368
};
7469

7570
const PaperCard = ({ paper, selectedLabels = [], onLabelClick }) => {
71+
const theme = useTheme();
72+
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
73+
7674
const mainPublication =
7775
paper.publications?.find(pub => pub.name !== 'arXiv') ||
7876
paper.publications?.[0];
@@ -113,88 +111,248 @@ const PaperCard = ({ paper, selectedLabels = [], onLabelClick }) => {
113111
return (
114112
<StyledCard>
115113
<CardContent sx={{ py: 0.5, px: 1, '&:last-child': { pb: 0.5 } }}>
116-
{/* Header with title, labels, and BibTeX action */}
114+
{/* Header with title */}
117115
<Stack
118116
direction="row"
119117
justifyContent="space-between"
120118
alignItems="flex-start"
121-
sx={{ mb: 0.5 }}
119+
sx={{ mb: 0.0 }}
122120
>
123-
<Box sx={{ flex: 1 }}>
121+
<Box sx={{ flex: 1, pr: isMobile ? 0 : 1 }}>
122+
{/* Desktop: Title and labels inline */}
123+
{!isMobile && (
124+
<Stack
125+
direction="row"
126+
alignItems="center"
127+
spacing={0.5}
128+
sx={{ flexWrap: 'wrap', gap: 0.5 }}
129+
>
130+
<PaperTitle
131+
variant="subtitle1"
132+
component="h3"
133+
sx={{ display: 'inline', mb: 0 }}
134+
>
135+
{paper.title}
136+
</PaperTitle>
137+
138+
{/* Topic labels inline with title on desktop */}
139+
{paper.labels?.map(label => {
140+
const isSelected = selectedLabels.includes(label);
141+
const labelColor = getLabelColor(label);
142+
return (
143+
<Chip
144+
key={`label-${label}`}
145+
label={label}
146+
size="small"
147+
variant={isSelected ? 'filled' : 'outlined'}
148+
color={labelColor}
149+
clickable
150+
onClick={() => {
151+
if (onLabelClick) {
152+
trackEvent('paper_label_click', {
153+
category: 'paper_interaction',
154+
label: label,
155+
custom_parameter_1: paper.title || 'Unknown paper',
156+
});
157+
onLabelClick(label);
158+
}
159+
}}
160+
sx={{
161+
borderRadius: 2,
162+
fontSize: '0.75rem',
163+
height: 22,
164+
cursor: 'pointer',
165+
transition: 'all 0.2s ease',
166+
'&:hover': {
167+
transform: 'scale(1.05)',
168+
boxShadow: 2,
169+
},
170+
}}
171+
/>
172+
);
173+
})}
174+
</Stack>
175+
)}
176+
177+
{/* Mobile: Title, then authors, then labels and badges */}
178+
{isMobile && (
179+
<>
180+
<PaperTitle
181+
variant="subtitle1"
182+
component="h3"
183+
sx={{ display: 'block', mb: 0.25 }}
184+
>
185+
{paper.title}
186+
</PaperTitle>
187+
188+
{/* Authors */}
189+
<Typography
190+
variant="caption"
191+
color="text.secondary"
192+
sx={{
193+
fontSize: '0.8rem',
194+
lineHeight: 1.2,
195+
display: 'block',
196+
mb: 0.5,
197+
}}
198+
>
199+
By{' '}
200+
{paper.authors
201+
? typeof paper.authors === 'string'
202+
? paper.authors
203+
: paper.authors.join(', ')
204+
: 'Unknown authors'}
205+
</Typography>
206+
207+
{/* Labels and badges */}
208+
<Stack
209+
direction="row"
210+
alignItems="center"
211+
spacing={0.5}
212+
sx={{ flexWrap: 'wrap', gap: 0.5 }}
213+
>
214+
{/* Topic labels */}
215+
{paper.labels?.map(label => {
216+
const isSelected = selectedLabels.includes(label);
217+
const labelColor = getLabelColor(label);
218+
return (
219+
<Chip
220+
key={`label-${label}`}
221+
label={label}
222+
size="small"
223+
variant={isSelected ? 'filled' : 'outlined'}
224+
color={labelColor}
225+
clickable
226+
onClick={() => {
227+
if (onLabelClick) {
228+
trackEvent('paper_label_click', {
229+
category: 'paper_interaction',
230+
label: label,
231+
custom_parameter_1:
232+
paper.title || 'Unknown paper',
233+
});
234+
onLabelClick(label);
235+
}
236+
}}
237+
sx={{
238+
borderRadius: 2,
239+
fontSize: '0.75rem',
240+
height: 22,
241+
cursor: 'pointer',
242+
transition: 'all 0.2s ease',
243+
'&:hover': {
244+
transform: 'scale(1.05)',
245+
boxShadow: 2,
246+
},
247+
}}
248+
/>
249+
);
250+
})}
251+
252+
{/* Publication badges inline with labels on mobile */}
253+
{paper.publications?.map((pub, index) => (
254+
<Tooltip
255+
key={`pub-${index}`}
256+
title={`${pub.name} ${pub.year}${pub.url ? ' - Click to view' : ''}`}
257+
>
258+
<Chip
259+
label={`${pub.name} '${pub.year.toString().slice(-2)}`}
260+
size="small"
261+
variant={pub.name === 'arXiv' ? 'outlined' : 'filled'}
262+
color={pub.name === 'arXiv' ? 'default' : 'primary'}
263+
onClick={() => {
264+
if (pub.url) {
265+
trackEvent('publication_link_click', {
266+
category: 'paper_interaction',
267+
label: paper.title || 'Unknown paper',
268+
custom_parameter_1: pub.name,
269+
custom_parameter_2: pub.year?.toString(),
270+
});
271+
openInNewTab(pub.url);
272+
}
273+
}}
274+
sx={{
275+
cursor: pub.url ? 'pointer' : 'default',
276+
'&:hover': pub.url
277+
? {
278+
transform: 'scale(1.05)',
279+
}
280+
: {},
281+
transition: 'transform 0.2s',
282+
height: 20,
283+
fontSize: '0.75rem',
284+
}}
285+
/>
286+
</Tooltip>
287+
))}
288+
</Stack>
289+
</>
290+
)}
291+
</Box>
292+
293+
{/* Publication badges and BibTeX button on the right (desktop only) */}
294+
{!isMobile && (
124295
<Stack
125296
direction="row"
126297
alignItems="center"
127298
spacing={0.5}
128-
sx={{ flexWrap: 'wrap', gap: 0.5 }}
299+
sx={{ flexShrink: 0 }}
129300
>
130-
<PaperTitle
131-
variant="subtitle1"
132-
component="h3"
133-
sx={{ display: 'inline', mb: 0 }}
134-
>
135-
{paper.title}
136-
</PaperTitle>
137-
138-
{/* Topic labels inline with title */}
139-
{paper.labels?.map(label => {
140-
const isSelected = selectedLabels.includes(label);
141-
const labelColor = getLabelColor(label);
142-
return (
301+
{/* Publication badges */}
302+
{paper.publications?.map((pub, index) => (
303+
<Tooltip
304+
key={`pub-${index}`}
305+
title={`${pub.name} ${pub.year}${pub.url ? ' - Click to view' : ''}`}
306+
>
143307
<Chip
144-
key={`label-${label}`}
145-
label={label}
308+
label={`${pub.name} '${pub.year.toString().slice(-2)}`}
146309
size="small"
147-
variant={isSelected ? 'filled' : 'outlined'}
148-
color={labelColor}
149-
clickable
310+
variant={pub.name === 'arXiv' ? 'outlined' : 'filled'}
311+
color={pub.name === 'arXiv' ? 'default' : 'primary'}
150312
onClick={() => {
151-
if (onLabelClick) {
152-
trackEvent('paper_label_click', {
313+
if (pub.url) {
314+
trackEvent('publication_link_click', {
153315
category: 'paper_interaction',
154-
label: label,
155-
custom_parameter_1: paper.title || 'Unknown paper',
316+
label: paper.title || 'Unknown paper',
317+
custom_parameter_1: pub.name,
318+
custom_parameter_2: pub.year?.toString(),
156319
});
157-
onLabelClick(label);
320+
openInNewTab(pub.url);
158321
}
159322
}}
160323
sx={{
161-
borderRadius: 2,
324+
cursor: pub.url ? 'pointer' : 'default',
325+
'&:hover': pub.url
326+
? {
327+
transform: 'scale(1.05)',
328+
}
329+
: {},
330+
transition: 'transform 0.2s',
331+
height: 20,
162332
fontSize: '0.75rem',
163-
height: 22,
164-
cursor: 'pointer',
165-
transition: 'all 0.2s ease',
166-
'&:hover': {
167-
transform: 'scale(1.05)',
168-
boxShadow: 2,
169-
},
170333
}}
171334
/>
172-
);
173-
})}
174-
</Stack>
175-
</Box>
335+
</Tooltip>
336+
))}
176337

177-
{hasBibtex && (
178-
<Tooltip title="Copy BibTeX">
179-
<IconButton
180-
onClick={handleCopyBibtex}
181-
size="small"
182-
color="primary"
183-
sx={{ p: 0.5 }}
184-
>
185-
<ContentCopy sx={{ fontSize: 18 }} />
186-
</IconButton>
187-
</Tooltip>
338+
{hasBibtex && (
339+
<Tooltip title="Copy BibTeX">
340+
<IconButton
341+
onClick={handleCopyBibtex}
342+
size="small"
343+
color="primary"
344+
sx={{ p: 0.5 }}
345+
>
346+
<ContentCopy sx={{ fontSize: 18 }} />
347+
</IconButton>
348+
</Tooltip>
349+
)}
350+
</Stack>
188351
)}
189352
</Stack>
190353

191-
{/* Authors and publication badges on second line */}
192-
<Stack
193-
direction="row"
194-
alignItems="center"
195-
spacing={0.5}
196-
sx={{ flexWrap: 'wrap', gap: 0.5 }}
197-
>
354+
{/* Authors on second line (desktop only) */}
355+
{!isMobile && (
198356
<Typography
199357
variant="caption"
200358
color="text.secondary"
@@ -207,44 +365,7 @@ const PaperCard = ({ paper, selectedLabels = [], onLabelClick }) => {
207365
: paper.authors.join(', ')
208366
: 'Unknown authors'}
209367
</Typography>
210-
211-
{/* Publication badges inline with authors */}
212-
{paper.publications?.map((pub, index) => (
213-
<Tooltip
214-
key={`pub-${index}`}
215-
title={`${pub.name} ${pub.year}${pub.url ? ' - Click to view' : ''}`}
216-
>
217-
<Chip
218-
label={`${pub.name} '${pub.year.toString().slice(-2)}`}
219-
size="small"
220-
variant={pub.name === 'arXiv' ? 'outlined' : 'filled'}
221-
color={pub.name === 'arXiv' ? 'default' : 'primary'}
222-
onClick={() => {
223-
if (pub.url) {
224-
trackEvent('publication_link_click', {
225-
category: 'paper_interaction',
226-
label: paper.title || 'Unknown paper',
227-
custom_parameter_1: pub.name,
228-
custom_parameter_2: pub.year?.toString(),
229-
});
230-
openInNewTab(pub.url);
231-
}
232-
}}
233-
sx={{
234-
cursor: pub.url ? 'pointer' : 'default',
235-
'&:hover': pub.url
236-
? {
237-
transform: 'scale(1.05)',
238-
}
239-
: {},
240-
transition: 'transform 0.2s',
241-
height: 20,
242-
fontSize: '0.75rem',
243-
}}
244-
/>
245-
</Tooltip>
246-
))}
247-
</Stack>
368+
)}
248369
</CardContent>
249370
</StyledCard>
250371
);

0 commit comments

Comments
 (0)