Skip to content

Commit d0b6c7c

Browse files
committed
feat: new level calculations and score in leaderboard
1 parent a26fe61 commit d0b6c7c

File tree

12 files changed

+138
-84
lines changed

12 files changed

+138
-84
lines changed

web/src/components/Popup/MiniGuides/JurorLevels.tsx

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -31,64 +31,73 @@ const Card = styled(_Card)`
3131
`;
3232

3333
const leftPageContents = [
34+
{
35+
title: "Juror Level 0: Diogenes",
36+
paragraphs: [
37+
"Coherence Score below 25.",
38+
"This level is for new jurors or those frequently voting incoherently. A few coherent votes can help climb out of this level quickly.",
39+
],
40+
},
3441
{
3542
title: "Juror Level 1: Pythagoras",
3643
paragraphs: [
37-
"Jurors are classified into distinct levels according to their performance starting from Level 1.",
38-
"Level 1: Jurors with ≥ 1 case arbitrated with 0-70% of coherent votes.",
44+
"Coherence Score between 25 and 49.",
45+
"Jurors here are gaining experience and starting to build voting reliability.",
3946
],
4047
},
4148
{
4249
title: "Juror Level 2: Socrates",
43-
paragraphs: ["Level 2: Jurors with ≥ 3 cases arbitrated with more than 70% coherent votes."],
50+
paragraphs: [
51+
"Coherence Score between 50 and 69.",
52+
"Mid-tier performance. Jurors at this level have demonstrated reasonable consistency in coherent voting.",
53+
],
4454
},
4555
{
4656
title: "Juror Level 3: Plato",
47-
paragraphs: ["Level 3: Jurors with ≥ 7 cases arbitrated with more than 80% of coherent votes."],
57+
paragraphs: [
58+
"Coherence Score between 70 and 89.",
59+
"Reliable jurors with a consistent track record of coherent votes. Just a few more coherent votes away from reaching the top.",
60+
],
4861
},
4962
{
5063
title: "Juror Level 4: Aristotle",
51-
paragraphs: ["Level 4: Jurors with ≥ 10 cases arbitrated with more than 90% of coherent votes."],
52-
},
53-
{
54-
title: "Juror Level 0: Diogenes",
5564
paragraphs: [
56-
"There's a level for the low-performance/lazy jurors. Level 0: Jurors with ≥ 3 cases arbitrated" +
57-
" with less than 50% of coherent votes.",
65+
"Coherence Score between 90 and 100.",
66+
"Top-tier jurors with excellent coherence. Trusted members of the platform.",
5867
],
5968
},
6069
];
6170

6271
const userLevelData = [
72+
{
73+
level: 0,
74+
title: "Diogenes",
75+
totalCoherentVotes: 2,
76+
totalResolvedVotes: 10,
77+
},
6378
{
6479
level: 1,
6580
title: "Pythagoras",
6681
totalCoherentVotes: 6,
67-
totalResolvedVotes: 10,
82+
totalResolvedVotes: 12,
6883
},
6984
{
7085
level: 2,
7186
title: "Socrates",
72-
totalCoherentVotes: 7,
73-
totalResolvedVotes: 10,
87+
totalCoherentVotes: 22,
88+
totalResolvedVotes: 34,
7489
},
7590
{
7691
level: 3,
7792
title: "Plato",
78-
totalCoherentVotes: 8,
79-
totalResolvedVotes: 10,
93+
totalCoherentVotes: 52,
94+
totalResolvedVotes: 65,
8095
},
8196
{
8297
level: 4,
8398
title: "Aristotle",
84-
totalCoherentVotes: 9,
85-
totalResolvedVotes: 10,
86-
},
87-
{
88-
level: 0,
89-
title: "Diogenes",
90-
totalCoherentVotes: 3,
91-
totalResolvedVotes: 10,
99+
totalCoherentVotes: 90,
100+
totalResolvedVotes: 90,
92101
},
93102
];
94103

web/src/pages/Home/TopJurors/Header/Coherence.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const Container = styled.div`
1111
display: flex;
1212
font-size: 12px !important;
1313
&::before {
14-
content: "Coherence";
14+
content: "Coherent\u00a0Votes";
1515
}
1616
color: ${({ theme }) => theme.secondaryText};
1717
align-items: center;
@@ -25,11 +25,10 @@ const Container = styled.div`
2525
`;
2626

2727
const coherentVotesTooltipMsg =
28-
"This is the percentage of coherent votes made by a juror." +
29-
" Hover to see the ratio of coherent votes: " +
28+
"This is the ratio of coherent votes made by a juror: " +
3029
"the number in the left is the number of times where the juror " +
3130
"voted coherently and the number in the right is the total number of times " +
32-
"the juror voted";
31+
"the juror voted. Hover to see the percentage of coherent votes.";
3332

3433
const Coherence: React.FC = () => {
3534
const isDesktop = useIsDesktop();

web/src/pages/Home/TopJurors/Header/DesktopHeader.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import JurorLevels from "components/Popup/MiniGuides/JurorLevels";
1616

1717
import Coherence from "./Coherence";
1818
import Rewards from "./Rewards";
19+
import Score from "./Score";
1920

2021
const Container = styled.div<{ renderIcon?: boolean }>`
2122
display: none;
@@ -31,10 +32,8 @@ const Container = styled.div<{ renderIcon?: boolean }>`
3132
landscapeStyle(
3233
() => css`
3334
display: grid;
34-
grid-template-columns: ${renderIcon
35-
? `min-content repeat(3, ${responsiveSize(160, 180, 900)}) auto`
36-
: `repeat(3, ${responsiveSize(160, 180, 900)}) auto`};
37-
column-gap: ${responsiveSize(12, 28, 900)};
35+
grid-template-columns: ${renderIcon ? `min-content 1fr 0.8fr 1fr 1.6fr 1fr` : `1fr 0.8fr 1fr 1.6fr 1fr`};
36+
column-gap: ${responsiveSize(12, 24, 900)};
3837
align-items: center;
3938
`
4039
)}
@@ -65,8 +64,9 @@ export const DesktopHeader: React.FC = () => {
6564
<Container renderIcon={renderIcon}>
6665
{renderIcon ? <StyledRankingIcon /> : null}
6766
<StyledLabel>Juror</StyledLabel>
68-
<Rewards />
67+
<Score />
6968
<Coherence />
69+
<Rewards />
7070
<HowItWorksContainer>
7171
<HowItWorks
7272
isMiniGuideOpen={isJurorLevelsMiniGuideOpen}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import React from "react";
2+
import styled, { css } from "styled-components";
3+
4+
import { landscapeStyle } from "styles/landscapeStyle";
5+
6+
import useIsDesktop from "hooks/useIsDesktop";
7+
8+
import WithHelpTooltip from "components/WithHelpTooltip";
9+
10+
const Container = styled.div`
11+
display: flex;
12+
font-size: 12px !important;
13+
&::before {
14+
content: "Score";
15+
}
16+
color: ${({ theme }) => theme.secondaryText};
17+
align-items: center;
18+
19+
${landscapeStyle(
20+
() => css`
21+
font-size: 14px !important;
22+
justify-content: center;
23+
`
24+
)}
25+
`;
26+
27+
const scoreTooltipMsg =
28+
"A score from 0 to 100 reflecting coherent voting, smoothed " +
29+
"to prevent jurors with low vote counts from ranking too high.";
30+
31+
const Score: React.FC = () => {
32+
const isDesktop = useIsDesktop();
33+
34+
return (
35+
<Container>
36+
<WithHelpTooltip place={isDesktop ? "top" : "left"} tooltipMsg={scoreTooltipMsg}></WithHelpTooltip>
37+
</Container>
38+
);
39+
};
40+
export default Score;

web/src/pages/Home/TopJurors/JurorCard/Coherence.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ const Coherence: React.FC<ICoherence> = ({ totalCoherentVotes, totalResolvedVote
2424

2525
return (
2626
<Container>
27-
<Tooltip text={coherenceRatio}>
28-
{getCoherencePercent(Number(totalCoherentVotes), Number(totalResolvedVotes))}
27+
<Tooltip text={getCoherencePercent(Number(totalCoherentVotes), Number(totalResolvedVotes))}>
28+
{coherenceRatio}
2929
</Tooltip>
3030
</Container>
3131
);

web/src/pages/Home/TopJurors/JurorCard/DesktopCard.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import JurorLevel from "./JurorLevel";
1010
import JurorTitle from "./JurorTitle";
1111
import Rank from "./Rank";
1212
import Rewards from "./Rewards";
13+
import Score from "./Score";
1314

1415
const Container = styled.div<{ renderRank?: boolean }>`
1516
${hoverShortTransitionTiming}
@@ -25,10 +26,8 @@ const Container = styled.div<{ renderRank?: boolean }>`
2526
landscapeStyle(
2627
() => css`
2728
display: grid;
28-
grid-template-columns: ${renderRank
29-
? `min-content repeat(3, ${responsiveSize(160, 180, 900)}) auto`
30-
: `repeat(3, ${responsiveSize(160, 180, 900)}) auto`};
31-
column-gap: ${responsiveSize(12, 28, 900)};
29+
grid-template-columns: ${renderRank ? `min-content 1fr 0.8fr 1fr 1.6fr 1fr` : `1fr 0.8fr 1fr 1.6fr 1fr`};
30+
column-gap: ${responsiveSize(12, 24, 900)};
3231
`
3332
)}
3433
@@ -40,27 +39,28 @@ const Container = styled.div<{ renderRank?: boolean }>`
4039
interface IDesktopCard {
4140
rank?: number;
4241
address: string;
42+
coherenceScore: string;
4343
totalCoherentVotes: string;
4444
totalResolvedVotes: string;
45-
totalResolvedDisputes: string;
4645
}
4746

4847
const DesktopCard: React.FC<IDesktopCard> = ({
4948
rank,
5049
address,
50+
coherenceScore,
5151
totalCoherentVotes,
5252
totalResolvedVotes,
53-
totalResolvedDisputes,
5453
}) => {
5554
const renderRank = !!rank;
5655

5756
return (
5857
<Container renderRank={renderRank}>
5958
{renderRank && <Rank rank={rank} />}
6059
<JurorTitle address={address} />
61-
<Rewards address={address} />
60+
<Score coherenceScore={coherenceScore} />
6261
<Coherence {...{ totalCoherentVotes, totalResolvedVotes }} />
63-
<JurorLevel {...{ totalCoherentVotes, totalResolvedVotes, totalResolvedDisputes }} />
62+
<Rewards address={address} />
63+
<JurorLevel coherenceScore={Number(coherenceScore)} />
6464
</Container>
6565
);
6666
};

web/src/pages/Home/TopJurors/JurorCard/JurorLevel.tsx

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import styled, { css } from "styled-components";
44
import { landscapeStyle } from "styles/landscapeStyle";
55

66
import { getUserLevelData } from "utils/userLevelCalculation";
7-
import { getCoherencePercent } from "utils/getCoherencePercent";
87

98
import PixelArt from "pages/Profile/JurorInfo/PixelArt";
109

@@ -40,14 +39,11 @@ const StyledLabel = styled.label`
4039
`;
4140

4241
interface IJurorLevel {
43-
totalCoherentVotes: string;
44-
totalResolvedVotes: string;
45-
totalResolvedDisputes: string;
42+
coherenceScore: number;
4643
}
4744

48-
const JurorLevel: React.FC<IJurorLevel> = ({ totalCoherentVotes, totalResolvedVotes, totalResolvedDisputes }) => {
49-
const coherencePercentage = getCoherencePercent(Number(totalCoherentVotes), Number(totalResolvedVotes));
50-
const userLevelData = getUserLevelData(coherencePercentage, Number(totalResolvedDisputes));
45+
const JurorLevel: React.FC<IJurorLevel> = ({ coherenceScore }) => {
46+
const userLevelData = getUserLevelData(coherenceScore);
5147
const level = userLevelData.level;
5248

5349
return (

web/src/pages/Home/TopJurors/JurorCard/MobileCard.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,15 @@ interface IMobileCard {
8282
address: string;
8383
totalCoherentVotes: string;
8484
totalResolvedVotes: string;
85-
totalResolvedDisputes: string;
85+
coherenceScore: string;
8686
}
8787

8888
const MobileCard: React.FC<IMobileCard> = ({
8989
rank,
9090
address,
9191
totalCoherentVotes,
9292
totalResolvedVotes,
93-
totalResolvedDisputes,
93+
coherenceScore,
9494
}) => {
9595
return (
9696
<Container>
@@ -99,7 +99,7 @@ const MobileCard: React.FC<IMobileCard> = ({
9999
{rank ? <Rank rank={rank} /> : null}
100100
<JurorTitle address={address} />
101101
</RankAndTitle>
102-
<JurorLevel {...{ totalCoherentVotes, totalResolvedVotes, totalResolvedDisputes }} />
102+
<JurorLevel coherenceScore={Number(coherenceScore)} />
103103
</TopSide>
104104
<BottomSide>
105105
<HeaderRewardsAndRewards>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { Tooltip } from "@kleros/ui-components-library";
2+
import React from "react";
3+
4+
import styled from "styled-components";
5+
6+
const Container = styled.div`
7+
display: flex;
8+
align-items: center;
9+
font-weight: 600;
10+
color: ${({ theme }) => theme.primaryText};
11+
flex-wrap: wrap;
12+
justify-content: center;
13+
`;
14+
15+
interface IScore {
16+
coherenceScore: string;
17+
}
18+
19+
const Score: React.FC<IScore> = ({ coherenceScore }) => {
20+
return (
21+
<Container>
22+
<Tooltip text={coherenceScore}>{coherenceScore}</Tooltip>
23+
</Container>
24+
);
25+
};
26+
27+
export default Score;

web/src/pages/Home/TopJurors/JurorCard/index.tsx

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,13 @@ import MobileCard from "./MobileCard";
66
interface IJurorCard {
77
rank: number;
88
address: `0x${string}`;
9+
coherenceScore: string;
910
totalCoherentVotes: string;
1011
totalResolvedVotes: string;
11-
totalResolvedDisputes: string;
1212
}
1313

14-
const JurorCard: React.FC<IJurorCard> = ({
15-
rank,
16-
address,
17-
totalCoherentVotes,
18-
totalResolvedVotes,
19-
totalResolvedDisputes,
20-
}) => {
21-
const allProps = { rank, address, totalCoherentVotes, totalResolvedVotes, totalResolvedDisputes };
14+
const JurorCard: React.FC<IJurorCard> = ({ rank, address, coherenceScore, totalCoherentVotes, totalResolvedVotes }) => {
15+
const allProps = { rank, address, coherenceScore, totalCoherentVotes, totalResolvedVotes };
2216

2317
return (
2418
<>

web/src/pages/Profile/JurorInfo/index.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import styled, { css } from "styled-components";
44
import { Card as _Card } from "@kleros/ui-components-library";
55

66
import { getUserLevelData } from "utils/userLevelCalculation";
7-
import { getCoherencePercent } from "utils/getCoherencePercent";
87

98
import { useUserQuery } from "queries/useUser";
109

@@ -46,9 +45,8 @@ const JurorInfo: React.FC<IJurorInfo> = ({ addressToQuery }) => {
4645
const { data } = useUserQuery(addressToQuery);
4746
const totalCoherentVotes = data?.user ? parseInt(data?.user?.totalCoherentVotes) : 0;
4847
const totalResolvedVotes = data?.user ? parseInt(data?.user?.totalResolvedVotes) : 0;
49-
const totalResolvedDisputes = data?.user ? parseInt(data?.user?.totalResolvedDisputes) : 0;
50-
const coherencePercentage = getCoherencePercent(Number(totalCoherentVotes), Number(totalResolvedVotes));
51-
const userLevelData = getUserLevelData(coherencePercentage, totalResolvedDisputes);
48+
const coherenceScore = data?.user ? parseInt(data?.user?.coherenceScore) : 0;
49+
const userLevelData = getUserLevelData(coherenceScore);
5250

5351
return (
5452
<Container>

0 commit comments

Comments
 (0)