diff --git a/web/package.json b/web/package.json
index 46d18bd06..a3f4b9b74 100644
--- a/web/package.json
+++ b/web/package.json
@@ -81,7 +81,7 @@
"@kleros/kleros-app": "^2.0.1",
"@kleros/kleros-sdk": "workspace:^",
"@kleros/kleros-v2-contracts": "workspace:^",
- "@kleros/ui-components-library": "^2.16.0",
+ "@kleros/ui-components-library": "^2.18.0",
"@lifi/wallet-management": "^3.4.6",
"@lifi/widget": "^3.12.3",
"@sentry/react": "^7.120.0",
diff --git a/web/src/assets/svgs/icons/star.svg b/web/src/assets/svgs/icons/star.svg
new file mode 100644
index 000000000..055e853c0
--- /dev/null
+++ b/web/src/assets/svgs/icons/star.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/web/src/components/CaseStarButton.tsx b/web/src/components/CaseStarButton.tsx
new file mode 100644
index 000000000..1ba097686
--- /dev/null
+++ b/web/src/components/CaseStarButton.tsx
@@ -0,0 +1,58 @@
+import React, { useMemo } from "react";
+import styled, { css } from "styled-components";
+
+import { Button, Tooltip } from "@kleros/ui-components-library";
+
+import Star from "svgs/icons/star.svg";
+
+import useIsDesktop from "hooks/useIsDesktop";
+import useStarredCases from "hooks/useStarredCases";
+
+const StyledButton = styled(Button)<{ starred: boolean }>`
+ background: none;
+ padding: 0 0 2px 0;
+
+ .button-svg {
+ width: 24px;
+ height: 24px;
+ margin: 0;
+ fill: none;
+
+ path {
+ stroke: ${({ theme }) => theme.secondaryPurple};
+ }
+ ${({ starred }) =>
+ starred &&
+ css`
+ fill: ${({ theme }) => theme.secondaryPurple};
+ `};
+ }
+
+ :hover {
+ background: none;
+ }
+`;
+
+const CaseStarButton: React.FC<{ id: string }> = ({ id }) => {
+ const { starredCases, starCase } = useStarredCases();
+ const isDesktop = useIsDesktop();
+ const starred = useMemo(() => Boolean(starredCases.has(id)), [id, starredCases]);
+ const text = starred ? "Remove from favorite" : "Add to favorite";
+ return (
+
+ {
+ e.stopPropagation();
+ starCase(id);
+ }}
+ />
+
+ );
+};
+
+export default CaseStarButton;
diff --git a/web/src/components/CasesDisplay/Filters.tsx b/web/src/components/CasesDisplay/Filters.tsx
index c7ae88513..cb417ac65 100644
--- a/web/src/components/CasesDisplay/Filters.tsx
+++ b/web/src/components/CasesDisplay/Filters.tsx
@@ -1,5 +1,7 @@
import React from "react";
-import styled, { useTheme } from "styled-components";
+import styled, { css, useTheme } from "styled-components";
+
+import { hoverShortTransitionTiming } from "styles/commonStyles";
import { useNavigate, useParams } from "react-router-dom";
@@ -19,15 +21,6 @@ const Container = styled.div`
width: fit-content;
`;
-const StyledGridIcon = styled(GridIcon)`
- cursor: pointer;
- transition: filter 0.2s ease;
- fill: ${({ theme }) => theme.primaryBlue};
- width: 16px;
- height: 16px;
- overflow: hidden;
-`;
-
const IconsContainer = styled.div`
display: flex;
justify-content: center;
@@ -35,13 +28,25 @@ const IconsContainer = styled.div`
gap: 4px;
`;
-const StyledListIcon = styled(ListIcon)`
+const BaseIconStyles = css`
+ ${hoverShortTransitionTiming}
cursor: pointer;
- transition: filter 0.2s ease;
fill: ${({ theme }) => theme.primaryBlue};
width: 16px;
height: 16px;
overflow: hidden;
+
+ :hover {
+ fill: ${({ theme }) => theme.secondaryBlue};
+ }
+`;
+
+const StyledGridIcon = styled(GridIcon)`
+ ${BaseIconStyles}
+`;
+
+const StyledListIcon = styled(ListIcon)`
+ ${BaseIconStyles}
`;
const Filters: React.FC = () => {
diff --git a/web/src/components/CasesDisplay/Search.tsx b/web/src/components/CasesDisplay/Search.tsx
index 6d1d265e3..2179df17f 100644
--- a/web/src/components/CasesDisplay/Search.tsx
+++ b/web/src/components/CasesDisplay/Search.tsx
@@ -18,14 +18,12 @@ import { responsiveSize } from "styles/responsiveSize";
const Container = styled.div`
display: flex;
flex-direction: column;
- gap: 4px;
+ gap: ${responsiveSize(8, 16)};
${landscapeStyle(
- () =>
- css`
- flex-direction: row;
- gap: ${responsiveSize(4, 22)};
- `
+ () => css`
+ flex-direction: row;
+ `
)}
`;
diff --git a/web/src/components/CasesDisplay/StatsAndFilters.tsx b/web/src/components/CasesDisplay/StatsAndFilters.tsx
index 51a04d7a5..78dd78ee5 100644
--- a/web/src/components/CasesDisplay/StatsAndFilters.tsx
+++ b/web/src/components/CasesDisplay/StatsAndFilters.tsx
@@ -1,6 +1,8 @@
import React from "react";
import styled from "styled-components";
+import { responsiveSize } from "styles/responsiveSize";
+
import Filters from "./Filters";
import Stats, { IStats } from "./Stats";
@@ -8,8 +10,8 @@ const Container = styled.div`
display: flex;
flex-wrap: wrap;
gap: 8px;
- margin-top: 11px;
- margin-bottom: 48px;
+ margin-top: ${responsiveSize(4, 8)};
+ margin-bottom: ${responsiveSize(16, 32)};
justify-content: space-between;
`;
diff --git a/web/src/components/CasesDisplay/index.tsx b/web/src/components/CasesDisplay/index.tsx
index 7b30e7751..6a3bf8684 100644
--- a/web/src/components/CasesDisplay/index.tsx
+++ b/web/src/components/CasesDisplay/index.tsx
@@ -17,7 +17,7 @@ const TitleContainer = styled.div`
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
- margin-bottom: ${responsiveSize(32, 48)};
+ margin-bottom: ${responsiveSize(12, 24)};
`;
const StyledTitle = styled.h1`
diff --git a/web/src/components/DisputePreview/Policies.tsx b/web/src/components/DisputePreview/Policies.tsx
index 91adfc4ad..2eb7f5c2e 100644
--- a/web/src/components/DisputePreview/Policies.tsx
+++ b/web/src/components/DisputePreview/Policies.tsx
@@ -8,6 +8,7 @@ import { getIpfsUrl } from "utils/getIpfsUrl";
import { isUndefined } from "utils/index";
import { responsiveSize } from "styles/responsiveSize";
+import { hoverShortTransitionTiming } from "styles/commonStyles";
import { InternalLink } from "components/InternalLink";
@@ -38,12 +39,12 @@ const StyledPaperclipIcon = styled(PaperclipIcon)`
`;
const StyledInternalLink = styled(InternalLink)`
+ ${hoverShortTransitionTiming}
display: flex;
gap: 4px;
&:hover {
svg {
- transition: fill 0.1s;
fill: ${({ theme }) => theme.secondaryBlue};
}
}
diff --git a/web/src/components/DisputeView/DisputeCardView.tsx b/web/src/components/DisputeView/DisputeCardView.tsx
index 2c2e370a3..602c98f06 100644
--- a/web/src/components/DisputeView/DisputeCardView.tsx
+++ b/web/src/components/DisputeView/DisputeCardView.tsx
@@ -8,6 +8,7 @@ import { Card } from "@kleros/ui-components-library";
import { Periods } from "consts/periods";
import { responsiveSize } from "styles/responsiveSize";
+import { hoverShortTransitionTiming } from "styles/commonStyles";
import { StyledSkeleton } from "components/StyledSkeleton";
@@ -15,15 +16,11 @@ import DisputeInfo from "./DisputeInfo";
import PeriodBanner from "./PeriodBanner";
const StyledCard = styled(Card)`
+ ${hoverShortTransitionTiming}
width: 100%;
height: 100%;
max-height: 335px;
min-height: 290px;
- transition: background-color 0.1s;
-
- &:hover {
- background-color: ${({ theme }) => theme.lightGrey}BB;
- }
`;
const CardContainer = styled.div`
@@ -61,7 +58,7 @@ interface IDisputeCardView {
const DisputeCardView: React.FC = ({ isLoading, ...props }) => {
return (
-
+
{isLoading ? : }
diff --git a/web/src/components/DisputeView/DisputeListView.tsx b/web/src/components/DisputeView/DisputeListView.tsx
index cdd4e64c3..d0c1c967a 100644
--- a/web/src/components/DisputeView/DisputeListView.tsx
+++ b/web/src/components/DisputeView/DisputeListView.tsx
@@ -9,20 +9,17 @@ import { Card } from "@kleros/ui-components-library";
import { Periods } from "consts/periods";
import { responsiveSize } from "styles/responsiveSize";
+import { hoverShortTransitionTiming } from "styles/commonStyles";
import DisputeInfo from "./DisputeInfo";
import PeriodBanner from "./PeriodBanner";
const StyledListItem = styled(Card)`
+ ${hoverShortTransitionTiming}
display: flex;
flex-grow: 1;
width: 100%;
height: 82px;
- transition: background-color 0.1s;
-
- &:hover {
- background-color: ${({ theme }) => theme.lightGrey}BB;
- }
`;
const ListContainer = styled.div`
@@ -64,7 +61,7 @@ const DisputeListView: React.FC = (props) => {
const { isDisconnected } = useAccount();
return (
-
+
diff --git a/web/src/components/DottedMenuButton.tsx b/web/src/components/DottedMenuButton.tsx
index 3684b24ed..d1f5102d0 100644
--- a/web/src/components/DottedMenuButton.tsx
+++ b/web/src/components/DottedMenuButton.tsx
@@ -1,6 +1,8 @@
import React from "react";
import styled, { css, keyframes } from "styled-components";
+import { hoverShortTransitionTiming } from "styles/commonStyles";
+
import DottedMenu from "svgs/icons/dotted-menu.svg";
const ripple = keyframes`
@@ -57,13 +59,16 @@ const Container = styled.div<{ displayRipple: boolean }>`
`;
const ButtonContainer = styled.div`
+ ${hoverShortTransitionTiming}
border-radius: 50%;
z-index: 1;
background-color: ${({ theme }) => theme.lightBackground};
- transition: background-color 0.1s;
:hover {
background-color: ${({ theme }) => theme.lightGrey};
+ svg {
+ fill: ${({ theme }) => theme.secondaryBlue};
+ }
}
`;
diff --git a/web/src/components/EvidenceCard.tsx b/web/src/components/EvidenceCard.tsx
index c5954f9eb..ddd7ba62c 100644
--- a/web/src/components/EvidenceCard.tsx
+++ b/web/src/components/EvidenceCard.tsx
@@ -3,6 +3,7 @@ import styled, { css } from "styled-components";
import { landscapeStyle } from "styles/landscapeStyle";
import { responsiveSize } from "styles/responsiveSize";
+import { hoverShortTransitionTiming } from "styles/commonStyles";
import Identicon from "react-identicons";
import ReactMarkdown from "react-markdown";
@@ -165,6 +166,7 @@ const MobileText = styled.span`
`;
const StyledInternalLink = styled(InternalLink)`
+ ${hoverShortTransitionTiming}
display: flex;
gap: ${responsiveSize(5, 6)};
> svg {
@@ -173,7 +175,6 @@ const StyledInternalLink = styled(InternalLink)`
}
:hover svg {
- transition: fill 0.1s;
fill: ${({ theme }) => theme.secondaryBlue};
}
`;
diff --git a/web/src/components/ExtraStatsDisplay.tsx b/web/src/components/ExtraStatsDisplay.tsx
index a562708a2..dd292164b 100644
--- a/web/src/components/ExtraStatsDisplay.tsx
+++ b/web/src/components/ExtraStatsDisplay.tsx
@@ -9,7 +9,6 @@ const Container = styled.div`
display: flex;
gap: 8px;
align-items: center;
- margin-top: 24px;
`;
const SVGContainer = styled.div`
diff --git a/web/src/components/FavoriteCases.tsx b/web/src/components/FavoriteCases.tsx
new file mode 100644
index 000000000..c90ab4f5b
--- /dev/null
+++ b/web/src/components/FavoriteCases.tsx
@@ -0,0 +1,81 @@
+import React, { useMemo, useState } from "react";
+import styled from "styled-components";
+
+import { StandardPagination } from "@kleros/ui-components-library";
+
+import useStarredCases from "hooks/useStarredCases";
+import { isUndefined } from "utils/index";
+
+import { DisputeDetailsFragment, useCasesQuery } from "queries/useCasesQuery";
+
+import { responsiveSize } from "styles/responsiveSize";
+
+import DisputeView from "components/DisputeView";
+import { SkeletonDisputeCard } from "components/StyledSkeleton";
+
+const Container = styled.div`
+ margin-top: ${responsiveSize(48, 80)};
+`;
+
+const Title = styled.h1`
+ margin-bottom: 4px;
+`;
+
+const DisputeContainer = styled.div`
+ --gap: 16px;
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(min(100%, max(312px, (100% - var(--gap) * 2)/3)), 1fr));
+ align-items: stretch;
+ gap: var(--gap);
+`;
+
+const StyledLabel = styled.label`
+ display: block;
+ color: ${({ theme }) => theme.primaryBlue};
+ cursor: pointer;
+ margin-bottom: ${responsiveSize(12, 16)};
+ :hover {
+ color: ${({ theme }) => theme.secondaryBlue};
+ }
+`;
+
+const StyledPagination = styled(StandardPagination)`
+ margin-top: 24px;
+ margin-left: auto;
+ margin-right: auto;
+`;
+
+const FavoriteCases: React.FC = () => {
+ const { starredCaseIds, clearAll } = useStarredCases();
+
+ const [currentPage, setCurrentPage] = useState(1);
+ const casesPerPage = 3;
+ const totalPages = Math.ceil(starredCaseIds.length / casesPerPage);
+
+ const { data } = useCasesQuery((currentPage - 1) * casesPerPage, casesPerPage, {
+ id_in: starredCaseIds,
+ });
+
+ const disputes: DisputeDetailsFragment[] = useMemo(() => data?.disputes as DisputeDetailsFragment[], [data]);
+
+ return starredCaseIds.length > 0 && (isUndefined(disputes) || disputes.length > 0) ? (
+
+ Favorite Cases
+ Clear all
+
+ {isUndefined(disputes)
+ ? Array.from({ length: 3 }).map((_, index) => )
+ : disputes.map((dispute) => )}
+
+ {totalPages > 1 ? (
+ setCurrentPage(page)}
+ />
+ ) : null}
+
+ ) : null;
+};
+
+export default FavoriteCases;
diff --git a/web/src/components/HowItWorks.tsx b/web/src/components/HowItWorks.tsx
index 7fc2cf8d9..ad4847d60 100644
--- a/web/src/components/HowItWorks.tsx
+++ b/web/src/components/HowItWorks.tsx
@@ -1,9 +1,12 @@
import React from "react";
import styled from "styled-components";
+import { hoverShortTransitionTiming } from "styles/commonStyles";
+
import BookOpenIcon from "svgs/icons/book-open.svg";
const Container = styled.div`
+ ${hoverShortTransitionTiming}
display: flex;
align-items: center;
font-size: 14px;
@@ -11,7 +14,6 @@ const Container = styled.div`
gap: 8px;
cursor: pointer;
color: ${({ theme }) => theme.primaryBlue};
- transition: color 0.1s;
svg path {
fill: ${({ theme }) => theme.primaryBlue};
@@ -20,7 +22,6 @@ const Container = styled.div`
&:hover {
color: ${({ theme }) => theme.secondaryBlue};
svg path {
- transition: fill 0.1s;
fill: ${({ theme }) => theme.secondaryBlue};
}
}
diff --git a/web/src/components/LatestCases.tsx b/web/src/components/LatestCases.tsx
index 9f8a9d55b..34f259f35 100644
--- a/web/src/components/LatestCases.tsx
+++ b/web/src/components/LatestCases.tsx
@@ -13,11 +13,11 @@ import { SkeletonDisputeCard } from "components/StyledSkeleton";
import { Dispute_Filter } from "../graphql/graphql";
const Container = styled.div`
- margin-top: ${responsiveSize(48, 80)};
+ margin-top: ${responsiveSize(28, 48)};
`;
const Title = styled.h1`
- margin-bottom: ${responsiveSize(16, 48)};
+ margin-bottom: ${responsiveSize(12, 24)};
`;
const DisputeContainer = styled.div`
diff --git a/web/src/components/LightButton.tsx b/web/src/components/LightButton.tsx
index 9e4c579bc..86307d53a 100644
--- a/web/src/components/LightButton.tsx
+++ b/web/src/components/LightButton.tsx
@@ -1,10 +1,12 @@
import React from "react";
import styled, { css } from "styled-components";
import { landscapeStyle } from "styles/landscapeStyle";
+import { hoverShortTransitionTiming } from "styles/commonStyles";
import { Button } from "@kleros/ui-components-library";
const StyledButton = styled(Button)<{ isMobileNavbar?: boolean }>`
+ ${hoverShortTransitionTiming}
background-color: transparent;
padding: 8px !important;
border-radius: 7px;
@@ -20,7 +22,6 @@ const StyledButton = styled(Button)<{ isMobileNavbar?: boolean }>`
.button-svg {
fill: ${({ theme, isMobileNavbar }) => (isMobileNavbar ? theme.primaryText : `${theme.white}`)} !important;
}
- transition: background-color 0.1s;
background-color: ${({ theme }) => theme.whiteLowOpacityStrong};
}
diff --git a/web/src/favicon.ico b/web/src/favicon.ico
index 16a8426ee..47556b429 100644
Binary files a/web/src/favicon.ico and b/web/src/favicon.ico differ
diff --git a/web/src/hooks/useStarredCases.tsx b/web/src/hooks/useStarredCases.tsx
new file mode 100644
index 000000000..eb6109306
--- /dev/null
+++ b/web/src/hooks/useStarredCases.tsx
@@ -0,0 +1,26 @@
+import { useMemo } from "react";
+
+import { useLocalStorage } from "./useLocalStorage";
+
+const useStarredCases = () => {
+ const initialValue = new Set();
+
+ const [localStarredCases, setLocalStarredCases] = useLocalStorage("starredCases", Array.from(initialValue));
+
+ const starredCases = useMemo(() => new Set(localStarredCases), [localStarredCases]);
+ const starredCaseIds = Array.from(starredCases.keys());
+
+ const starCase = (id: string) => {
+ if (starredCases.has(id)) starredCases.delete(id);
+ else starredCases.add(id);
+
+ setLocalStarredCases(Array.from(starredCases));
+ };
+
+ const clearAll = () => {
+ setLocalStarredCases(Array.from(initialValue));
+ };
+ return { starredCases, starredCaseIds, starCase, clearAll };
+};
+
+export default useStarredCases;
diff --git a/web/src/layout/Footer/index.tsx b/web/src/layout/Footer/index.tsx
index 046dd69b7..4007b781b 100644
--- a/web/src/layout/Footer/index.tsx
+++ b/web/src/layout/Footer/index.tsx
@@ -2,6 +2,7 @@ import React from "react";
import styled, { css } from "styled-components";
import { landscapeStyle } from "styles/landscapeStyle";
+import { hoverShortTransitionTiming } from "styles/commonStyles";
import SecuredByKlerosLogo from "svgs/footer/secured-by-kleros.svg";
@@ -32,6 +33,7 @@ const Container = styled.div`
`;
const StyledSecuredByKlerosLogo = styled(SecuredByKlerosLogo)`
+ ${hoverShortTransitionTiming}
min-height: 24px;
path {
@@ -40,7 +42,6 @@ const StyledSecuredByKlerosLogo = styled(SecuredByKlerosLogo)`
:hover path {
fill: ${({ theme }) => theme.white};
- transition: fill 0.1s;
}
`;
diff --git a/web/src/layout/Header/Logo.tsx b/web/src/layout/Header/Logo.tsx
index 36dd0cf0f..5ccaabe3b 100644
--- a/web/src/layout/Header/Logo.tsx
+++ b/web/src/layout/Header/Logo.tsx
@@ -1,6 +1,8 @@
import React, { useMemo } from "react";
import styled, { Theme } from "styled-components";
+import { hoverShortTransitionTiming } from "styles/commonStyles";
+
import { Link } from "react-router-dom";
import { ArbitratorTypes, getArbitratorType } from "consts/index";
@@ -29,13 +31,13 @@ const BadgeText = styled.label`
`;
const StyledKlerosCourtLogo = styled(KlerosCourtLogo)`
+ ${hoverShortTransitionTiming}
max-height: 40px;
width: auto;
&:hover {
path {
fill: ${({ theme }) => theme.white}BF;
- transition: fill 0.1s;
}
}
`;
diff --git a/web/src/pages/Cases/CaseDetails/Appeal/OptionCard.tsx b/web/src/pages/Cases/CaseDetails/Appeal/OptionCard.tsx
index c301e70e6..0ac19f61d 100644
--- a/web/src/pages/Cases/CaseDetails/Appeal/OptionCard.tsx
+++ b/web/src/pages/Cases/CaseDetails/Appeal/OptionCard.tsx
@@ -1,6 +1,8 @@
import React, { useMemo } from "react";
import styled from "styled-components";
+import { hoverShortTransitionTiming } from "styles/commonStyles";
+
import { useMeasure } from "react-use";
import { formatEther } from "viem";
@@ -11,8 +13,10 @@ import Gavel from "svgs/icons/gavel.svg";
import { isUndefined } from "utils/index";
const StyledCard = styled(Card)`
+ ${hoverShortTransitionTiming}
width: 100%;
padding: 24px;
+
&:hover {
cursor: pointer;
}
diff --git a/web/src/pages/Cases/CaseDetails/Tabs.tsx b/web/src/pages/Cases/CaseDetails/Tabs.tsx
index 7f8b07761..0ec722d98 100644
--- a/web/src/pages/Cases/CaseDetails/Tabs.tsx
+++ b/web/src/pages/Cases/CaseDetails/Tabs.tsx
@@ -1,6 +1,8 @@
import React, { useState, useEffect, useMemo } from "react";
import styled from "styled-components";
+import { responsiveSize } from "styles/responsiveSize";
+
import { useNavigate, useLocation, useParams } from "react-router-dom";
import { Tabs as TabsComponent } from "@kleros/ui-components-library";
@@ -20,6 +22,7 @@ import { useAppealCost } from "queries/useAppealCost";
const StyledTabs = styled(TabsComponent)`
width: 100%;
+ margin-top: ${responsiveSize(12, 24)};
> * {
display: flex;
flex-wrap: wrap;
diff --git a/web/src/pages/Cases/CaseDetails/Timeline.tsx b/web/src/pages/Cases/CaseDetails/Timeline.tsx
index be8113549..b4aa8ece4 100644
--- a/web/src/pages/Cases/CaseDetails/Timeline.tsx
+++ b/web/src/pages/Cases/CaseDetails/Timeline.tsx
@@ -1,6 +1,8 @@
import React, { useMemo } from "react";
import styled, { css } from "styled-components";
+import { landscapeStyle } from "styles/landscapeStyle";
+
import { Box, Steps } from "@kleros/ui-components-library";
import { Periods } from "consts/periods";
@@ -10,34 +12,26 @@ import { secondsToDayHourMinute } from "utils/date";
import { DisputeDetailsQuery } from "queries/useDisputeDetailsQuery";
-import { landscapeStyle } from "styles/landscapeStyle";
-import { responsiveSize } from "styles/responsiveSize";
-
import { StyledSkeleton } from "components/StyledSkeleton";
const TimeLineContainer = styled(Box)`
- display: block;
width: 100%;
- height: 98px;
+ height: auto;
border-radius: 0px;
- padding: ${responsiveSize(16, 48)} 8px 0px ${responsiveSize(12, 22)};
- margin-top: ${responsiveSize(16, 48)};
- margin-bottom: ${responsiveSize(12, 22)};
- background-color: ${({ theme }) => theme.whiteBackground};
-
- ${landscapeStyle(
- () => css`
- display: block;
- padding: 28px 8px 8px 8px;
- `
- )}
+ background-color: transparent;
`;
const StyledSteps = styled(Steps)`
display: flex;
justify-content: space-between;
- width: 85%;
+ width: 89%;
margin: auto;
+
+ ${landscapeStyle(
+ () => css`
+ width: 98%;
+ `
+ )}
`;
const Timeline: React.FC<{
diff --git a/web/src/pages/Cases/CaseDetails/Voting/VotesDetails/index.tsx b/web/src/pages/Cases/CaseDetails/Voting/VotesDetails/index.tsx
index ec0dfdcc9..340b7ba75 100644
--- a/web/src/pages/Cases/CaseDetails/Voting/VotesDetails/index.tsx
+++ b/web/src/pages/Cases/CaseDetails/Voting/VotesDetails/index.tsx
@@ -28,12 +28,7 @@ const StyledAccordion = styled(CustomAccordion)`
[class*="accordion-button"] {
padding: 11.5px ${responsiveSize(8, 18)} !important;
- background-color: ${({ theme }) => theme.whiteBackground} !important;
- border: 1px solid ${({ theme }) => theme.stroke} !important;
margin: 4px 0;
- > svg {
- fill: ${({ theme }) => theme.primaryText} !important;
- }
}
[class*="Body"] {
diff --git a/web/src/pages/Cases/CaseDetails/index.tsx b/web/src/pages/Cases/CaseDetails/index.tsx
index 643eb696d..64cc12424 100644
--- a/web/src/pages/Cases/CaseDetails/index.tsx
+++ b/web/src/pages/Cases/CaseDetails/index.tsx
@@ -12,6 +12,9 @@ import { useDisputeDetailsQuery } from "queries/useDisputeDetailsQuery";
import { responsiveSize } from "styles/responsiveSize";
+import CaseStarButton from "components/CaseStarButton";
+import ScrollTop from "components/ScrollTop";
+
import Appeal from "./Appeal";
import Evidence from "./Evidence";
import MaintenanceButtons from "./MaintenanceButtons";
@@ -19,7 +22,6 @@ import Overview from "./Overview";
import Tabs from "./Tabs";
import Timeline from "./Timeline";
import Voting from "./Voting";
-import ScrollTop from "components/ScrollTop";
const Container = styled.div``;
@@ -33,12 +35,16 @@ const HeaderContainer = styled.div`
width: 100%;
display: flex;
align-items: center;
- margin-bottom: ${responsiveSize(32, 54)};
+ margin-top: -2px;
+ margin-bottom: ${responsiveSize(16, 32)};
`;
const Header = styled.h1`
- margin: 0;
+ display: flex;
+ align-items: center;
flex: 1;
+ gap: 8px;
+ margin: 0;
`;
const CaseDetails: React.FC = () => {
@@ -52,11 +58,14 @@ const CaseDetails: React.FC = () => {
-
+
+ Case #{id} {id ? : null}
+
+
-
+
theme.lightBackground};
- padding: ${responsiveSize(32, 80)} ${responsiveSize(24, 136)} ${responsiveSize(76, 96)};
+ padding: ${responsiveSize(32, 48)} ${responsiveSize(24, 136)} ${responsiveSize(40, 60)};
max-width: ${MAX_WIDTH_LANDSCAPE};
margin: 0 auto;
`;
diff --git a/web/src/pages/Courts/CourtDetails/StakePanel/InputDisplay.tsx b/web/src/pages/Courts/CourtDetails/StakePanel/InputDisplay.tsx
index d93511fec..45818bba7 100644
--- a/web/src/pages/Courts/CourtDetails/StakePanel/InputDisplay.tsx
+++ b/web/src/pages/Courts/CourtDetails/StakePanel/InputDisplay.tsx
@@ -1,6 +1,8 @@
import React, { useState, useMemo, useEffect } from "react";
import styled from "styled-components";
+import { hoverShortTransitionTiming } from "styles/commonStyles";
+
import { useParams } from "react-router-dom";
import { useDebounce } from "react-use";
@@ -27,8 +29,13 @@ const LabelArea = styled.div`
`;
const StyledLabel = styled.label`
+ ${hoverShortTransitionTiming}
color: ${({ theme }) => theme.primaryBlue};
cursor: pointer;
+
+ :hover {
+ color: ${({ theme }) => theme.secondaryBlue};
+ }
`;
const InputArea = styled.div`
diff --git a/web/src/pages/Courts/CourtDetails/Stats.tsx b/web/src/pages/Courts/CourtDetails/Stats.tsx
index a1a71d6df..55bedfc72 100644
--- a/web/src/pages/Courts/CourtDetails/Stats.tsx
+++ b/web/src/pages/Courts/CourtDetails/Stats.tsx
@@ -32,14 +32,6 @@ import { StyledSkeleton } from "components/StyledSkeleton";
const StyledAccordion = styled(Accordion)`
> * > button {
justify-content: unset;
- background-color: ${({ theme }) => theme.whiteBackground} !important;
- border: 1px solid ${({ theme }) => theme.stroke} !important;
- > svg {
- fill: ${({ theme }) => theme.primaryText} !important;
- }
- > p {
- color: ${({ theme }) => theme.primaryText};
- }
}
//adds padding to body container
> * > div > div {
diff --git a/web/src/pages/Courts/CourtDetails/index.tsx b/web/src/pages/Courts/CourtDetails/index.tsx
index e255cb103..852ffb3dc 100644
--- a/web/src/pages/Courts/CourtDetails/index.tsx
+++ b/web/src/pages/Courts/CourtDetails/index.tsx
@@ -1,7 +1,7 @@
import React from "react";
import styled, { css } from "styled-components";
-import { useParams } from "react-router-dom";
+import { useNavigate, useParams } from "react-router-dom";
import { useToggle } from "react-use";
import { Card, Breadcrumb } from "@kleros/ui-components-library";
@@ -94,16 +94,15 @@ const CourtDetails: React.FC = () => {
const { data: policy } = useCourtPolicy(id);
const { data } = useCourtTree();
const [isStakingMiniGuideOpen, toggleStakingMiniGuide] = useToggle(false);
+ const navigate = useNavigate();
const courtPath = getCourtsPath(data?.court, id);
- const items = [];
- items.push(
- ...(courtPath?.map((node) => ({
+ const breadcrumbItems =
+ courtPath?.map((node) => ({
text: node.name,
value: node.id,
- })) ?? [])
- );
+ })) ?? [];
return (
@@ -111,7 +110,13 @@ const CourtDetails: React.FC = () => {
{policy ? policy.name : }
- {items.length > 1 && items[0]?.value !== 1 ? : null}
+ {breadcrumbItems.length > 1 ? (
+ navigate(`/courts/${courtId}`)}
+ />
+ ) : null}
{!isProductionDeployment() && }
diff --git a/web/src/pages/Courts/index.tsx b/web/src/pages/Courts/index.tsx
index 691c849d2..dea046be9 100644
--- a/web/src/pages/Courts/index.tsx
+++ b/web/src/pages/Courts/index.tsx
@@ -12,7 +12,7 @@ import TopSearch from "./TopSearch";
const Container = styled.div`
width: 100%;
background-color: ${({ theme }) => theme.lightBackground};
- padding: ${responsiveSize(32, 80)} ${responsiveSize(24, 136)} ${responsiveSize(76, 96)};
+ padding: ${responsiveSize(32, 48)} ${responsiveSize(24, 136)} ${responsiveSize(40, 60)};
max-width: ${MAX_WIDTH_LANDSCAPE};
margin: 0 auto;
`;
diff --git a/web/src/pages/Dashboard/Courts/Header.tsx b/web/src/pages/Dashboard/Courts/Header.tsx
index 3577acd68..7244de1dc 100644
--- a/web/src/pages/Dashboard/Courts/Header.tsx
+++ b/web/src/pages/Dashboard/Courts/Header.tsx
@@ -16,10 +16,10 @@ const Container = styled.div`
display: flex;
flex-direction: column;
width: 100%;
- gap: 12px;
+ gap: 4px;
align-items: flex-start;
justify-content: space-between;
- margin-bottom: ${responsiveSize(32, 48)};
+ margin-bottom: ${responsiveSize(16, 24)};
${landscapeStyle(
() => css`
diff --git a/web/src/pages/Dashboard/Courts/index.tsx b/web/src/pages/Dashboard/Courts/index.tsx
index 965185b80..2b99b4cb8 100644
--- a/web/src/pages/Dashboard/Courts/index.tsx
+++ b/web/src/pages/Dashboard/Courts/index.tsx
@@ -9,18 +9,19 @@ import { useReadSortitionModuleGetJurorBalance } from "hooks/contracts/generated
import { useJurorStakeDetailsQuery } from "queries/useJurorStakeDetailsQuery";
import { landscapeStyle } from "styles/landscapeStyle";
+import { responsiveSize } from "styles/responsiveSize";
import CourtCard from "./CourtCard";
import Header from "./Header";
const Container = styled.div`
- margin-top: 64px;
+ margin-top: ${responsiveSize(24, 48)};
`;
const CourtCardsContainer = styled.div`
display: flex;
flex-direction: column;
- gap: 12px;
+ gap: 4px;
z-index: 0;
${landscapeStyle(
diff --git a/web/src/pages/Dashboard/JurorInfo/Header.tsx b/web/src/pages/Dashboard/JurorInfo/Header.tsx
index 00660f3b7..907df0015 100644
--- a/web/src/pages/Dashboard/JurorInfo/Header.tsx
+++ b/web/src/pages/Dashboard/JurorInfo/Header.tsx
@@ -16,7 +16,7 @@ const Container = styled.div`
display: flex;
flex-direction: column;
justify-content: flex-start;
- margin-bottom: ${responsiveSize(32, 48)};
+ margin-bottom: ${responsiveSize(16, 24)};
gap: 12px;
${landscapeStyle(
diff --git a/web/src/pages/Dashboard/index.tsx b/web/src/pages/Dashboard/index.tsx
index 5aa271d7e..e8a890e66 100644
--- a/web/src/pages/Dashboard/index.tsx
+++ b/web/src/pages/Dashboard/index.tsx
@@ -1,9 +1,6 @@
import React, { useMemo } from "react";
import styled from "styled-components";
-import { MAX_WIDTH_LANDSCAPE } from "styles/landscapeStyle";
-import { responsiveSize } from "styles/responsiveSize";
-
import { useNavigate, useParams } from "react-router-dom";
import { useAccount } from "wagmi";
@@ -15,8 +12,12 @@ import { useUserQuery } from "queries/useUser";
import { OrderDirection } from "src/graphql/graphql";
+import { MAX_WIDTH_LANDSCAPE } from "styles/landscapeStyle";
+import { responsiveSize } from "styles/responsiveSize";
+
import CasesDisplay from "components/CasesDisplay";
import ConnectWallet from "components/ConnectWallet";
+import FavoriteCases from "components/FavoriteCases";
import ScrollTop from "components/ScrollTop";
import Courts from "./Courts";
@@ -25,16 +26,16 @@ import JurorInfo from "./JurorInfo";
const Container = styled.div`
width: 100%;
background-color: ${({ theme }) => theme.lightBackground};
- padding: ${responsiveSize(32, 80)} ${responsiveSize(24, 136)} ${responsiveSize(76, 96)};
+ padding: ${responsiveSize(32, 48)} ${responsiveSize(24, 136)} ${responsiveSize(40, 60)};
max-width: ${MAX_WIDTH_LANDSCAPE};
margin: 0 auto;
`;
const StyledCasesDisplay = styled(CasesDisplay)`
- margin-top: 64px;
+ margin-top: ${responsiveSize(32, 48)};
.title {
- margin-bottom: ${responsiveSize(16, 48)};
+ margin-bottom: ${responsiveSize(12, 24)};
}
`;
@@ -94,6 +95,7 @@ const Dashboard: React.FC = () => {
)}
+
);
diff --git a/web/src/pages/GetPnk/index.tsx b/web/src/pages/GetPnk/index.tsx
index dce7ea464..d21450262 100644
--- a/web/src/pages/GetPnk/index.tsx
+++ b/web/src/pages/GetPnk/index.tsx
@@ -19,7 +19,7 @@ const Wrapper = styled.div`
const Container = styled.div`
width: 100%;
background-color: ${({ theme }) => theme.lightBackground};
- padding: ${responsiveSize(32, 72)} ${responsiveSize(24, 132)} ${responsiveSize(76, 96)};
+ padding: 16px ${responsiveSize(24, 132)} ${responsiveSize(40, 60)};
max-width: ${MAX_WIDTH_LANDSCAPE};
margin: 0 auto;
display: flex;
diff --git a/web/src/pages/Home/Community/index.tsx b/web/src/pages/Home/Community/index.tsx
index 0c2cf8547..27af3020d 100644
--- a/web/src/pages/Home/Community/index.tsx
+++ b/web/src/pages/Home/Community/index.tsx
@@ -11,10 +11,10 @@ import { responsiveSize } from "styles/responsiveSize";
import { Element } from "./Element";
const Container = styled.div`
- margin-top: ${responsiveSize(44, 64)};
+ margin-top: ${responsiveSize(24, 48)};
h1 {
- margin-bottom: ${responsiveSize(16, 48)};
+ margin-bottom: ${responsiveSize(12, 24)};
}
`;
diff --git a/web/src/pages/Home/CourtOverview/Chart.tsx b/web/src/pages/Home/CourtOverview/Chart.tsx
index 10a53d1a4..94cf8f3bb 100644
--- a/web/src/pages/Home/CourtOverview/Chart.tsx
+++ b/web/src/pages/Home/CourtOverview/Chart.tsx
@@ -1,6 +1,8 @@
import React, { useMemo, useState } from "react";
import styled from "styled-components";
+import { responsiveSize } from "styles/responsiveSize";
+
import { Tooltip } from "chart.js";
import { formatUnits } from "viem";
@@ -8,8 +10,6 @@ import { DropdownSelect } from "@kleros/ui-components-library";
import { useHomePageContext } from "hooks/useHomePageContext";
-import { responsiveSize } from "styles/responsiveSize";
-
import { StyledSkeleton } from "components/StyledSkeleton";
import CasesByCourtsChart, { CasesByCourtsChartData } from "./CasesByCourtsChart";
@@ -17,14 +17,14 @@ import StakedPNKByCourtsChart, { StakedPNKByCourtsChartData } from "./StakedPNKB
import TimeSeriesChart from "./TimeSeriesChart";
const Container = styled.div`
- margin-bottom: ${responsiveSize(32, 48)};
+ margin-bottom: ${responsiveSize(16, 32)};
display: flex;
flex-direction: column;
`;
const StyledDropdown = styled(DropdownSelect)`
width: fit-content;
- align-self: end;
+ align-self: start;
`;
const CHART_OPTIONS = [
@@ -40,7 +40,6 @@ const ChartOptionsDropdown: React.FC<{
{
diff --git a/web/src/pages/Home/CourtOverview/ExtraStats.tsx b/web/src/pages/Home/CourtOverview/ExtraStats.tsx
index 18112c115..9786b4f61 100644
--- a/web/src/pages/Home/CourtOverview/ExtraStats.tsx
+++ b/web/src/pages/Home/CourtOverview/ExtraStats.tsx
@@ -1,6 +1,8 @@
import React, { useState } from "react";
import styled from "styled-components";
+import { responsiveSize } from "styles/responsiveSize";
+
import { DropdownSelect } from "@kleros/ui-components-library";
import LawBalance from "svgs/icons/law-balance.svg";
@@ -13,8 +15,9 @@ import ExtraStatsDisplay from "components/ExtraStatsDisplay";
const StyledCard = styled.div`
display: flex;
flex-wrap: wrap;
- gap: 0 24px;
+ gap: 12px 24px;
justify-content: center;
+ margin-top: ${responsiveSize(12, 16)};
`;
const StyledLabel = styled.label`
diff --git a/web/src/pages/Home/CourtOverview/Header.tsx b/web/src/pages/Home/CourtOverview/Header.tsx
index fa54bf4a2..8c21ecb87 100644
--- a/web/src/pages/Home/CourtOverview/Header.tsx
+++ b/web/src/pages/Home/CourtOverview/Header.tsx
@@ -3,31 +3,36 @@ import styled from "styled-components";
import { responsiveSize } from "styles/responsiveSize";
-import { Link } from "react-router-dom";
-
import { Button } from "@kleros/ui-components-library";
import Bookmark from "svgs/icons/bookmark.svg";
+import { InternalLink } from "components/InternalLink";
+
const StyledHeader = styled.div`
display: flex;
flex-wrap: wrap;
justify-content: space-between;
- gap: 0 12px;
- margin-bottom: ${responsiveSize(16, 0)};
+ gap: 8px 12px;
+ margin-bottom: ${responsiveSize(12, 20)};
`;
const StyledH1 = styled.h1`
font-size: ${responsiveSize(21, 24)};
+ margin: 0;
+`;
+
+const StyledInternalLink = styled(InternalLink)`
+ height: 34px;
`;
const Header: React.FC = () => {
return (
Court Overview
-
+
-
+
);
};
diff --git a/web/src/pages/Home/TopJurors/index.tsx b/web/src/pages/Home/TopJurors/index.tsx
index 45daaccb0..2a8eb7037 100644
--- a/web/src/pages/Home/TopJurors/index.tsx
+++ b/web/src/pages/Home/TopJurors/index.tsx
@@ -14,11 +14,11 @@ import Header from "./Header";
import JurorCard from "./JurorCard";
const Container = styled.div`
- margin-top: ${responsiveSize(64, 80)};
+ margin-top: ${responsiveSize(24, 48)};
`;
const Title = styled.h1`
- margin-bottom: ${responsiveSize(16, 48)};
+ margin-bottom: ${responsiveSize(12, 24)};
`;
const ListContainer = styled.div`
diff --git a/web/src/pages/Home/index.tsx b/web/src/pages/Home/index.tsx
index 0ca9d370c..82f0f2389 100644
--- a/web/src/pages/Home/index.tsx
+++ b/web/src/pages/Home/index.tsx
@@ -22,7 +22,7 @@ const Wrapper = styled.div`
const Container = styled.div`
width: 100%;
background-color: ${({ theme }) => theme.lightBackground};
- padding: ${responsiveSize(32, 72)} ${responsiveSize(24, 132)} ${responsiveSize(76, 96)};
+ padding: 16px ${responsiveSize(24, 132)} ${responsiveSize(40, 60)};
max-width: ${MAX_WIDTH_LANDSCAPE};
margin: 0 auto;
`;
diff --git a/web/src/styles/commonStyles.ts b/web/src/styles/commonStyles.ts
new file mode 100644
index 000000000..f6ef00ec1
--- /dev/null
+++ b/web/src/styles/commonStyles.ts
@@ -0,0 +1,9 @@
+import { css } from "styled-components";
+
+export const hoverShortTransitionTiming = css`
+ transition: 0.1s;
+`;
+
+export const hoverLongTransitionTiming = css`
+ transition: 0.2s;
+`;
diff --git a/web/src/styles/themes.ts b/web/src/styles/themes.ts
index 5182de490..b44dd177e 100644
--- a/web/src/styles/themes.ts
+++ b/web/src/styles/themes.ts
@@ -67,7 +67,7 @@ export const darkTheme = {
lightBlue: "#2A1260",
primaryText: "#DAF0FF",
secondaryText: "#BECCE5",
- stroke: "#42498F",
+ stroke: "#392C74",
lightGrey: "#2D1865",
whiteBackground: "#220050",
diff --git a/yarn.lock b/yarn.lock
index 37e83cbe3..0f5f8b7f0 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5572,7 +5572,7 @@ __metadata:
"@kleros/kleros-v2-eslint-config": "workspace:^"
"@kleros/kleros-v2-prettier-config": "workspace:^"
"@kleros/kleros-v2-tsconfig": "workspace:^"
- "@kleros/ui-components-library": "npm:^2.16.0"
+ "@kleros/ui-components-library": "npm:^2.18.0"
"@lifi/wallet-management": "npm:^3.4.6"
"@lifi/widget": "npm:^3.12.3"
"@sentry/react": "npm:^7.120.0"
@@ -5657,9 +5657,9 @@ __metadata:
languageName: node
linkType: hard
-"@kleros/ui-components-library@npm:^2.16.0":
- version: 2.16.0
- resolution: "@kleros/ui-components-library@npm:2.16.0"
+"@kleros/ui-components-library@npm:^2.18.0":
+ version: 2.18.0
+ resolution: "@kleros/ui-components-library@npm:2.18.0"
dependencies:
"@datepicker-react/hooks": "npm:^2.8.4"
"@swc/helpers": "npm:^0.3.2"
@@ -5676,7 +5676,7 @@ __metadata:
react-dom: ^18.0.0
react-is: ^18.0.0
styled-components: ^5.3.3
- checksum: 10/d17d05aa96c3df6ec8ee5a1ea31652f113d09ddeb5c8ac42aeb951c1d5346086744ede254da47fe0f6294950a64b23bf1b3cb4d44c330020b57a6c55994fdb32
+ checksum: 10/ef51cd75eaf037c2b2c69a0236a3b2891c657c339c5b357e5aa8ba84d9e1626bbbd76bf954d578f1caad3bbe2bc7d62097eace475ce62a7d8bfaafef5239d0ad
languageName: node
linkType: hard