Files
BarangaySystem/resources/js/Pages/Fragments/Home/HomePublic.vue
2026-06-06 18:43:00 +08:00

178 lines
5.6 KiB
Vue

<script setup>
import { ref, computed, onMounted } from 'vue';
import axios from 'axios';
import { useNavigate } from '../../../composables/Core/useNavigate.js';
// Core Components
import ServiceButtonGrid from '../../../Components/Core/Services/ServiceButtonGrid.vue';
import SideTextButtonList from '../../../Components/Core/Services/SideTextButtonList.vue';
import CardSimple from '../../../Components/Core/CardSimple.vue';
import GlobalAnnouncement from '../../../Components/GlobalAnnouncement.vue';
import { useUIStore } from '../../../stores/ui';
const { navigate } = useNavigate();
const uiStore = useUIStore();
const landingPageHtml = ref(null);
const hasLandingPage = ref(false);
const loadingLanding = ref(true);
// Fetch the active landing page
const fetchLandingPage = async () => {
loadingLanding.value = true;
try {
const res = await axios.get('/api/public/landing-page');
if (res.data.success && res.data.has_landing_page && res.data.data) {
landingPageHtml.value = res.data.data.html_content;
hasLandingPage.value = true;
uiStore.setFullWidth(true);
// Hide global app UI for a clean landing page experience
uiStore.setHeaderVisibility(false);
uiStore.setBottomNavVisibility(false);
} else {
hasLandingPage.value = false;
uiStore.setFullWidth(false);
uiStore.setHeaderVisibility(true);
uiStore.setBottomNavVisibility(true);
}
} catch (err) {
hasLandingPage.value = false;
uiStore.setFullWidth(false);
uiStore.setHeaderVisibility(true);
uiStore.setBottomNavVisibility(true);
} finally {
loadingLanding.value = false;
}
};
// Also ensure we reset full width if this fragment is unmounted
import { onUnmounted, watch } from 'vue';
onUnmounted(() => {
uiStore.setFullWidth(false);
uiStore.setHeaderVisibility(true);
uiStore.setBottomNavVisibility(true);
});
// Watch for changes in hasLandingPage to update UI store
watch(hasLandingPage, (newVal) => {
uiStore.setFullWidth(newVal);
});
onMounted(() => {
fetchLandingPage();
});
// Services for public users (no auth required)
const services = computed(() => [
{ icon: 'https://cdn.jsdelivr.net/gh/telemagnadon/obj-vault-3a@v2026.05.14-vendor-2/a/938032617d05.bin', title: 'Market', pagename: 'ListProductsMarket' },
{ icon: 'https://cdn.jsdelivr.net/gh/telemagnadon/obj-vault-3a@v2026.05.14-vendor-2/a/85605eacd4c8.bin', title: 'Stores', pagename: 'ListStores' },
]);
// Quick actions for public users
const quickActionsItems = computed(() => [
{ text: 'Browse Products', pagename: 'ListProductsMarket', icon: 'https://cdn.jsdelivr.net/gh/telemagnadon/obj-vault-3a@v2026.05.14-vendor-2/a/f0a0193d728e.bin' },
{ text: 'View Available Stores', pagename: 'ListStores', icon: 'https://cdn.jsdelivr.net/gh/telemagnadon/obj-vault-3a@v2026.05.14-vendor-2/a/85605eacd4c8.bin' },
]);
const handleItemClick = (item) => {
if (item.pagename) {
navigate({ page: item.pagename, props: { data: item.pagestring || '' } });
}
};
const goToLogin = () => {
navigate({ page: 'Auth.Login' });
};
</script>
<template>
<div class="home-public-fragment">
<!-- Loading state -->
<div v-if="loadingLanding" class="text-center py-5">
<div class="spinner-border text-primary" role="status"></div>
</div>
<!-- Custom Landing Page (from DB) -->
<div v-else-if="hasLandingPage && landingPageHtml" class="landing-page-container">
<div class="landing-page-content" v-html="landingPageHtml"></div>
</div>
<!-- Default Public Homepage (fallback) -->
<div v-else class="pb-5">
<!-- Global Announcements -->
<GlobalAnnouncement />
<!-- Services Grid -->
<div class="mt-4">
<h5 class="tf-container fw_6 mb-3">Featured Services</h5>
<ServiceButtonGrid :items="services" @item-click="handleItemClick" />
</div>
<!-- Quick Actions -->
<div class="tf-container mt-4">
<h5 class="fw_6 mb-3">Quick Links</h5>
<SideTextButtonList :items="quickActionsItems" @item-click="handleItemClick" />
</div>
<!-- Login CTA -->
<div class="tf-container mt-5">
<div class="login-cta-box text-center p-4">
<h4 class="fw_6 mb-2">Ready to trade?</h4>
<p class="mb-4 text-muted">Join the {{ uiStore.appName }} community today.</p>
<button @click="goToLogin" class="btn btn-primary w-100 py-3 rounded-pill fw_6">
Login / Sign Up
</button>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.announcement-img {
width: 100%;
border-radius: 10px;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
margin-bottom: 15px;
}
.announcement-text {
line-height: 1.6;
font-size: 0.95rem;
}
.login-cta-box {
background: #f8f9fa;
border-radius: 15px;
border: 1px dashed #dee2e6;
}
.btn-primary {
background: #42b983;
border: none;
font-size: 1.1rem;
transition: transform 0.2s;
}
.btn-primary:active {
transform: scale(0.98);
}
/* Landing page container - allow full-width custom content */
.landing-page-container {
width: 100%;
}
.landing-page-content {
width: 100%;
}
/* Ensure dark mode compatibility */
:global(.dark-mode) .login-cta-box {
background: var(--bg-card, #1e1e2e);
border-color: rgba(255,255,255,0.1);
}
</style>