Best Practices for Frontend Implementation
- Authentication Flow
Initial Setup: Store session tokens securely (localStorage for web, AsyncStorage for React Native)
Token Management: Include tokens in Authorization headers for all authenticated endpoints
Session Handling: Implement automatic logout on token expiration
For Employers (Web Frontend)General Setup
// API Base Configuration const API_BASE_URL = 'http://your-api-url'; const getAuthHeaders = () => ({ 'Authorization': `Bearer ${localStorage.getItem('sessionKey')}`, 'Content-Type': 'application/json' });
File Upload Implementation
// For multipart/form-data endpoints (signup, profile updates) const uploadWithFiles = async (endpoint, formData) => { const token = localStorage.getItem('sessionKey'); const response = await fetch(`${API_BASE_URL}${endpoint}`, { method: 'POST', headers: { 'Authorization': `Bearer ${token}` // Don't set Content-Type for multipart/form-data }, body: formData }); return response.json(); };
Complete Authentication Implementation
class AuthService { static async login(email, password) { const response = await fetch(`${API_BASE_URL}/login-employer`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email, password }) }); const data = await response.json(); if (data.Status === 'Success') { localStorage.setItem('sessionKey', data['Debug Session Key']); localStorage.setItem('userId', data['App User ID']); return data; } throw new Error(data.Message); } static async logout() { const token = localStorage.getItem('sessionKey'); await fetch(`${API_BASE_URL}/logout`, { method: 'POST', headers: { 'Authorization': `Bearer ${token}` } }); localStorage.removeItem('sessionKey'); localStorage.removeItem('userId'); } }
Job Management Implementation
class JobService { static async createJob(jobData) { const response = await fetch(`${API_BASE_URL}/create-jobs`, { method: 'POST', headers: getAuthHeaders(), body: JSON.stringify(jobData) }); return response.json(); } static async getJobs() { const response = await fetch(`${API_BASE_URL}/view-all-jobs`, { method: 'GET', headers: getAuthHeaders() }); return response.json(); } static async deleteJob(jobId) { const response = await fetch(`${API_BASE_URL}/delete-job/${jobId}`, { method: 'POST', headers: getAuthHeaders() }); return response.json(); } }
For Employees (React Native)Dependencies Setup
npm install @react-native-async-storage/async-storage expo install expo-image-picker expo-document-picker
General Setup
import AsyncStorage from '@react-native-async-storage/async-storage'; import * as ImagePicker from 'expo-image-picker'; import * as DocumentPicker from 'expo-document-picker'; const API_BASE_URL = 'http://your-api-url'; const getAuthHeaders = async () => { const token = await AsyncStorage.getItem('sessionKey'); return { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }; };
Complete Authentication Implementation
class AuthService { static async login(email, password) { const response = await fetch(`${API_BASE_URL}/login-employee`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email, password }) }); const data = await response.json(); if (data.Status === 'Success') { await AsyncStorage.setItem('sessionKey', data['Debug Session Key']); await AsyncStorage.setItem('userId', data['App User ID']); return data; } throw new Error(data.Message); } static async logout() { const token = await AsyncStorage.getItem('sessionKey'); await fetch(`${API_BASE_URL}/logout`, { method: 'POST', headers: { 'Authorization': `Bearer ${token}` } }); await AsyncStorage.removeItem('sessionKey'); await AsyncStorage.removeItem('userId'); } }
File Upload Implementation
class FileService { static async pickImage() { const result = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ImagePicker.MediaTypeOptions.Images, allowsEditing: true, aspect: [1, 1], quality: 0.8, }); if (!result.canceled) { return result.assets[0]; } return null; } static async pickDocument() { const result = await DocumentPicker.getDocumentAsync({ type: 'application/pdf', copyToCacheDirectory: false, }); if (result.type === 'success') { return result; } return null; } static async uploadResume(resumeUri) { const token = await AsyncStorage.getItem('sessionKey'); const formData = new FormData(); formData.append('file', { uri: resumeUri, type: 'application/pdf', name: 'resume.pdf' }); const response = await fetch(`${API_BASE_URL}/upload-resume`, { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'multipart/form-data' }, body: formData }); return response.json(); } }
Job Application Implementation
class JobApplicationService { static async getRecommendations() { const headers = await getAuthHeaders(); const response = await fetch(`${API_BASE_URL}/reco-jobs`, { method: 'GET', headers }); return response.json(); } static async applyForJob(jobId) { const headers = await getAuthHeaders(); const response = await fetch(`${API_BASE_URL}/apply-job/${jobId}`, { method: 'POST', headers }); return response.json(); } static async getApplicationHistory() { const headers = await getAuthHeaders(); const response = await fetch(`${API_BASE_URL}/my-applications`, { method: 'GET', headers }); return response.json(); } }
Error Handling Best PracticesStandard Error Handler
const handleApiError = (error) => { if (error.message.includes('401')) { // Redirect to login window.location.href = '/login'; // Web // or navigation.navigate('Login'); // React Native } else if (error.message.includes('404')) { console.error('Resource not found'); } else if (error.message.includes('500')) { console.error('Server error'); } else { console.error('API Error:', error.message); } };
File Validation
const validateFile = (file, type = 'image', maxSize = 5) => { const maxSizeBytes = maxSize * 1024 * 1024; // Convert MB to bytes if (file.size > maxSizeBytes) { throw new Error(`File size must be less than ${maxSize}MB`); } if (type === 'image') { const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif']; if (!allowedTypes.includes(file.type)) { throw new Error('Only JPG, JPEG, PNG, and GIF files are allowed'); } } else if (type === 'pdf') { if (file.type !== 'application/pdf') { throw new Error('Only PDF files are allowed'); } } };
UI/UX Implementation TipsLoading States
const [loading, setLoading] = useState(false); const handleSubmit = async () => { setLoading(true); try { await apiCall(); // Success feedback } catch (error) { // Error feedback } finally { setLoading(false); } };
Form Validation
const validateForm = (formData) => { const errors = {}; if (!formData.email) errors.email = 'Email is required'; if (!formData.password || formData.password.length < 8) { errors.password = 'Password must be at least 8 characters'; } return errors; };
Last updated