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}
+
+ 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 - +