Skip to content

Commit bd5ecbb

Browse files
committed
feat(web): dispute-maintenance-buttons
1 parent ad0154c commit bd5ecbb

File tree

9 files changed

+436
-2
lines changed

9 files changed

+436
-2
lines changed
Lines changed: 1 addition & 0 deletions
Loading

web/src/hooks/queries/useDisputeDetailsQuery.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const disputeDetailsQuery = graphql(`
2626
tied
2727
currentRound {
2828
id
29+
nbVotes
2930
}
3031
currentRoundIndex
3132
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import React, { useMemo, useState } from "react";
2+
import styled from "styled-components";
3+
4+
import { usePublicClient } from "wagmi";
5+
6+
import { Button } from "@kleros/ui-components-library";
7+
8+
import { useSimulateKlerosCoreExecute, useWriteKlerosCoreExecute } from "hooks/contracts/generated";
9+
import { wrapWithToast } from "utils/wrapWithToast";
10+
11+
import { isUndefined } from "src/utils";
12+
13+
import { IBaseMaintenaceButton } from ".";
14+
15+
const StyledButton = styled(Button)`
16+
width: 100%;
17+
`;
18+
19+
interface IDistributeRewards extends IBaseMaintenaceButton {
20+
numberOfVotes?: string;
21+
roundIndex?: string;
22+
}
23+
24+
const DistributeRewards: React.FC<IDistributeRewards> = ({ id, numberOfVotes, roundIndex, setIsOpen }) => {
25+
const [isSending, setIsSending] = useState(false);
26+
const publicClient = usePublicClient();
27+
28+
const {
29+
data: executeConfig,
30+
isLoading: isLoadingConfig,
31+
isError,
32+
} = useSimulateKlerosCoreExecute({
33+
query: {
34+
enabled: !isUndefined(id) && !isUndefined(numberOfVotes) && !isUndefined(roundIndex),
35+
},
36+
args: [BigInt(id ?? 0), BigInt(roundIndex ?? 0), BigInt(numberOfVotes ?? 0)],
37+
});
38+
39+
const { writeContractAsync: execute } = useWriteKlerosCoreExecute();
40+
41+
const isLoading = useMemo(() => isLoadingConfig || isSending, [isLoadingConfig, isSending]);
42+
const isDisabled = useMemo(
43+
() => isUndefined(id) || isUndefined(numberOfVotes) || isError || isLoading,
44+
[id, numberOfVotes, isError, isLoading]
45+
);
46+
const handleClick = () => {
47+
if (!executeConfig) return;
48+
49+
setIsSending(true);
50+
51+
wrapWithToast(async () => await execute(executeConfig.request), publicClient).finally(() => {
52+
setIsOpen(false);
53+
});
54+
};
55+
return <StyledButton text="Rewards" small isLoading={isLoading} disabled={isDisabled} onClick={handleClick} />;
56+
};
57+
58+
export default DistributeRewards;
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import React, { useMemo, useState } from "react";
2+
import styled from "styled-components";
3+
4+
import { usePublicClient } from "wagmi";
5+
6+
import { Button } from "@kleros/ui-components-library";
7+
8+
import { useSimulateKlerosCoreDraw, useWriteKlerosCoreDraw } from "hooks/contracts/generated";
9+
import { wrapWithToast } from "utils/wrapWithToast";
10+
11+
import { isUndefined } from "src/utils";
12+
13+
import { IBaseMaintenaceButton } from ".";
14+
15+
const StyledButton = styled(Button)`
16+
width: 100%;
17+
`;
18+
19+
interface IDrawButton extends IBaseMaintenaceButton {
20+
numberOfVotes?: string;
21+
}
22+
23+
const DrawButton: React.FC<IDrawButton> = ({ id, numberOfVotes, setIsOpen }) => {
24+
const [isSending, setIsSending] = useState(false);
25+
const publicClient = usePublicClient();
26+
27+
const {
28+
data: drawConfig,
29+
isLoading: isLoadingConfig,
30+
isError,
31+
} = useSimulateKlerosCoreDraw({
32+
query: {
33+
enabled: !isUndefined(id) && !isUndefined(numberOfVotes),
34+
},
35+
args: [BigInt(id ?? 0), BigInt(numberOfVotes ?? 0)],
36+
});
37+
38+
const { writeContractAsync: draw } = useWriteKlerosCoreDraw();
39+
40+
const isLoading = useMemo(() => isLoadingConfig || isSending, [isLoadingConfig, isSending]);
41+
const isDisabled = useMemo(
42+
() => isUndefined(id) || isUndefined(numberOfVotes) || isError || isLoading,
43+
[id, numberOfVotes, isError, isLoading]
44+
);
45+
const handleClick = () => {
46+
if (!drawConfig) return;
47+
48+
setIsSending(true);
49+
50+
wrapWithToast(async () => await draw(drawConfig.request), publicClient).finally(() => {
51+
setIsSending(false);
52+
setIsOpen(false);
53+
});
54+
};
55+
return <StyledButton text="Draw" small isLoading={isLoading} disabled={isDisabled} onClick={handleClick} />;
56+
};
57+
58+
export default DrawButton;
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import React, { useMemo, useState } from "react";
2+
import styled from "styled-components";
3+
4+
import { usePublicClient } from "wagmi";
5+
6+
import { Button } from "@kleros/ui-components-library";
7+
8+
import { useSimulateKlerosCoreExecuteRuling, useWriteKlerosCoreExecuteRuling } from "hooks/contracts/generated";
9+
import { wrapWithToast } from "utils/wrapWithToast";
10+
11+
import { isUndefined } from "src/utils";
12+
13+
import { IBaseMaintenaceButton } from ".";
14+
15+
const StyledButton = styled(Button)`
16+
width: 100%;
17+
`;
18+
19+
type IExecuteRulingButton = IBaseMaintenaceButton;
20+
21+
const ExecuteRulingButton: React.FC<IExecuteRulingButton> = ({ id, setIsOpen }) => {
22+
const [isSending, setIsSending] = useState(false);
23+
const publicClient = usePublicClient();
24+
25+
const {
26+
data: ruleConfig,
27+
isLoading: isLoadingConfig,
28+
isError,
29+
} = useSimulateKlerosCoreExecuteRuling({
30+
query: {
31+
enabled: !isUndefined(id),
32+
},
33+
args: [BigInt(id ?? 0)],
34+
});
35+
36+
const { writeContractAsync: rule } = useWriteKlerosCoreExecuteRuling();
37+
38+
const isLoading = useMemo(() => isLoadingConfig || isSending, [isLoadingConfig, isSending]);
39+
const isDisabled = useMemo(() => isUndefined(id) || isError || isLoading, [id, isError, isLoading]);
40+
const handleClick = () => {
41+
if (!ruleConfig) return;
42+
43+
setIsSending(true);
44+
45+
wrapWithToast(async () => await rule(ruleConfig.request), publicClient).finally(() => {
46+
setIsSending(false);
47+
setIsOpen(false);
48+
});
49+
};
50+
return <StyledButton text="Rule" small isLoading={isLoading} disabled={isDisabled} onClick={handleClick} />;
51+
};
52+
53+
export default ExecuteRulingButton;
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import React from "react";
2+
import styled, { css, keyframes } from "styled-components";
3+
4+
import DottedMenu from "svgs/icons/dotted-menu.svg";
5+
6+
const ripple = keyframes`
7+
0% {
8+
opacity: 0;
9+
transform: scale3d(0.5, 0.5, 1);
10+
}
11+
10% {
12+
opacity: 0.5;
13+
transform: scale3d(0.75, 0.75, 1);
14+
}
15+
16+
100% {
17+
opacity: 0;
18+
transform: scale3d(1.75, 1.75, 1);
19+
}
20+
`;
21+
22+
const ring = (duration: string, delay: string) => css`
23+
opacity: 0;
24+
position: absolute;
25+
top: 0;
26+
left: 0;
27+
transform: translate(50%);
28+
content: "";
29+
height: 36px;
30+
width: 36px;
31+
border: 3px solid ${({ theme }) => theme.primaryBlue};
32+
border-radius: 100%;
33+
animation-name: ${ripple};
34+
animation-duration: ${duration};
35+
animation-delay: ${delay};
36+
animation-iteration-count: infinite;
37+
animation-timing-function: cubic-bezier(0.65, 0, 0.34, 1);
38+
z-index: 0;
39+
`;
40+
41+
const Container = styled.div<{ displayRipple: boolean }>`
42+
display: flex;
43+
justify-content: center;
44+
align-items: center;
45+
${({ displayRipple }) =>
46+
displayRipple &&
47+
css`
48+
&::after {
49+
${ring("3s", "0s")}
50+
}
51+
&::before {
52+
${ring("3s", "0.5s")}
53+
}
54+
`}
55+
`;
56+
57+
const ButtonContainer = styled.div`
58+
border-radius: 50%;
59+
z-index: 1;
60+
background-color: ${({ theme }) => theme.lightBackground};
61+
`;
62+
63+
const StyledDottedMenu = styled(DottedMenu)`
64+
cursor: pointer;
65+
width: 36px;
66+
height: 36px;
67+
fill: ${({ theme }) => theme.primaryBlue};
68+
`;
69+
70+
interface IMenuButton {
71+
setIsOpen: (open: boolean) => void;
72+
displayRipple: boolean;
73+
}
74+
75+
const MenuButton: React.FC<IMenuButton> = ({ setIsOpen, displayRipple }) => {
76+
return (
77+
<Container {...{ displayRipple }}>
78+
<ButtonContainer>
79+
<StyledDottedMenu onClick={() => setIsOpen(true)} />
80+
</ButtonContainer>
81+
</Container>
82+
);
83+
};
84+
85+
export default MenuButton;
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import React, { useMemo, useState } from "react";
2+
import styled from "styled-components";
3+
4+
import { usePublicClient } from "wagmi";
5+
6+
import { Button } from "@kleros/ui-components-library";
7+
8+
import { useSimulateKlerosCorePassPeriod, useWriteKlerosCorePassPeriod } from "hooks/contracts/generated";
9+
import { wrapWithToast } from "utils/wrapWithToast";
10+
11+
import { isUndefined } from "src/utils";
12+
13+
import { IBaseMaintenaceButton } from ".";
14+
15+
const StyledButton = styled(Button)`
16+
width: 100%;
17+
`;
18+
19+
type IPassPeriodButton = IBaseMaintenaceButton;
20+
21+
const PassPeriodButton: React.FC<IPassPeriodButton> = ({ id, setIsOpen }) => {
22+
const [isSending, setIsSending] = useState(false);
23+
const publicClient = usePublicClient();
24+
25+
const {
26+
data: passPeriodConfig,
27+
isLoading: isLoadingConfig,
28+
isError,
29+
} = useSimulateKlerosCorePassPeriod({
30+
query: {
31+
enabled: !isUndefined(id),
32+
},
33+
args: [BigInt(id ?? 0)],
34+
});
35+
36+
const { writeContractAsync: passPeriod } = useWriteKlerosCorePassPeriod();
37+
38+
const isLoading = useMemo(() => isLoadingConfig || isSending, [isLoadingConfig, isSending]);
39+
const isDisabled = useMemo(() => isUndefined(id) || isError || isLoading, [id, isError, isLoading]);
40+
const handleClick = () => {
41+
if (!passPeriodConfig) return;
42+
43+
setIsSending(true);
44+
45+
wrapWithToast(async () => await passPeriod(passPeriodConfig.request), publicClient).finally(() => {
46+
setIsSending(false);
47+
setIsOpen(false);
48+
});
49+
};
50+
return <StyledButton text="Pass Period" small isLoading={isLoading} disabled={isDisabled} onClick={handleClick} />;
51+
};
52+
53+
export default PassPeriodButton;

0 commit comments

Comments
 (0)