Files
KLC-Hr-Dashboard-Frontend/src/context/AuthContext.tsx
2026-04-10 16:38:25 +05:30

136 lines
3.7 KiB
TypeScript

// src/context/AuthContext.tsx
import { createContext, useContext, useState, useEffect } from "react";
import type { ReactNode } from "react";
import { useNavigate } from "react-router-dom";
import { useToast } from "../components/toast/useToast";
import { useLoginMutation, UserInfo } from "../redux/services/loginApi";
interface AuthContextType {
user: UserInfo | null;
login: (email: string, password: string) => Promise<void>;
logout: () => void;
isAuthenticated: boolean;
token: string | null;
}
const AuthContext = createContext<AuthContextType | undefined>(undefined);
export const AuthProvider = ({ children }: { children: ReactNode }) => {
const [user, setUser] = useState<UserInfo | null>(() => {
const storedUser = localStorage.getItem("user");
if (storedUser) {
try {
// Try to parse as JSON first
return JSON.parse(storedUser);
} catch {
// If it fails (like "admin" string), return null or handle accordingly
return null;
}
}
return null;
});
const [token, setToken] = useState<string | null>(() => {
const storedToken = localStorage.getItem("token");
return storedToken || null;
});
const navigate = useNavigate();
const { showToast } = useToast();
const [loginMutation] = useLoginMutation();
const login = async (email: string, password: string) => {
try {
const response = await loginMutation({
email_address: email,
password
}).unwrap();
if (response.success) {
// Store token and user info
localStorage.setItem("token", response.data.access_token);
localStorage.setItem("user", JSON.stringify(response.data.user_info));
setToken(response.data.access_token);
setUser(response.data.user_info);
showToast(
"Login Successful",
response.message || "You have been logged in successfully.",
"success"
);
navigate("/hr/dashboard");
} else {
showToast(
"Login Failed",
response.message || "Invalid credentials. Please try again.",
"error"
);
}
} catch (error: any) {
console.error("Login error:", error);
showToast(
"Error",
error.data?.message || error.message || "An error occurred during login",
"error"
);
}
};
const logout = () => {
localStorage.removeItem("token");
localStorage.removeItem("user");
setToken(null);
setUser(null);
showToast(
"Logged Out",
"You have been logged out successfully.",
"success"
);
navigate("/login");
};
const isAuthenticated = !!token && !!user;
// Optional: Add token expiration check
useEffect(() => {
if (token) {
try {
// Decode token to check expiration (if needed)
const payload = JSON.parse(atob(token.split('.')[1]));
const exp = payload.exp * 1000; // Convert to milliseconds
const now = Date.now();
if (now >= exp) {
// Token expired
logout();
showToast(
"Session Expired",
"Your session has expired. Please login again.",
"error"
);
}
} catch (error) {
// Invalid token format
console.error("Error checking token expiration:", error);
}
}
}, [token]);
return (
<AuthContext.Provider value={{ user, login, logout, isAuthenticated, token }}>
{children}
</AuthContext.Provider>
);
};
export const useAuth = () => {
const ctx = useContext(AuthContext);
if (!ctx) throw new Error("useAuth must be used inside AuthProvider");
return ctx;
};