Skip to content

Commit 474605b

Browse files
authored
Merge pull request #1863 from kleros/refactor/appeal-tab
Refactor/appeal tab
2 parents 227337b + 2a8a90c commit 474605b

File tree

6 files changed

+94
-44
lines changed

6 files changed

+94
-44
lines changed

web/src/hooks/useClassicAppealContext.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ interface ISelectedOptionContext {
2828
}
2929
const SelectedOptionContext = createContext<ISelectedOptionContext>({
3030
selectedOption: undefined,
31-
//eslint-disable-next-line @typescript-eslint/no-empty-function
31+
3232
setSelectedOption: () => {},
3333
});
3434

web/src/pages/Cases/CaseDetails/Appeal/Classic/Fund.tsx

+10-3
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ const StyledField = styled(Field)`
3333
&:before {
3434
position: absolute;
3535
content: "ETH";
36-
right: 12px;
36+
right: 32px;
3737
top: 50%;
3838
transform: translateY(-50%);
3939
color: ${({ theme }) => theme.primaryText};
@@ -112,8 +112,15 @@ const Fund: React.FC<IFund> = ({ amount, setAmount, setIsOpen }) => {
112112
const { fundAppealConfig, fundAppeal, isLoading, isError } = useFundAppeal(parsedAmount, insufficientBalance);
113113

114114
const isFundDisabled = useMemo(
115-
() => isDisconnected || isSending || !balance || insufficientBalance || Number(parsedAmount) <= 0 || isError,
116-
[isDisconnected, isSending, balance, insufficientBalance, parsedAmount, isError]
115+
() =>
116+
isDisconnected ||
117+
isSending ||
118+
!balance ||
119+
insufficientBalance ||
120+
Number(parsedAmount) <= 0 ||
121+
isError ||
122+
isLoading,
123+
[isDisconnected, isSending, balance, insufficientBalance, parsedAmount, isError, isLoading]
117124
);
118125

119126
return needFund ? (

web/src/pages/Cases/CaseDetails/Appeal/index.tsx

+7-9
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,13 @@ const Appeal: React.FC<{ currentPeriodIndex: number }> = ({ currentPeriodIndex }
4646
const [isAppealMiniGuideOpen, toggleAppealMiniGuide] = useToggle(false);
4747

4848
return (
49-
<ClassicAppealProvider>
50-
<Container>
51-
{Periods.appeal === currentPeriodIndex ? (
52-
<Classic isAppealMiniGuideOpen={isAppealMiniGuideOpen} toggleAppealMiniGuide={toggleAppealMiniGuide} />
53-
) : (
54-
<AppealHistory isAppealMiniGuideOpen={isAppealMiniGuideOpen} toggleAppealMiniGuide={toggleAppealMiniGuide} />
55-
)}
56-
</Container>
57-
</ClassicAppealProvider>
49+
<Container>
50+
{Periods.appeal === currentPeriodIndex ? (
51+
<Classic isAppealMiniGuideOpen={isAppealMiniGuideOpen} toggleAppealMiniGuide={toggleAppealMiniGuide} />
52+
) : (
53+
<AppealHistory isAppealMiniGuideOpen={isAppealMiniGuideOpen} toggleAppealMiniGuide={toggleAppealMiniGuide} />
54+
)}
55+
</Container>
5856
);
5957
};
6058

web/src/pages/Cases/CaseDetails/MaintenanceButtons/DrawButton.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import React, { useMemo, useState } from "react";
22
import styled from "styled-components";
33

4+
import { Link } from "react-router-dom";
5+
import { isAddress } from "viem";
46
import { usePublicClient } from "wagmi";
57

68
import { Button, Field } from "@kleros/ui-components-library";
@@ -11,15 +13,13 @@ import { wrapWithToast } from "utils/wrapWithToast";
1113

1214
import useDisputeMaintenanceQuery from "queries/useDisputeMaintenanceQuery";
1315

16+
import { isKlerosUniversity } from "src/consts";
1417
import { Period } from "src/graphql/graphql";
1518
import { isUndefined } from "src/utils";
1619

1720
import { Phases } from "components/Phase";
1821

1922
import { IBaseMaintenanceButton } from ".";
20-
import { Link } from "react-router-dom";
21-
import { isKlerosUniversity } from "src/consts";
22-
import { isAddress } from "viem";
2323

2424
const StyledButton = styled(Button)`
2525
width: 100%;

web/src/pages/Cases/CaseDetails/Timeline.tsx

+45-3
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
11
import React, { useMemo } from "react";
22
import styled, { css } from "styled-components";
33

4-
import { landscapeStyle } from "styles/landscapeStyle";
5-
import { responsiveSize } from "styles/responsiveSize";
6-
74
import { Box, Steps } from "@kleros/ui-components-library";
85

6+
import HourglassIcon from "svgs/icons/hourglass.svg";
7+
98
import { Periods } from "consts/periods";
9+
import { useCountdownContext, useFundingContext } from "hooks/useClassicAppealContext";
1010
import { useCountdown } from "hooks/useCountdown";
1111
import useIsDesktop from "hooks/useIsDesktop";
1212
import { secondsToDayHourMinute } from "utils/date";
1313

1414
import { DisputeDetailsQuery } from "queries/useDisputeDetailsQuery";
1515

16+
import { isUndefined } from "src/utils";
17+
18+
import { landscapeStyle } from "styles/landscapeStyle";
19+
import { responsiveSize } from "styles/responsiveSize";
20+
1621
import { StyledSkeleton } from "components/StyledSkeleton";
1722

1823
const TimeLineContainer = styled(Box)`
@@ -43,19 +48,56 @@ const StyledSteps = styled(Steps)`
4348
)}
4449
`;
4550

51+
const AppealBannerContainer = styled.div`
52+
background-color: ${({ theme }) => theme.whiteBackground};
53+
border-radius: 3px;
54+
margin-top: 16px;
55+
padding: 12px;
56+
display: flex;
57+
gap: 8px;
58+
align-items: center;
59+
justify-content: center;
60+
& > svg {
61+
width: 14px;
62+
fill: ${({ theme }) => theme.secondaryPurple};
63+
}
64+
`;
65+
4666
const Timeline: React.FC<{
4767
dispute: DisputeDetailsQuery["dispute"];
4868
currentPeriodIndex: number;
4969
}> = ({ currentPeriodIndex, dispute }) => {
5070
const currentItemIndex = currentPeriodToCurrentItem(currentPeriodIndex, dispute?.court.hiddenVotes);
5171
const items = useTimeline(dispute, currentItemIndex, currentItemIndex);
72+
5273
return (
5374
<TimeLineContainer>
5475
<StyledSteps horizontal {...{ items, currentItemIndex, currentPeriodIndex }} />
76+
{currentPeriodIndex === Periods.appeal ? <AppealBanner /> : null}
5577
</TimeLineContainer>
5678
);
5779
};
5880

81+
const AppealBanner: React.FC = () => {
82+
const { loserSideCountdown, winnerSideCountdown } = useCountdownContext();
83+
const { fundedChoices } = useFundingContext();
84+
85+
const text = useMemo(() => {
86+
if (loserSideCountdown)
87+
return `${secondsToDayHourMinute(loserSideCountdown)} left until losing options can be funded`;
88+
// only show if loosing option was funded and winner needs funding, else no action is needed from user
89+
if (winnerSideCountdown && !isUndefined(fundedChoices) && fundedChoices.length > 0)
90+
return `${secondsToDayHourMinute(winnerSideCountdown)} left until winning option can be funded`;
91+
return;
92+
}, [loserSideCountdown, winnerSideCountdown, fundedChoices]);
93+
94+
return text ? (
95+
<AppealBannerContainer>
96+
<HourglassIcon /> <small>{text}</small>
97+
</AppealBannerContainer>
98+
) : null;
99+
};
100+
59101
const currentPeriodToCurrentItem = (currentPeriodIndex: number, hiddenVotes?: boolean): number => {
60102
if (hiddenVotes) return currentPeriodIndex;
61103
if (currentPeriodIndex <= Periods.commit) return currentPeriodIndex;

web/src/pages/Cases/CaseDetails/index.tsx

+28-25
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { Route, Routes, useParams, Navigate } from "react-router-dom";
66
import { Card } from "@kleros/ui-components-library";
77

88
import { Periods } from "consts/periods";
9+
import { ClassicAppealProvider } from "hooks/useClassicAppealContext";
910
import { VotingContextProvider } from "hooks/useVotingContext";
1011

1112
import { useDisputeDetailsQuery } from "queries/useDisputeDetailsQuery";
@@ -58,32 +59,34 @@ const CaseDetails: React.FC = () => {
5859

5960
return (
6061
<VotingContextProvider>
61-
<Container>
62-
<HeaderContainer>
63-
<Header>
64-
Case #{id} {id ? <CaseStarButton id={id} /> : null}
65-
</Header>
62+
<ClassicAppealProvider>
63+
<Container>
64+
<HeaderContainer>
65+
<Header>
66+
Case #{id} {id ? <CaseStarButton id={id} /> : null}
67+
</Header>
6668

67-
<MaintenanceButtons />
68-
</HeaderContainer>
69-
<Timeline {...{ currentPeriodIndex, dispute }} />
70-
<Tabs />
71-
<StyledCard>
72-
<Routes>
73-
<Route
74-
path="overview"
75-
element={
76-
<Overview currentPeriodIndex={currentPeriodIndex} courtID={dispute?.court.id} {...{ arbitrable }} />
77-
}
78-
/>
79-
<Route path="evidence" element={<Evidence />} />
80-
<Route path="voting" element={<Voting {...{ arbitrable, currentPeriodIndex }} />} />
81-
<Route path="appeal" element={<Appeal {...{ currentPeriodIndex }} />} />
82-
<Route path="*" element={<Navigate to="overview" replace />} />
83-
</Routes>
84-
</StyledCard>
85-
<ScrollTop />
86-
</Container>
69+
<MaintenanceButtons />
70+
</HeaderContainer>
71+
<Timeline {...{ currentPeriodIndex, dispute }} />
72+
<Tabs />
73+
<StyledCard>
74+
<Routes>
75+
<Route
76+
path="overview"
77+
element={
78+
<Overview currentPeriodIndex={currentPeriodIndex} courtID={dispute?.court.id} {...{ arbitrable }} />
79+
}
80+
/>
81+
<Route path="evidence" element={<Evidence />} />
82+
<Route path="voting" element={<Voting {...{ arbitrable, currentPeriodIndex }} />} />
83+
<Route path="appeal" element={<Appeal {...{ currentPeriodIndex }} />} />
84+
<Route path="*" element={<Navigate to="overview" replace />} />
85+
</Routes>
86+
</StyledCard>
87+
<ScrollTop />
88+
</Container>
89+
</ClassicAppealProvider>
8790
</VotingContextProvider>
8891
);
8992
};

0 commit comments

Comments
 (0)