import type { InertiaLinkProps } from '@inertiajs/react'; import { usePage } from '@inertiajs/react'; import { toUrl } from '@/lib/utils'; export type IsCurrentUrlFn = ( urlToCheck: NonNullable, currentUrl?: string, startsWith?: boolean, ) => boolean; export type IsCurrentOrParentUrlFn = ( urlToCheck: NonNullable, currentUrl?: string, ) => boolean; export type WhenCurrentUrlFn = ( urlToCheck: NonNullable, ifTrue: TIfTrue, ifFalse?: TIfFalse, ) => TIfTrue | TIfFalse; export type UseCurrentUrlReturn = { currentUrl: string; isCurrentUrl: IsCurrentUrlFn; isCurrentOrParentUrl: IsCurrentOrParentUrlFn; whenCurrentUrl: WhenCurrentUrlFn; }; export function useCurrentUrl(): UseCurrentUrlReturn { const page = usePage(); const currentUrlPath = new URL( page.url, typeof window !== 'undefined' ? window.location.origin : 'http://localhost', ).pathname; const isCurrentUrl: IsCurrentUrlFn = ( urlToCheck: NonNullable, currentUrl?: string, startsWith: boolean = false, ) => { const urlString = toUrl(urlToCheck); const currentPath = currentUrl ?? currentUrlPath; const clean = (p: string) => { if (!p) return '/'; // Remove query and hash, then trailing slash let path = p.split('?')[0].split('#')[0]; if (path.startsWith('http')) { try { path = new URL(path).pathname; } catch { // Ignore } } return path.replace(/\/+$/, '') || '/'; }; const normCurrent = clean(currentPath); const normCheck = clean(urlString); if (startsWith) { if (normCheck === '/') { return normCurrent === '/'; } return normCurrent.startsWith(normCheck); } return normCurrent === normCheck; }; const isCurrentOrParentUrl: IsCurrentOrParentUrlFn = ( urlToCheck: NonNullable, currentUrl?: string, ) => { return isCurrentUrl(urlToCheck, currentUrl, true); }; const whenCurrentUrl: WhenCurrentUrlFn = ( urlToCheck: NonNullable, ifTrue: TIfTrue, ifFalse: TIfFalse = null as TIfFalse, ): TIfTrue | TIfFalse => { return isCurrentUrl(urlToCheck) ? ifTrue : ifFalse; }; return { currentUrl: currentUrlPath, isCurrentUrl, isCurrentOrParentUrl, whenCurrentUrl, }; }