feat: Add real-time notification center with WebSocket integration
- Add in-app notification system with database storage - Implement bell icon component with unread count badge in dashboard header - Add full Notifications page tab with pagination and filtering (All/Unread/Read) - Implement real-time WebSocket push notifications to all connected clients - Add notification API endpoints: GET, PUT /read, DELETE, POST /clear - Fix critical bug in notificationService where 'status' variable was undefined - Add Notifications route to App.js routing - Enhanced UI with notification popup in header and dedicated full-page view - Auto-reconnect WebSocket with 5s timeout on disconnect - Support rich notification content with resource details and timestamps
This commit is contained in:
1 parent
7968c9231e
commit
db85573986
37 files changed
+3521
-207
No files matched your search
@@ -28,12 +28,19 @@ export const formatLocalTime = (timestamp, options = {}) => {
|
||||
let timeZone;
|
||||
try {
|
||||
const cachedSettings = localStorage.getItem('serverTimezone');
|
||||
if (cachedSettings && cachedSettings !== 'null' && cachedSettings !== 'undefined' && cachedSettings.trim() !== '') {
|
||||
const cacheTime = localStorage.getItem('serverTimezoneTime');
|
||||
const now = Date.now();
|
||||
// Invalidate cache every 1 hour
|
||||
if (cachedSettings && cacheTime && (now - parseInt(cacheTime)) < 3600000 && cachedSettings !== 'null' && cachedSettings !== 'undefined' && cachedSettings.trim() !== '') {
|
||||
// Remove any quotes that might be in the string
|
||||
timeZone = cachedSettings.replace(/^["']|["']$/g, '').trim();
|
||||
} else if (cachedSettings) {
|
||||
// Clear stale cache
|
||||
localStorage.removeItem('serverTimezone');
|
||||
localStorage.removeItem('serverTimezoneTime');
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error reading serverTimezone from localStorage:', e);
|
||||
// Timezone load error handled silently
|
||||
}
|
||||
|
||||
const defaultOptions = {
|
||||
@@ -72,12 +79,27 @@ export const formatLocalTimeOnly = (timestamp, options = {}) => {
|
||||
|
||||
/**
|
||||
* Format timestamp for chart display (shorter format)
|
||||
* Shows date and time for better context
|
||||
*/
|
||||
export const formatChartTime = (timestamp) => {
|
||||
if (!timestamp) return '';
|
||||
|
||||
const date = new Date(timestamp);
|
||||
return date.toLocaleTimeString('en-US', {
|
||||
const now = new Date();
|
||||
const diffDays = Math.floor((now - date) / (1000 * 60 * 60 * 24));
|
||||
|
||||
// If within last 24 hours, show time only
|
||||
if (diffDays === 0) {
|
||||
return date.toLocaleTimeString('en-US', {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
});
|
||||
}
|
||||
|
||||
// Otherwise show date and time
|
||||
return date.toLocaleString('en-US', {
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user