-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #25 from Giveth/feat/recurring_donations_integration
feat: add recurring donations (count & USD totals statistics)
- Loading branch information
Showing
11 changed files
with
662 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import React, { useState } from 'react'; | ||
import { | ||
H2, | ||
H4, | ||
H6, | ||
IconHelpFilled16, | ||
neutralColors, | ||
Subline, | ||
} from '@giveth/ui-design-system'; | ||
import styled from 'styled-components'; | ||
import { | ||
firstOfNextMonth, | ||
firstOfGiveth, | ||
thousandsSeparator, | ||
} from '../../../lib/helpers'; | ||
import { Col, Row } from '../../styled-components/grid'; | ||
import { FlexCenter } from '../../styled-components/flex'; | ||
import { IconWithTooltip } from '../../IconWithTooltip'; | ||
import Spinner from '../../Spinner'; | ||
import useRecurringDonationsCount from '../../../hooks/useRecurringDonationsCount'; | ||
import RecurringDonationsCountChat from './charts/RecurringDonationsCountChat'; | ||
import CheckBox from '../../CheckBox'; | ||
import DatePicker from '../../DatePicker'; | ||
import RecurringDonationsCountTokenChart from './charts/RecurringDonationsCountTokenChart'; | ||
|
||
const RecurringDonationsCount = () => { | ||
const [fromDate, setFromDate] = useState(firstOfGiveth()); | ||
const [toDate, setToDate] = useState(firstOfNextMonth()); | ||
const [onlyVerified, setOnlyVerified] = useState(false); | ||
const { recurringDonationsCount, loading } = useRecurringDonationsCount( | ||
fromDate, | ||
toDate, | ||
undefined, | ||
onlyVerified, | ||
); | ||
|
||
const { total, totalPerMonthAndYear, totalPerToken } = | ||
recurringDonationsCount || {}; | ||
|
||
return ( | ||
<RowStyled> | ||
<Col md={4}> | ||
<FlexCenter gap='10px'> | ||
<H4>Recurring Donations Count </H4> | ||
<IconWithTooltip | ||
icon={<IconHelpFilled16 />} | ||
direction={'top'} | ||
> | ||
<TooltipBody> | ||
Total number of recurring donations during the | ||
selected timeframe, including anonymous recurring | ||
donations. | ||
</TooltipBody> | ||
</IconWithTooltip> | ||
</FlexCenter> | ||
</Col> | ||
<Col md={4}> | ||
<div> | ||
From: <DatePicker date={fromDate} setDate={setFromDate} /> | ||
</div> | ||
<br /> | ||
<div> | ||
To: <DatePicker date={toDate} setDate={setToDate} /> | ||
</div> | ||
<br /> | ||
<CheckBox | ||
checked={onlyVerified} | ||
onChange={setOnlyVerified} | ||
label='To verified projects only' | ||
/> | ||
</Col> | ||
<Col md={1} /> | ||
<Col md={2}> | ||
<H6>Total:</H6> | ||
{loading ? <Spinner /> : <H2>{thousandsSeparator(total)}</H2>} | ||
</Col> | ||
{loading ? ( | ||
<Spinner /> | ||
) : ( | ||
<RecurringDonationsCountChat | ||
totalPerMonthAndYear={totalPerMonthAndYear!} | ||
/> | ||
)} | ||
{loading ? ( | ||
<Spinner /> | ||
) : ( | ||
<RecurringDonationsCountTokenChart | ||
rDonationsPerToken={totalPerToken} | ||
/> | ||
)} | ||
</RowStyled> | ||
); | ||
}; | ||
|
||
const TooltipBody = styled(Subline)` | ||
color: ${neutralColors.gray[100]}; | ||
width: 270px; | ||
`; | ||
|
||
const RowStyled = styled(Row)` | ||
margin-top: 40px; | ||
align-items: center; | ||
margin-bottom: 40px; | ||
`; | ||
|
||
export default RecurringDonationsCount; |
110 changes: 110 additions & 0 deletions
110
src/components/views/home/RecurringDonationsTotalUsd.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import styled from 'styled-components'; | ||
import React, { useState } from 'react'; | ||
import { | ||
H2, | ||
H4, | ||
H6, | ||
IconHelpFilled16, | ||
neutralColors, | ||
Subline, | ||
} from '@giveth/ui-design-system'; | ||
import { Col, Row } from '../../styled-components/grid'; | ||
import Spinner from '../../Spinner'; | ||
import useRecurringDonationsTotalUsd from '../../../hooks/useRecurringDonationsTotalUsd'; | ||
import { | ||
firstOfNextMonth, | ||
firstOfGiveth, | ||
thousandsSeparator, | ||
} from '../../../lib/helpers'; | ||
import { IconWithTooltip } from '../../IconWithTooltip'; | ||
import { FlexCenter } from '../../styled-components/flex'; | ||
import RecurringDonationsTotalChart from './charts/RecurringDonationsTotalChart'; | ||
import CheckBox from '../../CheckBox'; | ||
import DatePicker from '../../DatePicker'; | ||
import RecurringDonationsTotalTokenChart from './charts/RecurringDonationsTotalTokenChart'; | ||
|
||
const RecurringDonationsTotalUsd = () => { | ||
const [fromDate, setFromDate] = useState(firstOfGiveth()); | ||
const [toDate, setToDate] = useState(firstOfNextMonth()); | ||
const [onlyVerified, setOnlyVerified] = useState(false); | ||
const { recurringDonationsTotaStreanedlUsd, loading } = | ||
useRecurringDonationsTotalUsd( | ||
fromDate, | ||
toDate, | ||
undefined, | ||
onlyVerified, | ||
); | ||
|
||
const { total, totalPerMonthAndYear, totalPerToken } = | ||
recurringDonationsTotaStreanedlUsd || {}; | ||
|
||
return ( | ||
<RowStyled> | ||
<Col md={4}> | ||
<FlexCenter gap='14px'> | ||
<H4>Total Recurring Donations ($)</H4> | ||
<IconWithTooltip | ||
icon={<IconHelpFilled16 />} | ||
direction={'top'} | ||
> | ||
<TooltipBody> | ||
Total sum of all recurring donations value in USD | ||
during the selected timeframe. | ||
</TooltipBody> | ||
</IconWithTooltip> | ||
</FlexCenter> | ||
</Col> | ||
<Col md={4}> | ||
<div> | ||
From: <DatePicker date={fromDate} setDate={setFromDate} /> | ||
</div> | ||
<br /> | ||
<div> | ||
To: <DatePicker date={toDate} setDate={setToDate} /> | ||
</div> | ||
<br /> | ||
<CheckBox | ||
checked={onlyVerified} | ||
onChange={setOnlyVerified} | ||
label='To verified projects only' | ||
/> | ||
</Col> | ||
<Col md={1} /> | ||
<Col md={2}> | ||
<H6>Total (USD):</H6> | ||
{loading ? ( | ||
<Spinner /> | ||
) : ( | ||
<H2>{thousandsSeparator(total?.toFixed(2))}</H2> | ||
)} | ||
</Col> | ||
{loading ? ( | ||
<Spinner /> | ||
) : ( | ||
<RecurringDonationsTotalChart | ||
totalPerMonthAndYear={totalPerMonthAndYear!} | ||
/> | ||
)} | ||
{loading ? ( | ||
<Spinner /> | ||
) : ( | ||
<RecurringDonationsTotalTokenChart | ||
rDonationsPerToken={totalPerToken} | ||
/> | ||
)} | ||
</RowStyled> | ||
); | ||
}; | ||
|
||
const TooltipBody = styled(Subline)` | ||
color: ${neutralColors.gray[100]}; | ||
width: 270px; | ||
`; | ||
|
||
const RowStyled = styled(Row)` | ||
margin-top: 40px; | ||
align-items: center; | ||
margin-bottom: 40px; | ||
`; | ||
|
||
export default RecurringDonationsTotalUsd; |
60 changes: 60 additions & 0 deletions
60
src/components/views/home/charts/RecurringDonationsCountChat.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { FC } from 'react'; | ||
import Highcharts from 'highcharts'; | ||
import HighchartsReact from 'highcharts-react-official'; | ||
import styled from 'styled-components'; | ||
import { IMonthlyData } from '../../../../types/gql'; | ||
|
||
const RecurringDonationsCountChat: FC<IMonthlyData> = ({ | ||
totalPerMonthAndYear, | ||
}) => { | ||
const data = totalPerMonthAndYear?.map(i => ({ | ||
name: i.date, | ||
y: i.total, | ||
})); | ||
const options = { | ||
chart: { | ||
type: 'column', | ||
zoomType: 'x', | ||
}, | ||
title: { | ||
text: 'Recurring donations count per month', | ||
}, | ||
subtitle: { | ||
text: '(Click and drag to zoom in)', | ||
}, | ||
xAxis: { | ||
type: 'category', | ||
min: 0, | ||
}, | ||
yAxis: { | ||
title: { | ||
text: 'Number of donations', | ||
}, | ||
}, | ||
tooltip: { | ||
enabled: true, | ||
pointFormat: '<b>Recurring Donations: {point.y}</b>', | ||
}, | ||
legend: { | ||
enabled: false, | ||
}, | ||
series: [{ data }], | ||
plotOptions: { | ||
series: { | ||
pointWidth: 15, | ||
}, | ||
}, | ||
}; | ||
|
||
return ( | ||
<ChartContainer> | ||
<HighchartsReact highcharts={Highcharts} options={options} /> | ||
</ChartContainer> | ||
); | ||
}; | ||
|
||
const ChartContainer = styled.div` | ||
margin-top: 60px; | ||
`; | ||
|
||
export default RecurringDonationsCountChat; |
82 changes: 82 additions & 0 deletions
82
src/components/views/home/charts/RecurringDonationsCountTokenChart.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import { FC } from 'react'; | ||
import Highcharts from 'highcharts'; | ||
import HighchartsReact from 'highcharts-react-official'; | ||
import styled from 'styled-components'; | ||
import { | ||
H5, | ||
IconHelpFilled16, | ||
neutralColors, | ||
Subline, | ||
} from '@giveth/ui-design-system'; | ||
import { IconWithTooltip } from '../../../IconWithTooltip'; | ||
import { FlexCenter } from '../../../styled-components/flex'; | ||
import { IRecurringDonationdPerTokenRecord } from '../../../../types/gql'; | ||
|
||
interface IProps { | ||
rDonationsPerToken?: IRecurringDonationdPerTokenRecord[]; | ||
} | ||
|
||
const RecurringDonationsCountTokenChart: FC<IProps> = ({ | ||
rDonationsPerToken, | ||
}) => { | ||
const data = rDonationsPerToken?.map(i => ({ | ||
name: i.token, | ||
y: i.total, | ||
})); | ||
const options = { | ||
chart: { | ||
plotBackgroundColor: null, | ||
type: 'pie', | ||
}, | ||
title: { | ||
text: null, | ||
}, | ||
tooltip: { | ||
enabled: true, | ||
pointFormat: '<b>{point.y}</b>', | ||
}, | ||
series: [ | ||
{ | ||
colorByPoint: true, | ||
data: data, | ||
}, | ||
], | ||
plotOptions: { | ||
pie: { | ||
allowPointSelect: true, | ||
cursor: 'pointer', | ||
dataLabels: { | ||
enabled: true, | ||
format: '<b>{point.name}</b>: {point.percentage:.1f} %', | ||
}, | ||
}, | ||
}, | ||
}; | ||
|
||
return ( | ||
<Container> | ||
<FlexCenter gap='10px'> | ||
<H5>Recurring Donations Count Per Token</H5> | ||
<IconWithTooltip icon={<IconHelpFilled16 />} direction={'top'}> | ||
<TooltipBody> | ||
Current distribution of all recurring donations by token | ||
during the selected timeframe. | ||
</TooltipBody> | ||
</IconWithTooltip> | ||
</FlexCenter> | ||
<HighchartsReact highcharts={Highcharts} options={options} /> | ||
</Container> | ||
); | ||
}; | ||
|
||
const TooltipBody = styled(Subline)` | ||
color: ${neutralColors.gray[100]}; | ||
width: 270px; | ||
`; | ||
|
||
const Container = styled.div` | ||
margin-top: 50px; | ||
text-align: center; | ||
`; | ||
|
||
export default RecurringDonationsCountTokenChart; |
Oops, something went wrong.