Skip to content

Commit 1348f3b

Browse files
committed
feat(web): update-batch-creation-ui
1 parent a0f1982 commit 1348f3b

File tree

4 files changed

+190
-50
lines changed

4 files changed

+190
-50
lines changed

web/src/components/PlusMinusField.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const IconContainer = styled.button`
2222

2323
const StyledEllipseIcon = styled(Ellipse)<{ isDisabled?: boolean }>`
2424
circle {
25+
fill: ${({ theme }) => theme.primaryBlue};
2526
${({ isDisabled }) =>
2627
isDisabled &&
2728
css`

web/src/pages/Resolver/NavigationButtons/SubmitBatchDisputesButton.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ const SubmitBatchDisputesButton: React.FC = () => {
8585
<EnsureChain>
8686
<div>
8787
<StyledButton
88-
text="Submit cases"
88+
text="Create cases"
8989
disabled={isButtonDisabled}
9090
isLoading={(isSubmittingCase || isBalanceLoading || isLoadingConfig) && !insufficientBalance}
9191
onClick={() => {
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
import React, { useState } from "react";
2+
import styled, { css } from "styled-components";
3+
4+
import { useDebounce } from "react-use";
5+
6+
import { Card, Switch } from "@kleros/ui-components-library";
7+
8+
import { CoinIds } from "consts/coingecko";
9+
import { useNewDisputeContext } from "context/NewDisputeContext";
10+
import { useCoinPrice } from "hooks/useCoinPrice";
11+
import { formatETH, formatUnitsWei, formatUSD } from "utils/format";
12+
13+
import { isUndefined } from "src/utils";
14+
15+
import { landscapeStyle } from "styles/landscapeStyle";
16+
17+
import { Divider } from "components/Divider";
18+
import PlusMinusField from "components/PlusMinusField";
19+
import WithHelpTooltip from "components/WithHelpTooltip";
20+
21+
const Container = styled(Card)`
22+
width: 100%;
23+
height: fit-content;
24+
`;
25+
26+
const TopContent = styled.div`
27+
width: 100%;
28+
min-height: 64px;
29+
display: flex;
30+
align-items: center;
31+
flex-wrap: wrap;
32+
gap: 16px;
33+
padding: 16px;
34+
35+
span::before {
36+
background-color: ${({ theme }) => theme.whiteBackground} !important;
37+
}
38+
${landscapeStyle(
39+
() => css`
40+
padding: 0px 32px;
41+
`
42+
)}
43+
`;
44+
45+
const BottomContent = styled.div`
46+
width: 100%;
47+
min-height: 64px;
48+
display: flex;
49+
flex-wrap: wrap;
50+
align-items: center;
51+
justify-content: start;
52+
gap: 16px;
53+
padding: 16px;
54+
55+
${landscapeStyle(
56+
() => css`
57+
justify-content: space-between;
58+
padding: 16px 32px;
59+
`
60+
)}
61+
`;
62+
63+
const NumberDisplayContainer = styled.div`
64+
display: flex;
65+
align-items: center;
66+
flex-wrap: wrap;
67+
gap: 16px;
68+
${landscapeStyle(
69+
() => css`
70+
gap: 32px;
71+
`
72+
)}
73+
`;
74+
75+
const NumberDisplay = styled.div`
76+
min-width: 64px;
77+
min-height: 64px;
78+
background-color: ${({ theme }) => theme.lightBackground};
79+
border: 1px solid ${({ theme }) => theme.stroke};
80+
border-radius: 3px;
81+
font-size: 32px;
82+
color: ${({ theme }) => theme.primaryBlue};
83+
text-align: center;
84+
align-content: center;
85+
`;
86+
87+
const Label = styled.p`
88+
padding: 0;
89+
margin: 0;
90+
font-size: 16px;
91+
color: ${({ theme }) => theme.secondaryText};
92+
`;
93+
94+
const Value = styled(Label)`
95+
font-weight: 600;
96+
color: ${({ theme }) => theme.primaryText};
97+
`;
98+
99+
const StyledPlusMinusField = styled(PlusMinusField)`
100+
margin: 0;
101+
path {
102+
fill: ${({ theme }) => theme.whiteBackground};
103+
}
104+
`;
105+
106+
const StyledP = styled.p`
107+
padding: 0;
108+
margin: 0;
109+
font-size: 16px;
110+
color: ${({ theme }) => theme.primaryText};
111+
`;
112+
113+
const InfosContainer = styled.div`
114+
display: flex;
115+
align-items: center;
116+
gap: 16px;
117+
flex-wrap: wrap;
118+
`;
119+
120+
const Info = styled.div`
121+
display: flex;
122+
gap: 8px;
123+
`;
124+
125+
const BatchCreationCard: React.FC = () => {
126+
const { disputeData, isBatchCreation, setIsBatchCreation, batchSize, setBatchSize } = useNewDisputeContext();
127+
const [localBatchSize, setLocalBatchSize] = useState(batchSize);
128+
useDebounce(() => setBatchSize(localBatchSize), 500, [localBatchSize]);
129+
130+
const { prices: pricesData } = useCoinPrice([CoinIds.ETH]);
131+
132+
const coinPrice = !isUndefined(pricesData) ? pricesData[CoinIds.ETH]?.price : undefined;
133+
134+
return (
135+
<Container>
136+
<TopContent>
137+
<Switch checked={isBatchCreation} onChange={() => setIsBatchCreation(!isBatchCreation)} />
138+
<WithHelpTooltip tooltipMsg="Batch Cases: You can create multiple copies of the case. ">
139+
<StyledP>Create multiple cases at once</StyledP>
140+
</WithHelpTooltip>
141+
</TopContent>
142+
{isBatchCreation ? (
143+
<>
144+
<Divider />
145+
<BottomContent>
146+
<NumberDisplayContainer>
147+
<NumberDisplay>{localBatchSize}</NumberDisplay>
148+
<StyledPlusMinusField
149+
minValue={2}
150+
currentValue={localBatchSize}
151+
updateValue={(val) => setLocalBatchSize(val)}
152+
/>
153+
<Label>(Number of cases to be created)</Label>
154+
</NumberDisplayContainer>
155+
<InfosContainer>
156+
<Info>
157+
<Label>Jurors per case:</Label>
158+
<Value>{disputeData.numberOfJurors}</Value>
159+
</Info>
160+
<Info>
161+
<Label>Total:</Label>
162+
<Value>{disputeData.numberOfJurors * localBatchSize}</Value>
163+
</Info>
164+
<Info>
165+
<Label>Total cost:</Label>
166+
<Value>{formatETH(BigInt(disputeData.arbitrationCost ?? 0) * BigInt(localBatchSize))} ETH </Value>
167+
<Label>
168+
~
169+
{formatUSD(
170+
Number(formatUnitsWei(BigInt(disputeData.arbitrationCost ?? 0) * BigInt(localBatchSize))) *
171+
(coinPrice ?? 0)
172+
)}
173+
</Label>
174+
</Info>
175+
</InfosContainer>
176+
</BottomContent>
177+
</>
178+
) : null}
179+
</Container>
180+
);
181+
};
182+
183+
export default BatchCreationCard;

web/src/pages/Resolver/Preview/index.tsx

Lines changed: 5 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from "react";
22
import styled, { css } from "styled-components";
33

4-
import { Card, Checkbox } from "@kleros/ui-components-library";
4+
import { Card } from "@kleros/ui-components-library";
55

66
import { useNewDisputeContext } from "context/NewDisputeContext";
77

@@ -14,11 +14,11 @@ import { DisputeContext } from "components/DisputePreview/DisputeContext";
1414
import { Policies } from "components/DisputePreview/Policies";
1515
import DisputeInfo from "components/DisputeView/DisputeInfo";
1616
import { Divider } from "components/Divider";
17-
import PlusMinusField from "components/PlusMinusField";
18-
import WithHelpTooltip from "components/WithHelpTooltip";
1917

2018
import NavigationButtons from "../NavigationButtons";
2119

20+
import BatchCreationCard from "./BatchCreationCard";
21+
2222
const Container = styled.div`
2323
width: 100%;
2424
padding: 0px ${responsiveSize(10, 130)};
@@ -56,33 +56,6 @@ const Header = styled.h2`
5656
)}
5757
`;
5858

59-
const BatchCreationContainer = styled.div`
60-
display: flex;
61-
flex-direction: column;
62-
gap: 16px;
63-
align-items: start;
64-
align-self: flex-start;
65-
margin-bottom: ${responsiveSize(130, 70)};
66-
`;
67-
68-
const FieldContainer = styled.div`
69-
display: flex;
70-
flex-direction: column;
71-
gap: 8px;
72-
align-items: start;
73-
`;
74-
75-
const FieldLabel = styled.p`
76-
padding: 0;
77-
margin: 0;
78-
font-size: 16px;
79-
color: ${({ theme }) => theme.secondaryText};
80-
`;
81-
82-
const StyledPlusMinusField = styled(PlusMinusField)`
83-
margin: 0;
84-
`;
85-
8659
const Overlay = styled.div`
8760
width: 100%;
8861
height: 100%;
@@ -93,8 +66,7 @@ const Overlay = styled.div`
9366
`;
9467

9568
const Preview: React.FC = () => {
96-
const { disputeData, disputeTemplate, isBatchCreation, setIsBatchCreation, batchSize, setBatchSize } =
97-
useNewDisputeContext();
69+
const { disputeData, disputeTemplate } = useNewDisputeContext();
9870
const { data: courtPolicy } = useCourtPolicy(disputeData.courtId);
9971
const courtName = courtPolicy?.name;
10072

@@ -118,23 +90,7 @@ const Preview: React.FC = () => {
11890
</PreviewContainer>
11991
<Policies disputePolicyURI={disputeTemplate.policyURI} courtId={disputeData.courtId} />
12092
</StyledCard>
121-
<BatchCreationContainer>
122-
<WithHelpTooltip tooltipMsg="Create multiple cases with same data.">
123-
<Checkbox
124-
label="Create batch cases"
125-
small
126-
checked={isBatchCreation}
127-
onChange={() => setIsBatchCreation(!isBatchCreation)}
128-
/>
129-
</WithHelpTooltip>
130-
131-
{isBatchCreation ? (
132-
<FieldContainer>
133-
<FieldLabel>Number of cases to be created: {batchSize}</FieldLabel>
134-
<StyledPlusMinusField minValue={2} currentValue={batchSize} updateValue={(val) => setBatchSize(val)} />
135-
</FieldContainer>
136-
) : null}
137-
</BatchCreationContainer>
93+
<BatchCreationCard />
13894
<NavigationButtons prevRoute="/resolver/policy" />
13995
</Container>
14096
);

0 commit comments

Comments
 (0)