EDMS/pages/dms/document-properties.vue
2025-05-30 16:16:59 +08:00

364 lines
20 KiB
Vue

<script setup>
import { ref, onMounted } from 'vue';
import { useDmsStore } from '~/stores/dms';
import DMSNavigation from '~/components/dms/navigation/DMSNavigation.vue';
// Define page metadata
definePageMeta({
title: "Document Properties",
middleware: ["auth"],
requiresAuth: true,
breadcrumb: [
{
name: "Dashboard",
path: "/dashboard",
},
{
name: "DMS",
path: "/dms",
},
{
name: "Document Properties",
path: "/dms/document-properties",
},
],
});
// Set up store
const dmsStore = useDmsStore();
// Local state
const currentDocument = ref(null);
const isEditing = ref(false);
const documentForm = ref({
title: '',
description: '',
keywords: '',
category: '',
status: '',
retention: '',
owner: '',
department: '',
created: '',
modified: '',
fileSize: '',
version: '',
versionHistory: []
});
// Mock document data
const documentData = {
id: 'doc123',
title: 'Pembangunan Sistem IT 2021',
description: 'Spesifikasi teknikal untuk pembangunan sistem IT baru di JKR Kota Bharu',
keywords: 'IT, sistem, JKR, spesifikasi, pembangunan',
category: 'Technical Specification',
status: 'Approved',
retention: '7 years',
owner: 'Mohd Faizal bin Abdullah',
department: 'IT Department',
created: '2021-05-20',
modified: '2021-05-25',
fileSize: '4MB',
filePath: '/JKR Cawangan Kota Bharu, Kelantan/Technical Documents/',
fileName: 'Pembangunan_Sistem_IT_2021.pdf',
fileType: 'PDF',
version: '1.2',
versionHistory: [
{ version: '1.2', date: '2021-05-25', user: 'Mohd Faizal bin Abdullah', notes: 'Final approved version' },
{ version: '1.1', date: '2021-05-22', user: 'Ahmad bin Ishak', notes: 'Updated requirements section' },
{ version: '1.0', date: '2021-05-20', user: 'Mohd Faizal bin Abdullah', notes: 'Initial draft' }
]
};
// Enable editing
const startEditing = () => {
// Copy current document values to form
documentForm.value = { ...currentDocument.value };
isEditing.value = true;
};
// Save changes
const saveChanges = () => {
// In a real app, we would send the updated data to the server
// For now, we'll just update our local copy
Object.assign(currentDocument.value, documentForm.value);
isEditing.value = false;
};
// Cancel editing
const cancelEditing = () => {
isEditing.value = false;
};
// Load document on mount
onMounted(() => {
// In a real app, we would fetch the document from an API
// For now, we'll use our mock data
currentDocument.value = documentData;
});
</script>
<template>
<div class="dms-page">
<LayoutsBreadcrumb />
<rs-card class="h-full">
<template #header>
<div class="flex flex-wrap items-center justify-between gap-4">
<h1 class="text-xl font-bold text-primary">Document Properties</h1>
<div class="flex items-center gap-3">
<rs-button v-if="!isEditing" color="primary" @click="startEditing">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="mr-2"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"></path><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"></path></svg>
Edit Properties
</rs-button>
<div v-else class="flex gap-2">
<rs-button color="primary" @click="saveChanges">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="mr-2"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"></path><polyline points="17 21 17 13 7 13 7 21"></polyline><polyline points="7 3 7 8 15 8"></polyline></svg>
Save
</rs-button>
<rs-button color="secondary" @click="cancelEditing">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="mr-2"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>
Cancel
</rs-button>
</div>
</div>
</div>
</template>
<template #body>
<div class="explorer-layout h-full flex overflow-hidden">
<!-- Left sidebar navigation -->
<DMSNavigation />
<!-- Main content area -->
<div class="flex-1 overflow-y-auto p-6">
<div v-if="currentDocument" class="max-w-4xl mx-auto">
<div class="bg-white dark:bg-gray-800 shadow-sm rounded-lg overflow-hidden mb-6">
<div class="bg-gray-50 dark:bg-gray-700 px-6 py-4 border-b border-gray-200 dark:border-gray-600">
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100 flex items-center">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="mr-2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line><polyline points="10 9 9 9 8 9"></polyline></svg>
File Information
</h2>
</div>
<div class="px-6 py-4">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">File Name</label>
<div class="text-gray-900 dark:text-gray-100">{{ currentDocument.fileName }}</div>
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">File Type</label>
<div class="text-gray-900 dark:text-gray-100">{{ currentDocument.fileType }}</div>
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">File Size</label>
<div class="text-gray-900 dark:text-gray-100">{{ currentDocument.fileSize }}</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">File Path</label>
<div class="text-gray-900 dark:text-gray-100">{{ currentDocument.filePath }}</div>
</div>
</div>
<div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Created Date</label>
<div class="text-gray-900 dark:text-gray-100">{{ currentDocument.created }}</div>
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Modified Date</label>
<div class="text-gray-900 dark:text-gray-100">{{ currentDocument.modified }}</div>
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Current Version</label>
<div class="text-gray-900 dark:text-gray-100">{{ currentDocument.version }}</div>
</div>
</div>
</div>
</div>
</div>
<div class="bg-white dark:bg-gray-800 shadow-sm rounded-lg overflow-hidden mb-6">
<div class="bg-gray-50 dark:bg-gray-700 px-6 py-4 border-b border-gray-200 dark:border-gray-600">
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100 flex items-center">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="mr-2"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="16" x2="12" y2="12"></line><line x1="12" y1="8" x2="12.01" y2="8"></line></svg>
Document Metadata
</h2>
</div>
<div class="px-6 py-4">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Title</label>
<div v-if="!isEditing" class="text-gray-900 dark:text-gray-100">{{ currentDocument.title }}</div>
<input
v-else
v-model="documentForm.title"
type="text"
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-primary focus:ring focus:ring-primary focus:ring-opacity-50"
/>
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Description</label>
<div v-if="!isEditing" class="text-gray-900 dark:text-gray-100">{{ currentDocument.description }}</div>
<textarea
v-else
v-model="documentForm.description"
rows="3"
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-primary focus:ring focus:ring-primary focus:ring-opacity-50"
></textarea>
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Keywords</label>
<div v-if="!isEditing" class="text-gray-900 dark:text-gray-100">{{ currentDocument.keywords }}</div>
<input
v-else
v-model="documentForm.keywords"
type="text"
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-primary focus:ring focus:ring-primary focus:ring-opacity-50"
/>
</div>
</div>
<div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Category</label>
<div v-if="!isEditing" class="text-gray-900 dark:text-gray-100">{{ currentDocument.category }}</div>
<select
v-else
v-model="documentForm.category"
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-primary focus:ring focus:ring-primary focus:ring-opacity-50"
>
<option value="Technical Specification">Technical Specification</option>
<option value="Project Proposal">Project Proposal</option>
<option value="Contract">Contract</option>
<option value="Report">Report</option>
<option value="Other">Other</option>
</select>
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Status</label>
<div v-if="!isEditing" class="text-gray-900 dark:text-gray-100">{{ currentDocument.status }}</div>
<select
v-else
v-model="documentForm.status"
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-primary focus:ring focus:ring-primary focus:ring-opacity-50"
>
<option value="Draft">Draft</option>
<option value="Under Review">Under Review</option>
<option value="Approved">Approved</option>
<option value="Rejected">Rejected</option>
<option value="Archived">Archived</option>
</select>
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Retention Period</label>
<div v-if="!isEditing" class="text-gray-900 dark:text-gray-100">{{ currentDocument.retention }}</div>
<select
v-else
v-model="documentForm.retention"
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-primary focus:ring focus:ring-primary focus:ring-opacity-50"
>
<option value="1 year">1 year</option>
<option value="3 years">3 years</option>
<option value="5 years">5 years</option>
<option value="7 years">7 years</option>
<option value="10 years">10 years</option>
<option value="Permanent">Permanent</option>
</select>
</div>
</div>
</div>
</div>
</div>
<div class="bg-white dark:bg-gray-800 shadow-sm rounded-lg overflow-hidden mb-6">
<div class="bg-gray-50 dark:bg-gray-700 px-6 py-4 border-b border-gray-200 dark:border-gray-600">
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100 flex items-center">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="mr-2"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="9" cy="7" r="4"></circle><path d="M23 21v-2a4 4 0 0 0-3-3.87"></path><path d="M16 3.13a4 4 0 0 1 0 7.75"></path></svg>
Ownership Information
</h2>
</div>
<div class="px-6 py-4">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Owner</label>
<div v-if="!isEditing" class="text-gray-900 dark:text-gray-100">{{ currentDocument.owner }}</div>
<input
v-else
v-model="documentForm.owner"
type="text"
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-primary focus:ring focus:ring-primary focus:ring-opacity-50"
/>
</div>
</div>
<div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Department</label>
<div v-if="!isEditing" class="text-gray-900 dark:text-gray-100">{{ currentDocument.department }}</div>
<input
v-else
v-model="documentForm.department"
type="text"
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-primary focus:ring focus:ring-primary focus:ring-opacity-50"
/>
</div>
</div>
</div>
</div>
</div>
<div class="bg-white dark:bg-gray-800 shadow-sm rounded-lg overflow-hidden">
<div class="bg-gray-50 dark:bg-gray-700 px-6 py-4 border-b border-gray-200 dark:border-gray-600">
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100 flex items-center">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="mr-2"><circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline></svg>
Version History
</h2>
</div>
<div class="px-6 py-4">
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
<thead>
<tr>
<th scope="col" class="px-6 py-3 bg-gray-50 dark:bg-gray-700 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Version</th>
<th scope="col" class="px-6 py-3 bg-gray-50 dark:bg-gray-700 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Date</th>
<th scope="col" class="px-6 py-3 bg-gray-50 dark:bg-gray-700 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">User</th>
<th scope="col" class="px-6 py-3 bg-gray-50 dark:bg-gray-700 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Notes</th>
<th scope="col" class="px-6 py-3 bg-gray-50 dark:bg-gray-700 text-right text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Actions</th>
</tr>
</thead>
<tbody class="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700">
<tr v-for="(version, index) in currentDocument.versionHistory" :key="index">
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">{{ version.version }}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">{{ version.date }}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">{{ version.user }}</td>
<td class="px-6 py-4 text-sm text-gray-900 dark:text-gray-100">{{ version.notes }}</td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<rs-button size="xs" color="secondary">View</rs-button>
<rs-button v-if="index > 0" size="xs" color="primary" class="ml-2">Restore</rs-button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
</rs-card>
</div>
</template>
<style scoped>
.dms-page {
height: calc(100vh - 64px - 48px - 32px); /* Adjust based on your layout */
}
.explorer-layout {
height: calc(100vh - 200px); /* Adjust based on your layout */
}
</style>