Skip to content

Commit 01234cb

Browse files
committed
feat: remove hardcoded values in vote cards, stylings, etc
1 parent c843eba commit 01234cb

File tree

9 files changed

+387
-44
lines changed

9 files changed

+387
-44
lines changed

web/src/components/StyledSkeleton.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ const StyledSkeletonDisputeListItem = styled(Skeleton)`
2121
height: 62px;
2222
`;
2323

24+
const StyledSkeletonVoteCard = styled(Skeleton)`
25+
height: 64px;
26+
`;
27+
2428
const StyledSkeletonEvidenceContainer = styled.div`
2529
width: 100%;
2630
span {
@@ -38,6 +42,8 @@ export const SkeletonDisputeCard = () => (
3842

3943
export const SkeletonDisputeListItem = () => <StyledSkeletonDisputeListItem />;
4044

45+
export const SkeletonVoteCard = () => <StyledSkeletonVoteCard />;
46+
4147
export const SkeletonEvidenceCard = () => (
4248
<StyledSkeletonEvidenceContainer>
4349
<Skeleton />
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
import { useQuery } from "@tanstack/react-query";
2+
import { Address } from "viem";
3+
4+
import { useGraphqlBatcher } from "context/GraphqlBatcher";
5+
import { isUndefined } from "utils/index";
6+
import { sanitizeFilter } from "utils/sanitizeFilter";
7+
8+
import { graphql } from "src/graphql";
9+
import { UserDrawsQuery, UserDrawsCountQuery, Draw_Filter, OrderDirection } from "src/graphql/graphql";
10+
export type { UserDrawsQuery, UserDrawsCountQuery };
11+
12+
const userDrawsQuery = graphql(`
13+
query UserDraws($jurorId: ID!, $skip: Int, $first: Int, $orderDirection: OrderDirection, $where: Draw_filter) {
14+
user(id: $jurorId) {
15+
id
16+
totalResolvedVotes
17+
draws(first: $first, skip: $skip, orderBy: blockNumber, orderDirection: $orderDirection, where: $where) {
18+
id
19+
voteIDNum
20+
dispute {
21+
id
22+
disputeID
23+
period
24+
ruled
25+
currentRoundIndex
26+
arbitrated {
27+
id
28+
}
29+
court {
30+
id
31+
name
32+
}
33+
}
34+
round {
35+
id
36+
}
37+
vote {
38+
... on ClassicVote {
39+
id
40+
choice
41+
commit
42+
commited
43+
voted
44+
localRound {
45+
... on ClassicRound {
46+
id
47+
winningChoice
48+
}
49+
}
50+
justification {
51+
id
52+
choice
53+
reference
54+
}
55+
}
56+
}
57+
}
58+
}
59+
}
60+
`);
61+
62+
const userDrawsCountQuery = graphql(`
63+
query UserDrawsCount($jurorId: ID!, $where: Draw_filter) {
64+
user(id: $jurorId) {
65+
id
66+
totalResolvedVotes
67+
draws(orderBy: blockNumber, where: $where) {
68+
id
69+
vote {
70+
... on ClassicVote {
71+
id
72+
voted
73+
commited
74+
}
75+
}
76+
}
77+
}
78+
}
79+
`);
80+
81+
export const useUserDraws = (
82+
jurorAddress?: Address,
83+
skip = 0,
84+
first = 5,
85+
where?: Draw_Filter,
86+
sortOrder?: OrderDirection
87+
) => {
88+
const { graphqlBatcher } = useGraphqlBatcher();
89+
const sanitizedWhere = sanitizeFilter(where);
90+
const isEnabled = !isUndefined(jurorAddress);
91+
92+
return useQuery<UserDrawsQuery>({
93+
queryKey: ["useUserDraws", jurorAddress?.toLowerCase(), skip, first, sanitizedWhere, sortOrder],
94+
enabled: isEnabled,
95+
queryFn: async () =>
96+
await graphqlBatcher.fetch({
97+
id: crypto.randomUUID(),
98+
document: userDrawsQuery,
99+
variables: {
100+
jurorId: jurorAddress?.toLowerCase(),
101+
skip,
102+
first,
103+
where: sanitizedWhere,
104+
orderDirection: sortOrder ?? "desc",
105+
},
106+
}),
107+
});
108+
};
109+
110+
export const useUserDrawsCount = (jurorAddress?: Address, where?: Draw_Filter) => {
111+
const { graphqlBatcher } = useGraphqlBatcher();
112+
const sanitizedWhere = sanitizeFilter(where);
113+
const isEnabled = !isUndefined(jurorAddress);
114+
115+
return useQuery<UserDrawsCountQuery>({
116+
queryKey: ["useUserDrawsCount", jurorAddress?.toLowerCase(), sanitizedWhere],
117+
enabled: isEnabled,
118+
queryFn: async () =>
119+
await graphqlBatcher.fetch({
120+
id: crypto.randomUUID(),
121+
document: userDrawsCountQuery,
122+
variables: {
123+
jurorId: jurorAddress?.toLowerCase(),
124+
where: sanitizedWhere,
125+
},
126+
}),
127+
});
128+
};

web/src/hooks/useStakingEventsByCourt.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { useQuery } from "@tanstack/react-query";
22
import { request } from "graphql-request";
3+
import { useChainId } from "wagmi";
4+
5+
import { sortitionModuleAddress } from "hooks/contracts/generated";
36

47
import { isUndefined } from "src/utils";
58

@@ -28,13 +31,26 @@ type StakingEventsResponse = {
2831
const atlasUri = import.meta.env.REACT_APP_ATLAS_URI;
2932

3033
export const useStakingEventsByCourt = (courtIds: number[], skip: number, take: number, partialAddress?: string) => {
34+
const chainId = useChainId();
3135
const addressParam = partialAddress ?? "";
36+
const contractAddress = sortitionModuleAddress[chainId as keyof typeof sortitionModuleAddress];
37+
3238
// Allow empty courtIds array for "all courts" query
33-
const isEnabled = !isUndefined(atlasUri);
39+
const isEnabled = !isUndefined(atlasUri) && !isUndefined(contractAddress);
3440

3541
const query = `
36-
query GetStakingEvents($partialAddress: String!, $courtIDs: [Int!], $pagination: PaginationArgs) {
37-
userStakingEvents(partialAddress: $partialAddress, courtIDs: $courtIDs, pagination: $pagination) {
42+
query GetStakingEvents(
43+
$partialAddress: String!
44+
$courtIDs: [Int!]
45+
$contract: ContractInput!
46+
$pagination: PaginationArgs
47+
) {
48+
userStakingEvents(
49+
partialAddress: $partialAddress
50+
courtIDs: $courtIDs
51+
contract: $contract
52+
pagination: $pagination
53+
) {
3854
items {
3955
item {
4056
id
@@ -60,11 +76,15 @@ export const useStakingEventsByCourt = (courtIds: number[], skip: number, take:
6076
partialAddress: addressParam,
6177
// If courtIds is empty, pass null to query all courts
6278
courtIDs: courtIds.length > 0 ? courtIds : null,
79+
contract: {
80+
chainId: chainId,
81+
address: contractAddress,
82+
},
6383
pagination: { skip, take },
6484
};
6585

6686
return useQuery<StakingEventsResponse>({
67-
queryKey: ["stakingEventsByCourt", courtIds, skip, take, partialAddress],
87+
queryKey: ["stakingEventsByCourt", courtIds, skip, take, partialAddress, chainId],
6888
enabled: isEnabled,
6989
staleTime: 60000,
7090
queryFn: async () => {

web/src/pages/Profile/Votes/VoteCard/CaseStatus.tsx

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ import { Periods } from "consts/periods";
55

66
import { getPeriodColors } from "components/DisputeView/PeriodBanner";
77

8-
interface ICaseStatus {}
8+
interface ICaseStatus {
9+
period?: string;
10+
ruled?: boolean;
11+
}
912

1013
const StyledLabel = styled.label<{ frontColor: string; withDot?: boolean }>`
1114
display: flex;
@@ -46,16 +49,17 @@ const getPeriodLabel = (period: Periods): string => {
4649
}
4750
};
4851

49-
const CaseStatus: React.FC<ICaseStatus> = ({}) => {
52+
const CaseStatus: React.FC<ICaseStatus> = ({ period, ruled }) => {
5053
const theme = useTheme();
51-
const [frontColor, backgroundColor] = useMemo(
52-
() => getPeriodColors(Periods.evidence, theme),
53-
[theme, Periods.evidence]
54-
);
54+
55+
// Determine the period or use execution if ruled
56+
const currentPeriod = ruled ? Periods.execution : (period as Periods) || Periods.evidence;
57+
58+
const [frontColor] = useMemo(() => getPeriodColors(currentPeriod, theme), [theme, currentPeriod]);
5559

5660
return (
5761
<StyledLabel frontColor={frontColor} withDot>
58-
{getPeriodLabel(Periods.evidence)}
62+
{getPeriodLabel(currentPeriod)}
5963
</StyledLabel>
6064
);
6165
};

web/src/pages/Profile/Votes/VoteCard/CourtName.tsx

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import styled, { css } from "styled-components";
33

44
import { landscapeStyle } from "styles/landscapeStyle";
55

6+
import { InternalLink } from "components/InternalLink";
7+
68
const Container = styled.div`
79
display: flex;
810
width: 100%;
@@ -12,11 +14,6 @@ const Container = styled.div`
1214
justify-content: space-between;
1315
flex-wrap: wrap;
1416
15-
small {
16-
height: 100%;
17-
font-weight: 400;
18-
}
19-
2017
${landscapeStyle(
2118
() => css`
2219
justify-content: flex-start;
@@ -25,14 +22,28 @@ const Container = styled.div`
2522
)}
2623
`;
2724

25+
const CourtLink = styled(InternalLink)`
26+
font-size: 14px;
27+
font-weight: 400;
28+
color: ${({ theme }) => theme.primaryBlue};
29+
text-decoration: none;
30+
cursor: pointer;
31+
height: 100%;
32+
33+
:hover {
34+
color: ${({ theme }) => theme.secondaryBlue};
35+
}
36+
`;
37+
2838
interface ICourtName {
2939
name: string;
40+
courtId: string;
3041
}
3142

32-
const CourtName: React.FC<ICourtName> = ({ name }) => {
43+
const CourtName: React.FC<ICourtName> = ({ name, courtId }) => {
3344
return (
3445
<Container>
35-
<small>{name}</small>
46+
<CourtLink to={`/courts/${courtId}`}>{name}</CourtLink>
3647
</Container>
3748
);
3849
};

web/src/pages/Profile/Votes/VoteCard/Vote.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import React from "react";
22
import styled from "styled-components";
33

4+
import Skeleton from "react-loading-skeleton";
5+
46
import VotedIcon from "svgs/icons/voted-ballot.svg";
57

68
const Container = styled.div`
79
display: flex;
810
flex-direction: row;
911
gap: 8px;
12+
align-items: center;
1013
1114
small {
1215
font-weight: 400;
@@ -21,18 +24,19 @@ const StyledVotedIcon = styled(VotedIcon)`
2124

2225
const BlueSmall = styled.small`
2326
color: ${({ theme }) => theme.primaryBlue};
27+
margin-left: -2px;
2428
`;
2529

2630
interface IVote {
27-
choice: string;
31+
choice: string | null;
2832
}
2933

3034
const Vote: React.FC<IVote> = ({ choice }) => {
3135
return (
3236
<Container>
3337
<StyledVotedIcon />
3438
<BlueSmall>Vote: </BlueSmall>
35-
<small>{choice}</small>
39+
{choice === null ? <Skeleton width={80} height={14} /> : <small>{choice}</small>}
3640
</Container>
3741
);
3842
};
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import React from "react";
2+
import styled from "styled-components";
3+
4+
import VotesIcon from "svgs/icons/voted-ballot.svg";
5+
6+
const Container = styled.div`
7+
display: flex;
8+
gap: 8px;
9+
align-items: center;
10+
11+
small {
12+
font-weight: 400;
13+
color: ${({ theme }) => theme.secondaryPurple};
14+
}
15+
16+
svg {
17+
path {
18+
fill: ${({ theme }) => theme.secondaryPurple};
19+
}
20+
}
21+
`;
22+
23+
interface IVoteCount {
24+
count: number;
25+
}
26+
27+
const VoteCount: React.FC<IVoteCount> = ({ count }) => {
28+
if (count <= 1) return null;
29+
30+
return (
31+
<Container>
32+
<VotesIcon />
33+
<small>{count} votes</small>
34+
</Container>
35+
);
36+
};
37+
38+
export default VoteCount;

0 commit comments

Comments
 (0)