From 4473dc380361a34e8eb9c5044a5345e31c9a2dcc Mon Sep 17 00:00:00 2001
From: kemuru <102478601+kemuru@users.noreply.github.com>
Date: Fri, 6 Dec 2024 13:46:01 +0100
Subject: [PATCH 01/11] feat: bunch of bug fixes, style impros, arrangement
impros, refactors
---
web/src/app.tsx | 2 +-
web/src/components/CasesDisplay/index.tsx | 8 +-
.../components/DisputePreview/Policies.tsx | 79 +++++++------------
.../DisputeInfo/DisputeInfoCard.tsx | 44 +----------
.../DisputeInfo/DisputeInfoList.tsx | 1 +
.../DisputeView/DisputeInfo/index.tsx | 2 +-
web/src/components/Field.tsx | 3 +
web/src/components/LightButton.tsx | 11 +--
web/src/components/Verdict/Answer.tsx | 23 +++++-
web/src/components/Verdict/FinalDecision.tsx | 7 +-
web/src/components/Verdict/VerdictBanner.tsx | 4 +-
web/src/layout/Header/navbar/Explore.tsx | 16 ++--
web/src/layout/Header/navbar/Menu/index.tsx | 10 ++-
web/src/layout/Header/navbar/index.tsx | 6 +-
.../Cases/CaseDetails/Overview/index.tsx | 2 +-
.../pages/Courts/CourtDetails/Description.tsx | 11 ++-
.../{SimulatorPopup => Simulator}/Header.tsx | 0
.../QuantityToSimulate.tsx | 0
.../{SimulatorPopup => Simulator}/index.tsx | 29 ++-----
.../Courts/CourtDetails/StakePanel/index.tsx | 5 +-
web/src/pages/Courts/CourtDetails/Stats.tsx | 67 ++++++++--------
web/src/pages/Courts/CourtDetails/index.tsx | 14 +---
web/src/styles/themes.ts | 2 +
web/src/utils/beautifyStatNumber.ts | 23 ++++++
24 files changed, 174 insertions(+), 195 deletions(-)
rename web/src/pages/Courts/CourtDetails/StakePanel/{SimulatorPopup => Simulator}/Header.tsx (100%)
rename web/src/pages/Courts/CourtDetails/StakePanel/{SimulatorPopup => Simulator}/QuantityToSimulate.tsx (100%)
rename web/src/pages/Courts/CourtDetails/StakePanel/{SimulatorPopup => Simulator}/index.tsx (89%)
diff --git a/web/src/app.tsx b/web/src/app.tsx
index 23a158b6c..f55365693 100644
--- a/web/src/app.tsx
+++ b/web/src/app.tsx
@@ -95,7 +95,7 @@ const App: React.FC = () => {
}
/>
- Justice not found here ¯\_( ͡° ͜ʖ ͡°)_/¯} />
+ Page not found} />
diff --git a/web/src/components/CasesDisplay/index.tsx b/web/src/components/CasesDisplay/index.tsx
index 088bafa14..7b30e7751 100644
--- a/web/src/components/CasesDisplay/index.tsx
+++ b/web/src/components/CasesDisplay/index.tsx
@@ -24,6 +24,10 @@ const StyledTitle = styled.h1`
margin: 0px;
`;
+const StyledLabel = styled.label`
+ font-size: 16px;
+`;
+
interface ICasesDisplay extends ICasesGrid {
numberDisputes?: number;
numberClosedDisputes?: number;
@@ -54,10 +58,10 @@ const CasesDisplay: React.FC = ({
) : null}
-
+
{disputes?.length === 0 ? (
- No cases found
+ No cases found
) : (
theme.mediumBlue};
-
- ${landscapeStyle(
- () => css`
- flex-direction: row;
- justify-content: space-between;
- `
- )};
`;
const StyledP = styled.p`
font-size: 14px;
- margin-top: 0;
- margin-bottom: 16px;
+ margin: 0;
color: ${({ theme }) => theme.primaryBlue};
- ${landscapeStyle(
- () => css`
- margin-bottom: 0;
- `
- )};
`;
const StyledPolicyIcon = styled(PolicyIcon)`
@@ -51,13 +37,6 @@ const StyledPaperclipIcon = styled(PaperclipIcon)`
fill: ${({ theme }) => theme.primaryBlue};
`;
-const LinkContainer = styled.div`
- display: flex;
- gap: ${responsiveSize(16, 24)};
- flex-wrap: wrap;
- align-items: center;
-`;
-
const StyledInternalLink = styled(InternalLink)`
display: flex;
gap: 4px;
@@ -82,28 +61,26 @@ interface IPolicies {
export const Policies: React.FC = ({ disputePolicyURI, courtId, attachment }) => {
return (
-
- Make sure you read and understand the Policies
-
- {!isUndefined(attachment) && !isUndefined(attachment.uri) ? (
-
-
- {attachment.label ?? "Attachment"}
-
- ) : null}
- {isUndefined(disputePolicyURI) ? null : (
-
-
- Dispute Policy
-
- )}
- {isUndefined(courtId) ? null : (
-
-
- Court Policy
-
- )}
-
-
+
+ Policy documents:
+ {!isUndefined(attachment) && !isUndefined(attachment.uri) ? (
+
+
+ {attachment.label ?? "Attachment"}
+
+ ) : null}
+ {isUndefined(disputePolicyURI) ? null : (
+
+
+ Dispute Policy
+
+ )}
+ {isUndefined(courtId) ? null : (
+
+
+ Court Policy
+
+ )}
+
);
};
diff --git a/web/src/components/DisputeView/DisputeInfo/DisputeInfoCard.tsx b/web/src/components/DisputeView/DisputeInfo/DisputeInfoCard.tsx
index 2985fa3f2..68d729164 100644
--- a/web/src/components/DisputeView/DisputeInfo/DisputeInfoCard.tsx
+++ b/web/src/components/DisputeView/DisputeInfo/DisputeInfoCard.tsx
@@ -1,14 +1,9 @@
-import React, { useMemo } from "react";
+import React from "react";
import styled, { css } from "styled-components";
-import LawBalanceIcon from "svgs/icons/law-balance.svg";
-
-import { useCourtTree } from "hooks/queries/useCourtTree";
-
import { landscapeStyle } from "styles/landscapeStyle";
import Field, { IField } from "components/Field";
-import { getCourtsPath } from "pages/Courts/CourtDetails";
import CardLabel from "../CardLabels";
@@ -22,12 +17,6 @@ const Container = styled.div`
justify-content: flex-end;
`;
-const CourtBranchFieldContainer = styled.div`
- display: flex;
- margin-top: 16px;
- flex-wrap: wrap;
-`;
-
const RestOfFieldsContainer = styled.div<{ isOverview?: boolean }>`
display: flex;
flex-direction: column;
@@ -42,7 +31,6 @@ const RestOfFieldsContainer = styled.div<{ isOverview?: boolean }>`
css`
${landscapeStyle(
() => css`
- margin-top: 16px;
gap: 32px;
flex-direction: row;
flex-wrap: wrap;
@@ -56,7 +44,6 @@ const StyledField = styled(Field)`
max-width: 100%;
label {
&.value {
- margin-left: 8px;
overflow: hidden;
text-overflow: ellipsis;
text-wrap: auto;
@@ -66,36 +53,9 @@ const StyledField = styled(Field)`
type IDisputeInfoCard = { fieldItems: FieldItem[] } & IDisputeInfo;
-const DisputeInfoCard: React.FC = ({
- isOverview,
- showLabels,
- fieldItems,
- court,
- courtId,
- disputeID,
- round,
-}) => {
- const { data } = useCourtTree();
- const courtPath = getCourtsPath(data?.court, courtId);
- const items = useMemo(
- () => [...(courtPath?.map((node) => ({ text: node.name, value: node.id })) ?? [])],
- [courtPath]
- );
-
- const courtBranchValue = items.map((item) => item.text).join(" / ");
+const DisputeInfoCard: React.FC = ({ isOverview, showLabels, fieldItems, disputeID, round }) => {
return (
- {court && courtId && isOverview && (
-
-
-
- )}
{fieldItems.map((item) =>
item.display ? : null
diff --git a/web/src/components/DisputeView/DisputeInfo/DisputeInfoList.tsx b/web/src/components/DisputeView/DisputeInfo/DisputeInfoList.tsx
index 65c0bdec7..a82417c29 100644
--- a/web/src/components/DisputeView/DisputeInfo/DisputeInfoList.tsx
+++ b/web/src/components/DisputeView/DisputeInfo/DisputeInfoList.tsx
@@ -30,6 +30,7 @@ const RestOfFieldsContainer = styled.div`
grid-template-columns: repeat(3, min-content);
justify-content: start;
`;
+
const StyledField = styled(Field)<{ style?: string }>`
${({ style }) => style ?? ""}
`;
diff --git a/web/src/components/DisputeView/DisputeInfo/index.tsx b/web/src/components/DisputeView/DisputeInfo/index.tsx
index 2bf8be948..ceb42580f 100644
--- a/web/src/components/DisputeView/DisputeInfo/index.tsx
+++ b/web/src/components/DisputeView/DisputeInfo/index.tsx
@@ -76,7 +76,7 @@ const DisputeInfo: React.FC = ({
name: "Court",
value: court,
link: `/courts/${courtId}`,
- display: !isUndefined(court) && !isUndefined(courtId) && !isOverview,
+ display: !isUndefined(court) && !isUndefined(courtId),
},
{
icon: RoundIcon,
diff --git a/web/src/components/Field.tsx b/web/src/components/Field.tsx
index 1bf44717c..ab6284030 100644
--- a/web/src/components/Field.tsx
+++ b/web/src/components/Field.tsx
@@ -48,6 +48,9 @@ const FieldContainer = styled.div`
text-align: none;
font-weight: 600;
}
+ a {
+ font-weight: 600;
+ }
svg {
margin-right: 0;
}
diff --git a/web/src/components/LightButton.tsx b/web/src/components/LightButton.tsx
index 610c75e72..9e4c579bc 100644
--- a/web/src/components/LightButton.tsx
+++ b/web/src/components/LightButton.tsx
@@ -4,7 +4,7 @@ import { landscapeStyle } from "styles/landscapeStyle";
import { Button } from "@kleros/ui-components-library";
-const StyledButton = styled(Button)`
+const StyledButton = styled(Button)<{ isMobileNavbar?: boolean }>`
background-color: transparent;
padding: 8px !important;
border-radius: 7px;
@@ -13,12 +13,12 @@ const StyledButton = styled(Button)`
font-weight: 400;
}
.button-svg {
- fill: ${({ theme }) => theme.white}BF !important;
+ fill: ${({ theme, isMobileNavbar }) => (isMobileNavbar ? theme.secondaryText : `${theme.white}BF`)} !important;
}
&:hover {
.button-svg {
- fill: ${({ theme }) => theme.white} !important;
+ fill: ${({ theme, isMobileNavbar }) => (isMobileNavbar ? theme.primaryText : `${theme.white}`)} !important;
}
transition: background-color 0.1s;
background-color: ${({ theme }) => theme.whiteLowOpacityStrong};
@@ -40,10 +40,11 @@ interface ILightButton {
onClick?: React.MouseEventHandler;
disabled?: boolean;
className?: string;
+ isMobileNavbar?: boolean;
}
-const LightButton: React.FC = ({ text, Icon, onClick, disabled, className }) => (
-
+const LightButton: React.FC = ({ text, Icon, onClick, disabled, className, isMobileNavbar }) => (
+
);
export default LightButton;
diff --git a/web/src/components/Verdict/Answer.tsx b/web/src/components/Verdict/Answer.tsx
index 906c27c21..1ace1352b 100644
--- a/web/src/components/Verdict/Answer.tsx
+++ b/web/src/components/Verdict/Answer.tsx
@@ -3,9 +3,24 @@ import styled from "styled-components";
import { Answer } from "@kleros/kleros-sdk/src/dataMappings/utils/disputeDetailsTypes";
+const Container = styled.div`
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: 6px;
+`;
+
const AnswerTitle = styled.h3`
margin: 0;
`;
+
+const AnswerDescription = styled.h4`
+ margin: 0;
+ font-size: 15px;
+ color: ${({ theme }) => theme.primaryText};
+`;
+
interface IAnswer {
answer?: Answer;
currentRuling: number;
@@ -14,12 +29,12 @@ const AnswerDisplay: React.FC = ({ answer, currentRuling }) => {
return (
<>
{answer ? (
-
+
{answer.title}
- {answer.description}
-
+ {answer.description}
+
) : (
- <>{currentRuling !== 0 ? Answer 0x{currentRuling}
: Refuse to Arbitrate
}>
+ {currentRuling !== 0 ? Answer 0x{currentRuling}
: Refuse to Arbitrate
}
)}
>
);
diff --git a/web/src/components/Verdict/FinalDecision.tsx b/web/src/components/Verdict/FinalDecision.tsx
index c287284c7..38f8808fa 100644
--- a/web/src/components/Verdict/FinalDecision.tsx
+++ b/web/src/components/Verdict/FinalDecision.tsx
@@ -30,8 +30,11 @@ const Container = styled.div`
const JuryContainer = styled.div`
display: flex;
- flex-direction: column;
+ flex-direction: row;
+ flex-wrap: wrap;
+ align-items: center;
gap: 8px;
+
h3 {
line-height: 21px;
margin-bottom: 0px;
@@ -45,7 +48,7 @@ const JuryDecisionTag = styled.small`
`;
const StyledDivider = styled(Divider)`
- margin: ${responsiveSize(16, 32)} 0px;
+ margin: ${responsiveSize(16, 24)} 0px;
`;
interface IFinalDecision {
diff --git a/web/src/components/Verdict/VerdictBanner.tsx b/web/src/components/Verdict/VerdictBanner.tsx
index 239371399..cb6d33619 100644
--- a/web/src/components/Verdict/VerdictBanner.tsx
+++ b/web/src/components/Verdict/VerdictBanner.tsx
@@ -4,12 +4,10 @@ import styled from "styled-components";
import ClosedCaseIcon from "svgs/icons/check-circle-outline.svg";
import HourglassIcon from "svgs/icons/hourglass.svg";
-import { responsiveSize } from "styles/responsiveSize";
-
const BannerContainer = styled.div`
display: flex;
gap: 8px;
- margin-bottom: ${responsiveSize(16, 24)};
+ margin-bottom: 8px;
svg {
width: 16px;
height: 16px;
diff --git a/web/src/layout/Header/navbar/Explore.tsx b/web/src/layout/Header/navbar/Explore.tsx
index 5b9321928..fb5209ced 100644
--- a/web/src/layout/Header/navbar/Explore.tsx
+++ b/web/src/layout/Header/navbar/Explore.tsx
@@ -1,10 +1,9 @@
import React from "react";
import styled, { css } from "styled-components";
+import { landscapeStyle } from "styles/landscapeStyle";
import { Link, useLocation } from "react-router-dom";
-import { landscapeStyle } from "styles/landscapeStyle";
-
import { useOpenContext } from "../MobileHeader";
const Container = styled.div`
@@ -30,17 +29,18 @@ const Title = styled.h1`
)};
`;
-const StyledLink = styled(Link)<{ isActive: boolean }>`
+const StyledLink = styled(Link)<{ isActive: boolean; isMobileNavbar?: boolean }>`
display: flex;
align-items: center;
text-decoration: none;
font-size: 16px;
color: ${({ isActive, theme }) => (isActive ? theme.primaryText : `${theme.primaryText}BA`)};
+ font-weight: ${({ isActive, isMobileNavbar }) => (isMobileNavbar && isActive ? "600" : "normal")};
padding: 8px 8px 8px 0;
border-radius: 7px;
&:hover {
- color: ${({ theme }) => theme.white} !important;
+ color: ${({ theme, isMobileNavbar }) => (isMobileNavbar ? theme.primaryText : theme.white)} !important;
}
${landscapeStyle(
@@ -59,7 +59,11 @@ const links = [
{ to: "/get-pnk", text: "Get PNK" },
];
-const Explore: React.FC = () => {
+interface IExplore {
+ isMobileNavbar?: boolean;
+}
+
+const Explore: React.FC = ({ isMobileNavbar }) => {
const location = useLocation();
const { toggleIsOpen } = useOpenContext();
@@ -69,9 +73,9 @@ const Explore: React.FC = () => {
{links.map(({ to, text }) => (
{text}
diff --git a/web/src/layout/Header/navbar/Menu/index.tsx b/web/src/layout/Header/navbar/Menu/index.tsx
index 3da8d3853..a54ff3240 100644
--- a/web/src/layout/Header/navbar/Menu/index.tsx
+++ b/web/src/layout/Header/navbar/Menu/index.tsx
@@ -13,7 +13,7 @@ import { landscapeStyle } from "styles/landscapeStyle";
import LightButton from "components/LightButton";
-import { IHelp, ISettings } from "..";
+import { IHelp, ISettings } from "../index";
const Container = styled.div`
display: flex;
@@ -48,7 +48,11 @@ const ButtonContainer = styled.div`
)}
`;
-const Menu: React.FC = ({ toggleIsHelpOpen, toggleIsSettingsOpen }) => {
+interface IMenu {
+ isMobileNavbar?: boolean;
+}
+
+const Menu: React.FC = ({ toggleIsHelpOpen, toggleIsSettingsOpen, isMobileNavbar }) => {
const [theme, toggleTheme] = useToggleTheme();
const isLightTheme = theme === "light";
@@ -77,7 +81,7 @@ const Menu: React.FC = ({ toggleIsHelpOpen, toggleIsSettingsO
{buttons.map(({ text, Icon, onClick }) => (
-
+
))}
diff --git a/web/src/layout/Header/navbar/index.tsx b/web/src/layout/Header/navbar/index.tsx
index a2caa7174..3480405ff 100644
--- a/web/src/layout/Header/navbar/index.tsx
+++ b/web/src/layout/Header/navbar/index.tsx
@@ -13,7 +13,6 @@ import LightButton from "components/LightButton";
import { Overlay } from "components/Overlay";
import { useOpenContext } from "../MobileHeader";
-
import DappList from "./DappList";
import Explore from "./Explore";
import Menu from "./Menu";
@@ -107,6 +106,7 @@ const NavBar: React.FC = () => {
{
toggleIsDappListOpen();
@@ -114,7 +114,7 @@ const NavBar: React.FC = () => {
Icon={KlerosSolutionsIcon}
/>
-
+
@@ -125,7 +125,7 @@ const NavBar: React.FC = () => {
)}
-
+
diff --git a/web/src/pages/Cases/CaseDetails/Overview/index.tsx b/web/src/pages/Cases/CaseDetails/Overview/index.tsx
index c01d5faea..11967f550 100644
--- a/web/src/pages/Cases/CaseDetails/Overview/index.tsx
+++ b/web/src/pages/Cases/CaseDetails/Overview/index.tsx
@@ -24,7 +24,7 @@ const Container = styled.div`
height: auto;
display: flex;
flex-direction: column;
- gap: ${responsiveSize(16, 32)};
+ gap: ${responsiveSize(16, 24)};
padding: ${responsiveSize(16, 32)};
`;
diff --git a/web/src/pages/Courts/CourtDetails/Description.tsx b/web/src/pages/Courts/CourtDetails/Description.tsx
index bec214d5e..e48e715ac 100644
--- a/web/src/pages/Courts/CourtDetails/Description.tsx
+++ b/web/src/pages/Courts/CourtDetails/Description.tsx
@@ -81,7 +81,16 @@ const Description: React.FC = () => {
{policy?.requiredSkills}
} />
-
+ 0 ? filteredTabs[0].path : ""} replace />
+ )
+ }
+ />
0 ? filteredTabs[0].path : ""} replace />} />
diff --git a/web/src/pages/Courts/CourtDetails/StakePanel/SimulatorPopup/Header.tsx b/web/src/pages/Courts/CourtDetails/StakePanel/Simulator/Header.tsx
similarity index 100%
rename from web/src/pages/Courts/CourtDetails/StakePanel/SimulatorPopup/Header.tsx
rename to web/src/pages/Courts/CourtDetails/StakePanel/Simulator/Header.tsx
diff --git a/web/src/pages/Courts/CourtDetails/StakePanel/SimulatorPopup/QuantityToSimulate.tsx b/web/src/pages/Courts/CourtDetails/StakePanel/Simulator/QuantityToSimulate.tsx
similarity index 100%
rename from web/src/pages/Courts/CourtDetails/StakePanel/SimulatorPopup/QuantityToSimulate.tsx
rename to web/src/pages/Courts/CourtDetails/StakePanel/Simulator/QuantityToSimulate.tsx
diff --git a/web/src/pages/Courts/CourtDetails/StakePanel/SimulatorPopup/index.tsx b/web/src/pages/Courts/CourtDetails/StakePanel/Simulator/index.tsx
similarity index 89%
rename from web/src/pages/Courts/CourtDetails/StakePanel/SimulatorPopup/index.tsx
rename to web/src/pages/Courts/CourtDetails/StakePanel/Simulator/index.tsx
index 03bb047bb..2d16bcb94 100644
--- a/web/src/pages/Courts/CourtDetails/StakePanel/SimulatorPopup/index.tsx
+++ b/web/src/pages/Courts/CourtDetails/StakePanel/Simulator/index.tsx
@@ -18,7 +18,6 @@ import { useHomePageExtraStats } from "queries/useHomePageExtraStats";
import { useJurorStakeDetailsQuery } from "queries/useJurorStakeDetailsQuery";
import GavelIcon from "svgs/icons/gavel.svg";
-import LawBalanceIcon from "svgs/icons/law-balance.svg";
import DiceIcon from "svgs/icons/dice.svg";
import DollarIcon from "svgs/icons/dollar.svg";
import ArrowRightIcon from "svgs/icons/arrow-right.svg";
@@ -115,12 +114,12 @@ const calculateJurorOdds = (newStake: number, totalStake: number): string => {
return `${odds.toFixed(2)}%`;
};
-interface ISimulatorPopup {
+interface ISimulator {
amountToStake: number;
isStaking: boolean;
}
-const SimulatorPopup: React.FC = ({ amountToStake, isStaking }) => {
+const Simulator: React.FC = ({ amountToStake, isStaking }) => {
const { id } = useParams();
const { address } = useAccount();
const { data: stakeData } = useJurorStakeDetailsQuery(address?.toLowerCase() as `0x${string}`);
@@ -155,7 +154,7 @@ const SimulatorPopup: React.FC = ({ amountToStake, isStaking })
};
}, [courtCurrentEffectiveStake, currentTreeVotesPerPnk, currentTreeDisputesPerPnk, currentTreeExpectedRewardPerPnk]);
- const { votes: totalVotes, cases: totalCases, rewards: totalRewards } = totals;
+ const { votes: totalVotes, rewards: totalRewards } = totals;
const courtFutureEffectiveStake = !isUndefined(courtCurrentEffectiveStake)
? Math.max(isStaking ? courtCurrentEffectiveStake + amountToStake : courtCurrentEffectiveStake - amountToStake, 0)
@@ -165,10 +164,7 @@ const SimulatorPopup: React.FC = ({ amountToStake, isStaking })
!isUndefined(courtFutureEffectiveStake) && !isUndefined(totalVotes)
? totalVotes / courtFutureEffectiveStake
: undefined;
- const futureTreeDisputesPerPnk =
- !isUndefined(courtFutureEffectiveStake) && !isUndefined(totalCases)
- ? totalCases / courtFutureEffectiveStake
- : undefined;
+
const futureTreeExpectedRewardPerPnk =
!isUndefined(courtFutureEffectiveStake) && !isUndefined(totalRewards)
? totalRewards / courtFutureEffectiveStake
@@ -187,15 +183,6 @@ const SimulatorPopup: React.FC = ({ amountToStake, isStaking })
? beautifyStatNumber(jurorFutureEffectiveStake * futureTreeVotesPerPnk)
: undefined;
- const currentExpectedCases =
- !isUndefined(jurorCurrentEffectiveStake) && !isUndefined(currentTreeDisputesPerPnk)
- ? beautifyStatNumber(jurorCurrentEffectiveStake * currentTreeDisputesPerPnk)
- : undefined;
- const futureExpectedCases =
- !isUndefined(jurorFutureEffectiveStake) && !isUndefined(futureTreeDisputesPerPnk)
- ? beautifyStatNumber(jurorFutureEffectiveStake * futureTreeDisputesPerPnk)
- : undefined;
-
const currentDrawingOdds =
!isUndefined(jurorCurrentEffectiveStake) && !isUndefined(courtCurrentEffectiveStake)
? calculateJurorOdds(jurorCurrentEffectiveStake, courtCurrentEffectiveStake)
@@ -223,12 +210,6 @@ const SimulatorPopup: React.FC = ({ amountToStake, isStaking })
currentValue: currentExpectedVotes,
futureValue: futureExpectedVotes,
},
- {
- title: "Cases",
- icon: ,
- currentValue: currentExpectedCases,
- futureValue: futureExpectedCases,
- },
{
title: "Drawing Odds",
icon: ,
@@ -286,4 +267,4 @@ const SimulatorPopup: React.FC = ({ amountToStake, isStaking })
);
};
-export default SimulatorPopup;
+export default Simulator;
diff --git a/web/src/pages/Courts/CourtDetails/StakePanel/index.tsx b/web/src/pages/Courts/CourtDetails/StakePanel/index.tsx
index 73ec4a3b3..4e77e5456 100644
--- a/web/src/pages/Courts/CourtDetails/StakePanel/index.tsx
+++ b/web/src/pages/Courts/CourtDetails/StakePanel/index.tsx
@@ -13,12 +13,11 @@ import { uncommify } from "utils/commify";
import InputDisplay from "./InputDisplay";
import { ActionType } from "./StakeWithdrawButton";
-import SimulatorPopup from "./SimulatorPopup";
+import Simulator from "./Simulator";
const Container = styled.div`
position: relative;
width: 100%;
- margin-top: 12px;
display: flex;
flex-direction: column;
gap: 28px;
@@ -100,7 +99,7 @@ const StakePanel: React.FC<{ courtName: string; id: string }> = ({ courtName = "
/>
)}
-
+
);
};
diff --git a/web/src/pages/Courts/CourtDetails/Stats.tsx b/web/src/pages/Courts/CourtDetails/Stats.tsx
index 7d1db45bc..15941591f 100644
--- a/web/src/pages/Courts/CourtDetails/Stats.tsx
+++ b/web/src/pages/Courts/CourtDetails/Stats.tsx
@@ -8,7 +8,6 @@ import { Accordion, DropdownSelect } from "@kleros/ui-components-library";
import EthereumIcon from "svgs/icons/ethereum.svg";
import BalanceIcon from "svgs/icons/law-balance.svg";
-import BalanceWithPNKIcon from "svgs/icons/law-balance-with-pnk.svg";
import MinStake from "svgs/icons/min-stake.svg";
import VotesPerPNKIcon from "svgs/icons/votes-per-pnk.svg";
import PNKIcon from "svgs/icons/pnk.svg";
@@ -27,7 +26,7 @@ import { useHomePageExtraStats } from "queries/useHomePageExtraStats";
import { calculateSubtextRender } from "utils/calculateSubtextRender";
import { formatETH, formatPNK, formatUnitsWei, formatUSD } from "utils/format";
import { isUndefined } from "utils/index";
-import { beautifyStatNumber } from "utils/beautifyStatNumber";
+import { beautifyStatNumber, unbeautifyStatNumber } from "utils/beautifyStatNumber";
import StatDisplay, { IStatDisplay } from "components/StatDisplay";
import { StyledSkeleton } from "components/StyledSkeleton";
@@ -36,7 +35,7 @@ import Info from "./Info";
const StyledAccordion = styled(Accordion)`
width: 100%;
- margin-top: 24px;
+ margin-top: ${responsiveSize(24, 32)};
> * > button {
justify-content: unset;
background-color: ${({ theme }) => theme.whiteBackground} !important;
@@ -207,6 +206,7 @@ interface ITimeframedStat {
title: string | React.ReactNode;
coinId?: number;
getText: (data: ITimeframedStatData) => string;
+ getSubtext?: (data: CourtDetailsQuery["court"], coinPrice?: number) => string;
color: IStatDisplay["color"];
icon: React.FC>;
}
@@ -235,12 +235,26 @@ const Stats = () => {
};
const timeframedStats: ITimeframedStat[] = [
+ {
+ title: (
+
+ PNK for 1 Vote
+
+ ),
+ coinId: 0,
+ getText: (data) => beautifyStatNumber(data?.treeVotesPerPnk, true),
+ getSubtext: (data, coinPrice) =>
+ formatUSD(unbeautifyStatNumber(beautifyStatNumber(data?.treeVotesPerPnk, true)) * (coinPrice ?? 0)),
+ color: "orange",
+ icon: VotesPerPNKIcon,
+ },
{
title: (
PNK for 1 USD
),
+ coinId: 0,
getText: (data) => {
const treeExpectedRewardPerPnk = data?.treeExpectedRewardPerPnk;
const ethPriceUSD = pricesData ? pricesData[CoinIds.ETH]?.price : undefined;
@@ -248,6 +262,13 @@ const Stats = () => {
const pnkNeeded = treeExpectedRewardPerPnk * ethPriceUSD;
return beautifyStatNumber(pnkNeeded, true);
},
+ getSubtext: (data, coinPrice) => {
+ const treeExpectedRewardPerPnk = data?.treeExpectedRewardPerPnk;
+ const ethPriceUSD = pricesData ? pricesData[CoinIds.ETH]?.price : undefined;
+ if (!ethPriceUSD || !treeExpectedRewardPerPnk) return "N/A";
+ const pnkNeeded = treeExpectedRewardPerPnk * ethPriceUSD;
+ return formatUSD(unbeautifyStatNumber(beautifyStatNumber(pnkNeeded, true)) * (coinPrice ?? 0));
+ },
color: "purple",
icon: PNKUSDIcon,
},
@@ -257,44 +278,22 @@ const Stats = () => {
PNK for 1 ETH
),
+ coinId: 0,
getText: (data) => {
const treeExpectedRewardPerPnk = data?.treeExpectedRewardPerPnk;
if (!treeExpectedRewardPerPnk) return "N/A";
const pnkNeeded = treeExpectedRewardPerPnk;
return beautifyStatNumber(pnkNeeded, true);
},
+ getSubtext: (data, coinPrice) => {
+ const treeExpectedRewardPerPnk = data?.treeExpectedRewardPerPnk;
+ if (!treeExpectedRewardPerPnk) return "N/A";
+ const pnkNeeded = treeExpectedRewardPerPnk;
+ return formatUSD(unbeautifyStatNumber(beautifyStatNumber(pnkNeeded, true)) * (coinPrice ?? 0));
+ },
color: "blue",
icon: PNKETHIcon,
},
- {
- title: (
-
- PNK for 1 Vote
-
- ),
- getText: (data) => {
- const treeVotesPerPnk = data?.treeVotesPerPnk;
- return beautifyStatNumber(treeVotesPerPnk, true);
- },
- color: "orange",
- icon: VotesPerPNKIcon,
- },
- {
- title: (
-
- PNK for 1 Case
-
- ),
- getText: (data) => {
- const treeDisputesPerPnk = data?.treeDisputesPerPnk;
- return beautifyStatNumber(treeDisputesPerPnk, true);
- },
- color: "orange",
- icon: BalanceWithPNKIcon,
- },
];
return (
@@ -337,12 +336,14 @@ const Stats = () => {
- {timeframedStats.map(({ title, getText, color, icon }) => {
+ {timeframedStats.map(({ title, coinId, getText, getSubtext, color, icon }) => {
+ const coinPrice = !isUndefined(pricesData) ? pricesData[coinIds[coinId!]]?.price : undefined;
return (
}
+ subtext={calculateSubtextRender(foundCourt, getSubtext, coinPrice)}
/>
);
})}
diff --git a/web/src/pages/Courts/CourtDetails/index.tsx b/web/src/pages/Courts/CourtDetails/index.tsx
index ce255278c..4996eb94c 100644
--- a/web/src/pages/Courts/CourtDetails/index.tsx
+++ b/web/src/pages/Courts/CourtDetails/index.tsx
@@ -38,7 +38,7 @@ const CourtHeader = styled.h1`
${landscapeStyle(
() => css`
- margin-bottom: 20px;
+ margin-bottom: 32px;
`
)};
`;
@@ -46,13 +46,7 @@ const CourtHeader = styled.h1`
const CourtInfo = styled.div`
display: flex;
flex-direction: column;
- gap: 16px;
-
- ${landscapeStyle(
- () => css`
- gap: 20px;
- `
- )};
+ gap: 8px;
`;
const ButtonContainer = styled.div`
@@ -93,7 +87,7 @@ const CourtDetails: React.FC = () => {
const courtPath = getCourtsPath(data?.court, id);
- const items = [{ text: "🏛️", value: "0" }];
+ const items = [];
items.push(
...(courtPath?.map((node) => ({
text: node.name,
@@ -107,7 +101,7 @@ const CourtDetails: React.FC = () => {
{policy ? policy.name : }
- {items.length > 1 ? : }
+ {items.length > 1 && items[0]?.value !== 1 ? : null}
= {
+ B: 1e9,
+ M: 1e6,
+ K: 1e3,
+ };
+
+ const match = value.match(/^([\d,\.]+)([BMK]?)$/);
+
+ if (!match) {
+ throw new Error("Invalid formatted number string");
+ }
+
+ const [, numericPart, unit] = match;
+ const numericValue = parseFloat(numericPart.replace(/,/g, ""));
+
+ if (unit && multiplierMap[unit]) {
+ return numericValue * multiplierMap[unit];
+ }
+
+ return numericValue;
+}
From 24b0a16b31712662a2527a7c8581d99f93c898a2 Mon Sep 17 00:00:00 2001
From: kemuru <102478601+kemuru@users.noreply.github.com>
Date: Fri, 6 Dec 2024 14:03:05 +0100
Subject: [PATCH 02/11] fix: nitpick in court link inside case overview
---
web/src/components/Field.tsx | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/web/src/components/Field.tsx b/web/src/components/Field.tsx
index ab6284030..e9d5bff65 100644
--- a/web/src/components/Field.tsx
+++ b/web/src/components/Field.tsx
@@ -59,7 +59,9 @@ const FieldContainer = styled.div`
`};
`;
-const LinkContainer = styled.div``;
+const LinkContainer = styled.div`
+ padding-bottom: 1px;
+`;
const StyledInternalLink = styled(InternalLink)`
text-wrap: auto;
From 4b0811ffdf99c618355c7bde9731ca88b73e9fa0 Mon Sep 17 00:00:00 2001
From: kemuru <102478601+kemuru@users.noreply.github.com>
Date: Fri, 6 Dec 2024 14:12:29 +0100
Subject: [PATCH 03/11] fix: style issue in courts page
---
web/src/pages/Courts/CourtDetails/index.tsx | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/web/src/pages/Courts/CourtDetails/index.tsx b/web/src/pages/Courts/CourtDetails/index.tsx
index 4996eb94c..4164ba7c7 100644
--- a/web/src/pages/Courts/CourtDetails/index.tsx
+++ b/web/src/pages/Courts/CourtDetails/index.tsx
@@ -52,9 +52,9 @@ const CourtInfo = styled.div`
const ButtonContainer = styled.div`
display: flex;
flex-wrap: wrap;
- flex-direction: column;
- align-items: flex-start;
- gap: 8px;
+ flex-direction: row;
+ justify-content: center;
+ gap: 20px;
${landscapeStyle(
() => css`
@@ -104,12 +104,12 @@ const CourtDetails: React.FC = () => {
{items.length > 1 && items[0]?.value !== 1 ? : null}
+ {!isProductionDeployment() && }
- {!isProductionDeployment() && }
From 2f89725eeabfbf1a838a9d8f3e3d4b716a02c037 Mon Sep 17 00:00:00 2001
From: kemuru <102478601+kemuru@users.noreply.github.com>
Date: Fri, 6 Dec 2024 14:18:24 +0100
Subject: [PATCH 04/11] fix: few code smells
---
.../pages/Courts/CourtDetails/StakePanel/Simulator/index.tsx | 2 +-
web/src/utils/beautifyStatNumber.ts | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/web/src/pages/Courts/CourtDetails/StakePanel/Simulator/index.tsx b/web/src/pages/Courts/CourtDetails/StakePanel/Simulator/index.tsx
index 2d16bcb94..95aadc68e 100644
--- a/web/src/pages/Courts/CourtDetails/StakePanel/Simulator/index.tsx
+++ b/web/src/pages/Courts/CourtDetails/StakePanel/Simulator/index.tsx
@@ -233,7 +233,7 @@ const Simulator: React.FC = ({ amountToStake, isStaking }) => {
{simulatorItems.map((item, index) => (
-
+
{item.icon}
{item.tooltipMsg ? (
diff --git a/web/src/utils/beautifyStatNumber.ts b/web/src/utils/beautifyStatNumber.ts
index 6428a7186..04ceae540 100644
--- a/web/src/utils/beautifyStatNumber.ts
+++ b/web/src/utils/beautifyStatNumber.ts
@@ -28,7 +28,8 @@ export function unbeautifyStatNumber(value: string): number {
K: 1e3,
};
- const match = value.match(/^([\d,\.]+)([BMK]?)$/);
+ const regex = /^([\d,.]+)([BMK]?)$/;
+ const match = regex.exec(value);
if (!match) {
throw new Error("Invalid formatted number string");
From b9eba671ba09396d4bb0f5f5732f742e054f562a Mon Sep 17 00:00:00 2001
From: kemuru <102478601+kemuru@users.noreply.github.com>
Date: Fri, 6 Dec 2024 15:09:21 +0100
Subject: [PATCH 05/11] fix: add hyphen to answer description
---
web/src/components/Verdict/Answer.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/web/src/components/Verdict/Answer.tsx b/web/src/components/Verdict/Answer.tsx
index 1ace1352b..08df3e9a6 100644
--- a/web/src/components/Verdict/Answer.tsx
+++ b/web/src/components/Verdict/Answer.tsx
@@ -30,7 +30,7 @@ const AnswerDisplay: React.FC = ({ answer, currentRuling }) => {
<>
{answer ? (
- {answer.title}
+ {answer.title} -
{answer.description}
) : (
From 875fcad9aae8b02a2b74e38201869d1f49ddf710 Mon Sep 17 00:00:00 2001
From: kemuru <102478601+kemuru@users.noreply.github.com>
Date: Fri, 6 Dec 2024 15:25:40 +0100
Subject: [PATCH 06/11] chore: adjust padding in policies section in case
overview
---
web/src/components/DisputePreview/Policies.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/web/src/components/DisputePreview/Policies.tsx b/web/src/components/DisputePreview/Policies.tsx
index b4e0eb87a..763e9e9f2 100644
--- a/web/src/components/DisputePreview/Policies.tsx
+++ b/web/src/components/DisputePreview/Policies.tsx
@@ -16,7 +16,7 @@ const Container = styled.div`
align-items: center;
flex-direction: row;
flex-wrap: wrap;
- gap: ${responsiveSize(16, 24)};
+ gap: 8px ${responsiveSize(16, 24)};
padding: ${responsiveSize(16, 20)} ${responsiveSize(16, 32)};
background-color: ${({ theme }) => theme.mediumBlue};
`;
From 00f56b5afb4aa0ee10b65a27041928a439a81bc5 Mon Sep 17 00:00:00 2001
From: kemuru <102478601+kemuru@users.noreply.github.com>
Date: Fri, 6 Dec 2024 15:33:54 +0100
Subject: [PATCH 07/11] chore: margin adjustments overview page
---
.../DisputePreview/DisputeContext.tsx | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/web/src/components/DisputePreview/DisputeContext.tsx b/web/src/components/DisputePreview/DisputeContext.tsx
index 1624bdb15..288702d4d 100644
--- a/web/src/components/DisputePreview/DisputeContext.tsx
+++ b/web/src/components/DisputePreview/DisputeContext.tsx
@@ -27,13 +27,10 @@ const QuestionAndDescription = styled.div`
div:first-child p:first-of-type {
font-size: 16px;
font-weight: 600;
+ margin: 0;
}
`;
-const StyledReactMarkDown = styled(ReactMarkdown)`
- margin: 0px;
-`;
-
const VotingOptions = styled(QuestionAndDescription)`
display: flex;
flex-direction: column;
@@ -45,6 +42,10 @@ const AnswersContainer = styled.div`
flex-direction: column;
`;
+const AnswersHeader = styled.h3`
+ margin: 0;
+`;
+
const Answer = styled.div`
margin: 0px;
display: flex;
@@ -70,11 +71,11 @@ export const DisputeContext: React.FC = ({ disputeDetails, isRp
const errMsg = isRpcError ? RPC_ERROR : INVALID_DISPUTE_DATA_ERROR;
return (
<>
- {isUndefined(disputeDetails) ? : disputeDetails?.title ?? errMsg}
+ {isUndefined(disputeDetails) ? : (disputeDetails?.title ?? errMsg)}
{!isUndefined(disputeDetails) && (
- {disputeDetails?.question}
- {disputeDetails?.description}
+ {disputeDetails?.question}
+ {disputeDetails?.description}
)}
{isUndefined(disputeDetails?.frontendUrl) ? null : (
@@ -83,7 +84,7 @@ export const DisputeContext: React.FC = ({ disputeDetails, isRp
)}
- {isUndefined(disputeDetails) ? null : Voting Options
}
+ {isUndefined(disputeDetails) ? null : Voting Options}
{disputeDetails?.answers?.map((answer: IAnswer, i: number) => (
From a9e621c6d12001dfaedde14a0d9085dd46c6839d Mon Sep 17 00:00:00 2001
From: kemuru <102478601+kemuru@users.noreply.github.com>
Date: Fri, 6 Dec 2024 15:42:24 +0100
Subject: [PATCH 08/11] chore: gap adjustments
---
web/src/components/DisputePreview/DisputeContext.tsx | 2 +-
web/src/components/Verdict/FinalDecision.tsx | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/web/src/components/DisputePreview/DisputeContext.tsx b/web/src/components/DisputePreview/DisputeContext.tsx
index 288702d4d..3b8cec7ab 100644
--- a/web/src/components/DisputePreview/DisputeContext.tsx
+++ b/web/src/components/DisputePreview/DisputeContext.tsx
@@ -50,7 +50,7 @@ const Answer = styled.div`
margin: 0px;
display: flex;
flex-wrap: wrap;
- gap: ${responsiveSize(2, 8)};
+ gap: 6px;
> label {
max-width: 100%;
}
diff --git a/web/src/components/Verdict/FinalDecision.tsx b/web/src/components/Verdict/FinalDecision.tsx
index 38f8808fa..3b0a01ce4 100644
--- a/web/src/components/Verdict/FinalDecision.tsx
+++ b/web/src/components/Verdict/FinalDecision.tsx
@@ -33,7 +33,7 @@ const JuryContainer = styled.div`
flex-direction: row;
flex-wrap: wrap;
align-items: center;
- gap: 8px;
+ gap: 4px 7px;
h3 {
line-height: 21px;
From 5c751053c936191baed1982695a6ddcebcbc9a97 Mon Sep 17 00:00:00 2001
From: kemuru <102478601+kemuru@users.noreply.github.com>
Date: Fri, 6 Dec 2024 15:53:00 +0100
Subject: [PATCH 09/11] chore: slight padding bottom to answer description to
align it beter
---
web/src/components/Verdict/Answer.tsx | 1 +
1 file changed, 1 insertion(+)
diff --git a/web/src/components/Verdict/Answer.tsx b/web/src/components/Verdict/Answer.tsx
index 08df3e9a6..0b5cb2681 100644
--- a/web/src/components/Verdict/Answer.tsx
+++ b/web/src/components/Verdict/Answer.tsx
@@ -19,6 +19,7 @@ const AnswerDescription = styled.h4`
margin: 0;
font-size: 15px;
color: ${({ theme }) => theme.primaryText};
+ padding-bottom: 0.5px;
`;
interface IAnswer {
From 8c2d861977470299b5d32eba4156197891edd7f0 Mon Sep 17 00:00:00 2001
From: kemuru <102478601+kemuru@users.noreply.github.com>
Date: Fri, 6 Dec 2024 16:05:39 +0100
Subject: [PATCH 10/11] chore: gap adjustment policies
---
web/src/components/DisputePreview/Policies.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/web/src/components/DisputePreview/Policies.tsx b/web/src/components/DisputePreview/Policies.tsx
index 763e9e9f2..91adfc4ad 100644
--- a/web/src/components/DisputePreview/Policies.tsx
+++ b/web/src/components/DisputePreview/Policies.tsx
@@ -16,7 +16,7 @@ const Container = styled.div`
align-items: center;
flex-direction: row;
flex-wrap: wrap;
- gap: 8px ${responsiveSize(16, 24)};
+ gap: 8px 16px;
padding: ${responsiveSize(16, 20)} ${responsiveSize(16, 32)};
background-color: ${({ theme }) => theme.mediumBlue};
`;
From 6e5113c5d3d4cd8fc76c8c62d3528eb37ff19cdc Mon Sep 17 00:00:00 2001
From: kemuru <102478601+kemuru@users.noreply.github.com>
Date: Fri, 6 Dec 2024 16:18:56 +0100
Subject: [PATCH 11/11] chore: remove hyphen if answer description does not
exist
---
web/src/components/DisputePreview/DisputeContext.tsx | 2 +-
web/src/components/Verdict/Answer.tsx | 9 +++++++--
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/web/src/components/DisputePreview/DisputeContext.tsx b/web/src/components/DisputePreview/DisputeContext.tsx
index 3b8cec7ab..12ce6a104 100644
--- a/web/src/components/DisputePreview/DisputeContext.tsx
+++ b/web/src/components/DisputePreview/DisputeContext.tsx
@@ -91,7 +91,7 @@ export const DisputeContext: React.FC = ({ disputeDetails, isRp
Option {i + 1}:
))}
diff --git a/web/src/components/Verdict/Answer.tsx b/web/src/components/Verdict/Answer.tsx
index 0b5cb2681..7eb3553e0 100644
--- a/web/src/components/Verdict/Answer.tsx
+++ b/web/src/components/Verdict/Answer.tsx
@@ -26,13 +26,17 @@ interface IAnswer {
answer?: Answer;
currentRuling: number;
}
+
const AnswerDisplay: React.FC = ({ answer, currentRuling }) => {
return (
<>
{answer ? (
- {answer.title} -
- {answer.description}
+
+ {answer.title}
+ {answer.description.trim() ? " -" : null}
+
+ {answer.description.trim()}
) : (
{currentRuling !== 0 ? Answer 0x{currentRuling}
: Refuse to Arbitrate
}
@@ -40,4 +44,5 @@ const AnswerDisplay: React.FC = ({ answer, currentRuling }) => {
>
);
};
+
export default AnswerDisplay;