Skip to content
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 @@ -74,7 +74,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.
3 changes: 2 additions & 1 deletion web/src/components/DisputeView/PeriodBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,14 @@ const StyledLabel = styled.label<{ frontColor: string; withDot?: boolean; isCard
`
: null}
`;

export interface IPeriodBanner {
id: number;
period: Periods;
isCard?: boolean;
}

const getPeriodColors = (period: Periods, theme: Theme): [string, string] => {
export const getPeriodColors = (period: Periods, theme: Theme): [string, string] => {
switch (period) {
case Periods.appeal:
return [theme.tint, theme.tintMedium];
Expand Down
7 changes: 4 additions & 3 deletions web/src/components/EvidenceCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ import { hoverShortTransitionTiming } from "styles/commonStyles";
import { landscapeStyle } from "styles/landscapeStyle";
import { responsiveSize } from "styles/responsiveSize";

import JurorLink from "components/JurorLink";

import { ExternalLink } from "./ExternalLink";
import { InternalLink } from "./InternalLink";
import JurorTitle from "pages/Home/TopJurors/JurorCard/JurorTitle";

const StyledCard = styled(Card)`
width: 100%;
Expand Down Expand Up @@ -211,8 +212,8 @@ const EvidenceCard: React.FC<IEvidenceCard> = ({
description,
fileURI,
}) => {
const profileLink = `/profile/1/desc/all?address=${sender}`;
const { id } = useParams();
const profileLink = `/profile/stakes/1?address=${sender}`;

const transactionExplorerLink = useMemo(() => {
return getTxnExplorerLink(transactionHash ?? "");
Expand All @@ -236,7 +237,7 @@ const EvidenceCard: React.FC<IEvidenceCard> = ({
<BottomShade>
<BottomLeftContent>
<StyledJurorInternalLink to={profileLink}>
<JurorTitle address={sender} />
<JurorLink address={sender} />
</StyledJurorInternalLink>
<StyledExternalLink to={transactionExplorerLink} rel="noopener noreferrer" target="_blank">
<label>{formatDate(Number(timestamp), true)}</label>
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 ArrowSvg from "svgs/icons/arrow.svg";
import { useAccount } from "wagmi";

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

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

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 @@ -45,27 +49,36 @@ export const ReStyledArrowLink = styled(StyledArrowLink)<{ smallDisplay?: boolea
`}
`;

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

const JurorTitle: React.FC<IJurorTitle> = ({ address, smallDisplay }) => {
const JurorLink: React.FC<IJurorLink> = ({ address, isInternalLink = true, smallDisplay }) => {
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/1?address=${address}`;
const addressExplorerLink = useMemo(() => {
return `${getChain(DEFAULT_CHAIN)?.blockExplorers?.default.url}/address/${address}`;
}, [address]);

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

export default JurorTitle;
export default JurorLink;
2 changes: 1 addition & 1 deletion web/src/components/NumberDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const NumberDisplay: React.FC<INumberDisplay> = ({
}) => {
const parsedValue = Number(value);
const formattedValue = commify(getFormattedValue(parsedValue, decimals));
const tooltipValue = isCurrency ? `${unit} ${value}` : `${value} ${unit}`;
const tooltipValue = isCurrency ? `${unit} ${commify(value)}` : `${commify(value)} ${unit}`;
const displayUnit = showUnitInDisplay ? unit : "";
const displayValue = isCurrency ? `${displayUnit} ${formattedValue}` : `${formattedValue} ${displayUnit}`;

Expand Down
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
62 changes: 62 additions & 0 deletions web/src/hooks/queries/useStakingHistory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { useQuery } from "@tanstack/react-query";

// dynamic atlasUri would go here
const atlasUri = "https://url.example/graphql";

const AUTH_TOKEN = "Bearer tokenExampleGoesHere";

export const useStakingHistory = (take: number, lastCursorId?: number) => {
const variables = {
pagination: { take, lastCursorId: lastCursorId ?? null },
};

return useQuery({
queryKey: ["stakingHistoryQuery", take, lastCursorId],
enabled: true,
staleTime: 60000,
queryFn: async () => {
console.log("Fetching with variables:", variables);

try {
const response = await fetch(atlasUri, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: AUTH_TOKEN,
},
body: JSON.stringify({
query: `
query GetStakingEvents($pagination: PaginationArgs) {
userStakingEvents(pagination: $pagination) {
edges {
node {
name
args
blockTimestamp
transactionHash
}
cursor
}
count
hasNextPage
}
}
`,
variables,
}),
});

const result = await response.json();

if (!response.ok) {
throw new Error(`GraphQL error: ${JSON.stringify(result)}`);
}

return result;
} catch (error) {
console.error("GraphQL Fetch Error:", error);
throw error;
}
},
});
};
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/stakes/1"} 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/1?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
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import styled from "styled-components";

import { hoverShortTransitionTiming } from "styles/commonStyles";

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

import Stake from "./Stake";

const Container = styled.div`
Expand All @@ -30,7 +31,7 @@ interface IJurorCard {
const JurorCard: React.FC<IJurorCard> = ({ address, effectiveStake }) => {
return (
<Container>
<JurorTitle {...{ address }} smallDisplay />
<JurorLink {...{ address }} smallDisplay />
<Stake {...{ effectiveStake }} />
</Container>
);
Expand Down
7 changes: 4 additions & 3 deletions web/src/pages/Home/TopJurors/JurorCard/DesktopCard.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import React from "react";
import styled, { css } from "styled-components";

import { hoverShortTransitionTiming } from "styles/commonStyles";
import { landscapeStyle } from "styles/landscapeStyle";
import { responsiveSize } from "styles/responsiveSize";
import { hoverShortTransitionTiming } from "styles/commonStyles";

import JurorLink from "components/JurorLink";

import Coherence from "./Coherence";
import JurorLevel from "./JurorLevel";
import JurorTitle from "./JurorTitle";
import Rank from "./Rank";
import Rewards from "./Rewards";
import Score from "./Score";
Expand Down Expand Up @@ -58,7 +59,7 @@ const DesktopCard: React.FC<IDesktopCard> = ({
return (
<Container renderRank={renderRank}>
{renderRank && <Rank rank={rank} />}
<JurorTitle address={address} />
<JurorLink address={address} />
<Score coherenceScore={coherenceScore} />
<Coherence {...{ totalCoherentVotes, totalResolvedVotes }} />
<Rewards address={address} />
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 @@ -5,7 +5,7 @@ import { landscapeStyle } from "styles/landscapeStyle";

import { getUserLevelData } from "utils/userLevelCalculation";

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 @@ -10,9 +10,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";
import Score from "./Score";

const Container = styled.div`
Expand Down Expand Up @@ -107,7 +107,7 @@ const MobileCard: React.FC<IMobileCard> = ({
<TopSide>
<RankAndTitle>
{rank ? <Rank {...{ rank }} /> : null}
<JurorTitle {...{ address }} />
<JurorLink {...{ address }} />
</RankAndTitle>
<JurorLevel coherenceScore={Number(coherenceScore)} />
</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/stakes/1">
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;
Loading
Loading