Skip to content

Commit

Permalink
resolve comments
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremy-babylonlabs committed Dec 16, 2024
1 parent f05787f commit 4565c8b
Show file tree
Hide file tree
Showing 12 changed files with 189 additions and 170 deletions.
4 changes: 2 additions & 2 deletions src/app/components/Delegations/Delegation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import { FaBitcoin } from "react-icons/fa";
import { IoIosWarning } from "react-icons/io";
import { Tooltip } from "react-tooltip";

import { useFinalityProviderService } from "@/app/hooks/services/useFinalityProviderService";
import {
type SigningStep,
useTransactionService,
} from "@/app/hooks/services/useTransactionService";
import { useHealthCheck } from "@/app/hooks/useHealthCheck";
import { useFinalityProviderState } from "@/app/state/FinalityProviderState";
import {
type Delegation as DelegationInterface,
DelegationState,
Expand Down Expand Up @@ -48,7 +48,7 @@ export const Delegation: React.FC<DelegationProps> = ({
const [currentTime, setCurrentTime] = useState(Date.now());
const { isApiNormal, isGeoBlocked } = useHealthCheck();
const { transitionPhase1Delegation } = useTransactionService();
const { getFinalityProviderMoniker } = useFinalityProviderService(); // get the moniker of the finality provider
const { getFinalityProviderMoniker } = useFinalityProviderState(); // get the moniker of the finality provider
useEffect(() => {
const timerId = setInterval(() => {
setCurrentTime(Date.now());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { Select } from "@babylonlabs-io/bbn-core-ui";

import { useFinalityProviderService } from "@/app/hooks/services/useFinalityProviderService";
import { useFinalityProviderState } from "@/app/state/FinalityProviderState";

const options = [
{ value: "active", label: "Active" },
{ value: "inactive", label: "Inactive" },
];

export const FinalityProviderFilter = () => {
const { filterValue, handleFilter } = useFinalityProviderService();
const { filterValue, handleFilter } = useFinalityProviderState();

return (
<Select
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { Input } from "@babylonlabs-io/bbn-core-ui";
import { useCallback } from "react";
import { RiSearchLine } from "react-icons/ri";

import { useFinalityProviderService } from "@/app/hooks/services/useFinalityProviderService";
import { useFinalityProviderState } from "@/app/state/FinalityProviderState";

export const FinalityProviderSearch = () => {
const { handleSearch, searchValue } = useFinalityProviderService();
const { handleSearch, searchValue } = useFinalityProviderState();

const onSearchChange = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
Expand Down

This file was deleted.

126 changes: 79 additions & 47 deletions src/app/components/Staking/FinalityProviders/FinalityProviderTable.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Avatar, Loader, Table } from "@babylonlabs-io/bbn-core-ui";
import Image from "next/image";
import { useMemo } from "react";

import warningOctagon from "@/app/assets/warning-octagon.svg";
import warningTriangle from "@/app/assets/warning-triangle.svg";
import { Hash } from "@/app/components/Hash/Hash";
import { useFinalityProviderService } from "@/app/hooks/services/useFinalityProviderService";
import { useFinalityProviderState } from "@/app/state/FinalityProviderState";
import {
FinalityProvider,
FinalityProviderState,
Expand All @@ -16,6 +17,12 @@ import { maxDecimals } from "@/utils/maxDecimals";

import { StatusView } from "./FinalityProviderTableStatusView";

const { coinName } = getNetworkConfig();

const mapStatus = (value: FinalityProviderState): string => {
return FinalityProviderStatus[value] || "Unknown";
};

export const FinalityProviderTable = () => {
const {
isFetching,
Expand All @@ -26,80 +33,99 @@ export const FinalityProviderTable = () => {
filterValue,
hasError,
handleRowSelect,
} = useFinalityProviderService();

const { coinName } = getNetworkConfig();

const mapStatus = (value: FinalityProviderState): string => {
return FinalityProviderStatus[value] || "Unknown";
};
} = useFinalityProviderState();

const columns = useMemo(
() => [
{
key: "moniker",
header: "Finality Provider",
render: (_: unknown, row: FinalityProvider) => (
<div className="flex items-center gap-2">
{row.description?.identity && (
<Avatar
size="small"
url={row.description.identity}
alt={row.description.moniker || ""}
/>
)}
<span className="text-primary-dark">
{row.description?.moniker || "No name provided"}
</span>
</div>
),
sorter: (a: FinalityProvider, b: FinalityProvider) =>
(a.description?.moniker || "").localeCompare(
b.description?.moniker || "",
),
render: (_: unknown, row?: FinalityProvider) => {
if (!row) return null;
return (
<div className="flex items-center gap-2">
{row.description?.identity && (
<Avatar
size="small"
url={row.description.identity}
alt={row.description.moniker || ""}
/>
)}
<span className="text-primary-dark">
{row.description?.moniker || "No name provided"}
</span>
</div>
);
},
sorter: (a?: FinalityProvider, b?: FinalityProvider) => {
const monikerA = a?.description?.moniker || "";
const monikerB = b?.description?.moniker || "";
return monikerA.localeCompare(monikerB);
},
},
{
key: "btcPk",
header: "BTC PK",
render: (_: unknown, row: FinalityProvider) => (
<Hash value={row.btcPk} address small noFade />
),
render: (_: unknown, row?: FinalityProvider) => {
if (!row?.btcPk) return null;
return <Hash value={row.btcPk} address small noFade />;
},
},
{
key: "activeTVLSat",
header: "Total Delegation",
render: (value: unknown) =>
`${maxDecimals(satoshiToBtc(value as number), 8)} ${coinName}`,
sorter: (a: FinalityProvider, b: FinalityProvider) =>
a.activeTVLSat - b.activeTVLSat,
render: (value: unknown) => {
const amount = Number(value);
if (isNaN(amount)) return "-";
return `${maxDecimals(satoshiToBtc(amount), 8)} ${coinName}`;
},
sorter: (a?: FinalityProvider, b?: FinalityProvider) => {
const valueA = a?.activeTVLSat ?? 0;
const valueB = b?.activeTVLSat ?? 0;
return valueA - valueB;
},
},
{
key: "commission",
header: "Commission",
render: (value: unknown) => `${maxDecimals(Number(value) * 100, 2)}%`,
sorter: (a: FinalityProvider, b: FinalityProvider) =>
Number(a.commission) - Number(b.commission),
render: (value: unknown) => {
const commission = Number(value);
if (isNaN(commission)) return "-";
return `${maxDecimals(commission * 100, 2)}%`;
},
sorter: (a?: FinalityProvider, b?: FinalityProvider) => {
const commissionA = Number(a?.commission) || 0;
const commissionB = Number(b?.commission) || 0;
return commissionA - commissionB;
},
},
{
key: "state",
header: "Status",
render: (value: unknown) => mapStatus(value as FinalityProviderState),
render: (value: unknown) => {
if (value == null) return "Unknown";
return mapStatus(value as FinalityProviderState);
},
},
],
[coinName],
);

const tableData = useMemo(
() => finalityProviders?.map((fp) => ({ ...fp, id: fp.btcPk })) || [],
[finalityProviders],
);
const tableData = useMemo(() => {
if (!finalityProviders) return [];
return finalityProviders.map((fp) => ({
...fp,
id: fp.btcPk,
}));
}, [finalityProviders]);

const renderContent = () => {
if (hasError) {
return (
<StatusView
icon={warningTriangle}
iconSize={88}
icon={
<Image src={warningTriangle} alt="Warning" width={88} height={88} />
}
title="Failed to Load"
description={
<>
Expand All @@ -111,7 +137,7 @@ export const FinalityProviderTable = () => {
);
}

if (isFetching && tableData.length === 0) {
if (isFetching && (!finalityProviders || finalityProviders.length === 0)) {
return (
<StatusView
icon={<Loader className="text-primary-dark" />}
Expand All @@ -120,11 +146,17 @@ export const FinalityProviderTable = () => {
);
}

if (!isFetching && tableData.length === 0) {
if (!isFetching && (!tableData || tableData.length === 0)) {
return (
<StatusView
icon={warningOctagon}
iconSize={160}
icon={
<Image
src={warningOctagon}
alt="Warning"
width={160}
height={160}
/>
}
title="No Matches Found"
/>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,19 @@
import { Heading, Text } from "@babylonlabs-io/bbn-core-ui";
import Image from "next/image";

export const StatusView = ({
icon,
iconSize,
title,
description,
}: {
icon: React.ReactNode | string;
iconSize?: number;
title: string;
description?: React.ReactNode;
}) => (
<div className="flex items-center justify-center h-[21rem]">
<div className="flex flex-col items-center gap-4">
<div className="bg-primary-contrast relative w-[5.5rem] h-[5.5rem]">
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
{typeof icon === "string" ? (
<Image
src={icon}
alt="Warning"
width={iconSize}
height={iconSize}
/>
) : (
icon
)}
{icon}
</div>
</div>
<Heading variant="h6" className="text-primary-dark">
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import { Heading, Text } from "@babylonlabs-io/bbn-core-ui";

import { FinalityProviderFilter } from "./FinalityProviderFilter";
import { FinalityProviderSearch } from "./FinalityProviderSearch";
import { FinalityProviderSubtitle } from "./FinalityProviderSubtitle";
import { FinalityProviderTable } from "./FinalityProviderTable";
import { FinalityProviderTitle } from "./FinalityProviderTitle";

export const FinalityProviders = () => {
return (
<div className="flex flex-col gap-4">
<FinalityProviderTitle />
<FinalityProviderSubtitle />
<Heading variant="h5" className="text-primary-dark">
Step 1
</Heading>
<Text variant="body1" className="text-primary-dark">
Select a Finality Provider
</Text>
<div className="flex flex-col md:flex-row gap-4">
<div className="flex-1">
<FinalityProviderSearch />
Expand Down
45 changes: 0 additions & 45 deletions src/app/state/FinalityProviderServiceState.tsx

This file was deleted.

Loading

0 comments on commit 4565c8b

Please sign in to comment.