import type { ReactElement } from 'react' import { useData, type PanelRef } from '@jaspers-ai/sdk' import { answers, calendarOutput, readCalendarRows, shiftDay, today, type CallsState } from './calls' import { cleanError, localTime, longDate, Publish, TickerField } from './shared' // The calls held on one day. A row opens its call in this panel and keeps the day, so the way back // lands on the same calendar. export function Calendar({ panel, state, write }: { panel: PanelRef; state: CallsState; write: (next: CallsState) => void }): ReactElement { const now = today(new Date()) const day = state.date ?? now const run = useData('earningscall/calendar', { date: day }) // Until the new day is in, the run still holds the last day's calls. const fresh = run.data !== undefined && answers(run.meta, { date: day }) const rows = fresh ? readCalendarRows(run.data) : [] const error = run.error ? cleanError(run.error) : null const go = (date: string | null): void => write({ ...state, date }) return (
{(fresh || error) && }
{longDate(day)} {day !== now && ( )} {run.loading && loading…} write({ ...state, symbol, exchange: null, year: null, quarter: null })} />
{error ? (

{error}

) : !fresh ? (

Loading…

) : rows.length === 0 ? (

No earnings calls on this day.

) : ( {rows.map((row) => ( write({ ...state, symbol: row.symbol, exchange: row.exchange, year: row.year, quarter: row.quarter, date: day })} > ))}
Time Ticker Company Call Transcript
{localTime(row.date)} {row.symbol} {row.company} Q{row.quarter} {row.year} {row.ready ? 'Ready' : 'Not yet'}
)}
) }