@@ -38,6 +40,7 @@ const RegistriesDisplay: React.FC
= ({
currentPage,
setCurrentPage,
registriesLoading,
+ showPagination,
}}
/>
)}
diff --git a/web/src/components/RegistryCard/RegistryInfo.tsx b/web/src/components/RegistryCard/RegistryInfo.tsx
index 33fc6c1..f9b7b21 100644
--- a/web/src/components/RegistryCard/RegistryInfo.tsx
+++ b/web/src/components/RegistryCard/RegistryInfo.tsx
@@ -27,7 +27,7 @@ const Container = styled.div<{ isListView: boolean }>`
display: grid;
grid-template-rows: repeat(3, min-content);
grid-template-columns: 21px max-content 1fr max-content;
- column-gap: ${responsiveSize(8, 12, 900)};
+ column-gap: ${responsiveSize(8, 24, 900)};
row-gap: 16px;
padding: 16px;
h3,
@@ -53,8 +53,8 @@ const Container = styled.div<{ isListView: boolean }>`
`;
const StyledLogo = styled.img<{ isListView: boolean }>`
- width: ${({ isListView }) => (isListView ? "48px" : "125px")};
- height: ${({ isListView }) => (isListView ? "48px" : "125px")};
+ width: ${({ isListView }) => (isListView ? "40px" : "125px")};
+ height: ${({ isListView }) => (isListView ? "40px" : "125px")};
object-fit: contain;
margin-bottom: ${({ isListView }) => (isListView ? "0px" : "8px")};
`;
@@ -93,8 +93,8 @@ const StyledButton = styled(Button)`
`;
const SkeletonLogo = styled(Skeleton)<{ isListView: boolean }>`
- width: ${({ isListView }) => (isListView ? "48px" : "125px")};
- height: ${({ isListView }) => (isListView ? "48px" : "125px")};
+ width: ${({ isListView }) => (isListView ? "40px" : "125px")};
+ height: ${({ isListView }) => (isListView ? "40px" : "125px")};
border-radius: ${({ isListView }) => (isListView ? "24px" : "62.5px")};
margin-bottom: ${({ isListView }) => (isListView ? "0px" : "8px")};
`;
diff --git a/web/src/components/RegistryCard/StatusBanner.tsx b/web/src/components/RegistryCard/StatusBanner.tsx
index 37cc3ba..7d5ccda 100644
--- a/web/src/components/RegistryCard/StatusBanner.tsx
+++ b/web/src/components/RegistryCard/StatusBanner.tsx
@@ -1,6 +1,7 @@
import React from "react";
import styled, { Theme } from "styled-components";
import { Status } from "consts/status";
+import { Status as SubgraphStatus } from "src/graphql/graphql";
const Container = styled.div<{ status: Status; isListView: boolean }>`
height: ${({ isListView }) => (isListView ? "min-content" : "45px")};
@@ -45,7 +46,8 @@ interface IStatusBanner {
export const getStatusColor = (status: Status, theme: Theme): [string, string] => {
switch (status) {
- case Status.Pending:
+ case Status.RegistrationPending:
+ case Status.ClearingPending:
return [theme.primaryBlue, theme.mediumBlue];
case Status.Disputed:
return [theme.secondaryPurple, theme.mediumPurple];
@@ -60,8 +62,10 @@ export const getStatusColor = (status: Status, theme: Theme): [string, string] =
export const getStatusLabel = (status: Status): string => {
switch (status) {
- case Status.Pending:
- return "Pending";
+ case Status.RegistrationPending:
+ return "Registration Pending";
+ case Status.ClearingPending:
+ return "Clearing Pending";
case Status.Disputed:
return "Disputed";
case Status.Included:
@@ -76,15 +80,14 @@ export const getStatusLabel = (status: Status): string => {
export const mapFromSubgraphStatus = (status: string, isDisputed: boolean) => {
if (isDisputed) return Status.Disputed;
switch (status) {
- case "absent":
+ case SubgraphStatus.Absent:
return Status.Removed;
- case "registered":
+ case SubgraphStatus.Registered:
return Status.Included;
- case "clearingRequested":
- case "registrationRequested":
- return Status.Pending;
+ case SubgraphStatus.RegistrationRequested:
+ return Status.RegistrationPending;
default:
- return Status.Pending;
+ return Status.ClearingPending;
}
};
const StatusBanner: React.FC = ({ status, isListView = false }) => (
diff --git a/web/src/components/RegistryInfo/AliasDisplay.tsx b/web/src/components/RegistryInfo/AliasDisplay.tsx
index ae81e29..bef153b 100644
--- a/web/src/components/RegistryInfo/AliasDisplay.tsx
+++ b/web/src/components/RegistryInfo/AliasDisplay.tsx
@@ -22,9 +22,10 @@ const TextContainer = styled.div`
interface IAlias {
address: string;
+ className?: string;
}
-const AliasDisplay: React.FC = ({ address }) => {
+const AliasDisplay: React.FC = ({ address, className }) => {
const { data: addressFromENS, isLoading } = useEnsAddress({
enabled: !isAddress(address),
name: address,
@@ -34,7 +35,7 @@ const AliasDisplay: React.FC = ({ address }) => {
const finalAddress = addressFromENS ?? address;
return (
-
+
{isLoading ? : }
{isLoading ? : }
diff --git a/web/src/components/StyledSkeleton.tsx b/web/src/components/StyledSkeleton.tsx
index f4888d5..8056236 100644
--- a/web/src/components/StyledSkeleton.tsx
+++ b/web/src/components/StyledSkeleton.tsx
@@ -24,6 +24,29 @@ const StyledSkeletonEvidenceCard = styled(Skeleton)`
width: 76vw;
`;
+const HistorySkeletonContainer = styled.div`
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+`;
+const HistoryStatusSkeleton = styled(Skeleton)`
+ height: 24px;
+ width: 160px;
+`;
+const HistoryDateSkeleton = styled(Skeleton)`
+ height: 18px;
+ width: 100px;
+`;
+
+export const HistorySkeletonCard = () => (
+
+
+
+
+
+
+);
+
export const SkeletonRegistryCard = () => (
diff --git a/web/src/consts/filters.ts b/web/src/consts/filters.ts
index d68c94e..fda45d5 100644
--- a/web/src/consts/filters.ts
+++ b/web/src/consts/filters.ts
@@ -1,7 +1,7 @@
import { Status } from "src/graphql/graphql";
export const List_filters = {
- Pending: { status_in: [Status.RegistrationRequested, Status.ClearingRequested] },
+ Pending: { status_in: [Status.RegistrationRequested, Status.ClearingRequested], disputed: false },
Disputed: { disputed: true },
Included: { status: Status.Registered },
Removed: { status: Status.Absent },
diff --git a/web/src/consts/index.ts b/web/src/consts/index.ts
index 998288a..5346b39 100644
--- a/web/src/consts/index.ts
+++ b/web/src/consts/index.ts
@@ -1,4 +1,3 @@
-import { Status } from "src/graphql/graphql";
import { version, gitCommitHash, gitCommitShortHash, gitBranch, gitTags, clean } from "../generatedGitInfo.json";
export const ONE_BASIS_POINT = 10000n;
@@ -21,99 +20,4 @@ export const ETH_SIGNATURE_REGEX = /^0x[a-fA-F0-9]{130}$/;
export const DEFAULT_LIST_LOGO = "ipfs://QmWfxEmfEWwM6LDgER2Qp2XZpK1MbDtNp7uGqCS4UPNtgJ/symbol-CURATE.png";
export const CURATION_POLICY = `${IPFS_GATEWAY}/ipfs/QmWciZMi8mBJg34FapRHK4Yh7a6UqmxrpcKQ3KRNMXzjfx`;
-// export const items = [
-// {
-// id: 1,
-// title: "ENS Resolver",
-// address: "0x922911F4f80a569a4425fa083456239838F7F003",
-// website: "metamask.io",
-// status: Status.Removed,
-// },
-// {
-// id: 2,
-// title: "ENS Resolver",
-// address: "0x922911F4f80a569a4425fa083456239838F7F003",
-// website: "metamask.io",
-// status: Status.Removed,
-// },
-// {
-// id: 3,
-// title: "ENS Resolver",
-// address: "0x922911F4f80a569a4425fa083456239838F7F003",
-// website: "metamask.io",
-// status: Status.Removed,
-// },
-// {
-// id: 4,
-// title: "ENS Resolver",
-// address: "0x922911F4f80a569a4425fa083456239838F7F003",
-// website: "metamask.io",
-// status: Status.Removed,
-// },
-// {
-// id: 5,
-// title: "ENS Resolver",
-// address: "0x922911F4f80a569a4425fa083456239838F7F003",
-// website: "metamask.io",
-// status: Status.Removed,
-// },
-// ];
-export const items = [
- {
- id: "1",
- status: Status.Registered,
- registerer: { id: "0x922911F4f80a569a4425fa083456239838F7F003" },
- disputed: false,
- props: [
- {
- label: "Address",
- description: "The token address.",
- value: "0x93ED3FBe21207Ec2E8f2d3c3de6e058Cb73Bc04d",
- isIdentifier: true,
- type: "address",
- },
- {
- label: "Chain ID",
- description: "The ID of the chain the token contract was deployed",
- value: "1",
- isIdentifier: false,
- type: "number",
- },
- {
- label: "Decimals",
- description: "The number of decimal places.",
- value: "18",
- isIdentifier: false,
- type: "number",
- },
- {
- label: "Logo",
- description: "The token's logo.",
- value: "/ipfs/QmQnCc3d5bjLkaqkrXuzyJ7kw3U9nu26neMFha1FK8FapL/dai.png",
- isIdentifier: false,
- type: "image",
- },
- {
- label: "Name",
- description: "The token name.",
- value: "Ethereum",
- isIdentifier: true,
- type: "text",
- },
- {
- label: "Ticker",
- description: "The token ticker.",
- value: "ETH",
- isIdentifier: true,
- type: "text",
- },
- {
- label: "Policy",
- description: "The token policy.",
- value: "/ipfs/QmU4X2mjdi7QtcV8TnDKzvR782oDZbKkFPrRLPQnHjy8SW/PoH Origin Constitution (final draft).pdf",
- isIdentifier: true,
- type: "file",
- },
- ],
- },
-];
+export const COURT_SITE = "https://dev--kleros-v2.netlify.app/#/cases";
diff --git a/web/src/consts/status.ts b/web/src/consts/status.ts
index cf934ce..10fa082 100644
--- a/web/src/consts/status.ts
+++ b/web/src/consts/status.ts
@@ -1,5 +1,6 @@
export enum Status {
- Pending,
+ RegistrationPending,
+ ClearingPending,
Disputed,
Included,
Removed,
diff --git a/web/src/context/SubmitItemContext.tsx b/web/src/context/SubmitItemContext.tsx
index ed5c9ad..a1b1858 100644
--- a/web/src/context/SubmitItemContext.tsx
+++ b/web/src/context/SubmitItemContext.tsx
@@ -1,5 +1,6 @@
-import React, { createContext, useContext, useMemo } from "react";
+import React, { createContext, useContext, useEffect, useMemo } from "react";
import { useLocalStorage } from "hooks/useLocalStorage";
+import { useLocation } from "react-router-dom";
type Fields = {
columns: {
@@ -34,6 +35,8 @@ const SubmitItemContext = createContext(initialSubmitItemCon
export const useSubmitItemContext = () => useContext(SubmitItemContext);
export const SubmitItemProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
+ const location = useLocation();
+
const [fields, setFields] = useLocalStorage("fields", initialSubmitItemContext.fields);
const [submissionDeposit, setSubmissionDeposit] = useLocalStorage("submissionDeposit", null);
const [isPolicyRead, setIsPolicyRead] = useLocalStorage(
@@ -42,11 +45,18 @@ export const SubmitItemProvider: React.FC<{ children: React.ReactNode }> = ({ ch
);
const resetItemData = () => {
- setFields({ ...initialSubmitItemContext.fields });
+ setFields({ columns: [] });
setIsPolicyRead(initialSubmitItemContext.isPolicyRead);
setSubmissionDeposit(null);
};
+ useEffect(() => {
+ // Cleanup function to clear local storage when user leaves the route
+ if (location.pathname.includes("/submit-item")) return;
+
+ resetItemData();
+ }, [location.pathname]);
+
const contextValues = useMemo(
() => ({
fields,
diff --git a/web/src/context/SubmitListContext.tsx b/web/src/context/SubmitListContext.tsx
index 660678b..4c8898f 100644
--- a/web/src/context/SubmitListContext.tsx
+++ b/web/src/context/SubmitListContext.tsx
@@ -1,7 +1,8 @@
-import React, { createContext, useState, useContext, useMemo } from "react";
+import React, { createContext, useState, useContext, useMemo, useEffect } from "react";
import { useLocalStorage } from "hooks/useLocalStorage";
import { EVIDENCE_MODULE, KLEROS_ARBITRATOR } from "consts/arbitration";
+import { useLocation } from "react-router-dom";
export interface IList {
governor: string;
@@ -121,12 +122,20 @@ export const SubmitListProvider: React.FC<{ children: React.ReactNode }> = ({ ch
const [isPolicyUploading, setIsPolicyUploading] = useState(false);
const [isLogoUploading, setIsLogoUploading] = useState(false);
const [progress, setProgress] = useState(ListProgress.Start);
+ const location = useLocation();
const resetListData = () => {
setListData(initialListData);
setListMetadata(initialListMetadata);
};
+ useEffect(() => {
+ // Cleanup function to clear local storage when user leaves the route
+ if (location.pathname.includes("/submit-list")) return;
+
+ resetListData();
+ }, [location.pathname]);
+
const contextValues = useMemo(
() => ({
listData,
diff --git a/web/src/hooks/queries/useItemDetailsQuery.ts b/web/src/hooks/queries/useItemDetailsQuery.ts
index f741ec4..87ec55a 100644
--- a/web/src/hooks/queries/useItemDetailsQuery.ts
+++ b/web/src/hooks/queries/useItemDetailsQuery.ts
@@ -10,6 +10,7 @@ const itemDetailsQuery = graphql(`
id
itemID
status
+ data
disputed
key0
key1
diff --git a/web/src/hooks/queries/useItemsQuery.ts b/web/src/hooks/queries/useItemsQuery.ts
index 5761472..0b3a35a 100644
--- a/web/src/hooks/queries/useItemsQuery.ts
+++ b/web/src/hooks/queries/useItemsQuery.ts
@@ -80,7 +80,7 @@ export const useItemsQuery = (
: itemsQueryWhere;
return useQuery<{ items: ItemDetailsFragment[] }>({
- queryKey: [`useItemsQuery`, skip, where, sortOrder, first, keywords],
+ queryKey: ["refetchOnBlock", `useItemsQuery`, skip, where, sortOrder, first, keywords],
queryFn: async () => {
const result = await graphqlBatcher.fetch({
id: crypto.randomUUID(),
diff --git a/web/src/hooks/queries/useRegistriesByIdsQuery.ts b/web/src/hooks/queries/useRegistriesByIdsQuery.ts
index b950743..164daa4 100644
--- a/web/src/hooks/queries/useRegistriesByIdsQuery.ts
+++ b/web/src/hooks/queries/useRegistriesByIdsQuery.ts
@@ -1,6 +1,7 @@
import { graphql } from "src/graphql";
import { useQuery } from "@tanstack/react-query";
import { useGraphqlBatcher } from "context/GraphqlBatcher";
+import { GetRegistriesByIdsQuery } from "src/graphql/graphql";
export const registriesByIdsQuery = graphql(`
query GetRegistriesByIds($ids: [ID!]!) {
@@ -19,7 +20,7 @@ export const registriesByIdsQuery = graphql(`
export const useRegistriesByIdsQuery = (ids) => {
const { graphqlBatcher } = useGraphqlBatcher();
- return useQuery({
+ return useQuery({
queryKey: ["GetRegistriesByIds", ids.join(",")],
queryFn: async () =>
await graphqlBatcher.fetch({
diff --git a/web/src/hooks/queries/useRegistryDetailsQuery.ts b/web/src/hooks/queries/useRegistryDetailsQuery.ts
index a72e607..99a64c6 100644
--- a/web/src/hooks/queries/useRegistryDetailsQuery.ts
+++ b/web/src/hooks/queries/useRegistryDetailsQuery.ts
@@ -9,6 +9,7 @@ export const itemFragment = graphql(`
fragment RegistryItemDetails on Item {
id
status
+ disputed
props {
label
description
diff --git a/web/src/hooks/queries/useRequestsQuery.ts b/web/src/hooks/queries/useRequestsQuery.ts
new file mode 100644
index 0000000..453f2b0
--- /dev/null
+++ b/web/src/hooks/queries/useRequestsQuery.ts
@@ -0,0 +1,57 @@
+import { graphql } from "src/graphql";
+import { useQuery } from "@tanstack/react-query";
+import { useGraphqlBatcher } from "context/GraphqlBatcher";
+import { RequestDetailsFragment } from "src/graphql/graphql";
+
+export const requestDetailsFragment = graphql(`
+ fragment RequestDetails on Request {
+ id
+ disputed
+ disputeID
+ submissionTime
+ resolved
+ requester {
+ id
+ }
+ challenger {
+ id
+ }
+ arbitrator
+ arbitratorExtraData
+ deposit
+ disputeOutcome
+ requestType
+ resolutionTime
+ finalRuling
+ creationTx
+ resolutionTx
+ }
+`);
+
+const requestQuery = graphql(`
+ query ItemRequests($id: ID!) {
+ item(id: $id) {
+ requests {
+ ...RequestDetails
+ }
+ }
+ }
+`);
+
+export const useItemRequests = (id?: string | number) => {
+ const isEnabled = id !== undefined;
+ const { graphqlBatcher } = useGraphqlBatcher();
+
+ return useQuery<{ requests: RequestDetailsFragment[] }>({
+ queryKey: ["refetchOnBlock", `requestsQuery${id}`],
+ enabled: isEnabled,
+ queryFn: async () =>
+ (
+ await graphqlBatcher.fetch({
+ id: crypto.randomUUID(),
+ document: requestQuery,
+ variables: { id },
+ })
+ )?.item,
+ });
+};
diff --git a/web/src/pages/AllLists/ItemDisplay/index.tsx b/web/src/pages/AllLists/ItemDisplay/index.tsx
index fa0eb34..34a8290 100644
--- a/web/src/pages/AllLists/ItemDisplay/index.tsx
+++ b/web/src/pages/AllLists/ItemDisplay/index.tsx
@@ -1,51 +1,30 @@
import React from "react";
-import { useTheme } from "styled-components";
import { useParams } from "react-router-dom";
-import ClosedIcon from "svgs/icons/check-circle-outline.svg";
import History from "components/HistoryDisplay";
import { useItemDetailsQuery } from "queries/useItemDetailsQuery";
import { useRegistryDetailsQuery } from "queries/useRegistryDetailsQuery";
-import { mapFromSubgraphStatus } from "components/RegistryCard/StatusBanner";
import ItemInformationCard from "components/ItemInformationCard";
const ItemDisplay: React.FC = () => {
const { itemId } = useParams();
const [, listAddress] = itemId?.split("@");
- const { data: itemDetails } = useItemDetailsQuery(itemId);
- const { data: registryDetails } = useRegistryDetailsQuery(listAddress);
- const theme = useTheme();
- const historyItems = [
- {
- title: "Item Submitted",
- variant: theme.primaryBlue,
- subtitle: "April 06, 2022",
- rightSided: true,
- },
- {
- title: "Item Challenged",
- party: "- Case #1369 by Alice.eth",
- variant: theme.secondaryPurple,
- subtitle: "April 07, 2022",
- rightSided: true,
- },
- {
- title: "Item Submitted",
- subtitle: "April 06, 2022",
- rightSided: true,
- Icon: ClosedIcon,
- },
- ];
+ const { data: itemDetails, refetch: refetchItemDetails } = useItemDetailsQuery(itemId);
+ const { data: registryDetails, refetch: refetchRegistryDetails } = useRegistryDetailsQuery(listAddress);
+ const refetch = () => {
+ refetchItemDetails();
+ refetchRegistryDetails();
+ };
return (
-
+
);
};
diff --git a/web/src/pages/AllLists/RegistriesFetcher.tsx b/web/src/pages/AllLists/RegistriesFetcher.tsx
index a9643fe..d4391c6 100644
--- a/web/src/pages/AllLists/RegistriesFetcher.tsx
+++ b/web/src/pages/AllLists/RegistriesFetcher.tsx
@@ -6,14 +6,13 @@ import RegistriesDisplay from "components/RegistriesDisplay";
import { BREAKPOINT_LANDSCAPE } from "styles/landscapeStyle";
import { DEFAULT_CHAIN } from "consts/chains";
import { listOfListsAddresses } from "utils/listOfListsAddresses";
-// import { isUndefined } from "utils/index";
-// import { OrderDirection } from "src/graphql/graphql";
import { useItemsQuery } from "queries/useItemsQuery";
import { useRegistriesByIdsQuery } from "queries/useRegistriesByIdsQuery";
import { isUndefined } from "utils/index";
import { OrderDirection } from "src/graphql/graphql";
import { useRegistryDetailsQuery } from "hooks/queries/useRegistryDetailsQuery";
import { List_filters } from "consts/filters";
+import { sortRegistriesByIds } from "utils/sortRegistriesByIds";
const RegistriesFetcher: React.FC = () => {
const { page, order, filter } = useParams();
@@ -46,9 +45,9 @@ const RegistriesFetcher: React.FC = () => {
const registryIds = useMemo(
() =>
itemsData
- ? itemsData?.items
+ ? (itemsData?.items
.map((item) => item?.props[0]?.value?.toLowerCase() ?? undefined)
- .filter((id) => !isUndefined(id))
+ .filter((id) => !isUndefined(id)) as string[])
: [],
[itemsData]
);
@@ -56,17 +55,23 @@ const RegistriesFetcher: React.FC = () => {
// get registries by id
const { data: registriesData, isLoading: isRegistriesDataLoading } = useRegistriesByIdsQuery(registryIds);
+ const sortedRegstries = useMemo(
+ () => (registriesData?.registries ? sortRegistriesByIds(registryIds, registriesData?.registries) : []),
+ [registriesData]
+ );
+
const combinedListsData = useMemo(() => {
- return registriesData?.registries.map((registry) => {
+ return sortedRegstries.map((registry) => {
const registryAsItem = itemsData?.items.find((item) => item?.props[0]?.value?.toLowerCase() === registry.id);
return {
...registry,
totalItems: registry.items.length,
status: registryAsItem?.status,
+ disputed: registryAsItem?.disputed,
itemId: registryAsItem?.id,
};
});
- }, [registriesData, itemsData]);
+ }, [sortedRegstries, itemsData]);
const totalRegistries = useMemo(() => {
if (!mainCurate || !mainCurate.registry) return 0;
@@ -98,6 +103,7 @@ const RegistriesFetcher: React.FC = () => {
setCurrentPage={(newPage: number) => navigate(`${location}/${newPage}/${order}/${filter}`)}
totalPages={totalPages}
registriesPerPage={registriesPerPage}
+ showPagination={!keywords}
/>
);
};
diff --git a/web/src/pages/AllLists/RegistryDetails/Tabs.tsx b/web/src/pages/AllLists/RegistryDetails/Tabs.tsx
index 1408ab4..1020f4a 100644
--- a/web/src/pages/AllLists/RegistryDetails/Tabs.tsx
+++ b/web/src/pages/AllLists/RegistryDetails/Tabs.tsx
@@ -22,13 +22,15 @@ const TABS = [
text: "List",
value: 0,
Icon: PaperIcon,
- path: "list",
+ path: "list/1/desc/all",
+ identifier: "list",
},
{
text: "History",
value: 1,
Icon: HistoryIcon,
path: "history",
+ identifier: "history",
},
];
@@ -38,7 +40,7 @@ const Tabs: React.FC = () => {
const location = useLocation();
const currentPathName = location.pathname.split("/").at(3);
- const findTabIndex = (pathName) => TABS.findIndex(({ path }) => pathName.startsWith(path));
+ const findTabIndex = (pathName) => TABS.findIndex(({ identifier }) => pathName.startsWith(identifier));
const [currentTab, setCurrentTab] = useState(findTabIndex(currentPathName));
useEffect(() => {
diff --git a/web/src/pages/AllLists/RegistryDetails/index.tsx b/web/src/pages/AllLists/RegistryDetails/index.tsx
index ed953b0..ae753e1 100644
--- a/web/src/pages/AllLists/RegistryDetails/index.tsx
+++ b/web/src/pages/AllLists/RegistryDetails/index.tsx
@@ -1,27 +1,41 @@
import React, { useEffect } from "react";
-import { useTheme } from "styled-components";
import { Navigate, Route, Routes, useParams } from "react-router-dom";
import InformationCard from "components/InformationCard";
import Tabs from "./Tabs";
import List from "./List";
import History from "components/HistoryDisplay";
import { useRegistryDetailsContext } from "context/RegistryDetailsContext";
-import ClosedIcon from "assets/svgs/icons/check-circle-outline.svg";
import { useRegistryDetailsQuery } from "queries/useRegistryDetailsQuery";
import { useItemDetailsQuery } from "queries/useItemDetailsQuery";
import { mapFromSubgraphStatus } from "components/RegistryCard/StatusBanner";
const RegistryDetails: React.FC = () => {
- const theme = useTheme();
const { id } = useParams();
const [listAddress, itemId] = id?.split("-");
+ const [, registryAddress] = itemId.split("@");
- const { data: itemDetails } = useItemDetailsQuery(itemId?.toLowerCase());
- const { data: registryDetails } = useRegistryDetailsQuery(listAddress?.toLowerCase());
+ const { data: itemDetails, refetch: refetchItemDetails } = useItemDetailsQuery(itemId?.toLowerCase());
+ const { data: registryDetails, refetch: refetchRegistryDetails } = useRegistryDetailsQuery(
+ listAddress?.toLowerCase()
+ );
+
+ const refetch = () => {
+ refetchItemDetails();
+ refetchRegistryDetails();
+ };
- const { title, status, logoURI, policyURI, description, registerer, disputed, setRegistryDetails } =
- useRegistryDetailsContext();
+ const {
+ title,
+ status,
+ logoURI,
+ policyURI,
+ description,
+ registerer,
+ disputed,
+ setRegistryDetails,
+ itemID: registryAsitemId,
+ } = useRegistryDetailsContext();
useEffect(() => {
if (itemDetails && registryDetails) {
@@ -33,40 +47,27 @@ const RegistryDetails: React.FC = () => {
}
}, [itemDetails, registryDetails, setRegistryDetails]);
- const historyItems = [
- {
- title: "List Submitted",
- variant: theme.primaryBlue,
- subtitle: "April 06, 2022",
- rightSided: true,
- },
- {
- title: "List Challenged",
- party: "- Case #1369 by Alice.eth",
- variant: theme.secondaryPurple,
- subtitle: "April 07, 2022",
- rightSided: true,
- },
- {
- title: "List Submitted",
- subtitle: "April 06, 2022",
- rightSided: true,
- Icon: ClosedIcon,
- },
- ];
-
return (
} />
- } />
+ } />
} />
diff --git a/web/src/pages/AllLists/StyledBreadcrumb.tsx b/web/src/pages/AllLists/StyledBreadcrumb.tsx
index b79c190..0108ad5 100644
--- a/web/src/pages/AllLists/StyledBreadcrumb.tsx
+++ b/web/src/pages/AllLists/StyledBreadcrumb.tsx
@@ -4,6 +4,7 @@ import { Breadcrumb as BreadcrumbBase } from "@kleros/ui-components-library";
import { useLocation, useNavigate } from "react-router-dom";
import HomeIcon from "svgs/icons/home.svg";
import { useRegistryDetailsQuery } from "hooks/queries/useRegistryDetailsQuery";
+import { useLocalStorage } from "hooks/useLocalStorage";
const StyledBreadcrumb = styled(BreadcrumbBase)`
margin-bottom: 32px;
@@ -20,6 +21,7 @@ const StyledHomeIcon = styled(HomeIcon)`
const Breadcrumb: React.FC = () => {
const location = useLocation();
const navigate = useNavigate();
+ const [registryItemID, setRegistryItemId] = useLocalStorage("registryAsItemID", "");
const [page, listAddress] = useMemo(() => {
const id = location.pathname.split("/")?.[2];
@@ -32,7 +34,8 @@ const Breadcrumb: React.FC = () => {
return ["item", address];
}
default: {
- const [address] = id.split("-");
+ const [address, itemId] = id.split("-");
+ setRegistryItemId(itemId);
return ["list", address];
}
}
@@ -58,7 +61,7 @@ const Breadcrumb: React.FC = () => {
baseItems.push(
{
text: registryDetails?.registry?.title ?? "List",
- value: `/lists/${listAddress}-${location.pathname.split("/")?.[3]}/list/1/desc/all`,
+ value: `/lists/${listAddress}-${registryItemID}/list/1/desc/all`,
},
{
text: "Item",
diff --git a/web/src/pages/Home/Header.tsx b/web/src/pages/Home/Header.tsx
index f7d96d1..689232b 100644
--- a/web/src/pages/Home/Header.tsx
+++ b/web/src/pages/Home/Header.tsx
@@ -1,4 +1,4 @@
-import React from "react";
+import React, { useEffect, useState } from "react";
import styled from "styled-components";
import { responsiveSize } from "styles/responsiveSize";
@@ -19,10 +19,21 @@ const StyledSpan = styled.span`
`;
const Header: React.FC = () => {
+ const [currentWordIndex, setCurrentWordIndex] = useState(0);
+ const words = ["Lists", "Knowledge"];
+
+ useEffect(() => {
+ const intervalId = setInterval(() => {
+ setCurrentWordIndex((prevIndex) => (prevIndex === 0 ? 1 : 0));
+ }, 3000);
+
+ return () => clearInterval(intervalId);
+ }, []);
+
return (
- Community Curated Lists
+ Community Curated {words[currentWordIndex]}
);
diff --git a/web/src/pages/Home/Highlights/index.tsx b/web/src/pages/Home/Highlights/index.tsx
index 1529450..0eeadae 100644
--- a/web/src/pages/Home/Highlights/index.tsx
+++ b/web/src/pages/Home/Highlights/index.tsx
@@ -14,6 +14,7 @@ import { useNavigateAndScrollTop } from "hooks/useNavigateAndScrollTop";
import { useItemsQuery } from "queries/useItemsQuery";
import { useRegistriesByIdsQuery } from "queries/useRegistriesByIdsQuery";
import { mapFromSubgraphStatus } from "components/RegistryCard/StatusBanner";
+import { sortRegistriesByIds } from "utils/sortRegistriesByIds";
const Container = styled.div`
width: 100%;
@@ -51,30 +52,35 @@ const HighlightedLists = () => {
registry: listOfListsAddresses[DEFAULT_CHAIN],
});
- // TODO: Json.parse can throw error
const registryIds = useMemo(
() =>
itemsData
- ? itemsData?.items
+ ? (itemsData?.items
.map((item) => item?.props[0]?.value?.toLowerCase() ?? undefined)
- .filter((id) => !isUndefined(id))
+ .filter((id) => !isUndefined(id)) as string[])
: [],
[itemsData]
);
const { data: registriesData, isLoading: isRegistriesDataLoading } = useRegistriesByIdsQuery(registryIds);
+ const sortedRegstries = useMemo(
+ () => (registriesData?.registries ? sortRegistriesByIds(registryIds, registriesData?.registries) : []),
+ [registriesData]
+ );
+
const combinedListsData = useMemo(() => {
- return registriesData?.registries.map((registry) => {
+ return sortedRegstries.map((registry) => {
const registryAsItem = itemsData?.items.find((item) => item?.props[0]?.value?.toLowerCase() === registry.id);
return {
...registry,
totalItems: registry.items.length,
status: registryAsItem?.status,
+ disputed: registryAsItem?.disputed,
itemId: registryAsItem?.id,
};
});
- }, [registriesData, itemsData]);
+ }, [sortedRegstries, itemsData]);
const registriesLoading = isUndefined(combinedListsData) || isItemsDataLoading || isRegistriesDataLoading;
diff --git a/web/src/pages/SubmitItem/Policy/ReadPolicy.tsx b/web/src/pages/SubmitItem/Policy/ReadPolicy.tsx
index 9f738b0..aa7cdb1 100644
--- a/web/src/pages/SubmitItem/Policy/ReadPolicy.tsx
+++ b/web/src/pages/SubmitItem/Policy/ReadPolicy.tsx
@@ -1,5 +1,7 @@
import React from "react";
import styled from "styled-components";
+import { useRegistryDetailsContext } from "context/RegistryDetailsContext";
+import { getIpfsUrl } from "utils/getIpfsUrl";
const StyledA = styled.a`
align-self: center;
@@ -10,11 +12,9 @@ const StyledA = styled.a`
interface IReadPolicy {}
const ReadPolicy: React.FC = () => {
+ const { policyURI } = useRegistryDetailsContext();
return (
-
+
→ Read the policy here ←
);
diff --git a/web/src/pages/SubmitList/index.tsx b/web/src/pages/SubmitList/index.tsx
index c763231..217bd6a 100644
--- a/web/src/pages/SubmitList/index.tsx
+++ b/web/src/pages/SubmitList/index.tsx
@@ -17,7 +17,6 @@ import ItemPreview from "./ItemParameters/ItemPreview";
import CustomName from "./ItemParameters/CustomName";
import AdvancedParameters from "./AdvancedParameters";
import DeployList from "./DeployList";
-import { SubmitListProvider } from "context/SubmitListContext";
const Container = styled.div`
display: flex;
@@ -69,7 +68,7 @@ const SubmitList: React.FC = () => {
location.pathname.includes("/deploy");
return (
-
+ <>
{isConnected && !isTimelineHidden ? Create a List : null}
@@ -98,7 +97,7 @@ const SubmitList: React.FC = () => {
)}
-
+ >
);
};
diff --git a/web/src/utils/date.ts b/web/src/utils/date.ts
index c0d586a..5d13a77 100644
--- a/web/src/utils/date.ts
+++ b/web/src/utils/date.ts
@@ -19,3 +19,14 @@ export function getOneYearAgoTimestamp(): number {
const currentTime = new Date().getTime() / 1000;
return currentTime - 31536000; // One year in seconds
}
+
+/**
+ *
+ * @param unixTimestamp
+ * @returns formatted date in MM(long)/DD/Year format
+ */
+export function formatDate(unixTimestamp: number): string {
+ const date = new Date(unixTimestamp * 1000);
+ const options: Intl.DateTimeFormatOptions = { month: "long", day: "2-digit", year: "numeric" };
+ return date.toLocaleDateString("en-US", options);
+}
diff --git a/web/src/utils/sortRegistriesByIds.ts b/web/src/utils/sortRegistriesByIds.ts
new file mode 100644
index 0000000..97fe1b1
--- /dev/null
+++ b/web/src/utils/sortRegistriesByIds.ts
@@ -0,0 +1,17 @@
+import { GetRegistriesByIdsQuery } from "src/graphql/graphql";
+
+/**
+ *
+ * @param registryIds Array containing registry ids
+ * @param registries Array containing registry objects to be sorted
+ * @returns An array of Registries matching the order of registryIds
+ */
+export const sortRegistriesByIds = (registryIds: string[], registries: GetRegistriesByIdsQuery["registries"]) => {
+ const idToIndexMap = {};
+ registryIds.forEach((id, index) => {
+ idToIndexMap[id] = index;
+ });
+
+ registries.sort((a, b) => idToIndexMap[a.id] - idToIndexMap[b.id]);
+ return registries;
+};
diff --git a/web/src/utils/submitListUtils.ts b/web/src/utils/submitListUtils.ts
index 622dfe4..62ee481 100644
--- a/web/src/utils/submitListUtils.ts
+++ b/web/src/utils/submitListUtils.ts
@@ -121,14 +121,14 @@ const constructRemovalTemplate = (listMetadata: IListMetadata) => {
? `an ${listMetadata.itemName.toLowerCase()}`
: `a ${listMetadata.itemName.toLowerCase()}`
: "an item"
- } to ${listMetadata.title}`,
+ } from ${listMetadata.title}`,
description: `Someone requested to remove ${
listMetadata.itemName
? isVowel(listMetadata.itemName[0])
? `an ${listMetadata.itemName.toLowerCase()}`
: `a ${listMetadata.itemName.toLowerCase()}`
: "an item"
- } to ${listMetadata.title}`,
+ } from ${listMetadata.title}`,
question: `Does the ${
(listMetadata.itemName && listMetadata.itemName.toLowerCase()) || "item"
} comply with the required criteria?`,