nexus/ui/src/api/push.ts
Nexus Dev 862cf7fef3 feat(26-04): create push API client, usePushNotifications hook, and NotificationPermissionPrompt
- Add ui/src/api/push.ts with getVapidPublicKey, subscribe, unsubscribe methods
- Add ui/src/hooks/usePushNotifications.ts with SW pushManager subscription flow
- urlBase64ToUint8Array utility converts VAPID key for applicationServerKey
- NotificationPermissionPrompt shows after 3rd agent response (engagement gate)
- Checks nexus.notifPromptDismissed localStorage key for dismiss state
- ChatPanel tracks agentResponseCount from assistant messages and renders prompt
- Install idb package (missing dependency from plan 26-00 prerequisites)
2026-04-04 03:55:48 +00:00

28 lines
933 B
TypeScript

import { api } from "./client";
export const pushApi = {
getVapidPublicKey(): Promise<{ publicKey: string | null }> {
return api.get<{ publicKey: string | null }>("/push/vapid-public-key");
},
subscribe(
subscription: ReturnType<PushSubscription["toJSON"]>,
meta?: { userId?: string; companyId?: string; deviceLabel?: string },
): Promise<void> {
return api.post<void>("/push/subscribe", { ...subscription, ...meta });
},
unsubscribe(endpoint: string): Promise<void> {
// DELETE with body requires a manual fetch since api.delete() doesn't support body
return fetch("/api/push/subscribe", {
method: "DELETE",
headers: { "Content-Type": "application/json" },
credentials: "include",
body: JSON.stringify({ endpoint }),
}).then((res) => {
if (!res.ok && res.status !== 204) {
throw new Error(`Unsubscribe failed: ${res.status}`);
}
});
},
};