diff --git a/src/Components/Profile/Subcomponents/CrowdfundingView.tsx b/src/Components/Profile/Subcomponents/CrowdfundingView.tsx index 59e6cd22..62990b1f 100644 --- a/src/Components/Profile/Subcomponents/CrowdfundingView.tsx +++ b/src/Components/Profile/Subcomponents/CrowdfundingView.tsx @@ -1,20 +1,161 @@ +import axios from 'axios' +import { useState, useEffect } from 'react' + import type { Item } from '#types/Item' +interface AccountData { + account: { + name: string + type: string + stats: { + balance: { + valueInCents: number + currency: string + } | null + totalAmountReceived: { + valueInCents: number + currency: string + } + totalAmountSpent: { + valueInCents: number + currency: string + } + contributionsCount: number + contributorsCount: number + } + } +} + +interface GraphQLResponse { + data?: T + errors?: { message: string }[] +} + +const GET_TRANSACTIONS = ` + query GetAccountStats($slug: String!) { + account(slug: $slug) { + name + type + stats { + balance { + valueInCents + currency + } + totalAmountReceived(net: true) { + valueInCents + currency + } + totalAmountSpent { + valueInCents + currency + } + contributionsCount + contributorsCount + } + } + } +` + +const token = '9350b1eecb4c70f2b15d85e32df4d4cf3ea80a1f' + +const graphqlClient = axios.create({ + baseURL: 'https://api.opencollective.com/graphql/v2', + headers: { + Authorization: `Bearer ${token}`, + 'Content-Type': 'application/json', + }, +}) + +const formatCurrency = (valueInCents: number, currency: string) => { + const value = valueInCents / 100 + const options: Intl.NumberFormatOptions = { + style: 'currency', + currency, + ...(Math.abs(value) >= 1000 ? { minimumFractionDigits: 0, maximumFractionDigits: 0 } : {}), + } + return new Intl.NumberFormat('de-DE', options).format(value) +} + export const CrowdfundingView = ({ item }: { item: Item }) => { + // Hier wird slug aus dem Item extrahiert. + const slug = item.slug + + const [data, setData] = useState(null) + const [loading, setLoading] = useState(true) + const [error, setError] = useState(null) + + useEffect(() => { + const fetchData = async () => { + setLoading(true) + setError(null) + try { + const response = await graphqlClient.post>('', { + query: GET_TRANSACTIONS, + variables: { slug }, + }) + if (response.data.errors?.length) { + setError(response.data.errors[0].message) + } else { + setData(response.data.data ?? null) + } + } catch (err: unknown) { + if (err instanceof Error) { + setError(err.message) + } else { + throw err + } + } + setLoading(false) + } + + if (slug) { + void fetchData() + } + }, [slug]) + + if (loading) + return ( +
+ +
+ ) + + if (error) { + return

Error: {error}

+ } + + if (!data?.account) { + return ( +

+ No data available for this account. +

+ ) + } + + const { stats } = data.account + const balanceValueInCents = stats.balance?.valueInCents ?? 0 + const currency = stats.balance?.currency ?? 'USD' + const currentBalance = balanceValueInCents + return (
-
-
+
+
+
+
Current Balance
+
{formatCurrency(currentBalance, currency)}
+
Received
-
$89,400
-
from 12 patrons
+
+ {formatCurrency(stats.totalAmountReceived.valueInCents, currency)} +
-
- +
Spent
+
+ {formatCurrency(stats.totalAmountReceived.valueInCents - currentBalance, currency)} +