-
Notifications
You must be signed in to change notification settings - Fork 55
Expand file tree
/
Copy pathOptionCard.tsx
More file actions
119 lines (103 loc) · 2.78 KB
/
OptionCard.tsx
File metadata and controls
119 lines (103 loc) · 2.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import React, { useMemo } from "react";
import styled from "styled-components";
import { hoverShortTransitionTiming } from "styles/commonStyles";
import { useMeasure } from "react-use";
import { formatEther } from "viem";
import { Card, Radio, LinearProgress } from "@kleros/ui-components-library";
import Gavel from "svgs/icons/gavel.svg";
import { isUndefined } from "utils/index";
const StyledCard = styled(Card)`
${hoverShortTransitionTiming}
width: 100%;
padding: 24px;
&:hover {
cursor: pointer;
}
`;
const WinnerLabel = styled.label<{ winner: boolean }>`
color: ${({ theme, winner }) => (winner ? theme.success : theme.warning)};
svg {
width: 12px;
margin-right: 8px;
fill: ${({ theme, winner }) => (winner ? theme.success : theme.warning)};
}
`;
const StyledRadio = styled(Radio)`
padding-left: 24px;
> input {
display: none;
}
`;
const TopContainer = styled.div`
display: flex;
justify-content: space-between;
height: 50%;
`;
const TextContainer = styled.div`
display: flex;
flex-direction: column;
flex-grow: 1;
min-width: 0;
`;
const BlockLabel = styled.label`
display: block;
font-weight: 600;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 100%;
`;
const LabelContainer = styled.div`
width: 100%;
display: flex;
justify-content: center;
`;
interface IOptionCard extends React.HTMLAttributes<HTMLDivElement> {
text: string;
funding: bigint;
required?: bigint;
winner?: boolean;
selected?: boolean;
canBeSelected?: boolean;
}
const OptionCard: React.FC<IOptionCard> = ({
text,
funding,
required,
winner,
selected,
canBeSelected = true,
...props
}) => {
const [ref, { width }] = useMeasure();
const [fundingLabel, progress] = useMemo(() => {
if (!isUndefined(required))
if (funding >= required) return ["Fully funded!", 100];
else
return [
`${formatEther(funding)} out of ${formatEther(required)} ETH required.`,
Number((funding * 100n) / required),
];
else if (funding > 0n) return [`Funded with ${formatEther(funding)} ETH.`, 30];
else return ["0 ETH contributed to this option", 0];
}, [funding, required]);
return (
<StyledCard ref={ref} hover {...props}>
<TopContainer>
<TextContainer>
<BlockLabel>{text}</BlockLabel>
<WinnerLabel winner={winner ? true : false}>
<Gavel />
Jury decision - {winner ? "Winner" : "Loser"}
</WinnerLabel>
</TextContainer>
{canBeSelected && <StyledRadio label="" checked={selected} />}
</TopContainer>
<LabelContainer>
<label>{fundingLabel}</label>
</LabelContainer>
<LinearProgress progress={progress} width={width} />
</StyledCard>
);
};
export default OptionCard;