Jaspers Hub

jaspers / earningscall

pluginOfficialReviewed★ 0↓ 6

EarningsCall Transcripts & Calendar: Shows a company's earnings call transcripts and the daily earnings calendar from EarningsCall.biz in a single panel view.

1.4 KB
1import { useCallback, type ReactElement } from 'react'
2import { useBridge, useData, type PanelRef } from '@jaspers-ai/sdk'
3import { Calendar } from './Calendar'
4import { CallPage } from './Call'
5import { readState, stored, type CallsState } from './calls'
6import './styles.css'
7
8// Earnings calls in one panel: a company's call when the state names a ticker, the calendar of a day
9// when it does not. One view rather than two, because a row of the calendar opens its call here and a
10// view cannot place another. The state is read whole and written whole, so opening another company
11// leaves no quarter of the last one behind.
12
13export function CallsView({ panel }: { panel: PanelRef }): ReactElement {
14 const bridge = useBridge()
15 const raw = useData(`workspaces/${panel.workspaceId}/panels/${panel.id}/state`)
16 const write = useCallback(
17 (next: CallsState) => void bridge.setState({ id: panel.id, workspaceId: panel.workspaceId }, [], stored(next)),
18 [bridge, panel.id, panel.workspaceId],
19 )
20 // The state arrives a round trip after the frame mounts; nothing runs until it is here.
21 if (raw === undefined) {
22 return (
23 <div className="ec-root">
24 <div className="ec-bar">
25 <span className="ec-muted">Loading…</span>
26 </div>
27 </div>
28 )
29 }
30 const state = readState(raw)
31 return state.symbol ? <CallPage panel={panel} state={state} write={write} /> : <Calendar panel={panel} state={state} write={write} />
32}