import api from './api'; export interface User { id: string; firstName: string; lastName: string; email: string; mobile: string | null; role: string; walletBalance: number; charityDonationTotal: number; hasPassword?: boolean; password?: string; currentPassword?: string; createdAt: string; updatedAt: string; pets?: unknown[]; orders?: unknown[]; } export interface AuthResponse { success: boolean; data: { user: User; accessToken: string; }; } interface ApiErr { response?: { status?: number; data?: { message?: string | string[]; }; }; } export class AuthService { private static instance: AuthService; private constructor() {} public static getInstance(): AuthService { if (!AuthService.instance) { AuthService.instance = new AuthService(); } return AuthService.instance; } /** * Send SMS verification code (OTP) */ public async sendOtp(phoneNumber: string): Promise<{ success: boolean; message: string }> { try { const response = await api.post('/auth/send-otp', { phoneNumber }); return response.data; } catch (error) { const err = error as ApiErr; const message = err.response?.data?.message || 'خطا در ارسال کد تایید'; throw new Error(Array.isArray(message) ? message[0] : message); } } /** * Verify SMS verification code and login/register */ public async verifyOtp(phoneNumber: string, code: string): Promise { try { const response = await api.post('/auth/verify-otp', { phoneNumber, code }); const { data } = response.data; if (data?.accessToken) { localStorage.setItem('accessToken', data.accessToken); } return response.data; } catch (error) { const err = error as ApiErr; const message = err.response?.data?.message || 'کد تایید نامعتبر است'; throw new Error(Array.isArray(message) ? message[0] : message); } } /** * Register with email/mobile and password */ public async register(data: Record): Promise { try { const response = await api.post('/auth/register', data); const { data: resData } = response.data; if (resData?.accessToken) { localStorage.setItem('accessToken', resData.accessToken); } return response.data; } catch (error) { const err = error as ApiErr; const message = err.response?.data?.message || 'خطا در ثبت‌نام'; throw new Error(Array.isArray(message) ? message[0] : message); } } /** * Login with mobile and password */ public async login(mobile: string, password: string): Promise { try { const response = await api.post('/auth/login', { mobile, password }); const { data } = response.data; if (data?.accessToken) { localStorage.setItem('accessToken', data.accessToken); } return response.data; } catch (error) { const err = error as ApiErr; const message = err.response?.data?.message || 'نام کاربری یا رمز عبور اشتباه است'; throw new Error(Array.isArray(message) ? message[0] : message); } } /** * Get current user profile */ public async getProfile(): Promise { try { const response = await api.get('/users/profile', { hideErrorToast: true } as unknown as import('axios').AxiosRequestConfig); return response.data; } catch (error) { const err = error as ApiErr; if (err.response?.status === 401 || err.response?.status === 403) { return null; } const message = err.response?.data?.message || 'خطا در دریافت اطلاعات کاربری'; throw new Error(Array.isArray(message) ? message[0] : message); } } /** * Update current user profile */ public async updateProfile(profileData: Partial): Promise { try { const response = await api.patch('/users/profile', profileData); return response.data; } catch (error) { const err = error as ApiErr; const message = err.response?.data?.message || 'خطا در ویرایش اطلاعات کاربری'; throw new Error(Array.isArray(message) ? message[0] : message); } } /** * Logout user and clear tokens */ public logout(): void { localStorage.removeItem('accessToken'); } } export const authService = AuthService.getInstance();