Skip to content

Commit

Permalink
feat: Add bounty filters to profile when viewing created or assigned …
Browse files Browse the repository at this point in the history
…bounties
  • Loading branch information
jordan-ae committed Mar 11, 2024
1 parent 6364e08 commit c82e648
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 47 deletions.
48 changes: 48 additions & 0 deletions src/pages/people/tabs/Wanted.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ beforeAll(() => {
mockUsehistory();
});

jest.mock("remark-gfm", () => null);

jest.mock("rehype-raw", () => null)

jest.mock('hooks', () => ({
...jest.requireActual('hooks'),
usePerson: jest.fn()
Expand Down Expand Up @@ -73,6 +77,50 @@ describe('Wanted Component', () => {
});
});


test('Correct calls are made when boxes are clicked', async () => {
const userBounty = { ...mockBounties[0], body: {} } as any;
userBounty.body = {
...userBounty.bounty,
owner_id: person.owner_pubkey,
title: 'test bounty here',
description: 'custom ticket for testing'
};

(usePerson as jest.Mock).mockImplementation(() => ({
person: {},
canEdit: false
}));

(useStores as jest.Mock).mockReturnValue({
main: {
getPersonCreatedBounties: jest.fn(() => [userBounty])
},
ui: {
selectedPerson: '123',
meInfo: {
owner_alias: 'test'
}
}
});

const mockedPersonAssignedBounites = jest
.spyOn(mainStore, 'getPersonCreatedBounties')
.mockReturnValue(Promise.resolve([userBounty]));
act(async () => {
const { getAllByTestId } = render(
<MemoryRouter initialEntries={['/p/1234/bounties']}>
<Route path="/p/:uuid/bounties" component={Wanted} />
</MemoryRouter>
);
await waitFor(() => getAllByTestId('user-created-bounty'));

expect(screen.getByText("Bounties")).toBeInTheDocument()

expect(mockedPersonAssignedBounites).toHaveBeenCalledWith();
});
});

test('Should render correct number of bounties created by the user', async () => {
const createdMockBounties = Array.from({ length: 15 }, (_: any, index: number) => ({
...(mockBounties[0] || {}),
Expand Down
47 changes: 29 additions & 18 deletions src/pages/people/tabs/Wanted.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import NoneSpace from 'people/utils/NoneSpace';
import { PostBounty } from 'people/widgetViews/postBounty';
import WantedView from 'people/widgetViews/WantedView';
import PageLoadSpinner from 'people/utils/PageLoadSpinner';
import React, { useEffect, useState } from 'react';
import React, { useCallback, useEffect, useState } from 'react';
import { Route, Switch, useHistory, useRouteMatch, useParams } from 'react-router-dom';
import { useStores } from 'store';
import { paginationQueryLimit } from 'store/main';
Expand Down Expand Up @@ -54,17 +54,28 @@ export const Wanted = observer(() => {
const [loading, setIsLoading] = useState<boolean>(false);
const [page, setPage] = useState(1);
const [hasMoreBounties, setHasMoreBounties] = useState(true);
const [sort, setSort] = useState('paid');

const Status = ['open', 'assingned', 'paid'];
const defaultStatus: Record<string, boolean> = {
Open: false,
Assigned: false,
Paid: false
};

const [checkboxIdToSelectedMap, setCheckboxIdToSelectedMap] = useState(defaultStatus);

const Status = Object.keys(defaultStatus);

const applyFilters = (id: string) => {
setCheckboxIdToSelectedMap({ ...defaultStatus, [id]: !checkboxIdToSelectedMap[id] });
};

// Function to fetch user tickets with pagination
const getUserTickets = async () => {
const getUserTickets = useCallback(async () => {
setIsLoading(true);

// Fetch bounties for the specified page and limit
const response = await main.getPersonCreatedBounties(
{ page: page, limit: paginationQueryLimit, sortBy: sort },
{ page: page, limit: paginationQueryLimit, sortBy: 'created', ...checkboxIdToSelectedMap },
uuid
);

Expand All @@ -73,29 +84,29 @@ export const Wanted = observer(() => {
setHasMoreBounties(false);
}
// Update the displayed bounties by appending the new bounties
setDisplayedBounties((prevBounties: BountyType[]) => [...prevBounties, ...response]);
setDisplayedBounties(response);
setIsLoading(false);
};
}, [checkboxIdToSelectedMap, main, page, uuid]);

const nextBounties = async () => {
const nextPage = page + 1;
setPage(nextPage);
// Fetch bounties for the next page
const response = await main.getPersonCreatedBounties(
{ page: nextPage, limit: paginationQueryLimit, sortBy: sort },
{ page: nextPage, limit: paginationQueryLimit, ...checkboxIdToSelectedMap },
uuid
);
// Check if the response has fewer bounties than the limit, indicating no more bounties to load
if (response.length < paginationQueryLimit) {
setHasMoreBounties(false);
}
// Update the displayed bounties by appending the new bounties
setDisplayedBounties((prevBounties: BountyType[]) => [...prevBounties, ...response]);
setDisplayedBounties(response);
};

useEffect(() => {
getUserTickets();
}, [main, sort]);
}, [main, checkboxIdToSelectedMap, getUserTickets]);

if (!main.createdBounties?.length && !loading) {
return (
Expand Down Expand Up @@ -140,17 +151,17 @@ export const Wanted = observer(() => {
alignItems: 'center'
}}
>
<h4>Bounties {sort}</h4>
<h4>Bounties </h4>
<div style={{ display: 'flex' }}>
<EuiCheckboxGroup
style={{ display: 'flex', alignItems: 'center', gap: 10, marginRight: 20 }}
options={Status.map((status: any) => ({
label: `${status}`,
id: status
style={{ display: 'flex', alignItems: 'center', gap: 20, marginRight: 20, }}
options={Status.map((status: string) => ({
label: status,
id: status,
}))}
idToSelectedMap={{ [sort]: true }}
onChange={(id: any) => {
setSort(id);
idToSelectedMap={checkboxIdToSelectedMap}
onChange={(optionId: any) => {
applyFilters(optionId);
}}
/>
{canEdit && <PostBounty widget="bounties" />}
Expand Down
64 changes: 37 additions & 27 deletions src/people/widgetViews/UserTicketsView.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react';
import React, { useCallback, useEffect, useState } from 'react';
import { Route, Switch, useParams, useRouteMatch, Router } from 'react-router-dom';
import { useStores } from 'store';
import { EuiCheckboxGroup } from '@elastic/eui';
Expand Down Expand Up @@ -51,8 +51,6 @@ const UserTickets = () => {
const isMobile = useIsMobile();
const { path, url } = useRouteMatch();

const Status = ['Assigned', 'Paid'];

const [deletePayload, setDeletePayload] = useState<object>({});
const [showDeleteModal, setShowDeleteModal] = useState<boolean>(false);
const closeModal = () => setShowDeleteModal(false);
Expand All @@ -61,10 +59,22 @@ const UserTickets = () => {
const [loading, setIsLoading] = useState<boolean>(true);
const [hasMoreBounties, setHasMoreBounties] = useState(true);
const [bountyOwner, setBountyOwner] = useState<Person>();
const [sort, setSort] = useState('');
const [page, setPage] = useState(1);
const paginationLimit = 20;

const defaultStatus: Record<string, boolean> = {
Assigned: false,
Open: false,
};

const [checkboxIdToSelectedMap, setCheckboxIdToSelectedMap] = useState(defaultStatus);

const Status = Object.keys(defaultStatus);

const applyFilters = (id: string) => {
setCheckboxIdToSelectedMap({ ...defaultStatus, [id]: !checkboxIdToSelectedMap[id] });
};

function onPanelClick(id: number, index: number) {
history.push({
pathname: `${url}/${id}/${index}`
Expand Down Expand Up @@ -99,35 +109,35 @@ const UserTickets = () => {
closeModal();
};

const getUserTickets = async () => {
const getUserTickets = useCallback(async () => {
setIsLoading(true);
const response = await main.getPersonAssignedBounties(
{ page: page, limit: paginationLimit },
uuid
);
if (response.length < paginationLimit) {
setHasMoreBounties(false);
}
setDisplayedBounties((prevBounties: BountyType[]) => [...prevBounties, ...response]);
setIsLoading(false);
};
const response = await main.getPersonAssignedBounties(
{ page: page, limit: paginationLimit, ...checkboxIdToSelectedMap },
uuid
);
if (response.length < paginationLimit) {
setHasMoreBounties(false);
}
setDisplayedBounties(response);
setIsLoading(false);
}, [ main, page, uuid, checkboxIdToSelectedMap]);

const nextBounties = async () => {
const nextPage = page + 1;
setPage(nextPage);
const response = await main.getPersonAssignedBounties(
{ page: nextPage, limit: paginationLimit, sortBy: sort },
{ page: nextPage, limit: paginationLimit },
uuid
);
if (response.length < paginationLimit) {
setHasMoreBounties(false);
}
setDisplayedBounties((prevBounties: BountyType[]) => [...prevBounties, ...response]);
setDisplayedBounties(response);
};

useEffect(() => {
getUserTickets();
}, [main, sort]);
}, [main, getUserTickets, checkboxIdToSelectedMap],);

const listItems =
displayedBounties && displayedBounties.length ? (
Expand Down Expand Up @@ -183,19 +193,19 @@ const UserTickets = () => {
alignItems: 'center'
}}
>
<h4>Assigned Bounties {sort}</h4>
<h4>Assigned Bounties</h4>
<div style={{ display: 'flex' }}>
<EuiCheckboxGroup
style={{ display: 'flex', gap: 20, alignItems: 'center', alignContent: 'center' }}
options={Status.map((status: any) => ({
label: `${status}`,
<EuiCheckboxGroup
style={{ display: 'flex', alignItems: 'center', gap: 10, marginRight: 20 }}
options={Status.map((status: string) => ({
label: status,
id: status
}))}
idToSelectedMap={{ [sort]: true }}
onChange={(id: any) => {
setSort(id);
idToSelectedMap={checkboxIdToSelectedMap}
onChange={(optionId: any) => {
applyFilters(optionId);
}}
/>
/>
</div>
</div>
{!loading ? listItems : ''}
Expand Down
4 changes: 2 additions & 2 deletions src/store/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -935,7 +935,7 @@ export class MainStore {
}

async getPersonAssignedBounties(queryParams?: any, uuid?: string): Promise<PersonBounty[]> {
queryParams = { ...queryParams, search: uiStore.searchText };
queryParams = { ...queryParams, ...(uiStore.searchText ? { search: uiStore.searchText} : {}) };

const query = this.appendQueryParams(`people/wanteds/assigned/${uuid}`, paginationQueryLimit, {
sortBy: 'paid',
Expand Down Expand Up @@ -982,7 +982,7 @@ export class MainStore {
}

async getPersonCreatedBounties(queryParams?: any, uuid?: string): Promise<PersonBounty[]> {
queryParams = { ...queryParams, search: uiStore.searchText };
queryParams = { ...queryParams, ...(uiStore.searchText ? { search: uiStore.searchText } : {}) };

const query = this.appendQueryParams(`people/wanteds/created/${uuid}`, paginationQueryLimit, {
...queryParams
Expand Down

0 comments on commit c82e648

Please sign in to comment.