alpha
Login
or
Join now
nandi.uk
/
semble
Star
0
Fork
0
Atom
Configure Feed
Issues
Pull Requests
Commits
Tags
Feed URL
Select the types of activity you want to include in your feed.
This repository has no description
Star
0
Fork
0
Atom
Configure Feed
Issues
Pull Requests
Commits
Tags
Feed URL
Select the types of activity you want to include in your feed.
Overview
Issues
Pulls
Pipelines
feat: search collection from profile
author
pdelfan
date
3 months ago
(Apr 27, 2026, 4:30 PM -0700)
commit
5eba62af
5eba62af7ad5b04fb887bafb88ec404fe0ded803
parent
214d2fbe
214d2fbebb55dd814e5b4d87b4d20d8164cc2309
+50
-49
4 changed files
Expand all
Collapse all
Unified
Split
src
webapp
app
(dashboard)
profile
[handle]
(withHeader)
collections
page.tsx
features
collections
containers
collectionsContainer
CollectionsContainer.tsx
Skeleton.CollectionsContainer.tsx
collectionsContainerContent
CollectionsContainerContent.tsx
+2
-39
src/webapp/app/(dashboard)/profile/[handle]/(withHeader)/collections/page.tsx
View file
Reviewed
···
1
1
import CollectionsContainer from '@/features/collections/containers/collectionsContainer/CollectionsContainer';
2
2
-
import { Group, Container } from '@mantine/core';
3
3
-
import { IoSearch } from 'react-icons/io5';
4
4
-
import {
5
5
-
CollectionFiltersRoot,
6
6
-
CollectionFiltersSortSelect,
7
7
-
CollectionFiltersViewToggle,
8
8
-
} from '@/features/collections/components/collectionFilters/CollectionFilters';
9
9
-
import { Fragment } from 'react';
10
10
-
import { CollectionSortField } from '@semble/types';
11
11
-
import { LinkButton } from '@/components/link/MantineLink';
12
2
13
3
interface Props {
14
4
params: Promise<{ handle: string }>;
15
15
-
searchParams: Promise<{ collectionSort?: string }>;
16
5
}
17
6
18
7
export default async function Page(props: Props) {
19
19
-
const [{ handle }, { collectionSort }] = await Promise.all([
20
20
-
props.params,
21
21
-
props.searchParams,
22
22
-
]);
23
23
-
24
24
-
const sort =
25
25
-
(collectionSort as CollectionSortField) ?? CollectionSortField.UPDATED_AT;
8
8
+
const { handle } = await props.params;
26
9
27
27
-
return (
28
28
-
<Fragment>
29
29
-
<Container p={0} size="xl">
30
30
-
<Group justify="space-between" gap="xs" px="xs" pt="xs">
31
31
-
<CollectionFiltersRoot>
32
32
-
<CollectionFiltersSortSelect />
33
33
-
<CollectionFiltersViewToggle />
34
34
-
</CollectionFiltersRoot>
35
35
-
<LinkButton
36
36
-
href={`/search/collections?handle=${handle}`}
37
37
-
variant="light"
38
38
-
color="gray"
39
39
-
rightSection={<IoSearch />}
40
40
-
>
41
41
-
Search
42
42
-
</LinkButton>
43
43
-
</Group>
44
44
-
</Container>
45
45
-
<CollectionsContainer handle={handle} key={sort} />
46
46
-
</Fragment>
47
47
-
);
10
10
+
return <CollectionsContainer handle={handle} />;
48
11
}
+44
-8
src/webapp/features/collections/containers/collectionsContainer/CollectionsContainer.tsx
View file
Reviewed
···
1
1
-
import { Container, Stack } from '@mantine/core';
2
2
-
import { Suspense } from 'react';
1
1
+
'use client';
2
2
+
3
3
+
import { CloseButton, Container, Group, Stack, TextInput } from '@mantine/core';
4
4
+
import { Suspense, useState } from 'react';
3
5
import CollectionsContainerContent from '../collectionsContainerContent/CollectionsContainerContent';
4
6
import CollectionsContainerContentSkeleton from '../collectionsContainerContent/Skeleton.collectionsContainerContent';
7
7
+
import { CollectionFilters } from '../../components/collectionFilters/CollectionFilters';
8
8
+
import { IoSearch } from 'react-icons/io5';
9
9
+
import { useDebouncedValue } from '@mantine/hooks';
5
10
6
11
interface Props {
7
12
handle: string;
8
13
}
9
14
10
15
export default function CollectionsContainer(props: Props) {
16
16
+
const [search, setSearch] = useState('');
17
17
+
const [debouncedSearch] = useDebouncedValue(search, 300);
18
18
+
11
19
return (
12
12
-
<Container p="xs" size="xl">
13
13
-
<Stack>
14
14
-
<Suspense fallback={<CollectionsContainerContentSkeleton />}>
15
15
-
<CollectionsContainerContent handle={props.handle} />
16
16
-
</Suspense>
17
17
-
</Stack>
20
20
+
<Container p={0} size={'xl'}>
21
21
+
<Group justify="space-between" gap="xs" px="xs" pt="xs">
22
22
+
<CollectionFilters.Root>
23
23
+
<CollectionFilters.SortSelect />
24
24
+
<CollectionFilters.ViewToggle />
25
25
+
</CollectionFilters.Root>
26
26
+
<TextInput
27
27
+
variant="filled"
28
28
+
placeholder="Search..."
29
29
+
leftSection={<IoSearch />}
30
30
+
rightSection={
31
31
+
<CloseButton
32
32
+
aria-label="Clear input"
33
33
+
onClick={() => setSearch('')}
34
34
+
style={{ display: search ? undefined : 'none' }}
35
35
+
/>
36
36
+
}
37
37
+
radius={'xl'}
38
38
+
value={search}
39
39
+
onChange={(e) => setSearch(e.currentTarget.value)}
40
40
+
w={160}
41
41
+
/>
42
42
+
</Group>
43
43
+
44
44
+
<Container p="xs" size="xl">
45
45
+
<Stack>
46
46
+
<Suspense fallback={<CollectionsContainerContentSkeleton />}>
47
47
+
<CollectionsContainerContent
48
48
+
handle={props.handle}
49
49
+
query={debouncedSearch || undefined}
50
50
+
/>
51
51
+
</Suspense>
52
52
+
</Stack>
53
53
+
</Container>
18
54
</Container>
19
55
);
20
56
}
+2
-2
src/webapp/features/collections/containers/collectionsContainer/Skeleton.CollectionsContainer.tsx
View file
Reviewed
···
4
4
export default function CollectionsContainerSkeleton() {
5
5
return (
6
6
<Container p="xs" size="xl">
7
7
-
<Stack>
7
7
+
<Stack gap={'xs'}>
8
8
<Group gap={'xs'} justify="space-between">
9
9
<Skeleton w={96} h={36} radius={'xl'} />
10
10
-
<Skeleton w={100} h={36} radius={'xl'} />
10
10
+
<Skeleton w={160} h={36} radius={'xl'} />
11
11
</Group>
12
12
13
13
<SimpleGrid cols={{ base: 1, sm: 2, lg: 4 }} spacing="xs">
+2
src/webapp/features/collections/containers/collectionsContainerContent/CollectionsContainerContent.tsx
View file
Reviewed
···
14
14
15
15
interface Props {
16
16
handle: string;
17
17
+
query?: string;
17
18
}
18
19
19
20
export default function CollectionsContainerContent(props: Props) {
···
26
27
useCollections({
27
28
didOrHandle: props.handle,
28
29
sortBy,
30
30
+
query: props.query,
29
31
});
30
32
31
33
const { settings } = useUserSettings();