Skip to content

Commit

Permalink
feat: add load more button to grant beneficiary box (#1385)
Browse files Browse the repository at this point in the history
  • Loading branch information
andyesp authored Nov 1, 2023
1 parent c3e8589 commit 031957a
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 67 deletions.
35 changes: 12 additions & 23 deletions src/back/routes/proposal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ import {
NewProposalPoll,
NewProposalTender,
PoiType,
ProjectWithUpdate,
ProposalAttributes,
ProposalCommentsInDiscourse,
ProposalRequiredVP,
Expand Down Expand Up @@ -82,6 +81,7 @@ import {
toSortingOrder,
} from '../../entities/Proposal/utils'
import { SNAPSHOT_DURATION } from '../../entities/Snapshot/constants'
import { isSameAddress } from '../../entities/Snapshot/utils'
import { validateUniqueAddresses } from '../../entities/Transparency/utils'
import UpdateModel from '../../entities/Updates/model'
import BidService from '../../services/BidService'
Expand Down Expand Up @@ -645,33 +645,22 @@ async function getGrants(): Promise<CategorizedGrants> {
return await ProjectService.getGrants()
}

// TODO: Still in use by user profile page.
async function getGrantsByUser(req: Request): ReturnType<typeof getGrants> {
async function getGrantsByUser(req: Request) {
const address = validateAddress(req.params.address)
const isCoauthoring = req.query.coauthor === 'true'

let coauthoringProposalIds = new Set<string>()
const coauthoring = await CoauthorModel.findProposals(address, CoauthorStatus.APPROVED)
const coauthoringProposalIds = new Set(coauthoring.map((coauthoringAttributes) => coauthoringAttributes.proposal_id))

if (isCoauthoring) {
const coauthoring = await CoauthorModel.findProposals(address, CoauthorStatus.APPROVED)
coauthoringProposalIds = new Set(coauthoring.map((coauthoringAttributes) => coauthoringAttributes.proposal_id))
}

const grantsResult = await getGrants()

const filterGrants = (grants: ProjectWithUpdate[]) => {
return grants.filter(
(grant) => grant.user.toLowerCase() === address.toLowerCase() || coauthoringProposalIds.has(grant.id)
)
}

const current = filterGrants(grantsResult.current)
const past = filterGrants(grantsResult.past)
const projects = await ProjectService.getProjects()
const filteredGrants = projects.data.filter(
(project) =>
project.type === ProposalType.Grant &&
(isSameAddress(project.user, address) || coauthoringProposalIds.has(project.id))
)

return {
current,
past,
total: current.length + past.length,
data: filteredGrants,
total: filteredGrants.length,
}
}

Expand Down
7 changes: 3 additions & 4 deletions src/clients/Governance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
NewProposalPoll,
NewProposalTender,
PendingProposalsQuery,
Project,
ProjectWithUpdate,
ProposalAttributes,
ProposalCommentsInDiscourse,
Expand Down Expand Up @@ -153,10 +154,8 @@ export class Governance extends API {
return await this.fetch<{ total: number }>(`/projects/tenders-total`, this.options().method('GET'))
}

async getGrantsByUser(user: string, coauthoring?: boolean) {
const grants = await this.fetch<ApiResponse<CategorizedGrants>>(
`/proposals/grants/${user}?coauthoring=${!!coauthoring}`
)
async getGrantsByUser(user: string) {
const grants = await this.fetch<ApiResponse<{ total: number; data: Project[] }>>(`/proposals/grants/${user}`)

return grants.data
}
Expand Down
23 changes: 18 additions & 5 deletions src/components/Profile/GrantBeneficiaryBox.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { useQuery } from '@tanstack/react-query'

import { Governance } from '../../clients/Governance'
import { DEFAULT_QUERY_STALE_TIME } from '../../hooks/constants'
import useFormatMessage from '../../hooks/useFormatMessage'
import useGrantsByUser from '../../hooks/useGrantsByUser'

import GrantBeneficiaryList from './GrantBeneficiaryList'
import { ProfileBox } from './ProfileBox'
Expand All @@ -10,14 +13,24 @@ interface Props {

export default function GrantBeneficiaryBox({ address }: Props) {
const t = useFormatMessage()
const grants = useGrantsByUser(address, true)
const hasGrants = grants.length > 0
const { data: grants } = useQuery({
queryKey: ['grants', address],
queryFn: async () => {
if (address) {
return await Governance.get().getGrantsByUser(address)
}
},
staleTime: DEFAULT_QUERY_STALE_TIME,
enabled: !!address,
})

if (!hasGrants) return null
if (grants?.total === 0 || !grants?.data) {
return null
}

return (
<ProfileBox title={t('page.profile.grants.title')} info={t('page.profile.grants.info')}>
<GrantBeneficiaryList grants={grants} />
<GrantBeneficiaryList grants={grants?.data} address={address} />
</ProfileBox>
)
}
20 changes: 16 additions & 4 deletions src/components/Profile/GrantBeneficiaryList.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,37 @@
import { useMemo } from 'react'
import { useEffect, useMemo, useState } from 'react'

import { Project } from '../../entities/Proposal/types'
import useFormatMessage from '../../hooks/useFormatMessage'
import { useSortingByKey } from '../../hooks/useSortingByKey'
import FullWidthButton from '../Common/FullWidthButton'

import GrantBeneficiaryItem from './GrantBeneficiaryItem'

interface Props {
address: string | null
grants: Project[]
}

const MAX_GRANTS = 4
const MAX_GRANTS = 3

function GrantBeneficiaryList({ grants }: Props) {
function GrantBeneficiaryList({ grants, address }: Props) {
const t = useFormatMessage()
const { sorted } = useSortingByKey(grants, 'enacted_at')
const grantsToShow = useMemo(() => sorted.slice(0, MAX_GRANTS), [sorted])
const [limit, setLimit] = useState(MAX_GRANTS)
const grantsToShow = useMemo(() => sorted.slice(0, limit), [sorted, limit])

useEffect(() => setLimit(MAX_GRANTS), [address])

return (
<>
{grantsToShow.map((grant) => (
<GrantBeneficiaryItem key={grant.id} grant={grant} />
))}
{sorted.length > limit && (
<FullWidthButton onClick={() => setLimit(() => limit + MAX_GRANTS)}>
{t('page.profile.grants.button')}
</FullWidthButton>
)}
</>
)
}
Expand Down
28 changes: 0 additions & 28 deletions src/hooks/useGrantsByUser.ts

This file was deleted.

3 changes: 2 additions & 1 deletion src/intl/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1364,7 +1364,8 @@
"one_time_tx": "One-time payment {time}",
"vested": "{amount} {token} vested",
"released": "{amount} {token} released",
"all_released": "All funds successfully released"
"all_released": "All funds successfully released",
"button": "View more proposals"
},
"delegation": {
"title": "Delegated VP to",
Expand Down
2 changes: 0 additions & 2 deletions static/api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,6 @@ paths:
parameters:
- name: address
$ref: '#/components/parameters/address'
- name: coauthoring
$ref: '#/components/parameters/isCoauthor'
responses:
'200':
$ref: '#/components/responses/200'
Expand Down

0 comments on commit 031957a

Please sign in to comment.