Skip to content

Commit 5b50c73

Browse files
committed
refactor(web): refactor-new-stake-flow
1 parent d5c9c27 commit 5b50c73

File tree

8 files changed

+266
-233
lines changed

8 files changed

+266
-233
lines changed

web/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,12 @@
8181
"@kleros/kleros-app": "workspace:^",
8282
"@kleros/kleros-sdk": "workspace:^",
8383
"@kleros/kleros-v2-contracts": "workspace:^",
84-
"@kleros/ui-components-library": "^2.15.0",
84+
"@kleros/ui-components-library": "^2.16.0",
8585
"@lifi/wallet-management": "^3.4.5",
8686
"@lifi/widget": "^3.12.2",
8787
"@sentry/react": "^7.120.0",
8888
"@sentry/tracing": "^7.120.0",
89-
"@tanstack/react-query": "^5.61.0",
89+
"@tanstack/react-query": "^5.56.2",
9090
"@types/react-modal": "^3.16.3",
9191
"@wagmi/connectors": "^5.5.0",
9292
"@wagmi/core": "^2.15.0",

web/src/components/Spinner.tsx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import styled, { keyframes } from "styled-components";
2+
3+
import SpinnerIcon from "svgs/icons/spinner.svg";
4+
5+
const rotating = keyframes`
6+
0%{
7+
transform: rotate(0deg);
8+
}
9+
50%{
10+
transform: rotate(180deg);
11+
}
12+
100%{
13+
transform: rotate(360deg);
14+
}
15+
`;
16+
17+
const Spinner = styled(SpinnerIcon)`
18+
path {
19+
fill: ${({ theme }) => theme.primaryBlue};
20+
}
21+
width: 16px;
22+
height: 16px;
23+
margin-right: 4px;
24+
animation: ${rotating} 2s ease-in-out infinite normal;
25+
`;
26+
27+
export default Spinner;

web/src/components/TxnHash.tsx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import React, { useMemo } from "react";
2+
import styled from "styled-components";
3+
4+
import NewTabIcon from "svgs/icons/new-tab.svg";
5+
6+
import { DEFAULT_CHAIN, getChain } from "consts/chains";
7+
8+
import { ExternalLink } from "./ExternalLink";
9+
10+
const TxnLabel = styled.label<{ variant: string }>`
11+
display: flex;
12+
gap: 4px;
13+
color: ${({ theme, variant }) => (variant === "pending" ? theme.primaryBlue : theme[variant])};
14+
cursor: pointer;
15+
path {
16+
fill: ${({ theme, variant }) => (variant === "pending" ? theme.primaryBlue : theme[variant])};
17+
}
18+
`;
19+
20+
interface ITxnHash {
21+
hash: `0x${string}`;
22+
variant: "success" | "error" | "pending";
23+
}
24+
const TxnHash: React.FC<ITxnHash> = ({ hash, variant }) => {
25+
const transactionExplorerLink = useMemo(() => {
26+
return `${getChain(DEFAULT_CHAIN)?.blockExplorers?.default.url}/tx/${hash}`;
27+
}, [hash]);
28+
29+
return (
30+
<ExternalLink to={transactionExplorerLink} rel="noopener noreferrer" target="_blank">
31+
<TxnLabel {...{ variant }}>
32+
{" "}
33+
<span>{hash.substring(0, 6) + "..." + hash.substring(hash.length - 4)}</span>
34+
<NewTabIcon />
35+
</TxnLabel>
36+
</ExternalLink>
37+
);
38+
};
39+
40+
export default TxnHash;

web/src/pages/Courts/CourtDetails/StakePanel/StakeWithdrawButton.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,12 +260,13 @@ const StakeWithdrawButton: React.FC<IActionButton> = ({ amount, parsedAmount, ac
260260
]);
261261

262262
useEffect(() => {
263+
if (isPopupOpen) return;
263264
if (setStakeError || allowanceError) {
264265
setErrorMsg(parseWagmiError(setStakeError || allowanceError));
265266
} else if (targetStake !== 0n && courtDetails && targetStake < BigInt(courtDetails.court?.minStake)) {
266267
setErrorMsg(`Min Stake in court is: ${formatETH(courtDetails?.court?.minStake)}`);
267268
}
268-
}, [setStakeError, setErrorMsg, targetStake, courtDetails, allowanceError]);
269+
}, [setStakeError, setErrorMsg, targetStake, courtDetails, allowanceError, isPopupOpen]);
269270

270271
const isDisabled = useMemo(() => {
271272
if (

web/src/pages/Courts/CourtDetails/StakePanel/StakeWithdrawPopup/Header.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,13 @@ const Header: React.FC<IHeader> = ({ action, amount, isSuccess }) => {
6464
const jurorCurrentSpecificStake = address && jurorStakeData ? Number(formatEther(jurorStakeData.staked)) : 0;
6565

6666
const isWithdraw = action === ActionType.withdraw;
67-
const actionText = useMemo(() => (isWithdraw ? "withdrew" : "staked"), [isWithdraw]);
67+
const preStakeText = useMemo(() => (isWithdraw ? "withdrawing" : "staking"), [isWithdraw]);
68+
const postStakeText = useMemo(() => (isWithdraw ? "withdrew" : "staked"), [isWithdraw]);
69+
6870
return (
6971
<StakingMsgContainer>
7072
{isSuccess ? <CheckIcon /> : null}
71-
<StakingMsg>{isSuccess ? `You successfully ${actionText}` : `You are ${actionText}`}</StakingMsg>
73+
<StakingMsg>{isSuccess ? `You successfully ${postStakeText}` : `You are ${preStakeText}`}</StakingMsg>
7274
<StakingAmount>{amount} PNK</StakingAmount>
7375
{courtDetails?.court?.name ? <CourtName>on {courtDetails.court.name}</CourtName> : null}
7476
{isSuccess ? null : (

web/src/pages/Courts/CourtDetails/StakePanel/StakeWithdrawPopup/index.tsx

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,37 @@
11
import React from "react";
2-
import styled, { css } from "styled-components";
2+
import styled, { css, keyframes } from "styled-components";
33

44
import { _TimelineItem1, CustomTimeline } from "@kleros/ui-components-library";
55

66
import Close from "svgs/icons/close.svg";
77

88
import { useLockOverlayScroll } from "hooks/useLockOverlayScroll";
9+
import { useSortitionModulePhase } from "hooks/useSortitionModule";
910

1011
import { landscapeStyle } from "styles/landscapeStyle";
1112
import { responsiveSize } from "styles/responsiveSize";
1213

1314
import { Divider } from "components/Divider";
15+
import InfoCard from "components/InfoCard";
1416
import LightButton from "components/LightButton";
1517
import { Overlay } from "components/Overlay";
18+
import { Phases } from "components/Phase";
1619

1720
import { ActionType } from "../StakeWithdrawButton";
1821

1922
import Header from "./Header";
2023

24+
const animation = keyframes`
25+
0%{
26+
transform: translate(-50%,-47%);
27+
opacity: 0;
28+
}
29+
100%{
30+
transform: translate(-50%,-50%);
31+
opacity: 1;
32+
};
33+
`;
34+
2135
const Container = styled.div`
2236
display: flex;
2337
position: fixed;
@@ -33,12 +47,14 @@ const Container = styled.div`
3347
justify-content: center;
3448
width: 86vw;
3549
max-width: 600px;
36-
border-radius: 3px;
50+
border-radius: 7px;
3751
border: 1px solid ${({ theme }) => theme.stroke};
3852
background-color: ${({ theme }) => theme.whiteBackground};
3953
box-shadow: 0px 2px 3px rgba(0, 0, 0, 0.06);
4054
padding: 8px;
4155
56+
animation: ${animation} 200ms ease-in;
57+
4258
svg {
4359
visibility: visible;
4460
}
@@ -66,12 +82,23 @@ const StyledButton = styled(LightButton)`
6682
border-radius: 7px !important;
6783
height: fit-content !important;
6884
align-self: end;
85+
.button-svg {
86+
path {
87+
fill: ${({ theme }) => theme.stroke};
88+
}
89+
}
6990
`;
7091

71-
const CloseIcon = styled(Close)`
72-
fill: ${({ theme }) => theme.stroke};
92+
const InfoContainer = styled.div`
93+
display: flex;
94+
flex-direction: column;
95+
gap: 24px;
96+
margin-top: 8px;
7397
`;
7498

99+
const StyledInfoCard = styled(InfoCard)`
100+
font-size: 14px;
101+
`;
75102
interface IStakeWithdrawPopup {
76103
action: ActionType;
77104
amount: string;
@@ -82,14 +109,24 @@ interface IStakeWithdrawPopup {
82109

83110
const StakeWithdrawPopup: React.FC<IStakeWithdrawPopup> = ({ amount, closePopup, steps, isSuccess, action }) => {
84111
useLockOverlayScroll(true);
112+
const { data: phase } = useSortitionModulePhase();
113+
85114
return (
86115
<Overlay onClick={closePopup}>
87116
<Container onClick={(e) => e.stopPropagation()}>
88-
<StyledButton Icon={CloseIcon} text="" onClick={closePopup} />
117+
<StyledButton Icon={Close} text="" onClick={closePopup} />
89118
<InnerContainer>
90119
<Header {...{ amount, isSuccess, action }} />
91120
<Divider />
92121
{steps?.items && <CustomTimeline items={steps.items} />}
122+
{phase !== Phases.staking ? (
123+
<InfoContainer>
124+
<Divider />
125+
<StyledInfoCard
126+
msg={`The ${action === ActionType.stake ? "stake" : "withdraw"} might be delayed by ~1 hr.`}
127+
/>
128+
</InfoContainer>
129+
) : null}
93130
</InnerContainer>
94131
</Container>
95132
</Overlay>

0 commit comments

Comments
 (0)