Skip to content

Commit

Permalink
Tong/delegation list refine UI (#385)
Browse files Browse the repository at this point in the history
* refine delegation list phase 2
  • Loading branch information
supertong authored Nov 25, 2024
1 parent 9f3a099 commit e894daf
Show file tree
Hide file tree
Showing 10 changed files with 111 additions and 129 deletions.
18 changes: 18 additions & 0 deletions src/app/components/Delegations/Activity.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Heading } from "@babylonlabs-io/bbn-core-ui";

import { AuthGuard } from "@/components/common/AuthGuard";
import { DelegationList } from "@/components/delegations/DelegationList";

import { Delegations } from "./Delegations";

export function Activity() {
return (
<AuthGuard>
<Heading as="h3" variant="h4" className="mb-8 text-primary-dark">
Activity
</Heading>
<Delegations />
<DelegationList />
</AuthGuard>
);
}
16 changes: 8 additions & 8 deletions src/app/components/Delegations/Delegation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export const Delegation: React.FC<DelegationProps> = ({
return (
<div className="flex justify-end lg:justify-start">
<button
className="btn btn-outline btn-xs inline-flex text-sm font-normal text-primary"
className="btn btn-outline btn-xs inline-flex text-sm font-normal text-primary-dark"
onClick={onTransition}
disabled={
intermediateState === DelegationState.INTERMEDIATE_TRANSITIONING
Expand All @@ -104,7 +104,7 @@ export const Delegation: React.FC<DelegationProps> = ({
return (
<div className="flex justify-end lg:justify-start">
<button
className="btn btn-outline btn-xs inline-flex text-sm font-normal text-primary"
className="btn btn-outline btn-xs inline-flex text-sm font-normal text-primary-dark"
onClick={() => onWithdraw(stakingTxHashHex)}
disabled={
intermediateState === DelegationState.INTERMEDIATE_WITHDRAWAL
Expand Down Expand Up @@ -145,7 +145,7 @@ export const Delegation: React.FC<DelegationProps> = ({

return (
<div
className={`card relative border bg-base-300 p-4 text-sm dark:bg-base-200 ${isOverflow ? "border-primary" : "dark:border-0"}`}
className={`relative rounded bg-secondary-contrast odd:bg-[#F9F9F9] p-4 text-base text-primary-dark`}
>
{isOverflow && (
<div className="absolute -top-1 right-1/2 flex translate-x-1/2 items-center gap-1 rounded-md bg-primary px-2 py-1 text-xs text-white lg:right-2 lg:top-1/2 lg:-translate-y-1/2 lg:translate-x-0">
Expand All @@ -165,12 +165,12 @@ export const Delegation: React.FC<DelegationProps> = ({
<p className="order-3 lg:order-2">
{durationTillNow(startTimestamp, currentTime)}
</p>
<div className="justify-center lg:flex order-2 lg:order-3">
<div className="justify-start lg:flex order-2 lg:order-3">
<a
href={`${mempoolApiUrl}/tx/${stakingTxHashHex}`}
target="_blank"
rel="noopener noreferrer"
className="text-primary hover:underline"
className="hover:underline"
>
{trim(stakingTxHashHex)}
</a>
Expand All @@ -179,8 +179,8 @@ export const Delegation: React.FC<DelegationProps> = ({
we need to center the text without the tooltip
add its size 12px and gap 4px, 16/2 = 8px
*/}
<div className="relative flex justify-end lg:justify-center order-4">
<div className="flex items-center gap-1">
<div className="relative flex justify-start lg:justify-start order-4">
<div className="flex items-center justify-start gap-1">
<p>{renderState()}</p>
<span
className="cursor-pointer text-xs"
Expand All @@ -198,7 +198,7 @@ export const Delegation: React.FC<DelegationProps> = ({
</div>
<DelegationPoints
stakingTxHashHex={stakingTxHashHex}
className="relative flex justify-end lg:justify-center order-5"
className="relative flex justify-start lg:justify-start order-5"
/>
<div className="order-6">{generateActionButton()}</div>
</div>
Expand Down
41 changes: 0 additions & 41 deletions src/app/components/Delegations/DelegationTabs.tsx

This file was deleted.

99 changes: 51 additions & 48 deletions src/app/components/Delegations/Delegations.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Heading } from "@babylonlabs-io/bbn-core-ui";
import type { networks } from "bitcoinjs-lib";
import { useEffect, useMemo, useState } from "react";
import InfiniteScroll from "react-infinite-scroll-component";
Expand Down Expand Up @@ -236,59 +237,61 @@ const DelegationsContent: React.FC<DelegationsContentProps> = ({
: // if no API data, fallback to using only local storage delegations
delegations;

if (combinedDelegationsData.length === 0) {
return null;
}

return (
<>
{combinedDelegationsData.length === 0 ? (
<div className="rounded-2xl border border-neutral-content p-4 text-center dark:border-neutral-content/20">
<p>No history found</p>
<div className="bg-secondary-contrast p-6">
<Heading variant="h6" className="text-primary-light py-2 mb-6">
Pending Transitions / Withdrawal (Phase 1)
</Heading>

<div
className={`hidden ${shouldShowPoints ? "grid-cols-6" : "grid-cols-5"} gap-2 p-4 lg:grid text-primary-light text-xs`}
>
<p className="text-left">Amount</p>
<p className="text-left">Inception</p>
<p className="text-left">Transaction hash</p>
<p className="text-left">Status</p>
{shouldShowPoints && <p className="text-left">Points</p>}
<p className="text-left">Action</p>
</div>
) : (
<>
<div
className={`hidden ${shouldShowPoints ? "grid-cols-6" : "grid-cols-5"} gap-2 px-4 lg:grid`}
>
<p>Amount</p>
<p>Inception</p>
<p className="text-center">Transaction hash</p>
<p className="text-center">Status</p>
{shouldShowPoints && <p className="text-center">Points</p>}
<p>Action</p>
</div>
<div
id="staking-history"
className="no-scrollbar max-h-[21rem] overflow-y-auto"
<div
id="staking-history"
className="no-scrollbar max-h-[21rem] overflow-y-auto"
>
<InfiniteScroll
className="flex flex-col gap-4 pt-3"
dataLength={combinedDelegationsData.length}
next={fetchMoreDelegations}
hasMore={hasMoreDelegations}
loader={isLoading ? <LoadingTableList /> : null}
scrollableTarget="staking-history"
>
<InfiniteScroll
className="flex flex-col gap-4 pt-3"
dataLength={combinedDelegationsData.length}
next={fetchMoreDelegations}
hasMore={hasMoreDelegations}
loader={isLoading ? <LoadingTableList /> : null}
scrollableTarget="staking-history"
>
{combinedDelegationsData?.map((delegation) => {
if (!delegation) return null;
const { stakingTx, stakingTxHashHex } = delegation;
const intermediateDelegation =
intermediateDelegationsLocalStorage.find(
(item) => item.stakingTxHashHex === stakingTxHashHex,
);

return (
<Delegation
key={stakingTxHashHex + stakingTx.startHeight}
delegation={delegation}
onWithdraw={() =>
handleModal(stakingTxHashHex, MODE_WITHDRAW)
}
intermediateState={intermediateDelegation?.state}
/>
{combinedDelegationsData?.map((delegation) => {
if (!delegation) return null;
const { stakingTx, stakingTxHashHex } = delegation;
const intermediateDelegation =
intermediateDelegationsLocalStorage.find(
(item) => item.stakingTxHashHex === stakingTxHashHex,
);
})}
</InfiniteScroll>
</div>
</>
)}

return (
<Delegation
key={stakingTxHashHex + stakingTx.startHeight}
delegation={delegation}
onWithdraw={() =>
handleModal(stakingTxHashHex, MODE_WITHDRAW)
}
intermediateState={intermediateDelegation?.state}
/>
);
})}
</InfiniteScroll>
</div>
</div>
{modalMode && txID && delegation && (
<WithdrawModal
open={modalOpen}
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/FAQ/FAQ.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const FAQ: React.FC<FAQProps> = () => {

return (
<div className="container mx-auto flex flex-col gap-2 p-6">
<Heading as="h3" variant="h4" className="mb-8">
<Heading as="h3" variant="h4" className="mb-8 text-primary-dark">
FAQ’s
</Heading>
<div className="flex flex-col gap-4 bg-warning-contrast border border-primary-light/20 rounded divide-y p-6">
Expand Down
4 changes: 2 additions & 2 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { initBTCCurve } from "@babylonlabs-io/btc-staking-ts";
import { useEffect } from "react";

import { DelegationTabs } from "./components/Delegations/DelegationTabs";
import { Activity } from "./components/Delegations/Activity";
import { FAQ } from "./components/FAQ/FAQ";
import { Footer } from "./components/Footer/Footer";
import { Header } from "./components/Header/Header";
Expand All @@ -27,7 +27,7 @@ const Home = () => {
<Stats />
<PersonalBalance />
<Staking />
<DelegationTabs />
<Activity />
</div>
</div>
<FAQ />
Expand Down
2 changes: 1 addition & 1 deletion src/components/common/GridTable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export function GridTable<R extends object, P extends object = {}>({
sortable={col.sortable}
field={col.field}
className={twMerge(
"sticky top-0",
"sticky top-0 bg-secondary-contrast",
classNames?.headerCellClassName,
col.headerCellClassName,
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type ButtonStrategy = Record<string, ButtonAdapter>;
const ACTION_BUTTONS: ButtonStrategy = {
[state.VERIFIED]: (props: ActionButtonProps) => (
<button
className="btn btn-outline btn-xs inline-flex text-sm font-normal text-primary"
className="btn btn-outline btn-xs inline-flex text-sm font-normal text-primary-dark"
onClick={() => props.onClick?.("stake", props.txHash)}
disabled={props.state === state.INTERMEDIATE_PENDING_CONFIRMATION}
>
Expand All @@ -21,7 +21,7 @@ const ACTION_BUTTONS: ButtonStrategy = {
),
[state.ACTIVE]: (props: ActionButtonProps) => (
<button
className="btn btn-outline btn-xs inline-flex text-sm font-normal text-primary"
className="btn btn-outline btn-xs inline-flex text-sm font-normal text-primary-dark"
onClick={() => props.onClick?.("unbound", props.txHash)}
disabled={props.state === state.INTERMEDIATE_UNBONDING}
>
Expand All @@ -31,7 +31,7 @@ const ACTION_BUTTONS: ButtonStrategy = {

[state.WITHDRAWABLE]: (props: ActionButtonProps) => (
<button
className="btn btn-outline btn-xs inline-flex text-sm font-normal text-primary"
className="btn btn-outline btn-xs inline-flex text-sm font-normal text-primary-dark"
onClick={() => props.onClick?.("withdraw", props.txHash)}
disabled={props.state === state.INTERMEDIATE_WITHDRAWAL}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export function TxHash({ value }: TxHashProps) {
href={`${mempoolApiUrl}/tx/${value}`}
target="_blank"
rel="noopener noreferrer"
className="text-primary hover:underline"
className="text-primary-dark hover:underline"
>
{trim(value)}
</a>
Expand Down
50 changes: 26 additions & 24 deletions src/components/delegations/DelegationList/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Heading } from "@babylonlabs-io/bbn-core-ui";

import { useTransactionService } from "@/app/hooks/services/useTransactionService";
import { useDelegationV2State } from "@/app/state/DelegationV2State";
import type { DelegationV2 } from "@/app/types/delegationsV2";
Expand All @@ -23,27 +25,20 @@ const columns: TableColumn<
field: "startHeight",
headerName: "Duration",
width: "max-content",
align: "center",
},
{
field: "stakingTxHashHex",
headerName: "Transaction hash",
cellClassName: "justify-center",
align: "center",
renderCell: (row) => <TxHash value={row.stakingTxHashHex} />,
},
{
field: "state",
headerName: "Status",
cellClassName: "justify-center",
align: "center",
renderCell: (row) => <Status value={row.state} />,
},
{
field: "actions",
headerName: "Action",
cellClassName: "justify-center",
align: "center",
renderCell: (row, _, { handleActionClick }) => (
<ActionButton
txHash={row.stakingTxHashHex}
Expand Down Expand Up @@ -117,22 +112,29 @@ export function DelegationList() {
};

return (
<GridTable
getRowId={(row) => `${row.stakingTxHashHex}-${row.startHeight}`}
columns={columns}
data={delegations}
loading={isLoading}
infiniteScroll={hasMoreDelegations}
onInfiniteScroll={fetchMoreDelegations}
classNames={{
headerCellClassName: "py-2 px-4 bg-base-300",
wrapperClassName: "max-h-[21rem] overflow-x-auto",
bodyClassName: "gap-y-4 min-w-[1000px]",
cellClassName:
"p-4 first:pl-4 first:rounded-l-2xl last:pr-4 last:rounded-r-2xl bg-base-300 border dark:bg-base-200 dark:border-0 flex items-center text-sm",
}}
params={{ handleActionClick }}
fallback={<div>No delegations found</div>}
/>
<div className="bg-secondary-contrast p-6">
<Heading variant="h6" className="text-primary-light py-2 mb-6">
Babylon Chain Stakes (Phase 2)
</Heading>
<GridTable
getRowId={(row) => `${row.stakingTxHashHex}-${row.startHeight}`}
columns={columns}
data={delegations}
loading={isLoading}
infiniteScroll={hasMoreDelegations}
onInfiniteScroll={fetchMoreDelegations}
classNames={{
headerRowClassName: "text-primary-light text-xs",
headerCellClassName: "p-4 text-align-left",
rowClassName: "group",
wrapperClassName: "max-h-[21rem] overflow-x-auto",
bodyClassName: "gap-y-4 min-w-[1000px]",
cellClassName:
"p-4 first:pl-4 first:rounded-l last:pr-4 last:rounded-r bg-secondary-contrast flex items-center text-base justify-start group-even:bg-[#F9F9F9] text-primary-dark",
}}
params={{ handleActionClick }}
fallback={<div>No delegations found</div>}
/>
</div>
);
}

0 comments on commit e894daf

Please sign in to comment.