Skip to content

Commit

Permalink
latest blocks (#155)
Browse files Browse the repository at this point in the history
  • Loading branch information
jagnani73 committed Apr 17, 2024
1 parent c07abc0 commit f5ca3e6
Show file tree
Hide file tree
Showing 12 changed files with 195 additions and 41 deletions.
1 change: 0 additions & 1 deletion .storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { StorybookConfig } from "@storybook/react-vite";
const config: StorybookConfig = {
stories: ["../src/**/*.stories.@(js|jsx|ts|tsx)"],
addons: [
"@storybook/addon-onboarding",
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions",
Expand Down
17 changes: 4 additions & 13 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@
"@storybook/addon-essentials": "^8.0.8",
"@storybook/addon-interactions": "^8.0.8",
"@storybook/addon-links": "^8.0.8",
"@storybook/addon-onboarding": "^8.0.8",
"@storybook/blocks": "^8.0.8",
"@storybook/manager-api": "^8.0.8",
"@storybook/react": "^8.0.8",
Expand Down Expand Up @@ -83,7 +82,7 @@
"vite-plugin-dts": "^3.8.2"
},
"dependencies": {
"@covalenthq/client-sdk": "^1.0.0",
"@covalenthq/client-sdk": "^1.0.1",
"@headlessui/react": "^1.7.18",
"@headlessui/tailwindcss": "^0.2.0",
"@radix-ui/react-avatar": "^1.0.4",
Expand Down
1 change: 1 addition & 0 deletions src/components/Atoms/Address/Address.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ type Story = StoryObj<typeof AddressComponent>;
export const Address: Story = {
args: {
address: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
show_copy_icon: true,
},
};
51 changes: 29 additions & 22 deletions src/components/Atoms/Address/Address.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import { type AddressProps } from "@/utils/types/atoms.types";
import { useToast } from "@/utils/hooks";
import { useState } from "react";

export const Address: React.FC<AddressProps> = ({ address }) => {
export const Address: React.FC<AddressProps> = ({
address,
show_copy_icon = true,
}) => {
const [showCopy, setShowCopy] = useState(false);
const { toast } = useToast();

Expand All @@ -21,27 +24,31 @@ export const Address: React.FC<AddressProps> = ({ address }) => {
return (
<div className="flex items-center gap-x-2">
<p>{truncate(address)}</p>
<button
className="cursor-pointer"
onClick={() => {
copyToClipboard(address);
}}
>
{showCopy ? (
<IconWrapper
icon_class_name="done"
icon_size="text-sm"
class_name="text-secondary-light dark:text-secondary-dark"
/>
) : (
<IconWrapper
icon_class_name="content_copy"
icon_size="text-sm"
class_name="text-secondary-light dark:text-secondary-dark"
on_click={() => handleCopyClick()}
/>
)}
</button>
{show_copy_icon ? (
<button
className="cursor-pointer"
onClick={() => {
copyToClipboard(address);
}}
>
{showCopy ? (
<IconWrapper
icon_class_name="done"
icon_size="text-sm"
class_name="text-secondary-light dark:text-secondary-dark"
/>
) : (
<IconWrapper
icon_class_name="content_copy"
icon_size="text-sm"
class_name="text-secondary-light dark:text-secondary-dark"
on_click={() => handleCopyClick()}
/>
)}
</button>
) : (
<></>
)}
</div>
);
};
18 changes: 18 additions & 0 deletions src/components/Molecules/LatestBlocks/LatestBlocks.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { type Meta, type StoryObj } from "@storybook/react";
import { LatestBlocks as LatestBlocksComponent } from "./LatestBlocks";

type Story = StoryObj<typeof LatestBlocksComponent>;

const meta: Meta<typeof LatestBlocksComponent> = {
title: "Molecules/Latest Blocks",
component: LatestBlocksComponent,
};

export default meta;

export const LatestBlocks: Story = {
args: {
chain_name: "eth-mainnet",
height: 16643179,
},
};
121 changes: 121 additions & 0 deletions src/components/Molecules/LatestBlocks/LatestBlocks.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import { Address } from "@/components/Atoms";
import { Button } from "@/components/ui/button";
import { Card, CardDescription } from "@/components/ui/card";
import { Skeleton } from "@/components/ui/skeleton";
import { GRK_SIZES } from "@/utils/constants/shared.constants";
import { timestampParser } from "@/utils/functions";
import { None, Some, type Option } from "@/utils/option";
import { useGoldRush } from "@/utils/store";
import { type LatestBlocksProps } from "@/utils/types/molecules.types";
import { type Block } from "@covalenthq/client-sdk";
import { ExternalLinkIcon } from "@radix-ui/react-icons";
import { useEffect, useState } from "react";

export const LatestBlocks: React.FC<LatestBlocksProps> = ({
chain_name,
height,
limit = 5,
on_view_details,
}) => {
const { covalentClient } = useGoldRush();
const [errorMessage, setErrorMessage] = useState<string | null>(null);
const [maybeResult, setResult] = useState<Option<Block[]>>(None);

useEffect(() => {
(async () => {
setResult(None);
setErrorMessage(null);
try {
const { data, ...error } =
await covalentClient.BaseService.getBlockHeightsByPage(
chain_name,
timestampParser(Date(), "YYYY MM DD"),
"2100-01-01",
{
pageSize: limit,
}
);
if (error.error) {
setErrorMessage(error.error_message);
throw error;
}
setResult(new Some(data.items));
} catch (error) {
console.error(error);
}
})();
}, [chain_name, height, limit]);

return maybeResult.match({
None: () => (
<>
{new Array(limit).fill(null).map(() => (
<Skeleton key={Math.random()} size={GRK_SIZES.LARGE} />
))}
</>
),
Some: (blocks) =>
errorMessage ? (
<p className="col-span-5">{errorMessage}</p>
) : (
blocks.map((block) => (
<Card
key={block.height}
className="m-4 flex w-full flex-col rounded border border-secondary-light p-2 dark:border-secondary-dark dark:bg-background-dark dark:text-white"
>
<div className="flex w-full justify-between">
<CardDescription>BLOCK HEIGHT</CardDescription>

<p className="text-sm">
{block.height.toLocaleString()}
</p>
</div>

<div className="flex w-full justify-between">
<CardDescription>SIGNED AT</CardDescription>

<p className="text-sm">
{timestampParser(block.signed_at, "relative")}
</p>
</div>

<div className="flex w-full justify-between text-sm">
<CardDescription>BLOCK HASH</CardDescription>

<Address
address={block.block_hash}
show_copy_icon={false}
/>
</div>

<div className="flex w-full justify-between text-sm">
<CardDescription>GAS USED</CardDescription>
{((block.gas_used / block.gas_limit) * 100).toFixed(
2
)}
%
</div>

<div className="flex w-full justify-between text-sm">
<CardDescription>GAS LIMIT</CardDescription>

{block.gas_limit.toLocaleString()}
</div>

{on_view_details ? (
<Button
variant="ghost"
className="mx-auto mb-2 mt-4 flex items-center justify-center gap-x-2 text-sm"
onClick={() => on_view_details(block)}
>
<span> View Block Details</span>
<ExternalLinkIcon />
</Button>
) : (
<></>
)}
</Card>
))
),
});
};
1 change: 1 addition & 0 deletions src/components/Molecules/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export { ChainSelector } from "./ChainSelector/ChainSelector";
export { CollectionCard } from "./CollectionCard/CollectionCard";
export { DecodedTransaction } from "./DecodedTransaction/DecodedTransaction";
export { GasCard } from "./GasCard/GasCard";
export { LatestBlocks } from "./LatestBlocks/LatestBlocks";
export { NFTFloorPrice } from "./NFTs/NFTFloorPrice/NFTFloorPrice";
export { NFTSalesCount } from "./NFTs/NFTSalesCount/NFTSalesCount";
export { NFTVolume } from "./NFTs/NFTVolume/NFTVolume";
Expand Down
2 changes: 1 addition & 1 deletion src/components/ui/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const buttonVariants = cva(
"bg-primary-light dark:bg-primary-dark text-foreground-light dark:text-foreground-dark shadow hover:bg-opacity-90",
outline:
"border border-input bg-background-light dark:bg-background-dark shadow-sm hover:bg-primary-light border-secondary-light dark:border-secondary-dark",
ghost: "hover:bg-primary-light hover:text-secondary-light dark:hover:bg-primary-dark dark:hover:text-secondary-dark",
ghost: "hover:bg-primary-light hover:text-foreground-light dark:hover:bg-primary-dark dark:hover:text-foreground-dark",
link: "text-primary-light dark:text-primary-dark underline-offset-4 hover:underline",
},
size: {
Expand Down
12 changes: 10 additions & 2 deletions src/utils/functions/timestamp-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const months: string[] = [

export const timestampParser = (
timestamp: string | Date,
type: "descriptive" | "DD MMM YY" | "relative"
type: "descriptive" | "DD MMM YY" | "relative" | "YYYY MM DD"
): string => {
const _unix: Date = new Date(timestamp);

Expand Down Expand Up @@ -78,8 +78,16 @@ export const timestampParser = (
}
}

case "YYYY MM DD": {
const year = _unix.getFullYear();
const month = String(_unix.getMonth() + 1).padStart(2, "0");
const day = String(_unix.getDate()).padStart(2, "0");

return `${year}-${month}-${day}`;
}

default: {
return "error";
return _unix.toISOString();
}
}
};
1 change: 1 addition & 0 deletions src/utils/types/atoms.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { type GRK_SIZES } from "../constants/shared.constants";

export interface AddressProps {
address: string;
show_copy_icon?: boolean;
}

export interface AddressAvatarProps {
Expand Down
8 changes: 8 additions & 0 deletions src/utils/types/molecules.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
type ExchangeTransaction,
type Transaction,
type ChainItem,
type Block,
} from "@covalenthq/client-sdk";
import {
type DECODED_ACTION,
Expand All @@ -24,6 +25,13 @@ export interface BlockDetailsProps {
height: number;
}

export interface LatestBlocksProps {
chain_name: Chain;
height: number;
limit?: number;
on_view_details?: (block: Block) => void;
}

export interface GasCardProps {
chain_name: Chain;
event_type: string;
Expand Down

0 comments on commit f5ca3e6

Please sign in to comment.