64 lines
2.2 KiB
TypeScript
64 lines
2.2 KiB
TypeScript
export type EtcDetailView = 'records' | 'bills';
|
|
|
|
export interface EtcDrillContext {
|
|
view: EtcDetailView;
|
|
startDate: string;
|
|
endDate: string;
|
|
search: string;
|
|
page: number;
|
|
}
|
|
|
|
interface LocationParts {
|
|
pathname: string;
|
|
search: string;
|
|
hash: string;
|
|
}
|
|
|
|
const DATE_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
|
|
|
|
function validDate(value: string | null): string {
|
|
if (!value || !DATE_PATTERN.test(value)) return '';
|
|
const [year, month, day] = value.split('-').map(Number);
|
|
const date = new Date(Date.UTC(year, month - 1, day));
|
|
return date.getUTCFullYear() === year
|
|
&& date.getUTCMonth() === month - 1
|
|
&& date.getUTCDate() === day
|
|
? value
|
|
: '';
|
|
}
|
|
|
|
function validPage(value: string | null): number {
|
|
if (!value || !/^\d+$/.test(value)) return 1;
|
|
const parsed = Number(value);
|
|
return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : 1;
|
|
}
|
|
|
|
export function parseEtcDrillContext(search: string): EtcDrillContext {
|
|
const params = new URLSearchParams(search);
|
|
const rawSearch = params.get('etcSearch')?.trim() ?? '';
|
|
const firstDate = validDate(params.get('etcStart'));
|
|
const secondDate = validDate(params.get('etcEnd'));
|
|
const startDate = firstDate && secondDate && firstDate > secondDate ? secondDate : firstDate;
|
|
const endDate = firstDate && secondDate && firstDate > secondDate ? firstDate : secondDate;
|
|
return {
|
|
view: params.get('etcView') === 'bills' ? 'bills' : 'records',
|
|
startDate,
|
|
endDate,
|
|
search: rawSearch.length <= 128 ? rawSearch : '',
|
|
page: validPage(params.get('etcPage')),
|
|
};
|
|
}
|
|
|
|
export function buildEtcDrillUrl(location: LocationParts, context: EtcDrillContext): string {
|
|
const params = new URLSearchParams(location.search);
|
|
for (const key of ['etcView', 'etcStart', 'etcEnd', 'etcSearch', 'etcPage']) params.delete(key);
|
|
params.set('etcView', context.view);
|
|
if (context.startDate) params.set('etcStart', context.startDate);
|
|
if (context.endDate) params.set('etcEnd', context.endDate);
|
|
const search = context.search.trim();
|
|
if (search && search.length <= 128) params.set('etcSearch', search);
|
|
if (context.page > 1) params.set('etcPage', String(context.page));
|
|
const query = params.toString();
|
|
return `${location.pathname}${query ? `?${query}` : ''}${location.hash}`;
|
|
}
|