diff --git a/apps/web/public/csp.json b/apps/web/public/csp.json index e506625bd29..8a4b953a88e 100644 --- a/apps/web/public/csp.json +++ b/apps/web/public/csp.json @@ -100,6 +100,7 @@ "https://x6ahx1oagk.execute-api.us-east-2.amazonaws.com", "https://mainnet.era.zksync.io/", "https://8mr3mthjba.execute-api.us-east-2.amazonaws.com", + "https://api.ethfollow.xyz/api/v1/", "wss://*.uniswap.org", "wss://relay.walletconnect.com", "wss://relay.walletconnect.org", diff --git a/apps/web/src/components/AccountDrawer/Stats.tsx b/apps/web/src/components/AccountDrawer/Stats.tsx new file mode 100644 index 00000000000..a5dd31ab190 --- /dev/null +++ b/apps/web/src/components/AccountDrawer/Stats.tsx @@ -0,0 +1,37 @@ +import { LoadingBubble } from 'components/Tokens/loading' +import useEFPStats from 'hooks/useEFPStats' +import { Link } from 'react-router-dom' +import { Flex, Text } from 'ui/src' + +export default function Stats({ account }: { account: string }) { + const { stats, isLoading, getStatLink } = useEFPStats(account) + + return ( + + + + + Following + + {isLoading ? ( + + ) : ( + {stats?.following_count ?? '-'} + )} + + + + + + Followers + + {isLoading ? ( + + ) : ( + {stats?.followers_count ?? '-'} + )} + + + + ) +} diff --git a/apps/web/src/components/AccountDrawer/Status.tsx b/apps/web/src/components/AccountDrawer/Status.tsx index 477fef68161..7604768eb8a 100644 --- a/apps/web/src/components/AccountDrawer/Status.tsx +++ b/apps/web/src/components/AccountDrawer/Status.tsx @@ -1,4 +1,5 @@ import { AddressDisplay } from 'components/AccountDetails/AddressDisplay' +import Stats from 'components/AccountDrawer/Stats' import StatusIcon from 'components/Identicon/StatusIcon' import styled from 'lib/styled-components' import { CopyHelper, ThemedText } from 'theme/components' @@ -45,6 +46,7 @@ export function Status({ )} + ) diff --git a/apps/web/src/hooks/useEFPStats.ts b/apps/web/src/hooks/useEFPStats.ts new file mode 100644 index 00000000000..a79d73f792a --- /dev/null +++ b/apps/web/src/hooks/useEFPStats.ts @@ -0,0 +1,27 @@ +import { useCallback, useEffect, useState } from 'react' +import { StatsResponse, fetchEFPStats } from 'utils/fetchEFPStats' + +export default function useEFPStats(nameOrAddress: string | Address) { + const [stats, setStats] = useState(null) + const [isLoading, setIsLoading] = useState(false) + + const fetchStats = useCallback(async () => { + const fetchedStats = await fetchEFPStats(nameOrAddress) + setStats(fetchedStats) + setIsLoading(false) + }, [nameOrAddress]) + + useEffect(() => { + setIsLoading(true) + fetchStats() + }, [fetchStats]) + + const getStatLink = useCallback( + (stat: string) => { + return `https://ethfollow.xyz/${nameOrAddress}?tab=${stat}` + }, + [nameOrAddress], + ) + + return { stats, isLoading, getStatLink } +} diff --git a/apps/web/src/utils/fetchEFPStats.ts b/apps/web/src/utils/fetchEFPStats.ts new file mode 100644 index 00000000000..bc65a35068d --- /dev/null +++ b/apps/web/src/utils/fetchEFPStats.ts @@ -0,0 +1,26 @@ +import { Address } from 'viem' + +export type StatsResponse = { + followers_count: number + following_count: number +} + +export async function fetchEFPStats(nameOrAddress: string | Address) { + const EFP_API_URL = 'https://api.ethfollow.xyz/api/v1' + const url = `${EFP_API_URL}/users/${nameOrAddress}/stats?cache=fresh` + + try { + const response = await fetch(url, { + method: 'GET', + cache: 'default', + headers: { + 'Content-Type': 'application/json', + Accept: 'application/json', + }, + }) + const data = (await response.json()) as StatsResponse + return data + } catch (error) { + return null + } +}