mirror of https://github.com/certusone/oyster.git
feat: add info
This commit is contained in:
parent
1dc3274a0a
commit
6521bfd17e
|
@ -6,7 +6,7 @@ import {
|
|||
LendingReserveParser,
|
||||
} from "../../models";
|
||||
import { TokenIcon } from "../TokenIcon";
|
||||
import { Button, Card, Slider, Spin } from "antd";
|
||||
import { Button, Card, Spin } from "antd";
|
||||
import { cache, ParsedAccount, useMint } from "../../contexts/accounts";
|
||||
import { NumericInput } from "../Input/numeric";
|
||||
import { useConnection } from "../../contexts/connection";
|
||||
|
@ -15,15 +15,12 @@ import { repay } from "../../actions";
|
|||
import { CollateralSelector } from "./../CollateralSelector";
|
||||
import "./style.less";
|
||||
import {
|
||||
wadToLamports,
|
||||
formatNumber,
|
||||
fromLamports,
|
||||
toLamports,
|
||||
} from "../../utils/utils";
|
||||
import { LABELS } from "../../constants";
|
||||
import { LoadingOutlined } from "@ant-design/icons";
|
||||
import { ActionConfirmation} from './../ActionConfirmation';
|
||||
import { BackButton } from "./../BackButton";
|
||||
|
||||
const antIcon = <LoadingOutlined style={{ fontSize: 24 }} spin />;
|
||||
|
||||
|
@ -67,9 +64,6 @@ export const RepayInput = (props: {
|
|||
[value, repayLiquidityMint]
|
||||
);
|
||||
|
||||
const mark =
|
||||
(wadToLamports(obligation?.info.borrowAmountWad).toNumber() / lamports) *
|
||||
100;
|
||||
|
||||
const onRepay = useCallback(() => {
|
||||
if (
|
||||
|
@ -193,10 +187,4 @@ export const RepayInput = (props: {
|
|||
);
|
||||
};
|
||||
|
||||
const marks = {
|
||||
0: "0%",
|
||||
25: "25%",
|
||||
50: "50%",
|
||||
75: "75%",
|
||||
100: "100%",
|
||||
};
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import React from "react";
|
|||
import { useTokenName } from "./../../hooks";
|
||||
import { calculateBorrowAPY, calculateDepositAPY, calculateUtilizationRatio, LendingReserve } from "../../models/lending";
|
||||
import { TokenIcon } from "../../components/TokenIcon";
|
||||
import { formatNumber, formatPct, fromLamports, wadToLamports } from "../../utils/utils";
|
||||
import { formatNumber, formatPct, fromLamports } from "../../utils/utils";
|
||||
import { Card, Typography } from "antd";
|
||||
import { ParsedAccount, useMint } from "../../contexts/accounts";
|
||||
import { Link } from "react-router-dom";
|
||||
|
|
|
@ -32,11 +32,6 @@ export function Routes() {
|
|||
<AppLayout>
|
||||
<Switch>
|
||||
<Route exact path="/" component={() => <HomeView />} />
|
||||
<Route
|
||||
exact
|
||||
path="/dashboard/deposits"
|
||||
children={<DashboardView />}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
path="/dashboard"
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
import React from "react";
|
||||
import {
|
||||
useCollateralBalance,
|
||||
useTokenName,
|
||||
useUserBalance,
|
||||
} from "../../hooks";
|
||||
import { LendingReserve } from "../../models/lending";
|
||||
import { TokenIcon } from "../../components/TokenIcon";
|
||||
import { formatNumber } from "../../utils/utils";
|
||||
import { Button, Card } from "antd";
|
||||
import { Link } from "react-router-dom";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
|
||||
export const ReserveItem = (props: {
|
||||
reserve: LendingReserve;
|
||||
address: PublicKey;
|
||||
}) => {
|
||||
const name = useTokenName(props.reserve.liquidityMint);
|
||||
const { balance: tokenBalance } = useUserBalance(props.reserve.liquidityMint);
|
||||
const { balance: collateralBalance } = useCollateralBalance(props.reserve);
|
||||
|
||||
return (
|
||||
<Link to={`/deposit/${props.address.toBase58()}`}>
|
||||
<Card>
|
||||
<div className="deposit-item">
|
||||
<span style={{ display: "flex" }}>
|
||||
<TokenIcon mintAddress={props.reserve.liquidityMint} />
|
||||
{name}
|
||||
</span>
|
||||
<div>
|
||||
{formatNumber.format(tokenBalance)} {name}
|
||||
</div>
|
||||
<div>
|
||||
{formatNumber.format(collateralBalance)} {name}
|
||||
</div>
|
||||
<div>--</div>
|
||||
<div>
|
||||
<Button>
|
||||
<span>Deposit</span>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</Link>
|
||||
);
|
||||
};
|
|
@ -1,32 +0,0 @@
|
|||
import React from "react";
|
||||
import { LABELS } from "../../constants";
|
||||
import { useUserDeposits, useUserObligations } from "./../../hooks";
|
||||
import { ObligationItem } from "./obligationItem";
|
||||
import "./style.less";
|
||||
|
||||
export const DashboardView = () => {
|
||||
const { userObligations } = useUserObligations();
|
||||
const { userDeposits } = useUserDeposits();
|
||||
|
||||
return (
|
||||
<div className="dashboard-container">
|
||||
<div className="dashboard-left">
|
||||
<span>{LABELS.DASHBOARD_TITLE_DEPOSITS}</span>
|
||||
</div>
|
||||
<div className="dashboard-right">
|
||||
<span>{LABELS.DASHBOARD_TITLE_LOANS}</span>
|
||||
{userObligations.length > 0 && (
|
||||
<div className="dashboard-item dashboard-header">
|
||||
<div>{LABELS.TABLE_TITLE_ASSET}</div>
|
||||
<div>{LABELS.TABLE_TITLE_LOAN_BALANCE}</div>
|
||||
<div>{LABELS.TABLE_TITLE_APY}</div>
|
||||
<div>{LABELS.TABLE_TITLE_ACTION}</div>
|
||||
</div>
|
||||
)}
|
||||
{userObligations.map((item) => {
|
||||
return <ObligationItem obligation={item.obligation} />;
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
|
@ -1,49 +0,0 @@
|
|||
import React from "react";
|
||||
import { useTokenName } from "../../hooks";
|
||||
import { LendingObligation, LendingReserve } from "../../models/lending";
|
||||
import { TokenIcon } from "../../components/TokenIcon";
|
||||
import { wadToLamports, formatNumber, fromLamports } from "../../utils/utils";
|
||||
import { Button, Card } from "antd";
|
||||
import { Link } from "react-router-dom";
|
||||
import { cache, ParsedAccount, useMint } from "../../contexts/accounts";
|
||||
|
||||
export const ObligationItem = (props: {
|
||||
obligation: ParsedAccount<LendingObligation>;
|
||||
}) => {
|
||||
const { obligation } = props;
|
||||
|
||||
const borrowReserve = cache.get(
|
||||
obligation.info.borrowReserve
|
||||
) as ParsedAccount<LendingReserve>;
|
||||
|
||||
const name = useTokenName(borrowReserve?.info.liquidityMint);
|
||||
|
||||
const liquidityMint = useMint(borrowReserve.info.liquidityMint);
|
||||
|
||||
const borrowAmount = fromLamports(
|
||||
wadToLamports(obligation.info.borrowAmountWad),
|
||||
liquidityMint
|
||||
);
|
||||
|
||||
return (
|
||||
<Link to={`/repay/loan/${obligation.pubkey.toBase58()}`}>
|
||||
<Card>
|
||||
<div className="dashboard-item">
|
||||
<span style={{ display: "flex" }}>
|
||||
<TokenIcon mintAddress={borrowReserve?.info.liquidityMint} />
|
||||
{name}
|
||||
</span>
|
||||
<div>
|
||||
{formatNumber.format(borrowAmount)} {name}
|
||||
</div>
|
||||
<div>--</div>
|
||||
<div>
|
||||
<Button>
|
||||
<span>Repay</span>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</Link>
|
||||
);
|
||||
};
|
|
@ -1,50 +0,0 @@
|
|||
.dashboard-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
& > div, span {
|
||||
flex: 20%;
|
||||
height: 22px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
& > :first-child {
|
||||
flex: 80px
|
||||
}
|
||||
}
|
||||
|
||||
.dashboard-header {
|
||||
margin: 0px 30px;
|
||||
|
||||
& > div {
|
||||
flex: 20%;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
& > :first-child {
|
||||
text-align: left;
|
||||
flex: 80px
|
||||
}
|
||||
}
|
||||
|
||||
.dashboard-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.dashboard-right {
|
||||
flex: 50%;
|
||||
}
|
||||
|
||||
.dashboard-left {
|
||||
flex: 50%;
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.dashboard-right, .dashboard-left {
|
||||
flex: 100%;
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
import React from "react";
|
||||
import React, { useMemo } from "react";
|
||||
import { useCollateralBalance, useTokenName } from "../../hooks";
|
||||
import { LendingReserve } from "../../models/lending";
|
||||
import { calculateDepositAPY, LendingReserve } from "../../models/lending";
|
||||
import { TokenIcon } from "../../components/TokenIcon";
|
||||
import { formatNumber } from "../../utils/utils";
|
||||
import { formatNumber, formatPct } from "../../utils/utils";
|
||||
import { Button, Card } from "antd";
|
||||
import { Link } from "react-router-dom";
|
||||
import { TokenAccount } from "../../models";
|
||||
|
@ -19,6 +19,10 @@ export const DepositItem = (props: {
|
|||
props.account.pubkey
|
||||
);
|
||||
|
||||
const depositAPY = useMemo(() => calculateDepositAPY(props.reserve.info), [
|
||||
props.reserve,
|
||||
]);
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<div className="dashboard-item">
|
||||
|
@ -29,7 +33,7 @@ export const DepositItem = (props: {
|
|||
<div>
|
||||
{formatNumber.format(collateralBalance)} {name}
|
||||
</div>
|
||||
<div>--</div>
|
||||
<div>{formatPct.format(depositAPY)}</div>
|
||||
<div style={{ display: "flex", justifyContent: "flex-end" }}>
|
||||
<Link to={`/deposit/${props.reserve.pubkey.toBase58()}`}>
|
||||
<Button>
|
||||
|
|
|
@ -1,16 +1,20 @@
|
|||
import React from "react";
|
||||
import { LABELS } from "../../constants";
|
||||
import { useWallet } from "../../contexts/wallet";
|
||||
import { useUserDeposits, useUserObligations } from "./../../hooks";
|
||||
import { DepositItem } from "./depositItem";
|
||||
import { ObligationItem } from "./obligationItem";
|
||||
import "./style.less";
|
||||
|
||||
export const DashboardView = () => {
|
||||
const { connected } = useWallet();
|
||||
const { userObligations } = useUserObligations();
|
||||
const { userDeposits } = useUserDeposits();
|
||||
|
||||
return (
|
||||
<div className="dashboard-container">
|
||||
{!connected && <div className="dashboard-info">Connect to a wallet to view your deposits/loans.</div>}
|
||||
{connected && userDeposits.length === 0 &&userObligations.length === 0 && <div className="dashboard-info">No loans or deposits.</div>}
|
||||
{userDeposits.length > 0 && (<div className="dashboard-left">
|
||||
<span>{LABELS.DASHBOARD_TITLE_DEPOSITS}</span>
|
||||
<div className="dashboard-item dashboard-header">
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import React from "react";
|
||||
import React, { useMemo } from "react";
|
||||
import { useTokenName } from "../../hooks";
|
||||
import { LendingObligation, LendingReserve } from "../../models/lending";
|
||||
import { calculateBorrowAPY, LendingObligation, LendingReserve } from "../../models/lending";
|
||||
import { TokenIcon } from "../../components/TokenIcon";
|
||||
import { wadToLamports, formatNumber, fromLamports } from "../../utils/utils";
|
||||
import { wadToLamports, formatNumber, fromLamports, formatPct } from "../../utils/utils";
|
||||
import { Button, Card } from "antd";
|
||||
import { Link } from "react-router-dom";
|
||||
import { cache, ParsedAccount, useMint } from "../../contexts/accounts";
|
||||
|
@ -25,6 +25,10 @@ export const ObligationItem = (props: {
|
|||
liquidityMint
|
||||
);
|
||||
|
||||
const borrowAPY = useMemo(() => calculateBorrowAPY(borrowReserve.info), [
|
||||
borrowReserve,
|
||||
]);
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<div className="dashboard-item">
|
||||
|
@ -35,7 +39,7 @@ export const ObligationItem = (props: {
|
|||
<div>
|
||||
{formatNumber.format(borrowAmount)} {name}
|
||||
</div>
|
||||
<div>--</div>
|
||||
<div>{formatPct.format(borrowAPY)}</div>
|
||||
<div style={{ display: "flex", justifyContent: "flex-end" }}>
|
||||
<Link to={`/borrow/${borrowReserve.pubkey.toBase58()}`}>
|
||||
<Button>
|
||||
|
|
|
@ -51,6 +51,13 @@
|
|||
flex: 50%;
|
||||
}
|
||||
|
||||
.dashboard-info {
|
||||
display: flex;
|
||||
align-self: center;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
@media (max-width: 700px) {
|
||||
.dashboard-right, .dashboard-left {
|
||||
flex: 100%;
|
||||
|
|
Loading…
Reference in New Issue