Skip to content

Commit

Permalink
Layout communities page with searching, sorting and pagination
Browse files Browse the repository at this point in the history
  • Loading branch information
barbarah committed Sep 14, 2023
1 parent 3e5323e commit d6474fc
Show file tree
Hide file tree
Showing 18 changed files with 334 additions and 136 deletions.
4 changes: 2 additions & 2 deletions apps/dataset-browser/src/app/[locale]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
FilterSet,
Paginator,
SelectedFilters,
SearchField,
SearchFieldWithLabel,
OrderSelector,
} from 'ui/list';
import {
Expand Down Expand Up @@ -52,7 +52,7 @@ function FacetMenu({filterKeysOrder, filters}: FacetMenuProps) {

return (
<>
<SearchField />
<SearchFieldWithLabel />
{filterKeysOrder.map(
filterKey =>
!!filters[filterKey]?.length && (
Expand Down
9 changes: 5 additions & 4 deletions apps/dataset-browser/src/messages/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,13 @@
"clearAllFilters": "Clear all",
"filterSearchPlaceholder": "Filter on {filterName}",
"accessibilityTypeToFilter": "Type to filter on text.",
"accessibilitySelectToFilter": "Select a checkbox to filter"
"accessibilitySelectToFilter": "Select a checkbox to filter",
"accessibilityClickToSearch": "Click to search"
},
"Sort": {
"sortRelevanceDesc": "Relevance",
"sortNameAsc": "Name - Ascending",
"sortNameDesc": "Name - Descending",
"relevanceDesc": "Relevance",
"nameAsc": "Name - Ascending",
"nameDesc": "Name - Descending",
"accessibilitySelectToChangeOrder": "Select to change the ordering of the result"
},
"WorkInProgress": {
Expand Down
9 changes: 5 additions & 4 deletions apps/dataset-browser/src/messages/nl/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,13 @@
"clearAllFilters": "Alles verwijderen",
"filterSearchPlaceholder": "Filteren op {filterName}",
"accessibilityTypeToFilter": "Typ om op tekst te filteren",
"accessibilitySelectToFilter": "Selecteer een selectievakje om te filteren"
"accessibilitySelectToFilter": "Selecteer een selectievakje om te filteren",
"accessibilityClickToSearch": "klik om te zoeken"
},
"Sort": {
"sortRelevanceDesc": "Relevantie",
"sortNameAsc": "Naam - Oplopend",
"sortNameDesc": "Naam - Aflopend",
"relevanceDesc": "Relevantie",
"nameAsc": "Naam - Oplopend",
"nameDesc": "Naam - Aflopend",
"accessibilitySelectToChangeOrder": "Selecteer om de volgorde van het resultaat te wijzigen"
},
"WorkInProgress": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ interface MembershipCountProps {
locale: string;
}

// TODO: This is a workaround for the fact that `includeMembersCount` does not work.
// See comment in `community.ts` for more information.
async function MembershipCount({communityId, locale}: MembershipCountProps) {
const t = await getTranslator(locale, 'Communities');
const memberships = await getMemberships(communityId);
Expand Down
83 changes: 48 additions & 35 deletions apps/researcher/src/app/[locale]/communities/page.tsx
Original file line number Diff line number Diff line change
@@ -1,66 +1,76 @@
import {getAllCommunities} from '@/lib/community';
import {
getAllCommunities,
CommunitySortBy,
defaultCommunitySortBy,
} from '@/lib/community';
import {getTranslator} from 'next-intl/server';
import ErrorMessage from '@/components/error-message';
import {MagnifyingGlassIcon} from '@heroicons/react/24/solid';
import CommunityCard from './community-card';

import {ClientListStore} from '@colonial-collections/list-store';
import {Paginator, SearchField, OrderSelector} from 'ui/list';

interface Props {
params: {
locale: string;
};
searchParams?: {
query?: string;
sortBy?: CommunitySortBy;
offset?: number;
};
}

// Revalidate the page
export const revalidate = 0;

export default async function CommunitiesPage({params}: Props) {
export default async function CommunitiesPage({
params,
searchParams = {},
}: Props) {
const t = await getTranslator(params.locale, 'Communities');

const {query, sortBy, offset} = searchParams;

let communities;
try {
communities = await getAllCommunities();
communities = await getAllCommunities({
query,
sortBy,
offset,
});
} catch (err) {
return <ErrorMessage error={t('error')} />;
}

return (
<>
<ClientListStore
{...{
totalCount: communities.length,
offset: offset ?? 0,
limit: 12,
query: query ?? '',
sortBy: sortBy,
baseUrl: '/communities',
defaultSortBy: defaultCommunitySortBy,
}}
/>
<div className="px-4 my-10 sm:px-10 w-full max-w-[1800px] mx-auto">
<h1 className="text-2xl md:text-4xl">{t('title')}</h1>
</div>
<div className="flex flex-col sm:flex-row justify-between h-full gap-6 w-full max-w-[1800px] mx-auto px-4 sm:px-10 pb-4 mb-10 -mt-6 rounded border-b">
<div className="">
<div className="w-full max-w-[450px] relative">
<label htmlFor="text-search" className="font-semibold"></label>
<div className="flex flex-row w-full">
<input
className=" py-1 px-3 w-full rounded-l border border-stone-700"
type="search"
id="text-search"
name="q"
placeholder="Search for community"
/>
<button
className="bg-stone-700 py-1 px-3 rounded-r border-t border-b border-r border-stone-700"
aria-label="Click to search"
value="amster"
>
<MagnifyingGlassIcon className="w-4 h-4 fill-white" />
</button>
</div>
</div>
<div>
<SearchField placeholder={t('searchPlaceholder')} />
</div>
<div className="">
<select
name="order"
className="mt-1 block rounded-md border-gray-300 py-2 pl-3 pr-10 text-base focus:border-sky-600 focus:outline-none focus:ring-sky-600 sm:text-sm"
aria-label="Select to change the ordering of the communities"
>
<option value="relevanceDesc">Date created</option>
<option value="nameAsc">Name - Ascending</option>
<option value="nameDesc">Name - Descending</option>
<option value="members">Most members</option>
</select>
<div>
<OrderSelector
values={[
CommunitySortBy.CreatedAtDesc,
CommunitySortBy.NameAsc,
CommunitySortBy.NameDesc,
]}
/>
</div>
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4 h-full grow content-stretch gap-6 w-full max-w-[1800px] mx-auto px-4 sm:px-10 mt-10">
Expand All @@ -72,6 +82,9 @@ export default async function CommunitiesPage({params}: Props) {
/>
))}
</div>
<div className="sm:px-10">
<Paginator />
</div>
</>
);
}
4 changes: 2 additions & 2 deletions apps/researcher/src/app/[locale]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
FilterSet,
Paginator,
SelectedFilters,
SearchField,
SearchFieldWithLabel,
OrderSelector,
} from 'ui/list';
import {SmallScreenSubMenu, SubMenuButton, SubMenuDialog} from 'ui';
Expand All @@ -46,7 +46,7 @@ function FacetMenu({filterKeysOrder, filters}: FacetMenuProps) {

return (
<>
<SearchField />
<SearchFieldWithLabel />
{filterKeysOrder.map(
filterKey =>
!!filters[filterKey]?.length && (
Expand Down
4 changes: 2 additions & 2 deletions apps/researcher/src/app/[locale]/persons/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
FilterSet,
Paginator,
SelectedFilters,
SearchField,
SearchFieldWithLabel,
OrderSelector,
} from 'ui/list';
import {
Expand Down Expand Up @@ -53,7 +53,7 @@ function FacetMenu({filterKeysOrder, filters}: FacetMenuProps) {

return (
<>
<SearchField />
<SearchFieldWithLabel />
{filterKeysOrder.map(
filterKey =>
!!filters[filterKey]?.length && (
Expand Down
119 changes: 118 additions & 1 deletion apps/researcher/src/lib/community.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import {describe, expect, it} from '@jest/globals';
import {auth} from '@clerk/nextjs';
import {isAdmin, Membership} from './community';
import {
isAdmin,
Membership,
sortCommunities,
CommunitySortBy,
} from './community';

jest.mock('@clerk/nextjs', () => ({
auth: jest.fn().mockImplementation(() => ({
Expand Down Expand Up @@ -92,3 +97,115 @@ describe('isAdmin', () => {
expect(isAdmin(memberships)).toEqual(false);
});
});

describe('sortCommunities', () => {
const communities = [
{
id: 'community2',
name: 'Community 2',
slug: 'community-2',
imageUrl: 'https://example.com/image.png',
createdAt: 1690000000000,
},
{
id: 'community1',
name: 'Community 1',
slug: 'community-1',
imageUrl: 'https://example.com/image.png',
createdAt: 1600000000000,
},
{
id: 'community4',
name: 'Community 4',
slug: 'community-4',
imageUrl: 'https://example.com/image.png',
createdAt: 1680000000000,
},
{
id: 'community3',
name: 'Community 3',
slug: 'community-3',
imageUrl: 'https://example.com/image.png',
createdAt: 1650000000000,
},
{
id: 'community5',
name: 'Community 5',
slug: 'community-5',
imageUrl: 'https://example.com/image.png',
createdAt: 1670000000000,
},
];
it('sorts communities by name ascending', () => {
const sortedCommunities = sortCommunities(
communities,
CommunitySortBy.NameAsc
);
const sortedCommunitiesIds = sortedCommunities.map(
community => community.id
);
expect(sortedCommunitiesIds).toEqual([
'community1',
'community2',
'community3',
'community4',
'community5',
]);
});

it('sorts communities by name descending', () => {
const sortedCommunities = sortCommunities(
communities,
CommunitySortBy.NameDesc
);
const sortedCommunitiesIds = sortedCommunities.map(
community => community.id
);
expect(sortedCommunitiesIds).toEqual([
'community5',
'community4',
'community3',
'community2',
'community1',
]);
});

it('sorts communities by creation date descending', () => {
const sortedCommunities = sortCommunities(
communities,
CommunitySortBy.CreatedAtDesc
);
const sortedCommunitiesIds = sortedCommunities.map(
community => community.id
);
expect(sortedCommunitiesIds).toEqual([
'community2',
'community4',
'community5',
'community3',
'community1',
]);
});

it('works with an empty array', () => {
const sortedCommunities = sortCommunities([], CommunitySortBy.NameAsc);
expect(sortedCommunities).toEqual([]);
});

it('returns the list unsorted if sortBy is an incorrect value', () => {
const sortedCommunities = sortCommunities(
communities,
'incorrect' as CommunitySortBy
);
const sortedCommunitiesIds = sortedCommunities.map(
community => community.id
);
expect(sortedCommunitiesIds).toEqual([
'community2',
'community1',
'community4',
'community3',
'community5',
]);
});
});
Loading

0 comments on commit d6474fc

Please sign in to comment.