From 5906eecf0641209d612d8357105b97584c4c18b7 Mon Sep 17 00:00:00 2001 From: marino <102478601+kemuru@users.noreply.github.com> Date: Mon, 21 Aug 2023 14:24:10 +0200 Subject: [PATCH 01/30] chore(web): code maintenace and consensus --- web/src/components/CasesDisplay/CasesGrid.tsx | 9 +- web/src/components/CasesDisplay/Stats.tsx | 10 +- .../components/DisputeCard/PeriodBanner.tsx | 32 +++---- web/src/components/EvidenceCard.tsx | 68 +++++++------- web/src/components/Field.tsx | 54 +++++------ web/src/components/Popup/index.tsx | 82 ++++++++--------- web/src/components/StatDisplay.tsx | 10 +- web/src/layout/Header/navbar/DappList.tsx | 92 +++++++++---------- web/src/layout/Header/navbar/Menu/Help.tsx | 74 +++++++-------- web/src/layout/Header/navbar/Product.tsx | 12 +-- .../Cases/CaseDetails/Appeal/Classic/Fund.tsx | 40 ++++---- .../Appeal/Classic/Options/StageOne.tsx | 22 ++--- .../Appeal/Classic/Options/StageTwo.tsx | 22 ++--- .../Appeal/Classic/Options/index.tsx | 8 +- .../Appeal/Classic/StageExplainer.tsx | 44 +++++---- .../Cases/CaseDetails/Appeal/OptionCard.tsx | 78 ++++++++-------- .../Evidence/SubmitEvidenceModal.tsx | 72 +++++++-------- web/src/pages/Cases/CaseDetails/Tabs.tsx | 22 ++--- web/src/pages/Cases/CaseDetails/Timeline.tsx | 26 +++--- .../CaseDetails/Voting/VotingHistory.tsx | 28 +++--- web/src/pages/Cases/CaseDetails/index.tsx | 20 ++-- .../pages/Courts/CourtDetails/Description.tsx | 40 ++++---- .../StakePanel/JurorStakeDisplay.tsx | 16 ++-- .../Courts/CourtDetails/StakePanel/index.tsx | 44 ++++----- web/src/pages/Courts/CourtDetails/index.tsx | 40 ++++---- web/src/pages/DisputeTemplateView.tsx | 80 ++++++++-------- 26 files changed, 518 insertions(+), 527 deletions(-) diff --git a/web/src/components/CasesDisplay/CasesGrid.tsx b/web/src/components/CasesDisplay/CasesGrid.tsx index a552db8fb..b9e9c9415 100644 --- a/web/src/components/CasesDisplay/CasesGrid.tsx +++ b/web/src/components/CasesDisplay/CasesGrid.tsx @@ -11,7 +11,6 @@ const Container = styled.div` gap: 8px; `; -// 24px as margin-top since we already have 8px from the flex gap const StyledPagination = styled(StandardPagination)` margin-top: 24px; margin-left: auto; @@ -26,13 +25,7 @@ export interface ICasesGrid { casesPerPage: number; } -const CasesGrid: React.FC = ({ - disputes, - currentPage, - setCurrentPage, - numberDisputes, - casesPerPage, -}) => { +const CasesGrid: React.FC = ({ disputes, currentPage, setCurrentPage, numberDisputes, casesPerPage }) => { return ( <> diff --git a/web/src/components/CasesDisplay/Stats.tsx b/web/src/components/CasesDisplay/Stats.tsx index e877af7ef..225811b6e 100644 --- a/web/src/components/CasesDisplay/Stats.tsx +++ b/web/src/components/CasesDisplay/Stats.tsx @@ -7,6 +7,11 @@ const FieldWrapper = styled.div` gap: 8px; `; +const SeparatorLabel = styled.label` + margin-left: 8px; + margin-right: 8px; +`; + const Field: React.FC<{ label: string; value: string }> = ({ label, value }) => ( @@ -14,11 +19,6 @@ const Field: React.FC<{ label: string; value: string }> = ({ label, value }) => ); -const SeparatorLabel = styled.label` - margin-left: 8px; - margin-right: 8px; -`; - const Separator: React.FC = () => |; const Stats: React.FC = () => { diff --git a/web/src/components/DisputeCard/PeriodBanner.tsx b/web/src/components/DisputeCard/PeriodBanner.tsx index 0990cf47c..fb8dd3e0a 100644 --- a/web/src/components/DisputeCard/PeriodBanner.tsx +++ b/web/src/components/DisputeCard/PeriodBanner.tsx @@ -2,22 +2,6 @@ import React from "react"; import styled, { Theme } from "styled-components"; import { Periods } from "consts/periods"; -export interface IPeriodBanner { - id: number; - period: Periods; -} - -const getPeriodColors = (period: Periods, theme: Theme): [string, string] => { - switch (period) { - case Periods.appeal: - return [theme.tint, theme.tintMedium]; - case Periods.execution: - return [theme.secondaryPurple, theme.mediumPurple]; - default: - return [theme.primaryBlue, theme.mediumBlue]; - } -}; - const Container = styled.div>` height: 45px; width: auto; @@ -54,6 +38,22 @@ const Container = styled.div>` }}; `; +export interface IPeriodBanner { + id: number; + period: Periods; +} + +const getPeriodColors = (period: Periods, theme: Theme): [string, string] => { + switch (period) { + case Periods.appeal: + return [theme.tint, theme.tintMedium]; + case Periods.execution: + return [theme.secondaryPurple, theme.mediumPurple]; + default: + return [theme.primaryBlue, theme.mediumBlue]; + } +}; + const getPeriodLabel = (period: Periods): string => { switch (period) { case Periods.appeal: diff --git a/web/src/components/EvidenceCard.tsx b/web/src/components/EvidenceCard.tsx index 4fffba6da..44a1cabeb 100644 --- a/web/src/components/EvidenceCard.tsx +++ b/web/src/components/EvidenceCard.tsx @@ -7,40 +7,6 @@ import { useIPFSQuery } from "hooks/useIPFSQuery"; import { shortenAddress } from "utils/shortenAddress"; import { IPFS_GATEWAY } from "consts/index"; -interface IEvidenceCard { - evidence: string; - sender: string; - index: number; -} - -const EvidenceCard: React.FC = ({ evidence, sender, index }) => { - const { data } = useIPFSQuery(evidence.at(0) === "/" ? evidence : undefined); - return ( - - - #{index}: - {data ? ( - <> -

{data.name}

-

{data.description}

- - ) : ( -

{evidence}

- )} -
- - -

{shortenAddress(sender)}

- {data && typeof data.fileURI !== "undefined" && ( - - - - )} -
-
- ); -}; - const StyledCard = styled(Card)` width: 100%; height: auto; @@ -85,4 +51,38 @@ const StyledA = styled.a` } `; +interface IEvidenceCard { + evidence: string; + sender: string; + index: number; +} + +const EvidenceCard: React.FC = ({ evidence, sender, index }) => { + const { data } = useIPFSQuery(evidence.at(0) === "/" ? evidence : undefined); + return ( + + + #{index}: + {data ? ( + <> +

{data.name}

+

{data.description}

+ + ) : ( +

{evidence}

+ )} +
+ + +

{shortenAddress(sender)}

+ {data && typeof data.fileURI !== "undefined" && ( + + + + )} +
+
+ ); +}; + export default EvidenceCard; diff --git a/web/src/components/Field.tsx b/web/src/components/Field.tsx index 7bdecf0d4..af7b09df8 100644 --- a/web/src/components/Field.tsx +++ b/web/src/components/Field.tsx @@ -2,6 +2,33 @@ import React from "react"; import { Link } from "react-router-dom"; import styled from "styled-components"; +const FieldContainer = styled.div` + width: ${({ width = "100%" }) => width}; + display: flex; + align-items: center; + justify-content: flex-start; + .value { + flex-grow: 1; + text-align: end; + color: ${({ theme }) => theme.primaryText}; + } + svg { + fill: ${({ theme }) => theme.secondaryPurple}; + margin-right: 8px; + width: 15px; + } + .link { + color: ${({ theme }) => theme.primaryBlue}; + :hover { + cursor: pointer; + } + } +`; + +type FieldContainerProps = { + width?: string; +}; + interface IField { icon: React.FunctionComponent>; name: string; @@ -10,10 +37,6 @@ interface IField { width?: string; } -type FieldContainerProps = { - width?: string; -}; - const Field: React.FC = ({ icon: Icon, name, value, link, width }) => ( {} @@ -29,26 +52,3 @@ const Field: React.FC = ({ icon: Icon, name, value, link, width }) => ( ); export default Field; - -const FieldContainer = styled.div` - width: ${({ width = "100%" }) => width}; - display: flex; - align-items: center; - justify-content: flex-start; - .value { - flex-grow: 1; - text-align: end; - color: ${({ theme }) => theme.primaryText}; - } - svg { - fill: ${({ theme }) => theme.secondaryPurple}; - margin-right: 8px; - width: 15px; - } - .link { - color: ${({ theme }) => theme.primaryBlue}; - :hover { - cursor: pointer; - } - } -`; diff --git a/web/src/components/Popup/index.tsx b/web/src/components/Popup/index.tsx index 313f5db1b..a289afe1c 100644 --- a/web/src/components/Popup/index.tsx +++ b/web/src/components/Popup/index.tsx @@ -9,47 +9,6 @@ import Appeal from "./Description/Appeal"; import VoteWithCommitExtraInfo from "./ExtraInfo/VoteWithCommitExtraInfo"; import StakeWithdrawExtraInfo from "./ExtraInfo/StakeWithdrawExtraInfo"; -export enum PopupType { - STAKE_WITHDRAW = "STAKE_WITHDRAW", - APPEAL = "APPEAL", - VOTE_WITHOUT_COMMIT = "VOTE_WITHOUT_COMMIT", - VOTE_WITH_COMMIT = "VOTE_WITH_COMMIT", -} - -interface IStakeWithdraw { - popupType: PopupType.STAKE_WITHDRAW; - pnkStaked: string; - courtName: string; - isStake: boolean; - courtId: string; -} - -interface IVoteWithoutCommit { - popupType: PopupType.VOTE_WITHOUT_COMMIT; - date: string; -} - -interface IVoteWithCommit { - popupType: PopupType.VOTE_WITH_COMMIT; - date: string; -} - -interface IAppeal { - popupType: PopupType.APPEAL; - amount: string; - option: string; -} -interface IPopup { - title: string; - icon: React.FC>; - popupType: PopupType; - setIsOpen: (val: boolean) => void; - setAmount?: (val: string) => void; - isCommit?: boolean; -} - -type PopupProps = IStakeWithdraw | IVoteWithoutCommit | IVoteWithCommit | IAppeal; - const Header = styled.h1` display: flex; margin-top: calc(12px + (32 - 12) * ((100vw - 375px) / (1250 - 375))); @@ -120,6 +79,47 @@ export const VoteDescriptionEmphasizedDate = styled.span` color: ${({ theme }) => theme.primaryText}; `; +export enum PopupType { + STAKE_WITHDRAW = "STAKE_WITHDRAW", + APPEAL = "APPEAL", + VOTE_WITHOUT_COMMIT = "VOTE_WITHOUT_COMMIT", + VOTE_WITH_COMMIT = "VOTE_WITH_COMMIT", +} + +interface IStakeWithdraw { + popupType: PopupType.STAKE_WITHDRAW; + pnkStaked: string; + courtName: string; + isStake: boolean; + courtId: string; +} + +interface IVoteWithoutCommit { + popupType: PopupType.VOTE_WITHOUT_COMMIT; + date: string; +} + +interface IVoteWithCommit { + popupType: PopupType.VOTE_WITH_COMMIT; + date: string; +} + +interface IAppeal { + popupType: PopupType.APPEAL; + amount: string; + option: string; +} +interface IPopup { + title: string; + icon: React.FC>; + popupType: PopupType; + setIsOpen: (val: boolean) => void; + setAmount?: (val: string) => void; + isCommit?: boolean; +} + +type PopupProps = IStakeWithdraw | IVoteWithoutCommit | IVoteWithCommit | IAppeal; + const Popup: React.FC = ({ title, icon: Icon, diff --git a/web/src/components/StatDisplay.tsx b/web/src/components/StatDisplay.tsx index 767d3a8b1..b6f2e4b90 100644 --- a/web/src/components/StatDisplay.tsx +++ b/web/src/components/StatDisplay.tsx @@ -1,11 +1,6 @@ import React from "react"; import styled, { useTheme } from "styled-components"; -const createPair = (iconColor: string, backgroundColor: string) => ({ - iconColor, - backgroundColor, -}); - const Container = styled.div` display: flex; align-items: center; @@ -34,6 +29,11 @@ const TextContainer = styled.div` } `; +const createPair = (iconColor: string, backgroundColor: string) => ({ + iconColor, + backgroundColor, +}); + export interface IStatDisplay { title: string; text: string; diff --git a/web/src/layout/Header/navbar/DappList.tsx b/web/src/layout/Header/navbar/DappList.tsx index b0474da1e..81c69a38b 100644 --- a/web/src/layout/Header/navbar/DappList.tsx +++ b/web/src/layout/Header/navbar/DappList.tsx @@ -12,6 +12,52 @@ import Tokens from "svgs/icons/tokens.svg"; import Product from "./Product"; import { Overlay } from "components/Overlay"; +const Header = styled.h1` + display: flex; + padding-top: 32px; + padding-bottom: 20px; + font-size: 24px; + font-weight: 600; + line-height: 32.68px; +`; + +const Container = styled.div` + display: flex; + position: absolute; + max-height: 60vh; + top: 5%; + left: 50%; + transform: translate(-50%); + z-index: 10; + flex-direction: column; + align-items: center; + + width: calc(300px + (480 - 300) * (100vw - 375px) / (1250 - 375)); + max-width: 480px; + min-width: 300px; + border-radius: 3px; + border: 1px solid ${({ theme }) => theme.stroke}; + background-color: ${({ theme }) => theme.whiteBackground}; + box-shadow: 0px 2px 3px rgba(0, 0, 0, 0.06); + + svg { + visibility: visible; + } +`; + +const ItemsDiv = styled.div` + display: grid; + overflow-y: auto; + padding: 16px calc(8px + (24 - 8) * ((100vw - 480px) / (1250 - 480))); + row-gap: 8px; + column-gap: 2px; + justify-items: center; + max-width: 480px; + min-width: 300px; + width: calc(300px + (480 - 300) * (100vw - 375px) / (1250 - 375)); + grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); +`; + interface IDappList { toggleSolution: () => void; } @@ -59,52 +105,6 @@ const ITEMS = [ }, ]; -const Header = styled.h1` - display: flex; - padding-top: 32px; - padding-bottom: 20px; - font-size: 24px; - font-weight: 600; - line-height: 32.68px; -`; - -const Container = styled.div` - display: flex; - position: absolute; - max-height: 60vh; - top: 5%; - left: 50%; - transform: translate(-50%); - z-index: 10; - flex-direction: column; - align-items: center; - - width: calc(300px + (480 - 300) * (100vw - 375px) / (1250 - 375)); - max-width: 480px; - min-width: 300px; - border-radius: 3px; - border: 1px solid ${({ theme }) => theme.stroke}; - background-color: ${({ theme }) => theme.whiteBackground}; - box-shadow: 0px 2px 3px rgba(0, 0, 0, 0.06); - - svg { - visibility: visible; - } -`; - -const ItemsDiv = styled.div` - display: grid; - overflow-y: auto; - padding: 16px calc(8px + (24 - 8) * ((100vw - 480px) / (1250 - 480))); - row-gap: 8px; - column-gap: 2px; - justify-items: center; - max-width: 480px; - min-width: 300px; - width: calc(300px + (480 - 300) * (100vw - 375px) / (1250 - 375)); - grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); -`; - const DappList: React.FC = ({ toggleSolution }) => { const containerRef = useRef(null); useFocusOutside(containerRef, () => { diff --git a/web/src/layout/Header/navbar/Menu/Help.tsx b/web/src/layout/Header/navbar/Menu/Help.tsx index f8d01eab0..1559d6b68 100644 --- a/web/src/layout/Header/navbar/Menu/Help.tsx +++ b/web/src/layout/Header/navbar/Menu/Help.tsx @@ -9,43 +9,6 @@ import Faq from "svgs/menu-icons/help.svg"; import Telegram from "svgs/socialmedia/telegram.svg"; import { Overlay } from "components/Overlay"; -const ITEMS = [ - { - text: "Onboarding", - Icon: Book, - url: "", - }, - { - text: "Get Help", - Icon: Telegram, - url: "https://t.me/kleros", - }, - { - text: "Report a Bug", - Icon: Bug, - url: "https://github.com/kleros/kleros-v2/issues", - }, - { - text: "DApp Guide", - Icon: Guide, - url: "https://docs.kleros.io/products/court-v2", - }, - { - text: "Crypto Beginner's Guide", - Icon: ETH, - url: "https://ethereum.org/en/wallets/", - }, - { - text: "FAQ", - Icon: Faq, - url: "https://docs.kleros.io/kleros-faq", - }, -]; - -interface IHelp { - toggle: () => void; -} - const Container = styled.div` display: flex; flex-direction: column; @@ -86,6 +49,43 @@ const Icon = styled.svg` fill: ${({ theme }) => theme.secondaryPurple}; `; +const ITEMS = [ + { + text: "Onboarding", + Icon: Book, + url: "", + }, + { + text: "Get Help", + Icon: Telegram, + url: "https://t.me/kleros", + }, + { + text: "Report a Bug", + Icon: Bug, + url: "https://github.com/kleros/kleros-v2/issues", + }, + { + text: "DApp Guide", + Icon: Guide, + url: "https://docs.kleros.io/products/court-v2", + }, + { + text: "Crypto Beginner's Guide", + Icon: ETH, + url: "https://ethereum.org/en/wallets/", + }, + { + text: "FAQ", + Icon: Faq, + url: "https://docs.kleros.io/kleros-faq", + }, +]; + +interface IHelp { + toggle: () => void; +} + const Help: React.FC = ({ toggle }) => { const containerRef = useRef(null); useFocusOutside(containerRef, () => { diff --git a/web/src/layout/Header/navbar/Product.tsx b/web/src/layout/Header/navbar/Product.tsx index 95f05deab..1fa47844c 100644 --- a/web/src/layout/Header/navbar/Product.tsx +++ b/web/src/layout/Header/navbar/Product.tsx @@ -1,12 +1,6 @@ import React from "react"; import styled from "styled-components"; -interface IProduct { - text: string; - url: string; - Icon: React.FC> | string; -} - const Container = styled.a` cursor: pointer; display: flex; @@ -54,6 +48,12 @@ const StyledImg = styled.img` max-height: 48px; `; +interface IProduct { + text: string; + url: string; + Icon: React.FC> | string; +} + const Product: React.FC = ({ text, url, Icon }) => { return ( diff --git a/web/src/pages/Cases/CaseDetails/Appeal/Classic/Fund.tsx b/web/src/pages/Cases/CaseDetails/Appeal/Classic/Fund.tsx index 9c522b952..2645336ea 100644 --- a/web/src/pages/Cases/CaseDetails/Appeal/Classic/Fund.tsx +++ b/web/src/pages/Cases/CaseDetails/Appeal/Classic/Fund.tsx @@ -15,6 +15,26 @@ import { useFundingContext, } from "hooks/useClassicAppealContext"; +const StyledField = styled(Field)` + width: 100%; + & > input { + text-align: center; + } + &:before { + position: absolute; + content: "ETH"; + right: 12px; + top: 50%; + transform: translateY(-50%); + color: ${({ theme }) => theme.primaryText}; + } +`; + +const StyledButton = styled(Button)` + margin: auto; + margin-top: 12px; +`; + const useNeedFund = () => { const loserSideCountdown = useLoserSideCountdownContext(); const { fundedChoices, winningChoice } = useFundingContext(); @@ -102,24 +122,4 @@ const Fund: React.FC = ({ amount, setAmount, setIsOpen }) => { ); }; -const StyledField = styled(Field)` - width: 100%; - & > input { - text-align: center; - } - &:before { - position: absolute; - content: "ETH"; - right: 12px; - top: 50%; - transform: translateY(-50%); - color: ${({ theme }) => theme.primaryText}; - } -`; - -const StyledButton = styled(Button)` - margin: auto; - margin-top: 12px; -`; - export default Fund; diff --git a/web/src/pages/Cases/CaseDetails/Appeal/Classic/Options/StageOne.tsx b/web/src/pages/Cases/CaseDetails/Appeal/Classic/Options/StageOne.tsx index 746137ddc..805ec3244 100644 --- a/web/src/pages/Cases/CaseDetails/Appeal/Classic/Options/StageOne.tsx +++ b/web/src/pages/Cases/CaseDetails/Appeal/Classic/Options/StageOne.tsx @@ -9,6 +9,17 @@ import { useSelectedOptionContext, } from "hooks/useClassicAppealContext"; +const Container = styled.div` + margin: 24px 0; +`; + +const OptionsContainer = styled.div` + display: flex; + flex-wrap: wrap; + gap: 24px; + margin-top: 12px; +`; + const StageOne: React.FC = () => { const { paidFees, winningChoice, loserRequiredFunding, winnerRequiredFunding } = useFundingContext(); const options = useOptionsContext(); @@ -38,15 +49,4 @@ const StageOne: React.FC = () => { ); }; -const Container = styled.div` - margin: 24px 0; -`; - -const OptionsContainer = styled.div` - display: flex; - flex-wrap: wrap; - gap: 24px; - margin-top: 12px; -`; - export default StageOne; diff --git a/web/src/pages/Cases/CaseDetails/Appeal/Classic/Options/StageTwo.tsx b/web/src/pages/Cases/CaseDetails/Appeal/Classic/Options/StageTwo.tsx index 4fb7f1ca9..6be1c1485 100644 --- a/web/src/pages/Cases/CaseDetails/Appeal/Classic/Options/StageTwo.tsx +++ b/web/src/pages/Cases/CaseDetails/Appeal/Classic/Options/StageTwo.tsx @@ -4,6 +4,17 @@ import OptionCard from "../../OptionCard"; import { useFundingContext, useOptionsContext, useSelectedOptionContext } from "hooks/useClassicAppealContext"; import { isUndefined } from "utils/index"; +const Container = styled.div` + margin: 24px 0; +`; + +const OptionsContainer = styled.div` + display: flex; + flex-wrap: wrap; + gap: 24px; + margin-top: 12px; +`; + const StageOne: React.FC = () => { const { paidFees, winningChoice, winnerRequiredFunding, fundedChoices } = useFundingContext(); const options = useOptionsContext(); @@ -39,15 +50,4 @@ const StageOne: React.FC = () => { ); }; -const Container = styled.div` - margin: 24px 0; -`; - -const OptionsContainer = styled.div` - display: flex; - flex-wrap: wrap; - gap: 24px; - margin-top: 12px; -`; - export default StageOne; diff --git a/web/src/pages/Cases/CaseDetails/Appeal/Classic/Options/index.tsx b/web/src/pages/Cases/CaseDetails/Appeal/Classic/Options/index.tsx index 1d99325e2..3fca8d204 100644 --- a/web/src/pages/Cases/CaseDetails/Appeal/Classic/Options/index.tsx +++ b/web/src/pages/Cases/CaseDetails/Appeal/Classic/Options/index.tsx @@ -5,6 +5,10 @@ import StageOne from "./StageOne"; import StageTwo from "./StageTwo"; import { isUndefined } from "utils/index"; +const Container = styled.div` + margin: 24px 0; +`; + const Options: React.FC = () => { const loserSideCountdown = useLoserSideCountdownContext(); return !isUndefined(loserSideCountdown) ? ( @@ -14,8 +18,4 @@ const Options: React.FC = () => { ); }; -const Container = styled.div` - margin: 24px 0; -`; - export default Options; diff --git a/web/src/pages/Cases/CaseDetails/Appeal/Classic/StageExplainer.tsx b/web/src/pages/Cases/CaseDetails/Appeal/Classic/StageExplainer.tsx index d3d2651b8..123838747 100644 --- a/web/src/pages/Cases/CaseDetails/Appeal/Classic/StageExplainer.tsx +++ b/web/src/pages/Cases/CaseDetails/Appeal/Classic/StageExplainer.tsx @@ -4,29 +4,6 @@ import { Box } from "@kleros/ui-components-library"; import { secondsToDayHourMinute } from "utils/date"; import HourglassIcon from "svgs/icons/hourglass.svg"; -interface IStageExplainer { - loserSideCountdown: number | undefined; -} - -const StageExplainer: React.FC = ({ loserSideCountdown }) => ( - - - - {typeof loserSideCountdown !== "undefined" && - secondsToDayHourMinute(loserSideCountdown)} - -
- - -
-
-); - const StyledBox = styled(Box)` border-radius: 3px; margin: 24px 0; @@ -52,4 +29,25 @@ const CountdownLabel = styled.label` } `; +interface IStageExplainer { + loserSideCountdown: number | undefined; +} + +const StageExplainer: React.FC = ({ loserSideCountdown }) => ( + + + + {typeof loserSideCountdown !== "undefined" && secondsToDayHourMinute(loserSideCountdown)} + +
+ + +
+
+); + export default StageExplainer; diff --git a/web/src/pages/Cases/CaseDetails/Appeal/OptionCard.tsx b/web/src/pages/Cases/CaseDetails/Appeal/OptionCard.tsx index 10f6a8ee7..df23ed64c 100644 --- a/web/src/pages/Cases/CaseDetails/Appeal/OptionCard.tsx +++ b/web/src/pages/Cases/CaseDetails/Appeal/OptionCard.tsx @@ -6,6 +6,45 @@ import Gavel from "svgs/icons/gavel.svg"; import { formatEther } from "viem"; import { isUndefined } from "utils/index"; +const StyledCard = styled(Card)` + width: 100%; + padding: 24px; + &:hover { + cursor: pointer; + } +`; + +const WinnerLabel = styled.label<{ winner: boolean }>` + color: ${({ theme, winner }) => (winner ? theme.success : theme.warning)}; + svg { + width: 12px; + margin-right: 4px; + fill: ${({ theme, winner }) => (winner ? theme.success : theme.warning)}; + } +`; + +const StyledRadio = styled(Radio)` + padding-left: 24px; + > input { + display: none; + } +`; + +const TopContainer = styled.div` + display: flex; + justify-content: space-between; + height: 50%; + .block { + display: block; + } +`; + +const LabelContainer = styled.div` + width: 100%; + display: flex; + justify-content: center; +`; + interface IOptionCard extends React.HTMLAttributes { text: string; funding: bigint; @@ -56,43 +95,4 @@ const OptionCard: React.FC = ({ ); }; -const StyledCard = styled(Card)` - width: 100%; - padding: 24px; - &:hover { - cursor: pointer; - } -`; - -const WinnerLabel = styled.label<{ winner: boolean }>` - color: ${({ theme, winner }) => (winner ? theme.success : theme.warning)}; - svg { - width: 12px; - margin-right: 4px; - fill: ${({ theme, winner }) => (winner ? theme.success : theme.warning)}; - } -`; - -const StyledRadio = styled(Radio)` - padding-left: 24px; - > input { - display: none; - } -`; - -const TopContainer = styled.div` - display: flex; - justify-content: space-between; - height: 50%; - .block { - display: block; - } -`; - -const LabelContainer = styled.div` - width: 100%; - display: flex; - justify-content: center; -`; - export default OptionCard; diff --git a/web/src/pages/Cases/CaseDetails/Evidence/SubmitEvidenceModal.tsx b/web/src/pages/Cases/CaseDetails/Evidence/SubmitEvidenceModal.tsx index d932a5de8..c844d036c 100644 --- a/web/src/pages/Cases/CaseDetails/Evidence/SubmitEvidenceModal.tsx +++ b/web/src/pages/Cases/CaseDetails/Evidence/SubmitEvidenceModal.tsx @@ -9,6 +9,42 @@ import { useWalletClient, usePublicClient } from "wagmi"; import { EnsureChain } from "components/EnsureChain"; import { prepareWriteDisputeKitClassic } from "hooks/contracts/generated"; +const StyledModal = styled(Modal)` + position: absolute; + top: 50%; + left: 50%; + right: auto; + bottom: auto; + margin-right: -50%; + transform: translate(-50%, -50%); + height: auto; + width: 80%; + border: 1px solid ${({ theme }) => theme.stroke}; + border-radius: 3px; + background-color: ${({ theme }) => theme.whiteBackground}; + + display: flex; + flex-direction: column; + align-items: center; + padding: 16px; + gap: 16px; +`; + +const StyledTextArea = styled(Textarea)` + width: 100%; + height: 200px; +`; + +const StyledFileUploader = styled(FileUploader)` + width: 100%; +`; + +const ButtonArea = styled.div` + width: 100%; + display: flex; + justify-content: space-between; +`; + const SubmitEvidenceModal: React.FC<{ isOpen: boolean; evidenceGroup: bigint; @@ -80,40 +116,4 @@ const constructEvidence = async (msg: string, file?: File): Promise => return formData; }; -const StyledModal = styled(Modal)` - position: absolute; - top: 50%; - left: 50%; - right: auto; - bottom: auto; - margin-right: -50%; - transform: translate(-50%, -50%); - height: auto; - width: 80%; - border: 1px solid ${({ theme }) => theme.stroke}; - border-radius: 3px; - background-color: ${({ theme }) => theme.whiteBackground}; - - display: flex; - flex-direction: column; - align-items: center; - padding: 16px; - gap: 16px; -`; - -const StyledTextArea = styled(Textarea)` - width: 100%; - height: 200px; -`; - -const StyledFileUploader = styled(FileUploader)` - width: 100%; -`; - -const ButtonArea = styled.div` - width: 100%; - display: flex; - justify-content: space-between; -`; - export default SubmitEvidenceModal; diff --git a/web/src/pages/Cases/CaseDetails/Tabs.tsx b/web/src/pages/Cases/CaseDetails/Tabs.tsx index d7ce0d44b..f7c976c0c 100644 --- a/web/src/pages/Cases/CaseDetails/Tabs.tsx +++ b/web/src/pages/Cases/CaseDetails/Tabs.tsx @@ -10,6 +10,17 @@ import DocIcon from "assets/svgs/icons/doc.svg"; import BalanceIcon from "assets/svgs/icons/law-balance.svg"; import BullhornIcon from "assets/svgs/icons/bullhorn.svg"; +const StyledTabs = styled(TabsComponent)` + width: 100%; + > * { + display: flex; + flex-wrap: wrap; + > svg { + margin-right: 0px !important; + } + } +`; + const TABS = [ { text: "Overview", @@ -68,15 +79,4 @@ const Tabs: React.FC = () => { ); }; -const StyledTabs = styled(TabsComponent)` - width: 100%; - > * { - display: flex; - flex-wrap: wrap; - > svg { - margin-right: 0px !important; - } - } -`; - export default Tabs; diff --git a/web/src/pages/Cases/CaseDetails/Timeline.tsx b/web/src/pages/Cases/CaseDetails/Timeline.tsx index cd66ccee2..9f9b5d0b1 100644 --- a/web/src/pages/Cases/CaseDetails/Timeline.tsx +++ b/web/src/pages/Cases/CaseDetails/Timeline.tsx @@ -6,6 +6,19 @@ import { Box, Steps } from "@kleros/ui-components-library"; import { useCountdown } from "hooks/useCountdown"; import { secondsToDayHourMinute } from "utils/date"; +const TimeLineContainer = styled(Box)` + width: 100%; + height: 100px; + border-radius: 3px; + margin: 16px 0px; + padding: 8px; +`; + +const StyledSteps = styled(Steps)` + width: 85%; + margin: auto; +`; + const Timeline: React.FC<{ dispute: DisputeDetailsQuery["dispute"]; currentPeriodIndex: number; @@ -68,17 +81,4 @@ const getDeadline = ( return 0; }; -const TimeLineContainer = styled(Box)` - width: 100%; - height: 100px; - border-radius: 3px; - margin: 16px 0px; - padding: 8px; -`; - -const StyledSteps = styled(Steps)` - width: 85%; - margin: auto; -`; - export default Timeline; diff --git a/web/src/pages/Cases/CaseDetails/Voting/VotingHistory.tsx b/web/src/pages/Cases/CaseDetails/Voting/VotingHistory.tsx index 9061a02fd..f53602a23 100644 --- a/web/src/pages/Cases/CaseDetails/Voting/VotingHistory.tsx +++ b/web/src/pages/Cases/CaseDetails/Voting/VotingHistory.tsx @@ -55,6 +55,20 @@ const StyledAccordion = styled(Accordion)` } `; +const VotedContainer = styled.div` + width: 100%; + margin-bottom: 8px; + display: flex; + align-items: center; + gap: 4px; +`; + +const JustificationContainer = styled.div` + > p { + margin: 0px; + } +`; + const AccordionContent: React.FC<{ choice: string; justification: string; @@ -73,20 +87,6 @@ const AccordionContent: React.FC<{ ); }; -const VotedContainer = styled.div` - width: 100%; - margin-bottom: 8px; - display: flex; - align-items: center; - gap: 4px; -`; - -const JustificationContainer = styled.div` - > p { - margin: 0px; - } -`; - export const getVoteChoice = (vote, answers) => { const selectedAnswer = answers?.[vote - 1]?.title; if (vote === 0) { diff --git a/web/src/pages/Cases/CaseDetails/index.tsx b/web/src/pages/Cases/CaseDetails/index.tsx index 2a858a9ea..46dc66017 100644 --- a/web/src/pages/Cases/CaseDetails/index.tsx +++ b/web/src/pages/Cases/CaseDetails/index.tsx @@ -11,6 +11,16 @@ import Tabs from "./Tabs"; import Timeline from "./Timeline"; import Voting from "./Voting"; +const Container = styled.div``; + +const StyledCard = styled(Card)` + margin-top: 16px; + width: 100%; + height: auto; + min-height: 100px; + padding: 16px; +`; + const CaseDetails: React.FC = () => { const { id } = useParams(); const { data } = useDisputeDetailsQuery(id); @@ -41,14 +51,4 @@ const CaseDetails: React.FC = () => { ); }; -const Container = styled.div``; - -const StyledCard = styled(Card)` - margin-top: 16px; - width: 100%; - height: auto; - min-height: 100px; - padding: 16px; -`; - export default CaseDetails; diff --git a/web/src/pages/Courts/CourtDetails/Description.tsx b/web/src/pages/Courts/CourtDetails/Description.tsx index 57caad908..8326430b0 100644 --- a/web/src/pages/Courts/CourtDetails/Description.tsx +++ b/web/src/pages/Courts/CourtDetails/Description.tsx @@ -5,6 +5,26 @@ import { Routes, Route, Navigate, useParams, useNavigate, useLocation } from "re import { Tabs } from "@kleros/ui-components-library"; import { useCourtPolicy } from "queries/useCourtPolicy"; +const Container = styled.div` + width: 100%; +`; + +const TextContainer = styled.div` + width: 100%; + padding: 12px 0; +`; + +const StyledTabs = styled(Tabs)` + width: 100%; + > * { + display: flex; + flex-wrap: wrap; + > svg { + margin-right: 0px !important; + } + } +`; + interface IPolicy { description?: string; requiredSkills?: string; @@ -71,24 +91,4 @@ const formatMarkdown = (markdown?: string) =>

Loading...

); -const Container = styled.div` - width: 100%; -`; - -const TextContainer = styled.div` - width: 100%; - padding: 12px 0; -`; - -const StyledTabs = styled(Tabs)` - width: 100%; - > * { - display: flex; - flex-wrap: wrap; - > svg { - margin-right: 0px !important; - } - } -`; - export default Description; diff --git a/web/src/pages/Courts/CourtDetails/StakePanel/JurorStakeDisplay.tsx b/web/src/pages/Courts/CourtDetails/StakePanel/JurorStakeDisplay.tsx index 4d79c581c..02a9fbe10 100644 --- a/web/src/pages/Courts/CourtDetails/StakePanel/JurorStakeDisplay.tsx +++ b/web/src/pages/Courts/CourtDetails/StakePanel/JurorStakeDisplay.tsx @@ -11,6 +11,14 @@ import PNKIcon from "svgs/icons/pnk.svg"; import { useCourtDetails } from "queries/useCourtDetails"; import { useKlerosCoreGetJurorBalance } from "hooks/contracts/generated"; +const Container = styled.div` + display: flex; + flex-direction: column; + justify-content: space-between; + gap: 8px; + margin-top: 12px; +`; + const format = (value: bigint | undefined): string => (value !== undefined ? formatEther(value) : "0"); const bigIntRatioToPercentage = (numerator: bigint, denominator: bigint): string => { @@ -103,11 +111,3 @@ const JurorBalanceDisplay = () => { }; export default JurorBalanceDisplay; - -const Container = styled.div` - display: flex; - flex-direction: column; - justify-content: space-between; - gap: 8px; - margin-top: 12px; -`; diff --git a/web/src/pages/Courts/CourtDetails/StakePanel/index.tsx b/web/src/pages/Courts/CourtDetails/StakePanel/index.tsx index ab0db4266..49590e6fe 100644 --- a/web/src/pages/Courts/CourtDetails/StakePanel/index.tsx +++ b/web/src/pages/Courts/CourtDetails/StakePanel/index.tsx @@ -8,6 +8,28 @@ import { ActionType } from "./StakeWithdrawButton"; import Popup, { PopupType } from "components/Popup/index"; import BalanceIcon from "assets/svgs/icons/balance.svg"; +const Container = styled.div` + position: relative; + width: 100%; + margin-top: 32px; + display: flex; + flex-direction: column; + gap: 28px; +`; + +const TagArea = styled.div` + display: flex; + gap: 10px; +`; + +const StakeArea = styled(TagArea)` + flex-direction: column; +`; + +const TextArea = styled.div` + color: ${({ theme }) => theme.primaryText}; +`; + const StakePanel: React.FC<{ courtName: string; id: string }> = ({ courtName = "General Court", id }) => { const [amount, setAmount] = useState(""); const [isSending, setIsSending] = useState(false); @@ -55,25 +77,3 @@ const StakePanel: React.FC<{ courtName: string; id: string }> = ({ courtName = " }; export default StakePanel; - -const Container = styled.div` - position: relative; - width: 100%; - margin-top: 32px; - display: flex; - flex-direction: column; - gap: 28px; -`; - -const TagArea = styled.div` - display: flex; - gap: 10px; -`; - -const StakeArea = styled(TagArea)` - flex-direction: column; -`; - -const TextArea = styled.div` - color: ${({ theme }) => theme.primaryText}; -`; diff --git a/web/src/pages/Courts/CourtDetails/index.tsx b/web/src/pages/Courts/CourtDetails/index.tsx index aea305377..2261829c4 100644 --- a/web/src/pages/Courts/CourtDetails/index.tsx +++ b/web/src/pages/Courts/CourtDetails/index.tsx @@ -15,6 +15,26 @@ import Description from "./Description"; import StakePanel from "./StakePanel"; import { usePnkFaucetWithdrewAlready, prepareWritePnkFaucet, usePnkBalanceOf } from "hooks/contracts/generated"; +const Container = styled.div``; + +const ButtonContainer = styled.div` + display: flex; + flex-wrap: wrap; + justify-content: space-between; +`; + +const StyledCard = styled(Card)` + margin-top: 16px; + width: 100%; + height: auto; + padding: 16px; + min-height: 100px; +`; + +const StyledBreadcrumb = styled(Breadcrumb)` + margin: 16px 0 12px 0; +`; + const CourtDetails: React.FC = () => { const { id } = useParams(); const [isSending, setIsSending] = useState(false); @@ -82,26 +102,6 @@ const CourtDetails: React.FC = () => { ); }; -const Container = styled.div``; - -const ButtonContainer = styled.div` - display: flex; - flex-wrap: wrap; - justify-content: space-between; -`; - -const StyledCard = styled(Card)` - margin-top: 16px; - width: 100%; - height: auto; - padding: 16px; - min-height: 100px; -`; - -const StyledBreadcrumb = styled(Breadcrumb)` - margin: 16px 0 12px 0; -`; - export default CourtDetails; interface IItem { diff --git a/web/src/pages/DisputeTemplateView.tsx b/web/src/pages/DisputeTemplateView.tsx index d7c3bfc82..dc902662d 100644 --- a/web/src/pages/DisputeTemplateView.tsx +++ b/web/src/pages/DisputeTemplateView.tsx @@ -7,46 +7,6 @@ import ReactMarkdown from "components/ReactMarkdown"; import { isUndefined } from "utils/index"; import { IPFS_GATEWAY } from "consts/index"; -const Wrapper = styled.div` - min-height: calc(100vh - 144px); - margin: 24px; - display: flex; - gap: 12px; -`; - -const StyledTextArea = styled(Textarea)` - width: 50%; - height: calc(100vh - 300px); -`; - -const DisputeTemplateView: React.FC = () => { - const [disputeTemplate, setDisputeTemplate] = useState(""); - const [errorMsg, setErrorMessage] = useState(""); - const parsedDisputeTemplate = useMemo(() => { - try { - const parsed = JSON.parse(disputeTemplate); - setErrorMessage(""); - return parsed; - } catch (e) { - setErrorMessage((e as SyntaxError).message); - return undefined; - } - }, [disputeTemplate]); - const isThereInput = useMemo(() => disputeTemplate !== "", [disputeTemplate]); - return ( - - setDisputeTemplate(e.target.value)} - placeholder="Enter dispute template" - variant={isThereInput && errorMsg !== "" ? "error" : ""} - message={isThereInput ? errorMsg : ""} - /> - - - ); -}; - const Container = styled.div` width: 50%; height: auto; @@ -106,6 +66,46 @@ const LinkContainer = styled.div` justify-content: space-between; `; +const Wrapper = styled.div` + min-height: calc(100vh - 144px); + margin: 24px; + display: flex; + gap: 12px; +`; + +const StyledTextArea = styled(Textarea)` + width: 50%; + height: calc(100vh - 300px); +`; + +const DisputeTemplateView: React.FC = () => { + const [disputeTemplate, setDisputeTemplate] = useState(""); + const [errorMsg, setErrorMessage] = useState(""); + const parsedDisputeTemplate = useMemo(() => { + try { + const parsed = JSON.parse(disputeTemplate); + setErrorMessage(""); + return parsed; + } catch (e) { + setErrorMessage((e as SyntaxError).message); + return undefined; + } + }, [disputeTemplate]); + const isThereInput = useMemo(() => disputeTemplate !== "", [disputeTemplate]); + return ( + + setDisputeTemplate(e.target.value)} + placeholder="Enter dispute template" + variant={isThereInput && errorMsg !== "" ? "error" : ""} + message={isThereInput ? errorMsg : ""} + /> + + + ); +}; + const Overview: React.FC<{ disputeTemplate: any }> = ({ disputeTemplate }) => { return ( <> From bd0802b0bf350ee24e7c5dcdcd6957abc6e75646 Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Tue, 22 Aug 2023 18:57:37 +0800 Subject: [PATCH 02/30] feat: small cosmetic change to the court breadcrumbs --- web/src/pages/Courts/CourtDetails/index.tsx | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/web/src/pages/Courts/CourtDetails/index.tsx b/web/src/pages/Courts/CourtDetails/index.tsx index aea305377..908c55325 100644 --- a/web/src/pages/Courts/CourtDetails/index.tsx +++ b/web/src/pages/Courts/CourtDetails/index.tsx @@ -49,10 +49,13 @@ const CourtDetails: React.FC = () => { const faucetCheck = !isUndefined(balance) && parseInt(formatEther(balance)) > 200; const courtPath = getCourtsPath(data?.court, id); - const items = courtPath?.map((node) => ({ - text: node.name, - value: node.id, - })); + const items = [{ text: "đŸ›ī¸", value: "0" }]; + items.push( + ...(courtPath?.map((node) => ({ + text: node.name, + value: node.id, + })) ?? []) + ); return ( @@ -99,7 +102,7 @@ const StyledCard = styled(Card)` `; const StyledBreadcrumb = styled(Breadcrumb)` - margin: 16px 0 12px 0; + margin: 0px 0 12px 0; `; export default CourtDetails; From 5734bd48614f6473578ffb2ee90ee0b227a2bcc5 Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Tue, 22 Aug 2023 19:43:05 +0800 Subject: [PATCH 03/30] chore: vscode ts lib setting --- .vscode/settings.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.vscode/settings.json b/.vscode/settings.json index 0386cc80f..0f801b6f5 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,6 +5,7 @@ }, "solidity-va.test.defaultUnittestTemplate": "hardhat", "solidity-language-server.trace.server.verbosity": "message", + "typescript.tsdk": "node_modules/typescript/lib", "eslint.packageManager": "yarn", "prettier.useEditorConfig": true, "prettier.configPath": "prettier-config/.prettierrc.js" From f0b1ea8163aaa7a4ded97ec9bbcb25fdf5fe2e27 Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Tue, 22 Aug 2023 23:45:55 +0800 Subject: [PATCH 04/30] chore: getting the actions/dependency-review workflow to play well with merge queues --- .github/workflows/dependency-review.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 8967e929a..cd4ae1eb1 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -31,5 +31,9 @@ jobs: - name: 'Checkout Repository' uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - name: 'Dependency Review' uses: actions/dependency-review-action@7d90b4f05fea31dde1c4a1fb3fa787e197ea93ab # v3.0.7 + with: + base-ref: ${{ github.event.pull_request.base.sha || 'dev' }} + head-ref: ${{ github.event.pull_request.head.sha || github.ref }} From ce4bb60e56f23b794b9417035a15999b637dadea Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Tue, 22 Aug 2023 18:13:51 +0200 Subject: [PATCH 05/30] chore: adding support for merge queues to the CodeQL workflow --- .github/workflows/codeql.yml | 72 ++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 .github/workflows/codeql.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 000000000..87c0c7d62 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,72 @@ +name: "CodeQL" + +on: + merge_group: + push: + branches: + - master + - dev + pull_request: + # The branches below must be a subset of the branches above + branches: + - master + - dev + schedule: + - cron: '26 1 * * 6' + +jobs: + analyze: + name: Analyze + runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} + timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }} + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ "javascript"] + + steps: + - name: Harden Runner + uses: step-security/harden-runner@128a63446a954579617e875aaab7d2978154e969 # v2.4.0 + with: + egress-policy: audit + + - name: Checkout repository + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@29b1f65c5e92e24fe6b6647da1eaabe529cec70f # v2.3.3 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + + + # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@29b1f65c5e92e24fe6b6647da1eaabe529cec70f # v2.3.3 + + # â„šī¸ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. + + # - run: | + # echo "Run, Build Application using script" + # ./location_of_script_within_repo/buildscript.sh + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@29b1f65c5e92e24fe6b6647da1eaabe529cec70f # v2.3.3 + with: + category: "/language:${{matrix.language}}" From 2764cad8e864f473ef026434fd798b97c4c878d9 Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Wed, 23 Aug 2023 00:21:43 +0800 Subject: [PATCH 06/30] chore: workflow name --- .github/workflows/codeql.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 87c0c7d62..169a1f627 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -1,4 +1,4 @@ -name: "CodeQL" +name: "CodeQL Advanced" on: merge_group: @@ -15,7 +15,7 @@ on: - cron: '26 1 * * 6' jobs: - analyze: + codeql-advanced-analysis: name: Analyze runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }} From 2a9c08f82756959ad49b24fd628a9db2e0e99f03 Mon Sep 17 00:00:00 2001 From: nhestrompia Date: Fri, 18 Aug 2023 10:55:05 +0300 Subject: [PATCH 07/30] fix(web): round-ongoing-info --- web/src/components/Verdict/DisputeTimeline.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/components/Verdict/DisputeTimeline.tsx b/web/src/components/Verdict/DisputeTimeline.tsx index a6c3b1812..c2efa61e1 100644 --- a/web/src/components/Verdict/DisputeTimeline.tsx +++ b/web/src/components/Verdict/DisputeTimeline.tsx @@ -80,7 +80,7 @@ const useItems = (disputeDetails?: DisputeDetailsQuery, arbitrable?: `0x${string return localRounds?.reduce( (acc, { winningChoice }, index) => { const parsedRoundChoice = parseInt(winningChoice); - const isOngoing = index === localRounds.length - 1 && currentPeriodIndex < 4; + const isOngoing = index === localRounds.length - 1 && currentPeriodIndex < 3; const eventDate = getCaseEventTimes(lastPeriodChange, currentPeriodIndex, courtTimePeriods, false); const icon = dispute.ruled && !rulingOverride && index === localRounds.length - 1 ? ClosedCaseIcon : ""; const answers = disputeTemplate?.answers; From 1bb89dac97c949b9642d2a9655467e8089629799 Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Wed, 23 Aug 2023 01:43:53 +0800 Subject: [PATCH 08/30] chore: netlify script --- scripts/cancel-all-netlify-builds.sh | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100755 scripts/cancel-all-netlify-builds.sh diff --git a/scripts/cancel-all-netlify-builds.sh b/scripts/cancel-all-netlify-builds.sh new file mode 100755 index 000000000..6dabd3120 --- /dev/null +++ b/scripts/cancel-all-netlify-builds.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +# netlify api listSites | jq '. | map([.name, .id])' +v2Site="86d94ae8-f655-46a4-a859-d68696173f3a" +v2ContractsSite="dd8bc215-e054-407f-92ef-d61511720928" + +function cancelSiteDeploy() #sideId +{ + local sideId=$1 + readarray -t builds < <(netlify api listSiteDeploys -d '{ "site_id": "'$sideId'", "state": "new"}' | jq --compact-output '.[]') + for build in "${builds[@]}" + do + local name=$(jq -r .name <<< $build) + local branch=$(jq -r .branch <<< $build) + if [[ "$branch" == "dev" || "$branch" == "master" ]]; then + continue; + fi + echo "Cancelling build for $name $branch" + echo netlify api cancelSiteDeploy -d '{ "deploy_id": "'$(jq -r .id <<< $build)'"}' + echo + done +} + +cancelSiteDeploy $v2Site +cancelSiteDeploy $v2ContractsSite From 35a6d7f224e510a5d1d69c0360d51f9a9fec4bcf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Aug 2023 05:08:43 +0000 Subject: [PATCH 09/30] chore(deps): bump github/codeql-action from 2.21.3 to 2.21.4 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2.21.3 to 2.21.4. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/5b6282e01c62d02e720b81eb8a51204f527c3624...a09933a12a80f87b87005513f0abb1494c27a716) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/scorecards.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 68e83d9dd..c626f8e4f 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -86,6 +86,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@5b6282e01c62d02e720b81eb8a51204f527c3624 # v2.21.3 + uses: github/codeql-action/upload-sarif@a09933a12a80f87b87005513f0abb1494c27a716 # v2.21.4 with: sarif_file: results.sarif From f3893c4051a65f768e158fd4e95a09f80a53014c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 18:22:53 +0000 Subject: [PATCH 10/30] chore(deps): update actions/upload-artifact digest to 65d8626 --- .github/workflows/contracts-testing.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/contracts-testing.yml b/.github/workflows/contracts-testing.yml index 0aa124185..29a5587bd 100644 --- a/.github/workflows/contracts-testing.yml +++ b/.github/workflows/contracts-testing.yml @@ -72,7 +72,7 @@ jobs: working-directory: contracts - name: Upload a build artifact - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce + uses: actions/upload-artifact@65d862660abb392b8c4a3d1195a2108db131dd05 with: name: code-coverage-report path: contracts/coverage From f95b4bf3b73ff9c2c29371961c1a49c13f0d3e6b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 18:22:45 +0000 Subject: [PATCH 11/30] chore(deps): update actions/checkout digest to 7739b9b --- .github/workflows/contracts-testing.yml | 2 +- .github/workflows/deploy-bots.yml | 2 +- .github/workflows/sentry-release.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/contracts-testing.yml b/.github/workflows/contracts-testing.yml index 29a5587bd..cfa7609d3 100644 --- a/.github/workflows/contracts-testing.yml +++ b/.github/workflows/contracts-testing.yml @@ -38,7 +38,7 @@ jobs: with: node-version: 16.x - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + - uses: actions/checkout@7739b9ba2efcda9dde65ad1e3c2dbe65b41dfba7 - name: Cache node modules uses: actions/cache@67b839edb68371cc5014f6cea11c9aa77238de78 diff --git a/.github/workflows/deploy-bots.yml b/.github/workflows/deploy-bots.yml index c8a4d9f21..3a21626b1 100644 --- a/.github/workflows/deploy-bots.yml +++ b/.github/workflows/deploy-bots.yml @@ -12,7 +12,7 @@ jobs: with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + - uses: actions/checkout@7739b9ba2efcda9dde65ad1e3c2dbe65b41dfba7 - uses: actions/setup-python@61a6322f88396a6271a6ee3565807d608ecaddd1 - uses: aws-actions/setup-sam@12a6719db503425e98edcc798b6779590a450e8f - uses: aws-actions/configure-aws-credentials@5fd3084fc36e372ff1fff382a39b10d03659f355 diff --git a/.github/workflows/sentry-release.yml b/.github/workflows/sentry-release.yml index 7cd838994..0586ae221 100644 --- a/.github/workflows/sentry-release.yml +++ b/.github/workflows/sentry-release.yml @@ -29,7 +29,7 @@ jobs: sentry.io:443 54.185.253.63:443 - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + - uses: actions/checkout@7739b9ba2efcda9dde65ad1e3c2dbe65b41dfba7 - name: Cache node modules uses: actions/cache@67b839edb68371cc5014f6cea11c9aa77238de78 From 6c0803dc3f6bd593ab5549a29b5aeb8b900001ff Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 18:22:49 +0000 Subject: [PATCH 12/30] chore(deps): update actions/setup-node digest to 5e21ff4 --- .github/workflows/contracts-testing.yml | 2 +- .github/workflows/sentry-release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/contracts-testing.yml b/.github/workflows/contracts-testing.yml index cfa7609d3..73ca1da7f 100644 --- a/.github/workflows/contracts-testing.yml +++ b/.github/workflows/contracts-testing.yml @@ -34,7 +34,7 @@ jobs: 54.185.253.63:443 - name: Setup Node.js environment - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c + uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d with: node-version: 16.x diff --git a/.github/workflows/sentry-release.yml b/.github/workflows/sentry-release.yml index 0586ae221..b87783381 100644 --- a/.github/workflows/sentry-release.yml +++ b/.github/workflows/sentry-release.yml @@ -45,7 +45,7 @@ jobs: ${{ runner.os }}-build-${{ secrets.CACHE_VERSION }}-${{ env.cache-name }}- - name: Set up Node.js - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c + uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d with: node-version: 16 From 6bd9e2590d245e8a1576a848dc86a1502a702038 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 18:22:57 +0000 Subject: [PATCH 13/30] chore(deps): update aws-actions/configure-aws-credentials digest to 131c7b6 --- .github/workflows/deploy-bots.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-bots.yml b/.github/workflows/deploy-bots.yml index 3a21626b1..7a0705675 100644 --- a/.github/workflows/deploy-bots.yml +++ b/.github/workflows/deploy-bots.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/checkout@7739b9ba2efcda9dde65ad1e3c2dbe65b41dfba7 - uses: actions/setup-python@61a6322f88396a6271a6ee3565807d608ecaddd1 - uses: aws-actions/setup-sam@12a6719db503425e98edcc798b6779590a450e8f - - uses: aws-actions/configure-aws-credentials@5fd3084fc36e372ff1fff382a39b10d03659f355 + - uses: aws-actions/configure-aws-credentials@131c7b6fd10c0d7f36e1e49650b241d91ee327b9 with: aws-access-key-id: ${{ secrets.STAGING_AWS_ACCESS_KEY }} aws-secret-access-key: ${{ secrets.STAGING_AWS_SECRET_KEY }} From 1a42737ce135417593ec10b13220072ef7aaf754 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 18:23:12 +0000 Subject: [PATCH 14/30] chore(deps): bump actions/dependency-review-action from 3.0.7 to 3.0.8 Bumps [actions/dependency-review-action](https://github.com/actions/dependency-review-action) from 3.0.7 to 3.0.8. - [Release notes](https://github.com/actions/dependency-review-action/releases) - [Commits](https://github.com/actions/dependency-review-action/compare/7d90b4f05fea31dde1c4a1fb3fa787e197ea93ab...f6fff72a3217f580d5afd49a46826795305b63c7) --- updated-dependencies: - dependency-name: actions/dependency-review-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/dependency-review.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index cd4ae1eb1..e2d45d0f3 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -33,7 +33,7 @@ jobs: uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - name: 'Dependency Review' - uses: actions/dependency-review-action@7d90b4f05fea31dde1c4a1fb3fa787e197ea93ab # v3.0.7 + uses: actions/dependency-review-action@f6fff72a3217f580d5afd49a46826795305b63c7 # v3.0.8 with: base-ref: ${{ github.event.pull_request.base.sha || 'dev' }} head-ref: ${{ github.event.pull_request.head.sha || github.ref }} From 510528ecc12561267db6caf933df714ddbdd91d5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 18:23:06 +0000 Subject: [PATCH 15/30] chore(deps): bump actions/cache Bumps [actions/cache](https://github.com/actions/cache) from 67b839edb68371cc5014f6cea11c9aa77238de78 to f7ebb81a3f195b4fb88dab7c14e2f7aff52045aa. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/67b839edb68371cc5014f6cea11c9aa77238de78...f7ebb81a3f195b4fb88dab7c14e2f7aff52045aa) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- .github/workflows/contracts-testing.yml | 2 +- .github/workflows/sentry-release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/contracts-testing.yml b/.github/workflows/contracts-testing.yml index 73ca1da7f..374a3991b 100644 --- a/.github/workflows/contracts-testing.yml +++ b/.github/workflows/contracts-testing.yml @@ -41,7 +41,7 @@ jobs: - uses: actions/checkout@7739b9ba2efcda9dde65ad1e3c2dbe65b41dfba7 - name: Cache node modules - uses: actions/cache@67b839edb68371cc5014f6cea11c9aa77238de78 + uses: actions/cache@f7ebb81a3f195b4fb88dab7c14e2f7aff52045aa env: cache-name: cache-node-modules with: diff --git a/.github/workflows/sentry-release.yml b/.github/workflows/sentry-release.yml index b87783381..2249fc87f 100644 --- a/.github/workflows/sentry-release.yml +++ b/.github/workflows/sentry-release.yml @@ -32,7 +32,7 @@ jobs: - uses: actions/checkout@7739b9ba2efcda9dde65ad1e3c2dbe65b41dfba7 - name: Cache node modules - uses: actions/cache@67b839edb68371cc5014f6cea11c9aa77238de78 + uses: actions/cache@f7ebb81a3f195b4fb88dab7c14e2f7aff52045aa env: cache-name: cache-node-modules with: From f58817461d40373d854c6ab761030da3cf890dba Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Tue, 22 Aug 2023 21:58:23 +0200 Subject: [PATCH 16/30] chore: keeping the linters happy --- .github/workflows/codeql.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 169a1f627..eb1501a37 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -14,6 +14,9 @@ on: schedule: - cron: '26 1 * * 6' +permissions: + actions: read + jobs: codeql-advanced-analysis: name: Analyze From 88d40d2758e8f92a705e47304c601b42671e8253 Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Wed, 23 Aug 2023 04:02:31 +0800 Subject: [PATCH 17/30] chore: minor tweaks --- .github/workflows/codeql.yml | 10 +++++++--- scripts/cancel-all-netlify-builds.sh | 11 +++++------ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index eb1501a37..3ec5a25cb 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -2,6 +2,9 @@ name: "CodeQL Advanced" on: merge_group: + branches: + - master + - dev push: branches: - master @@ -20,8 +23,8 @@ permissions: jobs: codeql-advanced-analysis: name: Analyze - runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} - timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }} + runs-on: ubuntu-latest + timeout-minutes: 360 permissions: actions: read contents: read @@ -30,7 +33,8 @@ jobs: strategy: fail-fast: false matrix: - language: [ "javascript"] + language: + - javascript steps: - name: Harden Runner diff --git a/scripts/cancel-all-netlify-builds.sh b/scripts/cancel-all-netlify-builds.sh index 6dabd3120..f9f923069 100755 --- a/scripts/cancel-all-netlify-builds.sh +++ b/scripts/cancel-all-netlify-builds.sh @@ -1,9 +1,5 @@ #!/usr/bin/env bash -# netlify api listSites | jq '. | map([.name, .id])' -v2Site="86d94ae8-f655-46a4-a859-d68696173f3a" -v2ContractsSite="dd8bc215-e054-407f-92ef-d61511720928" - function cancelSiteDeploy() #sideId { local sideId=$1 @@ -16,10 +12,13 @@ function cancelSiteDeploy() #sideId continue; fi echo "Cancelling build for $name $branch" - echo netlify api cancelSiteDeploy -d '{ "deploy_id": "'$(jq -r .id <<< $build)'"}' - echo + netlify api cancelSiteDeploy -d '{ "deploy_id": "'$(jq -r .id <<< $build)'"}' > /dev/null done } +# netlify api listSites | jq '. | map([.name, .id])' +v2Site="86d94ae8-f655-46a4-a859-d68696173f3a" +v2ContractsSite="dd8bc215-e054-407f-92ef-d61511720928" + cancelSiteDeploy $v2Site cancelSiteDeploy $v2ContractsSite From 14dff158e41182f3ef7e60a7c419aca296a763ef Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Wed, 23 Aug 2023 04:24:45 +0800 Subject: [PATCH 18/30] chore: skip contracts testing when unrelated workspaces are modified --- .github/workflows/contracts-testing.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/contracts-testing.yml b/.github/workflows/contracts-testing.yml index 374a3991b..f17e1e4ab 100644 --- a/.github/workflows/contracts-testing.yml +++ b/.github/workflows/contracts-testing.yml @@ -6,9 +6,20 @@ on: push: branches: - master + - dev + paths-ignore: + - "kleros-sdk/**" + - "services/**" + - "subgraph/**" + - "web/**" pull_request: branches: - "*" + paths-ignore: + - "kleros-sdk/**" + - "services/**" + - "subgraph/**" + - "web/**" permissions: # added using https://github.com/step-security/secure-workflows contents: read From 5d348d6984e22974b8893839b0222181016f2f22 Mon Sep 17 00:00:00 2001 From: marino <102478601+kemuru@users.noreply.github.com> Date: Mon, 21 Aug 2023 12:39:30 +0200 Subject: [PATCH 19/30] feat(web): improve court policy display --- web/src/pages/Cases/CaseDetails/Overview.tsx | 2 +- web/src/pages/Courts/CourtDetails/Description.tsx | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/web/src/pages/Cases/CaseDetails/Overview.tsx b/web/src/pages/Cases/CaseDetails/Overview.tsx index 569f9d4a4..49a3e7015 100644 --- a/web/src/pages/Cases/CaseDetails/Overview.tsx +++ b/web/src/pages/Cases/CaseDetails/Overview.tsx @@ -138,7 +138,7 @@ const Overview: React.FC = ({ arbitrable, courtID, currentPeriodIndex )} {courtPolicy && ( - + Court Policy diff --git a/web/src/pages/Courts/CourtDetails/Description.tsx b/web/src/pages/Courts/CourtDetails/Description.tsx index 8326430b0..86599aa86 100644 --- a/web/src/pages/Courts/CourtDetails/Description.tsx +++ b/web/src/pages/Courts/CourtDetails/Description.tsx @@ -62,8 +62,21 @@ const Description: React.FC = () => { const filteredTabs = TABS.filter(({ isVisible }) => isVisible(policy)); + const location = useLocation(); + const queryParams = new URLSearchParams(location.search); + const scrollToSection = queryParams.get("section"); + + useEffect(() => { + if (scrollToSection === "description") { + const element = document.getElementById(scrollToSection); + if (element) { + element.scrollIntoView({ behavior: "smooth" }); + } + } + }, [scrollToSection]); + return ( - + Date: Wed, 23 Aug 2023 04:15:59 +0800 Subject: [PATCH 20/30] chore: open the court description in the same tab --- web/src/pages/Cases/CaseDetails/Overview.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/pages/Cases/CaseDetails/Overview.tsx b/web/src/pages/Cases/CaseDetails/Overview.tsx index 49a3e7015..9ef42e9d1 100644 --- a/web/src/pages/Cases/CaseDetails/Overview.tsx +++ b/web/src/pages/Cases/CaseDetails/Overview.tsx @@ -138,7 +138,7 @@ const Overview: React.FC = ({ arbitrable, courtID, currentPeriodIndex )} {courtPolicy && ( - + Court Policy From 53bc94946272ad0b3eafd0c4e819897840f8127e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 18 Aug 2023 10:22:46 +0000 Subject: [PATCH 21/30] chore(deps-dev): bump typechain from 8.2.0 to 8.3.1 Bumps [typechain](https://github.com/ethereum-ts/Typechain) from 8.2.0 to 8.3.1. - [Release notes](https://github.com/ethereum-ts/Typechain/releases) - [Commits](https://github.com/ethereum-ts/Typechain/compare/typechain@8.2.0...typechain@8.3.1) --- updated-dependencies: - dependency-name: typechain dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- contracts/package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/contracts/package.json b/contracts/package.json index be24cbb53..2bac986af 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -75,7 +75,7 @@ "solhint-plugin-prettier": "^0.0.5", "solidity-coverage": "0.8.2", "ts-node": "^10.9.1", - "typechain": "^8.2.0", + "typechain": "^8.3.1", "typescript": "^4.9.5" }, "dependencies": { diff --git a/yarn.lock b/yarn.lock index 8e5154009..3447b0119 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5188,7 +5188,7 @@ __metadata: solhint-plugin-prettier: ^0.0.5 solidity-coverage: 0.8.2 ts-node: ^10.9.1 - typechain: ^8.2.0 + typechain: ^8.3.1 typescript: ^4.9.5 languageName: unknown linkType: soft @@ -30001,9 +30001,9 @@ __metadata: languageName: node linkType: hard -"typechain@npm:^8.2.0": - version: 8.2.0 - resolution: "typechain@npm:8.2.0" +"typechain@npm:^8.3.1": + version: 8.3.1 + resolution: "typechain@npm:8.3.1" dependencies: "@types/prettier": ^2.1.1 debug: ^4.3.1 @@ -30019,7 +30019,7 @@ __metadata: typescript: ">=4.3.0" bin: typechain: dist/cli/cli.js - checksum: 8591d333fda0e31172f4d9e0a8e23c24eee446ce3719989bd48e63f84a975917bb2f853ecaf616193ad7f3964e7c42fe3b1fc5abb69f4446794f465505f6c1a7 + checksum: c1e11ab1452d0c83be0c34a8b900b156b0c6654b95f7e7bb18dd98c0decd6009ffa1316e393f4e8def187af1bea3e931a13503815cc37155c0c945b7ae5b5215 languageName: node linkType: hard From e9e07739167177db0e80be597e839a8f827ea93d Mon Sep 17 00:00:00 2001 From: marino <102478601+kemuru@users.noreply.github.com> Date: Wed, 23 Aug 2023 10:52:52 +0200 Subject: [PATCH 22/30] fix(web): round decimals in stats --- web/src/pages/Courts/CourtDetails/Stats.tsx | 7 ++++--- web/src/pages/Home/CourtOverview/Stats.tsx | 7 ++++--- web/src/utils/roundDecimals.ts | 5 +++++ 3 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 web/src/utils/roundDecimals.ts diff --git a/web/src/pages/Courts/CourtDetails/Stats.tsx b/web/src/pages/Courts/CourtDetails/Stats.tsx index 07f44a203..a8c1596df 100644 --- a/web/src/pages/Courts/CourtDetails/Stats.tsx +++ b/web/src/pages/Courts/CourtDetails/Stats.tsx @@ -8,6 +8,7 @@ import StatDisplay, { IStatDisplay } from "components/StatDisplay"; import BalanceIcon from "svgs/icons/law-balance.svg"; import MinStake from "svgs/icons/min-stake.svg"; import { commify } from "utils/commify"; +import { roundDecimals } from "utils/roundDecimals"; import VoteStake from "svgs/icons/vote-stake.svg"; import PNKIcon from "svgs/icons/pnk.svg"; import PNKRedistributedIcon from "svgs/icons/redistributed-pnk.svg"; @@ -61,7 +62,7 @@ const stats: IStat[] = [ { title: "PNK Staked", coinId: 0, - getText: (data) => commify(formatUnits(data?.stake, 18)), + getText: (data) => commify(roundDecimals(formatUnits(data?.stake, 18), 0)), getSubtext: (data, coinPrice) => (parseInt(formatUnits(data?.stake, 18)) * (coinPrice ?? 0)).toFixed(2).toString() + "$", color: "purple", @@ -84,7 +85,7 @@ const stats: IStat[] = [ { title: "ETH paid to Jurors", coinId: 1, - getText: (data) => commify(formatEther(BigInt(data?.paidETH))), + getText: (data) => commify(roundDecimals(formatEther(BigInt(data?.paidETH)), 4)), getSubtext: (data, coinPrice) => (Number(formatUnits(data?.paidETH, 18)) * (coinPrice ?? 0)).toFixed(2).toString() + "$", color: "blue", @@ -93,7 +94,7 @@ const stats: IStat[] = [ { title: "PNK redistributed", coinId: 0, - getText: (data) => commify(formatUnits(data?.paidPNK, 18)), + getText: (data) => commify(roundDecimals(formatUnits(data?.paidPNK, 18), 0)), getSubtext: (data, coinPrice) => (parseInt(formatUnits(data?.paidPNK, 18)) * (coinPrice ?? 0)).toFixed(2).toString() + "$", color: "purple", diff --git a/web/src/pages/Home/CourtOverview/Stats.tsx b/web/src/pages/Home/CourtOverview/Stats.tsx index 92bb774dd..52871a1f0 100644 --- a/web/src/pages/Home/CourtOverview/Stats.tsx +++ b/web/src/pages/Home/CourtOverview/Stats.tsx @@ -11,6 +11,7 @@ import BalanceIcon from "svgs/icons/law-balance.svg"; import { KLEROS_CONTRACT_ADDRESS, WETH_CONTRACT_ADDRESS } from "src/consts/index"; import { commify } from "utils/commify"; import { isUndefined } from "utils/index"; +import { roundDecimals } from "utils/roundDecimals"; import { useHomePageContext, HomePageQuery, HomePageQueryDataPoints } from "hooks/useHomePageContext"; import { useCoinPrice } from "hooks/useCoinPrice"; @@ -39,7 +40,7 @@ const stats: IStat[] = [ { title: "PNK staked", coinId: 0, - getText: (counters) => commify(formatUnits(getLastOrZero(counters, "stakedPNK"), 18)), + getText: (counters) => commify(roundDecimals(formatUnits(getLastOrZero(counters, "stakedPNK"), 18), 0)), getSubtext: (counters, coinPrice) => (parseInt(formatUnits(getLastOrZero(counters, "stakedPNK"), 18)) * (coinPrice ?? 0)).toFixed(2).toString() + "$", color: "purple", @@ -48,7 +49,7 @@ const stats: IStat[] = [ { title: "ETH Paid to jurors", coinId: 1, - getText: (counters) => commify(formatEther(getLastOrZero(counters, "paidETH"))), + getText: (counters) => commify(roundDecimals(formatEther(getLastOrZero(counters, "paidETH")), 4)), getSubtext: (counters, coinPrice) => (Number(formatUnits(getLastOrZero(counters, "paidETH"), 18)) * (coinPrice ?? 0)).toFixed(2).toString() + "$", color: "blue", @@ -57,7 +58,7 @@ const stats: IStat[] = [ { title: "PNK redistributed", coinId: 0, - getText: (counters) => commify(formatUnits(getLastOrZero(counters, "redistributedPNK"), 18)), + getText: (counters) => commify(roundDecimals(formatUnits(getLastOrZero(counters, "redistributedPNK"), 18), 0)), getSubtext: (counters, coinPrice) => (parseInt(formatUnits(getLastOrZero(counters, "redistributedPNK"), 18)) * (coinPrice ?? 0)) .toFixed(2) diff --git a/web/src/utils/roundDecimals.ts b/web/src/utils/roundDecimals.ts new file mode 100644 index 000000000..25ec44d06 --- /dev/null +++ b/web/src/utils/roundDecimals.ts @@ -0,0 +1,5 @@ +export const roundDecimals = (value: string, decimals: number): string => { + const numberValue = parseFloat(value); + const roundedValue = Math.round(numberValue * Math.pow(10, decimals)) / Math.pow(10, decimals); + return roundedValue.toString(); +}; From 330a6eae8141cadca58e3ff2fad8ae91c7684d17 Mon Sep 17 00:00:00 2001 From: marino <102478601+kemuru@users.noreply.github.com> Date: Wed, 23 Aug 2023 11:53:24 +0200 Subject: [PATCH 23/30] refactor(web): switch to tofixed function -S --- web/src/pages/Courts/CourtDetails/Stats.tsx | 7 +++---- web/src/pages/Home/CourtOverview/Stats.tsx | 7 +++---- web/src/utils/roundDecimals.ts | 5 ----- 3 files changed, 6 insertions(+), 13 deletions(-) delete mode 100644 web/src/utils/roundDecimals.ts diff --git a/web/src/pages/Courts/CourtDetails/Stats.tsx b/web/src/pages/Courts/CourtDetails/Stats.tsx index a8c1596df..5c671c8b3 100644 --- a/web/src/pages/Courts/CourtDetails/Stats.tsx +++ b/web/src/pages/Courts/CourtDetails/Stats.tsx @@ -8,7 +8,6 @@ import StatDisplay, { IStatDisplay } from "components/StatDisplay"; import BalanceIcon from "svgs/icons/law-balance.svg"; import MinStake from "svgs/icons/min-stake.svg"; import { commify } from "utils/commify"; -import { roundDecimals } from "utils/roundDecimals"; import VoteStake from "svgs/icons/vote-stake.svg"; import PNKIcon from "svgs/icons/pnk.svg"; import PNKRedistributedIcon from "svgs/icons/redistributed-pnk.svg"; @@ -62,7 +61,7 @@ const stats: IStat[] = [ { title: "PNK Staked", coinId: 0, - getText: (data) => commify(roundDecimals(formatUnits(data?.stake, 18), 0)), + getText: (data) => commify(Number(formatUnits(data?.stake, 18)).toFixed(0)), getSubtext: (data, coinPrice) => (parseInt(formatUnits(data?.stake, 18)) * (coinPrice ?? 0)).toFixed(2).toString() + "$", color: "purple", @@ -85,7 +84,7 @@ const stats: IStat[] = [ { title: "ETH paid to Jurors", coinId: 1, - getText: (data) => commify(roundDecimals(formatEther(BigInt(data?.paidETH)), 4)), + getText: (data) => commify(Number(formatEther(BigInt(data?.paidETH))).toFixed(4)), getSubtext: (data, coinPrice) => (Number(formatUnits(data?.paidETH, 18)) * (coinPrice ?? 0)).toFixed(2).toString() + "$", color: "blue", @@ -94,7 +93,7 @@ const stats: IStat[] = [ { title: "PNK redistributed", coinId: 0, - getText: (data) => commify(roundDecimals(formatUnits(data?.paidPNK, 18), 0)), + getText: (data) => commify(Number(formatUnits(data?.paidPNK, 18)).toFixed(0)), getSubtext: (data, coinPrice) => (parseInt(formatUnits(data?.paidPNK, 18)) * (coinPrice ?? 0)).toFixed(2).toString() + "$", color: "purple", diff --git a/web/src/pages/Home/CourtOverview/Stats.tsx b/web/src/pages/Home/CourtOverview/Stats.tsx index 52871a1f0..59b709111 100644 --- a/web/src/pages/Home/CourtOverview/Stats.tsx +++ b/web/src/pages/Home/CourtOverview/Stats.tsx @@ -11,7 +11,6 @@ import BalanceIcon from "svgs/icons/law-balance.svg"; import { KLEROS_CONTRACT_ADDRESS, WETH_CONTRACT_ADDRESS } from "src/consts/index"; import { commify } from "utils/commify"; import { isUndefined } from "utils/index"; -import { roundDecimals } from "utils/roundDecimals"; import { useHomePageContext, HomePageQuery, HomePageQueryDataPoints } from "hooks/useHomePageContext"; import { useCoinPrice } from "hooks/useCoinPrice"; @@ -40,7 +39,7 @@ const stats: IStat[] = [ { title: "PNK staked", coinId: 0, - getText: (counters) => commify(roundDecimals(formatUnits(getLastOrZero(counters, "stakedPNK"), 18), 0)), + getText: (counters) => commify(Number(formatUnits(getLastOrZero(counters, "stakedPNK"), 18)).toFixed(0)), getSubtext: (counters, coinPrice) => (parseInt(formatUnits(getLastOrZero(counters, "stakedPNK"), 18)) * (coinPrice ?? 0)).toFixed(2).toString() + "$", color: "purple", @@ -49,7 +48,7 @@ const stats: IStat[] = [ { title: "ETH Paid to jurors", coinId: 1, - getText: (counters) => commify(roundDecimals(formatEther(getLastOrZero(counters, "paidETH")), 4)), + getText: (counters) => commify(Number(formatEther(getLastOrZero(counters, "paidETH"))).toFixed(4)), getSubtext: (counters, coinPrice) => (Number(formatUnits(getLastOrZero(counters, "paidETH"), 18)) * (coinPrice ?? 0)).toFixed(2).toString() + "$", color: "blue", @@ -58,7 +57,7 @@ const stats: IStat[] = [ { title: "PNK redistributed", coinId: 0, - getText: (counters) => commify(roundDecimals(formatUnits(getLastOrZero(counters, "redistributedPNK"), 18), 0)), + getText: (counters) => commify(Number(formatUnits(getLastOrZero(counters, "redistributedPNK"), 18)).toFixed(0)), getSubtext: (counters, coinPrice) => (parseInt(formatUnits(getLastOrZero(counters, "redistributedPNK"), 18)) * (coinPrice ?? 0)) .toFixed(2) diff --git a/web/src/utils/roundDecimals.ts b/web/src/utils/roundDecimals.ts deleted file mode 100644 index 25ec44d06..000000000 --- a/web/src/utils/roundDecimals.ts +++ /dev/null @@ -1,5 +0,0 @@ -export const roundDecimals = (value: string, decimals: number): string => { - const numberValue = parseFloat(value); - const roundedValue = Math.round(numberValue * Math.pow(10, decimals)) / Math.pow(10, decimals); - return roundedValue.toString(); -}; From 05e8b49b46fd236d5681f047620959f8667a00e4 Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Thu, 24 Aug 2023 17:01:34 +0800 Subject: [PATCH 24/30] refactor: moved some formatting functions to utils --- cspell.json | 1 + web/src/pages/Courts/CourtDetails/Stats.tsx | 33 ++++++++------------- web/src/pages/Home/CourtOverview/Stats.tsx | 18 +++++------ web/src/utils/index.ts | 13 ++++++++ 4 files changed, 34 insertions(+), 31 deletions(-) diff --git a/cspell.json b/cspell.json index 7049b6d51..a1f4e8bf3 100644 --- a/cspell.json +++ b/cspell.json @@ -12,6 +12,7 @@ "arbitrum", "autorestart", "codegen", + "commify", "commitlint", "COOLDOWN", "datetime", diff --git a/web/src/pages/Courts/CourtDetails/Stats.tsx b/web/src/pages/Courts/CourtDetails/Stats.tsx index 5c671c8b3..a37a4c454 100644 --- a/web/src/pages/Courts/CourtDetails/Stats.tsx +++ b/web/src/pages/Courts/CourtDetails/Stats.tsx @@ -1,19 +1,17 @@ import React from "react"; import styled from "styled-components"; -import { formatUnits, formatEther } from "viem"; import { useParams } from "react-router-dom"; import { useCourtDetails, CourtDetailsQuery } from "queries/useCourtDetails"; -import { KLEROS_CONTRACT_ADDRESS, WETH_CONTRACT_ADDRESS } from "src/consts/index"; +import { useCoinPrice } from "hooks/useCoinPrice"; +import { KLEROS_CONTRACT_ADDRESS, WETH_CONTRACT_ADDRESS } from "consts/index"; +import { formatETH, formatPNK, formatUnitsWei, formatUSD, isUndefined } from "utils/index"; import StatDisplay, { IStatDisplay } from "components/StatDisplay"; import BalanceIcon from "svgs/icons/law-balance.svg"; import MinStake from "svgs/icons/min-stake.svg"; -import { commify } from "utils/commify"; import VoteStake from "svgs/icons/vote-stake.svg"; import PNKIcon from "svgs/icons/pnk.svg"; import PNKRedistributedIcon from "svgs/icons/redistributed-pnk.svg"; import EthereumIcon from "svgs/icons/ethereum.svg"; -import { useCoinPrice } from "hooks/useCoinPrice"; -import { isUndefined } from "utils/index"; const StyledCard = styled.div` width: auto; @@ -36,18 +34,16 @@ const stats: IStat[] = [ { title: "Min Stake", coinId: 0, - getText: (data) => commify(formatUnits(data?.minStake, 18)), - getSubtext: (data, coinPrice) => - (parseInt(formatUnits(data?.minStake, 18)) * (coinPrice ?? 0)).toFixed(2).toString() + "$", + getText: (data) => formatPNK(data?.minStake), + getSubtext: (data, coinPrice) => formatUSD(Number(formatUnitsWei(data?.minStake)) * (coinPrice ?? 0)), color: "purple", icon: MinStake, }, { title: "Vote Stake", coinId: 0, - getText: (data) => commify(formatUnits(data?.minStake, 18)), - getSubtext: (data, coinPrice) => - (parseInt(formatUnits(data?.minStake, 18)) * (coinPrice ?? 0)).toFixed(2).toString() + "$", + getText: (data) => formatPNK(data?.minStake), + getSubtext: (data, coinPrice) => formatUSD(Number(formatUnitsWei(data?.minStake)) * (coinPrice ?? 0)), color: "purple", icon: VoteStake, }, @@ -61,9 +57,8 @@ const stats: IStat[] = [ { title: "PNK Staked", coinId: 0, - getText: (data) => commify(Number(formatUnits(data?.stake, 18)).toFixed(0)), - getSubtext: (data, coinPrice) => - (parseInt(formatUnits(data?.stake, 18)) * (coinPrice ?? 0)).toFixed(2).toString() + "$", + getText: (data) => formatPNK(data?.stake), + getSubtext: (data, coinPrice) => formatUSD(Number(formatUnitsWei(data?.stake)) * (coinPrice ?? 0)), color: "purple", icon: PNKIcon, }, @@ -84,18 +79,16 @@ const stats: IStat[] = [ { title: "ETH paid to Jurors", coinId: 1, - getText: (data) => commify(Number(formatEther(BigInt(data?.paidETH))).toFixed(4)), - getSubtext: (data, coinPrice) => - (Number(formatUnits(data?.paidETH, 18)) * (coinPrice ?? 0)).toFixed(2).toString() + "$", + getText: (data) => formatETH(data?.paidETH), + getSubtext: (data, coinPrice) => formatUSD(Number(formatUnitsWei(data?.paidETH)) * (coinPrice ?? 0)), color: "blue", icon: EthereumIcon, }, { title: "PNK redistributed", coinId: 0, - getText: (data) => commify(Number(formatUnits(data?.paidPNK, 18)).toFixed(0)), - getSubtext: (data, coinPrice) => - (parseInt(formatUnits(data?.paidPNK, 18)) * (coinPrice ?? 0)).toFixed(2).toString() + "$", + getText: (data) => formatPNK(data?.paidPNK, 18), + getSubtext: (data, coinPrice) => formatUSD(Number(formatUnitsWei(data?.paidPNK)) * (coinPrice ?? 0)), color: "purple", icon: PNKRedistributedIcon, }, diff --git a/web/src/pages/Home/CourtOverview/Stats.tsx b/web/src/pages/Home/CourtOverview/Stats.tsx index 59b709111..1529031bb 100644 --- a/web/src/pages/Home/CourtOverview/Stats.tsx +++ b/web/src/pages/Home/CourtOverview/Stats.tsx @@ -1,6 +1,5 @@ import React from "react"; import styled from "styled-components"; -import { formatEther, formatUnits } from "viem"; import { Card } from "@kleros/ui-components-library"; import StatDisplay, { IStatDisplay } from "components/StatDisplay"; import PNKIcon from "svgs/icons/pnk.svg"; @@ -9,8 +8,7 @@ import PNKRedistributedIcon from "svgs/icons/redistributed-pnk.svg"; import JurorIcon from "svgs/icons/user.svg"; import BalanceIcon from "svgs/icons/law-balance.svg"; import { KLEROS_CONTRACT_ADDRESS, WETH_CONTRACT_ADDRESS } from "src/consts/index"; -import { commify } from "utils/commify"; -import { isUndefined } from "utils/index"; +import { formatETH, formatPNK, formatUnitsWei, formatUSD, isUndefined } from "utils/index"; import { useHomePageContext, HomePageQuery, HomePageQueryDataPoints } from "hooks/useHomePageContext"; import { useCoinPrice } from "hooks/useCoinPrice"; @@ -39,29 +37,27 @@ const stats: IStat[] = [ { title: "PNK staked", coinId: 0, - getText: (counters) => commify(Number(formatUnits(getLastOrZero(counters, "stakedPNK"), 18)).toFixed(0)), + getText: (counters) => formatPNK(getLastOrZero(counters, "stakedPNK")), getSubtext: (counters, coinPrice) => - (parseInt(formatUnits(getLastOrZero(counters, "stakedPNK"), 18)) * (coinPrice ?? 0)).toFixed(2).toString() + "$", + formatUSD(Number(formatUnitsWei(getLastOrZero(counters, "stakedPNK"))) * (coinPrice ?? 0)), color: "purple", icon: PNKIcon, }, { title: "ETH Paid to jurors", coinId: 1, - getText: (counters) => commify(Number(formatEther(getLastOrZero(counters, "paidETH"))).toFixed(4)), + getText: (counters) => formatETH(getLastOrZero(counters, "paidETH")), getSubtext: (counters, coinPrice) => - (Number(formatUnits(getLastOrZero(counters, "paidETH"), 18)) * (coinPrice ?? 0)).toFixed(2).toString() + "$", + formatUSD(Number(formatUnitsWei(getLastOrZero(counters, "paidETH"))) * (coinPrice ?? 0)), color: "blue", icon: EthereumIcon, }, { title: "PNK redistributed", coinId: 0, - getText: (counters) => commify(Number(formatUnits(getLastOrZero(counters, "redistributedPNK"), 18)).toFixed(0)), + getText: (counters) => formatPNK(getLastOrZero(counters, "redistributedPNK")), getSubtext: (counters, coinPrice) => - (parseInt(formatUnits(getLastOrZero(counters, "redistributedPNK"), 18)) * (coinPrice ?? 0)) - .toFixed(2) - .toString() + "$", + formatUSD(Number(formatUnitsWei(getLastOrZero(counters, "redistributedPNK"))) * (coinPrice ?? 0)), color: "purple", icon: PNKRedistributedIcon, }, diff --git a/web/src/utils/index.ts b/web/src/utils/index.ts index 31059cf6e..0d37380be 100644 --- a/web/src/utils/index.ts +++ b/web/src/utils/index.ts @@ -1 +1,14 @@ +import { formatEther, formatUnits } from "viem"; +import { commify } from "./commify"; + export const isUndefined = (maybeObject: any): maybeObject is undefined => typeof maybeObject === "undefined"; + +export const formatUnitsWei = (value: bigint) => formatUnits(value, 18); + +export const formatPNK = (value: bigint, fractionDigits = 0) => + commify(Number(formatUnitsWei(value)).toFixed(fractionDigits)); + +export const formatETH = (value: bigint, fractionDigits = 4) => + commify(Number(formatEther(value)).toFixed(fractionDigits)); + +export const formatUSD = (value: number, fractionDigits = 2) => "$" + commify(Number(value).toFixed(fractionDigits)); From 7d5c8ecd85a715f0aa43b12dd079347250b011a2 Mon Sep 17 00:00:00 2001 From: marino <102478601+kemuru@users.noreply.github.com> Date: Wed, 23 Aug 2023 00:20:02 +0200 Subject: [PATCH 25/30] feat(web): add skeletons to improve UX, modularize code --- web/src/components/DisputeCard/index.tsx | 8 +--- web/src/components/StatDisplay.tsx | 4 +- web/src/components/StyledSkeleton.tsx | 6 +++ .../Appeal/Classic/Options/index.tsx | 3 +- web/src/pages/Cases/CaseDetails/Overview.tsx | 4 +- web/src/pages/Cases/CaseDetails/Timeline.tsx | 5 ++- .../pages/Courts/CourtDetails/Description.tsx | 3 +- web/src/pages/Courts/CourtDetails/Stats.tsx | 12 +++--- web/src/pages/Courts/CourtDetails/index.tsx | 17 +++++++-- web/src/pages/Courts/TopSearch.tsx | 19 +++------- web/src/pages/Dashboard/Courts/index.tsx | 17 ++++----- .../Dashboard/JurorInfo/JurorRewards.tsx | 37 +++++++++---------- .../Dashboard/JurorInfo/TokenRewards.tsx | 13 ++++--- web/src/pages/Dashboard/index.tsx | 14 +++---- web/src/pages/DisputeTemplateView.tsx | 4 +- web/src/pages/Home/CourtOverview/Chart.tsx | 3 +- web/src/pages/Home/CourtOverview/Stats.tsx | 13 ++++--- web/src/pages/Home/LatestCases.tsx | 7 ++-- web/src/utils/calculateSubtextRender.tsx | 18 +++++++++ 19 files changed, 115 insertions(+), 92 deletions(-) create mode 100644 web/src/components/StyledSkeleton.tsx create mode 100644 web/src/utils/calculateSubtextRender.tsx diff --git a/web/src/components/DisputeCard/index.tsx b/web/src/components/DisputeCard/index.tsx index 5470894c3..2579d0130 100644 --- a/web/src/components/DisputeCard/index.tsx +++ b/web/src/components/DisputeCard/index.tsx @@ -2,7 +2,7 @@ import React from "react"; import styled from "styled-components"; import { useNavigate } from "react-router-dom"; import { formatEther } from "viem"; -import Skeleton from "react-loading-skeleton"; +import { StyledSkeleton } from "components/StyledSkeleton"; import { Card } from "@kleros/ui-components-library"; import { Periods } from "consts/periods"; import { CasesPageQuery } from "queries/useCasesQuery"; @@ -17,10 +17,6 @@ const StyledCard = styled(Card)` min-width: 312px; width: auto; height: 260px; - - .react-loading-skeleton { - z-index: 0; - } `; const Container = styled.div` @@ -58,7 +54,7 @@ const DisputeCard: React.FC = ({ : getPeriodEndTimestamp(lastPeriodChange, currentPeriodIndex, court.timesPerPeriod); const { data: disputeTemplate } = useDisputeTemplate(id, arbitrated.id as `0x${string}`); const title = isUndefined(disputeTemplate) ? ( - + ) : ( disputeTemplate?.title ?? "The dispute's template is not correct please vote refuse to arbitrate" ); diff --git a/web/src/components/StatDisplay.tsx b/web/src/components/StatDisplay.tsx index b6f2e4b90..67ef929ff 100644 --- a/web/src/components/StatDisplay.tsx +++ b/web/src/components/StatDisplay.tsx @@ -36,8 +36,8 @@ const createPair = (iconColor: string, backgroundColor: string) => ({ export interface IStatDisplay { title: string; - text: string; - subtext: string; + text: string | React.ReactNode; + subtext: string | React.ReactNode; icon: React.FunctionComponent>; color: "red" | "orange" | "green" | "blue" | "purple"; } diff --git a/web/src/components/StyledSkeleton.tsx b/web/src/components/StyledSkeleton.tsx new file mode 100644 index 000000000..f49bf8c14 --- /dev/null +++ b/web/src/components/StyledSkeleton.tsx @@ -0,0 +1,6 @@ +import styled from "styled-components"; +import Skeleton from "react-loading-skeleton"; + +export const StyledSkeleton = styled(Skeleton)` + z-index: 0; +`; diff --git a/web/src/pages/Cases/CaseDetails/Appeal/Classic/Options/index.tsx b/web/src/pages/Cases/CaseDetails/Appeal/Classic/Options/index.tsx index 3fca8d204..83219b2c1 100644 --- a/web/src/pages/Cases/CaseDetails/Appeal/Classic/Options/index.tsx +++ b/web/src/pages/Cases/CaseDetails/Appeal/Classic/Options/index.tsx @@ -1,6 +1,7 @@ import React from "react"; import styled from "styled-components"; import { useLoserSideCountdownContext } from "hooks/useClassicAppealContext"; +import { StyledSkeleton } from "components/StyledSkeleton"; import StageOne from "./StageOne"; import StageTwo from "./StageTwo"; import { isUndefined } from "utils/index"; @@ -14,7 +15,7 @@ const Options: React.FC = () => { return !isUndefined(loserSideCountdown) ? ( {loserSideCountdown > 0 ? : } ) : ( -

Loading...

+ ); }; diff --git a/web/src/pages/Cases/CaseDetails/Overview.tsx b/web/src/pages/Cases/CaseDetails/Overview.tsx index 9ef42e9d1..7de07014f 100644 --- a/web/src/pages/Cases/CaseDetails/Overview.tsx +++ b/web/src/pages/Cases/CaseDetails/Overview.tsx @@ -3,7 +3,6 @@ import styled from "styled-components"; import { useParams } from "react-router-dom"; import ReactMarkdown from "react-markdown"; import { formatEther } from "viem"; -import Skeleton from "react-loading-skeleton"; import { useDisputeDetailsQuery } from "queries/useDisputeDetailsQuery"; import { useDisputeTemplate } from "queries/useDisputeTemplate"; import { useCourtPolicy } from "queries/useCourtPolicy"; @@ -12,6 +11,7 @@ import { isUndefined } from "utils/index"; import { Periods } from "consts/periods"; import { IPFS_GATEWAY } from "consts/index"; import PolicyIcon from "svgs/icons/policy.svg"; +import { StyledSkeleton } from "components/StyledSkeleton"; import DisputeInfo from "components/DisputeCard/DisputeInfo"; import Verdict from "components/Verdict/index"; @@ -95,7 +95,7 @@ const Overview: React.FC = ({ arbitrable, courtID, currentPeriodIndex

{isUndefined(disputeTemplate) ? ( - + ) : ( disputeTemplate?.title ?? "The dispute's template is not correct please vote refuse to arbitrate" )} diff --git a/web/src/pages/Cases/CaseDetails/Timeline.tsx b/web/src/pages/Cases/CaseDetails/Timeline.tsx index 9f9b5d0b1..9fb621da0 100644 --- a/web/src/pages/Cases/CaseDetails/Timeline.tsx +++ b/web/src/pages/Cases/CaseDetails/Timeline.tsx @@ -3,6 +3,7 @@ import styled from "styled-components"; import { Periods } from "consts/periods"; import { DisputeDetailsQuery } from "queries/useDisputeDetailsQuery"; import { Box, Steps } from "@kleros/ui-components-library"; +import { StyledSkeleton } from "components/StyledSkeleton"; import { useCountdown } from "hooks/useCountdown"; import { secondsToDayHourMinute } from "utils/date"; @@ -46,7 +47,7 @@ const useTimeline = (dispute: DisputeDetailsQuery["dispute"], currentItemIndex: dispute?.court.timesPerPeriod ); const countdown = useCountdown(deadlineCurrentPeriod); - const getSubitems = (index: number): string[] => { + const getSubitems = (index: number): string[] | React.ReactNode[] => { if (typeof countdown !== "undefined" && dispute) { if (index === currentItemIndex && countdown === 0) { return ["Time's up!"]; @@ -60,7 +61,7 @@ const useTimeline = (dispute: DisputeDetailsQuery["dispute"], currentItemIndex: return [secondsToDayHourMinute(dispute?.court.timesPerPeriod[index])]; } } - return ["Loading..."]; + return []; }; return titles.map((title, i) => ({ title, diff --git a/web/src/pages/Courts/CourtDetails/Description.tsx b/web/src/pages/Courts/CourtDetails/Description.tsx index 86599aa86..c48ce3593 100644 --- a/web/src/pages/Courts/CourtDetails/Description.tsx +++ b/web/src/pages/Courts/CourtDetails/Description.tsx @@ -3,6 +3,7 @@ import styled from "styled-components"; import ReactMarkdown from "react-markdown"; import { Routes, Route, Navigate, useParams, useNavigate, useLocation } from "react-router-dom"; import { Tabs } from "@kleros/ui-components-library"; +import { StyledSkeleton } from "components/StyledSkeleton"; import { useCourtPolicy } from "queries/useCourtPolicy"; const Container = styled.div` @@ -101,7 +102,7 @@ const formatMarkdown = (markdown?: string) => markdown ? ( {typeof markdown === "string" ? markdown.replace(/\n/g, " \n") : markdown} ) : ( -

Loading...

+ ); export default Description; diff --git a/web/src/pages/Courts/CourtDetails/Stats.tsx b/web/src/pages/Courts/CourtDetails/Stats.tsx index a37a4c454..365b68da8 100644 --- a/web/src/pages/Courts/CourtDetails/Stats.tsx +++ b/web/src/pages/Courts/CourtDetails/Stats.tsx @@ -5,7 +5,9 @@ import { useCourtDetails, CourtDetailsQuery } from "queries/useCourtDetails"; import { useCoinPrice } from "hooks/useCoinPrice"; import { KLEROS_CONTRACT_ADDRESS, WETH_CONTRACT_ADDRESS } from "consts/index"; import { formatETH, formatPNK, formatUnitsWei, formatUSD, isUndefined } from "utils/index"; +import { calculateSubtextRender } from "utils/calculateSubtextRender"; import StatDisplay, { IStatDisplay } from "components/StatDisplay"; +import { StyledSkeleton } from "components/StyledSkeleton"; import BalanceIcon from "svgs/icons/law-balance.svg"; import MinStake from "svgs/icons/min-stake.svg"; import VoteStake from "svgs/icons/vote-stake.svg"; @@ -25,7 +27,7 @@ interface IStat { title: string; coinId?: number; getText: (data: CourtDetailsQuery["court"]) => string; - getSubtext: (data: CourtDetailsQuery["court"], coinPrice?: number) => string; + getSubtext?: (data: CourtDetailsQuery["court"], coinPrice?: number) => string; color: IStatDisplay["color"]; icon: React.FC>; } @@ -50,7 +52,6 @@ const stats: IStat[] = [ { title: "Active Jurors", getText: (data) => data?.numberStakedJurors, - getSubtext: () => "", color: "purple", icon: PNKRedistributedIcon, }, @@ -65,14 +66,12 @@ const stats: IStat[] = [ { title: "Cases", getText: (data) => data?.numberDisputes, - getSubtext: () => "", color: "orange", icon: BalanceIcon, }, { title: "In Progress", getText: (data) => data?.numberDisputes, - getSubtext: () => "", color: "orange", icon: BalanceIcon, }, @@ -108,12 +107,13 @@ const Stats = () => { {stats.map(({ title, coinId, getText, getSubtext, color, icon }, i) => { const coinPrice = !isUndefined(pricesData) ? pricesData[coinIdToAddress[coinId!]]?.price : undefined; + return ( } + subtext={calculateSubtextRender(data ? data.court : undefined, getSubtext, coinPrice)} /> ); })} diff --git a/web/src/pages/Courts/CourtDetails/index.tsx b/web/src/pages/Courts/CourtDetails/index.tsx index 95f626f37..07cb7fa55 100644 --- a/web/src/pages/Courts/CourtDetails/index.tsx +++ b/web/src/pages/Courts/CourtDetails/index.tsx @@ -10,6 +10,7 @@ import { DEFAULT_CHAIN } from "consts/chains"; import { PNK_FAUCET_CONTRACT_ADDRESS } from "consts/index"; import { wrapWithToast } from "utils/wrapWithToast"; import { isUndefined } from "utils/index"; +import { StyledSkeleton } from "components/StyledSkeleton"; import Stats from "./Stats"; import Description from "./Description"; import StakePanel from "./StakePanel"; @@ -35,6 +36,10 @@ const StyledBreadcrumb = styled(Breadcrumb)` margin: 0px 0 12px 0; `; +const StyledBreadcrumbSkeleton = styled.div` + margin-top: 16px; +`; + const CourtDetails: React.FC = () => { const { id } = useParams(); const [isSending, setIsSending] = useState(false); @@ -44,7 +49,7 @@ const CourtDetails: React.FC = () => { const { address } = useAccount(); const { data: claimed } = usePnkFaucetWithdrewAlready({ enabled: !isUndefined(address), - args: [address], + args: [address ?? "0x00"], watch: true, }); @@ -80,9 +85,15 @@ const CourtDetails: React.FC = () => { return ( -

{policy ? policy.name : "Loading..."}

+

{policy ? policy.name : }

- {items && } + {items ? ( + + ) : ( + + + + )} {chain?.id === DEFAULT_CHAIN && !claimed && (