Skip to content

Commit 19b7526

Browse files
committed
Show direct donations
1 parent 7f41efc commit 19b7526

File tree

6 files changed

+145
-47
lines changed

6 files changed

+145
-47
lines changed

packages/builder/src/components/grants/stats/Stats.tsx

Lines changed: 94 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import { Spinner } from "@chakra-ui/react";
2+
import { BaseDonorValues, useDataLayer } from "data-layer";
23
import { useEffect, useState } from "react";
34
import { useSelector } from "react-redux";
45
import { useParams } from "react-router-dom";
56
import { RootState } from "../../../reducers";
67
import { ProjectStats } from "../../../reducers/projects";
78
import RoundDetailsCard from "./RoundDetailsCard";
89
import StatCard from "./StatCard";
10+
import { allChains } from "../../../utils/wagmi";
911

1012
export const slugify = (input: string): string =>
1113
input
@@ -19,9 +21,12 @@ export default function RoundStats() {
1921
const NAText = "N/A";
2022

2123
const params = useParams();
24+
const dataLayer = useDataLayer();
2225
const [details, setDetails] = useState<any>([]);
2326
const [allTimeStats, setAllTimeStats] = useState<any>({
2427
allTimeReceived: 0,
28+
totalCrowdFunding: 0,
29+
totalDirectDonations: 0,
2530
allTimeContributions: 0,
2631
roundsLength: 0,
2732
});
@@ -41,57 +46,93 @@ export default function RoundStats() {
4146
});
4247

4348
useEffect(() => {
44-
const detailsTmp: any[] = [];
45-
let allTime = {
46-
allTimeReceived: 0,
47-
allTimeContributions: 0,
48-
roundsLength: 0,
49-
};
49+
const fetch = async () => {
50+
const detailsTmp: any[] = [];
51+
let allTime = {
52+
allTimeReceived: 0,
53+
totalCrowdFunding: 0,
54+
totalDirectDonations: 0,
55+
allTimeContributions: 0,
56+
roundsLength: 0,
57+
};
58+
59+
let totalDirectDonations = 0;
60+
let totalDirectDonationCount = 0;
61+
62+
const directDonations: BaseDonorValues[] =
63+
await dataLayer.getDirectDonationsByProjectId({
64+
projectId: props.projectID,
65+
chainIds: allChains.map((chain) => chain.id),
66+
});
5067

51-
if (props.stats?.length > 0) {
52-
props.stats.forEach((stat) => {
53-
allTime = {
54-
allTimeReceived:
55-
allTime.allTimeReceived + (stat.success ? stat.fundingReceived : 0),
56-
allTimeContributions:
57-
allTime.allTimeContributions +
58-
(stat.success ? stat.totalContributions : 0),
59-
roundsLength: props.stats.length,
60-
};
61-
62-
const newStat = { ...stat };
63-
if (newStat.uniqueContributors > 0 || newStat.totalContributions > 0) {
64-
if (newStat.fundingReceived === 0) newStat.fundingReceived = NA;
65-
if (newStat.avgContribution === 0) newStat.avgContribution = NA;
66-
}
67-
68-
if (props.rounds[stat.roundId]?.round?.programName) {
69-
detailsTmp.push({
70-
round: props.rounds[stat.roundId].round,
71-
stats: { ...newStat },
72-
});
73-
}
68+
directDonations.forEach((donation) => {
69+
totalDirectDonations += donation.totalAmountDonatedInUsd;
70+
totalDirectDonationCount += donation.totalDonationsCount;
7471
});
75-
}
7672

77-
setAllTimeStats(allTime);
78-
setDetails(detailsTmp);
79-
}, [props.stats, props.rounds]);
73+
if (props.stats?.length > 0) {
74+
props.stats.forEach((stat) => {
75+
allTime = {
76+
...allTime,
77+
totalCrowdFunding:
78+
allTime.totalCrowdFunding +
79+
(stat.success ? stat.fundingReceived : 0),
80+
allTimeContributions:
81+
allTime.allTimeContributions +
82+
(stat.success ? stat.totalContributions : 0),
83+
roundsLength: props.stats.length,
84+
};
85+
86+
const newStat = { ...stat };
87+
if (
88+
newStat.uniqueContributors > 0 ||
89+
newStat.totalContributions > 0
90+
) {
91+
if (newStat.fundingReceived === 0) newStat.fundingReceived = NA;
92+
if (newStat.avgContribution === 0) newStat.avgContribution = NA;
93+
}
94+
95+
if (props.rounds[stat.roundId]?.round?.programName) {
96+
detailsTmp.push({
97+
round: props.rounds[stat.roundId].round,
98+
stats: { ...newStat },
99+
});
100+
}
101+
});
102+
}
103+
104+
allTime.totalDirectDonations = totalDirectDonations;
105+
allTime.allTimeReceived =
106+
allTime.totalCrowdFunding + totalDirectDonations;
107+
allTime.allTimeContributions += totalDirectDonationCount;
108+
109+
setAllTimeStats(allTime);
110+
setDetails(detailsTmp);
111+
};
112+
if (props.projectID) fetch();
113+
}, [props.stats, props.rounds, props.projectID, dataLayer]);
80114

81115
const section = (
82116
description: any,
83117
container: any,
84118
pt: boolean,
85-
key: string
119+
key: string,
120+
spaceBetween?: boolean
86121
) => (
87122
<div
88123
key={key}
89-
className={`grid md:grid-cols-7 sm:grid-cols-1 border-b border-gitcoin-grey-100 pb-10 ${
90-
pt && "pt-10"
91-
}`}
124+
className={`grid ${
125+
spaceBetween ? "md:grid-cols-8" : "md:grid-cols-7"
126+
} sm:grid-cols-1 border-b border-gitcoin-grey-100 pb-10 ${pt && "pt-10"}`}
92127
>
93-
<div className="md:col-span-2">{description}</div>
94-
<div className="md:col-span-4 sm:col-span-1 md:flex space-between">
128+
<div className={`${spaceBetween ? "md:col-span-2" : "md:col-span-1"}`}>
129+
{description}
130+
</div>
131+
<div
132+
className={`${
133+
spaceBetween ? "md:col-span-5" : "md:col-span-6"
134+
} sm:col-span-1 md:flex space-between`}
135+
>
95136
{container}
96137
</div>
97138
<div className="md:col-span-1 sm:col-span-1" />
@@ -131,6 +172,18 @@ export default function RoundStats() {
131172
bg="gitcoin-violet-100"
132173
tooltip="The estimated funding received by this project. This number is not final and may change based on updated data."
133174
/>
175+
<StatCard
176+
heading="Est. Crowdfunding Received"
177+
value={`$${allTimeStats.totalCrowdFunding.toFixed(2)}`}
178+
bg="gitcoin-violet-100"
179+
tooltip="The number of rounds this project has participated in."
180+
/>
181+
<StatCard
182+
heading="Total Direct Donations"
183+
value={`$${allTimeStats.totalDirectDonations.toFixed(2)}`}
184+
bg="gitcoin-violet-100"
185+
tooltip="The number of contributions this project has received."
186+
/>
134187
<StatCard
135188
heading="No. of Contributions"
136189
value={allTimeStats.allTimeContributions}
@@ -193,7 +246,8 @@ export default function RoundStats() {
193246
/>
194247
</>,
195248
true,
196-
`details-${index}`
249+
`details-${index}`,
250+
true
197251
)
198252
)}
199253
</>

packages/builder/src/utils/wagmi.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { providers } from "ethers";
88
import { type Account, type Chain, type Client, type Transport } from "viem";
99
import { Connector } from "wagmi";
1010

11-
const allChains: RChain[] =
11+
export const allChains: RChain[] =
1212
process.env.REACT_APP_ENV === "development" ? allNetworks : mainnetNetworks;
1313

1414
/* TODO: remove hardcoded value once we have environment variables validation */

packages/common/src/allo/backends/allo-v2.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,14 @@ export function getDirectAllocationPoolId(chainId: number) {
9797
return 36;
9898
case 43114:
9999
return 15;
100+
case 534352:
100101
case 534353:
101102
return 22;
102103
case 250:
103104
return 4;
104105
case 1:
105106
return 11;
107+
case 1329:
106108
case 808:
107109
return 8;
108110
case 42:
@@ -130,12 +132,16 @@ export function getDirectAllocationStrategyAddress(chainId: number) {
130132
return "0x86b4329E7CB8674b015477C81356420D79c71A53";
131133
case 534353:
132134
return "0x56662F9c0174cD6ae14b214fC52Bd6Eb6B6eA602";
135+
case 534352:
136+
return "0x9da0a7978b7bd826e06800427cbf1ec1200393e3";
133137
case 250:
134138
return "0x1E18cdce56B3754c4Dca34CB3a7439C24E8363de";
135139
case 1:
136140
return "0x56662F9c0174cD6ae14b214fC52Bd6Eb6B6eA602";
137141
case 808:
138142
return "0x1cfa7A687cd18b99D255bFc25930d3a0b05EB00F";
143+
case 1329:
144+
return "0x7836f59bd6dc1d87a45df8b9a74eefcdf25bc8a9";
139145
case 42:
140146
return "0xeB6325d9daCD1E46A20C02F46E41d4CAE45C0980";
141147
case 1088:

packages/data-layer/src/data-layer.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {
2626
ExpandedApplicationRef,
2727
RoundApplicationPayout,
2828
ProjectApplicationWithRoundAndProgram,
29+
BaseDonorValues,
2930
} from "./data.types";
3031
import {
3132
ApplicationSummary,
@@ -56,6 +57,7 @@ import {
5657
getPaginatedProjects,
5758
getProjectsBySearchTerm,
5859
getRoundsForManagerByAddress,
60+
getDirectDonationsByProjectId,
5961
} from "./queries";
6062
import { mergeCanonicalAndLinkedProjects } from "./utils";
6163

@@ -959,4 +961,19 @@ export class DataLayer {
959961
): Promise<SearchBasedProjectCategory | null> {
960962
return await categories.getSearchBasedCategoryById(id);
961963
}
964+
965+
async getDirectDonationsByProjectId({
966+
projectId,
967+
chainIds,
968+
}: {
969+
projectId: string;
970+
chainIds: number[];
971+
}): Promise<BaseDonorValues[]> {
972+
const response: { rounds: BaseDonorValues[] } = await request(
973+
this.gsIndexerEndpoint,
974+
getDirectDonationsByProjectId,
975+
{ projectId, chainIds },
976+
);
977+
return response.rounds;
978+
}
962979
}

packages/data-layer/src/data.types.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,8 @@ export type v2Project = {
211211
* The linked chains to the canonical project
212212
*/
213213
linkedChains?: number[];
214-
qfRounds? : string[];
215-
dgRounds? : string[];
214+
qfRounds?: string[];
215+
dgRounds?: string[];
216216
};
217217

218218
/**
@@ -257,6 +257,12 @@ export type RoundForExplorer = Omit<RoundGetRound, "applications"> & {
257257
uniqueDonorsCount?: number;
258258
};
259259

260+
export type BaseDonorValues = {
261+
totalAmountDonatedInUsd: number;
262+
totalDonationsCount: number;
263+
uniqueDonorsCount: number;
264+
};
265+
260266
/**
261267
* The project application type for v2
262268
*
@@ -269,11 +275,8 @@ export type ProjectApplication = {
269275
status: ApplicationStatus;
270276
metadataCid: string;
271277
metadata: ProjectApplicationMetadata;
272-
totalDonationsCount: number;
273-
totalAmountDonatedInUsd: number;
274-
uniqueDonorsCount: number;
275278
distributionTransaction: string | null;
276-
};
279+
} & BaseDonorValues;
277280

278281
export type ProjectApplicationForManager = ProjectApplication & {
279282
anchorAddress: Address;

packages/data-layer/src/queries.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -818,3 +818,21 @@ export const getPayoutsByChainIdRoundIdProjectId = gql`
818818
}
819819
}
820820
`;
821+
822+
// 0x4cd0051913234cdd7d165b208851240d334786d6e5afbb4d0eec203515a9c6f3 == DirectDonationsStrategy Id
823+
export const getDirectDonationsByProjectId = gql`
824+
query getDirectDonationsByProjectId($projectId: String!, $chainIds: [Int!]!) {
825+
rounds(
826+
filter: {
827+
strategyId: { equalTo: "0x4cd0051913234cdd7d165b208851240d334786d6e5afbb4d0eec203515a9c6f3" }
828+
chainId: { in: $chainIds }
829+
donations: { every: { projectId: { equalTo: $projectId } } }
830+
}
831+
) {
832+
id
833+
uniqueDonorsCount
834+
totalAmountDonatedInUsd
835+
totalDonationsCount
836+
}
837+
}
838+
`;

0 commit comments

Comments
 (0)