Skip to content
Merged
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/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
79 changes: 0 additions & 79 deletions web/src/pages/Profile/Courts/Header.tsx

This file was deleted.

139 changes: 139 additions & 0 deletions web/src/pages/Profile/Stakes/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import React from "react";
import styled, { css } from "styled-components";

import { useSearchParams } from "react-router-dom";
import { formatUnits } from "viem";

import LockerIcon from "svgs/icons/locker.svg";
import PnkIcon from "svgs/icons/pnk.svg";

import { isUndefined } from "utils/index";

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

import NumberDisplay from "components/NumberDisplay";

const Container = styled.div`
display: flex;
flex-direction: row;
flex-wrap: wrap;
width: 100%;
gap: 4px 16px;
align-items: center;
margin-bottom: ${responsiveSize(16, 24)};

${landscapeStyle(
() => css`
justify-content: space-between;
`
)}
`;

const LockedPnk = styled.div`
display: flex;
flex-wrap: nowrap;
gap: 8px;
align-items: center;
justify-content: center;
`;

const StakesGroup = styled.div`
display: flex;
gap: 12px 24px;
align-items: center;
flex-wrap: wrap;
`;

const AvailablePnk = styled.div`
display: flex;
flex-wrap: nowrap;
gap: 8px;
align-items: center;
justify-content: center;
`;

const EffectivePnk = styled.div`
display: flex;
flex-wrap: nowrap;
gap: 8px;
align-items: center;
justify-content: center;
`;

const StyledTitle = styled.h1`
margin-bottom: 0;
font-size: ${responsiveSize(20, 24)};
`;

const StyledLockerIcon = styled(LockerIcon)`
fill: ${({ theme }) => theme.secondaryPurple};
width: 14px;
height: 14px;
margin-bottom: 1px;
`;

const StyledPnkIcon = styled(PnkIcon)`
fill: ${({ theme }) => theme.secondaryPurple};
width: 14px;
height: 14px;
margin-bottom: 1px;
`;

const StyledEffectivePnkIcon = styled(PnkIcon)`
fill: ${({ theme }) => theme.secondaryPurple};
width: 14px;
height: 14px;
margin-bottom: 1px;
`;

interface IHeader {
availableStake?: bigint;
lockedStake?: bigint;
effectiveStake?: bigint;
}

const Header: React.FC<IHeader> = ({ availableStake, lockedStake, effectiveStake }) => {
const formattedAvailableStake = !isUndefined(availableStake) && formatUnits(availableStake, 18);
const formattedLockedStake = !isUndefined(lockedStake) && formatUnits(lockedStake, 18);
const formattedEffectiveStake = !isUndefined(effectiveStake) && formatUnits(effectiveStake, 18);
const [searchParams] = useSearchParams();
const searchParamAddress = searchParams.get("address")?.toLowerCase();

return (
<Container>
<StyledTitle>{searchParamAddress ? "Their" : "My"} Stakes</StyledTitle>
<StakesGroup>
{!isUndefined(availableStake) ? (
<AvailablePnk>
<StyledPnkIcon />
<label> Available: </label>
<small>
<NumberDisplay value={formattedAvailableStake.toString()} unit="PNK" />
</small>
</AvailablePnk>
) : null}
{!isUndefined(effectiveStake) ? (
<EffectivePnk>
<StyledEffectivePnkIcon />
<label> Staked: </label>
<small>
<NumberDisplay value={formattedEffectiveStake.toString()} unit="PNK" />
</small>
</EffectivePnk>
) : null}
{!isUndefined(lockedStake) ? (
<LockedPnk>
<StyledLockerIcon />
<label> Locked: </label>
<small>
<NumberDisplay value={formattedLockedStake.toString()} unit="PNK" />
</small>
</LockedPnk>
) : null}
</StakesGroup>
</Container>
);
};

export default Header;
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ const StyledLabel = styled.label`
font-size: ${responsiveSize(14, 16)};
`;

interface ICourts {
interface IStakes {
addressToQuery: `0x${string}`;
}

const Courts: React.FC<ICourts> = ({ addressToQuery }) => {
const Stakes: React.FC<IStakes> = ({ addressToQuery }) => {
const { data: stakeData, isLoading } = useJurorStakeDetailsQuery(addressToQuery);
const { data: jurorBalance } = useReadSortitionModuleGetJurorBalance({
args: [addressToQuery, BigInt(1)],
Expand All @@ -48,11 +48,15 @@ const Courts: React.FC<ICourts> = ({ addressToQuery }) => {
const searchParamAddress = searchParams.get("address")?.toLowerCase();
const stakedCourts = stakeData?.jurorTokensPerCourts?.filter(({ staked }) => staked > 0);
const isStaked = stakedCourts && stakedCourts.length > 0;
const availableStake = jurorBalance?.[0];
const lockedStake = jurorBalance?.[1];
const effectiveStake = stakeData?.jurorTokensPerCourts?.[0]?.effectiveStake
? BigInt(stakeData.jurorTokensPerCourts[0].effectiveStake)
: undefined;

return (
<Container>
<Header lockedStake={lockedStake ?? BigInt(0)} />
<Header {...{ lockedStake, availableStake, effectiveStake }} />
{isLoading ? <Skeleton /> : null}
{!isStaked && !isLoading ? (
<StyledLabel>{searchParamAddress ? "They" : "You"} are not staked in any court</StyledLabel>
Expand All @@ -70,4 +74,4 @@ const Courts: React.FC<ICourts> = ({ addressToQuery }) => {
);
};

export default Courts;
export default Stakes;
13 changes: 8 additions & 5 deletions web/src/pages/Profile/index.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
import React, { useMemo } from "react";

import styled, { css } from "styled-components";
import { MAX_WIDTH_LANDSCAPE, landscapeStyle } from "styles/landscapeStyle";
import { responsiveSize } from "styles/responsiveSize";

import { useNavigate, useParams, useSearchParams } from "react-router-dom";
import { useAccount } from "wagmi";

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

import { DisputeDetailsFragment, useMyCasesQuery } from "queries/useCasesQuery";
import { useUserQuery } from "queries/useUser";

import { Dispute_Filter, OrderDirection, UserDetailsFragment } from "src/graphql/graphql";

import { MAX_WIDTH_LANDSCAPE, landscapeStyle } 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";

import JurorInfo from "./JurorInfo";
import Stakes from "./Stakes";

const Container = styled.div`
width: 100%;
Expand Down Expand Up @@ -110,7 +113,7 @@ const Profile: React.FC = () => {
{isConnected || searchParamAddress ? (
<>
<JurorInfo {...{ addressToQuery }} />
<Courts {...{ addressToQuery }} />
<Stakes {...{ addressToQuery }} />
<StyledCasesDisplay
title={`${searchParamAddress ? "Their" : "My"} Cases`}
disputes={userData?.user !== null ? (disputesData?.user?.disputes as DisputeDetailsFragment[]) : []}
Expand Down
Loading