pos-dashboard/src/services/weddingGuestService.js
tuanOts 9edc668441 Integrate Wedding Guest List with real API and improve UX
🔗 API Integration:
- Add weddingGuestService.js with full CRUD operations
- Connect to /api/WeddingGuests endpoint using REACT_APP_API_BASE_URL
- Implement proper error handling and fallback mechanisms
- Add detailed debug logging for troubleshooting

🎯 Features Added:
- Real-time API calls for guests, statistics, and units
- Automatic fallback to mock data if API fails
- Export Excel functionality
- Delete confirmation with API integration
- Search and filter with API parameters

🎨 UX Improvements:
- Default 'Tất cả trạng thái' and 'Tất cả đơn vị' options
- Beautiful icons for filter options (📋 🏢   )
- User-friendly error messages and warnings
- Loading states with spinners
- Success/error notifications

🔧 Technical Enhancements:
- Axios client with interceptors for auth and error handling
- Proper pagination handling
- Status mapping between API and UI
- Environment variable configuration
- Mock data structure matching API format

🚀 Production Ready:
- Complete API integration with backend
- Fallback mechanisms for reliability
- Professional error handling
- Responsive design maintained
2025-05-31 19:13:52 +07:00

259 lines
7.2 KiB
JavaScript

import axios from 'axios';
const API_BASE_URL = process.env.REACT_APP_API_BASE_URL;
// Create axios instance with base configuration
const apiClient = axios.create({
baseURL: API_BASE_URL,
headers: {
'Content-Type': 'application/json',
},
});
// Add request interceptor for authentication if needed
apiClient.interceptors.request.use(
(config) => {
// Add auth token if available
const token = localStorage.getItem('authToken');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
// Add response interceptor for error handling
apiClient.interceptors.response.use(
(response) => {
return response;
},
(error) => {
console.error('API Error:', error);
// Handle common errors
if (error.response?.status === 401) {
// Unauthorized - redirect to login
localStorage.removeItem('authToken');
window.location.href = '/signin';
}
return Promise.reject(error);
}
);
// Wedding Guest API Service
export const weddingGuestService = {
// Get all wedding guests with pagination and filters
async getWeddingGuests(params = {}) {
try {
console.log('🔍 API Call - Wedding Guests:', {
baseURL: API_BASE_URL,
endpoint: '/WeddingGuests',
params: params
});
const response = await apiClient.get('/WeddingGuests', { params });
console.log('✅ API Response - Wedding Guests:', {
status: response.status,
data: response.data
});
return {
success: true,
data: response.data.data || response.data,
message: response.data.message || 'Success'
};
} catch (error) {
console.error('❌ Error fetching wedding guests:', {
message: error.message,
status: error.response?.status,
statusText: error.response?.statusText,
data: error.response?.data,
config: {
url: error.config?.url,
method: error.config?.method,
baseURL: error.config?.baseURL
}
});
return {
success: false,
data: null,
message: error.response?.data?.message || error.message || 'Failed to fetch wedding guests'
};
}
},
// Get wedding guest by ID
async getWeddingGuestById(id) {
try {
const response = await apiClient.get(`/WeddingGuests/${id}`);
return {
success: true,
data: response.data.data || response.data,
message: response.data.message || 'Success'
};
} catch (error) {
console.error('Error fetching wedding guest:', error);
return {
success: false,
data: null,
message: error.response?.data?.message || error.message || 'Failed to fetch wedding guest'
};
}
},
// Create new wedding guest
async createWeddingGuest(guestData) {
try {
const response = await apiClient.post('/WeddingGuests', guestData);
return {
success: true,
data: response.data.data || response.data,
message: response.data.message || 'Wedding guest created successfully'
};
} catch (error) {
console.error('Error creating wedding guest:', error);
return {
success: false,
data: null,
message: error.response?.data?.message || error.message || 'Failed to create wedding guest'
};
}
},
// Update wedding guest
async updateWeddingGuest(id, guestData) {
try {
const response = await apiClient.put(`/WeddingGuests/${id}`, guestData);
return {
success: true,
data: response.data.data || response.data,
message: response.data.message || 'Wedding guest updated successfully'
};
} catch (error) {
console.error('Error updating wedding guest:', error);
return {
success: false,
data: null,
message: error.response?.data?.message || error.message || 'Failed to update wedding guest'
};
}
},
// Delete wedding guest
async deleteWeddingGuest(id) {
try {
const response = await apiClient.delete(`/WeddingGuests/${id}`);
return {
success: true,
data: response.data.data || response.data,
message: response.data.message || 'Wedding guest deleted successfully'
};
} catch (error) {
console.error('Error deleting wedding guest:', error);
return {
success: false,
data: null,
message: error.response?.data?.message || error.message || 'Failed to delete wedding guest'
};
}
},
// Update wedding guest status only
async updateWeddingGuestStatus(id, status) {
try {
const response = await apiClient.put(`/WeddingGuests/${id}/status`, { status });
return {
success: true,
data: response.data.data || response.data,
message: response.data.message || 'Status updated successfully'
};
} catch (error) {
console.error('Error updating guest status:', error);
return {
success: false,
data: null,
message: error.response?.data?.message || error.message || 'Failed to update status'
};
}
},
// Get wedding guest statistics
async getWeddingGuestStatistics() {
try {
const response = await apiClient.get('/WeddingGuests/statistics');
return {
success: true,
data: response.data.data || response.data,
message: response.data.message || 'Success'
};
} catch (error) {
console.error('Error fetching statistics:', error);
return {
success: false,
data: null,
message: error.response?.data?.message || error.message || 'Failed to fetch statistics'
};
}
},
// Get available units for filter dropdown
async getUnits() {
try {
const response = await apiClient.get('/WeddingGuests/units');
return {
success: true,
data: response.data.data || response.data,
message: response.data.message || 'Success'
};
} catch (error) {
console.error('Error fetching units:', error);
return {
success: false,
data: [],
message: error.response?.data?.message || error.message || 'Failed to fetch units'
};
}
},
// Export wedding guest list
async exportWeddingGuests(format = 'excel') {
try {
const response = await apiClient.get('/WeddingGuests/export', {
params: { format },
responseType: 'blob'
});
// Create download link
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', `wedding-guests.${format === 'excel' ? 'xlsx' : 'csv'}`);
document.body.appendChild(link);
link.click();
link.remove();
window.URL.revokeObjectURL(url);
return {
success: true,
data: null,
message: 'Export completed successfully'
};
} catch (error) {
console.error('Error exporting wedding guests:', error);
return {
success: false,
data: null,
message: error.response?.data?.message || error.message || 'Failed to export wedding guests'
};
}
}
};
export default weddingGuestService;