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

Implement bounty sort by newest and oldest #1340

Closed
wants to merge 7 commits into from
Closed
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
1 change: 1 addition & 0 deletions frontend/app/src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from './useScroll';
export * from './uiHooks';
export * from './usePerson';
export * from './useInViewport';
export * from './useSuperAdmin';
20 changes: 20 additions & 0 deletions frontend/app/src/hooks/useSuperAdmin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { useState, useCallback, useEffect } from 'react';
import { useStores } from '../store';

export const useIsSuperAdmin = () => {
const { main, ui } = useStores();
const [isSuperAdmin, setIsSuperAdmin] = useState(true);

const getIsSuperAdmin = useCallback(async () => {
const admin = await main.getSuperAdmin();
setIsSuperAdmin(admin);
}, [main]);

useEffect(() => {
if (ui.meInfo?.tribe_jwt) {
getIsSuperAdmin();
}
}, [main, ui, getIsSuperAdmin]);

return isSuperAdmin;
};
46 changes: 14 additions & 32 deletions frontend/app/src/pages/superadmin/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@
import React, { useCallback, useEffect, useState } from 'react';
import { EuiLoadingSpinner } from '@elastic/eui';
import styled from 'styled-components';
import { BountyMetrics, BountyStatus } from 'store/main';
import { BountyMetrics, BountyStatus, defaultBountyStatus } from 'store/main';
import { useStores } from 'store';
import moment from 'moment';
import { useInViewPort } from 'hooks';
import { useInViewPort, useIsSuperAdmin } from 'hooks';
import { MyTable } from './tableComponent';
import { Header } from './header';
import { Statistics } from './statistics';
import AdminAccessDenied from './accessDenied';
import { normalizeMetrics } from './utils/metrics';

const Container = styled.body`
height: 100vh; /* Set a fixed height for the container */
Expand All @@ -38,20 +39,20 @@ export interface MockHunterMetrics {
export const SuperAdmin = () => {
//Todo: Remove all comments when metrcis development is done
const { main } = useStores();
const [isSuperAdmin] = useState(true);
const [bounties, setBounties] = useState<any[]>([]);
const [bountyMetrics, setBountyMetrics] = useState<BountyMetrics | undefined>(undefined);
const mockHunterMetrics: MockHunterMetrics = {
hunters_total_paid: 145,
hunters_first_bounty_paid: 12
};
const [bountyStatus, setBountyStatus] = useState<BountyStatus>({
Open: false,
Assigned: false,
Paid: false
...defaultBountyStatus,
Open: false
});
const [sortOrder, setSortOrder] = useState<string>('desc');
const [dropdownValue, setDropdownValue] = useState('all');
const [loading, setLoading] = useState(false);
const isSuperAdmin = useIsSuperAdmin();

/**
* Todo use the same date range,
Expand All @@ -60,22 +61,13 @@ export const SuperAdmin = () => {

const [endDate, setEndDate] = useState(moment().unix());
const [startDate, setStartDate] = useState(moment().subtract(30, 'days').unix());

const [inView, ref] = useInViewPort({
rootMargin: '0px',
threshold: 0.25
});

// const getIsSuperAdmin = useCallback(async () => {
// const admin = await main.getSuperAdmin();
// setIsSuperAdmin(admin);
// }, [main]);
const onDateFilterChange = useCallback((option: string) => setSortOrder(option), []);

// useEffect(() => {
// if (ui.meInfo?.tribe_jwt) {
// getIsSuperAdmin();
// }
// }, [main, ui, getIsSuperAdmin]);
const getBounties = useCallback(async () => {
setLoading(true);
if (startDate && endDate) {
Expand All @@ -87,7 +79,8 @@ export const SuperAdmin = () => {
},
{
resetPage: true,
...bountyStatus
...bountyStatus,
direction: sortOrder
}
);
setBounties(bounties);
Expand All @@ -99,25 +92,12 @@ export const SuperAdmin = () => {
setLoading(false);
}
}
}, [main, startDate, endDate, bountyStatus]);
}, [main, startDate, endDate, bountyStatus, sortOrder]);

useEffect(() => {
getBounties();
}, [getBounties]);

const normalizeMetrics = (data: any): BountyMetrics => ({
bounties_posted: data.BountiesPosted || data.bounties_posted,
bounties_paid: data.BountiesPaid || data.bounties_paid,
bounties_paid_average: data.bounties_paid_average || data.BountiesPaidPercentage,
sats_posted: data.sats_posted || data.SatsPosted,
sats_paid: data.sats_paid || data.SatsPaid,
sats_paid_percentage: data.sats_paid_percentage || data.SatsPaidPercentage,
average_paid: data.average_paid || data.AveragePaid,
average_completed: data.average_completed || data.AverageCompleted,
unique_hunters_paid: data.unique_hunters_paid || data.uniqueHuntersPaid,
new_hunters_paid: data.new_hunters_paid || data.newHuntersPaid
});

const getMetrics = useCallback(async () => {
if (startDate && endDate) {
try {
Expand All @@ -136,7 +116,7 @@ export const SuperAdmin = () => {

return (
<>
{!isSuperAdmin ? (
{isSuperAdmin ? (
<AdminAccessDenied />
) : (
<Container>
Expand All @@ -163,6 +143,8 @@ export const SuperAdmin = () => {
headerIsFrozen={inView}
bountyStatus={bountyStatus}
setBountyStatus={setBountyStatus}
onChangeFilterByDate={onDateFilterChange}
sortOrder={sortOrder}
dropdownValue={dropdownValue}
setDropdownValue={setDropdownValue}
/>
Expand Down
86 changes: 74 additions & 12 deletions frontend/app/src/pages/superadmin/tableComponent/TableStyle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ type FreezeProps = {
freeze: boolean;
};

type styledProps = {
color?: any;
};

const applyFreezeHeaderStyles = ({ freeze = false }: FreezeProps) =>
freeze &&
css`
Expand Down Expand Up @@ -216,6 +220,7 @@ export const BountyHeader = styled.div`
`;

export const Options = styled.div`
height: 20px;
font-size: 15px;
cursor: pointer;
outline: none;
Expand All @@ -226,18 +231,75 @@ export const Options = styled.div`
padding-right: 2px;
`;

export const StyledSelect = styled.select`
color: var(--Text-2, var(--Hover-Icon-Color, #3c3f41));
font-family: Barlow;
font-size: 15px;
font-style: normal;
font-weight: 500;
line-height: normal;
border-radius: 4px;
cursor: pointer;
outline: none;
width: 60px;
border: none;
export const DateFilterWrapper = styled.div<styledProps>`
width: 130px;
height: 20px;
display: flex;
gap: 5px;
flex-direction: row;
justify-content: center;
align-items: center !important;
margin-left: 19px;
user-select: none;
.image {
display: flex;
justify-content: space-between;
gap: 5px;
align-items: center;
width: 36px;
.materialIconImage {
color: ${(p: any) => p.color && p.color.grayish.G200};
cursor: pointer;
font-size: 18px;
margin-top: 4px;
}
}
.filterText {
color: var(--Main-bottom-icons, var(--Hover-Icon-Color, #5f6368));
font-family: Barlow;
font-size: 15px;
font-style: normal;
font-weight: 500;
line-height: normal;
margin-left: 15px;
}
&:hover {
.image {
.materialIconImage {
color: ${(p: any) => p.color && p.color.grayish.G50} !important;
cursor: pointer;
font-size: 18px;
margin-top: 4px;
}
}
.filterText {
color: ${(p: any) => p.color && p.color.grayish.G50};
}
}
&:active {
.image {
.materialIconImage {
color: ${(p: any) => p.color && p.color.grayish.G10} !important;
cursor: pointer;
font-size: 18px;
margin-top: 4px;
}
}
.filterText {
color: ${(p: any) => p.color && p.color.grayish.G10};
}
}
`;

export const DateFilterContent = styled.div<styledProps>`
width: 100%;
height: 100%;
padding: 15px 18px;
user-select: none;
display: flex;
flex-direction: column;
justify-content: space-between;
gap: 5px;
`;

export const StyledSelect2 = styled.select`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,19 +82,19 @@ it('renders "Sort By:" in the document', () => {
expect(getByText('Sort By:')).toBeInTheDocument();
});

it('renders "Date" twice in the document', () => {
const { getAllByText } = render(<MyTable bounties={mockBounties} headerIsFrozen={false} />);
expect(getAllByText('Date')).toHaveLength(2);
it('renders "Date" in the document', () => {
const { getByText } = render(<MyTable bounties={mockBounties} headerIsFrozen={false} />);
expect(getByText('Date')).toBeInTheDocument();
});

it('renders "Assignee" twice in the document', () => {
const { getAllByText } = render(<MyTable bounties={mockBounties} headerIsFrozen={false} />);
expect(getAllByText('Assignee')).toHaveLength(2);
it('renders "Assignee" in the document', () => {
const { getByText } = render(<MyTable bounties={mockBounties} headerIsFrozen={false} />);
expect(getByText('Assignee')).toBeInTheDocument();
});

it('renders "Status" twice in the document', () => {
const { getAllByText } = render(<MyTable bounties={mockBounties} headerIsFrozen={false} />);
expect(getAllByText('Status')).toHaveLength(2);
expect(getAllByText(/Status/i)).toHaveLength(2);
});

it('renders "Status:" in the document', () => {
Expand Down
Loading
Loading