Phase 8: Visitor Management - Visitor/VisitorLog/AccessZone models - Check-in/out with badge generation - Zone occupancy tracking - Kiosk and management pages Phase 9: Messaging & Communication - Announcements with priority levels - Acknowledgement tracking - Shift notes for team handoffs - AnnouncementBanner component Phase 10: Compliance & Audit Trail - Immutable AuditLog model - Document versioning and approval workflow - Acknowledgement tracking for SOPs - CSV export for audit logs Phase 11: Accessibility & i18n - WCAG 2.1 AA compliance utilities - react-i18next with EN/ES translations - User preferences context (theme, font size, etc) - High contrast and reduced motion support Phase 12: Hardware Integration - QR code generation for batches/plants/visitors - Printable label system - Visitor badge printing Phase 13: Advanced Features - Environmental monitoring (sensors, readings, alerts) - Financial tracking (transactions, P&L reports) - AI/ML insights (yield predictions, anomaly detection)
92 lines
2.8 KiB
TypeScript
92 lines
2.8 KiB
TypeScript
import api from './api';
|
|
|
|
export interface Announcement {
|
|
id: string;
|
|
title: string;
|
|
body: string;
|
|
priority: 'INFO' | 'WARNING' | 'CRITICAL';
|
|
requiresAck: boolean;
|
|
targetRoles: string[];
|
|
expiresAt?: string;
|
|
createdBy: { id: string; name: string };
|
|
createdAt: string;
|
|
isRead?: boolean;
|
|
isAcknowledged?: boolean;
|
|
}
|
|
|
|
export interface ShiftNote {
|
|
id: string;
|
|
roomId?: string;
|
|
batchId?: string;
|
|
content: string;
|
|
importance: 'LOW' | 'NORMAL' | 'HIGH' | 'URGENT';
|
|
createdBy: { id: string; name: string };
|
|
createdAt: string;
|
|
isRead?: boolean;
|
|
}
|
|
|
|
export const messagingApi = {
|
|
// Announcements
|
|
async getAnnouncements(): Promise<Announcement[]> {
|
|
const response = await api.get('/api/messaging/announcements');
|
|
return response.data;
|
|
},
|
|
|
|
async getPendingAnnouncements(): Promise<{ count: number; announcements: Announcement[] }> {
|
|
const response = await api.get('/api/messaging/announcements/pending');
|
|
return response.data;
|
|
},
|
|
|
|
async createAnnouncement(data: {
|
|
title: string;
|
|
body: string;
|
|
priority?: 'INFO' | 'WARNING' | 'CRITICAL';
|
|
requiresAck?: boolean;
|
|
targetRoles?: string[];
|
|
expiresAt?: string;
|
|
}): Promise<Announcement> {
|
|
const response = await api.post('/api/messaging/announcements', data);
|
|
return response.data;
|
|
},
|
|
|
|
async markRead(id: string): Promise<void> {
|
|
await api.post(`/api/messaging/announcements/${id}/read`);
|
|
},
|
|
|
|
async acknowledge(id: string): Promise<{ success: boolean; acknowledgedAt: string }> {
|
|
const response = await api.post(`/api/messaging/announcements/${id}/acknowledge`);
|
|
return response.data;
|
|
},
|
|
|
|
async getAcknowledgements(id: string): Promise<{
|
|
announcement: { id: string; title: string };
|
|
requiresAck: boolean;
|
|
totalUsers: number;
|
|
acknowledged: number;
|
|
pending: { id: string; name: string; email: string }[];
|
|
}> {
|
|
const response = await api.get(`/api/messaging/announcements/${id}/acks`);
|
|
return response.data;
|
|
},
|
|
|
|
// Shift Notes
|
|
async getShiftNotes(params?: { roomId?: string; batchId?: string; limit?: number }): Promise<ShiftNote[]> {
|
|
const response = await api.get('/api/messaging/shift-notes', { params });
|
|
return response.data;
|
|
},
|
|
|
|
async createShiftNote(data: {
|
|
content: string;
|
|
roomId?: string;
|
|
batchId?: string;
|
|
importance?: 'LOW' | 'NORMAL' | 'HIGH' | 'URGENT';
|
|
expiresAt?: string;
|
|
}): Promise<ShiftNote> {
|
|
const response = await api.post('/api/messaging/shift-notes', data);
|
|
return response.data;
|
|
},
|
|
|
|
async markShiftNoteRead(id: string): Promise<void> {
|
|
await api.post(`/api/messaging/shift-notes/${id}/read`);
|
|
}
|
|
};
|