From 33a9c936b6789e92661cc30b6dfebd5c4bf36b02 Mon Sep 17 00:00:00 2001 From: alcercu Date: Thu, 1 Dec 2022 10:34:46 +0100 Subject: [PATCH 001/144] feat(wip/web): add court details and staking flow --- web/codegen.yaml | 2 +- web/package.json | 9 +- web/src/app.tsx | 5 +- web/src/assets/svgs/icons/min-stake.svg | 13 + web/src/assets/svgs/icons/vote-stake.svg | 15 + web/src/components/DisputeCard/index.tsx | 3 +- web/src/components/WrongChainBoundary.tsx | 2 +- web/src/consts/supportedChains.ts | 6 +- web/src/graphql/generated.ts | 519 ++++++-------- web/src/hooks/queries/useCasesQuery.ts | 4 +- web/src/hooks/queries/useCourtDetails.ts | 32 + web/src/hooks/queries/useCourtPolicy.ts | 23 +- web/src/hooks/queries/useCourtTree.ts | 20 + web/src/hooks/queries/useHomePageQuery.ts | 27 +- web/src/hooks/queries/usePNKAllowance.ts | 18 + web/src/hooks/queries/usePNKBalance.ts | 18 + .../hooks/queries/usePolicyRegistryEvent.ts | 20 + .../pages/Courts/CourtDetails/Description.tsx | 84 +++ .../pages/Courts/CourtDetails/StakeModal.tsx | 104 +++ web/src/pages/Courts/CourtDetails/Stats.tsx | 109 +++ web/src/pages/Courts/CourtDetails/index.tsx | 39 ++ web/src/pages/Courts/TopSearch.tsx | 6 + web/src/pages/Courts/index.tsx | 26 + web/src/pages/Home/CourtOverview/Chart.tsx | 15 +- web/src/pages/Home/CourtOverview/Stats.tsx | 29 +- web/src/utils/getContract.ts | 2 +- yarn.lock | 647 +++++++++++++++++- 27 files changed, 1382 insertions(+), 415 deletions(-) create mode 100644 web/src/assets/svgs/icons/min-stake.svg create mode 100644 web/src/assets/svgs/icons/vote-stake.svg create mode 100644 web/src/hooks/queries/useCourtDetails.ts create mode 100644 web/src/hooks/queries/useCourtTree.ts create mode 100644 web/src/hooks/queries/usePNKAllowance.ts create mode 100644 web/src/hooks/queries/usePNKBalance.ts create mode 100644 web/src/hooks/queries/usePolicyRegistryEvent.ts create mode 100644 web/src/pages/Courts/CourtDetails/Description.tsx create mode 100644 web/src/pages/Courts/CourtDetails/StakeModal.tsx create mode 100644 web/src/pages/Courts/CourtDetails/Stats.tsx create mode 100644 web/src/pages/Courts/CourtDetails/index.tsx create mode 100644 web/src/pages/Courts/TopSearch.tsx create mode 100644 web/src/pages/Courts/index.tsx diff --git a/web/codegen.yaml b/web/codegen.yaml index 9a47307ab..e865e7646 100644 --- a/web/codegen.yaml +++ b/web/codegen.yaml @@ -1,4 +1,4 @@ -schema: https://api.thegraph.com/subgraphs/name/alcercu/kleros-core +schema: https://api.thegraph.com/subgraphs/name/alcercu/kleroscoretest documents: './src/hooks/queries/*.ts' generates: src/graphql/generated.ts: diff --git a/web/package.json b/web/package.json index 577ef8499..653a71a4e 100644 --- a/web/package.json +++ b/web/package.json @@ -32,9 +32,9 @@ "generate": "graphql-codegen" }, "devDependencies": { - "@parcel/transformer-svg-react": "^2.7.0", - "@types/react": "^18.0.24", - "@types/react-dom": "^18.0.6", + "@parcel/transformer-svg-react": "^2.8.0", + "@types/react": "^18.0.25", + "@types/react-dom": "^18.0.9", "@types/styled-components": "^5.1.26", "@typescript-eslint/eslint-plugin": "^5.43.0", "@typescript-eslint/parser": "^5.43.0", @@ -49,7 +49,7 @@ "eslint-plugin-security": "^1.4.0", "eslint-utils": "^3.0.0", "lru-cache": "^7.8.0", - "parcel": "^2.7.0", + "parcel": "^2.8.0", "prettier": "^2.5.1", "typescript": "^4.5.5" }, @@ -77,6 +77,7 @@ "react-is": "^18.2.0", "react-jazzicon": "^1.0.4", "react-loading-skeleton": "^3.1.0", + "react-markdown": "^8.0.3", "react-modal": "^3.16.1", "react-router-dom": "^6.4.2", "styled-components": "^5.3.6", diff --git a/web/src/app.tsx b/web/src/app.tsx index c45c47017..c4ce9e4fc 100644 --- a/web/src/app.tsx +++ b/web/src/app.tsx @@ -10,6 +10,7 @@ import Layout from "layout/index"; import Home from "./pages/Home"; import Cases from "./pages/Cases"; import Dashboard from "./pages/Dashboard"; +import Courts from "./pages/Courts"; const fetcherBuilder = (url: string) => @@ -24,7 +25,7 @@ const App: React.FC = () => { @@ -34,7 +35,7 @@ const App: React.FC = () => { }> } /> } /> - Courts} /> + } /> } /> + + + + + + + + + + + + diff --git a/web/src/assets/svgs/icons/vote-stake.svg b/web/src/assets/svgs/icons/vote-stake.svg new file mode 100644 index 000000000..945ad28ed --- /dev/null +++ b/web/src/assets/svgs/icons/vote-stake.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/web/src/components/DisputeCard/index.tsx b/web/src/components/DisputeCard/index.tsx index 4cb47bfc6..46e531868 100644 --- a/web/src/components/DisputeCard/index.tsx +++ b/web/src/components/DisputeCard/index.tsx @@ -58,8 +58,7 @@ const DisputeCard: React.FC = ({ ); const { data: metaEvidence } = useGetMetaEvidence(id, arbitrated); const title = metaEvidence ? metaEvidence.title : ; - const { data: courtPolicyPath } = useCourtPolicy(parseInt(subcourtID.id)); - const { data: courtPolicy } = useIPFSQuery(courtPolicyPath?.args._policy); + const { data: courtPolicy } = useCourtPolicy(subcourtID.id); const courtName = courtPolicy?.name; const category = metaEvidence ? metaEvidence.category : undefined; const navigate = useNavigate(); diff --git a/web/src/components/WrongChainBoundary.tsx b/web/src/components/WrongChainBoundary.tsx index 4987705a5..b85f47488 100644 --- a/web/src/components/WrongChainBoundary.tsx +++ b/web/src/components/WrongChainBoundary.tsx @@ -16,7 +16,7 @@ const WrongChainRecovery: React.FC<{ resetErrorBoundary: () => void }> = ({ text="Switch to Arbitrum" onClick={() => { setLoading(true); - switchChain(421611) + switchChain(421613) .then(resetErrorBoundary) .finally(() => setLoading(false)); }} diff --git a/web/src/consts/supportedChains.ts b/web/src/consts/supportedChains.ts index 6fbb8dd99..410ae383b 100644 --- a/web/src/consts/supportedChains.ts +++ b/web/src/consts/supportedChains.ts @@ -1,8 +1,8 @@ export const SUPPORTED_CHAINS = { - 421611: { - chainName: "Arbitrum Rinkeby", + 421613: { + chainName: "Arbitrum Goerli", nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://rinkeby.arbitrum.io/rpc"], + rpcUrls: ["https://goerli-rollup.arbitrum.io/rpc"], blockExplorerUrls: ["https://testnet.arbiscan.io/"], }, }; diff --git a/web/src/graphql/generated.ts b/web/src/graphql/generated.ts index 0af901d08..c3cda29d7 100644 --- a/web/src/graphql/generated.ts +++ b/web/src/graphql/generated.ts @@ -21,38 +21,6 @@ export type Scalars = { Bytes: any; }; -export type ActiveJurorsDataPoint = { - __typename?: "ActiveJurorsDataPoint"; - id: Scalars["ID"]; - value: Scalars["BigInt"]; -}; - -export type ActiveJurorsDataPoint_Filter = { - /** Filter for the block changed event. */ - _change_block?: InputMaybe; - id?: InputMaybe; - id_gt?: InputMaybe; - id_gte?: InputMaybe; - id_in?: InputMaybe>; - id_lt?: InputMaybe; - id_lte?: InputMaybe; - id_not?: InputMaybe; - id_not_in?: InputMaybe>; - value?: InputMaybe; - value_gt?: InputMaybe; - value_gte?: InputMaybe; - value_in?: InputMaybe>; - value_lt?: InputMaybe; - value_lte?: InputMaybe; - value_not?: InputMaybe; - value_not_in?: InputMaybe>; -}; - -export enum ActiveJurorsDataPoint_OrderBy { - Id = "id", - Value = "value", -} - export type BlockChangedFilter = { number_gte: Scalars["Int"]; }; @@ -63,15 +31,53 @@ export type Block_Height = { number_gte?: InputMaybe; }; -export type CasesDataPoint = { - __typename?: "CasesDataPoint"; +export type Counter = { + __typename?: "Counter"; + activeJurors: Scalars["BigInt"]; + cases: Scalars["BigInt"]; + casesRuled: Scalars["BigInt"]; + casesVoting: Scalars["BigInt"]; id: Scalars["ID"]; - value: Scalars["BigInt"]; + paidETH: Scalars["BigInt"]; + redistributedPNK: Scalars["BigInt"]; + stakedPNK: Scalars["BigInt"]; }; -export type CasesDataPoint_Filter = { +export type Counter_Filter = { /** Filter for the block changed event. */ _change_block?: InputMaybe; + activeJurors?: InputMaybe; + activeJurors_gt?: InputMaybe; + activeJurors_gte?: InputMaybe; + activeJurors_in?: InputMaybe>; + activeJurors_lt?: InputMaybe; + activeJurors_lte?: InputMaybe; + activeJurors_not?: InputMaybe; + activeJurors_not_in?: InputMaybe>; + cases?: InputMaybe; + casesRuled?: InputMaybe; + casesRuled_gt?: InputMaybe; + casesRuled_gte?: InputMaybe; + casesRuled_in?: InputMaybe>; + casesRuled_lt?: InputMaybe; + casesRuled_lte?: InputMaybe; + casesRuled_not?: InputMaybe; + casesRuled_not_in?: InputMaybe>; + casesVoting?: InputMaybe; + casesVoting_gt?: InputMaybe; + casesVoting_gte?: InputMaybe; + casesVoting_in?: InputMaybe>; + casesVoting_lt?: InputMaybe; + casesVoting_lte?: InputMaybe; + casesVoting_not?: InputMaybe; + casesVoting_not_in?: InputMaybe>; + cases_gt?: InputMaybe; + cases_gte?: InputMaybe; + cases_in?: InputMaybe>; + cases_lt?: InputMaybe; + cases_lte?: InputMaybe; + cases_not?: InputMaybe; + cases_not_in?: InputMaybe>; id?: InputMaybe; id_gt?: InputMaybe; id_gte?: InputMaybe; @@ -80,19 +86,41 @@ export type CasesDataPoint_Filter = { id_lte?: InputMaybe; id_not?: InputMaybe; id_not_in?: InputMaybe>; - value?: InputMaybe; - value_gt?: InputMaybe; - value_gte?: InputMaybe; - value_in?: InputMaybe>; - value_lt?: InputMaybe; - value_lte?: InputMaybe; - value_not?: InputMaybe; - value_not_in?: InputMaybe>; -}; - -export enum CasesDataPoint_OrderBy { + paidETH?: InputMaybe; + paidETH_gt?: InputMaybe; + paidETH_gte?: InputMaybe; + paidETH_in?: InputMaybe>; + paidETH_lt?: InputMaybe; + paidETH_lte?: InputMaybe; + paidETH_not?: InputMaybe; + paidETH_not_in?: InputMaybe>; + redistributedPNK?: InputMaybe; + redistributedPNK_gt?: InputMaybe; + redistributedPNK_gte?: InputMaybe; + redistributedPNK_in?: InputMaybe>; + redistributedPNK_lt?: InputMaybe; + redistributedPNK_lte?: InputMaybe; + redistributedPNK_not?: InputMaybe; + redistributedPNK_not_in?: InputMaybe>; + stakedPNK?: InputMaybe; + stakedPNK_gt?: InputMaybe; + stakedPNK_gte?: InputMaybe; + stakedPNK_in?: InputMaybe>; + stakedPNK_lt?: InputMaybe; + stakedPNK_lte?: InputMaybe; + stakedPNK_not?: InputMaybe; + stakedPNK_not_in?: InputMaybe>; +}; + +export enum Counter_OrderBy { + ActiveJurors = "activeJurors", + Cases = "cases", + CasesRuled = "casesRuled", + CasesVoting = "casesVoting", Id = "id", - Value = "value", + PaidEth = "paidETH", + RedistributedPnk = "redistributedPNK", + StakedPnk = "stakedPNK", } export type Court = { @@ -105,8 +133,13 @@ export type Court = { id: Scalars["ID"]; jurorsForCourtJump: Scalars["BigInt"]; minStake: Scalars["BigInt"]; + numberDisputes: Scalars["BigInt"]; + numberStakedJurors: Scalars["BigInt"]; + paidETH: Scalars["BigInt"]; + paidPNK: Scalars["BigInt"]; parent?: Maybe; policy?: Maybe; + stake: Scalars["BigInt"]; stakedJurors: Array; supportedDisputeKits: Array; timesPerPeriod: Array; @@ -202,6 +235,38 @@ export type Court_Filter = { minStake_lte?: InputMaybe; minStake_not?: InputMaybe; minStake_not_in?: InputMaybe>; + numberDisputes?: InputMaybe; + numberDisputes_gt?: InputMaybe; + numberDisputes_gte?: InputMaybe; + numberDisputes_in?: InputMaybe>; + numberDisputes_lt?: InputMaybe; + numberDisputes_lte?: InputMaybe; + numberDisputes_not?: InputMaybe; + numberDisputes_not_in?: InputMaybe>; + numberStakedJurors?: InputMaybe; + numberStakedJurors_gt?: InputMaybe; + numberStakedJurors_gte?: InputMaybe; + numberStakedJurors_in?: InputMaybe>; + numberStakedJurors_lt?: InputMaybe; + numberStakedJurors_lte?: InputMaybe; + numberStakedJurors_not?: InputMaybe; + numberStakedJurors_not_in?: InputMaybe>; + paidETH?: InputMaybe; + paidETH_gt?: InputMaybe; + paidETH_gte?: InputMaybe; + paidETH_in?: InputMaybe>; + paidETH_lt?: InputMaybe; + paidETH_lte?: InputMaybe; + paidETH_not?: InputMaybe; + paidETH_not_in?: InputMaybe>; + paidPNK?: InputMaybe; + paidPNK_gt?: InputMaybe; + paidPNK_gte?: InputMaybe; + paidPNK_in?: InputMaybe>; + paidPNK_lt?: InputMaybe; + paidPNK_lte?: InputMaybe; + paidPNK_not?: InputMaybe; + paidPNK_not_in?: InputMaybe>; parent?: InputMaybe; parent_?: InputMaybe; parent_contains?: InputMaybe; @@ -243,6 +308,14 @@ export type Court_Filter = { policy_not_starts_with_nocase?: InputMaybe; policy_starts_with?: InputMaybe; policy_starts_with_nocase?: InputMaybe; + stake?: InputMaybe; + stake_gt?: InputMaybe; + stake_gte?: InputMaybe; + stake_in?: InputMaybe>; + stake_lt?: InputMaybe; + stake_lte?: InputMaybe; + stake_not?: InputMaybe; + stake_not_in?: InputMaybe>; stakedJurors_?: InputMaybe; supportedDisputeKits?: InputMaybe>; supportedDisputeKits_?: InputMaybe; @@ -271,8 +344,13 @@ export enum Court_OrderBy { Id = "id", JurorsForCourtJump = "jurorsForCourtJump", MinStake = "minStake", + NumberDisputes = "numberDisputes", + NumberStakedJurors = "numberStakedJurors", + PaidEth = "paidETH", + PaidPnk = "paidPNK", Parent = "parent", Policy = "policy", + Stake = "stake", StakedJurors = "stakedJurors", SupportedDisputeKits = "supportedDisputeKits", TimesPerPeriod = "timesPerPeriod", @@ -614,38 +692,6 @@ export enum Draw_OrderBy { VoteId = "voteID", } -export type EthPaidDataPoint = { - __typename?: "ETHPaidDataPoint"; - id: Scalars["ID"]; - value: Scalars["BigInt"]; -}; - -export type EthPaidDataPoint_Filter = { - /** Filter for the block changed event. */ - _change_block?: InputMaybe; - id?: InputMaybe; - id_gt?: InputMaybe; - id_gte?: InputMaybe; - id_in?: InputMaybe>; - id_lt?: InputMaybe; - id_lte?: InputMaybe; - id_not?: InputMaybe; - id_not_in?: InputMaybe>; - value?: InputMaybe; - value_gt?: InputMaybe; - value_gte?: InputMaybe; - value_in?: InputMaybe>; - value_lt?: InputMaybe; - value_lte?: InputMaybe; - value_not?: InputMaybe; - value_not_in?: InputMaybe>; -}; - -export enum EthPaidDataPoint_OrderBy { - Id = "id", - Value = "value", -} - export type Evidence = { __typename?: "Evidence"; evidence: Scalars["String"]; @@ -849,6 +895,7 @@ export type Juror = { id: Scalars["ID"]; shifts: Array; tokens: Array; + totalStake: Scalars["BigInt"]; votes: Array; }; @@ -986,6 +1033,14 @@ export type Juror_Filter = { id_not_in?: InputMaybe>; shifts_?: InputMaybe; tokens_?: InputMaybe; + totalStake?: InputMaybe; + totalStake_gt?: InputMaybe; + totalStake_gte?: InputMaybe; + totalStake_in?: InputMaybe>; + totalStake_lt?: InputMaybe; + totalStake_lte?: InputMaybe; + totalStake_not?: InputMaybe; + totalStake_not_in?: InputMaybe>; votes_?: InputMaybe; }; @@ -994,6 +1049,7 @@ export enum Juror_OrderBy { Id = "id", Shifts = "shifts", Tokens = "tokens", + TotalStake = "totalStake", Votes = "votes", } @@ -1067,70 +1123,6 @@ export enum OutgoingBatch_OrderBy { Size = "size", } -export type PnkRedistributedDataPoint = { - __typename?: "PNKRedistributedDataPoint"; - id: Scalars["ID"]; - value: Scalars["BigInt"]; -}; - -export type PnkRedistributedDataPoint_Filter = { - /** Filter for the block changed event. */ - _change_block?: InputMaybe; - id?: InputMaybe; - id_gt?: InputMaybe; - id_gte?: InputMaybe; - id_in?: InputMaybe>; - id_lt?: InputMaybe; - id_lte?: InputMaybe; - id_not?: InputMaybe; - id_not_in?: InputMaybe>; - value?: InputMaybe; - value_gt?: InputMaybe; - value_gte?: InputMaybe; - value_in?: InputMaybe>; - value_lt?: InputMaybe; - value_lte?: InputMaybe; - value_not?: InputMaybe; - value_not_in?: InputMaybe>; -}; - -export enum PnkRedistributedDataPoint_OrderBy { - Id = "id", - Value = "value", -} - -export type PnkStakedDataPoint = { - __typename?: "PNKStakedDataPoint"; - id: Scalars["ID"]; - value: Scalars["BigInt"]; -}; - -export type PnkStakedDataPoint_Filter = { - /** Filter for the block changed event. */ - _change_block?: InputMaybe; - id?: InputMaybe; - id_gt?: InputMaybe; - id_gte?: InputMaybe; - id_in?: InputMaybe>; - id_lt?: InputMaybe; - id_lte?: InputMaybe; - id_not?: InputMaybe; - id_not_in?: InputMaybe>; - value?: InputMaybe; - value_gt?: InputMaybe; - value_gte?: InputMaybe; - value_in?: InputMaybe>; - value_lt?: InputMaybe; - value_lte?: InputMaybe; - value_not?: InputMaybe; - value_not_in?: InputMaybe>; -}; - -export enum PnkStakedDataPoint_OrderBy { - Id = "id", - Value = "value", -} - export enum Period { Appeal = "Appeal", Commit = "Commit", @@ -1143,10 +1135,8 @@ export type Query = { __typename?: "Query"; /** Access to subgraph metadata */ _meta?: Maybe<_Meta_>; - activeJurorsDataPoint?: Maybe; - activeJurorsDataPoints: Array; - casesDataPoint?: Maybe; - casesDataPoints: Array; + counter?: Maybe; + counters: Array; court?: Maybe; courts: Array; dispute?: Maybe; @@ -1155,8 +1145,6 @@ export type Query = { disputes: Array; draw?: Maybe; draws: Array; - ethpaidDataPoint?: Maybe; - ethpaidDataPoints: Array; evidence?: Maybe; evidenceGroup?: Maybe; evidenceGroups: Array; @@ -1169,10 +1157,6 @@ export type Query = { jurors: Array; outgoingBatch?: Maybe; outgoingBatches: Array; - pnkredistributedDataPoint?: Maybe; - pnkredistributedDataPoints: Array; - pnkstakedDataPoint?: Maybe; - pnkstakedDataPoints: Array; round?: Maybe; rounds: Array; tokenAndETHShift?: Maybe; @@ -1185,36 +1169,20 @@ export type Query_MetaArgs = { block?: InputMaybe; }; -export type QueryActiveJurorsDataPointArgs = { +export type QueryCounterArgs = { block?: InputMaybe; id: Scalars["ID"]; subgraphError?: _SubgraphErrorPolicy_; }; -export type QueryActiveJurorsDataPointsArgs = { +export type QueryCountersArgs = { block?: InputMaybe; first?: InputMaybe; - orderBy?: InputMaybe; + orderBy?: InputMaybe; orderDirection?: InputMaybe; skip?: InputMaybe; subgraphError?: _SubgraphErrorPolicy_; - where?: InputMaybe; -}; - -export type QueryCasesDataPointArgs = { - block?: InputMaybe; - id: Scalars["ID"]; - subgraphError?: _SubgraphErrorPolicy_; -}; - -export type QueryCasesDataPointsArgs = { - block?: InputMaybe; - first?: InputMaybe; - orderBy?: InputMaybe; - orderDirection?: InputMaybe; - skip?: InputMaybe; - subgraphError?: _SubgraphErrorPolicy_; - where?: InputMaybe; + where?: InputMaybe; }; export type QueryCourtArgs = { @@ -1281,22 +1249,6 @@ export type QueryDrawsArgs = { where?: InputMaybe; }; -export type QueryEthpaidDataPointArgs = { - block?: InputMaybe; - id: Scalars["ID"]; - subgraphError?: _SubgraphErrorPolicy_; -}; - -export type QueryEthpaidDataPointsArgs = { - block?: InputMaybe; - first?: InputMaybe; - orderBy?: InputMaybe; - orderDirection?: InputMaybe; - skip?: InputMaybe; - subgraphError?: _SubgraphErrorPolicy_; - where?: InputMaybe; -}; - export type QueryEvidenceArgs = { block?: InputMaybe; id: Scalars["ID"]; @@ -1393,38 +1345,6 @@ export type QueryOutgoingBatchesArgs = { where?: InputMaybe; }; -export type QueryPnkredistributedDataPointArgs = { - block?: InputMaybe; - id: Scalars["ID"]; - subgraphError?: _SubgraphErrorPolicy_; -}; - -export type QueryPnkredistributedDataPointsArgs = { - block?: InputMaybe; - first?: InputMaybe; - orderBy?: InputMaybe; - orderDirection?: InputMaybe; - skip?: InputMaybe; - subgraphError?: _SubgraphErrorPolicy_; - where?: InputMaybe; -}; - -export type QueryPnkstakedDataPointArgs = { - block?: InputMaybe; - id: Scalars["ID"]; - subgraphError?: _SubgraphErrorPolicy_; -}; - -export type QueryPnkstakedDataPointsArgs = { - block?: InputMaybe; - first?: InputMaybe; - orderBy?: InputMaybe; - orderDirection?: InputMaybe; - skip?: InputMaybe; - subgraphError?: _SubgraphErrorPolicy_; - where?: InputMaybe; -}; - export type QueryRoundArgs = { block?: InputMaybe; id: Scalars["ID"]; @@ -1475,6 +1395,7 @@ export type QueryVotesArgs = { export type Round = { __typename?: "Round"; + currentDecision?: Maybe; dispute: Dispute; disputeKitID: DisputeKit; drawnJurors: Array; @@ -1507,6 +1428,14 @@ export type RoundVotesArgs = { export type Round_Filter = { /** Filter for the block changed event. */ _change_block?: InputMaybe; + currentDecision?: InputMaybe; + currentDecision_gt?: InputMaybe; + currentDecision_gte?: InputMaybe; + currentDecision_in?: InputMaybe>; + currentDecision_lt?: InputMaybe; + currentDecision_lte?: InputMaybe; + currentDecision_not?: InputMaybe; + currentDecision_not_in?: InputMaybe>; dispute?: InputMaybe; disputeKitID?: InputMaybe; disputeKitID_?: InputMaybe; @@ -1610,6 +1539,7 @@ export type Round_Filter = { }; export enum Round_OrderBy { + CurrentDecision = "currentDecision", Dispute = "dispute", DisputeKitId = "disputeKitID", DrawnJurors = "drawnJurors", @@ -1627,10 +1557,8 @@ export type Subscription = { __typename?: "Subscription"; /** Access to subgraph metadata */ _meta?: Maybe<_Meta_>; - activeJurorsDataPoint?: Maybe; - activeJurorsDataPoints: Array; - casesDataPoint?: Maybe; - casesDataPoints: Array; + counter?: Maybe; + counters: Array; court?: Maybe; courts: Array; dispute?: Maybe; @@ -1639,8 +1567,6 @@ export type Subscription = { disputes: Array; draw?: Maybe; draws: Array; - ethpaidDataPoint?: Maybe; - ethpaidDataPoints: Array; evidence?: Maybe; evidenceGroup?: Maybe; evidenceGroups: Array; @@ -1653,10 +1579,6 @@ export type Subscription = { jurors: Array; outgoingBatch?: Maybe; outgoingBatches: Array; - pnkredistributedDataPoint?: Maybe; - pnkredistributedDataPoints: Array; - pnkstakedDataPoint?: Maybe; - pnkstakedDataPoints: Array; round?: Maybe; rounds: Array; tokenAndETHShift?: Maybe; @@ -1669,36 +1591,20 @@ export type Subscription_MetaArgs = { block?: InputMaybe; }; -export type SubscriptionActiveJurorsDataPointArgs = { +export type SubscriptionCounterArgs = { block?: InputMaybe; id: Scalars["ID"]; subgraphError?: _SubgraphErrorPolicy_; }; -export type SubscriptionActiveJurorsDataPointsArgs = { +export type SubscriptionCountersArgs = { block?: InputMaybe; first?: InputMaybe; - orderBy?: InputMaybe; + orderBy?: InputMaybe; orderDirection?: InputMaybe; skip?: InputMaybe; subgraphError?: _SubgraphErrorPolicy_; - where?: InputMaybe; -}; - -export type SubscriptionCasesDataPointArgs = { - block?: InputMaybe; - id: Scalars["ID"]; - subgraphError?: _SubgraphErrorPolicy_; -}; - -export type SubscriptionCasesDataPointsArgs = { - block?: InputMaybe; - first?: InputMaybe; - orderBy?: InputMaybe; - orderDirection?: InputMaybe; - skip?: InputMaybe; - subgraphError?: _SubgraphErrorPolicy_; - where?: InputMaybe; + where?: InputMaybe; }; export type SubscriptionCourtArgs = { @@ -1765,22 +1671,6 @@ export type SubscriptionDrawsArgs = { where?: InputMaybe; }; -export type SubscriptionEthpaidDataPointArgs = { - block?: InputMaybe; - id: Scalars["ID"]; - subgraphError?: _SubgraphErrorPolicy_; -}; - -export type SubscriptionEthpaidDataPointsArgs = { - block?: InputMaybe; - first?: InputMaybe; - orderBy?: InputMaybe; - orderDirection?: InputMaybe; - skip?: InputMaybe; - subgraphError?: _SubgraphErrorPolicy_; - where?: InputMaybe; -}; - export type SubscriptionEvidenceArgs = { block?: InputMaybe; id: Scalars["ID"]; @@ -1877,38 +1767,6 @@ export type SubscriptionOutgoingBatchesArgs = { where?: InputMaybe; }; -export type SubscriptionPnkredistributedDataPointArgs = { - block?: InputMaybe; - id: Scalars["ID"]; - subgraphError?: _SubgraphErrorPolicy_; -}; - -export type SubscriptionPnkredistributedDataPointsArgs = { - block?: InputMaybe; - first?: InputMaybe; - orderBy?: InputMaybe; - orderDirection?: InputMaybe; - skip?: InputMaybe; - subgraphError?: _SubgraphErrorPolicy_; - where?: InputMaybe; -}; - -export type SubscriptionPnkstakedDataPointArgs = { - block?: InputMaybe; - id: Scalars["ID"]; - subgraphError?: _SubgraphErrorPolicy_; -}; - -export type SubscriptionPnkstakedDataPointsArgs = { - block?: InputMaybe; - first?: InputMaybe; - orderBy?: InputMaybe; - orderDirection?: InputMaybe; - skip?: InputMaybe; - subgraphError?: _SubgraphErrorPolicy_; - where?: InputMaybe; -}; - export type SubscriptionRoundArgs = { block?: InputMaybe; id: Scalars["ID"]; @@ -2222,7 +2080,33 @@ export type CasesPageQuery = { timesPerPeriod: Array; }; }>; - casesDataPoint?: { __typename?: "CasesDataPoint"; value: any } | null; + counter?: { __typename?: "Counter"; cases: any } | null; +}; + +export type CourtDetailsQueryVariables = Exact<{ + ID: Scalars["ID"]; +}>; + +export type CourtDetailsQuery = { + __typename?: "Query"; + court?: { + __typename?: "Court"; + policy?: string | null; + minStake: any; + alpha: any; + numberDisputes: any; + numberStakedJurors: any; + stake: any; + paidETH: any; + paidPNK: any; + } | null; +}; + +export type CourtTreeQueryVariables = Exact<{ [key: string]: never }>; + +export type CourtTreeQuery = { + __typename?: "Query"; + court?: { __typename?: "Court"; id: string } | null; }; export type DisputeDetailsQueryVariables = Exact<{ @@ -2279,30 +2163,15 @@ export type HomePageQueryVariables = Exact<{ export type HomePageQuery = { __typename?: "Query"; disputes: Array<{ __typename?: "Dispute"; id: string }>; - pnkstakedDataPoints: Array<{ - __typename?: "PNKStakedDataPoint"; - id: string; - value: any; - }>; - ethpaidDataPoints: Array<{ - __typename?: "ETHPaidDataPoint"; - id: string; - value: any; - }>; - pnkredistributedDataPoints: Array<{ - __typename?: "PNKRedistributedDataPoint"; - id: string; - value: any; - }>; - activeJurorsDataPoints: Array<{ - __typename?: "ActiveJurorsDataPoint"; - id: string; - value: any; - }>; - casesDataPoints: Array<{ - __typename?: "CasesDataPoint"; - id: string; - value: any; + counters: Array<{ + __typename?: "Counter"; + stakedPNK: any; + redistributedPNK: any; + paidETH: any; + activeJurors: any; + cases: any; + casesVoting: any; + casesRuled: any; }>; }; diff --git a/web/src/hooks/queries/useCasesQuery.ts b/web/src/hooks/queries/useCasesQuery.ts index bcd2970e3..14d9a56b9 100644 --- a/web/src/hooks/queries/useCasesQuery.ts +++ b/web/src/hooks/queries/useCasesQuery.ts @@ -22,8 +22,8 @@ const casesQuery = gql` period lastPeriodChange } - casesDataPoint(id: "0") { - value + counter(id: "0") { + cases } } `; diff --git a/web/src/hooks/queries/useCourtDetails.ts b/web/src/hooks/queries/useCourtDetails.ts new file mode 100644 index 000000000..225957102 --- /dev/null +++ b/web/src/hooks/queries/useCourtDetails.ts @@ -0,0 +1,32 @@ +import useSWR from "swr"; +import { gql } from "graphql-request"; +import { CourtDetailsQuery } from "src/graphql/generated"; +export type { CourtDetailsQuery }; + +const courtDetailsQuery = gql` + query CourtDetails($id: ID!) { + court(id: $id) { + policy + minStake + alpha + numberDisputes + numberStakedJurors + stake + paidETH + paidPNK + } + } +`; + +export const useCourtDetails = (id?: string) => { + const { data, error, isValidating } = useSWR( + id + ? { + query: courtDetailsQuery, + variables: { id }, + } + : null + ); + const result = data ? (data as CourtDetailsQuery) : undefined; + return { data: result, error, isValidating }; +}; diff --git a/web/src/hooks/queries/useCourtPolicy.ts b/web/src/hooks/queries/useCourtPolicy.ts index be92202d8..a7dd507b4 100644 --- a/web/src/hooks/queries/useCourtPolicy.ts +++ b/web/src/hooks/queries/useCourtPolicy.ts @@ -1,20 +1,7 @@ -import useSWRImmutable from "swr/immutable"; -import { PolicyRegistry } from "@kleros/kleros-v2-contracts/typechain-types/src/arbitration/PolicyRegistry"; -import { useConnectedContract } from "hooks/useConnectedContract"; +import { usePolicyRegistryEvent } from "queries/usePolicyRegistryEvent"; +import { useIPFSQuery } from "hooks/useIPFSQuery"; -export const useCourtPolicy = (courtID?: number) => { - const policyRegistry = useConnectedContract( - "PolicyRegistry" - ) as PolicyRegistry; - return useSWRImmutable( - () => (policyRegistry && courtID ? `PolicyRegistry${courtID}` : false), - async () => { - if (policyRegistry) { - const policyFilter = policyRegistry.filters.PolicyUpdate(courtID); - return policyRegistry - .queryFilter(policyFilter) - .then((events) => events[0]); - } else throw Error; - } - ); +export const useCourtPolicy = (courtID?: string | number) => { + const { data: courtPolicyPath } = usePolicyRegistryEvent(courtID); + return useIPFSQuery(courtPolicyPath?.args._policy); }; diff --git a/web/src/hooks/queries/useCourtTree.ts b/web/src/hooks/queries/useCourtTree.ts new file mode 100644 index 000000000..099d11cd1 --- /dev/null +++ b/web/src/hooks/queries/useCourtTree.ts @@ -0,0 +1,20 @@ +import useSWR from "swr"; +import { gql } from "graphql-request"; +import { CourtTreeQuery } from "src/graphql/generated"; +export type { CourtTreeQuery }; + +const courtTreeQuery = gql` + query CourtTree { + court(id: "1") { + id + } + } +`; + +export const useCourtTree = () => { + const { data, error, isValidating } = useSWR({ + query: courtTreeQuery, + }); + const result = data ? (data as CourtTreeQuery) : undefined; + return { data: result, error, isValidating }; +}; diff --git a/web/src/hooks/queries/useHomePageQuery.ts b/web/src/hooks/queries/useHomePageQuery.ts index 7f83658cc..9e932a3f0 100644 --- a/web/src/hooks/queries/useHomePageQuery.ts +++ b/web/src/hooks/queries/useHomePageQuery.ts @@ -8,25 +8,14 @@ const homePageQuery = gql` disputes(first: 3) { id } - pnkstakedDataPoints(where: { id_gt: $timeframe }) { - id - value - } - ethpaidDataPoints(where: { id_gt: $timeframe }) { - id - value - } - pnkredistributedDataPoints(where: { id_gt: $timeframe }) { - id - value - } - activeJurorsDataPoints(where: { id_gt: $timeframe }) { - id - value - } - casesDataPoints(where: { id_gt: $timeframe }) { - id - value + counters(where: { id_gt: $timeframe }) { + stakedPNK + redistributedPNK + paidETH + activeJurors + cases + casesVoting + casesRuled } } `; diff --git a/web/src/hooks/queries/usePNKAllowance.ts b/web/src/hooks/queries/usePNKAllowance.ts new file mode 100644 index 000000000..9ab74366f --- /dev/null +++ b/web/src/hooks/queries/usePNKAllowance.ts @@ -0,0 +1,18 @@ +import useSWR from "swr"; +import { PNK } from "@kleros/kleros-v2-contracts/typechain-types/src/arbitration/mock/PNK"; +import { useConnectedContract } from "hooks/useConnectedContract"; +import { CONTRACTS } from "utils/getContract"; + +export const usePNKAllowance = (user?: string | null) => { + const pnkContract = useConnectedContract("PNK") as PNK; + return useSWR( + () => (pnkContract && user ? `PNKBalance${user}` : false), + async () => { + if (pnkContract && user) { + return await pnkContract.allowance(user, CONTRACTS["PNK"].address); + } else { + return false; + } + } + ); +}; diff --git a/web/src/hooks/queries/usePNKBalance.ts b/web/src/hooks/queries/usePNKBalance.ts new file mode 100644 index 000000000..b51b0d0a7 --- /dev/null +++ b/web/src/hooks/queries/usePNKBalance.ts @@ -0,0 +1,18 @@ +import useSWR from "swr"; +import { PNK } from "@kleros/kleros-v2-contracts/typechain-types/src/arbitration/mock/PNK"; +import { useConnectedContract } from "hooks/useConnectedContract"; + +export const usePNKBalance = (user?: string | null) => { + const pnkContract = useConnectedContract("PNK") as PNK; + return useSWR( + () => (pnkContract && user ? `PNKBalance${user}` : false), + async () => { + console.log("balance query"); + if (pnkContract && user) { + return await pnkContract.balanceOf(user); + } else { + return false; + } + } + ); +}; diff --git a/web/src/hooks/queries/usePolicyRegistryEvent.ts b/web/src/hooks/queries/usePolicyRegistryEvent.ts new file mode 100644 index 000000000..77c9c3c71 --- /dev/null +++ b/web/src/hooks/queries/usePolicyRegistryEvent.ts @@ -0,0 +1,20 @@ +import useSWRImmutable from "swr/immutable"; +import { PolicyRegistry } from "@kleros/kleros-v2-contracts/typechain-types/src/arbitration/PolicyRegistry"; +import { useConnectedContract } from "hooks/useConnectedContract"; + +export const usePolicyRegistryEvent = (courtID?: string | number) => { + const policyRegistry = useConnectedContract( + "PolicyRegistry" + ) as PolicyRegistry; + return useSWRImmutable( + () => (policyRegistry && courtID ? `PolicyRegistry${courtID}` : false), + async () => { + if (policyRegistry) { + const policyFilter = policyRegistry.filters.PolicyUpdate(courtID); + return policyRegistry + .queryFilter(policyFilter) + .then((events) => events[0]); + } else throw Error; + } + ); +}; diff --git a/web/src/pages/Courts/CourtDetails/Description.tsx b/web/src/pages/Courts/CourtDetails/Description.tsx new file mode 100644 index 000000000..277922b1f --- /dev/null +++ b/web/src/pages/Courts/CourtDetails/Description.tsx @@ -0,0 +1,84 @@ +import React, { useEffect, useState } from "react"; +import styled from "styled-components"; +import ReactMarkdown from "react-markdown"; +import { + Routes, + Route, + Navigate, + useParams, + useNavigate, + useLocation, +} from "react-router-dom"; +import { Tabs } from "@kleros/ui-components-library"; +import { useCourtPolicy } from "queries/useCourtPolicy"; + +const TABS = [ + { + text: "Purpose", + value: 0, + path: "purpose", + }, + { + text: "Skills", + value: 1, + path: "skills", + }, + { + text: "Policy", + value: 2, + path: "policy", + }, +]; + +const Description: React.FC = () => { + const { id } = useParams(); + const { data: policy } = useCourtPolicy(id); + const navigate = useNavigate(); + const currentPathName = useLocation().pathname.split("/").at(-1); + const [currentTab, setCurrentTab] = useState( + TABS.findIndex(({ path }) => path === currentPathName) + ); + useEffect( + () => setCurrentTab(TABS.findIndex(({ path }) => path === currentPathName)), + [currentPathName] + ); + return ( + + { + setCurrentTab(n); + navigate(TABS[n].path); + }} + /> + + +

} /> + + } /> +
+
+ ); +}; + +const formatMarkdown = (markdown?: string) => + markdown ? {markdown} :

Loading...

; + +const Container = styled.div` + width: 100%; + padding: 0 12px; +`; + +const StyledTabs = styled(Tabs)` + width: 100%; + > * { + display: flex; + flex-wrap: wrap; + > svg { + margin-right: 0px !important; + } + } +`; + +export default Description; diff --git a/web/src/pages/Courts/CourtDetails/StakeModal.tsx b/web/src/pages/Courts/CourtDetails/StakeModal.tsx new file mode 100644 index 000000000..c5df217a6 --- /dev/null +++ b/web/src/pages/Courts/CourtDetails/StakeModal.tsx @@ -0,0 +1,104 @@ +import React, { useState } from "react"; +import styled from "styled-components"; +import { useParams } from "react-router-dom"; +import Modal from "react-modal"; +import { utils } from "ethers"; +import { Field, Button } from "@kleros/ui-components-library"; +import { KlerosCore } from "@kleros/kleros-v2-contracts/typechain-types/src/arbitration/KlerosCore"; +import { useWeb3 } from "hooks/useWeb3"; +import { useConnectedContract } from "hooks/useConnectedContract"; +import { usePNKBalance } from "queries/usePNKBalance"; +import { usePNKAllowance } from "queries/usePNKAllowance"; + +const StakeModal: React.FC<{ isOpen: boolean; close: () => void }> = ({ + isOpen, + close, +}) => { + const { id } = useParams(); + const klerosCore = useConnectedContract("KlerosCore") as KlerosCore; + const [isSending, setIsSending] = useState(false); + const [amount, setAmount] = useState(""); + const { account } = useWeb3(); + const { data: balance } = usePNKBalance(account); + console.log(balance); + const { data: allowance } = usePNKAllowance(account); + return ( + +

Submit New Evidence

+ { + const newValue = e.target.value; + console.log( + "newValue", + newValue, + newValue.match(/^\d+(\.\d*){0,1}$/) + ); + if (newValue.match(/^[\d]+([.]\d*)?$/)) { + setAmount(newValue); + } + }} + placeholder="Amount to stake" + /> + +