Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(Agreements): improved agreements architecture #224

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 7 additions & 11 deletions packages/epics/src/agreements/components/agreements-list.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,24 @@
import { FC } from 'react';
import { AgreementItem } from '@hypha-platform/graphql/rsc';
import { AgreementCard } from './agreement-card';
import { useAgreements } from '../hooks/use-agreements';
import Link from 'next/link';

type AgreementsListProps = {
page: number;
activeFilter: string;
basePath: string;
agreements?: AgreementItem[];
isLoading?: boolean;
};

export const AgreementsList: FC<AgreementsListProps> = ({
page,
activeFilter,
basePath,
agreements,
isLoading,
}) => {
const { agreements, isLoading } = useAgreements({
page,
...(activeFilter !== 'all' && { filter: { status: activeFilter } }),
});
return (
<div className="agreement-list w-full">
{agreements.map((agreement, index) => (
{agreements?.map((agreement, index) => (
<Link href={`${basePath}/${agreement.slug}`} key={index} scroll={false}>
<AgreementCard key={index} {...agreement} isLoading={isLoading} />
<AgreementCard key={index} {...agreement} isLoading={false} />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should that still be isLoading?

Copy link
Contributor Author

@evgenibir evgenibir Jan 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should that still be isLoading?

In this case, the already loaded agreements will be in the loading state when click Load more, which is not very nice

</Link>
))}
{isLoading ? (
Expand Down
32 changes: 18 additions & 14 deletions packages/epics/src/agreements/components/agreements-section.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
'use client';

import { FC } from 'react';
import { AgreementsList } from './agreements-list';
import { Text } from '@radix-ui/themes';
import { useAgreementsSection } from '../hooks/use-agreements-section';
import { useAgreements } from '../hooks/use-agreements';
import {
SectionFilter,
SectionLoadMore,
Expand All @@ -15,15 +16,19 @@ type AgreementsSectionProps = {

export const AgreementsSection: FC<AgreementsSectionProps> = ({ basePath }) => {
const {
pages,
agreements,
pagination,
isLoading,
activeFilter,
setActiveFilter,
isLoading,
pages,
loadMore,
pagination,
sortOptions,
filterOptions,
} = useAgreementsSection();
} = useAgreements({
page: 1,
filter: 'all',
});

return (
<div className="flex flex-col w-full justify-center items-center">
Expand All @@ -39,17 +44,16 @@ export const AgreementsSection: FC<AgreementsSectionProps> = ({ basePath }) => {
setActiveTab={setActiveFilter}
tabs={filterOptions}
/>
{Array.from({ length: pages }).map((_, index) => (
<AgreementsList
page={index + 1}
key={index}
activeFilter={activeFilter}
basePath={basePath}
/>
))}

<AgreementsList
agreements={agreements}
basePath={basePath}
isLoading={isLoading}
/>

<SectionLoadMore
onClick={loadMore}
disabled={pagination?.totalPages === pages}
disabled={pagination?.totalPages === pages || isLoading}
isLoading={isLoading}
>
<Text>
Expand Down
40 changes: 0 additions & 40 deletions packages/epics/src/agreements/hooks/use-agreements-section.ts

This file was deleted.

59 changes: 49 additions & 10 deletions packages/epics/src/agreements/hooks/use-agreements.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,72 @@
'use client';

import React from 'react';
import useSWR from 'swr';
import {
AgreementItem,
FilterParams,
PaginationMetadata,
fetchAgreements,
} from '@hypha-platform/graphql/rsc';

import {
FILTER_OPTIONS_AGREEMENTS,
SORT_OPTIONS,
} from '../../common/constants';
type UseAgreementsReturn = {
agreements: AgreementItem[];
pagination?: PaginationMetadata;
isLoading: boolean;
activeFilter: string;
setActiveFilter: React.Dispatch<React.SetStateAction<string>>;
pages: number;
loadMore: () => void;
sortOptions: typeof SORT_OPTIONS;
filterOptions: typeof FILTER_OPTIONS_AGREEMENTS;
};

export const useAgreements = ({
page = 1,
filter,
filter: initialFilter = 'all',
}: {
page?: number;
filter?: FilterParams;
filter?: string;
}): UseAgreementsReturn => {
const { data, isLoading } = useSWR(['agreements', page, filter], () =>
fetchAgreements({ page, filter })
const [activeFilter, setActiveFilter] = React.useState(initialFilter);
const [pages, setPages] = React.useState(page);
const [allAgreements, setAllAgreements] = React.useState<AgreementItem[]>([]);
const filter = activeFilter === 'all' ? undefined : { status: activeFilter };

const { data, isLoading } = useSWR(
() => (activeFilter !== null ? ['agreements', pages, filter] : null),
() =>
fetchAgreements({
page: pages,
filter,
}),
{ revalidateOnFocus: false }
);

React.useEffect(() => {
if (data && data.agreements) {
setAllAgreements((prev) => [...prev, ...data.agreements]);
}
}, [data]);

const loadMore = React.useCallback(() => {
if (!data?.pagination?.hasNextPage) return;
setPages(pages + 1);
}, [pages, data?.pagination?.hasNextPage]);

React.useEffect(() => {
setPages(1);
setAllAgreements(data?.agreements || []);
}, [activeFilter]);

return {
agreements: data?.agreements || [],
agreements: allAgreements,
pagination: data?.pagination,
isLoading,
activeFilter,
setActiveFilter,
pages,
loadMore,
sortOptions: SORT_OPTIONS,
filterOptions: FILTER_OPTIONS_AGREEMENTS,
};
};
Loading