Initial commit: thbd-portal, duplicated from elmi-portal

Rebranded for Thunderbird Portal (THBD): numbering prefix EL->TH, all
"ELMI"/"ЭЛМИ" UI strings genericized, ELMI's real contract templates and
company legal/bank details removed (not applicable to this company), fresh
VAPID keypair and encryption key, fresh single-migration schema history.
Same architecture as elmi-portal: Web Push notifications, unread-chat app
badge, cookie-session auth.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gh2UXUQUVBWroWEnn1FLFG
This commit is contained in:
ogrechkoandClaude Sonnet 5 committed 2026-08-31 16:33:30 +00:00
commit 579528edf7
197 files changed
+25022

No files matched your search

+25
View File
@@ -0,0 +1,25 @@
"use client";
import { useEffect } from "react";
const INTERVAL_MS = 20_000;
/** Держит lastSeenAt свежим, пока вкладка открыта и видима — "онлайн" на клиенте вычисляется как lastSeenAt моложе ~30с. */
export function PresenceHeartbeat() {
useEffect(() => {
function ping() {
if (document.visibilityState === "visible") {
fetch("/api/presence/heartbeat", { method: "POST" }).catch(() => {});
}
}
ping();
const interval = setInterval(ping, INTERVAL_MS);
document.addEventListener("visibilitychange", ping);
return () => {
clearInterval(interval);
document.removeEventListener("visibilitychange", ping);
};
}, []);
return null;
}