Skip to content

Commit

Permalink
Merge pull request #108 from ar-io/PE-7099-staking-modal-updates
Browse files Browse the repository at this point in the history
PE-7099: Staking modal updates
  • Loading branch information
kunstmusik authored Nov 22, 2024
2 parents 156732c + c569597 commit 94be0d5
Show file tree
Hide file tree
Showing 23 changed files with 781 additions and 255 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"dependencies": {
"@ar.io/sdk": "2.5.0-alpha.8",
"@fontsource/rubik": "^5.0.19",
"@headlessui/react": "^1.7.19",
"@headlessui/react": "^2.2.0",
"@radix-ui/react-tooltip": "^1.0.7",
"@sentry/browser": "^7.101.1",
"@sentry/react": "^7.101.1",
Expand Down
6 changes: 3 additions & 3 deletions src/components/AssessmentDetailsPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Dialog } from '@headlessui/react';
import { Dialog, DialogPanel } from '@headlessui/react';
import {
CaretDoubleRightIcon,
CheckSquareIcon,
Expand Down Expand Up @@ -177,7 +177,7 @@ const AssessmentDetailsPanel = ({
/>

<div className="fixed right-0 top-0 h-screen w-[36rem]">
<Dialog.Panel
<DialogPanel
className={
'relative flex h-full flex-col bg-grey-800 text-sm text-mid'
}
Expand Down Expand Up @@ -270,7 +270,7 @@ const AssessmentDetailsPanel = ({
</div>
)}
</div>
</Dialog.Panel>
</DialogPanel>
</div>
</Dialog>
);
Expand Down
8 changes: 4 additions & 4 deletions src/components/Profile.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable tailwindcss/migration-from-tailwind-2 */
import { Popover } from '@headlessui/react';
import { Popover, PopoverButton, PopoverPanel } from '@headlessui/react';
import { useGlobalState } from '@src/store';
import { formatBalance, formatWalletAddress } from '@src/utils';
import { forwardRef, useState } from 'react';
Expand Down Expand Up @@ -45,9 +45,9 @@ const Profile = () => {

return walletAddress ? (
<Popover className="relative">
<Popover.Button as={CustomPopoverButton} />
<PopoverButton as={CustomPopoverButton} />

<Popover.Panel className="absolute right-0 z-50 mt-2.5 w-fit rounded-xl border border-grey-800 bg-grey-1000 text-sm shadow-xl">
<PopoverPanel className="absolute right-0 z-50 mt-2.5 w-fit rounded-xl border border-grey-800 bg-grey-1000 text-sm shadow-xl">
<div className="flex gap-2 px-4 py-5 ">
<WalletIcon className="size-4" />

Expand Down Expand Up @@ -110,7 +110,7 @@ const Profile = () => {
<LogoutIcon className="size-4" /> Logout
</button>
</div>
</Popover.Panel>
</PopoverPanel>
</Popover>
) : walletStateInitialized ? (
<div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/forms/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export const validateNumberRange = (
};
};

export const validateUnstakeAmount = (
export const validateWithdrawAmount = (
propertyName: string,
ticker: string,
currentStake: number,
Expand Down
1 change: 1 addition & 0 deletions src/components/icons/circle.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/components/icons/circle_check.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions src/components/icons/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import CancelButtonXIcon from './cancel_button_x.svg?react';
import CaretDoubleRightIcon from './caret_double_right.svg?react';
import CheckSquareIcon from './check_square.svg?react';
import ChevronDownIcon from './chevron_down.svg?react';
import CircleCheckIcon from './circle_check.svg?react';
import CircleIcon from './circle.svg?react';
import ClockRewindIcon from './clock_rewind.svg?react';
import CloseIcon from './close.svg?react';
import CloseDrawerIcon from './close_drawer.svg?react';
Expand Down Expand Up @@ -60,6 +62,8 @@ export {
CancelButtonXIcon,
CheckSquareIcon,
ChevronDownIcon,
CircleCheckIcon,
CircleIcon,
ClockRewindIcon,
CloseDrawerIcon,
CloseIcon,
Expand Down
10 changes: 5 additions & 5 deletions src/components/modals/BaseModal.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Dialog } from '@headlessui/react';
import { Dialog, DialogPanel } from '@headlessui/react';
import { ReactElement } from 'react';
import { CloseIcon } from '../icons';

Expand All @@ -21,18 +21,18 @@ const BaseModal = ({
/>

<div className="fixed inset-0 flex w-screen items-center justify-center p-4">
<Dialog.Panel
className={`relative flex max-h-full flex-col items-stretch rounded-xl bg-[#111112] ${useDefaultPadding ? 'p-8' : ''} text-center text-grey-100`}
<DialogPanel
className={`relative flex max-h-full flex-col items-stretch rounded-xl bg-[#111112] ${useDefaultPadding ? 'p-8' : ''} border border-stroke-low text-center text-grey-100`}
>
{showCloseButton && (
<button className="absolute -right-7 top-0" onClick={onClose}>
<CloseIcon className="size-5" />
</button>
)}
<div className="flex grow flex-col overflow-y-auto scrollbar">
<div className="flex grow flex-col overflow-hidden overflow-y-auto rounded-xl scrollbar">
{children}
</div>
</Dialog.Panel>
</DialogPanel>
</div>
</Dialog>
);
Expand Down
4 changes: 2 additions & 2 deletions src/components/modals/CancelWithdrawalModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ const CancelWithdrawalModal = ({
</div>
</div>

<div className="px-8 pb-8 pt-6">
<div className="bg-containerL0 px-8 pb-8 pt-6">
<div className="mb-6 flex flex-col items-center gap-2 text-sm text-mid">
<div>
Please type &quot;CONFIRM&quot; in the text box to proceed.
Expand All @@ -85,7 +85,7 @@ const CancelWithdrawalModal = ({
type="text"
onChange={(e) => setConfirmText(e.target.value)}
className={
'h-7 w-full rounded-md border border-grey-700 bg-grey-1000 p-3 text-sm text-mid outline-none placeholder:text-grey-400 focus:text-high'
'h-7 w-full rounded-md border border-grey-700 bg-grey-1000 p-4 text-sm text-mid outline-none placeholder:text-grey-400 focus:text-high'
}
value={confirmText}
/>
Expand Down
6 changes: 3 additions & 3 deletions src/components/modals/InstantWithdrawalModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ const InstantWithdrawalModal = ({
</ul>
</div>

<div className="mt-4 flex flex-col gap-1 px-8">
<div className="mt-4 flex flex-col gap-1 px-8 pb-4">
<LabelValueRow
label="Stake Withdrawing:"
value={`${formatWithCommas(new mIOToken(vault.balance).toIO().valueOf())} ${ticker}`}
Expand Down Expand Up @@ -180,7 +180,7 @@ const InstantWithdrawalModal = ({
/>
</div>

<div className="px-8 pb-8 pt-6">
<div className="bg-containerL0 px-8 pb-8 pt-4">
<div className="mb-6 flex flex-col items-center gap-2 text-sm text-mid">
<div>
Please type &quot;WITHDRAW&quot; in the text box to proceed.
Expand All @@ -189,7 +189,7 @@ const InstantWithdrawalModal = ({
type="text"
onChange={(e) => setConfirmText(e.target.value)}
className={
'h-7 w-full rounded-md border border-grey-700 bg-grey-1000 p-3 text-sm text-mid outline-none placeholder:text-grey-400 focus:text-high'
'h-7 w-full rounded-md border border-grey-700 bg-grey-1000 p-4 text-sm text-mid outline-none placeholder:text-grey-400 focus:text-high'
}
value={confirmText}
/>
Expand Down
4 changes: 2 additions & 2 deletions src/components/modals/LeaveNetworkModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,14 @@ const LeaveNetworkModal = ({ onClose }: { onClose: () => void }) => {
</ul>
</div>

<div className="px-8 pb-8 pt-6">
<div className="bg-containerL0 px-8 pb-8 pt-6">
<div className="mb-6 flex flex-col items-center gap-2 text-sm text-mid">
<div>Please type &quot;LEAVE NETWORK&quot; in the text box to proceed.</div>
<input
type="text"
onChange={(e) => setLeaveNetworkText(e.target.value)}
className={
'h-7 w-full rounded-md border border-grey-700 bg-grey-1000 p-3 text-sm text-mid outline-none placeholder:text-grey-400 focus:text-high'
'h-7 w-full rounded-md border border-grey-700 bg-grey-1000 p-4 text-sm text-mid outline-none placeholder:text-grey-400 focus:text-high'
}
value={leaveNetworkText}
/>
Expand Down
176 changes: 176 additions & 0 deletions src/components/modals/ReviewStakeModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
import { AoGatewayWithAddress, IOToken } from '@ar.io/sdk/web';
import { log, WRITE_OPTIONS } from '@src/constants';
import { useGlobalState } from '@src/store';
import { formatAddress, formatWithCommas } from '@src/utils';
import { ArweaveTransactionID } from '@src/utils/ArweaveTransactionId';
import { showErrorToast } from '@src/utils/toast';
import { useQueryClient } from '@tanstack/react-query';
import { useState } from 'react';
import Button, { ButtonType } from '../Button';
import { LinkArrowIcon } from '../icons';
import LabelValueRow from '../LabelValueRow';
import BaseModal from './BaseModal';
import BlockingMessageModal from './BlockingMessageModal';
import SuccessModal from './SuccessModal';
import WithdrawWarning from './WithdrawWarning';

const ReviewStakeModal = ({
gateway,
amountToStake,
onSuccess,
onClose,
walletAddress,
ticker,
}: {
gateway: AoGatewayWithAddress;
amountToStake: number;
walletAddress: ArweaveTransactionID;
onClose: () => void;
onSuccess: () => void;
ticker: string;
}) => {
const queryClient = useQueryClient();
const arIOWriteableSDK = useGlobalState((state) => state.arIOWriteableSDK);

const [txid, setTxid] = useState<string>();

const [showBlockingMessageModal, setShowBlockingMessageModal] =
useState(false);
const [showSuccessModal, setShowSuccessModal] = useState(false);

const submitForm = async () => {
if (arIOWriteableSDK) {
setShowBlockingMessageModal(true);

try {
const { id: txID } = await arIOWriteableSDK.delegateStake(
{
target: gateway.gatewayAddress,
stakeQty: new IOToken(amountToStake).toMIO(),
},
WRITE_OPTIONS,
);
setTxid(txID);

log.info(`Increase Delegate Stake txID: ${txID}`);

queryClient.invalidateQueries({
queryKey: ['gateway', walletAddress.toString()],
refetchType: 'all',
});
queryClient.invalidateQueries({
queryKey: ['gateways'],
refetchType: 'all',
});
queryClient.invalidateQueries({
queryKey: ['balances'],
refetchType: 'all',
});
queryClient.invalidateQueries({
queryKey: ['delegateStakes'],
refetchType: 'all',
});

setShowSuccessModal(true);
} catch (e: any) {
showErrorToast(`${e}`);
} finally {
setShowBlockingMessageModal(false);
}
}
};

return (
<>
<BaseModal
onClose={onClose}
useDefaultPadding={false}
showCloseButton={false}
>
<div className="w-[28.5rem]">
<div className="text-gradient rounded-t-xl border-b border-b-stroke-low bg-containerL3 p-4">
Review
</div>
<div className="flex flex-col gap-2 p-8">
<LabelValueRow
label="Gateway Owner:"
value={formatAddress(gateway.gatewayAddress)}
/>

<LabelValueRow
label="Label:"
value={gateway ? gateway.settings.label : '-'}
/>

<LabelValueRow
label="Domain:"
isLink={true}
value={gateway ? gateway.settings.fqdn : '-'}
/>

<LabelValueRow
label="Amount:"
value={`${formatWithCommas(amountToStake)} ${ticker}`}
/>
</div>

<div className="px-8 pb-6 text-left">
<WithdrawWarning />
</div>

<div className="flex size-full flex-col bg-containerL0 px-8 pb-2 pt-6">
<Button
className="h-[3.25rem] w-full"
onClick={submitForm}
buttonType={ButtonType.PRIMARY}
title={`Stake ${ticker}`}
text={`Stake ${ticker}`}
/>
<div>
<button className="h-[3.25rem] p-4 text-sm" onClick={onClose}>
Back
</button>
</div>
</div>
</div>
</BaseModal>

{showBlockingMessageModal && (
<BlockingMessageModal
onClose={() => setShowBlockingMessageModal(false)}
message="Sign the following data with your wallet to proceed."
></BlockingMessageModal>
)}
{showSuccessModal && (
<SuccessModal
onClose={() => {
setShowSuccessModal(false);
onClose();
onSuccess();
}}
title="Congratulations"
bodyText={
<div className="mb-8 text-sm text-mid">
<div>You have successfully updated your stake.</div>
<div className="my-2 flex flex-col justify-center gap-2">
<div>Transaction ID:</div>
<button
className="flex items-center justify-center"
title="View transaction on ao.link"
onClick={async () => {
window.open(`https://ao.link/#/message/${txid}`, '_blank');
}}
>
{txid}
<LinkArrowIcon className="ml-1 size-3" />
</button>
</div>
</div>
}
/>
)}
</>
);
};

export default ReviewStakeModal;
Loading

0 comments on commit 94be0d5

Please sign in to comment.