Skip to content

Commit 89c1bda

Browse files
authored
Merge pull request #1931 from kleros/feat/new-level-calculations-and-score-in-leaderboard
feat: new level calculations and score in leaderboard
2 parents 1b6b112 + 0c85e69 commit 89c1bda

File tree

13 files changed

+175
-99
lines changed

13 files changed

+175
-99
lines changed

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

+32-23
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

+4-5
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,18 +25,17 @@ 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();
3635

3736
return (
3837
<Container>
39-
<WithHelpTooltip place={isDesktop ? "top" : "left"} tooltipMsg={coherentVotesTooltipMsg}></WithHelpTooltip>
38+
<WithHelpTooltip place={isDesktop ? "top" : "right"} tooltipMsg={coherentVotesTooltipMsg}></WithHelpTooltip>
4039
</Container>
4140
);
4241
};

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

+6-4
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;
@@ -32,9 +33,9 @@ const Container = styled.div<{ renderIcon?: boolean }>`
3233
() => css`
3334
display: grid;
3435
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)};
36+
? `min-content minmax(160px, 1fr) minmax(60px, 1fr) minmax(80px, 0.8fr) minmax(180px, 1.5fr) minmax(100px, 1fr)`
37+
: `minmax(160px, 1fr) minmax(60px, 1fr) minmax(80px, 0.8fr) minmax(180px, 1.5fr) minmax(100px, 1fr)`};
38+
column-gap: ${responsiveSize(12, 24, 900)};
3839
align-items: center;
3940
`
4041
)}
@@ -65,8 +66,9 @@ export const DesktopHeader: React.FC = () => {
6566
<Container renderIcon={renderIcon}>
6667
{renderIcon ? <StyledRankingIcon /> : null}
6768
<StyledLabel>Juror</StyledLabel>
68-
<Rewards />
69+
<Score />
6970
<Coherence />
71+
<Rewards />
7072
<HowItWorksContainer>
7173
<HowItWorks
7274
isMiniGuideOpen={isJurorLevelsMiniGuideOpen}
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" : "right"} tooltipMsg={scoreTooltipMsg}></WithHelpTooltip>
37+
</Container>
38+
);
39+
};
40+
export default Score;

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

+3-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const Container = styled.div`
1212
color: ${({ theme }) => theme.primaryText};
1313
flex-wrap: wrap;
1414
justify-content: center;
15+
margin-top: 2px;
1516
`;
1617

1718
interface ICoherence {
@@ -24,8 +25,8 @@ const Coherence: React.FC<ICoherence> = ({ totalCoherentVotes, totalResolvedVote
2425

2526
return (
2627
<Container>
27-
<Tooltip text={coherenceRatio}>
28-
{getCoherencePercent(Number(totalCoherentVotes), Number(totalResolvedVotes))}
28+
<Tooltip text={getCoherencePercent(Number(totalCoherentVotes), Number(totalResolvedVotes))}>
29+
{coherenceRatio}
2930
</Tooltip>
3031
</Container>
3132
);

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

+9-7
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}
@@ -26,9 +27,9 @@ const Container = styled.div<{ renderRank?: boolean }>`
2627
() => css`
2728
display: grid;
2829
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)};
30+
? `min-content minmax(160px, 1fr) minmax(60px, 1fr) minmax(80px, 0.8fr) minmax(180px, 1.5fr) minmax(100px, 1fr)`
31+
: `minmax(160px, 1fr) minmax(60px, 1fr) minmax(80px, 0.8fr) minmax(180px, 1.5fr) minmax(100px, 1fr)`};
32+
column-gap: ${responsiveSize(12, 24, 900)};
3233
`
3334
)}
3435
@@ -40,27 +41,28 @@ const Container = styled.div<{ renderRank?: boolean }>`
4041
interface IDesktopCard {
4142
rank?: number;
4243
address: string;
44+
coherenceScore: string;
4345
totalCoherentVotes: string;
4446
totalResolvedVotes: string;
45-
totalResolvedDisputes: string;
4647
}
4748

4849
const DesktopCard: React.FC<IDesktopCard> = ({
4950
rank,
5051
address,
52+
coherenceScore,
5153
totalCoherentVotes,
5254
totalResolvedVotes,
53-
totalResolvedDisputes,
5455
}) => {
5556
const renderRank = !!rank;
5657

5758
return (
5859
<Container renderRank={renderRank}>
5960
{renderRank && <Rank rank={rank} />}
6061
<JurorTitle address={address} />
61-
<Rewards address={address} />
62+
<Score coherenceScore={coherenceScore} />
6263
<Coherence {...{ totalCoherentVotes, totalResolvedVotes }} />
63-
<JurorLevel {...{ totalCoherentVotes, totalResolvedVotes, totalResolvedDisputes }} />
64+
<Rewards address={address} />
65+
<JurorLevel coherenceScore={Number(coherenceScore)} />
6466
</Container>
6567
);
6668
};

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

+3-7
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 (

0 commit comments

Comments
 (0)