import { AnimatePresence, motion } from 'framer-motion'
import { Fragment, useEffect, useState } from 'react'
import { Database } from 'icons'
import { cn } from 'ui'
// Add overall icon dimension controls
const ICON_WIDTH = 48
const ICON_HEIGHT = 96
// Add these to your existing constants section
const LINE_WIDTH = 2 // SVG container width
const LINE_STROKE_WIDTH = 1 // Width of the actual line
const LINE_OFFSET = 1 // For centering the line in container
const FlowingLine = ({
x,
y1,
y2,
isActive,
}: {
x: number
y1: number
y2: number
isActive: boolean
}) => {
return (
{isActive && (
)}
)
}
const TopRect = ({ isActive }: { isActive: boolean }) => (
)
const BottomRect = ({ isActive }: { isActive: boolean }) => (
)
// Update existing constants to use these dimensions
const TOP_LINE_START = ICON_HEIGHT * 0.18 // 20% from top
const TOP_LINE_END = ICON_HEIGHT * 0.28 // 48% from top
const BOTTOM_LINE_START = ICON_HEIGHT * 0.4 // 65% from top
const BOTTOM_LINE_END = ICON_HEIGHT * 0.59 // 80% from top
// Update rect positions and dimensions
const TOP_RECT_Y = ICON_HEIGHT * 0.32 // 55% from top
const BOTTOM_RECT_Y = ICON_HEIGHT * 0.64 // 85% from top
const RECT_X = ICON_WIDTH * 0.17 // ~17% from left
const RECT_WIDTH = ICON_WIDTH * 0.67 // ~67% of total width
// Update circle positions
const CIRCLE_Y = ICON_HEIGHT * 0.13 // 13% from top
const CIRCLE_SPACING = ICON_WIDTH * 0.25 // 25% of width
const CIRCLE_START_X = ICON_WIDTH * 0.25 // 25% from left
const CIRCLE_RADIUS = ICON_WIDTH * 0.055 // ~3.8% of width
// Static circle for SessionIcon
const ConnectionDot = ({ index, isActive }: { index: number; isActive: boolean }) => (
)
export const TransactionIcon = () => {
const [dots, setDots] = useState([false, false, false])
const [lines, setLines] = useState([false, false, false])
const [bottomLineActive, setBottomLineActive] = useState(false)
useEffect(() => {
// Watch lines state and update bottomLineActive accordingly
setBottomLineActive(lines.some(Boolean))
}, [lines])
useEffect(() => {
const animateDot = (index: number) => {
// Clear previous state
setDots((prev) => {
const newState = [...prev]
newState[index] = false
return newState
})
setLines((prev) => {
const newState = [...prev]
newState[index] = false
return newState
})
// Step 1: Animate dot in
setTimeout(() => {
setDots((prev) => {
const newState = [...prev]
newState[index] = true
return newState
})
}, 0)
// Step 2: After dot is in, wait, then show line
setTimeout(() => {
setLines((prev) => {
const newState = [...prev]
newState[index] = true
return newState
})
}, 400) // Wait 400ms after dot appears before showing line
// Step 3: Clear everything
setTimeout(() => {
setDots((prev) => {
const newState = [...prev]
newState[index] = false
return newState
})
setLines((prev) => {
const newState = [...prev]
newState[index] = false
return newState
})
}, 1000) // Total animation duration
}
// Initial staggered animation
setTimeout(() => animateDot(0), 0)
setTimeout(() => animateDot(1), 200)
setTimeout(() => animateDot(2), 400)
// Set up intervals for continuous animation
const intervals = [0, 1, 2].map((index) =>
setInterval(() => animateDot(index), 3000 + index * 200)
)
return () => intervals.forEach(clearInterval)
}, [])
return (
{[0, 1, 2].map((index) => (
))}
)
}
export const SessionIcon = () => {
const [topLineStates, setTopLineStates] = useState([false, false, false])
const [bottomLineStates, setBottomLineStates] = useState([false, false, false])
useEffect(() => {
// Function to animate a single dot
const animateDot = (index: number) => {
setTopLineStates((prev) => {
const newState = [...prev]
newState[index] = true
return newState
})
setTimeout(() => {
setBottomLineStates((prev) => {
const newState = [...prev]
newState[index] = true
return newState
})
}, 300)
setTimeout(() => {
setTopLineStates((prev) => {
const newState = [...prev]
newState[index] = false
return newState
})
setBottomLineStates((prev) => {
const newState = [...prev]
newState[index] = false
return newState
})
}, 5000)
}
// Start initial animations immediately with slight delays
setTimeout(() => animateDot(0), 100)
setTimeout(() => animateDot(1), 1500)
setTimeout(() => animateDot(2), 3000)
// Set up intervals for subsequent animations
const intervals = [0, 1, 2].map((index) =>
setInterval(() => animateDot(index), Math.random() * 3000 + 8000)
)
return () => intervals.forEach(clearInterval)
}, [])
return (
{[0, 1, 2].map((index) => (
))}
)
}
export const DirectConnectionIcon = () => {
const [dots, setDots] = useState([false, false, false])
const [lines, setLines] = useState([false, false, false])
useEffect(() => {
// Function to animate a single dot
const animateDot = (index: number) => {
setDots((prev) => {
const newState = [...prev]
newState[index] = true
return newState
})
setLines((prev) => {
const newState = [...prev]
newState[index] = true
return newState
})
// Clear after 2.5s
setTimeout(() => {
setDots((prev) => {
const newState = [...prev]
newState[index] = false
return newState
})
setLines((prev) => {
const newState = [...prev]
newState[index] = false
return newState
})
}, 2500)
}
// Initial staggered animation
// Start initial animations immediately with slight delays
setTimeout(() => animateDot(0), 100)
setTimeout(() => animateDot(1), 1500)
setTimeout(() => animateDot(2), 3000)
// Set up intervals for continuous animation
const intervals = [0, 1, 2].map((index) =>
setInterval(() => animateDot(index), Math.random() * 3000 + 8000)
)
return () => intervals.forEach(clearInterval)
}, [])
return (
{[0, 1, 2].map((index) => (
))}
)
}