Skip to content

Commit

Permalink
Merge pull request #1324 from Polkadex-Substrate/internal
Browse files Browse the repository at this point in the history
  • Loading branch information
nuel77 committed Jul 4, 2024
2 parents f3e702b + fe260dc commit ecced18
Show file tree
Hide file tree
Showing 36 changed files with 2,324 additions and 96 deletions.
4 changes: 2 additions & 2 deletions apps/hestia/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@
"@orderbook/tsconfig": "*",
"@polkadex/blockchain-api": "^1.1.61",
"@polkadex/local-wallets": "^2.3.0",
"@polkadex/numericals": "^0.3.0",
"@polkadex/numericals": "^0.4.0",
"@polkadex/polkadex-api": "^3.6.2",
"@polkadex/subscan": "^1.1.61",
"@polkadex/thea": "^5.6.0",
"@polkadex/thea": "^6.1.1",
"@polkadex/ux": "^6.26.0",
"@polkadex/react-providers": "^2.2.1",
"@polkadex/types": "^1.2.2",
Expand Down
14 changes: 14 additions & 0 deletions apps/hestia/src/app/direct/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"use client";

import dynamic from "next/dynamic";

const Template = dynamic(
() => import("@/components/direct/template").then((mod) => mod.Template),
{
ssr: false,
}
);

export default function Page() {
return <Template />;
}
110 changes: 110 additions & 0 deletions apps/hestia/src/components/direct/History/columns.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
"use client";

import { createColumnHelper } from "@tanstack/react-table";
import { Typography } from "@polkadex/ux";
import { RiArrowRightLine } from "@remixicon/react";
import { GENESIS } from "@orderbook/core/index";

import { NetworkCard } from "./networkCard";
import { TokenInfo } from "./tokenInfo";
import { LinkCard } from "./linkCard";

import { formatedDate } from "@/helpers";
import { Transaction } from "@/hooks";

const columnHelper = createColumnHelper<Transaction>();

export const columns = [
columnHelper.accessor((row) => row, {
id: "token",
cell: (e) => {
const { asset, amount, status } = e.getValue();
const value = amount.toFormat();
const ready = ["CLAIMED", "APPROVED", "READY"].includes(status);

return <TokenInfo ticker={asset?.ticker} ready={ready} amount={value} />;
},
header: () => (
<Typography.Text size="xs" appearance="primary">
Token/Amount
</Typography.Text>
),
footer: (e) => e.column.id,
filterFn: (row, id, value: string[]) => {
const ticker = row.original.asset?.ticker?.toLowerCase() ?? "";
return value?.some((val) => val.toLowerCase().includes(ticker));
},

sortingFn: (rowA, rowB) => {
const numA = rowA.original.amount;
const numB = rowB.original.amount;
return numA > numB ? 1 : numA < numB ? -1 : 0;
},
}),
columnHelper.accessor((row) => row, {
id: "source",
cell: (e) => {
const { from, to } = e.getValue();

const isFromPolkadotNetwork = from?.genesis?.includes(GENESIS[0]);
const isToPolkadotNetwork = to?.genesis?.includes(GENESIS[0]);

return (
<div className="flex items-center gap-3">
<NetworkCard
name={from?.name}
isPolkadotEcosystem={isFromPolkadotNetwork}
/>
<div className="flex items-center justify-center w-5 h-5 p-0.5 bg-level-1 border border-primary">
<RiArrowRightLine className="w-full h-full text-primary" />
</div>
<NetworkCard
name={to?.name}
isPolkadotEcosystem={isToPolkadotNetwork}
/>
</div>
);
},
header: () => (
<Typography.Text size="xs" appearance="primary">
Source/Destination
</Typography.Text>
),
footer: (e) => e.column.id,
filterFn: (row, id, value: string[]) =>
value?.some((val) =>
val.toLowerCase().includes(row.original.from?.name.toLowerCase() ?? "")
),
}),
columnHelper.accessor((row) => row.hash, {
id: "hash",
cell: (e) => {
const data = e.getValue();

return <LinkCard value={data} />;
},
header: () => (
<Typography.Text size="xs" appearance="primary">
Hash
</Typography.Text>
),
footer: (e) => e.column.id,
}),
columnHelper.accessor((row) => row.timestamp, {
id: "date",
cell: (e) => {
const date = formatedDate(new Date(e.getValue()), false);
return (
<Typography.Text size="sm" className=" whitespace-nowrap">
{date}
</Typography.Text>
);
},
header: () => (
<Typography.Text size="xs" appearance="primary">
Date
</Typography.Text>
),
footer: (e) => e.column.id,
}),
];
76 changes: 76 additions & 0 deletions apps/hestia/src/components/direct/History/export.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { useSettingsProvider } from "@orderbook/core/providers/public/settings";
import { Button, Tooltip, Typography } from "@polkadex/ux";
import { useState } from "react";
import CSVLink from "react-csv-downloader";
import { RiDownload2Line } from "@remixicon/react";

import { formatedDate } from "@/helpers";

const csvColumns = [
"sourceChain",
"destinationChain",
"assetTicker",
"status",
"amount",
"from",
"hash",
"date",
].map((c) => ({
id: c,
}));

export const Export = ({ data, address }: { data: any[]; address: string }) => {
const exportedFileName = `Bridge_${new Date().getTime()}_Polkadex_Thea`;
const [loading, setLoading] = useState(false);
const { onHandleAlert, onHandleError } = useSettingsProvider();

const prepareData = async () => {
try {
onHandleAlert("Bridge history exported successfully...");
return data?.map((item) => {
const date = formatedDate(new Date(item.timestamp), false);

return {
sourceChain: item.from?.name ?? "",
destinationChain: item.to?.name ?? "",
assetTicker: item.asset?.ticker ?? "",
status: item.status,
amount: item.amount.toString(),
from: address,
hash: item.hash,
date,
};
});
} catch (error) {
onHandleError("Failed to prepare export data: " + error.message);
return [];
} finally {
setLoading(false);
}
};

return (
<CSVLink
columns={csvColumns}
datas={prepareData}
filename={exportedFileName}
handleError={(e) =>
onHandleError(`Some error occured: ${(e as Error).message}`)
}
>
<Tooltip>
<Tooltip.Trigger asChild>
<Button.Outline appearance="secondary" size="sm" disabled={loading}>
<RiDownload2Line className="w-4 h-4 inline-block mr-1" />
{loading ? "Exporting..." : "Export"}
</Button.Outline>
</Tooltip.Trigger>
<Tooltip.Content side="left" className="px-2 py-1">
<Typography.Text size="sm" appearance="primary">
* Last 6 months
</Typography.Text>
</Tooltip.Content>
</Tooltip>
</CSVLink>
);
};
85 changes: 85 additions & 0 deletions apps/hestia/src/components/direct/History/facetedFilters.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
"use client";

import { FilterGroup, Typography } from "@polkadex/ux";
import { Column } from "@tanstack/react-table";
import classNames from "classnames";

interface FacetedFilterProps<TData, TValue> {
column: Column<TData, TValue> | undefined;
title?: string;
withoutBorder?: boolean;
values: string[];
}
export const FacetedFilter = <TData, TValue>({
column,
title,
values,
withoutBorder,
}: FacetedFilterProps<TData, TValue>) => {
const selectedValues = new Set(column?.getFilterValue() as string[]);

return (
<FilterGroup>
{/* eslint-disable-next-line */}
{/* @ts-ignore */}
<FilterGroup.Root>
<FilterGroup.Trigger
className={classNames(withoutBorder && "border-0")}
>
<FilterGroup.Title>
<FilterGroup.Icon />
{title}
</FilterGroup.Title>
<FilterGroup.Filters maxItems={1}>
{values
?.filter((value) => selectedValues.has(value))
.map((v) => {
return (
<Typography.Text
key={v}
size="xs"
className="bg-level-1 rounded-md py-1 px-2"
>
{v}
</Typography.Text>
);
})}
</FilterGroup.Filters>
</FilterGroup.Trigger>
</FilterGroup.Root>
{/* eslint-disable-next-line */}
{/* @ts-ignore */}
<FilterGroup.Content>
{values.map((v) => {
const isSelected = selectedValues.has(v);
return (
<FilterGroup.Item
key={v}
checked={isSelected}
onClick={() => {
if (isSelected) selectedValues.delete(v);
else selectedValues.add(v);
column?.setFilterValue(
selectedValues.size ? Array.from(selectedValues) : undefined
);
}}
>
{v}
</FilterGroup.Item>
);
})}
{!!selectedValues.size && (
<FilterGroup.Button
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
column?.setFilterValue(undefined);
}}
>
Clear filter
</FilterGroup.Button>
)}
</FilterGroup.Content>
</FilterGroup>
);
};
Loading

0 comments on commit ecced18

Please sign in to comment.