Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: UX & UI impros in various places (evidence cards, voting cards, case overview, top jurors) #1754

Merged
2 changes: 2 additions & 0 deletions subgraph/core/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ interface Evidence {
sender: User!
senderAddress: String!
timestamp: BigInt!
transactionHash: Bytes!
name: String
description: String
fileURI: String
Expand Down Expand Up @@ -318,6 +319,7 @@ type ClassicEvidence implements Evidence @entity(immutable: true) {
sender: User!
senderAddress: String!
timestamp: BigInt!
transactionHash: Bytes!
kemuru marked this conversation as resolved.
Show resolved Hide resolved
name: String
description: String
fileURI: String
Expand Down
1 change: 1 addition & 0 deletions subgraph/core/src/EvidenceModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export function handleEvidenceEvent(event: EvidenceEvent): void {
evidence.evidenceIndex = evidenceIndex.plus(ONE).toString();
const userId = event.params._party.toHexString();
evidence.timestamp = event.block.timestamp;
evidence.transactionHash = event.transaction.hash;
evidence.evidence = event.params._evidence;
evidence.evidenceGroup = evidenceGroupID.toString();
evidence.sender = userId;
Expand Down
2 changes: 1 addition & 1 deletion subgraph/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@kleros/kleros-v2-subgraph",
"version": "0.9.0",
"version": "0.9.1",
"license": "MIT",
"scripts": {
"update:core:arbitrum-sepolia-devnet": "./scripts/update.sh arbitrumSepoliaDevnet arbitrum-sepolia core/subgraph.yaml",
Expand Down
23 changes: 21 additions & 2 deletions web/src/components/DisputeView/DisputeInfo/DisputeInfoCard.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import React, { useMemo } from "react";
import styled, { css } from "styled-components";

import { Link } from "react-router-dom";

import LawBalanceIcon from "svgs/icons/law-balance.svg";

import { useScrollTop } from "hooks/useScrollTop";
import { useCourtTree } from "hooks/queries/useCourtTree";

import { landscapeStyle } from "styles/landscapeStyle";
Expand All @@ -12,7 +15,7 @@ import { getCourtsPath } from "pages/Courts/CourtDetails";

import CardLabel from "../CardLabels";

import { FieldItem, IDisputeInfo } from ".";
import { FieldItem, IDisputeInfo } from "./index";

const Container = styled.div`
display: flex;
Expand Down Expand Up @@ -59,6 +62,19 @@ const StyledField = styled(Field)`
margin-left: 8px;
overflow: hidden;
text-overflow: ellipsis;
text-wrap: auto;
}
}
`;

const StyledLink = styled(Link)`
:hover {
label {
&.value {
cursor: pointer;
color: ${({ theme }) => theme.primaryBlue};
text-decoration: underline;
}
}
}
`;
Expand All @@ -74,6 +90,7 @@ const DisputeInfoCard: React.FC<IDisputeInfoCard> = ({
disputeID,
round,
}) => {
const scrollTop = useScrollTop();
const { data } = useCourtTree();
const courtPath = getCourtsPath(data?.court, courtId);
const items = useMemo(
Expand All @@ -86,7 +103,9 @@ const DisputeInfoCard: React.FC<IDisputeInfoCard> = ({
<Container>
{court && courtId && isOverview && (
<CourtBranchFieldContainer>
<StyledField icon={LawBalanceIcon} name="Court Branch" value={courtBranchValue} {...{ isOverview }} />
<StyledLink to={`/courts/${courtId}`} onClick={() => scrollTop()}>
<StyledField icon={LawBalanceIcon} name="Court Branch" value={courtBranchValue} {...{ isOverview }} />
</StyledLink>
</CourtBranchFieldContainer>
)}
<RestOfFieldsContainer {...{ isOverview }}>
Expand Down
48 changes: 42 additions & 6 deletions web/src/components/EvidenceCard.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from "react";
import React, { useMemo } from "react";
import styled, { css } from "styled-components";

import Identicon from "react-identicons";
Expand All @@ -9,6 +9,7 @@ import { Card } from "@kleros/ui-components-library";

import AttachmentIcon from "svgs/icons/attachment.svg";

import { DEFAULT_CHAIN, getChain } from "consts/chains";
import { formatDate } from "utils/date";
import { getIpfsUrl } from "utils/getIpfsUrl";
import { shortenAddress } from "utils/shortenAddress";
Expand Down Expand Up @@ -116,6 +117,19 @@ const StyledLink = styled(Link)`
)}
`;

const StyledA = styled.a`
:hover {
text-decoration: underline;
p {
color: ${({ theme }) => theme.primaryBlue};
}
label {
cursor: pointer;
color: ${({ theme }) => theme.primaryBlue};
}
}
`;

const AttachedFileText: React.FC = () => (
<>
<DesktopText>View attached file</DesktopText>
Expand All @@ -126,9 +140,27 @@ const AttachedFileText: React.FC = () => (
interface IEvidenceCard extends Pick<Evidence, "evidence" | "timestamp" | "name" | "description" | "fileURI"> {
sender: string;
index: number;
transactionHash: string;
}

const EvidenceCard: React.FC<IEvidenceCard> = ({ evidence, sender, index, timestamp, name, description, fileURI }) => {
const EvidenceCard: React.FC<IEvidenceCard> = ({
evidence,
sender,
index,
timestamp,
transactionHash,
name,
description,
fileURI,
}) => {
const addressExplorerLink = useMemo(() => {
kemuru marked this conversation as resolved.
Show resolved Hide resolved
return `${getChain(DEFAULT_CHAIN)?.blockExplorers?.default.url}/address/${sender}`;
}, [sender]);

const transactionExplorerLink = useMemo(() => {
return `${getChain(DEFAULT_CHAIN)?.blockExplorers?.default.url}/tx/${transactionHash}`;
}, [transactionHash]);

kemuru marked this conversation as resolved.
Show resolved Hide resolved
return (
<StyledCard>
<TextContainer>
Expand All @@ -145,15 +177,19 @@ const EvidenceCard: React.FC<IEvidenceCard> = ({ evidence, sender, index, timest
<BottomShade>
<AccountContainer>
<Identicon size="24" string={sender} />
<p>{shortenAddress(sender)}</p>
<StyledA href={addressExplorerLink} rel="noopener noreferrer" target="_blank">
<p>{shortenAddress(sender)}</p>
</StyledA>
</AccountContainer>
<Timestamp>{formatDate(Number(timestamp), true)}</Timestamp>
{fileURI && (
<StyledA href={transactionExplorerLink} rel="noopener noreferrer" target="_blank">
<Timestamp>{formatDate(Number(timestamp), true)}</Timestamp>
</StyledA>
{fileURI && fileURI !== "-" ? (
<StyledLink to={`attachment/?url=${getIpfsUrl(fileURI)}`}>
<AttachmentIcon />
<AttachedFileText />
</StyledLink>
)}
) : null}
</BottomShade>
</StyledCard>
);
Expand Down
1 change: 1 addition & 0 deletions web/src/hooks/queries/useEvidences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export const evidenceFragment = graphql(`
id
}
timestamp
transactionHash
name
description
fileURI
Expand Down
12 changes: 12 additions & 0 deletions web/src/hooks/useScrollTop.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { useContext } from "react";
import { OverlayScrollContext } from "context/OverlayScrollContext";

export const useScrollTop = () => {
const osInstanceRef = useContext(OverlayScrollContext);

const scrollTop = () => {
osInstanceRef?.current?.osInstance().elements().viewport.scroll({ top: 0 });
};

return scrollTop;
};
kemuru marked this conversation as resolved.
Show resolved Hide resolved
22 changes: 12 additions & 10 deletions web/src/pages/Cases/CaseDetails/Evidence/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,16 @@ const Evidence: React.FC = () => {
<EvidenceSearch {...{ search, setSearch, evidenceGroup: disputeData?.dispute?.externalDisputeId }} />
<ScrollButton small Icon={DownArrow} text="Scroll to latest" onClick={scrollToLatest} />
{evidences?.realEvidences ? (
evidences?.realEvidences.map(({ evidence, sender, timestamp, name, description, fileURI, evidenceIndex }) => (
<EvidenceCard
key={timestamp}
index={parseInt(evidenceIndex)}
sender={sender?.id}
{...{ evidence, timestamp, name, description, fileURI }}
/>
))
evidences?.realEvidences.map(
({ evidence, sender, timestamp, transactionHash, name, description, fileURI, evidenceIndex }) => (
<EvidenceCard
key={timestamp}
index={parseInt(evidenceIndex)}
sender={sender?.id}
{...{ evidence, timestamp, transactionHash, name, description, fileURI }}
/>
)
)
) : (
<SkeletonEvidenceCard />
)}
Expand All @@ -111,12 +113,12 @@ const Evidence: React.FC = () => {
<Divider />
{showSpam ? (
evidences?.spamEvidences.map(
({ evidence, sender, timestamp, name, description, fileURI, evidenceIndex }) => (
({ evidence, sender, timestamp, transactionHash, name, description, fileURI, evidenceIndex }) => (
<EvidenceCard
key={timestamp}
index={parseInt(evidenceIndex)}
sender={sender?.id}
{...{ evidence, timestamp, name, description, fileURI }}
{...{ evidence, timestamp, transactionHash, name, description, fileURI }}
/>
)
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React from "react";
import React, { useMemo } from "react";
import styled, { css } from "styled-components";

import Identicon from "react-identicons";

import { Answer } from "context/NewDisputeContext";
import { DEFAULT_CHAIN, getChain } from "consts/chains";
import { getVoteChoice } from "utils/getVoteChoice";
import { isUndefined } from "utils/index";
import { shortenAddress } from "utils/shortenAddress";
Expand All @@ -24,11 +25,13 @@ const TitleContainer = styled.div`
`
)}
`;

const AddressContainer = styled.div`
display: flex;
gap: 8px;
align-items: center;
`;

const StyledLabel = styled.label<{ variant?: string }>`
color: ${({ theme, variant }) => (variant ? theme[variant] : theme.primaryText)};
font-size: 16px;
Expand All @@ -38,6 +41,16 @@ const StyledSmall = styled.small`
font-size: 16px;
`;

const StyledA = styled.a`
:hover {
text-decoration: underline;
label {
cursor: pointer;
color: ${({ theme }) => theme.primaryBlue};
}
}
`;

const VoteStatus: React.FC<{
choice?: string;
period: string;
Expand Down Expand Up @@ -75,11 +88,17 @@ const AccordionTitle: React.FC<{
commited: boolean;
hiddenVotes: boolean;
}> = ({ juror, choice, voteCount, period, answers, isActiveRound, commited, hiddenVotes }) => {
const addressExplorerLink = useMemo(() => {
return `${getChain(DEFAULT_CHAIN)?.blockExplorers?.default.url}/address/${juror}`;
}, [juror]);

return (
<TitleContainer>
<AddressContainer>
<Identicon size="20" string={juror} />
<StyledLabel variant="secondaryText">{shortenAddress(juror)}</StyledLabel>
<StyledA href={addressExplorerLink} rel="noopener noreferrer" target="_blank">
<StyledLabel variant="secondaryText">{shortenAddress(juror)}</StyledLabel>
</StyledA>
</AddressContainer>
<VoteStatus {...{ choice, period, answers, isActiveRound, commited, hiddenVotes }} />
<StyledLabel variant="secondaryPurple">
Expand Down
21 changes: 19 additions & 2 deletions web/src/pages/Home/TopJurors/JurorCard/JurorTitle.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React from "react";
import React, { useMemo } from "react";
import styled from "styled-components";

import { IdenticonOrAvatar, AddressOrName } from "components/ConnectWallet/AccountDisplay";
import { DEFAULT_CHAIN, getChain } from "consts/chains";

const Container = styled.div`
display: flex;
Expand All @@ -19,15 +20,31 @@ const Container = styled.div`
}
`;

const StyledA = styled.a`
:hover {
text-decoration: underline;
label {
cursor: pointer;
color: ${({ theme }) => theme.primaryBlue};
}
}
`;

interface IJurorTitle {
address: string;
}

const JurorTitle: React.FC<IJurorTitle> = ({ address }) => {
const addressExplorerLink = useMemo(() => {
return `${getChain(DEFAULT_CHAIN)?.blockExplorers?.default.url}/address/${address}`;
}, [address]);

return (
<Container>
<IdenticonOrAvatar address={address} />
<AddressOrName address={address} />
<StyledA href={addressExplorerLink} rel="noopener noreferrer" target="_blank">
<AddressOrName address={address} />
</StyledA>
</Container>
);
};
Expand Down
Loading