pleroma/app/soapbox/features/groups/components/discover/search/results.tsx

94 lines
2.5 KiB
TypeScript
Raw Normal View History

2023-02-28 07:26:27 -08:00
import clsx from 'clsx';
import React, { useCallback, useState } from 'react';
import { FormattedMessage } from 'react-intl';
import { Components, Virtuoso, VirtuosoGrid } from 'react-virtuoso';
2023-04-03 09:56:29 -07:00
import { HStack, Stack, Text } from 'soapbox/components/ui';
2023-03-28 08:52:41 -07:00
import { useGroupSearch } from 'soapbox/hooks/api';
2023-02-28 07:26:27 -08:00
2023-03-08 10:22:10 -08:00
import GroupGridItem from '../group-grid-item';
import GroupListItem from '../group-list-item';
2023-04-03 09:56:29 -07:00
import LayoutButtons, { GroupLayout } from '../layout-buttons';
import type { Group } from 'soapbox/types/entities';
2023-02-28 07:26:27 -08:00
interface Props {
groupSearchResult: ReturnType<typeof useGroupSearch>
}
const GridList: Components['List'] = React.forwardRef((props, ref) => {
const { context, ...rest } = props;
return <div ref={ref} {...rest} className='flex flex-wrap' />;
});
export default (props: Props) => {
const { groupSearchResult } = props;
2023-04-03 09:56:29 -07:00
const [layout, setLayout] = useState<GroupLayout>(GroupLayout.LIST);
2023-02-28 07:26:27 -08:00
const { groups, hasNextPage, isFetching, fetchNextPage } = groupSearchResult;
const handleLoadMore = () => {
if (hasNextPage && !isFetching) {
fetchNextPage();
}
};
const renderGroupList = useCallback((group: Group, index: number) => (
2023-03-08 10:22:10 -08:00
<div
2023-02-28 07:26:27 -08:00
className={
clsx({
'pt-4': index !== 0,
})
}
>
2023-03-08 10:22:10 -08:00
<GroupListItem group={group} withJoinAction />
</div>
2023-02-28 07:26:27 -08:00
), []);
const renderGroupGrid = useCallback((group: Group, index: number) => (
<div className='pb-4'>
2023-03-08 10:22:10 -08:00
<GroupGridItem group={group} />
2023-02-28 07:26:27 -08:00
</div>
), []);
return (
2023-02-28 12:03:03 -08:00
<Stack space={4} data-testid='results'>
2023-02-28 07:26:27 -08:00
<HStack alignItems='center' justifyContent='between'>
2023-03-01 07:39:33 -08:00
<Text weight='semibold'>
<FormattedMessage
id='groups.discover.search.results.groups'
defaultMessage='Groups'
/>
</Text>
2023-02-28 07:26:27 -08:00
2023-04-03 09:56:29 -07:00
<LayoutButtons
layout={layout}
onSelect={(selectedLayout) => setLayout(selectedLayout)}
/>
2023-02-28 07:26:27 -08:00
</HStack>
2023-04-03 09:56:29 -07:00
{layout === GroupLayout.LIST ? (
2023-02-28 07:26:27 -08:00
<Virtuoso
useWindowScroll
data={groups}
itemContent={(index, group) => renderGroupList(group, index)}
endReached={handleLoadMore}
/>
) : (
<VirtuosoGrid
useWindowScroll
data={groups}
itemContent={(index, group) => renderGroupGrid(group, index)}
components={{
Item: (props) => (
<div {...props} className='w-1/2 flex-none' />
),
List: GridList,
}}
endReached={handleLoadMore}
/>
)}
</Stack>
);
};