This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

semble / src / webapp / features / collections / containers / collectionContainer / CollectionContainer.tsx
4.8 kB 172 lines
1'use client'; 2 3import { 4 Anchor, 5 Box, 6 Button, 7 Container, 8 Grid, 9 Group, 10 Stack, 11 Text, 12 Title, 13 Center, 14 Avatar, 15} from '@mantine/core'; 16import useCollection from '../../lib/queries/useCollection'; 17import UrlCard from '@/features/cards/components/urlCard/UrlCard'; 18import Link from 'next/link'; 19import { useState } from 'react'; 20import { FiPlus } from 'react-icons/fi'; 21import AddCardDrawer from '@/features/cards/components/addCardDrawer/AddCardDrawer'; 22import CollectionActions from '../../components/collectionActions/CollectionActions'; 23import CollectionContainerError from './Error.CollectionContainer'; 24import CollectionContainerSkeleton from './Skeleton.CollectionContainer'; 25 26interface Props { 27 rkey: string; 28 handle: string; 29} 30 31export default function CollectionContainer(props: Props) { 32 const { 33 data, 34 isPending, 35 error, 36 fetchNextPage, 37 hasNextPage, 38 isFetchingNextPage, 39 } = useCollection({ rkey: props.rkey, handle: props.handle }); 40 41 const [showAddDrawer, setShowAddDrawer] = useState(false); 42 43 if (isPending) { 44 return <CollectionContainerSkeleton />; 45 } 46 47 if (error) { 48 return <CollectionContainerError />; 49 } 50 51 const firstPage = data.pages[0]; 52 const allCards = data.pages.flatMap((page) => page.urlCards ?? []); 53 54 return ( 55 <Container p="xs" size="xl"> 56 <Stack justify="flex-start"> 57 <Group justify="space-between" align="start"> 58 <Stack gap={0}> 59 <Text fw={700} c="grape"> 60 Collection 61 </Text> 62 <Title order={1}>{firstPage.name}</Title> 63 {firstPage.description && ( 64 <Text c="gray" mt="lg"> 65 {firstPage.description} 66 </Text> 67 )} 68 </Stack> 69 70 <Group gap={'xs'}> 71 <Text fw={600} c="gray.7"> 72 By 73 </Text> 74 <Group gap={5}> 75 <Avatar 76 size={'sm'} 77 component={Link} 78 href={`/profile/${firstPage.author.handle}`} 79 src={firstPage.author.avatarUrl} 80 alt={`${firstPage.author.name}'s' avatar`} 81 /> 82 <Anchor 83 component={Link} 84 href={`/profile/${firstPage.author.handle}`} 85 fw={700} 86 c="blue" 87 > 88 {firstPage.author.name} 89 </Anchor> 90 </Group> 91 </Group> 92 </Group> 93 94 <Group justify="end"> 95 <CollectionActions 96 id={firstPage.id} 97 rkey={props.rkey} 98 name={firstPage.name} 99 description={firstPage.description} 100 authorHandle={firstPage.author.handle} 101 /> 102 </Group> 103 104 {allCards.length > 0 ? ( 105 <> 106 <Grid gutter="md"> 107 {allCards.map((card) => ( 108 <Grid.Col 109 key={card.id} 110 span={{ base: 12, xs: 6, sm: 4, lg: 3 }} 111 > 112 <UrlCard 113 id={card.id} 114 url={card.url} 115 cardContent={card.cardContent} 116 authorHandle={firstPage.author.handle} 117 cardAuthor={firstPage.author} 118 note={card.note} 119 urlLibraryCount={card.urlLibraryCount} 120 urlIsInLibrary={card.urlInLibrary} 121 currentCollection={firstPage} 122 /> 123 </Grid.Col> 124 ))} 125 </Grid> 126 127 {hasNextPage && ( 128 <Center> 129 <Button 130 mt="md" 131 variant="light" 132 color="gray" 133 onClick={() => fetchNextPage()} 134 loading={isFetchingNextPage} 135 > 136 {isFetchingNextPage ? 'Loading more...' : 'Load More'} 137 </Button> 138 </Center> 139 )} 140 </> 141 ) : ( 142 <Stack align="center" gap="xs"> 143 <Text fz="h3" fw={600} c="gray"> 144 No cards 145 </Text> 146 <Button 147 variant="light" 148 color="gray" 149 size="md" 150 rightSection={<FiPlus size={22} />} 151 onClick={() => setShowAddDrawer(true)} 152 > 153 Add your first card 154 </Button> 155 </Stack> 156 )} 157 </Stack> 158 159 <Box> 160 <AddCardDrawer 161 isOpen={showAddDrawer} 162 onClose={() => setShowAddDrawer(false)} 163 selectedCollection={{ 164 id: firstPage.id, 165 name: firstPage.name, 166 cardCount: allCards.length, 167 }} 168 /> 169 </Box> 170 </Container> 171 ); 172}