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

Fix: TEST-366 and TEST-367 Disable the redeem rewards button for the same duration the remove stake button AND Fix the notification when a user rejects the tx while onboarding #44

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from
Open
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
4 changes: 4 additions & 0 deletions components/molecules/AddStakeModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,11 @@ export const AddStakeModal = () => {
},
});
} else {
// This will handle both rejection and other failure cases
setCurrentToast({
severity: ToastSeverity.DANGER,
title: "Staking Unsuccessful",
description: "Transaction failed or was rejected by the user",
followupNotification: {
title: "Staking Unsuccessful",
type: NotificationType.REWARD,
Expand All @@ -87,6 +89,8 @@ export const AddStakeModal = () => {
title: "Processing Adding Stake",
description: "Your add stake transaction is in process.",
});
} else {
resetToast();
}
}, [isLoading]);

Expand Down
42 changes: 26 additions & 16 deletions components/molecules/RewardsCard.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useState } from "react";
import { useEffect, useState, useMemo } from "react";
import rewardsCardBg from "../../assets/rewards-card.png";
import { useNodeStatus } from "../../hooks/useNodeStatus";
import { Card } from "../layouts/Card";
Expand All @@ -8,9 +8,10 @@ import useModalStore from "../../hooks/useModalStore";
import { ConfirmRedemptionModal } from "./ConfirmRedemptionModal";
import { MobileModalWrapper } from "../layouts/MobileModalWrapper";
import { BgImage } from "../atoms/BgImage";
import { useSettings } from "../../hooks/useSettings";
import { formatRemainingTime } from "../../utils/formatTime";

function formatDate(date: Date) {
// Format date and time separately
const datePart = date.toLocaleDateString("en-US", {
weekday: "short",
day: "2-digit",
Expand All @@ -23,7 +24,6 @@ function formatDate(date: Date) {
hour12: true,
});

// Combine date and time parts
return `${datePart} ${timePart}`;
}

Expand All @@ -38,20 +38,26 @@ export const RewardsCard = () => {
const { nodeStatus } = useNodeStatus();
const { address, isConnected } = useAccount();
const { chain } = useNetwork();
const [canRedeem, setCanRedeem] = useState(
isConnected &&
chain?.id === CHAIN_ID &&
nodeStatus?.state === "stopped" &&
parseFloat(nodeStatus?.lockedStake || "0") > 0
);
const { settings } = useSettings();
const [canRedeem, setCanRedeem] = useState(false);

const { isStoppedForLongerThan15Minutes, remainingWaitTime } = useMemo(() => {
if (!settings?.lastStopped) return { isStoppedForLongerThan15Minutes: true, remainingWaitTime: 0 };
const timeDifference = Date.now() - settings.lastStopped;
const isStoppedForLongerThan15Minutes = timeDifference > 15 * 60 * 1000;
const remainingWaitTime = Math.max(15 * 60 * 1000 - timeDifference, 0);
return { isStoppedForLongerThan15Minutes, remainingWaitTime };
}, [settings?.lastStopped]);

useEffect(() => {
setCanRedeem(
isConnected &&
chain?.id === CHAIN_ID &&
nodeStatus?.state === "stopped" &&
parseFloat(nodeStatus?.lockedStake || "0") > 0
parseFloat(nodeStatus?.lockedStake || "0") > 0 &&
isStoppedForLongerThan15Minutes
);
}, [nodeStatus?.state, nodeStatus?.lockedStake, isConnected, chain?.id]);
}, [nodeStatus?.state, nodeStatus?.lockedStake, isConnected, chain?.id, isStoppedForLongerThan15Minutes]);

return (
<Card>
Expand All @@ -65,7 +71,6 @@ export const RewardsCard = () => {
{parseFloat(nodeStatus?.currentRewards || "0").toFixed(2)}{" "}
SHM
</span>
{/* <span className="text-xs leading-9 bodyFg">(~0.00$)</span> */}
</span>
<div className="text-xs flex justify-between w-full bodyFg">
<span>Earned since last validating cycle</span>
Expand All @@ -92,11 +97,16 @@ export const RewardsCard = () => {
(canRedeem
? "text-primary"
: `text-gray-400 ${
nodeStatus?.state === "active" ? "tooltip" : ""
nodeStatus?.state === "active" || !isStoppedForLongerThan15Minutes ? "tooltip" : ""
}`)
}
data-tip="It is not possible to redeem rewards while you are validating.
If absolutely necessary, use the force stop option in settings (Not Recommended)."
data-tip={
nodeStatus?.state === "active"
? "It is not possible to redeem rewards while you are validating. If absolutely necessary, use the force stop option in settings (Not Recommended)."
: !isStoppedForLongerThan15Minutes
? `Node has been stopped recently. Please wait for another ${formatRemainingTime(remainingWaitTime)} before redeeming rewards.`
: ""
}
disabled={!canRedeem}
onClick={() => {
resetModal();
Expand Down Expand Up @@ -128,4 +138,4 @@ export const RewardsCard = () => {
</div>
</Card>
);
};
};
7 changes: 2 additions & 5 deletions components/molecules/StakeDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { ClipboardIcon } from "../atoms/ClipboardIcon";
import { MobileModalWrapper } from "../layouts/MobileModalWrapper";
import { useAccountStakeInfo } from "../../hooks/useAccountStakeInfo";
import { useSettings } from "../../hooks/useSettings";
import { formatRemainingTime } from "../../utils/formatTime";

export const StakeDisplay = () => {
const addressRef = useRef<HTMLSpanElement>(null);
Expand Down Expand Up @@ -52,11 +53,7 @@ export const StakeDisplay = () => {
return { isStoppedForLongerThan15Minutes, remainingWaitTime };
}, [settings?.lastStopped]);

const formatRemainingTime = (ms: number) => {
const minutes = Math.floor(ms / 60000);
const seconds = Math.floor((ms % 60000) / 1000);
return `${minutes}m ${seconds}s`;
};


return (
<Card>
Expand Down
30 changes: 29 additions & 1 deletion pages/onboarding/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ const Onboarding = () => {
const [accountBalance, setAccountBalance] = useState("");
const [chainId, setChainId] = useState(0);
const [tokenClaimPhase, setTokenClaimPhase] = useState(0); // 0: hasn't claimed yet, 1: initiated request, 2: has claimed
const { resetToast } = useToastStore((state: any) => ({
resetToast: state.resetToast,
}));
const { isConnected, address } = useAccount({
onConnect: async (args) => {
if (args?.address) {
Expand Down Expand Up @@ -102,7 +105,30 @@ const Onboarding = () => {
stakeAmount: minimumStakeRequirement.toString(),
totalStaked: nodeStatus?.lockedStake ? Number(nodeStatus?.lockedStake) : 0,
onStake: (wasTxnSuccessful: boolean) => {
setIsStakingComplete(wasTxnSuccessful);
if (wasTxnSuccessful) {
setIsStakingComplete(true);
setCurrentToast({
severity: ToastSeverity.SUCCESS,
title: "Stake Added",
description: `${stakedAmount.toFixed(2)} SHM staked Successfully`,
followupNotification: {
title: "Stake Added",
type: NotificationType.REWARD,
severity: NotificationSeverity.SUCCESS,
},
});
} else {
setCurrentToast({
severity: ToastSeverity.DANGER,
title: "Staking Unsuccessful",
description: "Transaction failed or was rejected by the user",
followupNotification: {
title: "Staking Unsuccessful",
type: NotificationType.REWARD,
severity: NotificationSeverity.DANGER,
},
});
}
},
});

Expand Down Expand Up @@ -158,6 +184,8 @@ const Onboarding = () => {
description: "Your add stake transaction is in process.",
duration: 300000, // 300 seconds
});
} else {
resetToast();
}
}, [isStaking]);

Expand Down
5 changes: 5 additions & 0 deletions utils/formatTime.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const formatRemainingTime = (ms: number) => {
const minutes = Math.floor(ms / 60000);
const seconds = Math.floor((ms % 60000) / 1000);
return `${minutes}m ${seconds}s`;
};
Loading