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;