Skip to content

Commit a78bdff

Browse files
committed
feat(web): add dashboard pixel arts per level
1 parent f8eee02 commit a78bdff

File tree

8 files changed

+104
-41
lines changed

8 files changed

+104
-41
lines changed
68.7 KB
Loading
69.1 KB
Loading
68.3 KB
Loading
68.8 KB
Loading
67.8 KB
Loading
Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
import React from "react";
2-
import styled from "styled-components";
3-
import { useAccount } from "wagmi";
2+
import styled, { css } from "styled-components";
3+
import { landscapeStyle } from "styles/landscapeStyle";
44
import { CircularProgress } from "@kleros/ui-components-library";
55
import WithHelpTooltip from "../WithHelpTooltip";
6-
import { useUserQuery } from "queries/useUser";
76

87
const Container = styled.div`
98
display: flex;
109
flex-direction: column;
1110
align-items: center;
1211
gap: 4px;
12+
13+
${landscapeStyle(
14+
() => css`
15+
gap: 0;
16+
`
17+
)}
1318
`;
1419

1520
const tooltipMsg =
@@ -18,44 +23,33 @@ const tooltipMsg =
1823
" using the number of times you have been coherent and the total cases you" +
1924
" have been in.";
2025

21-
const levelTitles = [
22-
{ scoreRange: [0, 20], level: 0, title: "Diogenes" },
23-
{ scoreRange: [20, 40], level: 1, title: "Pythagoras" },
24-
{ scoreRange: [40, 60], level: 2, title: "Socrates" },
25-
{ scoreRange: [60, 80], level: 3, title: "Plato" },
26-
{ scoreRange: [80, 100], level: 4, title: "Aristotle" },
27-
];
28-
29-
const Coherency: React.FC = () => {
30-
const { address } = useAccount();
31-
const { data } = useUserQuery(address?.toLowerCase());
32-
const totalCoherent = data?.user ? parseInt(data?.user?.totalCoherent) : 0;
33-
const totalResolvedDisputes = data?.user ? parseInt(data?.user?.totalResolvedDisputes) : 1;
34-
const coherencyScore = calculateCoherencyScore(totalCoherent, totalResolvedDisputes);
35-
const roundedCoherencyScore = Math.round(coherencyScore * 100);
36-
const { level, title } =
37-
levelTitles.find(({ scoreRange }) => {
38-
return roundedCoherencyScore >= scoreRange[0] && roundedCoherencyScore < scoreRange[1];
39-
}) ?? levelTitles[0];
26+
interface ICoherency {
27+
userLevelData: {
28+
scoreRange: number[];
29+
level: number;
30+
title: string;
31+
};
32+
score: number;
33+
totalCoherent: number;
34+
totalResolvedDisputes: number;
35+
}
4036

37+
const Coherency: React.FC<ICoherency> = ({ userLevelData, score, totalCoherent, totalResolvedDisputes }) => {
4138
return (
4239
<Container>
43-
<small>{title}</small>
44-
<label>Level {level}</label>
40+
<small>{userLevelData.title}</small>
41+
<label>Level {userLevelData.level}</label>
4542
<CircularProgress
4643
progress={parseFloat(((totalCoherent / Math.max(totalResolvedDisputes, 1)) * 100).toFixed(2))}
4744
/>
4845
<WithHelpTooltip place="left" {...{ tooltipMsg }}>
4946
<label>
5047
Coherency Score:
51-
<small> {coherencyScore.toFixed(2)} </small>
48+
<small> {score.toFixed(2)} </small>
5249
</label>
5350
</WithHelpTooltip>
5451
</Container>
5552
);
5653
};
5754

58-
const calculateCoherencyScore = (totalCoherent: number, totalDisputes: number): number =>
59-
totalCoherent / (Math.max(totalDisputes, 1) + 10);
60-
6155
export default Coherency;
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import React, { useState } from "react";
2+
import styled from "styled-components";
3+
import Skeleton from "react-loading-skeleton";
4+
import diogenesImage from "assets/pngs/dashboard/diogenes.png";
5+
import pythagorasImage from "assets/pngs/dashboard/pythagoras.png";
6+
import socratesImage from "assets/pngs/dashboard/socrates.png";
7+
import platoImage from "assets/pngs/dashboard/plato.png";
8+
import aristotelesImage from "assets/pngs/dashboard/aristoteles.png";
9+
10+
const StyledImage = styled.img<{ show: boolean }>`
11+
width: 189px;
12+
height: 189px;
13+
display: ${({ show }) => (show ? "block" : "none")};
14+
`;
15+
16+
const StyledSkeleton = styled(Skeleton)`
17+
width: 189px;
18+
height: 189px;
19+
`;
20+
21+
const images = [diogenesImage, pythagorasImage, socratesImage, platoImage, aristotelesImage];
22+
23+
interface IPixelArt {
24+
level: number;
25+
}
26+
27+
const PixelArt: React.FC<IPixelArt> = ({ level }) => {
28+
const [imageLoaded, setImageLoaded] = useState(false);
29+
return (
30+
<div>
31+
{!imageLoaded && <StyledSkeleton />}
32+
<StyledImage
33+
src={images[level]}
34+
alt="Pixel Art per Level"
35+
onLoad={() => setImageLoaded(true)}
36+
show={imageLoaded}
37+
/>
38+
</div>
39+
);
40+
};
41+
42+
export default PixelArt;

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

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ import { landscapeStyle } from "styles/landscapeStyle";
44
import { Card as _Card } from "@kleros/ui-components-library";
55
import Coherency from "./Coherency";
66
import JurorRewards from "./JurorRewards";
7+
import PixelArt from "./PixelArt";
8+
import { useAccount } from "wagmi";
9+
import { useUserQuery } from "queries/useUser";
710
// import StakingRewards from "./StakingRewards";
811

912
const Container = styled.div``;
@@ -13,37 +16,61 @@ const Header = styled.h1`
1316
`;
1417

1518
const Card = styled(_Card)`
16-
width: 100%;
17-
height: auto;
18-
`;
19-
20-
const Layout = styled.div`
2119
display: flex;
2220
flex-direction: column;
2321
align-items: center;
2422
justify-content: center;
2523
26-
gap: 24px;
27-
width: auto;
28-
margin: 16px 32px;
24+
gap: 40px;
25+
width: 100%;
26+
height: auto;
27+
padding: 24px 0;
2928
3029
${landscapeStyle(
3130
() => css`
3231
flex-direction: row;
33-
gap: 48px;
32+
gap: calc(24px + (64 - 24) * (min(max(100vw, 375px), 1250px) - 375px) / 875);
33+
height: 236px;
3434
`
3535
)}
3636
`;
3737

38+
const levelTitles = [
39+
{ scoreRange: [0, 20], level: 0, title: "Diogenes" },
40+
{ scoreRange: [20, 40], level: 1, title: "Pythagoras" },
41+
{ scoreRange: [40, 60], level: 2, title: "Socrates" },
42+
{ scoreRange: [60, 80], level: 3, title: "Plato" },
43+
{ scoreRange: [80, 100], level: 4, title: "Aristotle" },
44+
];
45+
46+
const calculateCoherencyScore = (totalCoherent: number, totalDisputes: number): number =>
47+
totalCoherent / (Math.max(totalDisputes, 1) + 10);
48+
3849
const JurorInfo: React.FC = () => {
50+
const { address } = useAccount();
51+
const { data } = useUserQuery(address?.toLowerCase());
52+
const totalCoherent = data?.user ? parseInt(data?.user?.totalCoherent) : 0;
53+
const totalResolvedDisputes = data?.user ? parseInt(data?.user?.totalResolvedDisputes) : 1;
54+
55+
const coherencyScore = calculateCoherencyScore(totalCoherent, totalResolvedDisputes);
56+
const roundedCoherencyScore = Math.round(coherencyScore * 100);
57+
const userLevelData =
58+
levelTitles.find(({ scoreRange }) => {
59+
return roundedCoherencyScore >= scoreRange[0] && roundedCoherencyScore < scoreRange[1];
60+
}) ?? levelTitles[0];
61+
3962
return (
4063
<Container>
4164
<Header>Juror Dashboard</Header>
4265
<Card>
43-
<Layout>
44-
<Coherency />
45-
<JurorRewards />
46-
</Layout>
66+
<PixelArt level={userLevelData.level} />
67+
<Coherency
68+
userLevelData={userLevelData}
69+
score={coherencyScore}
70+
totalCoherent={totalCoherent}
71+
totalResolvedDisputes={totalResolvedDisputes}
72+
/>
73+
<JurorRewards />
4774
</Card>
4875
</Container>
4976
);

0 commit comments

Comments
 (0)