jlp
This commit is contained in:
parent
4d31939b0f
commit
e7cd3fd367
@ -1,17 +1,17 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="space-y-6">
|
||||
<!-- CARD: Status Semakan & Status Penerimaan -->
|
||||
<rs-card class="mt-4 p-4">
|
||||
<div class="flex justify-between">
|
||||
<h3>Status Semakan</h3>
|
||||
<rs-card class="p-6">
|
||||
<div class="flex justify-between items-center">
|
||||
<h3 class="text-lg font-semibold">Status Semakan</h3>
|
||||
<rs-badge
|
||||
:variant="statusSemakan === 'Selesai' ? 'success' : 'warning'"
|
||||
>
|
||||
{{ statusSemakan }}
|
||||
</rs-badge>
|
||||
</div>
|
||||
<div class="flex justify-between mt-2">
|
||||
<h3>Status Penerimaan</h3>
|
||||
<div class="flex justify-between items-center mt-4">
|
||||
<h3 class="text-lg font-semibold">Status Penerimaan</h3>
|
||||
<rs-badge
|
||||
:variant="statusPenerimaan === 'Diterima' ? 'success' : 'danger'"
|
||||
>
|
||||
@ -21,27 +21,39 @@
|
||||
</rs-card>
|
||||
|
||||
<!-- LIST: Pegawai Forensic Yang Terlibat -->
|
||||
<rs-card class="mt-4 p-4">
|
||||
<div class="flex justify-between items-center">
|
||||
<h3>Pegawai Forensik Yang Terlibat</h3>
|
||||
<rs-card class="p-6">
|
||||
<div class="flex justify-between items-center mb-4">
|
||||
<h3 class="text-lg font-semibold">Pegawai Forensik Yang Terlibat</h3>
|
||||
<rs-button
|
||||
v-if="isKetuaBahagian"
|
||||
@click="addPegawai"
|
||||
@click="openAddModal"
|
||||
variant="primary"
|
||||
size="sm"
|
||||
>Tambah Pegawai</rs-button
|
||||
>
|
||||
Tambah Pegawai
|
||||
</rs-button>
|
||||
</div>
|
||||
<rs-table
|
||||
v-if="forensicOfficers.length > 0"
|
||||
:data="forensicOfficers"
|
||||
:options="{ striped: true, borderless: true }"
|
||||
:options="{
|
||||
variant: 'default',
|
||||
striped: true,
|
||||
borderless: false,
|
||||
}"
|
||||
:options-advanced="{
|
||||
sortable: true,
|
||||
responsive: true,
|
||||
filterable: false,
|
||||
}"
|
||||
advanced
|
||||
>
|
||||
<template v-slot:header>
|
||||
<tr>
|
||||
<th>Pangkat</th>
|
||||
<th>Nama</th>
|
||||
<th>No Pegawai</th>
|
||||
<th v-if="isKetuaBahagian">Tindakan</th>
|
||||
<th>Tindakan</th>
|
||||
</tr>
|
||||
</template>
|
||||
<template v-slot:pangkat="data">
|
||||
@ -53,28 +65,46 @@
|
||||
<template v-slot:noPegawai="data">
|
||||
{{ data.text }}
|
||||
</template>
|
||||
<template v-slot:action="data" v-if="isKetuaBahagian">
|
||||
<template v-slot:tindakan="data">
|
||||
<div class="flex gap-2">
|
||||
<rs-button @click="editPegawai(data.value)" variant="info" size="sm"
|
||||
>Edit</rs-button
|
||||
>
|
||||
<rs-button
|
||||
@click="deletePegawai(data.value)"
|
||||
@click="openEditModal(data.value)"
|
||||
variant="info"
|
||||
size="sm"
|
||||
>
|
||||
<Icon name="ic:baseline-edit" size="1.2rem" />
|
||||
</rs-button>
|
||||
<rs-button
|
||||
@click="confirmDelete(data.value)"
|
||||
variant="danger"
|
||||
size="sm"
|
||||
>Delete</rs-button
|
||||
>
|
||||
<Icon name="ic:baseline-delete" size="1.2rem" />
|
||||
</rs-button>
|
||||
</div>
|
||||
</template>
|
||||
</rs-table>
|
||||
<div v-else class="text-center p-10">
|
||||
<p>Tidak ada pegawai forensik yang terlibat.</p>
|
||||
</div>
|
||||
</rs-card>
|
||||
|
||||
<!-- LIST: Bahan Bukti -->
|
||||
<rs-card class="mt-4 p-4">
|
||||
<h3>Bahan Bukti</h3>
|
||||
<rs-card class="p-6">
|
||||
<h3 class="text-lg font-semibold mb-4">Bahan Bukti</h3>
|
||||
<rs-table
|
||||
:data="evidences"
|
||||
:options="{ striped: true, borderless: true }"
|
||||
:options="{
|
||||
variant: 'default',
|
||||
striped: true,
|
||||
borderless: false,
|
||||
}"
|
||||
:options-advanced="{
|
||||
sortable: true,
|
||||
responsive: true,
|
||||
filterable: false,
|
||||
}"
|
||||
advanced
|
||||
>
|
||||
<template v-slot:header>
|
||||
<tr>
|
||||
@ -83,7 +113,7 @@
|
||||
<th>Tag No.</th>
|
||||
<th>Keadaan</th>
|
||||
<th>Kuantiti</th>
|
||||
<th v-if="!isKetuaJabatan">Tindakan</th>
|
||||
<th>Tindakan</th>
|
||||
</tr>
|
||||
</template>
|
||||
<template v-slot:no="data">
|
||||
@ -106,29 +136,114 @@
|
||||
@click="generateReport(data.value)"
|
||||
variant="primary"
|
||||
size="sm"
|
||||
>Jana Laporan</rs-button
|
||||
>
|
||||
Jana Laporan
|
||||
</rs-button>
|
||||
</template>
|
||||
</rs-table>
|
||||
</rs-card>
|
||||
|
||||
<!-- Add/Edit Modal -->
|
||||
<rs-modal v-model="showModal" @close="closeModal">
|
||||
<template #header>
|
||||
<h3>
|
||||
{{ editMode ? "Edit Pegawai Forensik" : "Tambah Pegawai Forensik" }}
|
||||
</h3>
|
||||
</template>
|
||||
<template #body>
|
||||
<FormKit
|
||||
type="form"
|
||||
:actions="false"
|
||||
@submit="handleSubmit"
|
||||
:value="pegawaiForm"
|
||||
>
|
||||
<FormKit
|
||||
v-if="!editMode"
|
||||
type="select"
|
||||
name="id"
|
||||
label="Pilih Pegawai"
|
||||
:options="pegawaiList.map(p => ({ value: p.id, label: `${p.pangkat} ${p.nama} (${p.noPegawai})` }))"
|
||||
validation="required"
|
||||
:validation-messages="{
|
||||
required: 'Sila pilih pegawai',
|
||||
}"
|
||||
/>
|
||||
<template v-else>
|
||||
<FormKit
|
||||
type="text"
|
||||
name="pangkat"
|
||||
label="Pangkat"
|
||||
validation="required"
|
||||
:validation-messages="{
|
||||
required: 'Pangkat diperlukan',
|
||||
}"
|
||||
/>
|
||||
<FormKit
|
||||
type="text"
|
||||
name="nama"
|
||||
label="Nama"
|
||||
validation="required"
|
||||
:validation-messages="{
|
||||
required: 'Nama diperlukan',
|
||||
}"
|
||||
/>
|
||||
<FormKit
|
||||
type="text"
|
||||
name="noPegawai"
|
||||
label="No Pegawai"
|
||||
validation="required|unique:noPegawai"
|
||||
:validation-messages="{
|
||||
required: 'No Pegawai diperlukan',
|
||||
unique: 'No Pegawai sudah wujud',
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<div class="flex justify-end gap-2">
|
||||
<rs-button variant="secondary" @click="closeModal">Tutup</rs-button>
|
||||
<rs-button variant="primary" btn-type="submit">
|
||||
Simpan
|
||||
</rs-button>
|
||||
</div>
|
||||
</FormKit>
|
||||
</template>
|
||||
<template #footer> </template>
|
||||
</rs-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { useNuxtApp } from "nuxt/app";
|
||||
import { ref, computed, onMounted } from "vue";
|
||||
|
||||
definePageMeta({
|
||||
layout: "default",
|
||||
});
|
||||
|
||||
const { $swal } = useNuxtApp();
|
||||
|
||||
// Status data
|
||||
const statusSemakan = ref("Selesai"); // Can be dynamic (e.g., "Dalam Proses", "Selesai")
|
||||
const statusPenerimaan = ref("Diterima"); // Can be dynamic (e.g., "Diterima", "Ditolak")
|
||||
const statusSemakan = ref("Selesai");
|
||||
const statusPenerimaan = ref("Diterima");
|
||||
|
||||
// Forensic Officers Data (Pangkat, Nama, No Pegawai)
|
||||
// Forensic Officers Data
|
||||
const forensicOfficers = ref([
|
||||
{ pangkat: "Inspektor", nama: "Ali bin Abu", noPegawai: "PG12345" },
|
||||
{ pangkat: "Sarjan", nama: "Siti binti Ahmad", noPegawai: "PG54321" },
|
||||
{
|
||||
id: 1,
|
||||
pangkat: "Inspektor",
|
||||
nama: "Ali bin Abu",
|
||||
noPegawai: "PG12345",
|
||||
tindakan: 1,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
pangkat: "Sarjan",
|
||||
nama: "Siti binti Ahmad",
|
||||
noPegawai: "PG54321",
|
||||
tindakan: 2,
|
||||
},
|
||||
]);
|
||||
|
||||
// Evidence Data (No, Jenis Barang, Tag No, Keadaan, Kuantiti)
|
||||
// Evidence Data
|
||||
const evidences = ref([
|
||||
{
|
||||
no: 1,
|
||||
@ -136,6 +251,7 @@ const evidences = ref([
|
||||
tagNo: "TAG001",
|
||||
keadaan: "Baik",
|
||||
kuantiti: 3,
|
||||
tindakan: 1,
|
||||
},
|
||||
{
|
||||
no: 2,
|
||||
@ -143,27 +259,133 @@ const evidences = ref([
|
||||
tagNo: "TAG002",
|
||||
keadaan: "Rosak",
|
||||
kuantiti: 5,
|
||||
tindakan: 2,
|
||||
},
|
||||
]);
|
||||
|
||||
// User Roles
|
||||
const isKetuaBahagian = ref(true); // Simulate role check
|
||||
const isKetuaJabatan = ref(false); // Simulate role check
|
||||
const isKetuaBahagian = ref(true);
|
||||
const isKetuaJabatan = ref(false);
|
||||
|
||||
// Modal Controls
|
||||
const showModal = ref(false);
|
||||
const editMode = ref(false);
|
||||
const pegawaiForm = ref({ id: "", pangkat: "", nama: "", noPegawai: "" });
|
||||
|
||||
// Sample pegawai listing (simulating API response)
|
||||
const pegawaiList = ref([]);
|
||||
|
||||
// Fetch pegawai list (simulated API call)
|
||||
const fetchPegawaiList = () => {
|
||||
// In a real scenario, this would be an API call
|
||||
pegawaiList.value = [
|
||||
{ id: 'PG001', nama: 'Ahmad bin Ali', pangkat: 'Inspektor', noPegawai: 'PG12345' },
|
||||
{ id: 'PG002', nama: 'Siti binti Omar', pangkat: 'Sarjan', noPegawai: 'PG67890' },
|
||||
{ id: 'PG003', nama: 'Muthu a/l Rajan', pangkat: 'Koperal', noPegawai: 'PG24680' },
|
||||
];
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
fetchPegawaiList();
|
||||
});
|
||||
|
||||
// Computed property for form validation
|
||||
const isFormValid = computed(() => {
|
||||
return (
|
||||
pegawaiForm.value.pangkat &&
|
||||
pegawaiForm.value.nama &&
|
||||
pegawaiForm.value.noPegawai
|
||||
);
|
||||
});
|
||||
|
||||
// Actions
|
||||
const addPegawai = () => {
|
||||
console.log("Add Pegawai clicked");
|
||||
const openAddModal = () => {
|
||||
editMode.value = false;
|
||||
pegawaiForm.value = { id: "" }; // Only store the selected pegawai id
|
||||
showModal.value = true;
|
||||
};
|
||||
|
||||
const editPegawai = (pegawai) => {
|
||||
console.log("Edit Pegawai:", pegawai);
|
||||
const openEditModal = (pegawai) => {
|
||||
editMode.value = true;
|
||||
pegawaiForm.value = { ...pegawai };
|
||||
showModal.value = true;
|
||||
};
|
||||
|
||||
const deletePegawai = (pegawai) => {
|
||||
console.log("Delete Pegawai:", pegawai);
|
||||
forensicOfficers.value = forensicOfficers.value.filter(
|
||||
(officer) => officer.noPegawai !== pegawai.noPegawai
|
||||
const closeModal = () => {
|
||||
showModal.value = false;
|
||||
pegawaiForm.value = { id: "", pangkat: "", nama: "", noPegawai: "" };
|
||||
};
|
||||
|
||||
const handleSubmit = () => {
|
||||
if (editMode.value) {
|
||||
updatePegawai();
|
||||
} else {
|
||||
addNewPegawai();
|
||||
}
|
||||
};
|
||||
|
||||
const addNewPegawai = () => {
|
||||
if (pegawaiForm.value.id) {
|
||||
const selectedPegawai = pegawaiList.value.find(p => p.id === pegawaiForm.value.id);
|
||||
if (selectedPegawai) {
|
||||
const newPegawai = { ...selectedPegawai, tindakan: uuidv4() };
|
||||
forensicOfficers.value.push(newPegawai);
|
||||
$swal.fire("Berjaya", "Pegawai baru telah ditambah", "success");
|
||||
closeModal();
|
||||
} else {
|
||||
$swal.fire("Ralat", "Pegawai tidak dijumpai", "error");
|
||||
}
|
||||
} else {
|
||||
$swal.fire("Ralat", "Sila pilih pegawai", "error");
|
||||
}
|
||||
};
|
||||
|
||||
const updatePegawai = () => {
|
||||
if (isFormValid.value) {
|
||||
const index = forensicOfficers.value.findIndex(
|
||||
(officer) => officer.id === pegawaiForm.value.id
|
||||
);
|
||||
if (index !== -1) {
|
||||
forensicOfficers.value[index] = { ...pegawaiForm.value };
|
||||
$swal.fire("Berjaya", "Maklumat pegawai telah dikemaskini", "success");
|
||||
closeModal();
|
||||
} else {
|
||||
$swal.fire("Ralat", "Pegawai tidak dijumpai", "error");
|
||||
}
|
||||
} else {
|
||||
$swal.fire("Ralat", "Sila isi semua maklumat yang diperlukan", "error");
|
||||
}
|
||||
};
|
||||
|
||||
const confirmDelete = (pegawai) => {
|
||||
$swal
|
||||
.fire({
|
||||
title: "Anda pasti?",
|
||||
text: "Pegawai ini akan dipadamkan.",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: "#d33",
|
||||
cancelButtonColor: "#3085d6",
|
||||
confirmButtonText: "Ya, padam",
|
||||
cancelButtonText: "Batal",
|
||||
})
|
||||
.then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
deletePegawai(pegawai.id);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const deletePegawai = (id) => {
|
||||
const index = forensicOfficers.value.findIndex(
|
||||
(officer) => officer.id === id
|
||||
);
|
||||
if (index !== -1) {
|
||||
forensicOfficers.value.splice(index, 1);
|
||||
$swal.fire("Dihapuskan!", "Pegawai telah dipadam.", "success");
|
||||
} else {
|
||||
$swal.fire("Ralat", "Pegawai tidak dijumpai", "error");
|
||||
}
|
||||
};
|
||||
|
||||
const generateReport = (bahanBukti) => {
|
||||
@ -171,6 +393,4 @@ const generateReport = (bahanBukti) => {
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* Style customizations for table or buttons */
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
@ -80,55 +80,53 @@
|
||||
validation="required|number"
|
||||
/>
|
||||
|
||||
<!-- Jenis Barang Input -->
|
||||
<FormKit
|
||||
type="text"
|
||||
label="Jenis Barang"
|
||||
v-model="jenisBarang"
|
||||
validation="required"
|
||||
/>
|
||||
|
||||
<!-- Tanda Barang Input -->
|
||||
<FormKit
|
||||
type="text"
|
||||
label="Tanda Barang"
|
||||
v-model="tandaBarang"
|
||||
validation="required"
|
||||
/>
|
||||
|
||||
<!-- Keadaan Barang Input -->
|
||||
<FormKit
|
||||
type="text"
|
||||
label="Keadaan Barang"
|
||||
v-model="keadaanBarang"
|
||||
validation="required"
|
||||
/>
|
||||
|
||||
<!-- Kuantiti Barang Input -->
|
||||
<FormKit
|
||||
type="number"
|
||||
label="Kuantiti Barang"
|
||||
v-model="kuantitiBarang"
|
||||
validation="required|number"
|
||||
/>
|
||||
|
||||
<!-- Jenis Barang Detail Select Input -->
|
||||
<FormKit
|
||||
type="select"
|
||||
label="Jenis Barang"
|
||||
v-model="jenisBarangDetail"
|
||||
:options="jenisBarangDetailOptions"
|
||||
validation="required"
|
||||
/>
|
||||
|
||||
<!-- Jenis Barang Siber Select Input -->
|
||||
<FormKit
|
||||
type="select"
|
||||
label="Jenis Barang Siber"
|
||||
v-model="jenisBarangSiber"
|
||||
:options="jenisBarangSiberOptions"
|
||||
validation="required"
|
||||
/>
|
||||
<!-- Barang Section -->
|
||||
<div class="mb-4">
|
||||
<h3 class="mb-2">Senarai Barang</h3>
|
||||
<table
|
||||
v-if="barangList.length > 0"
|
||||
class="w-full border-collapse border border-gray-300 mb-2"
|
||||
>
|
||||
<thead>
|
||||
<tr class="bg-gray-100">
|
||||
<th class="border border-gray-300 p-2">Jenis Barang</th>
|
||||
<th class="border border-gray-300 p-2">Kuantiti</th>
|
||||
<th class="border border-gray-300 p-2">Tindakan</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(barang, index) in barangList" :key="index">
|
||||
<td class="border border-gray-300 p-2">
|
||||
{{ barang.jenisBarang }}
|
||||
</td>
|
||||
<td class="border border-gray-300 p-2">
|
||||
{{ barang.kuantitiBarang }}
|
||||
</td>
|
||||
<td class="border border-gray-300 p-2">
|
||||
<rs-button
|
||||
type="button"
|
||||
@click="editBarang(index)"
|
||||
variant="secondary"
|
||||
class="mr-2"
|
||||
>
|
||||
Edit
|
||||
</rs-button>
|
||||
<rs-button
|
||||
type="button"
|
||||
@click="removeBarang(index)"
|
||||
variant="danger"
|
||||
>
|
||||
Buang
|
||||
</rs-button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div v-else class="text-gray-500 mb-2">Tiada barang ditambah</div>
|
||||
<rs-button type="button" @click="openBarangModal" variant="primary">
|
||||
Tambah Barang
|
||||
</rs-button>
|
||||
</div>
|
||||
|
||||
<!-- No Kertas Siasatan Input -->
|
||||
<FormKit
|
||||
@ -179,14 +177,120 @@
|
||||
>
|
||||
<rs-button
|
||||
type="submit"
|
||||
@click="submitForm"
|
||||
btn-type="submit"
|
||||
:disabled="!isFormValid"
|
||||
variant="success"
|
||||
>Hantar</rs-button
|
||||
>
|
||||
</div>
|
||||
</FormKit>
|
||||
</rs-card>
|
||||
|
||||
<!-- Barang Modal -->
|
||||
<div
|
||||
v-if="isBarangModalOpen"
|
||||
class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center"
|
||||
>
|
||||
<div class="bg-white p-6 rounded-lg w-full max-w-2xl">
|
||||
<h2 class="text-2xl font-bold mb-4">
|
||||
{{ editingBarangIndex === null ? "Tambah" : "Edit" }} Barang
|
||||
</h2>
|
||||
|
||||
<FormKit
|
||||
type="form"
|
||||
:actions="false"
|
||||
@submit="saveBarangModal"
|
||||
#default="{ state: formState }"
|
||||
>
|
||||
<FormKit
|
||||
type="text"
|
||||
name="jenisBarang"
|
||||
label="Jenis Barang"
|
||||
v-model="currentBarang.jenisBarang"
|
||||
validation="required"
|
||||
:validation-messages="{
|
||||
required: 'Jenis Barang diperlukan',
|
||||
}"
|
||||
/>
|
||||
|
||||
<FormKit
|
||||
type="text"
|
||||
name="tandaBarang"
|
||||
label="Tanda Barang"
|
||||
v-model="currentBarang.tandaBarang"
|
||||
validation="required"
|
||||
:validation-messages="{
|
||||
required: 'Tanda Barang diperlukan',
|
||||
}"
|
||||
/>
|
||||
|
||||
<FormKit
|
||||
type="text"
|
||||
name="keadaanBarang"
|
||||
label="Keadaan Barang"
|
||||
v-model="currentBarang.keadaanBarang"
|
||||
validation="required"
|
||||
:validation-messages="{
|
||||
required: 'Keadaan Barang diperlukan',
|
||||
}"
|
||||
/>
|
||||
|
||||
<FormKit
|
||||
type="number"
|
||||
name="kuantitiBarang"
|
||||
label="Kuantiti Barang"
|
||||
v-model="currentBarang.kuantitiBarang"
|
||||
validation="required|number|min:1"
|
||||
:validation-messages="{
|
||||
required: 'Kuantiti Barang diperlukan',
|
||||
number: 'Kuantiti Barang mesti nombor',
|
||||
min: 'Kuantiti Barang mesti sekurang-kurangnya 1',
|
||||
}"
|
||||
/>
|
||||
|
||||
<FormKit
|
||||
type="select"
|
||||
name="jenisBarangDetail"
|
||||
label="Jenis Barang Detail"
|
||||
v-model="currentBarang.jenisBarangDetail"
|
||||
:options="jenisBarangDetailOptions"
|
||||
validation="required"
|
||||
:validation-messages="{
|
||||
required: 'Jenis Barang Detail diperlukan',
|
||||
}"
|
||||
/>
|
||||
|
||||
<FormKit
|
||||
type="select"
|
||||
name="jenisBarangSiber"
|
||||
label="Jenis Barang Siber"
|
||||
v-model="currentBarang.jenisBarangSiber"
|
||||
:options="jenisBarangSiberOptions"
|
||||
validation="required"
|
||||
:validation-messages="{
|
||||
required: 'Jenis Barang Siber diperlukan',
|
||||
}"
|
||||
/>
|
||||
|
||||
<div class="flex justify-end gap-2 mt-4">
|
||||
<rs-button
|
||||
type="button"
|
||||
btn-type="reset"
|
||||
@click="cancelBarangModal"
|
||||
variant="danger"
|
||||
>Batal</rs-button
|
||||
>
|
||||
<rs-button
|
||||
type="submit"
|
||||
btn-type="submit"
|
||||
variant="success"
|
||||
:disabled="!formState.valid"
|
||||
>Simpan</rs-button
|
||||
>
|
||||
</div>
|
||||
</FormKit>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -204,12 +308,7 @@ const pangkatPenghantar = ref("");
|
||||
const noPegawaiPenghantar = ref("");
|
||||
const ringkasanKenyataanKes = ref("");
|
||||
const bilangan = ref(0);
|
||||
const jenisBarang = ref("");
|
||||
const tandaBarang = ref("");
|
||||
const keadaanBarang = ref("");
|
||||
const kuantitiBarang = ref(0);
|
||||
const jenisBarangDetail = ref("");
|
||||
const jenisBarangSiber = ref("");
|
||||
const barangList = ref([]);
|
||||
const noKertasSiasatan = ref("");
|
||||
const noLaporanPolis = ref("");
|
||||
const tarikhTemujanji = ref("");
|
||||
@ -218,6 +317,17 @@ const slotMasa = ref("");
|
||||
// State for single checkbox
|
||||
const isPenghantarSameAsPemohon = ref(false);
|
||||
|
||||
const isBarangModalOpen = ref(false);
|
||||
const editingBarangIndex = ref(null);
|
||||
const currentBarang = ref({
|
||||
jenisBarang: "",
|
||||
tandaBarang: "",
|
||||
keadaanBarang: "",
|
||||
kuantitiBarang: 1,
|
||||
jenisBarangDetail: "",
|
||||
jenisBarangSiber: "",
|
||||
});
|
||||
|
||||
const jenisBarangDetailOptions = [
|
||||
"PASPORT",
|
||||
"MALPASS",
|
||||
@ -249,6 +359,42 @@ const navigateBack = () => {
|
||||
router.back();
|
||||
};
|
||||
|
||||
const openBarangModal = () => {
|
||||
editingBarangIndex.value = null;
|
||||
currentBarang.value = {
|
||||
jenisBarang: "",
|
||||
tandaBarang: "",
|
||||
keadaanBarang: "",
|
||||
kuantitiBarang: 1,
|
||||
jenisBarangDetail: "",
|
||||
jenisBarangSiber: "",
|
||||
};
|
||||
isBarangModalOpen.value = true;
|
||||
};
|
||||
|
||||
const editBarang = (index) => {
|
||||
editingBarangIndex.value = index;
|
||||
currentBarang.value = { ...barangList.value[index] };
|
||||
isBarangModalOpen.value = true;
|
||||
};
|
||||
|
||||
const removeBarang = (index) => {
|
||||
barangList.value.splice(index, 1);
|
||||
};
|
||||
|
||||
const cancelBarangModal = () => {
|
||||
isBarangModalOpen.value = false;
|
||||
};
|
||||
|
||||
const saveBarangModal = () => {
|
||||
if (editingBarangIndex.value === null) {
|
||||
barangList.value.push({ ...currentBarang.value });
|
||||
} else {
|
||||
barangList.value[editingBarangIndex.value] = { ...currentBarang.value };
|
||||
}
|
||||
isBarangModalOpen.value = false;
|
||||
};
|
||||
|
||||
const isFormValid = () => {
|
||||
const requiredFields = [
|
||||
namaPemohon,
|
||||
@ -259,21 +405,25 @@ const isFormValid = () => {
|
||||
noPegawaiPenghantar,
|
||||
ringkasanKenyataanKes,
|
||||
bilangan,
|
||||
jenisBarang,
|
||||
tandaBarang,
|
||||
keadaanBarang,
|
||||
kuantitiBarang,
|
||||
jenisBarangDetail,
|
||||
jenisBarangSiber,
|
||||
noKertasSiasatan,
|
||||
noLaporanPolis,
|
||||
tarikhTemujanji,
|
||||
slotMasa,
|
||||
];
|
||||
|
||||
return requiredFields.every(
|
||||
const areRequiredFieldsFilled = requiredFields.every(
|
||||
(field) => field.value !== "" && field.value !== 0
|
||||
);
|
||||
|
||||
const areBarangFieldsValid = barangList.value.every((barang) =>
|
||||
Object.values(barang).every((value) => value !== "" && value !== 0)
|
||||
);
|
||||
|
||||
return (
|
||||
areRequiredFieldsFilled &&
|
||||
areBarangFieldsValid &&
|
||||
barangList.value.length > 0
|
||||
);
|
||||
};
|
||||
|
||||
const simpan = () => {
|
||||
@ -298,12 +448,7 @@ const simpan = () => {
|
||||
noPegawaiPenghantar: noPegawaiPenghantar.value,
|
||||
ringkasanKenyataanKes: ringkasanKenyataanKes.value,
|
||||
bilangan: bilangan.value,
|
||||
jenisBarang: jenisBarang.value,
|
||||
tandaBarang: tandaBarang.value,
|
||||
keadaanBarang: keadaanBarang.value,
|
||||
kuantitiBarang: kuantitiBarang.value,
|
||||
jenisBarangDetail: jenisBarangDetail.value,
|
||||
jenisBarangSiber: jenisBarangSiber.value,
|
||||
barangList: barangList.value,
|
||||
noKertasSiasatan: noKertasSiasatan.value,
|
||||
noLaporanPolis: noLaporanPolis.value,
|
||||
tarikhTemujanji: tarikhTemujanji.value,
|
||||
@ -344,12 +489,7 @@ const submitForm = () => {
|
||||
noPegawaiPenghantar: noPegawaiPenghantar.value,
|
||||
ringkasanKenyataanKes: ringkasanKenyataanKes.value,
|
||||
bilangan: bilangan.value,
|
||||
jenisBarang: jenisBarang.value,
|
||||
tandaBarang: tandaBarang.value,
|
||||
keadaanBarang: keadaanBarang.value,
|
||||
kuantitiBarang: kuantitiBarang.value,
|
||||
jenisBarangDetail: jenisBarangDetail.value,
|
||||
jenisBarangSiber: jenisBarangSiber.value,
|
||||
barangList: barangList.value,
|
||||
noKertasSiasatan: noKertasSiasatan.value,
|
||||
noLaporanPolis: noLaporanPolis.value,
|
||||
tarikhTemujanji: tarikhTemujanji.value,
|
||||
@ -367,7 +507,7 @@ const submitForm = () => {
|
||||
// Show error message
|
||||
$swal.fire({
|
||||
title: "Ralat!",
|
||||
text: "Sila isi semua medan yang diperlukan.",
|
||||
text: "Sila isi semua medan yang diperlukan dan tambah sekurang-kurangnya satu barang.",
|
||||
icon: "error",
|
||||
confirmButtonText: "OK",
|
||||
});
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="flex justify-between items-center">
|
||||
<h1>Kemaskini Permohonan</h1>
|
||||
<h1>Permohonan Baru</h1>
|
||||
</div>
|
||||
|
||||
<rs-card class="mt-4 p-4">
|
||||
@ -80,55 +80,53 @@
|
||||
validation="required|number"
|
||||
/>
|
||||
|
||||
<!-- Jenis Barang Input -->
|
||||
<FormKit
|
||||
type="text"
|
||||
label="Jenis Barang"
|
||||
v-model="jenisBarang"
|
||||
validation="required"
|
||||
/>
|
||||
|
||||
<!-- Tanda Barang Input -->
|
||||
<FormKit
|
||||
type="text"
|
||||
label="Tanda Barang"
|
||||
v-model="tandaBarang"
|
||||
validation="required"
|
||||
/>
|
||||
|
||||
<!-- Keadaan Barang Input -->
|
||||
<FormKit
|
||||
type="text"
|
||||
label="Keadaan Barang"
|
||||
v-model="keadaanBarang"
|
||||
validation="required"
|
||||
/>
|
||||
|
||||
<!-- Kuantiti Barang Input -->
|
||||
<FormKit
|
||||
type="number"
|
||||
label="Kuantiti Barang"
|
||||
v-model="kuantitiBarang"
|
||||
validation="required|number"
|
||||
/>
|
||||
|
||||
<!-- Jenis Barang Detail Select Input -->
|
||||
<FormKit
|
||||
type="select"
|
||||
label="Jenis Barang"
|
||||
v-model="jenisBarangDetail"
|
||||
:options="jenisBarangDetailOptions"
|
||||
validation="required"
|
||||
/>
|
||||
|
||||
<!-- Jenis Barang Siber Select Input -->
|
||||
<FormKit
|
||||
type="select"
|
||||
label="Jenis Barang Siber"
|
||||
v-model="jenisBarangSiber"
|
||||
:options="jenisBarangSiberOptions"
|
||||
validation="required"
|
||||
/>
|
||||
<!-- Barang Section -->
|
||||
<div class="mb-4">
|
||||
<h3 class="mb-2">Senarai Barang</h3>
|
||||
<table
|
||||
v-if="barangList.length > 0"
|
||||
class="w-full border-collapse border border-gray-300 mb-2"
|
||||
>
|
||||
<thead>
|
||||
<tr class="bg-gray-100">
|
||||
<th class="border border-gray-300 p-2">Jenis Barang</th>
|
||||
<th class="border border-gray-300 p-2">Kuantiti</th>
|
||||
<th class="border border-gray-300 p-2">Tindakan</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(barang, index) in barangList" :key="index">
|
||||
<td class="border border-gray-300 p-2">
|
||||
{{ barang.jenisBarang }}
|
||||
</td>
|
||||
<td class="border border-gray-300 p-2">
|
||||
{{ barang.kuantitiBarang }}
|
||||
</td>
|
||||
<td class="border border-gray-300 p-2">
|
||||
<rs-button
|
||||
type="button"
|
||||
@click="editBarang(index)"
|
||||
variant="secondary"
|
||||
class="mr-2"
|
||||
>
|
||||
Edit
|
||||
</rs-button>
|
||||
<rs-button
|
||||
type="button"
|
||||
@click="removeBarang(index)"
|
||||
variant="danger"
|
||||
>
|
||||
Buang
|
||||
</rs-button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div v-else class="text-gray-500 mb-2">Tiada barang ditambah</div>
|
||||
<rs-button type="button" @click="openBarangModal" variant="primary">
|
||||
Tambah Barang
|
||||
</rs-button>
|
||||
</div>
|
||||
|
||||
<!-- No Kertas Siasatan Input -->
|
||||
<FormKit
|
||||
@ -182,6 +180,112 @@
|
||||
</div>
|
||||
</FormKit>
|
||||
</rs-card>
|
||||
|
||||
<!-- Barang Modal -->
|
||||
<div
|
||||
v-if="isBarangModalOpen"
|
||||
class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center"
|
||||
>
|
||||
<div class="bg-white p-6 rounded-lg w-full max-w-2xl">
|
||||
<h2 class="text-2xl font-bold mb-4">
|
||||
{{ editingBarangIndex === null ? "Tambah" : "Edit" }} Barang
|
||||
</h2>
|
||||
|
||||
<FormKit
|
||||
type="form"
|
||||
:actions="false"
|
||||
@submit="saveBarangModal"
|
||||
#default="{ state: formState }"
|
||||
>
|
||||
<FormKit
|
||||
type="text"
|
||||
name="jenisBarang"
|
||||
label="Jenis Barang"
|
||||
v-model="currentBarang.jenisBarang"
|
||||
validation="required"
|
||||
:validation-messages="{
|
||||
required: 'Jenis Barang diperlukan',
|
||||
}"
|
||||
/>
|
||||
|
||||
<FormKit
|
||||
type="text"
|
||||
name="tandaBarang"
|
||||
label="Tanda Barang"
|
||||
v-model="currentBarang.tandaBarang"
|
||||
validation="required"
|
||||
:validation-messages="{
|
||||
required: 'Tanda Barang diperlukan',
|
||||
}"
|
||||
/>
|
||||
|
||||
<FormKit
|
||||
type="text"
|
||||
name="keadaanBarang"
|
||||
label="Keadaan Barang"
|
||||
v-model="currentBarang.keadaanBarang"
|
||||
validation="required"
|
||||
:validation-messages="{
|
||||
required: 'Keadaan Barang diperlukan',
|
||||
}"
|
||||
/>
|
||||
|
||||
<FormKit
|
||||
type="number"
|
||||
name="kuantitiBarang"
|
||||
label="Kuantiti Barang"
|
||||
v-model="currentBarang.kuantitiBarang"
|
||||
validation="required|number|min:1"
|
||||
:validation-messages="{
|
||||
required: 'Kuantiti Barang diperlukan',
|
||||
number: 'Kuantiti Barang mesti nombor',
|
||||
min: 'Kuantiti Barang mesti sekurang-kurangnya 1',
|
||||
}"
|
||||
/>
|
||||
|
||||
<FormKit
|
||||
type="select"
|
||||
name="jenisBarangDetail"
|
||||
label="Jenis Barang Detail"
|
||||
v-model="currentBarang.jenisBarangDetail"
|
||||
:options="jenisBarangDetailOptions"
|
||||
validation="required"
|
||||
:validation-messages="{
|
||||
required: 'Jenis Barang Detail diperlukan',
|
||||
}"
|
||||
/>
|
||||
|
||||
<FormKit
|
||||
type="select"
|
||||
name="jenisBarangSiber"
|
||||
label="Jenis Barang Siber"
|
||||
v-model="currentBarang.jenisBarangSiber"
|
||||
:options="jenisBarangSiberOptions"
|
||||
validation="required"
|
||||
:validation-messages="{
|
||||
required: 'Jenis Barang Siber diperlukan',
|
||||
}"
|
||||
/>
|
||||
|
||||
<div class="flex justify-end gap-2 mt-4">
|
||||
<rs-button
|
||||
type="button"
|
||||
btn-type="reset"
|
||||
@click="cancelBarangModal"
|
||||
variant="danger"
|
||||
>Batal</rs-button
|
||||
>
|
||||
<rs-button
|
||||
type="submit"
|
||||
btn-type="submit"
|
||||
variant="success"
|
||||
:disabled="!formState.valid"
|
||||
>Simpan</rs-button
|
||||
>
|
||||
</div>
|
||||
</FormKit>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -203,12 +307,7 @@ const pangkatPenghantar = ref("");
|
||||
const noPegawaiPenghantar = ref("");
|
||||
const ringkasanKenyataanKes = ref("");
|
||||
const bilangan = ref(0);
|
||||
const jenisBarang = ref("");
|
||||
const tandaBarang = ref("");
|
||||
const keadaanBarang = ref("");
|
||||
const kuantitiBarang = ref(0);
|
||||
const jenisBarangDetail = ref("");
|
||||
const jenisBarangSiber = ref("");
|
||||
const barangList = ref([]);
|
||||
const noKertasSiasatan = ref("");
|
||||
const noLaporanPolis = ref("");
|
||||
const tarikhTemujanji = ref("");
|
||||
@ -229,6 +328,18 @@ const jenisBarangDetailOptions = [
|
||||
|
||||
const jenisBarangSiberOptions = ["SIBER", "TULISAN TANGAN"];
|
||||
|
||||
// Barang modal state
|
||||
const isBarangModalOpen = ref(false);
|
||||
const editingBarangIndex = ref(null);
|
||||
const currentBarang = ref({
|
||||
jenisBarang: "",
|
||||
tandaBarang: "",
|
||||
keadaanBarang: "",
|
||||
kuantitiBarang: 1,
|
||||
jenisBarangDetail: "",
|
||||
jenisBarangSiber: "",
|
||||
});
|
||||
|
||||
// Watcher to update Penghantar fields when the checkbox is checked
|
||||
watch(isPenghantarSameAsPemohon, (newValue) => {
|
||||
if (newValue) {
|
||||
@ -248,6 +359,43 @@ const navigateBack = () => {
|
||||
router.back();
|
||||
};
|
||||
|
||||
// Barang modal functions
|
||||
const openBarangModal = () => {
|
||||
editingBarangIndex.value = null;
|
||||
currentBarang.value = {
|
||||
jenisBarang: "",
|
||||
tandaBarang: "",
|
||||
keadaanBarang: "",
|
||||
kuantitiBarang: 1,
|
||||
jenisBarangDetail: "",
|
||||
jenisBarangSiber: "",
|
||||
};
|
||||
isBarangModalOpen.value = true;
|
||||
};
|
||||
|
||||
const editBarang = (index) => {
|
||||
editingBarangIndex.value = index;
|
||||
currentBarang.value = { ...barangList.value[index] };
|
||||
isBarangModalOpen.value = true;
|
||||
};
|
||||
|
||||
const removeBarang = (index) => {
|
||||
barangList.value.splice(index, 1);
|
||||
};
|
||||
|
||||
const cancelBarangModal = () => {
|
||||
isBarangModalOpen.value = false;
|
||||
};
|
||||
|
||||
const saveBarangModal = () => {
|
||||
if (editingBarangIndex.value === null) {
|
||||
barangList.value.push({ ...currentBarang.value });
|
||||
} else {
|
||||
barangList.value[editingBarangIndex.value] = { ...currentBarang.value };
|
||||
}
|
||||
isBarangModalOpen.value = false;
|
||||
};
|
||||
|
||||
// Validate the form
|
||||
const isFormValid = () => {
|
||||
const requiredFields = [
|
||||
@ -259,21 +407,25 @@ const isFormValid = () => {
|
||||
noPegawaiPenghantar,
|
||||
ringkasanKenyataanKes,
|
||||
bilangan,
|
||||
jenisBarang,
|
||||
tandaBarang,
|
||||
keadaanBarang,
|
||||
kuantitiBarang,
|
||||
jenisBarangDetail,
|
||||
jenisBarangSiber,
|
||||
noKertasSiasatan,
|
||||
noLaporanPolis,
|
||||
tarikhTemujanji,
|
||||
slotMasa,
|
||||
];
|
||||
|
||||
return requiredFields.every(
|
||||
const areRequiredFieldsFilled = requiredFields.every(
|
||||
(field) => field.value !== "" && field.value !== 0
|
||||
);
|
||||
|
||||
const areBarangFieldsValid = barangList.value.every((barang) =>
|
||||
Object.values(barang).every((value) => value !== "" && value !== 0)
|
||||
);
|
||||
|
||||
return (
|
||||
areRequiredFieldsFilled &&
|
||||
areBarangFieldsValid &&
|
||||
barangList.value.length > 0
|
||||
);
|
||||
};
|
||||
|
||||
const simpan = () => {
|
||||
@ -298,12 +450,7 @@ const simpan = () => {
|
||||
noPegawaiPenghantar: noPegawaiPenghantar.value,
|
||||
ringkasanKenyataanKes: ringkasanKenyataanKes.value,
|
||||
bilangan: bilangan.value,
|
||||
jenisBarang: jenisBarang.value,
|
||||
tandaBarang: tandaBarang.value,
|
||||
keadaanBarang: keadaanBarang.value,
|
||||
kuantitiBarang: kuantitiBarang.value,
|
||||
jenisBarangDetail: jenisBarangDetail.value,
|
||||
jenisBarangSiber: jenisBarangSiber.value,
|
||||
barangList: barangList.value,
|
||||
noKertasSiasatan: noKertasSiasatan.value,
|
||||
noLaporanPolis: noLaporanPolis.value,
|
||||
tarikhTemujanji: tarikhTemujanji.value,
|
||||
@ -344,12 +491,7 @@ const submitForm = () => {
|
||||
noPegawaiPenghantar: noPegawaiPenghantar.value,
|
||||
ringkasanKenyataanKes: ringkasanKenyataanKes.value,
|
||||
bilangan: bilangan.value,
|
||||
jenisBarang: jenisBarang.value,
|
||||
tandaBarang: tandaBarang.value,
|
||||
keadaanBarang: keadaanBarang.value,
|
||||
kuantitiBarang: kuantitiBarang.value,
|
||||
jenisBarangDetail: jenisBarangDetail.value,
|
||||
jenisBarangSiber: jenisBarangSiber.value,
|
||||
barangList: barangList.value,
|
||||
noKertasSiasatan: noKertasSiasatan.value,
|
||||
noLaporanPolis: noLaporanPolis.value,
|
||||
tarikhTemujanji: tarikhTemujanji.value,
|
||||
@ -367,7 +509,7 @@ const submitForm = () => {
|
||||
// Show error message
|
||||
$swal.fire({
|
||||
title: "Ralat!",
|
||||
text: "Sila isi semua medan yang diperlukan.",
|
||||
text: "Sila isi semua medan yang diperlukan dan tambah sekurang-kurangnya satu barang.",
|
||||
icon: "error",
|
||||
confirmButtonText: "OK",
|
||||
});
|
||||
@ -398,6 +540,15 @@ function generateSampleData(noSiri) {
|
||||
];
|
||||
const keadaanBarangOptions = ["Baik", "Sederhana", "Rosak"];
|
||||
|
||||
const generateBarang = () => ({
|
||||
jenisBarang: randomChoice(jenisBarangOptions),
|
||||
tandaBarang: `TB-${randomNumber(1000, 9999)}`,
|
||||
keadaanBarang: randomChoice(keadaanBarangOptions),
|
||||
kuantitiBarang: randomNumber(1, 10),
|
||||
jenisBarangDetail: randomChoice(jenisBarangDetailOptions),
|
||||
jenisBarangSiber: randomChoice(jenisBarangSiberOptions),
|
||||
});
|
||||
|
||||
return {
|
||||
noSiri: noSiri,
|
||||
namaPemohon: randomChoice(namaPemohon),
|
||||
@ -405,16 +556,12 @@ function generateSampleData(noSiri) {
|
||||
noPegawaiPemohon: `PG${randomNumber(10000, 99999)}`,
|
||||
namaPenghantar: randomChoice(namaPemohon),
|
||||
pangkatPenghantar: randomChoice(pangkat),
|
||||
noPegawaiPenghantar: `PG${randomNumber(10000, 99999)}`,
|
||||
ringkasanKenyataanKes: `Kes ${noSiri}: Penemuan barang bukti dalam serbuan di lokasi ${randomChoice(
|
||||
["A", "B", "C", "D"]
|
||||
)}`,
|
||||
bilangan: randomNumber(1, 10),
|
||||
jenisBarang: randomChoice(jenisBarangOptions),
|
||||
tandaBarang: `TB-${randomNumber(1000, 9999)}`,
|
||||
keadaanBarang: randomChoice(keadaanBarangOptions),
|
||||
kuantitiBarang: randomNumber(1, 100),
|
||||
jenisBarangDetail: randomChoice(jenisBarangDetailOptions),
|
||||
jenisBarangSiber: randomChoice(jenisBarangSiberOptions),
|
||||
bilangan: randomNumber(1, 5),
|
||||
barangList: Array.from({ length: randomNumber(1, 3) }, generateBarang),
|
||||
noKertasSiasatan: `KS-${randomNumber(10000, 99999)}`,
|
||||
noLaporanPolis: `RPT-${randomNumber(100000, 999999)}`,
|
||||
tarikhTemujanji: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000)
|
||||
@ -432,14 +579,10 @@ onMounted(() => {
|
||||
noPegawaiPemohon.value = sampleData.noPegawaiPemohon;
|
||||
namaPenghantar.value = sampleData.namaPenghantar;
|
||||
pangkatPenghantar.value = sampleData.pangkatPenghantar;
|
||||
noPegawaiPenghantar.value = sampleData.noPegawaiPenghantar;
|
||||
ringkasanKenyataanKes.value = sampleData.ringkasanKenyataanKes;
|
||||
bilangan.value = sampleData.bilangan;
|
||||
jenisBarang.value = sampleData.jenisBarang;
|
||||
tandaBarang.value = sampleData.tandaBarang;
|
||||
keadaanBarang.value = sampleData.keadaanBarang;
|
||||
kuantitiBarang.value = sampleData.kuantitiBarang;
|
||||
jenisBarangDetail.value = sampleData.jenisBarangDetail;
|
||||
jenisBarangSiber.value = sampleData.jenisBarangSiber;
|
||||
barangList.value = sampleData.barangList;
|
||||
noKertasSiasatan.value = sampleData.noKertasSiasatan;
|
||||
noLaporanPolis.value = sampleData.noLaporanPolis;
|
||||
tarikhTemujanji.value = sampleData.tarikhTemujanji;
|
||||
|
Loading…
x
Reference in New Issue
Block a user