Skip to content

Commit 21c2aba

Browse files
committed
feat: enhance ListComponent with sorting functionality and add ListConference, ListPost, and ListRepo components
1 parent dcfb5a1 commit 21c2aba

4 files changed

Lines changed: 67 additions & 16 deletions

File tree

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { ReactNode } from 'react'
1+
import React, { ReactNode, useMemo } from 'react'
22
import { Placeholder } from 'src/components/placeholders'
33
import { MAX_ITEMS_PER_CARD } from 'src/config'
44

@@ -9,15 +9,17 @@ type PlaceholdersProps = {
99
const Placeholders = React.memo<PlaceholdersProps>(({ placeholder }) => {
1010
return (
1111
<>
12-
{[...Array(7)].map((x, i) => (
12+
{[...Array(7)].map((_, i) => (
1313
<span key={i}>{placeholder}</span>
1414
))}
1515
</>
1616
)
1717
})
1818

1919
export type ListComponentPropsType<T extends unknown> = {
20-
items: T[]
20+
items?: T[]
21+
sortBy?: keyof T
22+
sortFn?: (a: T, b: T) => number
2123
isLoading: boolean
2224
renderItem: (item: T, index: number) => React.ReactNode
2325
placeholder?: React.ReactNode
@@ -27,11 +29,13 @@ export type ListComponentPropsType<T extends unknown> = {
2729
limit?: number
2830
}
2931

30-
export function ListComponent<T extends unknown>(props: ListComponentPropsType<T>) {
32+
export function ListComponent<T extends any>(props: ListComponentPropsType<T>) {
3133
const {
3234
items,
35+
sortBy,
3336
isLoading,
3437
error,
38+
sortFn,
3539
renderItem,
3640
header,
3741
placeholder = <Placeholder />,
@@ -42,20 +46,49 @@ export function ListComponent<T extends unknown>(props: ListComponentPropsType<T
4246
return <p className="errorMsg">{error?.message || error}</p>
4347
}
4448

45-
const renderItems = () => {
46-
if (!items) {
47-
return
49+
if (items && items.length == 0) {
50+
return (
51+
<p className="errorMsg">
52+
No items found, try adjusting your filter or choosing a different tag.
53+
</p>
54+
)
55+
}
56+
57+
const sortedData = useMemo(() => {
58+
if (!items || items.length == 0) return []
59+
if (!sortBy) return items
60+
61+
const result = sortFn
62+
? [...items].sort(sortFn)
63+
: [...items].sort((a, b) => {
64+
const aVal = a[sortBy]
65+
const bVal = b[sortBy]
66+
if (typeof aVal === 'number' && typeof bVal === 'number') return bVal - aVal
67+
if (typeof aVal === 'string' && typeof bVal === 'string') return bVal.localeCompare(aVal)
68+
return 0
69+
})
70+
71+
return result
72+
}, [sortBy, sortFn, items])
73+
74+
const enrichedItems = useMemo(() => {
75+
if (!sortedData || sortedData.length === 0) {
76+
return []
4877
}
4978

50-
return items.slice(0, limit).map((item, index) => {
51-
let content: ReactNode[] = [renderItem(item, index)]
52-
if (header && index === 0) {
53-
content.unshift(header)
54-
}
79+
try {
80+
return sortedData.slice(0, limit).map((item, index) => {
81+
let content: ReactNode[] = [renderItem(item, index)]
82+
if (header && index === 0) {
83+
content.unshift(header)
84+
}
5585

56-
return content
57-
})
58-
}
86+
return content
87+
})
88+
} catch (e) {
89+
return []
90+
}
91+
}, [sortedData])
5992

60-
return <>{isLoading ? <Placeholders placeholder={placeholder} /> : renderItems()}</>
93+
return <>{isLoading ? <Placeholders placeholder={placeholder} /> : enrichedItems}</>
6194
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { Conference } from 'src/types'
2+
import { ListComponent, ListComponentPropsType } from './ListComponent'
3+
4+
export function ListConferenceComponent(props: ListComponentPropsType<Conference>) {
5+
return <ListComponent<Conference> {...props} />
6+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { Article } from 'src/types'
2+
import { ListComponent, ListComponentPropsType } from './ListComponent'
3+
4+
export function ListPostComponent(props: ListComponentPropsType<Article>) {
5+
return <ListComponent<Article> {...props} />
6+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { Repository } from 'src/types'
2+
import { ListComponent, ListComponentPropsType } from './ListComponent'
3+
4+
export function ListRepoComponent(props: ListComponentPropsType<Repository>) {
5+
return <ListComponent<Repository> {...props} />
6+
}

0 commit comments

Comments
 (0)