upgrade navigation and route prefetch responsiveness
This commit is contained in:
11
lib/query/keys.ts
Normal file
11
lib/query/keys.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
export const queryKeys = {
|
||||
companyAnalysis: (ticker: string) => ['analysis', ticker] as const,
|
||||
filings: (ticker: string | null, limit: number) => ['filings', ticker ?? '', limit] as const,
|
||||
report: (accessionNumber: string) => ['report', accessionNumber] as const,
|
||||
watchlist: () => ['watchlist'] as const,
|
||||
holdings: () => ['portfolio', 'holdings'] as const,
|
||||
portfolioSummary: () => ['portfolio', 'summary'] as const,
|
||||
latestPortfolioInsight: () => ['portfolio', 'insights', 'latest'] as const,
|
||||
task: (taskId: string) => ['tasks', 'detail', taskId] as const,
|
||||
recentTasks: (limit: number) => ['tasks', 'recent', limit] as const
|
||||
};
|
||||
92
lib/query/options.ts
Normal file
92
lib/query/options.ts
Normal file
@@ -0,0 +1,92 @@
|
||||
import { queryOptions } from '@tanstack/react-query';
|
||||
import {
|
||||
getCompanyAiReport,
|
||||
getCompanyAnalysis,
|
||||
getLatestPortfolioInsight,
|
||||
getPortfolioSummary,
|
||||
getTask,
|
||||
listFilings,
|
||||
listHoldings,
|
||||
listRecentTasks,
|
||||
listWatchlist
|
||||
} from '@/lib/api';
|
||||
import { queryKeys } from '@/lib/query/keys';
|
||||
|
||||
export function companyAnalysisQueryOptions(ticker: string) {
|
||||
const normalizedTicker = ticker.trim().toUpperCase();
|
||||
|
||||
return queryOptions({
|
||||
queryKey: queryKeys.companyAnalysis(normalizedTicker),
|
||||
queryFn: () => getCompanyAnalysis(normalizedTicker),
|
||||
staleTime: 120_000
|
||||
});
|
||||
}
|
||||
|
||||
export function filingsQueryOptions(input: { ticker?: string; limit?: number } = {}) {
|
||||
const normalizedTicker = input.ticker?.trim().toUpperCase() ?? null;
|
||||
const limit = input.limit ?? 120;
|
||||
|
||||
return queryOptions({
|
||||
queryKey: queryKeys.filings(normalizedTicker, limit),
|
||||
queryFn: () => listFilings({ ticker: normalizedTicker ?? undefined, limit }),
|
||||
staleTime: 60_000
|
||||
});
|
||||
}
|
||||
|
||||
export function aiReportQueryOptions(accessionNumber: string) {
|
||||
const normalizedAccession = accessionNumber.trim();
|
||||
|
||||
return queryOptions({
|
||||
queryKey: queryKeys.report(normalizedAccession),
|
||||
queryFn: () => getCompanyAiReport(normalizedAccession),
|
||||
staleTime: 300_000
|
||||
});
|
||||
}
|
||||
|
||||
export function watchlistQueryOptions() {
|
||||
return queryOptions({
|
||||
queryKey: queryKeys.watchlist(),
|
||||
queryFn: () => listWatchlist(),
|
||||
staleTime: 30_000
|
||||
});
|
||||
}
|
||||
|
||||
export function holdingsQueryOptions() {
|
||||
return queryOptions({
|
||||
queryKey: queryKeys.holdings(),
|
||||
queryFn: () => listHoldings(),
|
||||
staleTime: 30_000
|
||||
});
|
||||
}
|
||||
|
||||
export function portfolioSummaryQueryOptions() {
|
||||
return queryOptions({
|
||||
queryKey: queryKeys.portfolioSummary(),
|
||||
queryFn: () => getPortfolioSummary(),
|
||||
staleTime: 30_000
|
||||
});
|
||||
}
|
||||
|
||||
export function latestPortfolioInsightQueryOptions() {
|
||||
return queryOptions({
|
||||
queryKey: queryKeys.latestPortfolioInsight(),
|
||||
queryFn: () => getLatestPortfolioInsight(),
|
||||
staleTime: 30_000
|
||||
});
|
||||
}
|
||||
|
||||
export function taskQueryOptions(taskId: string) {
|
||||
return queryOptions({
|
||||
queryKey: queryKeys.task(taskId),
|
||||
queryFn: () => getTask(taskId),
|
||||
staleTime: 5_000
|
||||
});
|
||||
}
|
||||
|
||||
export function recentTasksQueryOptions(limit = 20) {
|
||||
return queryOptions({
|
||||
queryKey: queryKeys.recentTasks(limit),
|
||||
queryFn: () => listRecentTasks(limit),
|
||||
staleTime: 5_000
|
||||
});
|
||||
}
|
||||
18
lib/types.ts
18
lib/types.ts
@@ -158,3 +158,21 @@ export type CompanyAnalysis = {
|
||||
filings: Filing[];
|
||||
aiReports: CompanyAiReport[];
|
||||
};
|
||||
|
||||
export type NavGroup = 'overview' | 'research' | 'portfolio';
|
||||
export type NavMatchMode = 'exact' | 'prefix';
|
||||
|
||||
export type NavItem = {
|
||||
id: string;
|
||||
href: string;
|
||||
label: string;
|
||||
group: NavGroup;
|
||||
matchMode: NavMatchMode;
|
||||
preserveTicker?: boolean;
|
||||
mobilePrimary?: boolean;
|
||||
};
|
||||
|
||||
export type ActiveContext = {
|
||||
pathname: string;
|
||||
activeTicker: string | null;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user