// /composables/useAuth.ts interface User { id: string; email: string; nickname: string; } export function useAuth() { // All Nuxt composables that require instance access MUST be called inside the setup function. // useState is how we create shared, SSR-safe state in Nuxt. const user = useState('user', () => null); const initialized = useState('auth_initialized', () => false); const loading = ref(false); // This is a local, non-shared loading ref for fetchMe's internal use const api = useApi(); const isAuthenticated = computed(() => !!user.value); const fetchMe = async () => { if (initialized.value) return; loading.value = true; initialized.value = true; try { user.value = await api('/auth/me', { method: 'GET' }); } catch (error) { user.value = null; // Silently set user to null } finally { loading.value = false; } }; const login = async (email, password) => { // The calling component is responsible for its own loading state. // This function just performs the action. await api('/auth/login', { method: 'POST', body: { email, password }, }); // After a successful login, allow a re-fetch of the user state. initialized.value = false; await fetchMe(); }; const logout = async () => { try { await api('/auth/logout', { method: 'POST' }); } finally { // Always clear state and redirect, regardless of API call success. user.value = null; initialized.value = false; await navigateTo('/login'); } }; // Expose the state and methods. return { user, isAuthenticated, initialized, fetchMe, login, logout, }; }