Files
iistwin/client/src/hooks/useWebNotifications.ts
Ильяс Султанов 1f5ecb6da4 fix(number-fields): избегаем потери точности длинных чисел
- number-поля теперь рендерятся как text + inputMode=numeric,
  чтобы браузер не округлял значения через input type=number
- пробелы при вставке в number-поля удаляются
- бэкенд нормализует значения number-полей в строку перед сохранением
- добавлен хелпер normalizeFieldValueForStorage

Closes: искажение расчётного счёта и других длинных числовых полей
2026-07-07 21:03:40 +03:00

77 lines
2.2 KiB
TypeScript

import { useEffect, useRef } from 'react';
interface WebNotificationOptions {
title: string;
body: string;
icon?: string;
tag?: string;
}
export const useWebNotifications = () => {
const permissionRef = useRef<NotificationPermission>('default');
const isEnabledRef = useRef(false);
useEffect(() => {
// Проверяем поддержку браузера
if ('Notification' in window) {
permissionRef.current = Notification.permission;
isEnabledRef.current = Notification.permission === 'granted';
}
}, []);
const requestPermission = async (): Promise<boolean> => {
if (!('Notification' in window)) {
console.warn('Браузер не поддерживает Web Notifications API');
return false;
}
if (permissionRef.current === 'granted') {
return true;
}
try {
const permission = await Notification.requestPermission();
permissionRef.current = permission;
isEnabledRef.current = permission === 'granted';
return permission === 'granted';
} catch (error) {
console.error('Ошибка при запросе разрешения на уведомления:', error);
return false;
}
};
const showNotification = async (options: WebNotificationOptions): Promise<boolean> => {
if (!isEnabledRef.current) {
console.warn('Уведомления отключены или не поддерживаются');
return false;
}
try {
const notification = new Notification(options.title, {
body: options.body,
icon: options.icon || '/favicon.ico',
tag: options.tag,
silent: false,
requireInteraction: false
});
// Автоматически закрываем уведомление через 5 секунд
setTimeout(() => {
notification.close();
}, 5000);
return true;
} catch (error) {
console.error('Ошибка при показе уведомления:', error);
return false;
}
};
return {
isSupported: 'Notification' in window,
permission: permissionRef.current,
isEnabled: isEnabledRef.current,
requestPermission,
showNotification
};
};