Skip to content

Commit f24471f

Browse files
committed
feat: add SubjectCard component to display subject-level search results
1 parent 3de04fc commit f24471f

File tree

2 files changed

+157
-5
lines changed

2 files changed

+157
-5
lines changed
Lines changed: 109 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,114 @@
1-
import { Box, Card, CardContent, Grid, Link } from "@mui/material";
1+
import {
2+
Box,
3+
Typography,
4+
Card,
5+
CardContent,
6+
Stack,
7+
Chip,
8+
Grid,
9+
Link,
10+
} from "@mui/material";
211
import { Colors } from "design/theme";
12+
import React from "react";
313

4-
const SubjectCard: React.FC = () => {
5-
return <></>;
14+
interface SubjectCardProps {
15+
dbname: string;
16+
dsname: string;
17+
age: string;
18+
subj: string;
19+
parsedJson: {
20+
key: string[];
21+
value: {
22+
modalities?: string[];
23+
tasks?: string[];
24+
sessions?: string[];
25+
types?: string[];
26+
};
27+
};
28+
}
29+
30+
const SubjectCard: React.FC<SubjectCardProps> = ({
31+
dbname,
32+
dsname,
33+
age,
34+
subj,
35+
parsedJson,
36+
}) => {
37+
const { modalities, tasks, sessions, types } = parsedJson.value;
38+
39+
return (
40+
<Card sx={{ mb: 3 }}>
41+
<CardContent>
42+
<Typography
43+
variant="h6"
44+
sx={{ fontWeight: 600, color: Colors.darkPurple }}
45+
>
46+
Database: {dbname} &nbsp;&nbsp;|&nbsp;&nbsp; Dataset Number: {dsname}
47+
</Typography>
48+
49+
<Typography variant="body2" color="text.secondary" gutterBottom>
50+
Subject: {subj} &nbsp;&nbsp;|&nbsp;&nbsp; Age: {age}
51+
</Typography>
52+
53+
<Stack spacing={2} margin={1}>
54+
<Stack direction="row" spacing={1} flexWrap="wrap" gap={1}>
55+
<Typography variant="body2" mt={1}>
56+
<strong>Modalities:</strong>
57+
</Typography>
58+
{modalities?.map((mod, idx) => (
59+
<Chip
60+
key={idx}
61+
label={mod}
62+
variant="outlined"
63+
sx={{
64+
color: Colors.darkPurple,
65+
border: `1px solid ${Colors.darkPurple}`,
66+
fontWeight: "bold",
67+
}}
68+
/>
69+
))}
70+
</Stack>
71+
72+
<Stack direction="row" spacing={1} flexWrap="wrap" gap={1}>
73+
<Typography variant="body2" mt={1}>
74+
<strong>Tasks:</strong>
75+
</Typography>
76+
{tasks?.map((task, idx) => (
77+
<Chip
78+
key={`task-${idx}`}
79+
label={task}
80+
variant="outlined"
81+
sx={{
82+
color: Colors.darkPurple,
83+
border: `1px solid ${Colors.darkPurple}`,
84+
fontWeight: "bold",
85+
}}
86+
/>
87+
))}
88+
</Stack>
89+
<Stack direction="row" spacing={1} flexWrap="wrap" gap={1}>
90+
<Typography variant="body2" mt={1}>
91+
<strong>Sessions:</strong> {sessions?.length}
92+
</Typography>
93+
{/* {sessions?.map((session, idx) => (
94+
<Chip
95+
key={`sess-${idx}`}
96+
label={`Session ${session}`}
97+
variant="outlined"
98+
/>
99+
))} */}
100+
</Stack>
101+
<Stack direction="row" spacing={1} flexWrap="wrap" gap={1}>
102+
{types?.length && (
103+
<Typography variant="body2" mt={1}>
104+
<strong>Types:</strong> {types.join(", ")}
105+
</Typography>
106+
)}
107+
</Stack>
108+
</Stack>
109+
</CardContent>
110+
</Card>
111+
);
6112
};
7113

8114
export default SubjectCard;

src/pages/SearchPage.tsx

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { generateSchemaWithDatabaseEnum } from "./searchformSchema";
22
import { Typography, Container, Box } from "@mui/material";
33
import Form from "@rjsf/mui";
44
import validator from "@rjsf/validator-ajv8";
5+
import DatasetCard from "components/SearchPage/DatasetCard";
6+
import SubjectCard from "components/SearchPage/SubjectCard";
57
import { Colors } from "design/theme";
68
import { useAppDispatch } from "hooks/useAppDispatch";
79
import { useAppSelector } from "hooks/useAppSelector";
@@ -25,7 +27,7 @@ const SearchPage: React.FC = () => {
2527
(state: RootState) => state.neurojson.registry
2628
);
2729

28-
console.log("result:", searchResults);
30+
// console.log("result:", searchResults);
2931
if (Array.isArray(searchResults)) {
3032
searchResults.forEach((item, idx) => {
3133
// console.log(`Raw item #${idx}:`, item);
@@ -106,6 +108,50 @@ const SearchPage: React.FC = () => {
106108
{hasSearched && searchResults && (
107109
<Box mt={4}>
108110
{Array.isArray(searchResults) ? (
111+
searchResults.length > 0 ? (
112+
searchResults.map((item, idx) => {
113+
try {
114+
const parsedJson = JSON.parse(item.json);
115+
const isDataset =
116+
parsedJson?.value?.subj &&
117+
Array.isArray(parsedJson.value.subj);
118+
119+
return isDataset ? (
120+
<DatasetCard
121+
key={idx}
122+
dbname={item.dbname}
123+
dsname={item.dsname}
124+
parsedJson={parsedJson}
125+
/>
126+
) : (
127+
<SubjectCard
128+
key={idx}
129+
{...item}
130+
parsedJson={parsedJson}
131+
/>
132+
);
133+
} catch (e) {
134+
return (
135+
<Typography key={idx} color="error">
136+
Failed to parse item #{idx}
137+
</Typography>
138+
);
139+
}
140+
})
141+
) : (
142+
<Typography variant="h6">
143+
No matching dataset was found
144+
</Typography>
145+
)
146+
) : (
147+
<Typography color="error">
148+
{searchResults?.msg === "empty output"
149+
? "No results found based on your criteria. Please adjust the filters and try again."
150+
: "Something went wrong. Please try again later."}
151+
</Typography>
152+
)}
153+
154+
{/* {Array.isArray(searchResults) ? (
109155
searchResults.length > 0 ? (
110156
<>
111157
<Typography
@@ -147,7 +193,7 @@ const SearchPage: React.FC = () => {
147193
? "No results found based on your criteria. Please adjust the filters and try again."
148194
: "Something went wrong. Please try again later."}
149195
</Typography>
150-
)}
196+
)} */}
151197
</Box>
152198
)}
153199
</Box>

0 commit comments

Comments
 (0)