Skip to content

Commit

Permalink
styles: begin figma work
Browse files Browse the repository at this point in the history
  • Loading branch information
nelitow committed Jan 24, 2025
1 parent 22f33d5 commit 9b9d6fb
Show file tree
Hide file tree
Showing 5 changed files with 205 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export function TxOperations({
}

return (
<Box.Stack gap="$4">
<Box.Stack gap="$0">
{operations?.map((operation, index) => (
<TxOperation
// biome-ignore lint/suspicious/noArrayIndexKey: <explanation>
Expand All @@ -43,7 +43,7 @@ export function TxOperations({
}

TxOperations.Loader = () => (
<Box.Stack gap="$4">
<Box.Stack gap="$0">
<TxOperation.Loader />
</Box.Stack>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { cssObj } from '@fuel-ui/css';
import { Box, Icon, Text } from '@fuel-ui/react';
import { useState } from 'react';
import type { SimplifiedOperation } from '../../../types';
import { TxOperation } from './operations/TxOperation';

type TxOperationsGroupProps = {
title: string;
operations: SimplifiedOperation[];
showNesting?: boolean;
};

export function TxOperationsGroup({
title,
operations,
showNesting,
}: TxOperationsGroupProps) {
const [isExpanded, setIsExpanded] = useState(false);

if (!operations.length) return null;

const handleClick = (e: React.MouseEvent) => {
e.preventDefault();
e.stopPropagation();
setIsExpanded(!isExpanded);
};

return (
<Box.Stack gap="$2" css={styles.root}>
<Box.Flex as="button" onClick={handleClick} css={styles.header}>
<Icon
icon={isExpanded ? 'CaretDown' : 'CaretRight'}
size={16}
css={styles.icon}
/>
<Text fontSize="sm" css={styles.title}>
{title} ({operations.length})
</Text>
</Box.Flex>
{isExpanded && (
<Box.Stack
gap="$1"
css={styles.content}
onClick={(e) => e.stopPropagation()}
>
{operations.map((operation, index) => (
<TxOperation
key={`${operation.type}-${operation.from}-${operation.to}-${index}`}
operation={operation}
showNesting={showNesting}
/>
))}
</Box.Stack>
)}
</Box.Stack>
);
}

const styles = {
root: cssObj({
borderTop: '1px solid $border',
marginTop: '$2',
paddingTop: '$2',
}),
header: cssObj({
display: 'flex',
alignItems: 'center',
gap: '$2',
padding: '$2',
cursor: 'pointer',
backgroundColor: 'transparent',
border: 'none',
width: '100%',
borderRadius: '$md',
transition: 'all 0.2s ease',
'&:hover': {
backgroundColor: '$gray3',
},
}),
icon: cssObj({
color: '$gray8',
}),
title: cssObj({
color: '$gray8',
fontWeight: '$medium',
}),
content: cssObj({
paddingLeft: '$6',
}),
};
Original file line number Diff line number Diff line change
@@ -1,22 +1,86 @@
import { Box } from '@fuel-ui/react';
import { useMemo } from 'react';
import type { SimplifiedOperation } from '../../../types';
import { TxCategory } from '../../../types';
import { TxOperationsGroup } from './TxOperationsGroup';
import { TxOperation } from './operations/TxOperation';

type TxOperationsListProps = {
operations: SimplifiedOperation[];
currentAccount?: string;
};

export function TxOperationsList({ operations }: TxOperationsListProps) {
const renderedOperations = useMemo(() => {
return operations.map((operation, index) => {
console.log('Rendering operation:', operation);
const key = `${operation.type}-${operation.from}-${operation.to}-${index}`;
return <TxOperation key={key} operation={operation} />;
});
}, [operations]);
export function TxOperationsList({
operations,
currentAccount,
}: TxOperationsListProps) {
const { mainOperations, otherRootOperations, intermediateOperations } =
useMemo(() => {
const main: SimplifiedOperation[] = [];
const otherRoot: SimplifiedOperation[] = [];
const intermediate: SimplifiedOperation[] = [];

return <Box.Stack gap="$1">{renderedOperations}</Box.Stack>;
for (const op of operations) {
const depth = op.metadata?.depth || 0;
const isTransfer = op.type === TxCategory.SEND;
const isFromCurrentAccount =
currentAccount && op.from === currentAccount;
const isToCurrentAccount = currentAccount && op.to === currentAccount;

// All transfers go to main list
if (isTransfer) {
main.push(op);
continue;
}

// Contract calls at root level (depth 0)
if (depth === 0) {
// If related to current account, show in main list
if (isFromCurrentAccount || isToCurrentAccount) {
main.push(op);
} else {
otherRoot.push(op);
}
continue;
}

// All other operations (intermediate contract calls)
intermediate.push(op);
}

return {
mainOperations: main,
otherRootOperations: otherRoot,
intermediateOperations: intermediate,
};
}, [operations, currentAccount]);

return (
<Box>
{/* Main operations (transfers and root contract calls related to current account) */}
{mainOperations.map((operation, index) => (
<TxOperation
key={`${operation.type}-${operation.from}-${operation.to}-${index}`}
operation={operation}
showNesting={false}
/>
))}

{/* Other root operations not related to current account */}
<TxOperationsGroup
title="Other Contract Calls"
operations={otherRootOperations}
showNesting={false}
/>

{/* Intermediate operations with nesting */}
<TxOperationsGroup
title="Intermediate Operations"
operations={intermediateOperations}
showNesting={true}
/>
</Box>
);
}

TxOperationsList.Loader = function TxOperationsListLoader() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ export function TxAddressDisplay({
name,
image,
isContract,
label,
}: TxAddressDisplayProps) {
const { accounts } = useAccounts();
const account = accounts?.find(
Expand All @@ -27,19 +26,19 @@ export function TxAddressDisplay({
<Box.Flex css={styles.root}>
<Box css={styles.iconCol}>
{image ? (
<Avatar src={image} size={20} name={name || 'Contract'} />
<Avatar src={image} size="sm" name={name || 'Contract'} />
) : (
<Avatar.Generated hash={address} size={20} />
<Avatar.Generated
role="img"
size="sm"
hash={address}
aria-label={address}
/>
)}
</Box>
<Box.Flex gap="$1" css={styles.contentCol}>
{label && (
<Text fontSize="sm" color="gray8">
{label}:
</Text>
)}
<Text as="span" fontSize="sm">
{account?.name || name || shortAddress(address)}
{account?.name || 'Unknown'}
</Text>
{isContract && (
<Box css={styles.badge}>
Expand All @@ -48,6 +47,9 @@ export function TxAddressDisplay({
</Text>
</Box>
)}
<Text fontSize="sm" color="gray8">
{shortAddress(address)}
</Text>
<IconButton
size="xs"
variant="link"
Expand All @@ -70,7 +72,6 @@ const styles = {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: '20px',
flexShrink: 0,
}),
contentCol: cssObj({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,42 @@
import { cssObj } from '@fuel-ui/css';
import { Box, Icon, Text } from '@fuel-ui/react';
import { Avatar, AvatarGenerated, Box, Icon, Text } from '@fuel-ui/react';
import { ReceiptType } from 'fuels';
import { useContractMetadata } from '~/systems/Contract/hooks/useContractMetadata';
import { TxCategory } from '../../../../types';
import type { SimplifiedOperation } from '../../../../types';
import { TxRecipientContractLogo } from '../../../TxRecipientCard/TxRecipientContractLogo';
import { TxAddressDisplay } from './TxAddressDisplay';
import { TxAssetDisplay } from './TxAssetDisplay';
import { TxOperationNesting } from './TxOperationNesting';

type TxOperationProps = {
operation: SimplifiedOperation;
showNesting?: boolean;
};

export function TxOperation({ operation }: TxOperationProps) {
export function TxOperation({
operation,
showNesting = true,
}: TxOperationProps) {
const metadata = operation.metadata;
const amount = metadata?.amount || operation.amount;
const assetId = metadata?.assetId || operation.assetId;
const hasAsset = Boolean(amount && assetId);
const depth = metadata?.depth || 0;
const receiptType = metadata?.receiptType;
const isContract = operation.type === TxCategory.CONTRACTCALL;
const isTransfer = operation.type === TxCategory.SEND;
const _contract = useContractMetadata(operation.from);

const receiptTypeLabel = receiptType ? ReceiptType[receiptType] : null;

if (depth !== 0) return null;
// For transfers, always show with 0 indentation
// For contract calls, only show if root level (depth === 0) unless showNesting is true
if (isContract && !showNesting && depth !== 0) return null;

return (
<Box.Flex css={styles.root}>
<TxOperationNesting depth={depth} />
{isContract && showNesting && <TxOperationNesting depth={depth} />}
<Box.Stack gap="$2" css={styles.contentCol}>
<Box.Flex css={styles.header}>
<Text fontSize="xs" css={styles.typeLabel}>
Expand All @@ -38,19 +48,17 @@ export function TxOperation({ operation }: TxOperationProps) {
</Text>
)}
</Box.Flex>
<TxAddressDisplay address={operation.from} label="From" />
<TxAddressDisplay
address={operation.to}
label={isContract ? 'Contract' : 'To'}
isContract={isContract}
/>
<TxAddressDisplay address={operation.from} />
{isTransfer && (
<Icon icon="CircleArrowDown" css={styles.arrow} size={16} />
)}
<TxAddressDisplay address={operation.to} isContract={isContract} />
{hasAsset && amount && assetId && (
<Box.Stack gap="$0">
{!isContract && <Icon icon="ArrowDown" css={styles.arrow} />}
<TxAssetDisplay
amount={amount.toString()}
assetId={assetId}
showLabel={!isContract}
showLabel={isTransfer}
/>
</Box.Stack>
)}
Expand All @@ -61,23 +69,23 @@ export function TxOperation({ operation }: TxOperationProps) {
</Box.Flex>
);
}
// root level rule is only for contract calls, all transfers should show as well
// we also have the operations not related to the account in a group, and intermediate contract calls
const styles = {
root: cssObj({
display: 'flex',
alignItems: 'flex-start',
gap: '$2',
padding: '$3',
backgroundColor: '$cardBg',
borderRadius: '$md',
padding: '$1',
backgroundColor: '#E0E0E0',
borderRadius: '12px',
width: '100%',
minWidth: 0,
boxSizing: 'border-box',
}),
contentCol: cssObj({
display: 'flex',
backgroundColor: 'white',
boxShadow: '0px 2px 6px -1px #2020201A, 0px 0px 0px 1px #2020201F',
flex: 1,
borderRadius: '8px',
minWidth: 0,
padding: '$3',
}),
header: cssObj({
display: 'flex',
Expand All @@ -99,9 +107,7 @@ const styles = {
fontWeight: '$normal',
}),
arrow: cssObj({
color: '$gray8',
marginTop: '$1',
marginLeft: '$2',
color: '#0D74CE',
}),
functionName: cssObj({
fontSize: '$sm',
Expand Down

0 comments on commit 9b9d6fb

Please sign in to comment.