Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apt 1605 apt 1616 apt 1621 : Loading splash - add token to wallet - bg not working on some devices #20

Merged
merged 2 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added public/static/stake-background.webp
Binary file not shown.
267 changes: 174 additions & 93 deletions src/components/stakingPoolDetailsView.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
import StakingCalculator from "@/components/stakingCalculator";
import UnstakingCalculator from "@/components/unstakingCalculator";
import WithdrawZilPanel from "@/components/withdrawUnstakedZilPanel";
import { WalletConnector } from "@/contexts/walletConnector";
import { formatPercentage, formatUnitsToHumanReadable } from "@/misc/formatting";
import { StakingPool } from "@/misc/stakingPoolsConfig";
import { UserStakingPoolData, UserUnstakingPoolData } from "@/misc/walletsConfig";
import { DateTime } from "luxon";
import { useState } from "react";
import StakingCalculator from '@/components/stakingCalculator';
import UnstakingCalculator from '@/components/unstakingCalculator';
import WithdrawZilPanel from '@/components/withdrawUnstakedZilPanel';
import { WalletConnector } from '@/contexts/walletConnector';
import { getViemClient } from '@/misc/chainConfig';
import {
formatPercentage,
formatUnitsToHumanReadable,
} from '@/misc/formatting';
import { StakingPool } from '@/misc/stakingPoolsConfig';
import {
UserStakingPoolData,
UserUnstakingPoolData,
} from '@/misc/walletsConfig';
import { Button } from 'antd';
import { DateTime } from 'luxon';
import { useState } from 'react';
import { useWatchAsset } from 'wagmi';
import { useWalletClient } from 'wagmi';

interface StakingPoolDetailsViewProps {
stakingPoolData: StakingPool;
Expand All @@ -15,131 +25,202 @@ interface StakingPoolDetailsViewProps {
selectStakingPoolForStaking: (stakingPoolId: string) => void;
}

const StakingPoolDetailsView: React.FC<StakingPoolDetailsViewProps> = ({
const StakingPoolDetailsView: React.FC<
StakingPoolDetailsViewProps
> = ({
stakingPoolData,
userStakingPoolData,
userUnstakingPoolData,
}) => {

const {
zilAvailable,
} = WalletConnector.useContainer();
const { zilAvailable } = WalletConnector.useContainer();

const [selectedPane, setSelectedPane] = useState<string>('Stake');

const colorInfoEntry = (title: string, value: string | null) => (
<div>
<div className='body2-bold text-aqua2'>
{ value }
</div>
<div className='text-aqua3 info-label'>
{ title }
</div>
<div className="body2-bold text-aqua2">{value}</div>
<div className="text-aqua3 info-label">{title}</div>
</div>
)
);

const greyInfoEntry = (title: string, value: string | JSX.Element | null) => (
const greyInfoEntry = (
title: string,
value: string | JSX.Element | null
) => (
<div>
{
value ? (
<div className='body2-bold text-gray1 xl:whitespace-nowrap'>
{ value }
</div>
) : (
<div className="animated-gradient h-[1.5em] w-[4em]"></div>
)
}
<div className='text-gray2 info-label xl:whitespace-nowrap'>
{ title }
{value ? (
<div className="body2-bold text-gray1 xl:whitespace-nowrap">
{value}
</div>
) : (
<div className="animated-gradient h-[1.5em] w-[4em]"></div>
)}
<div className="text-gray2 info-label xl:whitespace-nowrap">
{title}
</div>
</div>
)

const pendingUnstakesValue = userUnstakingPoolData?.filter(
(item) => item.availableAt > DateTime.now()
).reduce(
(acc, item) => acc + item.zilAmount,
0n
);

const availableToClaim = userUnstakingPoolData?.filter(
(item) => item.availableAt <= DateTime.now()
).reduce(
(acc, item) => acc + item.zilAmount,
0n
const pendingUnstakesValue = userUnstakingPoolData
?.filter((item) => item.availableAt > DateTime.now())
.reduce((acc, item) => acc + item.zilAmount, 0n);

const availableToClaim = userUnstakingPoolData
?.filter((item) => item.availableAt <= DateTime.now())
.reduce((acc, item) => acc + item.zilAmount, 0n);

const doesUserHoldAnyFundsInThisPool = !!(
userStakingPoolData?.stakingTokenAmount ||
pendingUnstakesValue ||
availableToClaim
);

const doesUserHoldAnyFundsInThisPool = !!(userStakingPoolData?.stakingTokenAmount || pendingUnstakesValue || availableToClaim);
const humanReadableStakingToken = (value: bigint) =>
formatUnitsToHumanReadable(
value,
stakingPoolData.definition.tokenDecimals
);

const humanReadableStakingToken = (value: bigint) => formatUnitsToHumanReadable(value, stakingPoolData.definition.tokenDecimals);
const { watchAsset } = useWatchAsset();

const handleClickAaddToken = () =>
watchAsset(
{
type: 'ERC20',
options: {
address: stakingPoolData.definition.tokenAddress,
symbol: stakingPoolData.definition.tokenSymbol,
decimals: stakingPoolData.definition.tokenDecimals,
},
},
{
onSuccess: (data) => {
console.log('Asset watched successfully:', data);
},
onError: (error) => {
console.error('Failed to watch the asset:', error);
},
}
);

return (
<div className="relative overflow-y-auto max-h-[calc(90vh-10vh)] sm:max-h-[calc(90vh-15vh)]
<div
className="relative overflow-y-auto max-h-[calc(90vh-10vh)] sm:max-h-[calc(90vh-15vh)]
scrollbar-thin scrollbar-thumb-gray1 scrollbar-track-gray3 hover:scrollbar-thumb-gray2 pb-2"
>
<div className="items-center flex justify-between py-1 lg:py-7.5">
<div className="max-lg:ms-1 items-center flex">
<span className='hero lg:h2 text-white2'>
<span className="hero lg:h2 text-white2">
{stakingPoolData.definition.name}
</span>
<span className='body1 lg:h4 text-black2 ml-2.5'>
<span className="body1 lg:h4 text-black2 ml-2.5">
{stakingPoolData.definition.tokenSymbol}
</span>
</div>
<div>
<Button
onClick={handleClickAaddToken}
className="btn-primary-gradient-aqua-lg lg:btn-primary-gradient-aqua"
>
+
</Button>
</div>
</div>

<div className="bg-darkbg py-7.5 lg:py-5 flex flex-col gap-4">
{doesUserHoldAnyFundsInThisPool &&
<div className="grid grid-cols-2 lg:grid-cols-4 gap-4 pb-4 border-b border-black2/50">
{ colorInfoEntry("Available to stake", `${formatUnitsToHumanReadable(zilAvailable || 0n, 18)} ZIL`) }
{ colorInfoEntry("Staked", `${humanReadableStakingToken(userStakingPoolData?.stakingTokenAmount || 0n)} ${stakingPoolData.definition.tokenSymbol}`) }
{ colorInfoEntry("Unstake", pendingUnstakesValue ? `${humanReadableStakingToken(pendingUnstakesValue)} ${stakingPoolData.definition.tokenSymbol}`: "-" ) }
{ colorInfoEntry("Available to claim", availableToClaim ? `${humanReadableStakingToken(availableToClaim)} ${stakingPoolData.definition.tokenSymbol}` : "-") }
</div>
}
{doesUserHoldAnyFundsInThisPool && (
<div className="grid grid-cols-2 lg:grid-cols-4 gap-4 pb-4 border-b border-black2/50">
{colorInfoEntry(
'Available to stake',
`${formatUnitsToHumanReadable(
zilAvailable || 0n,
18
)} ZIL`
)}
{colorInfoEntry(
'Staked',
`${humanReadableStakingToken(
userStakingPoolData?.stakingTokenAmount || 0n
)} ${stakingPoolData.definition.tokenSymbol}`
)}
{colorInfoEntry(
'Unstake',
pendingUnstakesValue
? `${humanReadableStakingToken(
pendingUnstakesValue
)} ${stakingPoolData.definition.tokenSymbol}`
: '-'
)}
{colorInfoEntry(
'Available to claim',
availableToClaim
? `${humanReadableStakingToken(availableToClaim)} ${
stakingPoolData.definition.tokenSymbol
}`
: '-'
)}
</div>
)}
<div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
{ greyInfoEntry("Voting power", stakingPoolData.data && formatPercentage(stakingPoolData.data.votingPower)) }
{ greyInfoEntry("Total supply", stakingPoolData.data && `${humanReadableStakingToken(stakingPoolData.data.tvl)} ${stakingPoolData.definition.tokenSymbol}`) }
{ greyInfoEntry("Commission", stakingPoolData.data && formatPercentage(stakingPoolData.data.commission)) }
{ greyInfoEntry("", stakingPoolData.data &&
(
{greyInfoEntry(
'Voting power',
stakingPoolData.data &&
formatPercentage(stakingPoolData.data.votingPower)
)}
{greyInfoEntry(
'Total supply',
stakingPoolData.data &&
`${humanReadableStakingToken(
stakingPoolData.data.tvl
)} ${stakingPoolData.definition.tokenSymbol}`
)}
{greyInfoEntry(
'Commission',
stakingPoolData.data &&
formatPercentage(stakingPoolData.data.commission)
)}
{greyInfoEntry(
'',
stakingPoolData.data && (
<>
1 ZIL ~ <br />
{stakingPoolData.data.zilToTokenRate.toPrecision(3)} {stakingPoolData.definition.tokenSymbol}
{stakingPoolData.data.zilToTokenRate.toPrecision(
3
)}{' '}
{stakingPoolData.definition.tokenSymbol}
</>
)) }
)
)}
</div>
</div>
<div className="grid grid-cols-3">
{
['Stake', 'Unstake', 'Claim'].map((pane) => (
<div
key={pane}
className={`body1 lg:base text-center py-7 cursor-pointer border-solid border-b ${selectedPane === pane ? "text-white2 border-gradient-1" : "text-gray2 border-black2"} `}
onClick={() => setSelectedPane(pane)}
>
{pane}
</div>
))
}
{['Stake', 'Unstake', 'Claim'].map((pane) => (
<div
key={pane}
className={`body1 lg:base text-center py-7 cursor-pointer border-solid border-b ${
selectedPane === pane
? 'text-white2 border-gradient-1'
: 'text-gray2 border-black2'
} `}
onClick={() => setSelectedPane(pane)}
>
{pane}
</div>
))}
</div>

{
selectedPane === 'Stake' ? (
<StakingCalculator />
) : selectedPane === 'Unstake' ? (
<UnstakingCalculator />
) : (
<WithdrawZilPanel
userUnstakingPoolData={userUnstakingPoolData}
stakingPoolData={stakingPoolData}
/>
)
}

{selectedPane === 'Stake' ? (
<StakingCalculator />
) : selectedPane === 'Unstake' ? (
<UnstakingCalculator />
) : (
<WithdrawZilPanel
userUnstakingPoolData={userUnstakingPoolData}
stakingPoolData={stakingPoolData}
/>
)}
</div>
)

}
);
};

export default StakingPoolDetailsView;
export default StakingPoolDetailsView;
48 changes: 45 additions & 3 deletions src/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { AppConfigStorage } from "@/contexts/appConfigStorage";
export default function App({ Component, pageProps }: AppProps) {
const queryClient = new QueryClient();
const [appConfig, setAppConfig] = useState<AppConfig | null>(null);
const [loadingPercentage, setLoadingPercentage] = useState(0);

useEffect(() => {
fetch("/api/config")
Expand All @@ -26,10 +27,51 @@ export default function App({ Component, pageProps }: AppProps) {
.catch(console.error);
}, []);

useEffect(() => {
const fetchConfig = async () => {
try {
const res = await fetch("/api/config");
const reader = res.body?.getReader();
const contentLength = res.headers.get("Content-Length");

if (reader && contentLength) {
const totalLength = parseInt(contentLength, 10);
let loaded = 0;
while (true) {
const { done, value } = await reader.read();
if (done) break;

loaded += value?.length || 0;
const progress = Math.round((loaded / totalLength) * 100);
setLoadingPercentage(progress);
}
}

const data = await res.json();
setAppConfig(data);
} catch (error) {
console.error(error);
}
};

if (!appConfig) {
return <div>Loading...</div> // APT-1605
}
fetchConfig();
}, []);


if (!appConfig) {
return(
<div className="h-screen bg-black text-white1 ">
<div className="h-full flex flex-col justify-between">
<div className="w-full h-10 overflow-hidden">
<div
className="h-full bg-colorful-gradient"
style={{ width: `${loadingPercentage}%` }}
></div>
</div>
<div className="self-end text-80 lg:text-114 font-int-extrabold mr-7">{loadingPercentage}%</div>
</div></div>
)
}

return (
<AppConfigStorage.Provider initialState={{ appConfig }}>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/_document.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export default function Document() {
return (
<Html lang="en">
<Head />
<body className="bg-[url('https://s3-alpha-sig.figma.com/img/2094/27b4/0031fd7fbc83ae7020637ddc7c563ea4?Expires=1733097600&Key-Pair-Id=APKAQ4GOSFWCVNEHN3O4&Signature=Kqd3RVzZ5qHkIJoS4q45mvtbfLBVz3iJA879jwkqn3PydxJUjtSd9LX-FGW~Zkey9mCDOO-ZiX4fSGl2O-Ur9Ck3qL-jNorGoxxzhvN8MrBCdMBis2gyc11glVLh4dUR7sohttYIffOETquCISkigUJjPZStuvI2qP806mwwtQTKnqmf4Of5Dw07bjERivJEvMiI34LdDyEeUjo97qeqWaZBhZA2E1YFdBJcsZ3UpaZm63Lo93lU5T7MSz6tPfcIJIi7tov8E~X6iuxE-pZV~jrslzcq1tYURdMYif~36n-Jomo3POBd2Ln0HPWIl-K~8s6tp2xkV7l7Otr2w4a2xQ__')] bg-right bg-no-repeat bg-cover bg-origin-content">
<body className="bg-[url('/static/stake-background.webp')] bg-right bg-no-repeat bg-cover bg-origin-content">
<Main />
<NextScript />
</body>
Expand Down
Loading