120 lines
5.6 KiB
Vue
120 lines
5.6 KiB
Vue
// src/views/about/HallView.vue
|
|
<template>
|
|
<div class="container mx-auto px-4 md:px-8 lg:px-16 py-12">
|
|
<div class="text-center mb-12">
|
|
<h1 class="text-3xl font-bold text-blue-800">
|
|
{{ appStore.checkLang.isTh ? header_th : header_en }}
|
|
</h1>
|
|
<p class="mt-3 text-lg opacity-90 text-gray-700">
|
|
{{ appStore.checkLang.isTh ? 'ทำความรู้จักกับทำเนียบอดีตผู้บริหารองค์กร' : 'Meet the former executives of our organization' }}
|
|
</p>
|
|
</div>
|
|
|
|
<div v-if="aboutUsStore.isLoading.formerExecutives" class="text-center py-20">
|
|
<span class="loading loading-spinner loading-lg text-blue-500"></span>
|
|
<p class="mt-4 text-xl text-gray-500">
|
|
{{ appStore.checkLang.isTh ? 'กำลังโหลดทำเนียบอดีตผู้บริหาร...' : 'Loading former executives...' }}
|
|
</p>
|
|
</div>
|
|
|
|
<div v-else-if="aboutUsStore.errors.formerExecutives" class="text-center text-red-600 py-20">
|
|
<p class="text-xl font-medium">
|
|
{{ appStore.checkLang.isTh ? 'เกิดข้อผิดพลาดในการโหลดข้อมูล' : 'Error loading data.' }}
|
|
</p>
|
|
<p class="text-sm mt-2">
|
|
{{ appStore.checkLang.isTh ? 'ไม่สามารถดึงข้อมูลทำเนียบอดีตผู้บริหารได้ โปรดลองอีกครั้ง' : 'Failed to fetch former executives data. Please try again.' }}
|
|
</p>
|
|
</div>
|
|
|
|
<div v-else-if="aboutUsStore.getFormerExecutivesForDisplay.length > 0">
|
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8 justify-items-center">
|
|
<div v-for="executive in aboutUsStore.getFormerExecutivesForDisplay" :key="executive.id" class="text-center">
|
|
<figure class="figure flex flex-col items-center">
|
|
<template v-if="shouldShowImage(executive)">
|
|
<img
|
|
:src="getImageUrl(executive.image.url)"
|
|
class="figure-img rounded-lg object-cover w-48 h-48 mb-3 shadow-md border-2 border-gray-300 hover:border-blue-500 transition-all duration-300"
|
|
:alt="appStore.checkLang.isTh ? executive.title_th : executive.title_en"
|
|
@error="onImageError(executive.id)"
|
|
/>
|
|
</template>
|
|
<template v-else>
|
|
<div class="w-48 h-48 rounded-lg shadow-md border-2 border-gray-300 hover:border-blue-500 transition-all duration-300 bg-gray-100 flex items-center justify-center mb-3">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-24 w-24 text-gray-400" viewBox="0 0 24 24" fill="currentColor">
|
|
<path fill-rule="evenodd" d="M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z" clip-rule="evenodd" />
|
|
</svg>
|
|
</div>
|
|
</template>
|
|
<figcaption class="figure-caption text-center text-gray-700 text-lg" v-html="appStore.checkLang.isTh ? executive.title_th : executive.title_en">
|
|
</figcaption>
|
|
</figure>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div v-else class="text-center text-gray-400 py-16">
|
|
<p class="text-xl">
|
|
{{ appStore.checkLang.isTh ? 'ไม่พบข้อมูลทำเนียบอดีตผู้บริหาร' : 'No former executives found.' }}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { onMounted, watch, ref } from 'vue'; // Import ref
|
|
import { useAppStore } from '@/stores/app.js';
|
|
import { useAboutUsStore } from '@/stores/aboutUsStore.js';
|
|
|
|
const appStore = useAppStore();
|
|
const aboutUsStore = useAboutUsStore();
|
|
|
|
// Ref to track image loading errors, keyed by executive ID
|
|
const imageLoadErrors = ref({});
|
|
|
|
const header_th = "ทำเนียบอดีตผู้บริหารองค์กร";
|
|
const header_en = "Former Executives of the Organization";
|
|
|
|
// Function to construct the image URL using Vite's environment variables
|
|
const getImageUrl = (path) => {
|
|
const baseURL = import.meta.env.VITE_IMAGE_BASE_URL;
|
|
if (!baseURL) {
|
|
console.warn("VITE_IMAGE_BASE_URL is not defined in your .env file. Using relative path.");
|
|
return path;
|
|
}
|
|
return `${baseURL}${path}`;
|
|
};
|
|
|
|
// Handler when an image fails to load
|
|
const onImageError = (id) => {
|
|
// Set the error status for the specific image ID
|
|
imageLoadErrors.value = { ...imageLoadErrors.value, [id]: true };
|
|
};
|
|
|
|
// Function to determine if the image should be shown
|
|
const shouldShowImage = (executive) => {
|
|
// Check if executive.image and executive.image.url exist,
|
|
// AND if there hasn't been a load error recorded for this executive's ID.
|
|
return executive.image && executive.image.url && !imageLoadErrors.value[executive.id];
|
|
};
|
|
|
|
onMounted(() => {
|
|
aboutUsStore.fetchFormerExecutives();
|
|
});
|
|
|
|
watch(() => appStore.checkLang.isTh, (newLangIsTh, oldLangIsTh) => {
|
|
if (newLangIsTh !== oldLangIsTh) {
|
|
console.log("Language changed, re-fetching former executives data.");
|
|
// Reset imageLoadErrors when language changes to attempt loading images again
|
|
imageLoadErrors.value = {};
|
|
aboutUsStore.fetchFormerExecutives();
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<style scoped>
|
|
/* No specific styles needed here, Tailwind/DaisyUI handles most of it */
|
|
.figure-img {
|
|
/* Using Tailwind's shadow-md for consistency, if you had this in your original project */
|
|
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
|
}
|
|
</style> |