diff --git a/web/package.json b/web/package.json index 203e349..7959d06 100644 --- a/web/package.json +++ b/web/package.json @@ -67,7 +67,7 @@ "dependencies": { "@cyntler/react-doc-viewer": "^1.16.3", "@kleros/kleros-app": "^2.0.1", - "@kleros/ui-components-library": "^2.15.0", + "@kleros/ui-components-library": "^2.19.0", "@sentry/react": "^7.93.0", "@sentry/tracing": "^7.93.0", "@tanstack/react-query": "^5.61.5", diff --git a/web/src/assets/svgs/header/escrow.svg b/web/src/assets/svgs/header/escrow.svg index a7290c1..a2620fc 100644 --- a/web/src/assets/svgs/header/escrow.svg +++ b/web/src/assets/svgs/header/escrow.svg @@ -1,6 +1,6 @@ - - + + - - + + diff --git a/web/src/assets/svgs/hero/hero-darkmode-desktop.svg b/web/src/assets/svgs/hero/hero-darkmode-desktop.svg index 61c2b8f..9969332 100644 --- a/web/src/assets/svgs/hero/hero-darkmode-desktop.svg +++ b/web/src/assets/svgs/hero/hero-darkmode-desktop.svg @@ -1,15 +1,15 @@ - - - - - - - - + + + + + + + + - - + + diff --git a/web/src/assets/svgs/hero/hero-darkmode-mobile.svg b/web/src/assets/svgs/hero/hero-darkmode-mobile.svg index 8d7d4cf..7bc445f 100644 --- a/web/src/assets/svgs/hero/hero-darkmode-mobile.svg +++ b/web/src/assets/svgs/hero/hero-darkmode-mobile.svg @@ -1,20 +1,20 @@ - - - - - - - - - - + + + + + + + + + + - + diff --git a/web/src/assets/svgs/socialmedia/discord.svg b/web/src/assets/svgs/socialmedia/discord.svg index cd9ecfe..8689eef 100644 --- a/web/src/assets/svgs/socialmedia/discord.svg +++ b/web/src/assets/svgs/socialmedia/discord.svg @@ -1,10 +1,10 @@ - + - + diff --git a/web/src/assets/svgs/socialmedia/etherscan.svg b/web/src/assets/svgs/socialmedia/etherscan.svg index bb140d2..56aea03 100644 --- a/web/src/assets/svgs/socialmedia/etherscan.svg +++ b/web/src/assets/svgs/socialmedia/etherscan.svg @@ -1,10 +1,10 @@ - + - + diff --git a/web/src/assets/svgs/socialmedia/ghost-blog.svg b/web/src/assets/svgs/socialmedia/ghost-blog.svg index 6734e2d..cbd9a81 100644 --- a/web/src/assets/svgs/socialmedia/ghost-blog.svg +++ b/web/src/assets/svgs/socialmedia/ghost-blog.svg @@ -1,10 +1,10 @@ - + - + diff --git a/web/src/assets/svgs/socialmedia/github.svg b/web/src/assets/svgs/socialmedia/github.svg index e38d902..74c5a4a 100644 --- a/web/src/assets/svgs/socialmedia/github.svg +++ b/web/src/assets/svgs/socialmedia/github.svg @@ -1,10 +1,10 @@ - + - + diff --git a/web/src/assets/svgs/socialmedia/linkedin.svg b/web/src/assets/svgs/socialmedia/linkedin.svg index 6a710c4..0b10e33 100644 --- a/web/src/assets/svgs/socialmedia/linkedin.svg +++ b/web/src/assets/svgs/socialmedia/linkedin.svg @@ -1,10 +1,10 @@ - + - + diff --git a/web/src/assets/svgs/socialmedia/reddit.svg b/web/src/assets/svgs/socialmedia/reddit.svg index 56f3445..29638ab 100644 --- a/web/src/assets/svgs/socialmedia/reddit.svg +++ b/web/src/assets/svgs/socialmedia/reddit.svg @@ -1,10 +1,10 @@ - + - + diff --git a/web/src/assets/svgs/socialmedia/slack.svg b/web/src/assets/svgs/socialmedia/slack.svg index 9a2a637..25551ed 100644 --- a/web/src/assets/svgs/socialmedia/slack.svg +++ b/web/src/assets/svgs/socialmedia/slack.svg @@ -1,10 +1,10 @@ - + - + diff --git a/web/src/assets/svgs/socialmedia/snapshot.svg b/web/src/assets/svgs/socialmedia/snapshot.svg index dee191a..fa69e36 100644 --- a/web/src/assets/svgs/socialmedia/snapshot.svg +++ b/web/src/assets/svgs/socialmedia/snapshot.svg @@ -1,10 +1,10 @@ - + - + diff --git a/web/src/assets/svgs/socialmedia/telegram.svg b/web/src/assets/svgs/socialmedia/telegram.svg index 22e46b1..85690c4 100644 --- a/web/src/assets/svgs/socialmedia/telegram.svg +++ b/web/src/assets/svgs/socialmedia/telegram.svg @@ -1,10 +1,10 @@ - + - + diff --git a/web/src/assets/svgs/socialmedia/youtube.svg b/web/src/assets/svgs/socialmedia/youtube.svg index 42fbfdc..6411254 100644 --- a/web/src/assets/svgs/socialmedia/youtube.svg +++ b/web/src/assets/svgs/socialmedia/youtube.svg @@ -1,10 +1,10 @@ - + - + diff --git a/web/src/components/ConnectWallet/AccountDisplay.tsx b/web/src/components/ConnectWallet/AccountDisplay.tsx index ded18b6..bc44baf 100644 --- a/web/src/components/ConnectWallet/AccountDisplay.tsx +++ b/web/src/components/ConnectWallet/AccountDisplay.tsx @@ -4,8 +4,9 @@ import styled, { css } from "styled-components"; import Identicon from "react-identicons"; import { isAddress } from "viem"; import { normalize } from "viem/ens"; -import { useAccount, useEnsAvatar, useEnsName } from "wagmi"; +import { useAccount, useChainId, useEnsAvatar, useEnsName } from "wagmi"; +import { getChain } from "consts/chains"; import { shortenAddress } from "utils/shortenAddress"; import { landscapeStyle } from "styles/landscapeStyle"; @@ -20,10 +21,22 @@ const Container = styled.div` align-items: center; background-color: ${({ theme }) => theme.whiteBackground}; padding: 0px; + cursor: pointer; + + &:hover { + label { + color: ${({ theme }) => theme.white} !important; + transition: color 0.2s; + } + } ${landscapeStyle( () => css` - background-color: ${({ theme }) => theme.whiteLowOpacity}; + background-color: ${({ theme }) => theme.whiteLowOpacitySubtle}; + &:hover { + transition: background-color 0.1s; + background-color: ${({ theme }) => theme.whiteLowOpacityStrong}; + } flex-direction: row; align-content: center; border-radius: 300px; @@ -49,13 +62,14 @@ const AccountContainer = styled.div` () => css` gap: 12px; > label { - color: ${({ theme }) => theme.primaryText}; + color: ${({ theme }) => theme.white}CC !important; font-weight: 400; font-size: 14px; } ` )} `; + const ChainConnectionContainer = styled.div` display: flex; width: fit-content; @@ -143,7 +157,8 @@ export const AddressOrName: React.FC = ({ address: propAddress } }; export const ChainDisplay: React.FC = () => { - const { chain } = useAccount(); + const chainId = useChainId(); + const chain = getChain(chainId); return ; }; diff --git a/web/src/components/ExternalLink.tsx b/web/src/components/ExternalLink.tsx new file mode 100644 index 0000000..8470386 --- /dev/null +++ b/web/src/components/ExternalLink.tsx @@ -0,0 +1,9 @@ +import styled from "styled-components"; + +import { Link } from "react-router-dom"; + +export const ExternalLink = styled(Link)` + :hover { + text-decoration: underline; + } +`; diff --git a/web/src/components/LightButton.tsx b/web/src/components/LightButton.tsx index 3ade4bc..86307d5 100644 --- a/web/src/components/LightButton.tsx +++ b/web/src/components/LightButton.tsx @@ -1,22 +1,38 @@ import React from "react"; -import styled from "styled-components"; +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)` +const StyledButton = styled(Button)<{ isMobileNavbar?: boolean }>` + ${hoverShortTransitionTiming} background-color: transparent; - padding-left: 0; + padding: 8px !important; + border-radius: 7px; .button-text { color: ${({ theme }) => theme.primaryText}; font-weight: 400; } .button-svg { - fill: ${({ theme }) => theme.secondaryPurple}; + fill: ${({ theme, isMobileNavbar }) => (isMobileNavbar ? theme.secondaryText : `${theme.white}BF`)} !important; } - :focus, - :hover { - background-color: transparent; + &:hover { + .button-svg { + fill: ${({ theme, isMobileNavbar }) => (isMobileNavbar ? theme.primaryText : `${theme.white}`)} !important; + } + background-color: ${({ theme }) => theme.whiteLowOpacityStrong}; } + + ${landscapeStyle( + () => css` + padding: 8px !important; + .button-svg { + margin-right: 0; + } + ` + )} `; interface ILightButton { @@ -25,10 +41,11 @@ interface ILightButton { onClick?: React.MouseEventHandler; disabled?: boolean; className?: string; + isMobileNavbar?: boolean; } -const LightButton: React.FC = ({ text, Icon, onClick, disabled, className }) => ( - +const LightButton: React.FC = ({ text, Icon, onClick, disabled, className, isMobileNavbar }) => ( + ); export default LightButton; diff --git a/web/src/components/OverlayPortal.tsx b/web/src/components/OverlayPortal.tsx new file mode 100644 index 0000000..b2f3c94 --- /dev/null +++ b/web/src/components/OverlayPortal.tsx @@ -0,0 +1,18 @@ +import React from "react"; +import ReactDOM from "react-dom"; +import styled from "styled-components"; + +const PortalContainer = styled.div` + position: fixed; + top: 0; + left: 0; + z-index: 9999; + width: 100%; + height: 100%; +`; + +const OverlayPortal: React.FC<{ children: React.ReactNode }> = ({ children }) => { + return ReactDOM.createPortal({children}, document.body); +}; + +export default OverlayPortal; diff --git a/web/src/components/PreviewCard/Header.tsx b/web/src/components/PreviewCard/Header.tsx index 9393490..6d3f2ec 100644 --- a/web/src/components/PreviewCard/Header.tsx +++ b/web/src/components/PreviewCard/Header.tsx @@ -14,7 +14,7 @@ const Container = styled.div` flex-direction: row; justify-content: space-between; flex-wrap: wrap; - gap: 20px; + gap: 12px; `; const StyledLabel = styled.label` @@ -26,6 +26,7 @@ const StyledHeader = styled.h1` flex-wrap: wrap; word-break: break-word; width: 100%; + font-size: ${responsiveSize(20, 24)}; `; const LeftContent = styled.div` diff --git a/web/src/components/PreviewCard/Terms/index.tsx b/web/src/components/PreviewCard/Terms/index.tsx index 590170b..cb97b42 100644 --- a/web/src/components/PreviewCard/Terms/index.tsx +++ b/web/src/components/PreviewCard/Terms/index.tsx @@ -1,5 +1,8 @@ import React from "react"; -import styled from "styled-components"; + +import styled, { css } from "styled-components"; +import { landscapeStyle } from "styles/landscapeStyle"; + import AttachedFile from "./AttachedFile"; import Description from "./Description"; import Header from "./Header"; @@ -7,7 +10,13 @@ import Header from "./Header"; const Container = styled.div` display: flex; flex-direction: column; - gap: 24px; + gap: 16px; + + ${landscapeStyle( + () => css` + gap: 24px; + ` + )} `; interface ITerms { diff --git a/web/src/components/PreviewCard/index.tsx b/web/src/components/PreviewCard/index.tsx index 9e8803c..d24e394 100644 --- a/web/src/components/PreviewCard/index.tsx +++ b/web/src/components/PreviewCard/index.tsx @@ -2,7 +2,6 @@ import React from "react"; import styled, { css } from "styled-components"; import { landscapeStyle } from "styles/landscapeStyle"; import { Card } from "@kleros/ui-components-library"; -import { responsiveSize } from "styles/responsiveSize"; import Header from "./Header"; import TransactionInfo from "components/TransactionInfo"; import Terms from "./Terms"; @@ -11,14 +10,12 @@ import PreviewCardButtons from "pages/MyTransactions/TransactionDetails/PreviewC import { DisputeRequest, HasToPayFee, Payment, SettlementProposal, TransactionResolved } from "src/graphql/graphql"; export const StyledCard = styled(Card)<{ isPreview?: boolean }>` - height: auto; - min-height: 100px; - width: 86vw; - align-self: center; display: flex; flex-direction: column; - gap: 32px; - padding: ${responsiveSize(24, 32)}; + gap: 16px; + padding: 20px 16px 16px; + width: 100%; + height: auto; ${({ isPreview }) => isPreview && @@ -28,7 +25,8 @@ export const StyledCard = styled(Card)<{ isPreview?: boolean }>` ${landscapeStyle( () => css` - max-width: 100%; + padding: 32px; + gap: 24px; ` )} `; @@ -44,7 +42,7 @@ export const Divider = styled.hr` const TransactionInfoContainer = styled.div` display: flex; flex-direction: column; - gap: 32px; + gap: 24px; `; interface IPreviewCard { diff --git a/web/src/components/TransactionCard/index.tsx b/web/src/components/TransactionCard/index.tsx index d9d2bb8..2803481 100644 --- a/web/src/components/TransactionCard/index.tsx +++ b/web/src/components/TransactionCard/index.tsx @@ -1,20 +1,26 @@ import React from "react"; -import styled from "styled-components"; -import { responsiveSize } from "styles/responsiveSize"; +import styled, { css } from "styled-components"; + +import { landscapeStyle } from "styles/landscapeStyle"; + import { Card } from "@kleros/ui-components-library"; import { formatEther } from "viem"; + import { useIsList } from "context/IsListProvider"; import { mapStatusToEnum } from "utils/mapStatusToEnum"; import { isUndefined } from "utils/index"; -import { StyledSkeleton, StyledSkeletonTitle } from "../StyledSkeleton"; -import TransactionInfo from "../TransactionInfo"; -import StatusBanner from "./StatusBanner"; + import { useNavigateAndScrollTop } from "hooks/useNavigateAndScrollTop"; import { useNativeTokenSymbol } from "hooks/useNativeTokenSymbol"; import useFetchIpfsJson from "hooks/useFetchIpfsJson"; import { useTokenMetadata } from "hooks/useTokenMetadata"; + import { TransactionDetailsFragment } from "src/graphql/graphql"; +import { StyledSkeleton, StyledSkeletonTitle } from "../StyledSkeleton"; +import TransactionInfo from "../TransactionInfo"; +import StatusBanner from "./StatusBanner"; + const StyledCard = styled(Card)` width: 100%; height: 260px; @@ -29,10 +35,16 @@ const StyledListItem = styled(Card)` const CardContainer = styled.div` height: calc(100% - 45px); - padding: ${responsiveSize(20, 24)}; + padding: 20px 16px; display: flex; flex-direction: column; justify-content: space-between; + + ${landscapeStyle( + () => css` + padding: 20px 24px; + ` + )} `; const ListContainer = styled.div` diff --git a/web/src/components/TransactionInfo/index.tsx b/web/src/components/TransactionInfo/index.tsx index c575ab3..ab624c1 100644 --- a/web/src/components/TransactionInfo/index.tsx +++ b/web/src/components/TransactionInfo/index.tsx @@ -42,6 +42,15 @@ const RestOfFieldsContainer = styled.div<{ isList?: boolean; isPreview?: boolean width: 100%; height: 100%; + ${({ isPreview }) => + isPreview && + css` + gap: 16px 32px; + flex-direction: row; + flex-wrap: wrap; + justify-content: flex-start; + `}; + ${({ isList, isPreview }) => isList && !isPreview && @@ -62,14 +71,7 @@ const RestOfFieldsContainer = styled.div<{ isList?: boolean; isPreview?: boolean ` )} `}; - ${({ isPreview }) => - isPreview && - css` - gap: 32px; - flex-direction: row; - flex-wrap: wrap; - justify-content: flex-start; - `}; + `; const StyledA = styled.a` diff --git a/web/src/components/TransactionsDisplay/Filters.tsx b/web/src/components/TransactionsDisplay/Filters.tsx index 1a17c30..e2f1b9b 100644 --- a/web/src/components/TransactionsDisplay/Filters.tsx +++ b/web/src/components/TransactionsDisplay/Filters.tsx @@ -1,13 +1,17 @@ import React from "react"; -import styled, { useTheme } from "styled-components"; + +import styled, { css } from "styled-components"; +import { hoverShortTransitionTiming } from "styles/commonStyles"; + import { useNavigate, useParams } from "react-router-dom"; -import { useWindowSize } from "react-use"; import { DropdownSelect } from "@kleros/ui-components-library"; + import { useIsList } from "context/IsListProvider"; +import useIsDesktop from "hooks/useIsDesktop"; +import { decodeURIFilter, encodeURIFilter, useRootPath } from "utils/uri"; + import ListIcon from "svgs/icons/list.svg"; import GridIcon from "svgs/icons/grid.svg"; -import { BREAKPOINT_LANDSCAPE } from "styles/landscapeStyle"; -import { decodeURIFilter, encodeURIFilter, useRootPath } from "utils/uri"; const Container = styled.div` display: flex; @@ -16,15 +20,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; @@ -32,36 +27,40 @@ 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 = () => { - const theme = useTheme(); const { order, filter } = useParams(); - const { ruled, period, ...filterObject } = decodeURIFilter(filter ?? "all"); + const { ...filterObject } = decodeURIFilter(filter ?? "all"); const navigate = useNavigate(); const location = useRootPath(); - const handleStatusChange = (value: string | number) => { - const parsedValue = JSON.parse(value as string); - const encodedFilter = encodeURIFilter({ ...filterObject, ...parsedValue }); - navigate(`${location}/1/${order}/${encodedFilter}`); - }; - const handleOrderChange = (value: string | number) => { - const encodedFilter = encodeURIFilter({ ruled, period, ...filterObject }); + const encodedFilter = encodeURIFilter({ ...filterObject }); navigate(`${location}/1/${value}/${encodedFilter}`); }; - const { width } = useWindowSize(); const { isList, setIsList } = useIsList(); - const screenIsBig = width > BREAKPOINT_LANDSCAPE; + const isDesktop = useIsDesktop(); return ( @@ -75,14 +74,14 @@ const Filters: React.FC = () => { defaultValue={order} callback={handleOrderChange} /> - {screenIsBig ? ( + {isDesktop ? ( {isList ? ( setIsList(false)} /> ) : ( { - if (screenIsBig) { + if (isDesktop) { setIsList(true); } }} diff --git a/web/src/components/TransactionsDisplay/Search.tsx b/web/src/components/TransactionsDisplay/Search.tsx index 0abfa78..b6ead52 100644 --- a/web/src/components/TransactionsDisplay/Search.tsx +++ b/web/src/components/TransactionsDisplay/Search.tsx @@ -1,7 +1,6 @@ import React, { useState } from "react"; import styled, { css } from "styled-components"; import { landscapeStyle } from "styles/landscapeStyle"; -import { responsiveSize } from "styles/responsiveSize"; import { useNavigate, useParams } from "react-router-dom"; import { useDebounce } from "react-use"; import { Searchbar, DropdownSelect } from "@kleros/ui-components-library"; @@ -11,17 +10,25 @@ import { isEmpty } from "src/utils"; const Container = styled.div` display: flex; flex-direction: column; - gap: 4px; + gap: 8px; ${landscapeStyle( - () => - css` + () => + css` flex-direction: row; - gap: ${responsiveSize(4, 22)}; + gap: 16px; ` - )} +)} `; +const StyledDropdownSelect = styled(DropdownSelect)` + [class*="button__Container"] { + [class*="base-item__Item"] { + border-left: 1px solid transparent; + } + } +` + const SearchBarContainer = styled.div` width: 100%; display: flex; @@ -68,15 +75,7 @@ const Search: React.FC = () => { return ( - - setSearch(e.target.value)} - /> - - { defaultValue={decodedFilter.status ?? "all"} callback={(value) => handleStatusChange(value)} /> + + setSearch(e.target.value)} + /> + ); }; diff --git a/web/src/components/TransactionsDisplay/StatsAndFilters.tsx b/web/src/components/TransactionsDisplay/StatsAndFilters.tsx index 255d1a3..a360c66 100644 --- a/web/src/components/TransactionsDisplay/StatsAndFilters.tsx +++ b/web/src/components/TransactionsDisplay/StatsAndFilters.tsx @@ -1,5 +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"; @@ -7,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/TransactionsDisplay/TransactionsGrid.tsx b/web/src/components/TransactionsDisplay/TransactionsGrid.tsx index 119c66c..5a74bf1 100644 --- a/web/src/components/TransactionsDisplay/TransactionsGrid.tsx +++ b/web/src/components/TransactionsDisplay/TransactionsGrid.tsx @@ -12,9 +12,9 @@ import TransactionCard from "components/TransactionCard"; import { TransactionDetailsFragment } from "src/graphql/graphql"; const GridContainer = styled.div` - --gap: 24px; + --gap: 16px; display: grid; - grid-template-columns: repeat(auto-fill, minmax(min(100%, max(348px, (100% - var(--gap) * 2)/3)), 1fr)); + grid-template-columns: repeat(auto-fill, minmax(min(100%, max(312px, (100% - var(--gap) * 2)/3)), 1fr)); align-items: center; gap: var(--gap); `; diff --git a/web/src/components/TransactionsDisplay/index.tsx b/web/src/components/TransactionsDisplay/index.tsx index a296e29..6bf02f5 100644 --- a/web/src/components/TransactionsDisplay/index.tsx +++ b/web/src/components/TransactionsDisplay/index.tsx @@ -7,7 +7,12 @@ import { responsiveSize } from "styles/responsiveSize"; import { TransactionDetailsFragment } from "src/graphql/graphql"; const StyledTitle = styled.h1` - margin-bottom: ${responsiveSize(32, 48)}; + margin-bottom: ${responsiveSize(12, 24)}; + font-size: ${responsiveSize(20, 24)}; +`; + +const StyledLabel = styled.label` + font-size: ${responsiveSize(14, 16)}; `; interface ITransactionsDisplay extends ITransactionsGrid { @@ -36,7 +41,7 @@ const TransactionsDisplay: React.FC = ({ {transactions?.length === 0 ? ( -

No transactions found

+ No transactions found ) : ( = { - [arbitrumSepolia.id]: arbitrumSepolia, + [isProductionDeployment() ? arbitrum.id : arbitrumSepolia.id]: isProductionDeployment() ? arbitrum : arbitrumSepolia, }; -export const SUPPORTED_CHAIN_IDS = Object.keys(SUPPORTED_CHAINS); +// Read Only export const QUERY_CHAINS: Record = { - [gnosisChiado.id]: gnosisChiado, + [isProductionDeployment() ? gnosis.id : gnosisChiado.id]: isProductionDeployment() ? gnosis : gnosisChiado, + [mainnet.id]: mainnet, }; export const ALL_CHAINS = [...Object.values(SUPPORTED_CHAINS), ...Object.values(QUERY_CHAINS)]; +export const SUPPORTED_CHAIN_IDS = Object.keys(SUPPORTED_CHAINS); + export const QUERY_CHAIN_IDS = Object.keys(QUERY_CHAINS); + +export const getChain = (chainId: number): Chain | null => + extractChain({ + chains: ALL_CHAINS, + id: chainId, + }); diff --git a/web/src/consts/index.ts b/web/src/consts/index.ts index 05cfc74..fa775d8 100644 --- a/web/src/consts/index.ts +++ b/web/src/consts/index.ts @@ -19,3 +19,6 @@ export const EMAIL_REGEX = export const TELEGRAM_REGEX = /^@\w{5,32}$/; export const ETH_ADDRESS_REGEX = /^0x[a-fA-F0-9]{40}$/; export const ETH_SIGNATURE_REGEX = /^0x[a-fA-F0-9]{130}$/; + +export const isProductionDeployment = () => import.meta.env.REACT_APP_DEPLOYMENT === "mainnet"; +export const isTestnetDeployment = () => import.meta.env.REACT_APP_DEPLOYMENT === "testnet"; diff --git a/web/src/consts/socialmedia.tsx b/web/src/consts/socialmedia.tsx index 2318054..9f1500c 100644 --- a/web/src/consts/socialmedia.tsx +++ b/web/src/consts/socialmedia.tsx @@ -1,5 +1,3 @@ -import React from "react"; - import DiscordLogo from "svgs/socialmedia/discord.svg"; import GithubLogo from "svgs/socialmedia/github.svg"; import LinkedinLogo from "svgs/socialmedia/linkedin.svg"; @@ -9,27 +7,27 @@ import XLogo from "svgs/socialmedia/x.svg"; export const socialmedia = { telegram: { - icon: , + icon: TelegramLogo, url: "https://t.me/kleros", }, x: { - icon: , + icon: XLogo, url: "https://x.com/kleros_io", }, discord: { - icon: , + icon: DiscordLogo, url: "https://discord.com/invite/MhXQGCyHd9", }, youtube: { - icon: , + icon: YouTubeLogo, url: "https://youtube.com/@kleros_io", }, github: { - icon: , + icon: GithubLogo, url: "https://github.com/kleros", }, linkedin: { - icon: , + icon: LinkedinLogo, url: "https://www.linkedin.com/company/kleros/", }, }; diff --git a/web/src/favicon.ico b/web/src/favicon.ico index b2c98bb..e1b782d 100644 Binary files a/web/src/favicon.ico and b/web/src/favicon.ico differ diff --git a/web/src/hooks/useIsDesktop.tsx b/web/src/hooks/useIsDesktop.tsx new file mode 100644 index 0000000..1ff105d --- /dev/null +++ b/web/src/hooks/useIsDesktop.tsx @@ -0,0 +1,12 @@ +import { useMemo } from "react"; + +import { useWindowSize } from "react-use"; + +import { BREAKPOINT_LANDSCAPE } from "styles/landscapeStyle"; + +const useIsDesktop = () => { + const { width } = useWindowSize(); + return useMemo(() => width > BREAKPOINT_LANDSCAPE, [width]); +}; + +export default useIsDesktop; diff --git a/web/src/index.html b/web/src/index.html index f209b8a..1c5b631 100644 --- a/web/src/index.html +++ b/web/src/index.html @@ -12,7 +12,7 @@ content="dispute resolution, decentralized arbitration, Kleros, blockchain court" /> - Kleros · Escrow V2 + Kleros · Escrow
diff --git a/web/src/layout/Footer/index.tsx b/web/src/layout/Footer/index.tsx index d967919..bebb00c 100644 --- a/web/src/layout/Footer/index.tsx +++ b/web/src/layout/Footer/index.tsx @@ -1,65 +1,72 @@ 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"; + import { socialmedia } from "consts/socialmedia"; +import LightButton from "components/LightButton"; +import { ExternalLink } from "components/ExternalLink"; + const Container = styled.div` - height: 122px; + height: 114px; width: 100%; - background-color: ${({ theme }) => theme.primaryPurple}; + background-color: ${({ theme }) => (theme.name === "dark" ? theme.lightBlue : theme.primaryPurple)}; display: flex; flex-direction: column; justify-content: center; align-items: center; - padding: 0 32px 8px 32px; - gap: 24px; + padding: 8px; + gap: 16px; ${landscapeStyle( () => css` height: 64px; flex-direction: row; justify-content: space-between; - padding-bottom: 0; + padding: 0 32px; ` )} +`; - .secured-by-kleros { - min-height: 24px; +const StyledSecuredByKlerosLogo = styled(SecuredByKlerosLogo)` + ${hoverShortTransitionTiming} + min-height: 24px; + + path { + fill: ${({ theme }) => theme.white}BF; } - .socialmedia { - display: flex; - gap: 16px; - justify-content: center; + :hover path { + fill: ${({ theme }) => theme.white}; + } +`; + +const StyledSocialMedia = styled.div` + display: flex; - a { - display: inline-block; - svg { - height: 16px; - width: 16px; - max-heigth: 16px; - max-width: 16px; - fill: white; - } - } + .button-svg { + margin-right: 0; } `; const SecuredByKleros: React.FC = () => ( - - - + + + ); const SocialMedia = () => ( -
+ {Object.values(socialmedia).map((site, i) => ( - - {site.icon} - + + + ))} -
+ ); const Footer: React.FC = () => ( @@ -69,4 +76,4 @@ const Footer: React.FC = () => ( ); -export default Footer; \ No newline at end of file +export default Footer; diff --git a/web/src/layout/Header/DesktopHeader.tsx b/web/src/layout/Header/DesktopHeader.tsx index e2becf8..9b4cc07 100644 --- a/web/src/layout/Header/DesktopHeader.tsx +++ b/web/src/layout/Header/DesktopHeader.tsx @@ -1,24 +1,33 @@ import React, { useCallback, useEffect, useState } from "react"; import styled, { css } from "styled-components"; + import { landscapeStyle } from "styles/landscapeStyle"; +import { responsiveSize } from "styles/responsiveSize"; + import { useToggle } from "react-use"; -import { Link } from "react-router-dom"; import { useAccount } from "wagmi"; + import { useLockOverlayScroll } from "hooks/useLockOverlayScroll"; import { DEFAULT_CHAIN } from "consts/chains"; + import KlerosSolutionsIcon from "svgs/menu-icons/kleros-solutions.svg"; -import EscrowLogo from "svgs/header/escrow.svg"; + import ConnectWallet from "components/ConnectWallet"; import LightButton from "components/LightButton"; +import OverlayPortal from "components/OverlayPortal"; +import { Overlay } from "components/Overlay"; + import DappList from "./navbar/DappList"; import Explore from "./navbar/Explore"; import Menu from "./navbar/Menu"; import Help from "./navbar/Menu/Help"; import Settings from "./navbar/Menu/Settings"; -import { PopupContainer } from "."; +import Logo from "./Logo"; + const Container = styled.div` display: none; position: absolute; + height: 64px; ${landscapeStyle( () => css` @@ -33,6 +42,7 @@ const Container = styled.div` const LeftSide = styled.div` display: flex; + gap: 8px; `; const MiddleSide = styled.div` @@ -46,7 +56,8 @@ const MiddleSide = styled.div` const RightSide = styled.div` display: flex; - gap: calc(8px + (16 - 8) * ((100vw - 300px) / (1024 - 300))); + gap: ${responsiveSize(4, 8)}; + margin-left: 8px; canvas { width: 20px; @@ -56,13 +67,6 @@ const RightSide = styled.div` const LightButtonContainer = styled.div` display: flex; align-items: center; - width: 16px; - margin-left: calc(4px + (8 - 4) * ((100vw - 375px) / (1250 - 375))); - margin-right: calc(12px + (16 - 12) * ((100vw - 375px) / (1250 - 375))); -`; - -const StyledLink = styled(Link)` - min-height: 48px; `; const StyledKlerosSolutionsIcon = styled(KlerosSolutionsIcon)` @@ -72,17 +76,8 @@ const StyledKlerosSolutionsIcon = styled(KlerosSolutionsIcon)` const ConnectWalletContainer = styled.div<{ isConnected: boolean; isDefaultChain: boolean }>` label { color: ${({ theme }) => theme.white}; + cursor: pointer; } - - ${({ isConnected, isDefaultChain }) => - isConnected && - isDefaultChain && - css` - cursor: pointer; - & > * { - pointer-events: none; - } - `} `; const DesktopHeader = () => { @@ -109,11 +104,15 @@ const DesktopHeader = () => { - + { + toggleIsDappListOpen(); + }} + Icon={StyledKlerosSolutionsIcon} + /> - - - + @@ -131,11 +130,13 @@ const DesktopHeader = () => { {(isDappListOpen || isHelpOpen || isSettingsOpen) && ( - - {isDappListOpen && } - {isHelpOpen && } - {isSettingsOpen && } - + + + {isDappListOpen && } + {isHelpOpen && } + {isSettingsOpen && } + + )} ); diff --git a/web/src/layout/Header/Logo.tsx b/web/src/layout/Header/Logo.tsx new file mode 100644 index 0000000..ccc7ab8 --- /dev/null +++ b/web/src/layout/Header/Logo.tsx @@ -0,0 +1,38 @@ +import React from "react"; +import styled from "styled-components"; + +import { hoverShortTransitionTiming } from "styles/commonStyles"; + +import { Link } from "react-router-dom"; + +import EscrowLogo from "svgs/header/escrow.svg"; + +const Container = styled.div` + display: flex; + flex-direction: row; + align-items: center; + gap: 16px; +`; + +const StyledEscrowLogo = styled(EscrowLogo)` + ${hoverShortTransitionTiming} + max-height: 40px; + width: auto; + + &:hover { + path { + fill: ${({ theme }) => theme.white}BF; + } + } +`; + +const Logo: React.FC = () => ( + + {" "} + + + + +); + +export default Logo; diff --git a/web/src/layout/Header/MobileHeader.tsx b/web/src/layout/Header/MobileHeader.tsx index c5730a8..b961d1f 100644 --- a/web/src/layout/Header/MobileHeader.tsx +++ b/web/src/layout/Header/MobileHeader.tsx @@ -1,18 +1,23 @@ import React, { useContext, useMemo, useRef } from "react"; import styled, { css } from "styled-components"; import { useClickAway, useToggle } from "react-use"; + import { landscapeStyle } from "styles/landscapeStyle"; + import { Link } from "react-router-dom"; -import EscrowLogo from "svgs/header/escrow.svg"; + import HamburgerIcon from "svgs/header/hamburger.svg"; + import LightButton from "components/LightButton"; import NavBar from "./navbar"; +import Logo from "./Logo"; const Container = styled.div` display: flex; align-items: center; justify-content: space-between; width: 100%; + height: 64px; ${landscapeStyle( () => css` @@ -33,10 +38,6 @@ const StyledLightButton = styled(LightButton)` } `; -const StyledLink = styled(Link)` - min-height: 48px; -`; - const OpenContext = React.createContext({ isOpen: false, toggleIsOpen: () => { @@ -56,9 +57,9 @@ const MobileHeader = () => { return ( - - - + + + diff --git a/web/src/layout/Header/index.tsx b/web/src/layout/Header/index.tsx index bb84141..1ac2aaf 100644 --- a/web/src/layout/Header/index.tsx +++ b/web/src/layout/Header/index.tsx @@ -1,18 +1,20 @@ import React from "react"; import styled from "styled-components"; -import MobileHeader from "./MobileHeader"; + import DesktopHeader from "./DesktopHeader"; +import MobileHeader from "./MobileHeader"; const Container = styled.div` + display: flex; + flex-wrap: wrap; position: sticky; + padding: 0 24px; z-index: 10; top: 0; width: 100%; - height: 64px; - background-color: ${({ theme }) => theme.primaryPurple}; - - padding: 0 24px; - display: flex; + background-color: ${({ theme }) => (theme.name === "dark" ? `${theme.lightBlue}A6` : theme.primaryPurple)}; + backdrop-filter: ${({ theme }) => (theme.name === "dark" ? "blur(12px)" : "none")}; + -webkit-backdrop-filter: ${({ theme }) => (theme.name === "dark" ? "blur(12px)" : "none")}; // Safari support `; export const PopupContainer = styled.div` diff --git a/web/src/layout/Header/navbar/DappList.tsx b/web/src/layout/Header/navbar/DappList.tsx index 407978c..508d40b 100644 --- a/web/src/layout/Header/navbar/DappList.tsx +++ b/web/src/layout/Header/navbar/DappList.tsx @@ -1,8 +1,11 @@ import React, { useRef } from "react"; import styled, { css } from "styled-components"; + import { landscapeStyle } from "styles/landscapeStyle"; import { responsiveSize } from "styles/responsiveSize"; + import { useClickAway } from "react-use"; + import Curate from "svgs/icons/curate-image.png"; import Resolver from "svgs/icons/dispute-resolver.svg"; import Escrow from "svgs/icons/escrow.svg"; @@ -10,15 +13,8 @@ import Governor from "svgs/icons/governor.svg"; import Court from "svgs/icons/kleros.svg"; import POH from "svgs/icons/poh-image.png"; import Vea from "svgs/icons/vea.svg"; -import Product from "./Product"; -const Header = styled.h1` - padding-top: 32px; - padding-bottom: 20px; - font-size: 24px; - font-weight: 600; - line-height: 32.68px; -`; +import Product from "./Product"; const Container = styled.div` display: flex; @@ -33,7 +29,6 @@ const Container = styled.div` width: 86vw; max-width: 480px; - min-width: 300px; border-radius: 3px; border: 1px solid ${({ theme }) => theme.stroke}; background-color: ${({ theme }) => theme.whiteBackground}; @@ -56,10 +51,17 @@ const Container = styled.div` )} `; +const Header = styled.h1` + padding-top: 24px; + font-size: 24px; + font-weight: 600; + line-height: 32.68px; +`; + const ItemsDiv = styled.div` display: grid; overflow-y: auto; - padding: 16px ${responsiveSize(8, 24, 480)}; + padding: 4px ${responsiveSize(8, 24)} 16px ${responsiveSize(8, 24)}; row-gap: 8px; column-gap: 2px; justify-items: center; diff --git a/web/src/layout/Header/navbar/Explore.tsx b/web/src/layout/Header/navbar/Explore.tsx index 1ca6984..e216591 100644 --- a/web/src/layout/Header/navbar/Explore.tsx +++ b/web/src/layout/Header/navbar/Explore.tsx @@ -1,30 +1,25 @@ import React from "react"; import styled, { css } from "styled-components"; import { landscapeStyle } from "styles/landscapeStyle"; -import { Link, LinkProps, useLocation } from "react-router-dom"; + +import { Link, useLocation } from "react-router-dom"; + import { useOpenContext } from "../MobileHeader"; const Container = styled.div` display: flex; - gap: 0px; flex-direction: column; ${landscapeStyle( () => css` flex-direction: row; - gap: calc(4px + (16 - 4) * ((100vw - 375px) / (1250 - 375))); ` )}; `; -const LinkContainer = styled.div` - display: flex; - min-height: 32px; - align-items: center; -`; - const Title = styled.h1` display: block; + margin-bottom: 8px; ${landscapeStyle( () => css` @@ -33,20 +28,24 @@ const Title = styled.h1` )}; `; -interface StyledLinkProps extends LinkProps { - isActive: boolean; -} - -const StyledLink = styled(({ isActive, ...props }: StyledLinkProps) => )` - color: ${({ theme }) => theme.primaryText}; +const StyledLink = styled(Link) <{ isActive: boolean; isMobileNavbar?: boolean; }>` + display: flex; + align-items: center; text-decoration: none; font-size: 16px; + color: ${({ isActive, theme }) => (isActive ? theme.primaryText : `${theme.primaryText}BA`)}; + font-weight: ${({ isActive, isMobileNavbar }) => (isMobileNavbar && isActive ? "600" : "normal")}; + padding: 8px 8px 8px 0; + border-radius: 7px; - font-weight: ${({ isActive }: StyledLinkProps) => (isActive ? "600" : "normal")}; + &:hover { + color: ${({ theme, isMobileNavbar }) => (isMobileNavbar ? theme.primaryText : theme.white)} !important; + } ${landscapeStyle( () => css` - color: ${({ theme }) => theme.white}; + color: ${({ isActive, theme }) => (isActive ? theme.white : `${theme.white}BA`)}; + padding: 16px 8px; ` )}; `; @@ -56,7 +55,11 @@ const links = [ { to: "/transactions/display/1/desc/all", text: "My Transactions" }, ]; -const Explore: React.FC = () => { +interface IExplore { + isMobileNavbar?: boolean; +} + +const Explore: React.FC = ({ isMobileNavbar }) => { const location = useLocation(); const { toggleIsOpen } = useOpenContext(); @@ -64,11 +67,14 @@ const Explore: React.FC = () => { Explore {links.map(({ to, text }) => ( - - - {text} - - + + {text} + ))} ); diff --git a/web/src/layout/Header/navbar/Menu/Help.tsx b/web/src/layout/Header/navbar/Menu/Help.tsx index 280128f..0a4768f 100644 --- a/web/src/layout/Header/navbar/Menu/Help.tsx +++ b/web/src/layout/Header/navbar/Menu/Help.tsx @@ -1,14 +1,17 @@ import React, { useRef } from "react"; import styled, { css } from "styled-components"; import { landscapeStyle } from "styles/landscapeStyle"; + import { useClickAway } from "react-use"; + import Guide from "svgs/icons/book.svg"; import Bug from "svgs/icons/bug.svg"; import ETH from "svgs/icons/eth.svg"; import Faq from "svgs/menu-icons/help.svg"; import Telegram from "svgs/socialmedia/telegram.svg"; -import { IHelp } from ".."; + import Debug from "../Debug"; +import { IHelp } from "../index"; const Container = styled.div` display: flex; @@ -22,8 +25,7 @@ const Container = styled.div` left: 50%; transform: translateX(-50%); z-index: 1; - padding: 27px 10px; - gap: 23px; + padding: 12px 12px 24px 12px; border: 1px solid ${({ theme }) => theme.stroke}; background-color: ${({ theme }) => theme.whiteBackground}; border-radius: 3px; @@ -44,20 +46,25 @@ const Container = styled.div` const ListItem = styled.a` display: flex; gap: 8px; - padding: 0px 8px; + padding: 12px 8px; cursor: pointer; - :hover { - transform: scale(1.02) translateZ(0); - transition: 200ms; - transition-timing-function: cubic-bezier(0.3, 0, 0.2, 1); - backface-visibility: hidden; - } + transition: transform 0.2s; small { font-size: 16px; font-weight: 400; } + + :hover { + transform: scale(1.02); + } + + :hover small { + transition: color 0.1s; + color: ${({ theme }) => theme.secondaryPurple}; + } `; + const Icon = styled.svg` display: inline-block; width: 16px; @@ -101,7 +108,11 @@ const Help: React.FC = ({ toggleIsHelpOpen }) => { <> {ITEMS.map((item, index) => ( - + {item.text} diff --git a/web/src/layout/Header/navbar/Menu/index.tsx b/web/src/layout/Header/navbar/Menu/index.tsx index fb12c6e..354f690 100644 --- a/web/src/layout/Header/navbar/Menu/index.tsx +++ b/web/src/layout/Header/navbar/Menu/index.tsx @@ -1,25 +1,27 @@ import React from "react"; import styled, { css } from "styled-components"; -import { landscapeStyle } from "styles/landscapeStyle"; -import LightButton from "components/LightButton"; + import DarkModeIcon from "svgs/menu-icons/dark-mode.svg"; import HelpIcon from "svgs/menu-icons/help.svg"; import LightModeIcon from "svgs/menu-icons/light-mode.svg"; -import NotificationsIcon from "svgs/menu-icons/notifications.svg"; +// import NotificationsIcon from "svgs/menu-icons/notifications.svg"; import SettingsIcon from "svgs/menu-icons/settings.svg"; + import { useToggleTheme } from "hooks/useToggleThemeContext"; -import { IHelp, ISettings } from ".."; + +import { landscapeStyle } from "styles/landscapeStyle"; + +import LightButton from "components/LightButton"; + +import { IHelp, ISettings } from "../index"; const Container = styled.div` display: flex; - flex-direction: column; - gap: 0px; ${landscapeStyle( () => css` flex-direction: row; - gap: 8px; ` )} `; @@ -37,15 +39,8 @@ const ButtonContainer = styled.div` display: block; } - .button-svg { - fill: ${({ theme }) => theme.secondaryPurple}; - } - ${landscapeStyle( () => css` - .button-svg { - fill: ${({ theme }) => theme.white}; - } .button-text { display: none; } @@ -53,12 +48,16 @@ const ButtonContainer = styled.div` )} `; -const Menu: React.FC = ({ toggleIsHelpOpen, toggleIsSettingsOpen }) => { +interface IMenu { + isMobileNavbar?: boolean; +} + +const Menu: React.FC = ({ toggleIsHelpOpen, toggleIsSettingsOpen, isMobileNavbar }) => { const [theme, toggleTheme] = useToggleTheme(); const isLightTheme = theme === "light"; const buttons = [ - { text: "Notifications", Icon: NotificationsIcon }, + // { text: "Notifications", Icon: NotificationsIcon }, { text: "Settings", Icon: SettingsIcon, @@ -82,7 +81,7 @@ const Menu: React.FC = ({ toggleIsHelpOpen, toggleIsSettingsO {buttons.map(({ text, Icon, onClick }) => ( - + ))} diff --git a/web/src/layout/Header/navbar/Product.tsx b/web/src/layout/Header/navbar/Product.tsx index 8d568ac..09f27e7 100644 --- a/web/src/layout/Header/navbar/Product.tsx +++ b/web/src/layout/Header/navbar/Product.tsx @@ -1,23 +1,27 @@ -import React from "react"; +import React, { useState } from "react"; import styled from "styled-components"; + import { responsiveSize } from "styles/responsiveSize"; +import Skeleton from "react-loading-skeleton"; + const Container = styled.a` cursor: pointer; display: flex; flex-direction: column; align-items: center; - padding: 20px 8px 35px 8px; + padding: 16px 8px 28px 8px; max-width: 100px; border-radius: 3px; :hover { - transform: scale(1.05); - transition: 350ms; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition: + transform 0.15s, + background-color 0.3s; + transform: scale(1.02); + background-color: ${({ theme }) => theme.lightGrey}; } gap: 8px; width: ${responsiveSize(100, 130)}; - background-color: ${({ theme }) => theme.lightBackground}; `; @@ -26,9 +30,10 @@ const StyledIcon = styled.svg` height: 48px; `; -const StyledImg = styled.img` +const StyledImg = styled.img<{ isLoaded: boolean }>` width: 48px; height: 48px; + display: ${({ isLoaded }) => (isLoaded ? "block" : "none")}; `; const StyledSmall = styled.small` @@ -45,9 +50,18 @@ interface IProduct { } const Product: React.FC = ({ text, url, Icon }) => { + const [isImgLoaded, setIsImgLoaded] = useState(false); + return ( - {typeof Icon === "string" ? : } + {typeof Icon === "string" ? ( + <> + {!isImgLoaded ? : null} + setIsImgLoaded(true)} /> + + ) : ( + + )} {text} ); diff --git a/web/src/layout/Header/navbar/index.tsx b/web/src/layout/Header/navbar/index.tsx index 6d3b3d6..57b2a1d 100644 --- a/web/src/layout/Header/navbar/index.tsx +++ b/web/src/layout/Header/navbar/index.tsx @@ -1,19 +1,25 @@ import React from "react"; import styled from "styled-components"; + import { useToggle } from "react-use"; import { useAccount } from "wagmi"; + import { useLockOverlayScroll } from "hooks/useLockOverlayScroll"; + +import KlerosSolutionsIcon from "svgs/menu-icons/kleros-solutions.svg"; + +import ConnectWallet from "components/ConnectWallet"; +import LightButton from "components/LightButton"; +import OverlayPortal from "components/OverlayPortal"; +import { Overlay } from "components/Overlay"; + import { useOpenContext } from "../MobileHeader"; import DappList from "./DappList"; import Explore from "./Explore"; -import ConnectWallet from "components/ConnectWallet"; -import LightButton from "components/LightButton"; -import KlerosSolutionsIcon from "svgs/menu-icons/kleros-solutions.svg"; import Menu from "./Menu"; import Help from "./Menu/Help"; import Settings from "./Menu/Settings"; import { DisconnectWalletButton } from "./Menu/Settings/General"; -import { PopupContainer } from ".."; const Container = styled.div<{ isOpen: boolean }>` position: absolute; @@ -77,7 +83,7 @@ const NavBar: React.FC = () => {
- +
@@ -92,11 +98,13 @@ const NavBar: React.FC = () => {
{(isDappListOpen || isHelpOpen || isSettingsOpen) && ( - - {isDappListOpen && } - {isHelpOpen && } - {isSettingsOpen && } - + + + {isDappListOpen && } + {isHelpOpen && } + {isSettingsOpen && } + + )} ); diff --git a/web/src/pages/AttachmentDisplay/index.tsx b/web/src/pages/AttachmentDisplay/index.tsx index 647e4aa..d387c21 100644 --- a/web/src/pages/AttachmentDisplay/index.tsx +++ b/web/src/pages/AttachmentDisplay/index.tsx @@ -12,19 +12,9 @@ import Header from "./Header"; const FileViewer = lazy(() => import("components/FileViewer")); const Container = styled.div` - width: 100%; - background-color: ${({ theme }) => theme.lightBackground}; - padding: calc(24px + (136 - 24) * (min(max(100vw, 375px), 1250px) - 375px) / 875); - padding-top: calc(32px + (80 - 32) * (min(max(100vw, 375px), 1250px) - 375px) / 875); - padding-bottom: calc(76px + (96 - 76) * (min(max(100vw, 375px), 1250px) - 375px) / 875); - max-width: 1780px; - margin: 0 auto; -`; - -const AttachmentContainer = styled.div` - width: 100%; display: flex; flex-direction: column; + width: 100%; gap: 8px; `; @@ -53,25 +43,23 @@ const AttachmentDisplay: React.FC = () => { const url = searchParams.get("url"); return ( - -
- {url ? ( - <> - - Open in new tab - - - - - } - > - - - - ) : null} - +
+ {url ? ( + <> + + Open in new tab + + + + + } + > + + + + ) : null} ); }; diff --git a/web/src/pages/MyTransactions/TransactionDetails/WasItFulfilled/index.tsx b/web/src/pages/MyTransactions/TransactionDetails/WasItFulfilled/index.tsx index 19f2677..636d6f1 100644 --- a/web/src/pages/MyTransactions/TransactionDetails/WasItFulfilled/index.tsx +++ b/web/src/pages/MyTransactions/TransactionDetails/WasItFulfilled/index.tsx @@ -10,7 +10,7 @@ const StyledCard = styled(Card)` gap: 22px; background-color: ${({ theme }) => theme.mediumBlue}; border: 1px solid ${({ theme }) => theme.primaryBlue}; - width: 86vw; + width: 100%; height: auto; align-items: center; align-self: center; diff --git a/web/src/pages/MyTransactions/TransactionDetails/index.tsx b/web/src/pages/MyTransactions/TransactionDetails/index.tsx index 013ec63..75328b7 100644 --- a/web/src/pages/MyTransactions/TransactionDetails/index.tsx +++ b/web/src/pages/MyTransactions/TransactionDetails/index.tsx @@ -24,7 +24,8 @@ const OverviewContainer = styled.div` `; const Header = styled.h1` - margin-bottom: ${responsiveSize(16, 48)}; + margin-bottom: ${responsiveSize(12, 24)}; + font-size: ${responsiveSize(20, 24)}; `; const TransactionDetails: React.FC = () => { diff --git a/web/src/pages/MyTransactions/index.tsx b/web/src/pages/MyTransactions/index.tsx index 2af3aec..ee0c3a3 100644 --- a/web/src/pages/MyTransactions/index.tsx +++ b/web/src/pages/MyTransactions/index.tsx @@ -1,21 +1,31 @@ import React from "react"; -import styled from "styled-components"; +import styled, { css } from "styled-components"; + +import { MAX_WIDTH_LANDSCAPE, landscapeStyle } from "styles/landscapeStyle"; +import { responsiveSize } from "styles/responsiveSize"; + import { Route, Routes } from "react-router-dom"; import { useAccount } from "wagmi"; + import { DEFAULT_CHAIN } from "consts/chains"; +import { TransactionDetailsProvider } from "context/TransactionDetailsContext"; + import ConnectWallet from "components/ConnectWallet"; import TransactionsFetcher from "./TransactionsFetcher"; import TransactionDetails from "./TransactionDetails"; -import { TransactionDetailsProvider } from "context/TransactionDetailsContext"; const Container = styled.div` width: 100%; background-color: ${({ theme }) => theme.lightBackground}; - padding: calc(24px + (136 - 24) * (min(max(100vw, 375px), 1250px) - 375px) / 875); - padding-top: calc(32px + (80 - 32) * (min(max(100vw, 375px), 1250px) - 375px) / 875); - padding-bottom: calc(76px + (96 - 76) * (min(max(100vw, 375px), 1250px) - 375px) / 875); - max-width: 1780px; + padding: 32px 16px 40px; + max-width: ${MAX_WIDTH_LANDSCAPE}; margin: 0 auto; + + ${landscapeStyle( + () => css` + padding: 48px ${responsiveSize(0, 132)} 60px; + ` + )} `; export const ConnectWalletContainer = styled.div` diff --git a/web/src/pages/NewTransaction/EscrowDetails/TypeOfEscrow/EscrowOptions/index.tsx b/web/src/pages/NewTransaction/EscrowDetails/TypeOfEscrow/EscrowOptions/index.tsx index 22deb9c..7384d3f 100644 --- a/web/src/pages/NewTransaction/EscrowDetails/TypeOfEscrow/EscrowOptions/index.tsx +++ b/web/src/pages/NewTransaction/EscrowDetails/TypeOfEscrow/EscrowOptions/index.tsx @@ -1,7 +1,7 @@ import React from "react"; import styled, { css } from "styled-components"; import GeneralEscrow from "./GeneralEscrow"; -import CryptoSwap from "./CryptoSwap"; +// import CryptoSwap from "./CryptoSwap"; import { Card } from "@kleros/ui-components-library"; const Container = styled.div` @@ -31,7 +31,7 @@ const EscrowOptions: React.FC = () => { return ( - + {/* */} ); }; diff --git a/web/src/pages/NewTransaction/EscrowDetails/TypeOfEscrow/Info.tsx b/web/src/pages/NewTransaction/EscrowDetails/TypeOfEscrow/Info.tsx index 09e0340..0f5dc8b 100644 --- a/web/src/pages/NewTransaction/EscrowDetails/TypeOfEscrow/Info.tsx +++ b/web/src/pages/NewTransaction/EscrowDetails/TypeOfEscrow/Info.tsx @@ -8,7 +8,6 @@ import { landscapeStyle } from "styles/landscapeStyle"; const Container = styled.div` display: flex; justify-content: center; - width: 84vw; ${landscapeStyle( () => css` diff --git a/web/src/pages/NewTransaction/EscrowDetails/TypeOfEscrow/index.tsx b/web/src/pages/NewTransaction/EscrowDetails/TypeOfEscrow/index.tsx index 5692939..3348c1a 100644 --- a/web/src/pages/NewTransaction/EscrowDetails/TypeOfEscrow/index.tsx +++ b/web/src/pages/NewTransaction/EscrowDetails/TypeOfEscrow/index.tsx @@ -14,7 +14,8 @@ const Container = styled.div` const TypeOfEscrow: React.FC = () => { return ( -
+
+ {/*
*/} diff --git a/web/src/pages/NewTransaction/Header.tsx b/web/src/pages/NewTransaction/Header.tsx index 19c4083..e56cb01 100644 --- a/web/src/pages/NewTransaction/Header.tsx +++ b/web/src/pages/NewTransaction/Header.tsx @@ -1,15 +1,19 @@ import React from "react"; + import styled, { css } from "styled-components"; +import { responsiveSize } from "styles/responsiveSize"; import { landscapeStyle } from "styles/landscapeStyle"; const Container = styled.h1` - margin-bottom: 29px; + margin-bottom: 20px; width: 84vw; text-align: center; + font-size: ${responsiveSize(20, 24)}; ${landscapeStyle( () => css` width: auto; + margin-bottom: 29px; ` )} `; diff --git a/web/src/pages/NewTransaction/Preview/Header.tsx b/web/src/pages/NewTransaction/Preview/Header.tsx index 3700645..3d25088 100644 --- a/web/src/pages/NewTransaction/Preview/Header.tsx +++ b/web/src/pages/NewTransaction/Preview/Header.tsx @@ -6,8 +6,9 @@ const StyledHeader = styled.h1` margin: 0; color: ${({ theme }) => theme.secondaryPurple}; font-weight: 400; - margin-bottom: 32px; + margin-bottom: ${responsiveSize(20, 24)}; margin-top: ${responsiveSize(4, 20)}; + font-size: ${responsiveSize(20, 24)}; `; const Header: React.FC = () => { diff --git a/web/src/pages/NewTransaction/Terms/Payment/DestinationAddress.tsx b/web/src/pages/NewTransaction/Terms/Payment/DestinationAddress.tsx index 989e5eb..45ee358 100644 --- a/web/src/pages/NewTransaction/Terms/Payment/DestinationAddress.tsx +++ b/web/src/pages/NewTransaction/Terms/Payment/DestinationAddress.tsx @@ -10,7 +10,6 @@ import { ensDomainPattern, validateAddress } from "utils/validateAddress"; import { isEmpty } from "src/utils"; const StyledField = styled(Field)` - width: 84vw; margin-bottom: ${responsiveSize(68, 40)}; small { diff --git a/web/src/pages/NewTransaction/index.tsx b/web/src/pages/NewTransaction/index.tsx index 8f3ab66..6817a9d 100644 --- a/web/src/pages/NewTransaction/index.tsx +++ b/web/src/pages/NewTransaction/index.tsx @@ -1,8 +1,8 @@ import React from "react"; import { Navigate, Route, Routes, useLocation } from "react-router-dom"; -import styled from "styled-components"; +import styled, { css } from "styled-components"; import { useWindowSize } from "react-use"; -import { BREAKPOINT_LANDSCAPE } from "styles/landscapeStyle"; +import { BREAKPOINT_LANDSCAPE, MAX_WIDTH_LANDSCAPE, landscapeStyle } from "styles/landscapeStyle"; import Title from "./EscrowDetails/Title"; import TypeOfEscrow from "./EscrowDetails/TypeOfEscrow"; import HeroImage from "./HeroImage"; @@ -20,15 +20,17 @@ import { DEFAULT_CHAIN } from "consts/chains"; import { EnsureAuth } from "components/EnsureAuth"; const Container = styled.div` - display: flex; - flex-direction: column; width: 100%; background-color: ${({ theme }) => theme.lightBackground}; - padding: ${responsiveSize(24, 32)}; - padding-top: ${responsiveSize(36, 42)}; - padding-bottom: ${responsiveSize(76, 96)}; - max-width: 1780px; + padding: 24px 16px 40px; + max-width: ${MAX_WIDTH_LANDSCAPE}; margin: 0 auto; + + ${landscapeStyle( + () => css` + padding: 32px ${responsiveSize(0, 132)} 60px; + ` + )} `; const MiddleContentContainer = styled.div` diff --git a/web/src/styles/commonStyles.ts b/web/src/styles/commonStyles.ts new file mode 100644 index 0000000..f6ef00e --- /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/global-style.ts b/web/src/styles/global-style.ts index 4191267..1b548df 100644 --- a/web/src/styles/global-style.ts +++ b/web/src/styles/global-style.ts @@ -17,6 +17,7 @@ export const GlobalStyle = createGlobalStyle` body { font-family: "Open Sans", sans-serif; margin: 0px; + background-color: ${({ theme }) => theme.lightBlue} } html { diff --git a/web/src/styles/landscapeStyle.ts b/web/src/styles/landscapeStyle.ts index d81be50..ac781c1 100644 --- a/web/src/styles/landscapeStyle.ts +++ b/web/src/styles/landscapeStyle.ts @@ -1,9 +1,11 @@ import { css, DefaultTheme, FlattenInterpolation, ThemeProps } from "styled-components"; +export const MAX_WIDTH_LANDSCAPE = "1400px"; + export const BREAKPOINT_LANDSCAPE = 900; export const landscapeStyle = (styleFn: () => FlattenInterpolation>) => css` @media (min-width: ${BREAKPOINT_LANDSCAPE}px) { ${() => styleFn()} } -`; \ No newline at end of file +`; diff --git a/web/src/styles/themes.ts b/web/src/styles/themes.ts index 9a81e66..b44dd17 100644 --- a/web/src/styles/themes.ts +++ b/web/src/styles/themes.ts @@ -4,8 +4,10 @@ export const lightTheme = { ...componentsLightTheme, name: "light", white: "#FFFFFF", + black: "#000000", primaryPurple: "#4D00B4", secondaryPurple: "#9013FE", + darkPurple: "#220050", mediumPurple: "#F8F1FF", lightPurple: "#FBF9FE", violetPurple: "#6A1DCD", @@ -24,7 +26,8 @@ export const lightTheme = { defaultShadow: "#00000002", hoveredShadow: "#00000002", - whiteLowOpacity: "#0000000d", + whiteLowOpacitySubtle: "#FFFFFF0D", + whiteLowOpacityStrong: "#FFFFFF26", blackLowOpacity: "#00000080", success: "#00C42B", @@ -41,14 +44,19 @@ export const lightTheme = { skeletonBackground: "#EBEBEB", skeletonHighlight: "#F5F5F5", + + paleCyan: "#ACFFFF", + limeGreen: "#F3FFD9", }; export const darkTheme = { ...componentsDarkTheme, name: "dark", white: "#FFFFFF", + black: "#000000", primaryPurple: "#7E1BD4", secondaryPurple: "#B45FFF", + darkPurple: "#220050", mediumPurple: "#390F6C", lightPurple: "#FCFBFF", violetPurple: "#6A1DCD", @@ -59,7 +67,7 @@ export const darkTheme = { lightBlue: "#2A1260", primaryText: "#DAF0FF", secondaryText: "#BECCE5", - stroke: "#42498F", + stroke: "#392C74", lightGrey: "#2D1865", whiteBackground: "#220050", @@ -67,7 +75,8 @@ export const darkTheme = { defaultShadow: "#00000000", hoveredShadow: "#42498f80", - whiteLowOpacity: "#FFFFFF0F", + whiteLowOpacitySubtle: "#FFFFFF0F", + whiteLowOpacityStrong: "#FFFFFF24", blackLowOpacity: "#00000080", success: "#65DC7F", @@ -84,4 +93,7 @@ export const darkTheme = { skeletonBackground: "#3A2270", skeletonHighlight: "#3E307C", -}; \ No newline at end of file + + paleCyan: "#ACFFFF", + limeGreen: "#F3FFD9", +}; diff --git a/yarn.lock b/yarn.lock index 3a0d134..cc844c1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4475,7 +4475,7 @@ __metadata: "@graphql-codegen/cli": "npm:^4.0.1" "@graphql-codegen/client-preset": "npm:^4.1.0" "@kleros/kleros-app": "npm:^2.0.1" - "@kleros/ui-components-library": "npm:^2.15.0" + "@kleros/ui-components-library": "npm:^2.19.0" "@sentry/react": "npm:^7.93.0" "@sentry/tracing": "npm:^7.93.0" "@tanstack/react-query": "npm:^5.61.5" @@ -4554,9 +4554,9 @@ __metadata: languageName: node linkType: hard -"@kleros/ui-components-library@npm:^2.15.0": - version: 2.15.0 - resolution: "@kleros/ui-components-library@npm:2.15.0" +"@kleros/ui-components-library@npm:^2.19.0": + version: 2.19.0 + resolution: "@kleros/ui-components-library@npm:2.19.0" dependencies: "@datepicker-react/hooks": "npm:^2.8.4" "@swc/helpers": "npm:^0.3.2" @@ -4573,7 +4573,7 @@ __metadata: react-dom: ^18.0.0 react-is: ^18.0.0 styled-components: ^5.3.3 - checksum: 10/7c97e8fe45b1cd002a0aaf7fe4670b8c668a3abbbab82fac9261ef9a8382ccaf7d4a974ee54b8f299f1e8e7b68e58dab1f3f31d7c8b3b60c58a5af8abdf4a783 + checksum: 10/b4c6b4e35812582af48246546ce634e7c6f2bb62281f3deff100897f905c53b54f85e35f2f04ae68cee89d83412750b2005a0791195f33610bffbd78e77846f4 languageName: node linkType: hard