- Add Reports page with population/household/document/blotter/budget/project views - Add ReportsController with year-filtered queries for all report types - Add /reports module to config/modules.php - Register /barangay/reports in VueRouteMap and web.php - Remove unused market Home fragments (HomeCoopMember, HomeStoreOwner, etc.) - Remove leftover market Components/Market/ directory - Add Reports card to Home.vue admin quick access
106 lines
5.0 KiB
Vue
106 lines
5.0 KiB
Vue
<script setup>
|
|
import { ref, onMounted } from 'vue';
|
|
import { usePageTitle } from '../composables/Core/usePageTitle';
|
|
import { useAuth } from '../composables/Core/useAuth.js';
|
|
import { useUIStore } from '../stores/ui';
|
|
import { executeRequest } from '../utils/executeRequest.js';
|
|
import { navigate } from '../utils/navigate.js';
|
|
|
|
const uiStore = useUIStore();
|
|
usePageTitle(uiStore.appName ?? 'Barangay System');
|
|
|
|
const { isSuperAdmin, isPunongBarangay, isAdmin, isBarangayStaff, isResident, role } = useAuth();
|
|
|
|
const stats = ref({});
|
|
const loading = ref(false);
|
|
|
|
const loadStats = async () => {
|
|
loading.value = true;
|
|
try {
|
|
const res = await executeRequest('/home-data');
|
|
if (res?.props?.stats) stats.value = res.props.stats;
|
|
} catch (e) { /* silent */ }
|
|
loading.value = false;
|
|
};
|
|
|
|
const adminCards = [
|
|
{ label: 'Residents', icon: '👥', route: '/Barangay/ManageResidents', color: 'bg-blue-500' },
|
|
{ label: 'Households', icon: '🏠', route: '/Barangay/ManageHouseholds', color: 'bg-green-500' },
|
|
{ label: 'Blotters', icon: '⚖️', route: '/Barangay/ManageBlotters', color: 'bg-orange-500' },
|
|
{ label: 'Documents', icon: '📋', route: '/Barangay/ManageDocumentRequests', color: 'bg-purple-500' },
|
|
{ label: 'Projects', icon: '🏗️', route: '/Barangay/ManageProjects', color: 'bg-indigo-500' },
|
|
{ label: 'Budget', icon: '💰', route: '/Barangay/BudgetLedger', color: 'bg-emerald-500' },
|
|
{ label: 'Announcements', icon: '📢', route: '/ManageAnnouncements', color: 'bg-yellow-500' },
|
|
{ label: 'Reports', icon: '📊', route: '/barangay/reports', color: 'bg-rose-500' },
|
|
{ label: 'Settings', icon: '⚙️', route: '/SystemSettings', color: 'bg-gray-500' },
|
|
];
|
|
|
|
const serviceCards = [
|
|
{ label: 'Request Document', icon: '📄', route: '/Barangay/RequestDocument', color: 'bg-blue-500' },
|
|
{ label: 'View Announcements', icon: '📢', route: '/ManageAnnouncements', color: 'bg-yellow-500' },
|
|
];
|
|
|
|
onMounted(loadStats);
|
|
</script>
|
|
|
|
<template>
|
|
<div class="p-4 max-w-5xl mx-auto">
|
|
<div class="mb-6">
|
|
<h1 class="text-2xl font-bold text-gray-800">Barangay Management System</h1>
|
|
<p class="text-gray-500 text-sm mt-1">Welcome. Here's today's overview.</p>
|
|
</div>
|
|
|
|
<!-- Stats (admin/staff) -->
|
|
<div v-if="isBarangayStaff" class="grid grid-cols-2 sm:grid-cols-4 gap-3 mb-5">
|
|
<div class="bg-white rounded-xl shadow p-4 text-center">
|
|
<div class="text-3xl font-bold text-blue-600">{{ stats.total_residents ?? 0 }}</div>
|
|
<div class="text-xs text-gray-500 mt-1">Residents</div>
|
|
</div>
|
|
<div class="bg-white rounded-xl shadow p-4 text-center">
|
|
<div class="text-3xl font-bold text-green-600">{{ stats.total_households ?? 0 }}</div>
|
|
<div class="text-xs text-gray-500 mt-1">Households</div>
|
|
</div>
|
|
<div class="bg-white rounded-xl shadow p-4 text-center">
|
|
<div class="text-3xl font-bold text-orange-600">{{ stats.open_blotters ?? 0 }}</div>
|
|
<div class="text-xs text-gray-500 mt-1">Open Blotters</div>
|
|
</div>
|
|
<div class="bg-white rounded-xl shadow p-4 text-center">
|
|
<div class="text-3xl font-bold text-purple-600">{{ stats.pending_documents ?? 0 }}</div>
|
|
<div class="text-xs text-gray-500 mt-1">Pending Docs</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Quick Access (admin/staff) -->
|
|
<div v-if="isBarangayStaff" class="mb-6">
|
|
<h2 class="text-lg font-semibold text-gray-700 mb-3">Quick Access</h2>
|
|
<div class="grid grid-cols-2 sm:grid-cols-4 gap-3">
|
|
<button
|
|
v-for="card in adminCards"
|
|
:key="card.label"
|
|
@click="navigate(card.route)"
|
|
:class="`${card.color} text-white rounded-xl p-4 flex flex-col items-center gap-2 hover:opacity-90 transition`"
|
|
>
|
|
<span class="text-3xl">{{ card.icon }}</span>
|
|
<span class="text-sm font-medium">{{ card.label }}</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Services (resident) -->
|
|
<div v-if="isResident" class="mb-6">
|
|
<h2 class="text-lg font-semibold text-gray-700 mb-3">Services Available to You</h2>
|
|
<div class="grid grid-cols-2 gap-3">
|
|
<button
|
|
v-for="card in serviceCards"
|
|
:key="card.label"
|
|
@click="navigate(card.route)"
|
|
:class="`${card.color} text-white rounded-xl p-5 flex flex-col items-center gap-2 hover:opacity-90 transition`"
|
|
>
|
|
<span class="text-4xl">{{ card.icon }}</span>
|
|
<span class="text-sm font-medium">{{ card.label }}</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|