feat: implement barangay system phases 2-14
Complete adaptation from BukidBountyApp to Philippine barangay governance: - Barangay models: Resident, Household, HouseholdMember, Blotter, BlotterHearing, DocumentRequest, RequestPayment, RequestType, BarangayProject, BarangayBudget - Controllers: ResidentController, HouseholdController, BlotterController, BlotterHearingController, DocumentRequestController, RequestTypeController, ProjectController, BudgetController, QRPHController, AdminConsoleController, UserController, FileController, ChapterController, LoginController - Vue pages: Home, ManageResidents, ResidentProfile, ManageHouseholds, ManageBlotters, BlotterDetail, RequestDocument, ManageDocumentRequests, DocumentRequestDetail, ManageRequestTypes, ManageProjects, BudgetLedger, AdminConsole - Barangay roles: PunongBarangay, Kagawad, Secretary, Treasurer, SK, Tanod, BHW, Staff, Resident - UserPermissions matrix rewritten with barangay-specific permission mappings - VueRouteMap replaced with barangay SPA routes - UserActions enum references corrected across all controllers - Removed all market/cooperative/POS/subscription code and models
This commit is contained in:
@@ -1,53 +1,35 @@
|
||||
import { ref, computed, onMounted } from 'vue';
|
||||
import { ref, computed } from 'vue';
|
||||
import axios from 'axios';
|
||||
import { UserTypes } from '../../utils/UserTypes.js';
|
||||
import { UserTypes, ADMIN_ROLES, STAFF_ROLES } 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;
|
||||
}
|
||||
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 && 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();
|
||||
}
|
||||
@@ -58,90 +40,79 @@ export function resetRole() {
|
||||
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) {
|
||||
} catch {
|
||||
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);
|
||||
}
|
||||
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);
|
||||
// Barangay-specific role helpers
|
||||
const isSuperAdmin = computed(() => role.value === UserTypes.SUPER_ADMIN);
|
||||
const isPunongBarangay = computed(() => role.value === UserTypes.PUNONG_BARANGAY);
|
||||
const isKagawad = computed(() => role.value === UserTypes.KAGAWAD);
|
||||
const isSecretary = computed(() => role.value === UserTypes.SECRETARY);
|
||||
const isTreasurer = computed(() => role.value === UserTypes.TREASURER);
|
||||
const isSkChairperson = computed(() => role.value === UserTypes.SK_CHAIRPERSON);
|
||||
const isSkCouncilor = computed(() => role.value === UserTypes.SK_COUNCILOR);
|
||||
const isTanod = computed(() => role.value === UserTypes.TANOD);
|
||||
const isBhw = computed(() => role.value === UserTypes.BHW);
|
||||
const isDaycareWorker = computed(() => role.value === UserTypes.DAYCARE_WORKER);
|
||||
const isStaff = computed(() => role.value === UserTypes.STAFF);
|
||||
const isResident = computed(() => role.value === UserTypes.RESIDENT);
|
||||
const isAudit = computed(() => role.value === UserTypes.AUDIT);
|
||||
const isPublic = computed(() => role.value === UserTypes.PUBLIC || !userStore.isLoggedIn);
|
||||
const isLoggedIn = computed(() => userStore.isLoggedIn);
|
||||
|
||||
// Group helpers
|
||||
const isAdmin = computed(() => ADMIN_ROLES.includes(role.value));
|
||||
const isBarangayStaff = computed(() => STAFF_ROLES.includes(role.value));
|
||||
|
||||
return {
|
||||
user: currentUser,
|
||||
role,
|
||||
hasRole,
|
||||
isUltimate,
|
||||
isSuperOperator,
|
||||
isOperator,
|
||||
isCoordinator,
|
||||
isStoreOwner,
|
||||
isStoreManager,
|
||||
isRider,
|
||||
isSupplier,
|
||||
isSupplierOverseer,
|
||||
isWholesaleBuyer,
|
||||
isSuperAdmin,
|
||||
isPunongBarangay,
|
||||
isKagawad,
|
||||
isSecretary,
|
||||
isTreasurer,
|
||||
isSkChairperson,
|
||||
isSkCouncilor,
|
||||
isTanod,
|
||||
isBhw,
|
||||
isDaycareWorker,
|
||||
isStaff,
|
||||
isResident,
|
||||
isAudit,
|
||||
isUser,
|
||||
isCoopOfficer,
|
||||
isCoopMember,
|
||||
isPOSTerminal,
|
||||
isPublic,
|
||||
isLoggedIn,
|
||||
isAdmin,
|
||||
isBarangayStaff,
|
||||
UserTypes,
|
||||
refreshRole: fetchRole,
|
||||
// Expose the user store for direct access to user data
|
||||
userStore
|
||||
userStore,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user