/* FinPulse — IPO tracker (Indian IPOs + optional Finnhub global calendar). */
const IPO_TABS = [
{ key: 'open', label: 'Open' },
{ key: 'upcoming', label: 'Upcoming' },
{ key: 'listed', label: 'Listed' },
];
function IpoCard({ ipo }) {
const cur = ipo.currency || '₹';
const isListed = ipo.status === 'listed';
const isOpen = ipo.status === 'open';
return (
{ipo.initials}
{ipo.name}
{ipo.sector}{ipo.symbol ? ' · ' + ipo.symbol : ''}
{ipo.live &&
}
{isOpen &&
● Open}
{ipo.status === 'upcoming' &&
Upcoming}
{isListed && ipo.listGain != null &&
= 0 ? 'gain' : 'loss'}`}>{ipo.listGain >= 0 ? '▲' : '▼'} {fmt.pct(ipo.listGain)}}
Price Band
{cur}{ipo.bandLo}{ipo.bandHi !== ipo.bandLo ? '–' + cur + ipo.bandHi : ''}
Issue Size
{ipo.issueLabel || (cur + ipo.issueCr + ' Cr')}
{isOpen && ipo.subscription != null &&
Subscribed
{ipo.subscription}x
}
{isOpen && ipo.gmp != null &&
}
{!isOpen &&
Min. Invest
{cur}{(ipo.bandHi * ipo.lot).toLocaleString('en-IN')}
}
{ipo.note}
{isOpen
?
: }
);
}
function EarningsRow({ e }) {
return (
{e.symbol}
{e.date}{e.hour ? ' · ' + e.hour : ''}
{e.epsEstimate != null &&
EPS est. {e.epsEstimate}
}
{e.quarter != null &&
Q{e.quarter} {e.year || ''}
}
);
}
function IpoScreen() {
const L = useLive();
const [tab, setTab] = useState('open');
const [globalIpos, setGlobalIpos] = useState([]);
const [earnings, setEarnings] = useState([]);
const [view, setView] = useState('ipo');
const [loading, setLoading] = useState(false);
const [err, setErr] = useState('');
async function loadGlobal() {
if (!L.hasKey) return;
setLoading(true); setErr('');
try {
const [ipos, earn] = await Promise.all([
L.market.getIpoCalendar(),
L.market.getEarningsCalendar(2, 0).catch(() => []),
]);
setGlobalIpos(ipos);
setEarnings(earn);
L.refreshRateLimit();
} catch (e) {
setErr(apiErrorMessage(e));
setGlobalIpos([]);
setEarnings([]);
} finally { setLoading(false); }
}
useEffect(() => {
if (L.hasKey) loadGlobal();
}, [L.hasKey]);
const source = globalIpos;
const filtered = source.filter((i) => i.status === tab);
return (
IPO Tracker
{view === 'earnings' ? 'Earnings calendar via Finnhub' : 'IPO calendar via Finnhub'}
{!L.hasKey && (
Connect API} />
)}
{L.hasKey && (
<>
{view === 'ipo' && (
{IPO_TABS.map((t) => (
))}
)}
{err && {err}
}
{loading ? (
) : view === 'earnings' ? (
earnings.length ? (
{earnings.map((e) => )}
) : (
)
) : filtered.length ? (
{filtered.map((ipo) => )}
) : (
)}
>
)}
);
}
Object.assign(window, { IpoScreen });