fix: wire data adapters, fix OptionsAdapter v3, build Research pages

- Fix OptionsAdapter for yahoo-finance2 v3 API ({ date: expiry } instead of positional arg)
- Fix institutional.flow and insiderStream endpoints to query correct DB tables
- Fix anonymous user INSERT (pw_hash column, not password_hash)
- Create secDataFetcher module for 13F/Form 4 data population
- Add institutional and marketOutlook endpoints to frontend trpc client
- Build out Chart Lab, Institutional, Market Outlook pages with real components
- Add focus-visible rings, aria-labels, hex tokens, shape icons across all panels
- Integrate EmotionLogger, MobileTabNav, useKeyboardShortcuts
- Add localStorage persistence for emotion logs
- Normalize spacing, type scale, hover effects across all components
This commit is contained in:
Investor Flow Build
2026-07-05 08:50:12 -04:00
parent 1e818c0881
commit 55f07e6b42
27 changed files with 2331 additions and 555 deletions
+39
View File
@@ -0,0 +1,39 @@
"use client";
import { useEffect } from "react";
interface KeyboardShortcut {
key: string;
ctrl?: boolean;
shift?: boolean;
alt?: boolean;
handler: (e: KeyboardEvent) => void;
// Only fire when no input/modal is focused
when?: () => boolean;
}
/**
* Shared keyboard shortcut hook.
* Registers shortcuts at the LayoutShell level (closest to root).
* Uses keydown events with preventDefault only when needed.
*/
export function useKeyboardShortcuts(shortcuts: KeyboardShortcut[]) {
useEffect(() => {
const handler = (e: KeyboardEvent) => {
for (const shortcut of shortcuts) {
const matchesKey = e.key === shortcut.key;
const matchesCtrl = shortcut.ctrl ? e.ctrlKey || e.metaKey : !e.ctrlKey && !e.metaKey;
const matchesShift = shortcut.shift ? e.shiftKey : !e.shiftKey;
const matchesAlt = shortcut.alt ? e.altKey : !e.altKey;
if (matchesKey && matchesCtrl && matchesShift && matchesAlt) {
if (shortcut.when && !shortcut.when()) continue;
e.preventDefault();
shortcut.handler(e);
}
}
};
window.addEventListener("keydown", handler);
return () => window.removeEventListener("keydown", handler);
}, [shortcuts]);
}