'use client' import { useState, useRef, useEffect, useId } from 'react' import { scaleLinear } from 'd3-scale' import { subMonths, format } from 'date-fns' import { useResizeObserver } from 'usehooks-ts' import { useAIState } from '@aigxion/isdk/rsc' interface Stock { symbol: string price: number delta: number } export function Stock({ props: { symbol, price, delta } }: { props: Stock }) { const [aiState, setAIState] = useAIState() const id = useId() const [priceAtTime, setPriceAtTime] = useState({ time: '00:00', value: price.toFixed(2), x: 0 }) const [startHighlight, setStartHighlight] = useState(0) const [endHighlight, setEndHighlight] = useState(0) const chartRef = useRef(null) const { width = 0 } = useResizeObserver({ ref: chartRef, box: 'border-box' }) const xToDate = scaleLinear( [0, width], [subMonths(new Date(), 6), new Date()] ) const xToValue = scaleLinear( [0, width], [price - price / 2, price + price / 2] ) useEffect(() => { if (startHighlight && endHighlight) { const message = { id, role: 'system' as const, content: `[User has highlighted dates between between ${format( xToDate(startHighlight), 'd LLL' )} and ${format(xToDate(endHighlight), 'd LLL, yyyy')}` } if (aiState.messages[aiState.messages.length - 1]?.id === id) { setAIState({ ...aiState, messages: [...aiState.messages.slice(0, -1), message] }) } else { setAIState({ ...aiState, messages: [...aiState.messages, message] }) } } }, [startHighlight, endHighlight]) return (
{`${delta > 0 ? '+' : ''}${((delta / price) * 100).toFixed(2)}% ${delta > 0 ? '↑' : '↓' }`}
{symbol}
${price}
Closed: Feb 27, 4:59 PM EST
{ if (chartRef.current) { const { clientX } = event const { left } = chartRef.current.getBoundingClientRect() setStartHighlight(clientX - left) setEndHighlight(0) setPriceAtTime({ time: format(xToDate(clientX), 'dd LLL yy'), value: xToValue(clientX).toFixed(2), x: clientX - left }) } }} onPointerUp={event => { if (chartRef.current) { const { clientX } = event const { left } = chartRef.current.getBoundingClientRect() setEndHighlight(clientX - left) } }} onPointerMove={event => { if (chartRef.current) { const { clientX } = event const { left } = chartRef.current.getBoundingClientRect() setPriceAtTime({ time: format(xToDate(clientX), 'dd LLL yy'), value: xToValue(clientX).toFixed(2), x: clientX - left }) } }} onPointerLeave={() => { setPriceAtTime({ time: '00:00', value: price.toFixed(2), x: 0 }) }} ref={chartRef} > {priceAtTime.x > 0 ? (
${priceAtTime.value}
{priceAtTime.time}
) : null} {startHighlight ? (
) : null}
) }