Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: new profile page #1871

Draft
wants to merge 3 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion web/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ const App: React.FC = () => {
}
/>
<Route
path="profile/:page/:order/:filter"
path="profile/*"
element={
<Suspense fallback={<Loader width={"48px"} height={"48px"} />}>
<Profile />
Expand Down
5 changes: 5 additions & 0 deletions web/src/assets/svgs/icons/voted-ballot.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion web/src/components/EvidenceCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ const EvidenceCard: React.FC<IEvidenceCard> = ({
description,
fileURI,
}) => {
const profileLink = `/profile/1/desc/all?address=${sender}`;
const profileLink = `/profile/stakes?address=${sender}`;

const transactionExplorerLink = useMemo(() => {
return getTxnExplorerLink(transactionHash ?? "");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import React from "react";
import React, { useMemo } from "react";
import styled from "styled-components";

import { useAccount } from "wagmi";

import { DEFAULT_CHAIN, getChain } from "consts/chains";

import ArrowIcon from "svgs/icons/arrow.svg";
import NewTabIcon from "svgs/icons/new-tab.svg";

import { IdenticonOrAvatar, AddressOrName } from "components/ConnectWallet/AccountDisplay";
import { StyledArrowLink } from "components/StyledArrowLink";
import { useAccount } from "wagmi";

const Container = styled.div`
display: flex;
Expand Down Expand Up @@ -36,26 +40,34 @@ export const ReStyledArrowLink = styled(StyledArrowLink)`
}
`;

interface IJurorTitle {
interface IJurorLink {
address: string;
isInternalLink?: boolean;
}

const JurorTitle: React.FC<IJurorTitle> = ({ address }) => {
const JurorLink: React.FC<IJurorLink> = ({ address, isInternalLink = true }) => {
const { isConnected, address: connectedAddress } = useAccount();
const profileLink =
isConnected && connectedAddress?.toLowerCase() === address.toLowerCase()
? "/profile/1/desc/all"
: `/profile/1/desc/all?address=${address}`;
? "/profile"
: `/profile/stakes?address=${address}`;
const addressExplorerLink = useMemo(() => {
return `${getChain(DEFAULT_CHAIN)?.blockExplorers?.default.url}/address/${address}`;
}, [address]);

return (
<Container>
<IdenticonOrAvatar address={address} />
<ReStyledArrowLink to={profileLink}>
<ReStyledArrowLink
to={isInternalLink ? profileLink : addressExplorerLink}
rel={`${isInternalLink ? "" : "noopener noreferrer"}`}
target={`${isInternalLink ? "" : "_blank"}`}
>
<AddressOrName address={address} />
<ArrowIcon />
{isInternalLink ? <ArrowIcon /> : <NewTabIcon />}
</ReStyledArrowLink>
</Container>
);
};

export default JurorTitle;
export default JurorLink;
4 changes: 2 additions & 2 deletions web/src/components/Popup/MiniGuides/JurorLevels.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { Card as _Card } from "@kleros/ui-components-library";

import { landscapeStyle } from "styles/landscapeStyle";

import Coherence from "pages/Profile/JurorInfo/Coherence";
import PixelArt from "pages/Profile/JurorInfo/PixelArt";
import Coherence from "pages/Profile/JurorCard/BottomContent/Coherence";
import PixelArt from "pages/Profile/JurorCard/BottomContent/PixelArt";

import Template from "./MainStructureTemplate";
import { Title, ParagraphsContainer, LeftContentContainer } from "./PageContentsTemplate";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const WalletAndProfile: React.FC<ISettings> = ({ toggleIsSettingsOpen }) => {
<IdenticonOrAvatar />
<AddressOrName />
</AvatarAndAddressContainer>
<ReStyledArrowLink to={"/profile/1/desc/all"} onClick={toggleIsSettingsOpen}>
<ReStyledArrowLink to={"/profile"} onClick={toggleIsSettingsOpen}>
My Profile <ArrowIcon />
</ReStyledArrowLink>
</Container>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { getVoteChoice } from "utils/getVoteChoice";
import { isUndefined } from "utils/index";

import { InternalLink } from "components/InternalLink";
import JurorTitle from "pages/Home/TopJurors/JurorCard/JurorTitle";
import JurorLink from "components/JurorLink";

const TitleContainer = styled.div`
display: flex;
Expand Down Expand Up @@ -86,13 +86,13 @@ const AccordionTitle: React.FC<{
commited: boolean;
hiddenVotes: boolean;
}> = ({ juror, choice, voteCount, period, answers, isActiveRound, commited, hiddenVotes }) => {
const profileLink = `/profile/1/desc/all?address=${juror}`;
const profileLink = `/profile/stakes?address=${juror}`;

return (
<TitleContainer>
<AddressContainer>
<StyledInternalLink to={profileLink}>
<JurorTitle address={juror} />
<JurorLink address={juror} />
</StyledInternalLink>
</AddressContainer>
<VoteStatus {...{ choice, period, answers, isActiveRound, commited, hiddenVotes }} />
Expand Down
4 changes: 2 additions & 2 deletions web/src/pages/Home/TopJurors/JurorCard/DesktopCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import { hoverShortTransitionTiming } from "styles/commonStyles";

import Coherence from "./Coherence";
import JurorLevel from "./JurorLevel";
import JurorTitle from "./JurorTitle";
import Rank from "./Rank";
import Rewards from "./Rewards";
import JurorLink from "components/JurorLink";

const Container = styled.div<{ renderRank?: boolean }>`
${hoverShortTransitionTiming}
Expand Down Expand Up @@ -57,7 +57,7 @@ const DesktopCard: React.FC<IDesktopCard> = ({
return (
<Container renderRank={renderRank}>
{renderRank && <Rank rank={rank} />}
<JurorTitle address={address} />
<JurorLink address={address} />
<Rewards address={address} />
<Coherence {...{ totalCoherentVotes, totalResolvedVotes }} />
<JurorLevel {...{ totalCoherentVotes, totalResolvedVotes, totalResolvedDisputes }} />
Expand Down
2 changes: 1 addition & 1 deletion web/src/pages/Home/TopJurors/JurorCard/JurorLevel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { landscapeStyle } from "styles/landscapeStyle";
import { getUserLevelData } from "utils/userLevelCalculation";
import { getCoherencePercent } from "utils/getCoherencePercent";

import PixelArt from "pages/Profile/JurorInfo/PixelArt";
import PixelArt from "pages/Profile/JurorCard/BottomContent/PixelArt";

const Container = styled.div`
display: flex;
Expand Down
4 changes: 2 additions & 2 deletions web/src/pages/Home/TopJurors/JurorCard/MobileCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import HeaderRewards from "../Header/Rewards";

import Coherence from "./Coherence";
import JurorLevel from "./JurorLevel";
import JurorTitle from "./JurorTitle";
import Rank from "./Rank";
import Rewards from "./Rewards";
import JurorLink from "components/JurorLink";

const Container = styled.div`
${hoverShortTransitionTiming}
Expand Down Expand Up @@ -97,7 +97,7 @@ const MobileCard: React.FC<IMobileCard> = ({
<TopSide>
<RankAndTitle>
{rank ? <Rank rank={rank} /> : null}
<JurorTitle address={address} />
<JurorLink address={address} />
</RankAndTitle>
<JurorLevel {...{ totalCoherentVotes, totalResolvedVotes, totalResolvedDisputes }} />
</TopSide>
Expand Down
2 changes: 1 addition & 1 deletion web/src/pages/Jurors/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ const Jurors: React.FC = () => {
<Header>
<StyledTitle>Jurors Leaderboard</StyledTitle>
{isConnected ? (
<StyledArrowLink to="/profile/1/desc/all">
<StyledArrowLink to="/profile">
My Profile <ArrowIcon />
</StyledArrowLink>
) : null}
Expand Down
68 changes: 68 additions & 0 deletions web/src/pages/Profile/Cases/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React, { useMemo } from "react";
import { useNavigate, useParams, useSearchParams } from "react-router-dom";

import styled from "styled-components";
import { responsiveSize } from "styles/responsiveSize";

import { isUndefined } from "utils/index";
import { decodeURIFilter, useRootPath } from "utils/uri";

import { DisputeDetailsFragment, OrderDirection } from "src/graphql/graphql";
import { useMyCasesQuery } from "queries/useCasesQuery";
import { useUserQuery } from "queries/useUser";
import CasesDisplay from "components/CasesDisplay";

const StyledCasesDisplay = styled(CasesDisplay)`
margin-top: ${responsiveSize(24, 32)};

.title {
margin-bottom: ${responsiveSize(12, 24)};
}
`;

interface ICases {
searchParamAddress: `0x${string}`;
}

const Cases: React.FC<ICases> = ({ searchParamAddress }) => {
const { page, order, filter } = useParams();
const [searchParams] = useSearchParams();
const location = useRootPath();
const navigate = useNavigate();

const casesPerPage = 3;
const pageNumber = parseInt(page ?? "1");
const disputeSkip = casesPerPage * (pageNumber - 1);
const decodedFilter = decodeURIFilter(filter ?? "all");
const { data: disputesData } = useMyCasesQuery(
searchParamAddress,
disputeSkip,
decodedFilter,
order === "asc" ? OrderDirection.Asc : OrderDirection.Desc
);

const { data: userData } = useUserQuery(searchParamAddress, decodedFilter);
const totalCases = userData?.user?.disputes.length;
const totalResolvedCases = parseInt(userData?.user?.totalResolvedDisputes);
const totalPages = useMemo(
() => (!isUndefined(totalCases) ? Math.ceil(totalCases / casesPerPage) : 1),
[totalCases, casesPerPage]
);

return (
<StyledCasesDisplay
title="Cases Drawn"
disputes={userData?.user !== null ? (disputesData?.user?.disputes as DisputeDetailsFragment[]) : []}
numberDisputes={totalCases}
numberClosedDisputes={totalResolvedCases}
totalPages={totalPages}
currentPage={pageNumber}
setCurrentPage={(newPage: number) =>
navigate(`${location}/${newPage}/${order}/${filter}?${searchParams.toString()}`)
}
{...{ casesPerPage }}
/>
);
};

export default Cases;
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import React from "react";
import styled, { css } from "styled-components";

import { landscapeStyle } from "styles/landscapeStyle";

import { CircularProgress } from "@kleros/ui-components-library";

import { landscapeStyle } from "styles/landscapeStyle";
import { ILevelCriteria } from "utils/userLevelCalculation";

import WithHelpTooltip from "components/WithHelpTooltip";

Expand All @@ -26,10 +28,7 @@ const tooltipMsg =
" the majority of jurors it's considered a Coherent Vote.";

interface ICoherence {
userLevelData: {
level: number;
title: string;
};
userLevelData: ILevelCriteria;
totalCoherentVotes: number;
totalResolvedVotes: number;
isMiniGuide: boolean;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from "react";
import styled from "styled-components";
import styled, { css } from "styled-components";

import { useAccount } from "wagmi";
import { landscapeStyle } from "styles/landscapeStyle";

import { CoinIds } from "consts/coingecko";
import { useCoinPrice } from "hooks/useCoinPrice";
Expand All @@ -10,14 +10,28 @@ import { getFormattedRewards } from "utils/jurorRewardConfig";
import { useUserQuery } from "queries/useUser";

import WithHelpTooltip from "components/WithHelpTooltip";

import TokenRewards from "./TokenRewards";
import TokenRewards from "../TokenRewards";

const Container = styled.div`
display: flex;
flex-direction: column;
align-items: flex-start;
align-items: center;
width: auto;
gap: 12px;

${landscapeStyle(
() => css`
align-items: flex-start;
gap: 24px;
`
)}
`;

const TokenRewardsContainer = styled.div`
display: flex;
flex-direction: column;
align-items: start;
gap: 16px;
`;

const tooltipMsg =
Expand All @@ -27,11 +41,11 @@ const tooltipMsg =
"arbitration fees (ETH) + PNK redistribution between jurors.";

interface IJurorRewards {
addressToQuery: `0x${string}`;
searchParamAddress: `0x${string}`;
}

const JurorRewards: React.FC<IJurorRewards> = ({ addressToQuery }) => {
const { data } = useUserQuery(addressToQuery);
const JurorRewards: React.FC<IJurorRewards> = ({ searchParamAddress }) => {
const { data } = useUserQuery(searchParamAddress);
const coinIds = [CoinIds.PNK, CoinIds.ETH];
const { prices: pricesData } = useCoinPrice(coinIds);

Expand All @@ -42,9 +56,11 @@ const JurorRewards: React.FC<IJurorRewards> = ({ addressToQuery }) => {
<WithHelpTooltip place="bottom" {...{ tooltipMsg }}>
<label> Juror Rewards </label>
</WithHelpTooltip>
{formattedRewards.map(({ token, amount, value }) => (
<TokenRewards key={token} {...{ token }} amount={amount} value={value} />
))}
<TokenRewardsContainer>
{formattedRewards.map(({ token, amount, value }) => (
<TokenRewards key={token} {...{ token }} amount={amount} value={value} />
))}
</TokenRewardsContainer>
</Container>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ import platoImage from "assets/pngs/dashboard/plato.png";
import pythagorasImage from "assets/pngs/dashboard/pythagoras.png";
import socratesImage from "assets/pngs/dashboard/socrates.png";

const Container = styled.div`
display: flex;
justify-content: center;
`;

interface IStyledImage {
show: boolean;
width: number | string;
Expand Down Expand Up @@ -42,7 +47,7 @@ interface IPixelArt {
const PixelArt: React.FC<IPixelArt> = ({ level, width, height }) => {
const [imageLoaded, setImageLoaded] = useState(false);
return (
<div>
<Container>
{!imageLoaded && <StyledSkeleton width={width} height={height} />}
<StyledImage
src={images[level]}
Expand All @@ -52,7 +57,7 @@ const PixelArt: React.FC<IPixelArt> = ({ level, width, height }) => {
width={width}
height={height}
/>
</div>
</Container>
);
};

Expand Down
Loading