Spaces:
Sleeping
Sleeping
File size: 3,493 Bytes
9ff626c e53121c 9ff626c e53121c 9ff626c a02bcda c97fee1 e53121c a02bcda 3752ea5 e1d0e9c 03a1f85 a02bcda 9ff626c 03a1f85 9ff626c c67a45c 03a1f85 c67a45c 03a1f85 9ff626c a02bcda 9ff626c a02bcda 9ff626c a02bcda 9b7c3e8 9ff626c a02bcda 9ff626c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | import axios from 'axios';
// Create axios instance with base configuration
// FORCE REBUILD: Fixed double /api issue by removing /api from baseURL
const api = axios.create({
baseURL: 'https://linguabot-transcreation-backend.hf.space',
headers: {
'Content-Type': 'application/json',
},
timeout: 10000, // 10 second timeout
});
// Debug: Log the API URL being used
console.log('π§ API CONFIGURATION DEBUG - FIXED DOUBLE /API ISSUE:');
console.log('API Base URL: https://linguabot-transcreation-backend.hf.space');
console.log('Environment variables:', {
REACT_APP_API_URL: process.env.REACT_APP_API_URL,
NODE_ENV: process.env.NODE_ENV
});
console.log('Build timestamp:', new Date().toISOString()); // FORCE REBUILD - Video seeking and subtitle syncing
console.log('π FORCE REBUILD: Admin API routes fixed - should resolve 404 errors');
console.log('π FORCE REBUILD: Subtitle submissions feature added - new UI and API endpoints');
// Request interceptor to add auth token and user role
api.interceptors.request.use(
(config) => {
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
// Add user role and info to headers
const user = localStorage.getItem('user');
if (user) {
try {
const userData = JSON.parse(user);
config.headers['user-role'] = userData.role || 'visitor';
const derivedUsername = userData.username || userData.name || userData.displayName || (userData.email ? String(userData.email).split('@')[0] : undefined);
config.headers['user-info'] = JSON.stringify({
_id: userData._id || userData.id,
username: derivedUsername,
name: userData.name,
displayName: userData.displayName,
email: userData.email,
role: userData.role
});
} catch (error) {
config.headers['user-role'] = 'visitor';
}
}
// Debug: Log the actual request URL
console.log('π Making API request to:', (config.baseURL || '') + (config.url || ''));
console.log('π Auth token:', token ? 'Present' : 'Missing');
return config;
},
(error) => {
return Promise.reject(error);
}
);
// Response interceptor to handle errors
api.interceptors.response.use(
(response) => {
console.log('β
API response received:', response.config.url);
return response;
},
(error) => {
console.error('β API request failed:', error.config?.url, error.message);
// Don't auto-redirect for admin operations - let the component handle it
if (error.response?.status === 401 && !error.config?.url?.includes('/subtitles/update/')) {
// Token expired or invalid - only redirect for non-admin operations
localStorage.removeItem('token');
localStorage.removeItem('user');
window.location.href = '/login';
} else if (error.response?.status === 429) {
// Rate limit exceeded - retry after delay
console.warn('Rate limit exceeded, retrying after delay...');
return new Promise(resolve => {
setTimeout(() => {
resolve(api.request(error.config));
}, 2000); // Wait 2 seconds before retry
});
} else if (error.response?.status === 500) {
console.error('Server error:', error.response.data);
} else if (error.code === 'ECONNABORTED') {
console.error('Request timeout');
}
return Promise.reject(error);
}
);
export { api }; |