mirror of
https://github.com/HamzaSha1/zod-backend.git
synced 2025-08-25 05:42:27 +00:00
141 lines
4.6 KiB
TypeScript
141 lines
4.6 KiB
TypeScript
import axios from 'axios';
|
|
import { LoginRequest } from '../types/auth';
|
|
import { CreateJuniorRequest, JuniorTheme } from '../types/junior';
|
|
import { CreateTaskRequest, TaskStatus, TaskSubmission } from '../types/task';
|
|
|
|
const API_BASE_URL = 'https://zod.life';
|
|
const AUTH_TOKEN = btoa('zod-digital:Zod2025'); // Base64 encode credentials
|
|
|
|
// Helper function to get auth header
|
|
const getAuthHeader = () => {
|
|
const token = localStorage.getItem('accessToken');
|
|
return token ? `Bearer ${token}` : `Basic ${AUTH_TOKEN}`;
|
|
};
|
|
|
|
export const apiClient = axios.create({
|
|
baseURL: API_BASE_URL,
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'x-client-id': 'web-client',
|
|
},
|
|
});
|
|
|
|
// Add request interceptor to include current auth header
|
|
apiClient.interceptors.request.use((config) => {
|
|
config.headers.Authorization = getAuthHeader();
|
|
return config;
|
|
});
|
|
|
|
// Add response interceptor to handle errors
|
|
apiClient.interceptors.response.use(
|
|
(response) => response,
|
|
(error) => {
|
|
const errorMessage =
|
|
error.response?.data?.message || error.response?.data?.error || error.message || 'An unexpected error occurred';
|
|
|
|
console.error('API Error:', {
|
|
status: error.response?.status,
|
|
message: errorMessage,
|
|
data: error.response?.data,
|
|
});
|
|
|
|
// Throw error with meaningful message
|
|
throw new Error(errorMessage);
|
|
},
|
|
);
|
|
|
|
// Auth API
|
|
export const authApi = {
|
|
register: (countryCode: string, phoneNumber: string) => {
|
|
// Ensure phone number is in the correct format (remove any non-digit characters)
|
|
const cleanPhoneNumber = phoneNumber.replace(/\D/g, '');
|
|
return apiClient.post('/api/auth/register/otp', {
|
|
countryCode: countryCode.startsWith('+') ? countryCode : `+${countryCode}`,
|
|
phoneNumber: cleanPhoneNumber,
|
|
});
|
|
},
|
|
|
|
verifyOtp: (countryCode: string, phoneNumber: string, otp: string) =>
|
|
apiClient.post('/api/auth/register/verify', { countryCode, phoneNumber, otp }),
|
|
|
|
setEmail: (email: string) => {
|
|
// Use the stored token from localStorage
|
|
const storedToken = localStorage.getItem('accessToken');
|
|
if (!storedToken) {
|
|
throw new Error('No access token found');
|
|
}
|
|
return apiClient.post('/api/auth/register/set-email', { email });
|
|
},
|
|
|
|
setPasscode: (passcode: string) => {
|
|
// Use the stored token from localStorage
|
|
const storedToken = localStorage.getItem('accessToken');
|
|
if (!storedToken) {
|
|
throw new Error('No access token found');
|
|
}
|
|
return apiClient.post('/api/auth/register/set-passcode', { passcode });
|
|
},
|
|
|
|
login: ({ grantType, email, password, appleToken, googleToken }: LoginRequest) =>
|
|
apiClient.post('/api/auth/login', {
|
|
grantType,
|
|
email,
|
|
password,
|
|
appleToken,
|
|
googleToken,
|
|
fcmToken: 'web-client-token', // Required by API
|
|
signature: 'web-login', // Required by API
|
|
}),
|
|
};
|
|
|
|
// Juniors API
|
|
export const juniorsApi = {
|
|
createJunior: (data: CreateJuniorRequest) => apiClient.post('/api/juniors', data),
|
|
|
|
getJuniors: (page = 1, size = 10) => apiClient.get(`/api/juniors?page=${page}&size=${size}`),
|
|
|
|
getJunior: (juniorId: string) => apiClient.get(`/api/juniors/${juniorId}`),
|
|
|
|
setTheme: (data: JuniorTheme) => apiClient.post('/api/juniors/set-theme', data),
|
|
|
|
getQrCode: (juniorId: string) => apiClient.get(`/api/juniors/${juniorId}/qr-code`),
|
|
|
|
validateQrCode: (token: string) => apiClient.get(`/api/juniors/qr-code/${token}/validate`),
|
|
};
|
|
|
|
// Document API
|
|
export const documentApi = {
|
|
upload: (file: File, documentType: string) => {
|
|
const formData = new FormData();
|
|
formData.append('document', file);
|
|
formData.append('documentType', documentType);
|
|
return apiClient.post('/api/document', formData, {
|
|
headers: {
|
|
'Content-Type': 'multipart/form-data',
|
|
},
|
|
});
|
|
},
|
|
};
|
|
|
|
// Tasks API
|
|
export const tasksApi = {
|
|
createTask: (data: CreateTaskRequest) => apiClient.post('/api/tasks', data),
|
|
|
|
getTasks: (status: TaskStatus, page = 1, size = 10, juniorId?: string) => {
|
|
const url = new URL('/api/tasks', API_BASE_URL);
|
|
url.searchParams.append('status', status);
|
|
url.searchParams.append('page', page.toString());
|
|
url.searchParams.append('size', size.toString());
|
|
if (juniorId) url.searchParams.append('juniorId', juniorId);
|
|
return apiClient.get(url.pathname + url.search);
|
|
},
|
|
|
|
getTaskById: (taskId: string) => apiClient.get(`/api/tasks/${taskId}`),
|
|
|
|
submitTask: (taskId: string, data: TaskSubmission) => apiClient.patch(`/api/tasks/${taskId}/submit`, data),
|
|
|
|
approveTask: (taskId: string) => apiClient.patch(`/api/tasks/${taskId}/approve`),
|
|
|
|
rejectTask: (taskId: string) => apiClient.patch(`/api/tasks/${taskId}/reject`),
|
|
};
|