Implemented three-tier sensor status (online/warning/offline) with visual indicators and BLE scanning for nearby devices. Features: - WPSensor type with status field (online/warning/offline) - Automatic status calculation based on lastSeen time: • Online: < 5 minutes (fresh data) • Warning: 5 min - 1 hour (potential issue) • Offline: > 1 hour (definitely problem) - Dual sensor display: Connected (API) + Available Nearby (BLE) - BLE scanning button for discovering nearby WP sensors - Action Sheet for offline sensors with Reconnect/Remove options - Updated summary card: Total/Online/Warning/Offline counts - Visual status indicators: colored dots and labels - Graceful error handling for API unavailability Files changed: - types/index.ts: Added WPSensor interface with status and source fields - services/api.ts: Updated getDevicesForBeneficiary with status calculation - equipment.tsx: Complete UI overhaul with BLE scanning and two-tier sensor list 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
196 lines
5.0 KiB
TypeScript
196 lines
5.0 KiB
TypeScript
// User & Auth Types
|
|
// User & Auth Types
|
|
export interface User {
|
|
user_id: number | string;
|
|
email?: string;
|
|
firstName?: string | null;
|
|
lastName?: string | null;
|
|
phone?: string | null;
|
|
max_role: number | string;
|
|
privileges: string | string[];
|
|
}
|
|
|
|
export interface AuthResponse {
|
|
access_token: string;
|
|
privileges: string;
|
|
user_id: number;
|
|
max_role: number;
|
|
status: string;
|
|
}
|
|
|
|
export interface LoginCredentials {
|
|
username: string;
|
|
password: string;
|
|
}
|
|
|
|
// Subscription status for beneficiary
|
|
export interface BeneficiarySubscription {
|
|
status: 'active' | 'trialing' | 'expired' | 'none' | 'expiring_soon' | 'past_due' | 'canceled';
|
|
startDate?: string; // ISO date
|
|
endDate?: string; // ISO date (currentPeriodEnd from Stripe)
|
|
planType?: 'monthly' | 'annual';
|
|
price?: number;
|
|
cancelAtPeriodEnd?: boolean; // Will cancel at end of billing period
|
|
}
|
|
|
|
// Device/Sensor connected to beneficiary
|
|
export interface BeneficiaryDevice {
|
|
id: string;
|
|
type: 'motion' | 'door' | 'temperature' | 'bed' | 'other';
|
|
name: string;
|
|
location?: string;
|
|
status: 'online' | 'offline';
|
|
lastSeen?: string;
|
|
}
|
|
|
|
// WP Sensor (Water Pressure sensor) from Legacy API
|
|
export interface WPSensor {
|
|
deviceId: string; // Device ID from Legacy API
|
|
wellId: number; // Well ID (physical device identifier)
|
|
mac: string; // MAC address
|
|
name: string; // Display name (e.g., "WP_12_a1b2c3")
|
|
status: 'online' | 'warning' | 'offline'; // Connection status
|
|
lastSeen: Date; // Last data transmission time
|
|
location?: string; // Physical location
|
|
description?: string; // User description
|
|
beneficiaryId: string; // Associated beneficiary
|
|
deploymentId: number; // Legacy API deployment ID
|
|
source: 'api' | 'ble'; // Data source (API = attached, BLE = nearby)
|
|
}
|
|
|
|
// Equipment/Kit delivery status
|
|
export type EquipmentStatus =
|
|
| 'none' // No equipment ordered
|
|
| 'ordered' // Kit ordered, waiting to ship
|
|
| 'shipped' // Kit shipped, in transit
|
|
| 'delivered' // Kit delivered, ready to activate
|
|
| 'active' // Equipment activated and working
|
|
| 'demo'; // Demo mode (DEMO-00000)
|
|
|
|
// Beneficiary Types (elderly people being monitored)
|
|
export interface Beneficiary {
|
|
id: number;
|
|
name: string;
|
|
avatar?: string;
|
|
device_id?: string;
|
|
status: 'online' | 'offline';
|
|
relationship?: string;
|
|
last_activity?: string;
|
|
sensor_data?: SensorData;
|
|
// Extended data from dashboard_single API
|
|
address?: string;
|
|
timezone?: string;
|
|
wellness_score?: number;
|
|
wellness_descriptor?: string;
|
|
last_location?: string;
|
|
temperature?: number;
|
|
units?: string;
|
|
sleep_hours?: number;
|
|
bedroom_temperature?: number;
|
|
before_last_location?: string;
|
|
last_detected_time?: string;
|
|
// Subscription & Devices
|
|
subscription?: BeneficiarySubscription;
|
|
devices?: BeneficiaryDevice[];
|
|
hasDevices?: boolean;
|
|
// Equipment status
|
|
equipmentStatus?: EquipmentStatus;
|
|
trackingNumber?: string; // Shipping tracking number
|
|
isDemo?: boolean; // Demo mode flag
|
|
// User's role for this beneficiary
|
|
role?: 'custodian' | 'guardian' | 'caretaker';
|
|
// Invitations for sharing access
|
|
invitations?: {
|
|
id: string;
|
|
email: string;
|
|
role: string;
|
|
label?: string;
|
|
status: string;
|
|
created_at: string;
|
|
}[];
|
|
}
|
|
|
|
// Dashboard API response
|
|
export interface DashboardSingleResponse {
|
|
result_list: BeneficiaryDashboardData[];
|
|
status: string;
|
|
}
|
|
|
|
export interface BeneficiaryDashboardData {
|
|
user_id: number;
|
|
name: string;
|
|
address: string;
|
|
time_zone: string;
|
|
picture: string;
|
|
deployment_id: string;
|
|
wellness_score_percent: number;
|
|
wellness_descriptor: string;
|
|
wellness_descriptor_color: string;
|
|
last_location: string;
|
|
last_detected_time: string;
|
|
before_last_location: string;
|
|
temperature: number;
|
|
bedroom_temperature: number;
|
|
sleep_hours: number;
|
|
units: string;
|
|
location_list: string[];
|
|
}
|
|
|
|
export interface SensorData {
|
|
motion_detected?: boolean;
|
|
last_motion?: string;
|
|
door_status?: 'open' | 'closed';
|
|
temperature?: number;
|
|
humidity?: number;
|
|
last_updated?: string;
|
|
}
|
|
|
|
// Chat Types
|
|
export interface Message {
|
|
id: string;
|
|
role: 'user' | 'assistant';
|
|
content: string;
|
|
timestamp: Date;
|
|
}
|
|
|
|
export interface ChatResponse {
|
|
ok: boolean;
|
|
response: {
|
|
Command: string;
|
|
body: string;
|
|
language: string;
|
|
};
|
|
status: string;
|
|
}
|
|
|
|
// Notification Settings
|
|
export interface NotificationSettings {
|
|
// Alert types
|
|
emergencyAlerts: boolean;
|
|
activityAlerts: boolean;
|
|
lowBattery: boolean;
|
|
dailySummary: boolean;
|
|
weeklySummary: boolean;
|
|
// Delivery methods
|
|
pushEnabled: boolean;
|
|
emailEnabled: boolean;
|
|
smsEnabled: boolean;
|
|
// Quiet hours
|
|
quietHours: boolean;
|
|
quietStart: string; // "HH:MM" format
|
|
quietEnd: string; // "HH:MM" format
|
|
}
|
|
|
|
// API Types
|
|
export interface ApiError {
|
|
message: string;
|
|
code?: string;
|
|
status?: number;
|
|
}
|
|
|
|
export interface ApiResponse<T> {
|
|
data?: T;
|
|
error?: ApiError;
|
|
ok: boolean;
|
|
}
|