Files
BarangaySystem/resources/js/composables/Core/useAuth.js
2026-06-06 18:43:00 +08:00

148 lines
5.2 KiB
JavaScript

import { ref, computed, onMounted } from 'vue';
import axios from 'axios';
import { UserTypes } from '../../utils/UserTypes.js';
import { useUserStore } from '../../stores/user.js';
// Global reactive state to persist throughout the SPA session
const globalRole = ref(sessionStorage.getItem('user_acct_type') || UserTypes.PUBLIC);
const isFetching = ref(false);
/**
* Fetches the user account type from the server.
* Ensures only one request is made per session.
*/
async function fetchRole() {
if (isFetching.value) return;
// If we already have a specialized role in sessionStorage, don't fetch again
const cached = sessionStorage.getItem('user_acct_type');
if (cached && cached !== UserTypes.PUBLIC) {
return;
}
isFetching.value = true;
try {
const response = await axios.get('/get/user/acct-type');
let acctType = response.data?.acct_type;
// Handle case where acct_type might be an object (Enum serialization)
if (acctType && typeof acctType === 'object' && acctType.value) {
acctType = acctType.value;
}
if (acctType) {
globalRole.value = acctType;
sessionStorage.setItem('user_acct_type', acctType);
}
} catch (error) {
// If 401, we are likely a guest
if (error.response?.status === 401) {
globalRole.value = UserTypes.PUBLIC;
sessionStorage.setItem('user_acct_type', UserTypes.PUBLIC);
} else {
console.warn('Failed to fetch user acct type from server:', error);
}
} finally {
isFetching.value = false;
}
}
// Initial fetch attempt if we don't have a definitive role
if (!sessionStorage.getItem('user_acct_type') || sessionStorage.getItem('user_acct_type') === UserTypes.PUBLIC) {
fetchRole();
}
export function resetRole() {
globalRole.value = UserTypes.PUBLIC;
isFetching.value = false;
sessionStorage.removeItem('user_acct_type');
}
/**
* Composable for managing user roles and permissions in the frontend.
* @param {Object} [user] - Optional user object for legacy support or specific overrides
*/
export function useAuth(user = null) {
const userStore = useUserStore();
// Priority: Explicitly passed user prop > user store > sessionStorage fallback
const currentUser = computed(() => {
if (user?.value ?? user) return user?.value ?? user;
const storeUser = userStore.user;
if (storeUser && Object.keys(storeUser).length > 0) return storeUser;
try {
const stored = sessionStorage.getItem('currentUser');
return stored ? JSON.parse(stored) : null;
} catch (e) {
return null;
}
});
const role = computed(() => {
// Priority 1: User object passed directly or from store
const localRole = userStore.acctType || currentUser.value?.acct_type;
if (localRole) {
if (typeof localRole === 'object' && localRole.value) return localRole.value;
return localRole;
}
// Priority 2: Global fetched role
return globalRole.value;
});
const hasRole = (targetRole) => {
if (Array.isArray(targetRole)) {
return targetRole.some(r => role.value === r);
}
return role.value === targetRole;
};
// Role-specific helpers
const isUltimate = computed(() => role.value === UserTypes.ULTIMATE);
const isSuperOperator = computed(() => role.value === UserTypes.SUPER_OPERATOR);
const isOperator = computed(() => role.value === UserTypes.OPERATOR);
const isCoordinator = computed(() => role.value === UserTypes.COORDINATOR);
const isStoreOwner = computed(() => role.value === UserTypes.STORE_OWNER);
const isStoreManager = computed(() => role.value === UserTypes.STORE_MANAGER);
const isRider = computed(() => role.value === UserTypes.RIDER);
const isSupplier = computed(() => role.value === UserTypes.SUPPLIER);
const isSupplierOverseer = computed(() => role.value === UserTypes.SUPPLIER_OVERSEER);
const isWholesaleBuyer = computed(() => role.value === UserTypes.WHOLESALE_BUYER);
const isAudit = computed(() => role.value === UserTypes.AUDIT);
const isUser = computed(() => role.value === UserTypes.USER);
const isCoopOfficer = computed(() => role.value === UserTypes.COOP_OFFICER);
const isCoopMember = computed(() => role.value === UserTypes.COOP_MEMBER);
const isPOSTerminal = computed(() => role.value === UserTypes.POS_TERMINAL);
const isPublic = computed(() => role.value === UserTypes.PUBLIC || !userStore.isLoggedIn);
const isLoggedIn = computed(() => userStore.isLoggedIn);
return {
user: currentUser,
role,
hasRole,
isUltimate,
isSuperOperator,
isOperator,
isCoordinator,
isStoreOwner,
isStoreManager,
isRider,
isSupplier,
isSupplierOverseer,
isWholesaleBuyer,
isAudit,
isUser,
isCoopOfficer,
isCoopMember,
isPOSTerminal,
isPublic,
isLoggedIn,
UserTypes,
refreshRole: fetchRole,
// Expose the user store for direct access to user data
userStore
};
}