- Enhance RequestPermitModal with multiple time-off types and validation - Implement CalendarWidget for visualizing time-off requests - Improve API error handling and token management - Add utility functions for consistent date and time formatting - Clean up unused mock data and update types
130 lines
4.5 KiB
TypeScript
130 lines
4.5 KiB
TypeScript
import { createContext, PropsWithChildren, useContext, useEffect, useState } from 'react';
|
|
import { SplashScreen, useRouter, useSegments } from 'expo-router';
|
|
import { UserData } from '@/types/types';
|
|
import * as SecureStore from 'expo-secure-store';
|
|
import api, { KEY_TOKEN } from './api';
|
|
|
|
type AuthState = {
|
|
isAuthenticated: boolean;
|
|
isReady: boolean;
|
|
user: UserData | null;
|
|
logIn: (token: string, userData: UserData) => void;
|
|
logOut: () => void;
|
|
};
|
|
|
|
SplashScreen.preventAutoHideAsync();
|
|
|
|
export const AuthContext = createContext<AuthState>({
|
|
isAuthenticated: false,
|
|
isReady: false,
|
|
user: null,
|
|
logIn: () => { },
|
|
logOut: () => { },
|
|
});
|
|
|
|
export const useAuth = () => useContext(AuthContext);
|
|
|
|
export function AuthProvider({ children }: PropsWithChildren) {
|
|
const [isReady, setIsReady] = useState(false);
|
|
const [isAuthenticated, setIsAuthenticated] = useState(false);
|
|
const [user, setUser] = useState<UserData | null>(null);
|
|
const router = useRouter();
|
|
const segments = useSegments();
|
|
|
|
const logIn = async (token: string, userData: UserData) => {
|
|
try {
|
|
await SecureStore.setItemAsync(KEY_TOKEN, token);
|
|
setIsAuthenticated(true);
|
|
setUser(userData);
|
|
|
|
router.replace('/');
|
|
} catch (error) {
|
|
console.error('Errore durante il login:', error);
|
|
}
|
|
};
|
|
|
|
const logOut = async () => {
|
|
try {
|
|
await SecureStore.deleteItemAsync(KEY_TOKEN);
|
|
setIsAuthenticated(false);
|
|
setUser(null);
|
|
|
|
router.replace('/login');
|
|
} catch (error) {
|
|
console.error('Errore durante il logout:', error);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
const initApp = async () => {
|
|
try {
|
|
// 1. Recupero Token salvato
|
|
const savedToken = await SecureStore.getItemAsync(KEY_TOKEN);
|
|
|
|
if (savedToken) {
|
|
console.log("Token trovato: ", savedToken);
|
|
|
|
// 2. Chiamata al backend per verificare il token e scaricare i dati utente
|
|
// Nota: api.ts aggiunge già l'header Authorization grazie all'interceptor (se configurato per leggere da SecureStore)
|
|
// Se il tuo api.ts legge da AsyncStorage, assicurati che siano allineati, altrimenti passalo a mano qui:
|
|
const response = await api.get("/user/info", {
|
|
headers: { Authorization: `Bearer ${savedToken}` }
|
|
});
|
|
|
|
const result = response.data;
|
|
const userData = result.user;
|
|
console.log("Sessione valida, dati utente caricati:", userData);
|
|
|
|
// 3. Mappatura dati (Backend -> Frontend)
|
|
// Il backend actionMe ritorna: { id, username, role }
|
|
const loadedUser: UserData = {
|
|
id: userData.id,
|
|
username: userData.username,
|
|
role: userData.role,
|
|
// Gestiamo i campi opzionali se il backend non li manda ancora
|
|
name: userData.name,
|
|
surname: userData.surname || '',
|
|
email: userData.email || '',
|
|
};
|
|
|
|
setUser(loadedUser);
|
|
setIsAuthenticated(true);
|
|
} else {
|
|
console.log("Nessun token salvato.");
|
|
}
|
|
|
|
} catch (error: any) {
|
|
console.error('Errore inizializzazione (Token scaduto o Server down):', error.message);
|
|
|
|
// Se il token non è valido, puliamo tutto
|
|
await SecureStore.deleteItemAsync(KEY_TOKEN);
|
|
setIsAuthenticated(false);
|
|
setUser(null);
|
|
} finally {
|
|
setIsReady(true);
|
|
await SplashScreen.hideAsync();
|
|
}
|
|
};
|
|
|
|
initApp();
|
|
}, []);
|
|
|
|
// Protezione rotte (opzionale, ma consigliata qui o nel Layout)
|
|
useEffect(() => {
|
|
if (!isReady) return;
|
|
|
|
const inAuthGroup = segments[0] === '(protected)';
|
|
|
|
if (!isAuthenticated && inAuthGroup) {
|
|
router.replace('/login');
|
|
} else if (isAuthenticated && !inAuthGroup) {
|
|
router.replace('/');
|
|
}
|
|
}, [isReady, isAuthenticated, segments]);
|
|
|
|
return (
|
|
<AuthContext.Provider value={{ isReady, isAuthenticated, user, logIn, logOut }}>
|
|
{children}
|
|
</AuthContext.Provider>
|
|
);
|
|
} |