From d7c8c4143db23330578b3bb163dac782a1ee2be2 Mon Sep 17 00:00:00 2001 From: LewisB Date: Sun, 20 Oct 2024 18:01:56 +0700 Subject: [PATCH] add: totalStats subgraph hook --- packages/app/src/components/ActionButton.tsx | 34 +++++++++ packages/app/src/hooks/index.ts | 1 + packages/app/src/hooks/useTotalStats.ts | 38 ++++++++++ packages/app/src/pages/HomePage.tsx | 70 ++++++++----------- packages/app/src/subgraph/index.ts | 1 + packages/app/src/subgraph/useSubgraphData.ts | 5 ++ .../app/src/subgraph/useSubgraphTotalStats.ts | 22 ++++++ packages/app/src/theme/theme.ts | 11 ++- 8 files changed, 141 insertions(+), 41 deletions(-) create mode 100644 packages/app/src/components/ActionButton.tsx create mode 100644 packages/app/src/hooks/useTotalStats.ts create mode 100644 packages/app/src/subgraph/useSubgraphTotalStats.ts diff --git a/packages/app/src/components/ActionButton.tsx b/packages/app/src/components/ActionButton.tsx new file mode 100644 index 00000000..0a83c637 --- /dev/null +++ b/packages/app/src/components/ActionButton.tsx @@ -0,0 +1,34 @@ +import { Box, Link, Pressable, Text } from 'native-base'; + +type ActionButtonProps = { + href?: string; + text: string; + bg: string; + textColor: string; + onPress?: any; + buttonStyles?: any; +}; + +const ActionButton = ({ href, text, bg, textColor, onPress, buttonStyles }: ActionButtonProps) => { + const { buttonContainer, button, buttonText } = buttonStyles ?? {}; + + const content = ( + + + {text} + + + ); + + if (href) { + return ( + + {content} + + ); + } + + return {content}; +}; + +export default ActionButton; diff --git a/packages/app/src/hooks/index.ts b/packages/app/src/hooks/index.ts index 47681548..c143fa71 100644 --- a/packages/app/src/hooks/index.ts +++ b/packages/app/src/hooks/index.ts @@ -6,3 +6,4 @@ export * from './useContractCalls'; export * from './useGetTokenPrice'; export * from './useIsStewardVerified'; export * from './useEthers'; +export * from './useTotalStats'; diff --git a/packages/app/src/hooks/useTotalStats.ts b/packages/app/src/hooks/useTotalStats.ts new file mode 100644 index 00000000..9527c06a --- /dev/null +++ b/packages/app/src/hooks/useTotalStats.ts @@ -0,0 +1,38 @@ +import { useMemo } from 'react'; + +import { useSubgraphTotalStats } from '../subgraph'; +import { formatGoodDollarAmount } from '../lib/calculateGoodDollarAmounts'; + +type StatsFormatted = { + amount: string; + copy: string; +}; +type TotalStats = { + totalDonations: StatsFormatted; + totalPools: StatsFormatted; + totalMembers: StatsFormatted; +}; + +export const useTotalStats = (): TotalStats | undefined => { + const stats = useSubgraphTotalStats(); + + return useMemo(() => { + const totalDonations = stats?.collectives?.reduce((acc, collective) => acc + Number(collective.totalDonations), 0); + const donationsFormatted = formatGoodDollarAmount(totalDonations?.toString() ?? '0'); + + return { + totalPools: { + amount: stats?.activeCollectives?.length.toString() ?? '0', + copy: 'GoodCollective pools', + }, + totalDonations: { + amount: 'G$ ' + donationsFormatted, + copy: 'Total Donations', + }, + totalMembers: { + amount: stats?.stewards?.length.toString() ?? '0', + copy: 'GoodCollective Members Paid', + }, + }; + }, [stats]); +}; diff --git a/packages/app/src/pages/HomePage.tsx b/packages/app/src/pages/HomePage.tsx index a8b2d67f..ee71e882 100644 --- a/packages/app/src/pages/HomePage.tsx +++ b/packages/app/src/pages/HomePage.tsx @@ -1,8 +1,10 @@ import { useRef } from 'react'; import { withTheme } from '@gooddollar/good-design'; +import { Box, HStack, Text, useMediaQuery, VStack, ScrollView, Spinner } from 'native-base'; -import { Box, HStack, Link, Text, Pressable, useMediaQuery, VStack, ScrollView } from 'native-base'; +import { useTotalStats } from '../hooks'; +import ActionButton from '../components/ActionButton'; import CollectiveHomeCard from '../components/CollectiveHomeCard'; import Layout from '../components/Layout/Layout'; import { InterSemiBold } from '../utils/webFonts'; @@ -80,24 +82,10 @@ export const theme = { }, }; -const placeHolderTotalStats = { - pools: { - amount: 'G$ 230', - copy: 'GoodCollective pools', - }, - totalDonations: { - amount: 'G$ 2,300.000', - copy: 'Total donations', - }, - totalMembers: { - amount: 'G$ 230', - copy: 'Total members', - }, -}; - const HomePage = withTheme({ name: 'HomePage' })(({ containerStyles, buttonStyles }: HomePageProps) => { const collectives = useCollectivesMetadata(); - const { buttonContainer, button, buttonText } = buttonStyles ?? {}; + const totalStats = useTotalStats(); + const { body, sectionContainer, sectionContainerDesktop } = containerStyles ?? {}; const [isDesktopResolution] = useMediaQuery({ @@ -112,6 +100,8 @@ const HomePage = withTheme({ name: 'HomePage' })(({ containerStyles, buttonStyle } }; + if (!totalStats) return ; + return ( @@ -129,8 +119,8 @@ individuals and communities by providing direct digital payments to those who ne Impact to Date - {Object.values(placeHolderTotalStats).map(({ amount, copy }) => ( - + {Object.values(totalStats).map(({ amount, copy }) => ( + {amount} @@ -141,29 +131,29 @@ individuals and communities by providing direct digital payments to those who ne - - - - How it works - - - + - - - - Donate to a GoodCollective - - - - - - - Create a GoodCollective - - - + + diff --git a/packages/app/src/subgraph/index.ts b/packages/app/src/subgraph/index.ts index 4f3c6373..6c9d8783 100644 --- a/packages/app/src/subgraph/index.ts +++ b/packages/app/src/subgraph/index.ts @@ -6,3 +6,4 @@ export * from './useSubgraphCollective'; export * from './useSubgraphIpfsCollective'; export * from './useSubgraphClaim'; export * from './useSubgraphSupportEvent'; +export * from './useSubgraphTotalStats'; diff --git a/packages/app/src/subgraph/useSubgraphData.ts b/packages/app/src/subgraph/useSubgraphData.ts index aa45007a..7f5c7f38 100644 --- a/packages/app/src/subgraph/useSubgraphData.ts +++ b/packages/app/src/subgraph/useSubgraphData.ts @@ -17,6 +17,11 @@ export type StewardsSubgraphResponse = { stewards?: SubgraphSteward[] }; export type DonorCollectiveSubgraphResponse = { donorCollectives?: SubgraphDonorCollective[] }; export type ClaimsSubgraphResponse = { claims?: SubgraphClaim[] }; export type SupportEventsSubgraphResponse = { supportEvents?: SubgraphSupportEvent[] }; +export type TotalStatsCollectivesResponse = { + activeCollectives: { id: string }[]; + collectives: { totalDonations: string }[]; + stewards: { id: string }[]; +}; export function useSubgraphData( query: DocumentNode | TypedDocumentNode, diff --git a/packages/app/src/subgraph/useSubgraphTotalStats.ts b/packages/app/src/subgraph/useSubgraphTotalStats.ts new file mode 100644 index 00000000..3297352a --- /dev/null +++ b/packages/app/src/subgraph/useSubgraphTotalStats.ts @@ -0,0 +1,22 @@ +import { gql } from '@apollo/client'; +import { TotalStatsCollectivesResponse, useSubgraphData } from './useSubgraphData'; + +const collectivesTotalStats = gql` + query COLLECTIVES_TOTAL_STATS { + stewards(where: { or: [{ totalEarned_gt: 0 }, { totalUBIEarned_gt: 0 }] }) { + id + } + collectives(where: { totalDonations_gt: 0 }) { + totalDonations + } + activeCollectives: collectives { + id + } + } +`; + +export function useSubgraphTotalStats(): TotalStatsCollectivesResponse | undefined { + const response = useSubgraphData(collectivesTotalStats); + + return response as TotalStatsCollectivesResponse; +} diff --git a/packages/app/src/theme/theme.ts b/packages/app/src/theme/theme.ts index a7993dd1..f8fc57cb 100644 --- a/packages/app/src/theme/theme.ts +++ b/packages/app/src/theme/theme.ts @@ -8,7 +8,7 @@ export const nbTheme = extendTheme({ fontConfig: getPlatformFamilies(fontConfig), colors: { /* g$ design system */ - primary: '#00AFFF', + gdPrimary: '#00AFFF', primaryHoverDark: '#0075AC', white: '#FFFFFF', black: '#000000', @@ -81,6 +81,15 @@ export const nbTheme = extendTheme({ components: { ...components, ...pages, + Spinner: { + variants: { + 'page-loader': () => ({ + borderWidth: '0', + color: 'gdPrimary', + paddingBottom: 4, + }), + }, + }, Text: { baseStyle: { color: 'goodGrey.600',