Skip to content

Commit

Permalink
Merge pull request #33 from OriginProtocol/feat/history
Browse files Browse the repository at this point in the history
Feat/history
  • Loading branch information
dcodes05 authored Sep 13, 2023
2 parents 8ac6884 + a0b6687 commit 8ed43d5
Show file tree
Hide file tree
Showing 38 changed files with 1,232 additions and 183 deletions.
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
VITE_SUBSQUID_URL="https://squid.subsquid.io/origin-squid/v/v4/graphql"
VITE_SUBSQUID_URL="https://squid.subsquid.io/origin-squid/v/v5/graphql"
VITE_CUSTOM_RPC=
VITE_WALLET_CONNECT_PROJECT_ID=
VITE_ALCHEMY_ID=
1 change: 1 addition & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
]
}
],
"@typescript-eslint/no-explicit-any": false,
"react/react-in-jsx-scope": "off",
"no-empty": ["error", { "allowEmptyCatch": true }],
// Unused imports rules
Expand Down
2 changes: 1 addition & 1 deletion .graphqlconfig
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"name": "Subsquid GraphQL Schema",
"schemaPath": "https://squid.subsquid.io/origin-squid/v/v4/graphql"
"schemaPath": "https://squid.subsquid.io/origin-squid/v/v5/graphql"
}
5 changes: 3 additions & 2 deletions apps/oeth/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { Container, CssBaseline, Stack } from '@mui/material';
import { ApyHeader } from '@origin/oeth/shared';
import { Outlet } from 'react-router-dom';

import { Topnav } from './components/Topnav';
import { registerChart } from '@origin/shared/providers';

registerChart();

export const App = () => {
return (
Expand All @@ -23,7 +25,6 @@ export const App = () => {
}}
maxWidth="sm"
>
<ApyHeader />
<Stack mt={3}>
<Outlet />
</Stack>
Expand Down
73 changes: 73 additions & 0 deletions libs/oeth/history/src/components/APYContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { Divider, Stack, Typography } from '@mui/material';
import { valueFormat } from '@origin/shared/components';
import { useIntl } from 'react-intl';
import { useAccount } from 'wagmi';
import { useHistoryTableQuery } from '../queries.generated';

export function APYContainer() {
const { address, isConnected } = useAccount();
const { data } = useHistoryTableQuery(
{ addressId: address?.toLowerCase(), offset: 0 },
{
enabled: isConnected,
},
);
const intl = useIntl();
return (
<Stack
sx={{
paddingInline: { xs: 2, md: 2.75 },
backgroundColor: (theme) => theme.palette.background.paper,
borderRadius: 1,
}}
direction="row"
justifyContent="space-between"
>
<ValueContainer
label={intl.formatMessage({ defaultMessage: 'OETH Balance' })}
value={data?.addressById?.balance ?? 0}
/>
<Divider orientation="vertical" flexItem />
<ValueContainer
label={intl.formatMessage({ defaultMessage: 'Pending Yield' })}
value={0.0023}
/>
<Divider orientation="vertical" flexItem />
<ValueContainer
label={intl.formatMessage({
defaultMessage: 'Lifetime earnings (OETH)',
})}
value={data?.addressById?.earned ?? 0}
/>
</Stack>
);
}

interface Props {
label: string;
value: number;
}

function ValueContainer(props: Props) {
const intl = useIntl();
return (
<Stack gap={0.5} sx={{ paddingBlock: 2, textAlign: 'center', flex: 1 }}>
<Typography variant="body2" color="text.secondary">
{props.label}
</Typography>
<Typography
sx={{
fontFamily: 'Sailec',
fontSize: (theme) => theme.typography.pxToRem(20),
fontStyle: 'normal',
fontWeight: 700,
lineHeight: '2rem',
textAlign: 'center',
}}
color="primary.contrastText"
>
{intl.formatNumber(props.value, valueFormat)}
</Typography>
</Stack>
);
}
50 changes: 50 additions & 0 deletions libs/oeth/history/src/components/ChartCard.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import type { Meta, StoryObj } from '@storybook/react';
import { ChartCard } from './ChartCard';
import { Container } from '@mui/material';

const meta: Meta<typeof ChartCard> = {
component: ChartCard,
title: 'History/ChartCard',
args: {
apyPercent: 9.71,
apy: [
{
timestamp: '2023-09-12T06:59:59.000000Z',
value: 8.422167648369584,
},
{
timestamp: '2023-09-11T07:01:47.000000Z',
value: 8.042548530846783,
},
{
timestamp: '2023-09-10T06:59:47.000000Z',
value: 8.405314460699497,
},
{
timestamp: '2023-09-09T06:59:47.000000Z',
value: 7.772087576083497,
},
{
timestamp: '2023-09-08T06:59:59.000000Z',
value: 7.998306152376022,
},
{
timestamp: '2023-09-07T06:59:47.000000Z',
value: 7.588201747600309,
},
{
timestamp: '2023-09-06T06:59:47.000000Z',
value: 8.448718911023612,
},
],
},
render: (args) => (
<Container maxWidth="sm">
<ChartCard {...args} />
</Container>
),
};

export default meta;

export const Default: StoryObj<typeof ChartCard> = {};
96 changes: 96 additions & 0 deletions libs/oeth/history/src/components/ChartCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { Box, Stack, Typography, useTheme } from '@mui/material';
import { Card } from '@origin/shared/components';
import React, { useLayoutEffect, useRef } from 'react';
import { useIntl } from 'react-intl';

import { Line } from 'react-chartjs-2';

interface Props {
apyPercent: number;
apy: { timestamp: string; value: number }[];
}

export function ChartCard(props: Props) {
const theme = useTheme();
const intl = useIntl();

return (
<Card
sxCardTitle={{ paddingBlock: { xs: 2, md: 3 } }}
sxCardContent={{ paddingInline: 0 }}
title={<>{intl.formatMessage({ defaultMessage: 'APY' })}</>}
>
<Stack sx={{ paddingBlock: { xs: 2, md: 3 }, paddingInline: 2 }}>
<Typography variant="h3" color="primary.contrastText">
{intl.formatNumber(props.apyPercent / 100, {
style: 'percent',
maximumFractionDigits: 2,
})}
</Typography>
<Typography variant="body2" color="text.secondary">
{intl.formatDate(new Date(), {
month: 'long',
day: 'numeric',
year: 'numeric',
})}
</Typography>
</Stack>

<Line
options={{
backgroundColor: theme.palette.background.paper,
color: theme.palette.text.secondary,
responsive: true,
animation: {
easing: 'easeInOutQuad',
},

borderColor(ctx, options) {
const gradient = ctx.chart.ctx.createLinearGradient(
0,
0,
ctx.chart.width,
ctx.chart.height,
);
gradient.addColorStop(0, theme.palette.primary.main);
gradient.addColorStop(1, theme.palette.primary.dark);
return gradient;
},
scales: {
y: {
display: false,
ticks: {
stepSize: 200,
},
},
x: {
ticks: {
padding: 16,
font: {
size: 11,
family: 'Inter',
weight: '400',
},
},
},
},
}}
data={{
datasets: [
{
data: props.apy.map((item) => ({
x: intl.formatDate(new Date(item.timestamp), {
month: 'short',
day: 'numeric',
}),
y: item.value,
})),
pointRadius: 0,
tension: 0.5,
},
],
}}
/>
</Card>
);
}
46 changes: 46 additions & 0 deletions libs/oeth/history/src/components/ExportData.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React, { useCallback, useMemo, useRef } from 'react';

import { Box, Link } from '@mui/material';
import { useIntl } from 'react-intl';

import { HistoryFilterButton } from './HistoryButton';
import { Rows } from './HistoryTable';

interface Props {
data?: Rows;
}

export function ExportData({ data }: Props) {
const link = useRef<HTMLAnchorElement>(null);
const intl = useIntl();

const generateCSV = useCallback(() => {
const rows = [['Date', 'Type', 'Amount', 'Balance', 'Transaction Hash']];
data.forEach((row) =>
rows.push([row.timestamp, row.type, row.value, row.balance, row.txHash]),
);
link.current.href =
'data:text/csv;charset=utf-8,' +
encodeURI(rows.map((e) => e.join(',')).join('\n'));
link.current.click();
}, [data]);

return (
<>
<Link
ref={link}
sx={{ display: 'none' }}
target="_blank"
download="transaction_history.csv"
></Link>
<HistoryFilterButton onClick={generateCSV}>
<Box
component="img"
src="/images/download.svg"
sx={{ height: '0.75rem', width: '0.75rem' }}
></Box>
{intl.formatMessage({ defaultMessage: 'CSV' })}
</HistoryFilterButton>
</>
);
}
Loading

0 comments on commit 8ed43d5

Please sign in to comment.