feat: enhance admin and contact components with new functionality
- Updated `AdminPage` to conditionally display duty reassignment instructions based on visible groups, improving user guidance. - Refactored `AdminDutyList` to streamline the display of duties, enhancing visual clarity and organization. - Introduced `openPhoneLink` and `triggerHapticLight` functions in `ContactLinks` for improved phone link interaction and haptic feedback. - Added unit tests for `openPhoneLink` to ensure correct functionality and handling of various phone number formats. - Enhanced existing tests for `ContactLinks` to verify new phone link behavior, ensuring robust testing coverage.
This commit is contained in:
46
webapp-next/src/lib/open-phone-link.ts
Normal file
46
webapp-next/src/lib/open-phone-link.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Opens a phone number for calling. Uses native tel: navigation so the OS
|
||||
* or WebView can open the dialer. Does not use Telegram openLink() for tel:
|
||||
* (protocol is not supported; it closes the app on desktop and does nothing on mobile).
|
||||
*/
|
||||
|
||||
/**
|
||||
* Builds a tel: URL from a phone string (digits and optional leading + only).
|
||||
*/
|
||||
function buildTelUrl(phone: string): string {
|
||||
const trimmed = String(phone).trim();
|
||||
if (trimmed === "") return "";
|
||||
const digits = trimmed.replace(/\D/g, "");
|
||||
if (digits.length === 11 && (digits[0] === "7" || digits[0] === "8")) {
|
||||
return `tel:+7${digits.slice(1)}`;
|
||||
}
|
||||
if (digits.length === 10) {
|
||||
return `tel:+7${digits}`;
|
||||
}
|
||||
return `tel:${trimmed.startsWith("+") ? "+" : ""}${digits}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the given phone number for calling. Tries window.open(telUrl) first
|
||||
* (reported to work for tel: in some Telegram WebViews), then a programmatic
|
||||
* click on a temporary tel: link. openLink(tel:) is not used — Telegram does
|
||||
* not support it (closes app on desktop, no dialer on mobile). Safe to call
|
||||
* from click handlers; does not throw.
|
||||
*/
|
||||
export function openPhoneLink(phone: string | null | undefined): void {
|
||||
if (phone == null || String(phone).trim() === "") return;
|
||||
const telUrl = buildTelUrl(phone);
|
||||
if (telUrl === "") return;
|
||||
if (typeof window === "undefined" || !window.document) return;
|
||||
|
||||
const opened = window.open(telUrl);
|
||||
if (opened !== null) return;
|
||||
|
||||
const anchor = window.document.createElement("a");
|
||||
anchor.href = telUrl;
|
||||
anchor.style.display = "none";
|
||||
anchor.setAttribute("aria-hidden", "true");
|
||||
window.document.body.appendChild(anchor);
|
||||
anchor.click();
|
||||
anchor.remove();
|
||||
}
|
||||
Reference in New Issue
Block a user