139 lines
6 KiB
Vue
139 lines
6 KiB
Vue
<script setup lang="ts">
|
||
/** FR-12 UI — รายการเอกสารที่สร้างจาก template หนึ่งตัว (เข้าได้แม้ template ถูก deactivate) */
|
||
import type { TemplateDetail, TemplateDocumentListItem } from '~/types/api'
|
||
|
||
const route = useRoute()
|
||
const { apiJson } = useApi()
|
||
|
||
const templateId = computed(() => String(route.params.id))
|
||
|
||
const template = ref<TemplateDetail | null>(null)
|
||
const documents = ref<TemplateDocumentListItem[]>([])
|
||
const loading = ref(true)
|
||
const loadError = ref<string | null>(null)
|
||
|
||
async function load() {
|
||
loading.value = true
|
||
loadError.value = null
|
||
try {
|
||
const [tpl, docs] = await Promise.all([
|
||
apiJson<TemplateDetail>(`/api/templates/${templateId.value}`),
|
||
apiJson<TemplateDocumentListItem[]>(`/api/templates/${templateId.value}/documents`),
|
||
])
|
||
template.value = tpl!
|
||
documents.value = docs ?? []
|
||
useHead({ title: `เอกสารของ ${tpl?.name} — e-Court Documents Versioning` })
|
||
} catch (err) {
|
||
loadError.value = err instanceof Error ? err.message : 'โหลดรายการเอกสารไม่สำเร็จ'
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
|
||
onMounted(load)
|
||
</script>
|
||
|
||
<template>
|
||
<AuthGate>
|
||
<section class="space-y-6">
|
||
<div v-if="loading" class="flex items-center gap-3 py-10 text-sm text-muted">
|
||
<span class="spinner" />
|
||
กำลังโหลด…
|
||
</div>
|
||
|
||
<AlertBox v-else-if="loadError" type="error">
|
||
{{ loadError }}
|
||
<NuxtLink to="/templates" class="ml-1 font-medium underline">กลับรายการ template</NuxtLink>
|
||
</AlertBox>
|
||
|
||
<template v-else-if="template">
|
||
<div class="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
|
||
<div class="min-w-0">
|
||
<p class="text-xs text-muted">เอกสารที่สร้างจาก template</p>
|
||
<h1 class="mt-1 text-page-title">{{ template.name }}</h1>
|
||
<p v-if="template.description" class="mt-1 text-sm text-muted">
|
||
{{ template.description }}
|
||
</p>
|
||
</div>
|
||
<div class="flex shrink-0 flex-wrap items-center gap-2">
|
||
<NuxtLink :to="`/templates/${template.id}/edit`" class="btn btn-secondary btn-sm">
|
||
แก้ไข template
|
||
</NuxtLink>
|
||
<NuxtLink
|
||
v-if="template.isActive"
|
||
:to="`/documents/create/${template.id}`"
|
||
class="btn btn-primary btn-sm"
|
||
>
|
||
+ สร้างเอกสารใหม่
|
||
</NuxtLink>
|
||
</div>
|
||
</div>
|
||
|
||
<AlertBox v-if="!template.isActive">
|
||
template นี้ถูก deactivate แล้ว — สร้างเอกสารใหม่ไม่ได้ แต่เอกสารที่สร้างไว้แล้วยังใช้งานได้ตามปกติ
|
||
</AlertBox>
|
||
|
||
<div v-if="documents.length === 0" class="empty-state">
|
||
ยังไม่มีเอกสารจาก template นี้<template v-if="template.isActive">
|
||
—
|
||
<NuxtLink :to="`/documents/create/${template.id}`" class="link">สร้างเอกสารแรก</NuxtLink></template
|
||
>
|
||
</div>
|
||
|
||
<template v-else>
|
||
<!-- มือถือ: card list -->
|
||
<ul class="space-y-3 md:hidden">
|
||
<li v-for="d in documents" :key="d.documentId" class="card space-y-2 p-4">
|
||
<NuxtLink :to="`/documents/${d.documentId}`" class="link break-words font-semibold">
|
||
{{ d.fileName }}
|
||
</NuxtLink>
|
||
<p class="text-xs text-muted">สร้าง {{ formatDateTime(d.createdAt) }} · {{ d.versionCount }} versions</p>
|
||
<p class="text-xs text-muted">
|
||
<template v-if="d.latestVersionAt">
|
||
ล่าสุด v{{ d.latestVersionNumber }} · {{ formatDateTime(d.latestVersionAt) }}
|
||
</template>
|
||
<template v-else>—</template>
|
||
</p>
|
||
<NuxtLink :to="`/documents/${d.documentId}`" class="btn btn-secondary btn-xs">ดูรายละเอียด</NuxtLink>
|
||
</li>
|
||
</ul>
|
||
|
||
<!-- desktop: ตาราง -->
|
||
<div class="table-card hidden md:block">
|
||
<table class="w-full text-sm">
|
||
<thead class="table-head">
|
||
<tr>
|
||
<th class="px-4 py-3">ไฟล์เอกสาร</th>
|
||
<th class="px-4 py-3">สร้างเมื่อ</th>
|
||
<th class="px-4 py-3 text-center">versions</th>
|
||
<th class="px-4 py-3">กิจกรรมล่าสุด</th>
|
||
<th class="px-4 py-3 text-right">การกระทำ</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody class="divide-y divide-line">
|
||
<tr v-for="d in documents" :key="d.documentId">
|
||
<td class="max-w-72 px-4 py-3">
|
||
<NuxtLink :to="`/documents/${d.documentId}`" class="link">{{ d.fileName }}</NuxtLink>
|
||
</td>
|
||
<td class="px-4 py-3 text-muted">{{ formatDateTime(d.createdAt) }}</td>
|
||
<td class="px-4 py-3 text-center">{{ d.versionCount }}</td>
|
||
<td class="px-4 py-3 text-muted">
|
||
<template v-if="d.latestVersionAt">
|
||
v{{ d.latestVersionNumber }} · {{ formatDateTime(d.latestVersionAt) }}
|
||
</template>
|
||
<template v-else>—</template>
|
||
</td>
|
||
<td class="px-4 py-3 text-right">
|
||
<NuxtLink :to="`/documents/${d.documentId}`" class="btn btn-secondary btn-xs">
|
||
ดูรายละเอียด
|
||
</NuxtLink>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</template>
|
||
</template>
|
||
</section>
|
||
</AuthGate>
|
||
</template>
|