Skip to content

Commit 4969429

Browse files
committed
group clubs
1 parent 0460bd9 commit 4969429

File tree

2 files changed

+33
-8
lines changed

2 files changed

+33
-8
lines changed

client/src/components/lists/List.tsx

+32-8
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ type ListProps<T> = {
99
filter: ([id, value]: [string, T]) => boolean,
1010
map: ([id, value]: [string, T]) => JSX.Element,
1111
sort: ([idA, valueA]: [string, T], [idB, valueB]: [string, T]) => number,
12-
pinned: string[]
12+
pinned: string[],
13+
groupBy?: keyof T
1314
}
1415

1516
// A higher order list component of type T where T is the type of the JSON representation of a list value
@@ -21,8 +22,8 @@ type ListProps<T> = {
2122
// Pinned items (given as a string[] of IDs) are displayed in a separate category above other results.
2223
export default function List<T>(props: ListProps<T>) {
2324
// Filter and map are different for each list, so pass them in as props
24-
const {data, filter, map, sort, pinned: pinnedIds} = props;
25-
const [{pinned, unpinned}, setContent] = useState(parseContent());
25+
const {data, filter, map, sort, pinned: pinnedIds, groupBy} = props;
26+
const [{pinned, unpinned, grouped}, setContent] = useState(parseContent());
2627

2728
// Maps content to JSX components, sorting, filtering, and splitting by pinned and unpinned.
2829
function parseContent() {
@@ -36,9 +37,20 @@ export default function List<T>(props: ListProps<T>) {
3637
const pinnedContent = parsed.filter(([id, value]) => pinnedIds.includes(id));
3738
const unpinnedContent = parsed.filter(([id, value]) => !pinnedIds.includes(id));
3839

40+
const groupedContent = groupBy ? unpinnedContent.reduce((clubs, [id, club]) => {
41+
const group = club[groupBy] as string;
42+
if (!clubs[group]) clubs[group] = [];
43+
clubs[group].push([id, club]);
44+
return clubs;
45+
}, {} as Record<string, [string, T][]>) : {};
46+
3947
return {
4048
pinned: pinnedContent.filter(filter).map(map),
41-
unpinned: unpinnedContent.filter(filter).map(map)
49+
unpinned: unpinnedContent.filter(filter).map(map),
50+
grouped: Object.entries(groupedContent).map(([group, clubs]) => [
51+
group,
52+
clubs.filter(filter).map(map)
53+
])
4254
};
4355
}
4456

@@ -57,10 +69,22 @@ export default function List<T>(props: ListProps<T>) {
5769
</MaterialList>
5870
)}
5971
{unpinned.length > 0 && pinned.length > 0 && <hr/>}
60-
{unpinned.length > 0 && (
61-
<MaterialList>
62-
{unpinned}
63-
</MaterialList>
72+
{groupBy ? grouped.map(([group, clubs]) => (
73+
clubs.length > 0 && (
74+
<>
75+
<p className="mt-2 pl-2 text-secondary text-2xl font-bold">{group}</p>
76+
<hr className="mx-2 mt-2 mb-0" />
77+
<MaterialList>
78+
{clubs}
79+
</MaterialList>
80+
</>
81+
)
82+
)) : (
83+
unpinned.length > 0 && (
84+
<MaterialList>
85+
{unpinned}
86+
</MaterialList>
87+
)
6488
)}
6589
</>) : (
6690
<NoResults/>

client/src/pages/Clubs.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ export default function Clubs() {
105105
)}
106106
sort={([idA, clubA], [idB, clubB]) => clubA.name.localeCompare(clubB.name)}
107107
pinned={userData.clubs}
108+
groupBy="type"
108109
/>
109110
</HeaderPage>
110111
);

0 commit comments

Comments
 (0)