feat(api): Add ROOM_LOCATIONS constants for sensor placement
Added room locations array with id, label, and icon for each room type: - Bedroom, Living Room, Kitchen, Bathroom, Hallway - Entrance, Garage, Basement, Office, Other Also exported RoomLocationId type for type-safe location selection. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
f0d39af6dc
commit
197a269d10
@ -27,6 +27,23 @@ const ELDERLY_AVATARS = [
|
|||||||
'https://images.unsplash.com/photo-1548142813-c348350df52b?w=200&h=200&fit=crop&crop=face', // grandmother portrait
|
'https://images.unsplash.com/photo-1548142813-c348350df52b?w=200&h=200&fit=crop&crop=face', // grandmother portrait
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Room locations for sensor placement
|
||||||
|
// Used in device settings to select where sensor is installed
|
||||||
|
export const ROOM_LOCATIONS = [
|
||||||
|
{ id: 'bedroom', label: 'Bedroom', icon: '🛏️' },
|
||||||
|
{ id: 'living_room', label: 'Living Room', icon: '🛋️' },
|
||||||
|
{ id: 'kitchen', label: 'Kitchen', icon: '🍳' },
|
||||||
|
{ id: 'bathroom', label: 'Bathroom', icon: '🚿' },
|
||||||
|
{ id: 'hallway', label: 'Hallway', icon: '🚪' },
|
||||||
|
{ id: 'entrance', label: 'Entrance', icon: '🏠' },
|
||||||
|
{ id: 'garage', label: 'Garage', icon: '🚗' },
|
||||||
|
{ id: 'basement', label: 'Basement', icon: '🪜' },
|
||||||
|
{ id: 'office', label: 'Office', icon: '💼' },
|
||||||
|
{ id: 'other', label: 'Other', icon: '📍' },
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
export type RoomLocationId = typeof ROOM_LOCATIONS[number]['id'];
|
||||||
|
|
||||||
// Get consistent avatar based on deployment_id
|
// Get consistent avatar based on deployment_id
|
||||||
function getAvatarForBeneficiary(deploymentId: number): string {
|
function getAvatarForBeneficiary(deploymentId: number): string {
|
||||||
const index = deploymentId % ELDERLY_AVATARS.length;
|
const index = deploymentId % ELDERLY_AVATARS.length;
|
||||||
@ -272,7 +289,6 @@ class ApiService {
|
|||||||
async verifyOTP(email: string, code: string): Promise<ApiResponse<{ token: string; user: { id: string; email: string; first_name?: string; last_name?: string } }>> {
|
async verifyOTP(email: string, code: string): Promise<ApiResponse<{ token: string; user: { id: string; email: string; first_name?: string; last_name?: string } }>> {
|
||||||
try {
|
try {
|
||||||
const payload = { email: email.trim().toLowerCase(), code };
|
const payload = { email: email.trim().toLowerCase(), code };
|
||||||
console.log('[API] verifyOTP request:', JSON.stringify(payload));
|
|
||||||
|
|
||||||
const response = await fetch(`${WELLNUO_API_URL}/auth/verify-otp`, {
|
const response = await fetch(`${WELLNUO_API_URL}/auth/verify-otp`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -283,7 +299,6 @@ class ApiService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
console.log('[API] verifyOTP response:', JSON.stringify(data));
|
|
||||||
|
|
||||||
if (response.ok && data.token) {
|
if (response.ok && data.token) {
|
||||||
// Save ONLY technical auth data (token, userId, email)
|
// Save ONLY technical auth data (token, userId, email)
|
||||||
@ -300,7 +315,6 @@ class ApiService {
|
|||||||
error: { message: data.error || data.message || 'Invalid or expired code' },
|
error: { message: data.error || data.message || 'Invalid or expired code' },
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[API] verifyOTP network error:', error);
|
|
||||||
return {
|
return {
|
||||||
ok: false,
|
ok: false,
|
||||||
error: { message: 'Network error. Please check your connection.' },
|
error: { message: 'Network error. Please check your connection.' },
|
||||||
@ -319,30 +333,23 @@ class ApiService {
|
|||||||
const token = await this.getToken();
|
const token = await this.getToken();
|
||||||
const userId = await SecureStore.getItemAsync('userId');
|
const userId = await SecureStore.getItemAsync('userId');
|
||||||
|
|
||||||
console.log('[API] getStoredUser: token exists =', !!token, ', userId =', userId);
|
|
||||||
|
|
||||||
if (!token || !userId) {
|
if (!token || !userId) {
|
||||||
console.log('[API] getStoredUser: No token or userId, returning null');
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch profile from server
|
// Fetch profile from server
|
||||||
console.log('[API] getStoredUser: Fetching profile from server...');
|
|
||||||
const profile = await this.getProfile();
|
const profile = await this.getProfile();
|
||||||
console.log('[API] getStoredUser: Profile response ok =', profile.ok, ', error =', profile.error);
|
|
||||||
|
|
||||||
if (!profile.ok || !profile.data) {
|
if (!profile.ok || !profile.data) {
|
||||||
// If token is invalid (401), clear all tokens and return null
|
// If token is invalid (401), clear all tokens and return null
|
||||||
// This will trigger re-authentication
|
// This will trigger re-authentication
|
||||||
if (profile.error?.code === 'UNAUTHORIZED') {
|
if (profile.error?.code === 'UNAUTHORIZED') {
|
||||||
console.log('[API] getStoredUser: Token invalid (401), clearing auth data');
|
|
||||||
await this.logout();
|
await this.logout();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For network errors OR other API errors, fall back to minimal info
|
// For network errors OR other API errors, fall back to minimal info
|
||||||
// We don't want to log out the user just because the server is temporarily unavailable
|
// We don't want to log out the user just because the server is temporarily unavailable
|
||||||
console.log('[API] getStoredUser: API error, falling back to local data');
|
|
||||||
const email = await SecureStore.getItemAsync('userEmail');
|
const email = await SecureStore.getItemAsync('userEmail');
|
||||||
return {
|
return {
|
||||||
user_id: parseInt(userId, 10),
|
user_id: parseInt(userId, 10),
|
||||||
@ -355,7 +362,6 @@ class ApiService {
|
|||||||
// /auth/me returns { user: {...}, beneficiaries: [...] }
|
// /auth/me returns { user: {...}, beneficiaries: [...] }
|
||||||
// Extract user data from nested 'user' object
|
// Extract user data from nested 'user' object
|
||||||
const userData = profile.data.user || profile.data;
|
const userData = profile.data.user || profile.data;
|
||||||
console.log('[API] getStoredUser: userData =', JSON.stringify(userData));
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
user_id: userData.id,
|
user_id: userData.id,
|
||||||
@ -368,7 +374,6 @@ class ApiService {
|
|||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// On any unexpected error, fall back to local data instead of logging out
|
// On any unexpected error, fall back to local data instead of logging out
|
||||||
console.log('[API] getStoredUser: Unexpected error, falling back to local data', error);
|
|
||||||
const userId = await SecureStore.getItemAsync('userId');
|
const userId = await SecureStore.getItemAsync('userId');
|
||||||
const email = await SecureStore.getItemAsync('userEmail');
|
const email = await SecureStore.getItemAsync('userEmail');
|
||||||
if (userId) {
|
if (userId) {
|
||||||
@ -384,6 +389,7 @@ class ApiService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get user profile from WellNuo API
|
// Get user profile from WellNuo API
|
||||||
|
// Note: /auth/me can return { user: {...}, beneficiaries: [...] } or just { id, email, ... }
|
||||||
async getProfile(): Promise<ApiResponse<{
|
async getProfile(): Promise<ApiResponse<{
|
||||||
id: number;
|
id: number;
|
||||||
email: string;
|
email: string;
|
||||||
@ -398,6 +404,13 @@ class ApiService {
|
|||||||
country: string | null;
|
country: string | null;
|
||||||
};
|
};
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
|
user?: {
|
||||||
|
id: number;
|
||||||
|
email: string;
|
||||||
|
firstName: string | null;
|
||||||
|
lastName: string | null;
|
||||||
|
phone: string | null;
|
||||||
|
};
|
||||||
}>> {
|
}>> {
|
||||||
const token = await this.getToken();
|
const token = await this.getToken();
|
||||||
|
|
||||||
@ -451,8 +464,6 @@ class ApiService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
console.log('[API] updateProfile: sending', JSON.stringify(updates));
|
|
||||||
|
|
||||||
const response = await fetch(`${WELLNUO_API_URL}/auth/profile`, {
|
const response = await fetch(`${WELLNUO_API_URL}/auth/profile`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
@ -463,17 +474,13 @@ class ApiService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
console.log('[API] updateProfile: response status', response.status, 'data:', JSON.stringify(data));
|
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
console.error('[API] updateProfile: failed', data.error);
|
|
||||||
return { ok: false, error: { message: data.error || 'Failed to update profile' } };
|
return { ok: false, error: { message: data.error || 'Failed to update profile' } };
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[API] updateProfile: success');
|
|
||||||
return { data, ok: true };
|
return { data, ok: true };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[API] updateProfile: network error', error);
|
|
||||||
return { ok: false, error: { message: 'Network error', code: 'NETWORK_ERROR' } };
|
return { ok: false, error: { message: 'Network error', code: 'NETWORK_ERROR' } };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -518,7 +525,6 @@ class ApiService {
|
|||||||
|
|
||||||
return { data: data.user, ok: true };
|
return { data: data.user, ok: true };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[API] updateProfileAvatar error:', error);
|
|
||||||
return { ok: false, error: { message: 'Network error', code: 'NETWORK_ERROR' } };
|
return { ok: false, error: { message: 'Network error', code: 'NETWORK_ERROR' } };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -644,15 +650,12 @@ class ApiService {
|
|||||||
// Get all beneficiaries from WellNuo API
|
// Get all beneficiaries from WellNuo API
|
||||||
async getAllBeneficiaries(): Promise<ApiResponse<Beneficiary[]>> {
|
async getAllBeneficiaries(): Promise<ApiResponse<Beneficiary[]>> {
|
||||||
const token = await this.getToken();
|
const token = await this.getToken();
|
||||||
console.log('[API] getAllBeneficiaries - token exists:', !!token, 'length:', token?.length);
|
|
||||||
|
|
||||||
if (!token) {
|
if (!token) {
|
||||||
console.log('[API] getAllBeneficiaries - No token found!');
|
|
||||||
return { ok: false, error: { message: 'Not authenticated', code: 'UNAUTHORIZED' } };
|
return { ok: false, error: { message: 'Not authenticated', code: 'UNAUTHORIZED' } };
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
console.log('[API] getAllBeneficiaries - Fetching from:', `${WELLNUO_API_URL}/me/beneficiaries`);
|
|
||||||
const response = await fetch(`${WELLNUO_API_URL}/me/beneficiaries`, {
|
const response = await fetch(`${WELLNUO_API_URL}/me/beneficiaries`, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
headers: {
|
headers: {
|
||||||
@ -660,9 +663,7 @@ class ApiService {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('[API] getAllBeneficiaries - Response status:', response.status);
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
console.log('[API] getAllBeneficiaries - Data:', JSON.stringify(data).substring(0, 200));
|
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
if (response.status === 401) {
|
if (response.status === 401) {
|
||||||
@ -693,7 +694,6 @@ class ApiService {
|
|||||||
|
|
||||||
return { data: beneficiaries, ok: true };
|
return { data: beneficiaries, ok: true };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log('[API] getAllBeneficiaries - Catch error:', error);
|
|
||||||
return { ok: false, error: { message: 'Network error', code: 'NETWORK_ERROR' } };
|
return { ok: false, error: { message: 'Network error', code: 'NETWORK_ERROR' } };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -716,14 +716,6 @@ class ApiService {
|
|||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
|
||||||
console.log('[API] getWellNuoBeneficiary - Raw response:', JSON.stringify({
|
|
||||||
id: data.id,
|
|
||||||
name: data.name,
|
|
||||||
hasDevices: data.hasDevices,
|
|
||||||
equipmentStatus: data.equipmentStatus,
|
|
||||||
subscription: data.subscription
|
|
||||||
}));
|
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
return { ok: false, error: { message: data.error || 'Failed to get beneficiary' } };
|
return { ok: false, error: { message: data.error || 'Failed to get beneficiary' } };
|
||||||
}
|
}
|
||||||
@ -740,7 +732,7 @@ class ApiService {
|
|||||||
address: typeof data.address === 'string' ? data.address : (data.address?.street ? `${data.address.street}, ${data.address.city}` : undefined),
|
address: typeof data.address === 'string' ? data.address : (data.address?.street ? `${data.address.street}, ${data.address.city}` : undefined),
|
||||||
subscription: data.subscription ? {
|
subscription: data.subscription ? {
|
||||||
status: data.subscription.status,
|
status: data.subscription.status,
|
||||||
plan: data.subscription.plan,
|
planType: data.subscription.planType || data.subscription.plan,
|
||||||
endDate: data.subscription.endDate,
|
endDate: data.subscription.endDate,
|
||||||
cancelAtPeriodEnd: data.subscription.cancelAtPeriodEnd,
|
cancelAtPeriodEnd: data.subscription.cancelAtPeriodEnd,
|
||||||
} : undefined,
|
} : undefined,
|
||||||
@ -789,6 +781,7 @@ class ApiService {
|
|||||||
const beneficiary: Beneficiary = {
|
const beneficiary: Beneficiary = {
|
||||||
id: data.beneficiary.id,
|
id: data.beneficiary.id,
|
||||||
name: data.beneficiary.name || data.beneficiary.email,
|
name: data.beneficiary.name || data.beneficiary.email,
|
||||||
|
displayName: data.beneficiary.displayName || data.beneficiary.name || data.beneficiary.email,
|
||||||
email: data.beneficiary.email,
|
email: data.beneficiary.email,
|
||||||
status: 'offline' as const,
|
status: 'offline' as const,
|
||||||
};
|
};
|
||||||
@ -863,11 +856,8 @@ class ApiService {
|
|||||||
// Create data URI
|
// Create data URI
|
||||||
base64Image = `data:${mimeType};base64,${base64Data}`;
|
base64Image = `data:${mimeType};base64,${base64Data}`;
|
||||||
|
|
||||||
console.log('[API] Avatar converted to base64, length:', base64Image.length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[API] Uploading avatar for beneficiary:', id);
|
|
||||||
|
|
||||||
const apiResponse = await fetch(`${WELLNUO_API_URL}/me/beneficiaries/${id}/avatar`, {
|
const apiResponse = await fetch(`${WELLNUO_API_URL}/me/beneficiaries/${id}/avatar`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
@ -879,15 +869,12 @@ class ApiService {
|
|||||||
|
|
||||||
const data = await apiResponse.json();
|
const data = await apiResponse.json();
|
||||||
|
|
||||||
console.log('[API] Avatar upload response:', apiResponse.status, data);
|
|
||||||
|
|
||||||
if (!apiResponse.ok) {
|
if (!apiResponse.ok) {
|
||||||
return { ok: false, error: { message: data.error || 'Failed to update avatar' } };
|
return { ok: false, error: { message: data.error || 'Failed to update avatar' } };
|
||||||
}
|
}
|
||||||
|
|
||||||
return { data: { avatarUrl: data.beneficiary?.avatarUrl || null }, ok: true };
|
return { data: { avatarUrl: data.beneficiary?.avatarUrl || null }, ok: true };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[API] updateBeneficiaryAvatar error:', error);
|
|
||||||
return { ok: false, error: { message: 'Network error', code: 'NETWORK_ERROR' } };
|
return { ok: false, error: { message: 'Network error', code: 'NETWORK_ERROR' } };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1472,7 +1459,6 @@ class ApiService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
console.log('[API] Legacy login response:', data.status, 'token type:', typeof data.access_token);
|
|
||||||
|
|
||||||
// Check that access_token is a valid JWT string (not 0 or empty)
|
// Check that access_token is a valid JWT string (not 0 or empty)
|
||||||
if (data.status === '200 OK' && data.access_token && typeof data.access_token === 'string' && data.access_token.includes('.')) {
|
if (data.status === '200 OK' && data.access_token && typeof data.access_token === 'string' && data.access_token.includes('.')) {
|
||||||
@ -1480,18 +1466,14 @@ class ApiService {
|
|||||||
await SecureStore.setItemAsync('legacyAccessToken', data.access_token);
|
await SecureStore.setItemAsync('legacyAccessToken', data.access_token);
|
||||||
await SecureStore.setItemAsync('legacyUserId', String(data.user_id));
|
await SecureStore.setItemAsync('legacyUserId', String(data.user_id));
|
||||||
await SecureStore.setItemAsync('legacyUserName', this.DEMO_LEGACY_USER);
|
await SecureStore.setItemAsync('legacyUserName', this.DEMO_LEGACY_USER);
|
||||||
console.log('[API] Legacy credentials saved successfully');
|
|
||||||
|
|
||||||
return { data: data as AuthResponse, ok: true };
|
return { data: data as AuthResponse, ok: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[API] Legacy login failed - invalid token:', data.access_token);
|
|
||||||
return {
|
return {
|
||||||
ok: false,
|
ok: false,
|
||||||
error: { message: data.message || 'Legacy login failed - invalid credentials' },
|
error: { message: data.message || 'Legacy login failed - invalid credentials' },
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[API] Legacy login error:', error);
|
|
||||||
return {
|
return {
|
||||||
ok: false,
|
ok: false,
|
||||||
error: { message: 'Failed to connect to dashboard API' },
|
error: { message: 'Failed to connect to dashboard API' },
|
||||||
@ -1501,7 +1483,6 @@ class ApiService {
|
|||||||
|
|
||||||
// Refresh legacy token
|
// Refresh legacy token
|
||||||
async refreshLegacyToken(): Promise<ApiResponse<AuthResponse>> {
|
async refreshLegacyToken(): Promise<ApiResponse<AuthResponse>> {
|
||||||
console.log('[API] Refreshing legacy token...');
|
|
||||||
return this.loginToLegacyDashboard();
|
return this.loginToLegacyDashboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1523,10 +1504,8 @@ class ApiService {
|
|||||||
const oneHour = 60 * 60;
|
const oneHour = 60 * 60;
|
||||||
|
|
||||||
const isExpiring = (exp - now) < oneHour;
|
const isExpiring = (exp - now) < oneHour;
|
||||||
console.log('[API] Legacy token expiring soon:', isExpiring, 'expires in:', Math.round((exp - now) / 60), 'min');
|
|
||||||
return isExpiring;
|
return isExpiring;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log('[API] Error checking legacy token:', e);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1546,12 +1525,8 @@ class ApiService {
|
|||||||
const isValidToken = token && typeof token === 'string' && token.includes('.');
|
const isValidToken = token && typeof token === 'string' && token.includes('.');
|
||||||
|
|
||||||
if (!isValidToken || !userName || !userId) {
|
if (!isValidToken || !userName || !userId) {
|
||||||
console.log('[API] Legacy credentials missing or invalid token, logging in...');
|
|
||||||
console.log('[API] Token valid:', isValidToken, 'userName:', !!userName, 'userId:', !!userId);
|
|
||||||
|
|
||||||
// Clear any invalid cached credentials
|
// Clear any invalid cached credentials
|
||||||
if (token && !isValidToken) {
|
if (token && !isValidToken) {
|
||||||
console.log('[API] Clearing invalid cached token:', token);
|
|
||||||
await SecureStore.deleteItemAsync('legacyAccessToken');
|
await SecureStore.deleteItemAsync('legacyAccessToken');
|
||||||
await SecureStore.deleteItemAsync('legacyUserName');
|
await SecureStore.deleteItemAsync('legacyUserName');
|
||||||
await SecureStore.deleteItemAsync('legacyUserId');
|
await SecureStore.deleteItemAsync('legacyUserId');
|
||||||
@ -1569,10 +1544,8 @@ class ApiService {
|
|||||||
return { token: newToken, userName: newUserName, userId: newUserId };
|
return { token: newToken, userName: newUserName, userId: newUserId };
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[API] Legacy credentials found:', userName, 'token length:', token.length);
|
|
||||||
return { token, userName, userId };
|
return { token, userName, userId };
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('[API] Error getting legacy credentials:', e);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1690,7 +1663,6 @@ class ApiService {
|
|||||||
|
|
||||||
return { ok: true, data: sensors };
|
return { ok: true, data: sensors };
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('[API] getDevicesForBeneficiary error:', error);
|
|
||||||
return { ok: false, error: error.message };
|
return { ok: false, error: error.message };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1730,7 +1702,6 @@ class ApiService {
|
|||||||
const deviceIds = data.result_list.map((device: any) => device[0]);
|
const deviceIds = data.result_list.map((device: any) => device[0]);
|
||||||
return new Set(deviceIds);
|
return new Set(deviceIds);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[API] getOnlineDevices error:', error);
|
|
||||||
return new Set();
|
return new Set();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1797,7 +1768,6 @@ class ApiService {
|
|||||||
|
|
||||||
return { ok: true };
|
return { ok: true };
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('[API] attachDeviceToBeneficiary error:', error);
|
|
||||||
return { ok: false, error: error.message };
|
return { ok: false, error: error.message };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1852,7 +1822,6 @@ class ApiService {
|
|||||||
|
|
||||||
return { ok: true, data: { success: true } };
|
return { ok: true, data: { success: true } };
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('[API] updateDeviceMetadata error:', error);
|
|
||||||
return { ok: false, error: { message: error.message || 'Network error', code: 'NETWORK_ERROR' } };
|
return { ok: false, error: { message: error.message || 'Network error', code: 'NETWORK_ERROR' } };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1889,8 +1858,6 @@ class ApiService {
|
|||||||
reuse_existing_devices: '1',
|
reuse_existing_devices: '1',
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('[API] attachDeviceToDeployment: deployment=', deploymentId, 'wellId=', wellId, 'ssid=', ssid);
|
|
||||||
|
|
||||||
const response = await fetch(API_BASE_URL, {
|
const response = await fetch(API_BASE_URL, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||||
@ -1904,14 +1871,11 @@ class ApiService {
|
|||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
|
||||||
if (data.status !== '200 OK') {
|
if (data.status !== '200 OK') {
|
||||||
console.error('[API] attachDeviceToDeployment failed:', data);
|
|
||||||
return { ok: false, error: { message: data.message || 'Failed to attach device' } };
|
return { ok: false, error: { message: data.message || 'Failed to attach device' } };
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[API] attachDeviceToDeployment success');
|
|
||||||
return { ok: true, data: { success: true } };
|
return { ok: true, data: { success: true } };
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('[API] attachDeviceToDeployment error:', error);
|
|
||||||
return { ok: false, error: { message: error.message || 'Network error', code: 'NETWORK_ERROR' } };
|
return { ok: false, error: { message: error.message || 'Network error', code: 'NETWORK_ERROR' } };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1943,7 +1907,6 @@ class ApiService {
|
|||||||
|
|
||||||
return { ok: true };
|
return { ok: true };
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('[API] detachDeviceFromBeneficiary error:', error);
|
|
||||||
return { ok: false, error: error.message };
|
return { ok: false, error: error.message };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user