vue_website_template/src/views/TabContentView.vue

168 lines
8.2 KiB
Vue

// src/views/TabContentView.vue
<template>
<div class="container mx-auto p-4 md:p-8">
<div v-if="newsItem" class="bg-white shadow-lg rounded-lg overflow-hidden">
<div class="relative w-full h-64 md:h-96 overflow-hidden">
<img
v-if="newsItem.image && newsItem.image.url"
:src="`${appStore.imageBaseUrl}${newsItem.image.url}`"
:alt="appStore.checkLang.isTh ? newsItem.title_th : newsItem.title_en"
class="w-full h-full object-cover object-center"
loading="lazy"
/>
<div v-else class="w-full h-full bg-gray-200 flex items-center justify-center text-gray-500 text-lg">
{{ appStore.checkLang.isTh ? 'ไม่มีรูปภาพ' : 'No Image Available' }}
</div>
</div>
<div class="p-6 md:p-8">
<nav class="text-sm text-gray-600 mb-4" aria-label="Breadcrumb">
<ol class="list-none p-0 inline-flex">
<li class="flex items-center">
<router-link to="/home" class="text-blue-600 hover:underline">
{{ appStore.checkLang.isTh ? 'หน้าหลัก' : 'Home' }}
</router-link>
<svg class="fill-current w-3 h-3 mx-3" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 75.253c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.476 239.029c9.373 9.372 9.373 24.568 0 33.942z"/></svg>
</li>
<li class="flex items-center">
<router-link :to="`/tab-news/${newsItem.type}`" class="text-blue-600 hover:underline">
{{ appStore.checkLang.isTh ? categoryTitleTh : categoryTitleEn }}
</router-link>
<svg class="fill-current w-3 h-3 mx-3" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 75.253c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.476 239.029c9.373 9.372 9.373 24.568 0 33.942z"/></svg>
</li>
<li>
<span class="text-gray-500">{{ appStore.checkLang.isTh ? newsItem.title_th : newsItem.title_en }}</span>
</li>
</ol>
</nav>
<h1 class="text-3xl md:text-4xl font-bold text-gray-900 mb-4 leading-tight">
{{ appStore.checkLang.isTh ? newsItem.title_th : newsItem.title_en }}
</h1>
<p class="text-sm text-gray-500 mb-6">
<span v-if="newsItem.release_date">
{{ appStore.checkLang.isTh ? 'เผยแพร่เมื่อ' : 'Published on' }}:
<span class="font-medium text-gray-700">{{ formatDate(newsItem.release_date) }}</span>
</span>
</p>
<div class="prose lg:prose-lg max-w-3xl mx-auto text-gray-800 leading-relaxed break-words">
<div v-html="appStore.checkLang.isTh ? newsItem.detail_th : newsItem.detail_en"></div>
</div>
<div class="mt-8 pt-4 border-t border-gray-200 flex justify-end">
<button class="btn bg-[#1b3872] text-white hover:bg-[#1b3872]/90 rounded-none border-none shadow-md">
<svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 20 20"><path d="M15 8a3 3 0 10-2.977-2.909L8 7.239V4.75a3 3 0 00-3-3H4.75a3 3 0 00-3 3v.475a3 3 0 003 3V12h-.25a2.75 2.75 0 000 5.5h.25a2.75 2.75 0 000-5.5H4.75a.75.75 0 010-1.5h.25a.75.75 0 01.75.75v.25c0 .285.068.558.196.804l3.153-1.636a3 3 0 003.545-5.908L15 8zM5 4.5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm9.5 9.5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zM15 6a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z"></path></svg>
{{ appStore.checkLang.isTh ? 'แชร์' : 'Share' }}
</button>
</div>
</div>
</div>
<div v-else class="text-center text-gray-600 py-16">
<p class="text-2xl font-semibold mb-4">
{{ appStore.checkLang.isTh ? 'ไม่พบข่าวสารนี้ หรือข่าวสารนี้ไม่พร้อมใช้งานในภาษาปัจจุบัน' : 'News not found or not available in the current language.' }}
</p>
<router-link to="/home" class="btn bg-[#1b3872] text-white hover:bg-[#1b3872]/90 rounded-none border-none shadow-md">
{{ appStore.checkLang.isTh ? 'กลับหน้าหลัก' : 'Back to Home' }}
</router-link>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, watch, computed } from 'vue';
import { useRoute } from 'vue-router';
import { useAppStore } from '@/stores/app.js';
import { RouterLink } from 'vue-router';
const appStore = useAppStore();
const route = useRoute();
const newsItem = ref(null);
// Computed property เพื่อดึงชื่อหมวดหมู่สำหรับ Breadcrumbs
const categoryTitleTh = computed(() => {
if (newsItem.value && appStore.tabs && Array.isArray(appStore.tabs) && appStore.tabs.length > 0) {
const tab = appStore.tabs.find(t => t.category === newsItem.value.type);
return tab ? tab.title : 'ไม่ระบุหมวดหมู่';
}
return appStore.checkLang.isTh ? 'กำลังโหลด...' : 'Loading...';
});
const categoryTitleEn = computed(() => {
if (newsItem.value && appStore.tabs && Array.isArray(appStore.tabs) && appStore.tabs.length > 0) {
const tab = appStore.tabs.find(t => t.category === newsItem.value.type);
return tab ? tab.title_en : 'Unspecified Category';
}
return appStore.checkLang.isTh ? 'Loading...' : 'Loading...';
});
const fetchNewsDetail = async (id) => {
// ในสถานการณ์จริง จะเรียก API เช่น await axios.get(`/api/news/${id}`);
// สำหรับตอนนี้ ใช้ mock data ใน store
const foundNews = appStore.mockNewsData.find(item => item.id == id);
if (foundNews) {
// ตรวจสอบ active และ active_en ตามภาษาปัจจุบัน
if (appStore.isTh && foundNews.active) {
newsItem.value = foundNews;
} else if (!appStore.isTh && foundNews.active_en) {
newsItem.value = foundNews;
} else {
newsItem.value = null; // ไม่พบข่าวที่ active ในภาษาปัจจุบัน
}
} else {
newsItem.value = null;
}
};
const formatDate = (dateString) => {
if (!dateString) return '';
const parts = dateString.split('/'); // Assumes MM/DD/YYYY
if (parts.length === 3) {
const [month, day, year] = parts;
const dateObj = new Date(parseInt(year), parseInt(month) - 1, parseInt(day));
const formattedDay = String(dateObj.getDate()).padStart(2, '0');
const formattedMonth = String(dateObj.getMonth() + 1).padStart(2, '0');
const formattedYear = dateObj.getFullYear();
return `${formattedDay}/${formattedMonth}/${formattedYear}`;
}
return dateString;
};
onMounted(() => {
fetchNewsDetail(route.params.id);
});
watch(() => route.params.id, (newId) => {
fetchNewsDetail(newId);
});
watch(() => appStore.isTh, () => {
fetchNewsDetail(route.params.id);
});
</script>
<style scoped>
/* ตัวอย่างการกำหนดความกว้างของเนื้อหา */
.prose {
max-width: 70ch; /* จำกัดความกว้างของข้อความให้อ่านง่ายขึ้น */
}
/* ปรับปรุงการแสดงผลรูปภาพภายในเนื้อหา (ถ้าอยู่ใน detail_th/en) */
.prose img {
max-width: 100%;
height: auto;
display: block; /* ทำให้รูปภาพเป็น block level */
margin: 1em auto; /* จัดกึ่งกลางและมีระยะห่าง */
border-radius: 0.5rem; /* ตัวอย่าง: ขอบมน */
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); /* ตัวอย่าง: เพิ่มเงา */
}
/* สำหรับภาพปก */
.object-cover {
object-fit: cover;
object-position: center; /* ทำให้รูปภาพอยู่ตรงกลางเมื่อถูก crop */
}
</style>