Add frontend/modules/loyalty with types, API client, design system, feature pages and thin App Router routes under app/loyalty/. BFF proxy at app/api/loyalty/. Include loyalty frontend docs. Co-authored-by: Cursor <cursoragent@cursor.com>
43 lines
1.1 KiB
TypeScript
43 lines
1.1 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect } from "react";
|
|
import { useRouter } from "next/navigation";
|
|
import { LOYALTY_SHORTCUTS } from "@/modules/loyalty/constants/portals";
|
|
|
|
export function useLoyaltyKeyboardShortcuts() {
|
|
const router = useRouter();
|
|
|
|
useEffect(() => {
|
|
let pending: string | null = null;
|
|
let timer: ReturnType<typeof setTimeout>;
|
|
|
|
const onKeyDown = (e: KeyboardEvent) => {
|
|
if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) return;
|
|
const key = e.key.toLowerCase();
|
|
if (pending === "g") {
|
|
const chord = `g ${key}`;
|
|
const href = LOYALTY_SHORTCUTS[chord];
|
|
if (href) {
|
|
e.preventDefault();
|
|
router.push(href);
|
|
}
|
|
pending = null;
|
|
return;
|
|
}
|
|
if (key === "g") {
|
|
pending = "g";
|
|
clearTimeout(timer);
|
|
timer = setTimeout(() => {
|
|
pending = null;
|
|
}, 800);
|
|
}
|
|
};
|
|
|
|
window.addEventListener("keydown", onKeyDown);
|
|
return () => {
|
|
window.removeEventListener("keydown", onKeyDown);
|
|
clearTimeout(timer);
|
|
};
|
|
}, [router]);
|
|
}
|