Skip to content

Commit

Permalink
feat: add filters
Browse files Browse the repository at this point in the history
  • Loading branch information
danielsimao committed Jan 22, 2025
1 parent 0224c7d commit d3c62d9
Show file tree
Hide file tree
Showing 13 changed files with 253 additions and 261 deletions.
1 change: 0 additions & 1 deletion apps/evm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
"@sentry/nextjs": "catalog:",
"@tanstack/react-query": "catalog:",
"@tanstack/react-store": "catalog:",
"@tanstack/react-virtual": "catalog:",
"@vercel/kv": "catalog:",
"@wagmi/core": "catalog:",
"big.js": "catalog:",
Expand Down
10 changes: 6 additions & 4 deletions apps/evm/src/app/[lang]/(bridge)/bridge/Bridge.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client';

import { ChainId, getChainIdByChainName, getChainName } from '@gobob/chains';
import { Card, Flex, Spinner, Tabs, TabsItem, Span, SolidClock, Button } from '@gobob/ui';
import { Card, Flex, Spinner, Tabs, TabsItem, Span, SolidClock, Button, Skeleton } from '@gobob/ui';
import { Trans } from '@lingui/macro';
import { useRouter } from 'next/navigation';
import { Key, useCallback, useEffect, useMemo, useState } from 'react';
Expand Down Expand Up @@ -56,7 +56,7 @@ interface Props {
const Bridge = ({ searchParams }: Props) => {
const router = useRouter();

const { txPendingUserAction } = useGetBridgeTransactions();
const { txPendingUserAction, isPending } = useGetBridgeTransactions();
const { open } = useConnectModal();

const { address: evmAddress } = useAccount();
Expand Down Expand Up @@ -130,7 +130,7 @@ const Bridge = ({ searchParams }: Props) => {
const handleOpenProfile = () => {
store.setState((state) => ({
...state,
shared: { ...state.shared, profile: { isOpen: true, selectedTab: 'activity' } }
shared: { ...state.shared, profile: { ...state.shared.profile, isOpen: true, selectedTab: 'activity' } }
}));
};

Expand Down Expand Up @@ -166,7 +166,9 @@ const Bridge = ({ searchParams }: Props) => {
<Flex justifyContent='flex-end'>
<Button size='s' style={{ gap: 4, alignItems: 'center' }} onPress={handleActivity}>
<SolidClock />
{txPendingUserAction && txPendingUserAction > 0 ? (
{isPending ? (
<Skeleton height='1.5rem' width='5rem' />
) : txPendingUserAction && txPendingUserAction > 0 ? (
<Card
alignItems='center'
background='primary-500'
Expand Down
2 changes: 1 addition & 1 deletion apps/evm/src/components/Layout/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,10 @@ const Header = (): JSX.Element => {
<Trans>Multisig</Trans>
</NavItem>
</Nav>
<SocialsGroup hidden={isMobile} variant='ghost' />
</PopoverBody>
</PopoverContent>
</Popover>
<SocialsGroup hidden={isMobile} variant='ghost' />
</Flex>
</Flex>
<Flex alignItems='center' gap='xl'>
Expand Down
13 changes: 3 additions & 10 deletions apps/evm/src/components/Layout/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@

import {
Bars3,
Button,
DrawerButton,
DrawerContent,
DrawerOverlay,
DrawerPortal,
DrawerRoot,
DrawerTitle,
Flex,
XMark
Flex
} from '@gobob/ui';
import { t, Trans } from '@lingui/macro';
import { useLingui } from '@lingui/react';
Expand Down Expand Up @@ -44,13 +42,8 @@ const Sidebar = ({ isMobile }: { isMobile: boolean }): JSX.Element | null => {
</DrawerTitle>
<Flex direction='column' elementType='nav' style={{ height: '100%' }}>
<Flex direction='column' flex={1} gap='4xl'>
<Flex alignItems='center' justifyContent='space-between'>
<Logo href={RoutesPath.HOME} onPress={handleClose} />
<Button isIconOnly variant='ghost' onPress={handleClose}>
<XMark size='s' />
</Button>
</Flex>
<Flex direction='column' flex={1} justifyContent='space-between'>
<Logo href={RoutesPath.HOME} onPress={handleClose} />
<Flex direction='column' flex={1} gap='lg' justifyContent='space-between'>
<Nav direction='column' gap='3xl'>
<NavItem href={RoutesPath.BRIDGE} onPress={handleClose}>
<Trans>Bridge</Trans>
Expand Down
85 changes: 2 additions & 83 deletions apps/evm/src/components/ProfileActivity/ProfileActivity.style.tsx
Original file line number Diff line number Diff line change
@@ -1,79 +1,15 @@
import { ArrowDownCircle, Button, Card, Flex, Span, UnstyledButton, hexToRgba } from '@gobob/ui';
import { Card, Flex, UnstyledButton, hexToRgba } from '@gobob/ui';
import styled from 'styled-components';

type StyledExpandIconProps = {
$isExpanded?: boolean;
};

type StyledTransactionItemCardProps = {
$isExpanded?: boolean;
$isShowMoreHovered?: boolean;
};

type StyledVirtualizerProps = {
$height: number;
};

type StyledVirtualizerItemProps = {
$translateY: number;
};

const StyledSpan = styled(Span)`
display: inline-flex;
align-items: center;
position: relative;
margin-left: ${({ theme }) => theme.spacing('md')};
padding: 0 ${({ theme }) => theme.spacing('s')};
height: 24px;
border-radius: ${({ theme }) => theme.rounded('full')};
`;

const StyledSpinnerWrapper = styled.span`
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
`;

const StyledTransactionList = styled(Flex)`
flex: 1 1 auto;
`;

const StyledTransactionListWrapper = styled(Flex)`
overflow: hidden;
`;

const StyledTransactionListParent = styled.div`
height: 100%;
overflow: auto;
`;

const StyledVirtualizer = styled.div<StyledVirtualizerProps>`
width: 100%;
position: relative;
height: ${({ $height }) => `${$height}px`};
`;

const StyledVirtualizerItem = styled.div<StyledVirtualizerItemProps>`
position: absolute;
width: 100%;
transform: ${({ $translateY }) => `translateY(${$translateY}px)`};
`;

const StyledDetailsButton = styled(Flex)`
font: inherit;
display: flex;
width: 100%;
flex-direction: column;
gap: ${({ theme }) => theme.spacing('md')};
padding: ${({ theme }) => `${theme.spacing('md')} 0`};
`;

const StyledExpandIcon = styled(ArrowDownCircle)<StyledExpandIconProps>`
${({ theme }) => theme.transition('common', 'normal')};
transform: ${({ $isExpanded }) => ($isExpanded ? 'rotate(-180deg)' : 'rotate(0deg)')};
`;

const StyledShowMore = styled(UnstyledButton)`
display: flex;
justify-content: center;
Expand Down Expand Up @@ -103,21 +39,4 @@ const StyledTransactionItemCard = styled(Card)<StyledTransactionItemCardProps>`
`linear-gradient(${theme.color('grey-400')} 70%, ${theme.color($isShowMoreHovered ? 'grey-700' : 'grey-500')} 100%)`};
`;

const StyledFilterButton = styled(Button)`
gap: ${({ theme }) => theme.spacing('s')};
`;

export {
StyledDetailsButton,
StyledExpandIcon,
StyledFilterButton,
StyledShowMore,
StyledSpan,
StyledSpinnerWrapper,
StyledTransactionItemCard,
StyledTransactionList,
StyledTransactionListParent,
StyledTransactionListWrapper,
StyledVirtualizer,
StyledVirtualizerItem
};
export { StyledShowMore, StyledTransactionItemCard, StyledTransactionList };
83 changes: 29 additions & 54 deletions apps/evm/src/components/ProfileActivity/ProfileActivity.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
import { Flex, P, Skeleton } from '@gobob/ui';
import { Trans } from '@lingui/macro';
import { useEffect, useMemo, useRef } from 'react';
import { useConfig } from 'wagmi';
import { useStore } from '@tanstack/react-store';
import { watchAccount } from '@wagmi/core';
import { useEffect, useMemo, useRef } from 'react';
import { useConfig } from 'wagmi';

import { StyledTransactionList } from './ProfileActivity.style';
import { ProfileActivityFilter, StatusFilterOption, TransactionTypeFilterOption } from './ProfileActivityFilter';
import {
ProfileActivityFilters,
ProfileActivityFiltersData,
ProfileActivityStatusFilterOption,
ProfileActivityTypeFilterOption
} from './ProfileActivityFilters';
import { TransactionItem } from './TransactionItem';

import { useGetBridgeTransactions, useGetGatewayTransactions } from '@/hooks';
import { store } from '@/lib/store';
import { BridgeTransactionStatus, GatewayTransactionType, TransactionType } from '@/types';

const ProfileActivity = (): JSX.Element => {
const { status = StatusFilterOption.ANY_STATUS, type = TransactionTypeFilterOption.ALL_TRANSACTIONS } = useStore(
store,
(state) => state.shared.profile.activityFilters
);
const { filters } = useStore(store, (state) => state.shared.profile.transactions);

const config = useConfig();

Expand Down Expand Up @@ -56,38 +58,38 @@ const ProfileActivity = (): JSX.Element => {
}, [isInitialLoading, isLoading]);

const dataByType = useMemo(() => {
switch (type) {
case TransactionTypeFilterOption.BTC_BRIDGE:
switch (filters.type) {
case ProfileActivityTypeFilterOption.BTC_BRIDGE:
return gateway.data?.filter((item) => item.subType === GatewayTransactionType.BRIDGE) || [];
case TransactionTypeFilterOption.STRATEGIES:
case ProfileActivityTypeFilterOption.STRATEGIES:
return gateway.data?.filter((item) => item.subType === GatewayTransactionType.STRATEGY) || [];
case TransactionTypeFilterOption.NATIVE_BRIDGE:
case ProfileActivityTypeFilterOption.NATIVE_BRIDGE:
return bridge.data;
default:
case TransactionTypeFilterOption.ALL_TRANSACTIONS:
case ProfileActivityTypeFilterOption.ALL_TRANSACTIONS:
return [...bridge.data, ...(gateway?.data || [])];
}
}, [bridge.data, gateway.data, type]);
}, [bridge.data, gateway.data, filters.type]);

const dataByStatus = useMemo(() => {
switch (status) {
case StatusFilterOption.PENDING:
switch (filters.status) {
case ProfileActivityStatusFilterOption.PENDING:
return dataByType.filter((item) =>
item.type === TransactionType.Bridge
? item.status !== BridgeTransactionStatus.RELAYED
: item.status !== 'l2-confirmation'
);
case StatusFilterOption.COMPLETE:
case ProfileActivityStatusFilterOption.COMPLETE:
return dataByType.filter((item) =>
item.type === TransactionType.Bridge
? item.status === BridgeTransactionStatus.RELAYED
: item.status === 'l2-confirmation'
);
case StatusFilterOption.FAILED:
case ProfileActivityStatusFilterOption.FAILED:
return dataByType.filter((item) =>
item.type === TransactionType.Bridge ? item.status === BridgeTransactionStatus.FAILED_L1_TO_L2_MESSAGE : false
);
case StatusFilterOption.NEEDED_ACTION:
case ProfileActivityStatusFilterOption.NEEDED_ACTION:
return dataByType.filter((item) =>
item.type === TransactionType.Bridge
? item.status === BridgeTransactionStatus.READY_TO_PROVE ||
Expand All @@ -96,10 +98,10 @@ const ProfileActivity = (): JSX.Element => {
);

default:
case StatusFilterOption.ANY_STATUS:
case ProfileActivityStatusFilterOption.ANY_STATUS:
return dataByType;
}
}, [dataByType, status]);
}, [dataByType, filters.status]);

const sortedData = useMemo(() => {
return dataByStatus?.sort((a, b) => b.date.getTime() - a.date.getTime());
Expand All @@ -108,53 +110,26 @@ const ProfileActivity = (): JSX.Element => {
return (
<Flex direction='column' marginTop='md'>
<Flex wrap gap='s' justifyContent='flex-end'>
<ProfileActivityFilter<StatusFilterOption>
label={<Trans>Status</Trans>}
options={[
{ children: <Trans>Any Status</Trans>, key: StatusFilterOption.ANY_STATUS },
{ children: <Trans>Pending</Trans>, key: StatusFilterOption.PENDING },
{ children: <Trans>Needed Action</Trans>, key: StatusFilterOption.NEEDED_ACTION },
{ children: <Trans>Complete</Trans>, key: StatusFilterOption.COMPLETE },
{ children: <Trans>Failed</Trans>, key: StatusFilterOption.FAILED }
]}
value={status as StatusFilterOption}
onSelectionChange={(value) =>
store.setState((state) => ({
...state,
shared: {
...state.shared,
profile: {
...state.shared.profile,
activityFilters: { ...state.shared.profile.activityFilters, status: value }
}
}
}))
}
/>
<ProfileActivityFilter<TransactionTypeFilterOption>
label={<Trans>Transaction type</Trans>}
options={[
{ children: <Trans>Any Transaction</Trans>, key: TransactionTypeFilterOption.ALL_TRANSACTIONS },
{ children: <Trans>Native Bridge</Trans>, key: TransactionTypeFilterOption.NATIVE_BRIDGE },
{ children: <Trans>BTC Bridge</Trans>, key: TransactionTypeFilterOption.BTC_BRIDGE },
{ children: <Trans>Staking</Trans>, key: TransactionTypeFilterOption.STRATEGIES }
]}
value={type as TransactionTypeFilterOption}
<ProfileActivityFilters
value={filters as ProfileActivityFiltersData}
onSelectionChange={(value) =>
store.setState((state) => ({
...state,
shared: {
...state.shared,
profile: {
...state.shared.profile,
activityFilters: { ...state.shared.profile.activityFilters, type: value }
transactions: {
...state.shared.profile.transactions,
filters: value
}
}
}
}))
}
/>
</Flex>
<StyledTransactionList direction='column' elementType='ul' flex={1} gap='md' marginTop='md'>
<StyledTransactionList direction='column' elementType='ul' flex={1} marginTop='md'>
{isInitialLoading ? (
Array(8)
.fill(undefined)
Expand Down
Loading

0 comments on commit d3c62d9

Please sign in to comment.