Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/agentic-chat/src/components/Portfolio/ActivityList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export function ActivityList() {

const activities = useMemo(() => {
return transactions
.filter(tx => tx.toolType === 'swap' || tx.toolType === 'send')
.filter(tx => tx.toolType === 'swap' || tx.toolType === 'send' || tx.toolType === 'limit_order')
.filter(tx => !tx.phases.includes('error'))
.map(tx => normalizeToActivityItem(tx))
.filter((item): item is ActivityItem => item !== null)
Expand All @@ -23,7 +23,7 @@ export function ActivityList() {
return (
<div className="flex flex-col items-center justify-center py-12 text-center">
<div className="text-muted-foreground">No activity yet</div>
<div className="text-sm text-muted-foreground mt-1">Your swap and send transactions will appear here</div>
<div className="text-sm text-muted-foreground mt-1">Your swaps, sends, and limit orders will appear here</div>
</div>
)
}
Expand Down
147 changes: 0 additions & 147 deletions apps/agentic-chat/src/components/Portfolio/ActivityRow.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { formatDistanceToNow } from 'date-fns'
import { ArrowRightLeft, Send, Timer } from 'lucide-react'

import { DrawerListItem } from '@/components/ui/DrawerListItem'
import { ToolCard } from '@/components/ui/ToolCard'
import { stopPropagationHandler } from '@/lib/eventHandlers'
import { getExplorerUrl } from '@/lib/explorers'
import { formatCryptoAmount } from '@/lib/number'
import { truncateAddress } from '@/lib/utils'
import type { ActivityItem } from '@/types/activity'

import { LimitOrderDetails } from './components/LimitOrderDetails'
import { SendDetails } from './components/SendDetails'
import { SwapDetails } from './components/SwapDetails'

type ActivityRowProps = {
activity: ActivityItem
}

const ACTIVITY_ICONS = {
swap: ArrowRightLeft,
send: Send,
limit_order: Timer,
}

function formatActivityTitle(activity: ActivityItem): string {
switch (activity.type) {
case 'swap':
return `Swapped ${formatCryptoAmount(activity.details.sellAsset.amount, { symbol: activity.details.sellAsset.symbol })} to ${formatCryptoAmount(activity.details.buyAsset.amount, { symbol: activity.details.buyAsset.symbol })}`
case 'send':
return `Sent ${formatCryptoAmount(activity.details.asset.amount, { symbol: activity.details.asset.symbol })}`
case 'limit_order':
return `Limit order: ${formatCryptoAmount(activity.details.sellAsset.amount, { symbol: activity.details.sellAsset.symbol })} → ${formatCryptoAmount(activity.details.buyAsset.estimatedAmount, { symbol: activity.details.buyAsset.symbol })}`
}
}

function ActivityDetails({ activity }: { activity: ActivityItem }) {
const txHash = activity.type !== 'limit_order' ? activity.txHash : undefined
const explorerUrl = txHash ? getExplorerUrl(activity.network, txHash) : undefined

return (
<ToolCard.Details>
{explorerUrl && txHash && (
<ToolCard.DetailItem
label="TX ID"
value={
<a
href={explorerUrl}
target="_blank"
rel="noopener noreferrer"
className="font-mono text-sm text-blue-500 hover:text-blue-400 transition-colors"
onClick={stopPropagationHandler}
>
{truncateAddress(txHash, 8, 6)}
</a>
}
/>
)}
{activity.type === 'swap' && <SwapDetails details={activity.details} network={activity.network} />}
{activity.type === 'send' && <SendDetails details={activity.details} />}
{activity.type === 'limit_order' && <LimitOrderDetails details={activity.details} />}
</ToolCard.Details>
)
}

export function ActivityRow({ activity }: ActivityRowProps) {
const Icon = ACTIVITY_ICONS[activity.type]

return (
<DrawerListItem expandedChildren={<ActivityDetails activity={activity} />}>
<div className="flex-shrink-0">
<div className="w-10 h-10 rounded-full bg-primary/10 flex items-center justify-center">
<Icon className="w-5 h-5 text-primary" />
</div>
</div>

<div className="flex-1 min-w-0">
<div className="font-medium text-sm text-foreground truncate">{formatActivityTitle(activity)}</div>
<div className="text-xs text-muted-foreground">
{formatDistanceToNow(activity.timestamp, { addSuffix: true })}
</div>
</div>
</DrawerListItem>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Amount } from '@/components/ui/Amount'
import { ToolCard } from '@/components/ui/ToolCard'
import { stopPropagationHandler } from '@/lib/eventHandlers'
import type { LimitOrderActivityDetails } from '@/types/activity'

type LimitOrderDetailsProps = {
details: LimitOrderActivityDetails
}

export function LimitOrderDetails({ details }: LimitOrderDetailsProps) {
return (
<>
<ToolCard.DetailItem
label="Sell"
value={<Amount.Crypto value={details.sellAsset.amount} symbol={details.sellAsset.symbol} />}
/>
<ToolCard.DetailItem
label="Buy (estimated)"
value={<Amount.Crypto value={details.buyAsset.estimatedAmount} symbol={details.buyAsset.symbol} />}
/>
<ToolCard.DetailItem
label="Limit Price"
value={`1 ${details.sellAsset.symbol} = ${details.limitPrice} ${details.buyAsset.symbol}`}
/>
<ToolCard.DetailItem label="Expires" value={new Date(details.expiresAt).toLocaleString()} />
<ToolCard.DetailItem label="Provider" value={details.provider.toUpperCase()} />
Comment thread
premiumjibles marked this conversation as resolved.
<ToolCard.DetailItem
label="Track Order"
value={
<a
href={details.trackingUrl}
target="_blank"
rel="noopener noreferrer"
className="text-sm text-blue-500 hover:text-blue-400 transition-colors"
onClick={stopPropagationHandler}
>
View on CoW Explorer
</a>
}
/>
</>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Amount } from '@/components/ui/Amount'
import { ToolCard } from '@/components/ui/ToolCard'
import { truncateAddress } from '@/lib/utils'
import type { SendActivityDetails } from '@/types/activity'

type SendDetailsProps = {
details: SendActivityDetails
}

export function SendDetails({ details }: SendDetailsProps) {
return (
<>
<ToolCard.DetailItem
label="Amount"
value={<Amount.Crypto value={details.asset.amount} symbol={details.asset.symbol} />}
/>
<ToolCard.DetailItem label="From" value={truncateAddress(details.from)} />
<ToolCard.DetailItem label="To" value={truncateAddress(details.to)} />
{details.fee && (
<ToolCard.DetailItem label="Fee" value={<Amount.Crypto value={details.fee} symbol={details.feeSymbol} />} />
)}
</>
)
}
Comment thread
premiumjibles marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { Amount } from '@/components/ui/Amount'
import { ToolCard } from '@/components/ui/ToolCard'
import { stopPropagationHandler } from '@/lib/eventHandlers'
import { getExplorerUrl } from '@/lib/explorers'
import { truncateAddress } from '@/lib/utils'
import type { SwapActivityDetails } from '@/types/activity'

type SwapDetailsProps = {
details: SwapActivityDetails
network: string
}

export function SwapDetails({ details, network }: SwapDetailsProps) {
const approvalExplorerUrl = details.approval ? getExplorerUrl(network, details.approval.txHash) : undefined

return (
<>
<ToolCard.DetailItem
label="Sold"
value={
<Amount.Crypto
value={details.sellAsset.amount}
symbol={details.sellAsset.symbol}
suffix={
<>
(<Amount.Fiat value={details.sellAsset.valueUSD} />)
</>
}
/>
}
/>
<ToolCard.DetailItem
label="Received"
value={
<Amount.Crypto
value={details.buyAsset.amount}
symbol={details.buyAsset.symbol}
suffix={
<>
(<Amount.Fiat value={details.buyAsset.valueUSD} />)
</>
}
/>
}
/>
<ToolCard.DetailItem label="DEX" value={details.dex} />
{details.fee && <ToolCard.DetailItem label="Fee" value={<Amount.Fiat value={details.fee} />} />}
{details.approval && approvalExplorerUrl && (
<ToolCard.DetailItem
label="Approval TX"
value={
<a
href={approvalExplorerUrl}
target="_blank"
rel="noopener noreferrer"
className="font-mono text-sm text-blue-500 hover:text-blue-400 transition-colors"
onClick={stopPropagationHandler}
>
{truncateAddress(details.approval.txHash, 8, 6)}
</a>
}
/>
)}
</>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { ActivityRow } from './ActivityRow'
Loading
Loading