mirror of
https://github.com/HamzaSha1/zod-backend.git
synced 2025-08-25 05:42:27 +00:00
120 lines
3.7 KiB
TypeScript
120 lines
3.7 KiB
TypeScript
import React, { createContext, useCallback, useContext, useState } from 'react';
|
|
import { authApi } from '../api/client';
|
|
import { LoginRequest, LoginResponse, User } from '../types/auth';
|
|
|
|
interface AuthContextType {
|
|
isAuthenticated: boolean;
|
|
user: User | null;
|
|
login: (loginRequest: LoginRequest) => Promise<void>;
|
|
logout: () => void;
|
|
register: (countryCode: string, phoneNumber: string) => Promise<void>;
|
|
verifyOtp: (countryCode: string, phoneNumber: string, otp: string) => Promise<string>;
|
|
setEmail: (email: string) => Promise<void>;
|
|
setPasscode: (passcode: string) => Promise<void>;
|
|
}
|
|
|
|
const AuthContext = createContext<AuthContextType | null>(null);
|
|
|
|
export const useAuth = () => {
|
|
const context = useContext(AuthContext);
|
|
if (!context) {
|
|
throw new Error('useAuth must be used within an AuthProvider');
|
|
}
|
|
return context;
|
|
};
|
|
|
|
export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
|
const [isAuthenticated, setIsAuthenticated] = useState(false);
|
|
const [user, setUser] = useState<User | null>(null);
|
|
|
|
const login = useCallback(async (loginRequest: LoginRequest) => {
|
|
try {
|
|
const response = await authApi.login(loginRequest);
|
|
const loginData = response.data.data as LoginResponse;
|
|
setUser(loginData.user);
|
|
// Store tokens
|
|
localStorage.setItem('accessToken', loginData.accessToken);
|
|
localStorage.setItem('refreshToken', loginData.refreshToken);
|
|
setIsAuthenticated(true);
|
|
// Store tokens or other auth data in localStorage if needed
|
|
} catch (error) {
|
|
console.error('Login failed:', error);
|
|
throw error;
|
|
}
|
|
}, []);
|
|
|
|
const logout = useCallback(() => {
|
|
setUser(null);
|
|
setIsAuthenticated(false);
|
|
// Clear any stored auth data
|
|
localStorage.clear();
|
|
}, []);
|
|
|
|
// Registration state
|
|
const [registrationData, setRegistrationData] = useState<{
|
|
countryCode?: string;
|
|
phoneNumber?: string;
|
|
email?: string;
|
|
token?: string;
|
|
}>({});
|
|
|
|
const register = useCallback(async (countryCode: string, phoneNumber: string) => {
|
|
try {
|
|
await authApi.register(countryCode, phoneNumber);
|
|
setRegistrationData({ countryCode, phoneNumber });
|
|
} catch (error) {
|
|
console.error('Registration failed:', error);
|
|
throw error;
|
|
}
|
|
}, []);
|
|
|
|
const verifyOtp = useCallback(async (countryCode: string, phoneNumber: string, otp: string) => {
|
|
try {
|
|
const response = await authApi.verifyOtp(countryCode, phoneNumber, otp);
|
|
console.log('OTP verification response:', response.data);
|
|
const { accessToken } = response.data.data;
|
|
console.log('Access token:', accessToken);
|
|
// Store token in localStorage immediately
|
|
localStorage.setItem('accessToken', accessToken);
|
|
setRegistrationData((prev) => ({ ...prev, token: accessToken }));
|
|
return accessToken;
|
|
} catch (error) {
|
|
console.error('OTP verification failed:', error);
|
|
throw error;
|
|
}
|
|
}, []);
|
|
|
|
const setEmail = useCallback(async (email: string) => {
|
|
try {
|
|
await authApi.setEmail(email);
|
|
setRegistrationData((prev) => ({ ...prev, email }));
|
|
} catch (error) {
|
|
console.error('Setting email failed:', error);
|
|
throw error;
|
|
}
|
|
}, []);
|
|
|
|
const setPasscode = useCallback(async (passcode: string) => {
|
|
try {
|
|
await authApi.setPasscode(passcode);
|
|
setIsAuthenticated(true);
|
|
} catch (error) {
|
|
console.error('Setting passcode failed:', error);
|
|
throw error;
|
|
}
|
|
}, []);
|
|
|
|
const value = {
|
|
isAuthenticated,
|
|
user,
|
|
login,
|
|
logout,
|
|
register,
|
|
verifyOtp,
|
|
setEmail,
|
|
setPasscode,
|
|
};
|
|
|
|
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
|
|
};
|