This commit is contained in:
Haqeem Solehan 2024-09-04 16:12:14 +08:00
parent fa0838eddf
commit 254b6334af
5 changed files with 834 additions and 99 deletions

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"vue3snippets.enable-compile-vue-file-on-did-save-code": true
}

View File

@ -56,6 +56,7 @@
"crypto-js": "^4.1.1", "crypto-js": "^4.1.1",
"floating-vue": "^2.0.0-beta.24", "floating-vue": "^2.0.0-beta.24",
"jsonwebtoken": "^8.5.1", "jsonwebtoken": "^8.5.1",
"jspdf": "^2.5.1",
"luxon": "^3.1.0", "luxon": "^3.1.0",
"maska": "^1.5.0", "maska": "^1.5.0",
"pinia": "^2.1.6", "pinia": "^2.1.6",
@ -64,6 +65,7 @@
"sass": "^1.62.0", "sass": "^1.62.0",
"swiper": "^8.4.4", "swiper": "^8.4.4",
"thememirror": "^2.0.1", "thememirror": "^2.0.1",
"uuid": "^10.0.0",
"v-calendar": "^3.0.3", "v-calendar": "^3.0.3",
"vue-chart-3": "^3.1.8", "vue-chart-3": "^3.1.8",
"vue-code-highlight": "^0.7.8", "vue-code-highlight": "^0.7.8",

View File

@ -0,0 +1,306 @@
<template>
<div class="container mx-auto p-4">
<div class="flex justify-between items-center mb-4">
<h1 class="text-2xl font-bold">Laporan Bahan Bukti</h1>
<button
@click="generatePDF"
class="bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded"
>
Jana PDF
</button>
</div>
<rs-card class="p-4">
<FormKit
type="form"
@submit="submitForm"
#default="{ state }"
:actions="false"
class="space-y-6"
>
<!-- KES ID and BARANG KES DETAIL -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<FormKit
type="text"
name="kesId"
label="KES ID"
v-model="generatedData.kesId"
validation="required"
:validation-messages="{ required: 'KES ID diperlukan' }"
disabled
/>
<FormKit
type="text"
name="tagNo"
label="TAG NO"
v-model="generatedData.tagNo"
validation="required"
:validation-messages="{ required: 'TAG NO diperlukan' }"
disabled
/>
<FormKit
type="text"
name="jenisBrg"
label="Jenis Barang"
v-model="generatedData.jenisBrg"
validation="required"
:validation-messages="{ required: 'Jenis Barang diperlukan' }"
disabled
/>
<FormKit
type="text"
name="jenisPemeriksaan"
label="Jenis Pemeriksaan"
v-model="generatedData.jenisPemeriksaan"
validation="required"
:validation-messages="{ required: 'Jenis Pemeriksaan diperlukan' }"
disabled
/>
</div>
<!-- BUTIRAN PEGAWAI -->
<div class="space-y-4">
<h2 class="text-xl font-semibold">Butiran Pegawai</h2>
<div
v-for="role in ['PENYIASAT', 'PENGHANTAR', 'PENERIMA', 'PEMERIKSA']"
:key="role"
class="grid grid-cols-1 md:grid-cols-3 gap-4"
>
<FormKit
type="text"
:name="`pegawai.${role}.nama`"
:label="`${role} - Nama`"
v-model="generatedData.pegawai[role].nama"
validation="required"
:validation-messages="{ required: 'Nama diperlukan' }"
disabled
/>
<FormKit
type="text"
:name="`pegawai.${role}.pangkat`"
:label="`${role} - Pangkat`"
v-model="generatedData.pegawai[role].pangkat"
validation="required"
:validation-messages="{ required: 'Pangkat diperlukan' }"
disabled
/>
<FormKit
type="text"
:name="`pegawai.${role}.noPegawai`"
:label="`${role} - No Pegawai`"
v-model="generatedData.pegawai[role].noPegawai"
validation="required"
:validation-messages="{ required: 'No Pegawai diperlukan' }"
disabled
/>
</div>
</div>
<!-- Peralatan and Langkah2 -->
<div class="space-y-4">
<FormKit
type="textarea"
name="peralatan"
label="Peralatan"
validation="required"
:validation-messages="{ required: 'Peralatan diperlukan' }"
:rows="3"
/>
<FormKit
type="textarea"
name="langkah2"
label="Langkah-langkah"
validation="required"
:validation-messages="{ required: 'Langkah-langkah diperlukan' }"
:rows="5"
/>
</div>
<!-- Dapatan -->
<FormKit
type="radio"
name="dapatan"
label="Dapatan"
:options="['Tulen', 'Palsu', 'Tidak dapat dikenalpasti']"
validation="required"
:validation-messages="{ required: 'Dapatan diperlukan' }"
/>
<!-- Document Tambahan -->
<div>
<h2 class="text-xl font-semibold mb-2">Document Tambahan</h2>
<FormKit type="list" name="documentTambahan" :value="[]">
<FormKit type="group" :repeatable="true" :key="index">
<div class="flex items-center space-x-2">
<FormKit
type="text"
name="nama"
placeholder="Nama dokumen"
validation="required"
:validation-messages="{ required: 'Nama dokumen diperlukan' }"
/>
<FormKit
type="file"
name="file"
validation="required"
multiple
:validation-messages="{ required: 'Fail diperlukan' }"
/>
</div>
</FormKit>
</FormKit>
</div>
<div class="flex justify-end gap-2">
<rs-button btn-type="reset" @click="previousPage()"
>Kembali</rs-button
>
<rs-button type="submit" btn-type="submit">Hantar Laporan</rs-button>
</div>
</FormKit>
</rs-card>
</div>
</template>
<script setup>
import { useRoute } from "vue-router";
import { ref, onMounted } from "vue";
import { jsPDF } from "jspdf";
const route = useRoute();
const bahanBukti = route.params.bahanBukti;
const generatedData = ref({
kesId: "",
tagNo: "",
jenisBrg: "",
jenisPemeriksaan: "",
pegawai: {
PENYIASAT: { nama: "", pangkat: "", noPegawai: "" },
PENGHANTAR: { nama: "", pangkat: "", noPegawai: "" },
PENERIMA: { nama: "", pangkat: "", noPegawai: "" },
PEMERIKSA: { nama: "", pangkat: "", noPegawai: "" },
},
peralatan: "",
langkah2: "",
dapatan: "",
documentTambahan: [],
});
onMounted(() => {
// Simulate fetching system-generated data
generatedData.value = {
kesId: `KES${Math.floor(Math.random() * 1000000)
.toString()
.padStart(6, "0")}`,
tagNo: `TAG${Math.floor(Math.random() * 10000)
.toString()
.padStart(4, "0")}`,
jenisBrg: ["Dokumen", "Elektronik", "Senjata"][
Math.floor(Math.random() * 3)
],
jenisPemeriksaan: ["Forensik", "Visual", "Kimia"][
Math.floor(Math.random() * 3)
],
pegawai: {
PENYIASAT: generatePegawai("KB"),
PENGHANTAR: generatePegawai(),
PENERIMA: generatePegawai(),
PEMERIKSA: generatePegawai(),
},
};
});
function generatePegawai(role = "") {
const names = ["Ahmad", "Siti", "Mohd", "Nurul", "Lim", "Raj"];
const surnames = ["Abdullah", "Tan", "Kumar", "Lee", "Muthu", "Hassan"];
const pangkat = ["Inspektor", "Sarjan", "Koperal", "Konstabel"];
return {
nama: `${names[Math.floor(Math.random() * names.length)]} ${
surnames[Math.floor(Math.random() * surnames.length)]
}`,
pangkat:
role === "KB"
? "Ketua Bahagian"
: pangkat[Math.floor(Math.random() * pangkat.length)],
noPegawai: `P${Math.floor(Math.random() * 100000)
.toString()
.padStart(5, "0")}`,
};
}
const submitForm = async (formData) => {
console.log("Form submitted:", formData);
// Implement your API call or form submission logic here
};
const generatePDF = () => {
const doc = new jsPDF();
// Set font sizes
const titleSize = 16;
const subtitleSize = 14;
const normalSize = 10;
// Add title
doc.setFontSize(titleSize);
doc.text("Laporan Bahan Bukti", 105, 20, { align: "center" });
// Add case details
doc.setFontSize(subtitleSize);
doc.text("Butiran Kes", 20, 40);
doc.setFontSize(normalSize);
doc.text(`KES ID: ${generatedData.value.kesId}`, 30, 50);
doc.text(`TAG NO: ${generatedData.value.tagNo}`, 30, 60);
doc.text(`Jenis Barang: ${generatedData.value.jenisBrg}`, 30, 70);
doc.text(`Jenis Pemeriksaan: ${generatedData.value.jenisPemeriksaan}`, 30, 80);
// Add officer details
doc.setFontSize(subtitleSize);
doc.text("Butiran Pegawai", 20, 100);
doc.setFontSize(normalSize);
let yPos = 110;
for (const [role, officer] of Object.entries(generatedData.value.pegawai)) {
doc.text(`${role}:`, 30, yPos);
doc.text(`Nama: ${officer.nama}`, 40, yPos + 10);
doc.text(`Pangkat: ${officer.pangkat}`, 40, yPos + 20);
doc.text(`No Pegawai: ${officer.noPegawai}`, 40, yPos + 30);
yPos += 45;
}
// Add examination details
doc.setFontSize(subtitleSize);
doc.text("Butiran Pemeriksaan", 20, yPos);
doc.setFontSize(normalSize);
doc.text(`Peralatan: ${generatedData.value.peralatan || "N/A"}`, 30, yPos + 10);
doc.text(`Langkah-langkah: ${generatedData.value.langkah2 || "N/A"}`, 30, yPos + 20);
doc.text(`Dapatan: ${generatedData.value.dapatan || "N/A"}`, 30, yPos + 30);
// Add additional documents
if (generatedData.value.documentTambahan && generatedData.value.documentTambahan.length > 0) {
yPos += 50;
doc.setFontSize(subtitleSize);
doc.text("Dokumen Tambahan", 20, yPos);
doc.setFontSize(normalSize);
generatedData.value.documentTambahan.forEach((doc, index) => {
doc.text(`${index + 1}. ${doc.nama}`, 30, yPos + 10 + (index * 10));
});
}
// Generate and download the PDF
doc.save(`Laporan_${generatedData.value.kesId}.pdf`);
};
function previousPage() {
window.history.back();
}
</script>
<style lang="scss" scoped>
// Add any scoped styles here if needed
</style>

View File

@ -4,20 +4,22 @@
<rs-card class="p-6"> <rs-card class="p-6">
<div class="flex justify-between items-center"> <div class="flex justify-between items-center">
<h3 class="text-lg font-semibold">Status Semakan</h3> <h3 class="text-lg font-semibold">Status Semakan</h3>
<rs-badge <rs-badge :variant="statusSemakan === 'Selesai' ? 'success' : 'warning'">
:variant="statusSemakan === 'Selesai' ? 'success' : 'warning'"
>
{{ statusSemakan }} {{ statusSemakan }}
</rs-badge> </rs-badge>
</div> </div>
<div class="flex justify-between items-center mt-4"> <div class="flex justify-between items-center mt-4">
<h3 class="text-lg font-semibold">Status Penerimaan</h3> <h3 class="text-lg font-semibold">Status Penerimaan</h3>
<rs-badge <rs-badge :variant="statusPenerimaan === 'Diterima' ? 'success' : 'danger'">
:variant="statusPenerimaan === 'Diterima' ? 'success' : 'danger'"
>
{{ statusPenerimaan }} {{ statusPenerimaan }}
</rs-badge> </rs-badge>
</div> </div>
<div class="flex gap-2 justify-end mt-5">
<rs-button @click="openSemakModal">Semak</rs-button>
<rs-button @click="openTerimaModal">Terima</rs-button>
<rs-button @click="openTolakModal">Tolak</rs-button>
</div>
</rs-card> </rs-card>
<!-- LIST: Pegawai Forensic Yang Terlibat --> <!-- LIST: Pegawai Forensic Yang Terlibat -->
@ -68,17 +70,13 @@
<template v-slot:tindakan="data"> <template v-slot:tindakan="data">
<div class="flex gap-2"> <div class="flex gap-2">
<rs-button <rs-button
@click="openEditModal(data.value)" @click="openEditModal(data.text, data.index)"
variant="info" variant="info"
size="sm" size="sm"
> >
<Icon name="ic:baseline-edit" size="1.2rem" /> <Icon name="ic:baseline-edit" size="1.2rem" />
</rs-button> </rs-button>
<rs-button <rs-button @click="confirmDelete(data.text)" variant="danger" size="sm">
@click="confirmDelete(data.value)"
variant="danger"
size="sm"
>
<Icon name="ic:baseline-delete" size="1.2rem" /> <Icon name="ic:baseline-delete" size="1.2rem" />
</rs-button> </rs-button>
</div> </div>
@ -131,13 +129,14 @@
<template v-slot:kuantiti="data"> <template v-slot:kuantiti="data">
{{ data.text }} {{ data.text }}
</template> </template>
<template v-slot:action="data" v-if="!isKetuaJabatan"> <template v-slot:tindakan="data">
<rs-button <rs-button
@click="generateReport(data.value)" @click="generateReport(data.text)"
variant="primary" variant="ghost"
size="sm" size="sm"
class="text-primary hover:text-primary-dark"
> >
Jana Laporan <Icon name="mdi:file-report-outline" size="1.5rem" />
</rs-button> </rs-button>
</template> </template>
</rs-table> </rs-table>
@ -151,64 +150,221 @@
</h3> </h3>
</template> </template>
<template #body> <template #body>
<FormKit <FormKit type="form" :actions="false" @submit="handleSubmit">
type="form"
:actions="false"
@submit="handleSubmit"
:value="pegawaiForm"
>
<FormKit <FormKit
v-if="!editMode"
type="select" type="select"
name="id" name="id"
label="Pilih Pegawai" label="Pilih Pegawai"
:options="pegawaiList.map(p => ({ value: p.id, label: `${p.pangkat} ${p.nama} (${p.noPegawai})` }))" :options="pegawaiOption"
v-model="selectedPegawai"
validation="required" validation="required"
:validation-messages="{ :validation-messages="{
required: 'Sila pilih pegawai', 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"> <div class="flex justify-end gap-2">
<rs-button variant="secondary" @click="closeModal">Tutup</rs-button> <rs-button variant="secondary" @click="closeModal">Tutup</rs-button>
<rs-button variant="primary" btn-type="submit"> <rs-button variant="primary" btn-type="submit"> Simpan </rs-button>
Simpan
</rs-button>
</div> </div>
</FormKit> </FormKit>
</template> </template>
<template #footer> </template> <template #footer> </template>
</rs-modal> </rs-modal>
<!-- Semak Modal -->
<rs-modal v-model="showSemakModal" @close="closeSemakModal">
<template #header>
<h3>Semak Maklumat</h3>
</template>
<template #body>
<FormKit
v-if="userRole === 'Pegawai Kaunter'"
type="form"
:actions="false"
@submit="handleSemakSubmit"
>
<!-- Existing form for kaunter role -->
<FormKit
type="radio"
name="peralatanBaik"
label="Peralatan dalam keadaan baik"
:options="['Ya', 'Tidak']"
validation="required"
/>
<FormKit
type="radio"
name="pegawaiBerkelayakan"
label="Pegawai berkelayakan"
:options="['Ya', 'Tidak']"
validation="required"
/>
<FormKit
type="radio"
name="kaedahDapatDilakukan"
label="Kaedah dapat dilakukan"
:options="['Ya', 'Tidak']"
validation="required"
/>
<FormKit
type="radio"
name="subkontrakDiperlukan"
label="Subkontrak diperlukan"
:options="['Ya', 'Tidak']"
validation="required"
/>
<FormKit
type="radio"
name="tugasanDiterima"
label="Tugasan diterima"
:options="['Ya', 'Tidak']"
validation="required"
/>
<FormKit
type="textarea"
name="ulasanPegawaiKaunter"
label="Ulasan pegawai kaunter"
validation="required"
/>
<div class="flex justify-end gap-2 mt-4">
<rs-button variant="danger" @click="closeSemakModal">Batal</rs-button>
<rs-button variant="primary" type="submit">Hantar</rs-button>
</div>
</FormKit>
<FormKit
v-else-if="userRole === 'Ketua Bahagian'"
type="form"
:actions="false"
@submit="handleSemakSubmit"
>
<FormKit
type="radio"
name="kelulusanKetuaBahagian"
label="Kelulusan ketua bahagian"
:options="['Diterima', 'Ditolak']"
validation="required"
/>
<FormKit
type="textarea"
name="ulasanKetuaBahagian"
label="Ulasan"
validation="required"
:validation-messages="{
required: 'Sila masukkan ulasan',
}"
/>
<div class="flex justify-end gap-2 mt-4">
<rs-button variant="danger" @click="closeSemakModal">Batal</rs-button>
<rs-button variant="primary" type="submit">Hantar</rs-button>
</div>
</FormKit>
</template>
<template #footer>
<div></div>
</template>
</rs-modal>
<!-- Terima Modal -->
<rs-modal v-model="showTerimaModal" @close="closeTerimaModal">
<template #header>
<h3>Terima Permohonan</h3>
</template>
<template #body>
<FormKit type="form" :actions="false" @submit="handleTerimaSubmit">
<FormKit
type="radio"
name="peralatanBaik"
label="Peralatan dalam keadaan baik"
:options="['Ya', 'Tidak']"
validation="required"
/>
<FormKit
type="radio"
name="pegawaiBerkelayakan"
label="Pegawai berkelayakan"
:options="['Ya', 'Tidak']"
validation="required"
/>
<FormKit
type="radio"
name="kaedahDapatDilakukan"
label="Kaedah dapat dilakukan"
:options="['Ya', 'Tidak']"
validation="required"
/>
<FormKit
type="radio"
name="subkontrakDiperlukan"
label="Subkontrak diperlukan"
:options="['Ya', 'Tidak']"
validation="required"
/>
<FormKit
type="radio"
name="tugasanDiterima"
label="Tugasan diterima"
:options="['Ya', 'Tidak']"
validation="required"
/>
<FormKit
type="textarea"
name="ulasanPegawaiKaunter"
label="Ulasan pegawai kaunter"
validation="required"
/>
<div class="flex justify-end gap-2 mt-4">
<rs-button variant="danger" @click="closeTerimaModal">Batal</rs-button>
<rs-button variant="primary" type="submit">Hantar</rs-button>
</div>
</FormKit>
</template>
<template #footer>
<div></div>
</template>
</rs-modal>
<!-- Tolak Modal -->
<rs-modal v-model="showTolakModal" @close="closeTolakModal">
<template #header>
<h3>Tolak Permohonan</h3>
</template>
<template #body>
<FormKit type="form" :actions="false" @submit="handleTolakSubmit">
<FormKit
type="select"
name="sebabPenolakan"
label="Sebab penolakan permohonan"
:options="[
'Dokumen tidak lengkap',
'Maklumat tidak tepat',
'Tidak memenuhi syarat',
'Lain-lain',
]"
validation="required"
:validation-messages="{
required: 'Sila pilih sebab penolakan',
}"
/>
<FormKit
type="textarea"
name="lainLainSebab"
label="Lain-lain sebab"
validation="required_if:sebabPenolakan,Lain-lain"
:validation-messages="{
required_if: 'Sila nyatakan sebab lain',
}"
/>
<div class="flex justify-end gap-2 mt-4">
<rs-button variant="secondary" @click="closeTolakModal">Batal</rs-button>
<rs-button variant="danger" type="submit">Hantar</rs-button>
</div>
</FormKit>
</template>
<template #footer>
<div></div>
</template>
</rs-modal>
</div> </div>
</template> </template>
@ -226,22 +382,7 @@ const statusSemakan = ref("Selesai");
const statusPenerimaan = ref("Diterima"); const statusPenerimaan = ref("Diterima");
// Forensic Officers Data // Forensic Officers Data
const forensicOfficers = ref([ const forensicOfficers = ref([]);
{
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 // Evidence Data
const evidences = ref([ const evidences = ref([
@ -270,50 +411,83 @@ const isKetuaJabatan = ref(false);
// Modal Controls // Modal Controls
const showModal = ref(false); const showModal = ref(false);
const editMode = ref(false); const editMode = ref(false);
const pegawaiForm = ref({ id: "", pangkat: "", nama: "", noPegawai: "" }); const selectedPegawai = ref(null);
// Sample pegawai listing (simulating API response) // Sample pegawai listing (simulating API response)
const pegawaiList = ref([]); const pegawaiList = ref([]);
const pegawaiOption = ref([
{
value: null,
label: "Pilih Pegawai",
},
]);
// Fetch pegawai list (simulated API call) // Fetch pegawai list (simulated API call)
const fetchPegawaiList = () => { const fetchPegawaiList = () => {
// In a real scenario, this would be an API call // In a real scenario, this would be an API call
pegawaiList.value = [ pegawaiList.value = [
{ id: 'PG001', nama: 'Ahmad bin Ali', pangkat: 'Inspektor', noPegawai: 'PG12345' }, {
{ id: 'PG002', nama: 'Siti binti Omar', pangkat: 'Sarjan', noPegawai: 'PG67890' }, id: "PG001",
{ id: 'PG003', nama: 'Muthu a/l Rajan', pangkat: 'Koperal', noPegawai: 'PG24680' }, nama: "Ahmad bin Ali",
pangkat: "Inspektor",
noPegawai: "PG12345",
tindakan: 1,
},
{
id: "PG002",
nama: "Siti binti Omar",
pangkat: "Sarjan",
noPegawai: "PG67890",
tindakan: 2,
},
{
id: "PG003",
nama: "Muthu a/l Rajan",
pangkat: "Koperal",
noPegawai: "PG24680",
tindakan: 3,
},
]; ];
}; };
onMounted(() => { onMounted(() => {
fetchPegawaiList(); fetchPegawaiList();
for (let index = 0; index < pegawaiList.value.length; index++) {
pegawaiOption.value.push({
value: pegawaiList.value[index].tindakan,
label: `${pegawaiList.value[index].pangkat} ${pegawaiList.value[index].nama} (${pegawaiList.value[index].noPegawai})`,
});
}
}); });
// Computed property for form validation // Computed property for form validation
const isFormValid = computed(() => { const isFormValid = computed(() => {
return ( return (
pegawaiForm.value.pangkat && // filter pegawaiList based on selectedPegawai
pegawaiForm.value.nama && pegawaiList.value.filter((p) => p.tindakan === selectedPegawai.value)
pegawaiForm.value.noPegawai
); );
}); });
// Actions // Actions
const openAddModal = () => { const openAddModal = () => {
editMode.value = false; editMode.value = false;
pegawaiForm.value = { id: "" }; // Only store the selected pegawai id selectedPegawai.value = null;
showModal.value = true; showModal.value = true;
}; };
const openEditModal = (pegawai) => { const openEditModal = (pegawai, index) => {
editMode.value = true; editMode.value = true;
pegawaiForm.value = { ...pegawai }; selectedPegawai.value = pegawai;
console.log(selectedPegawai.value);
console.log("index", index);
showModal.value = true; showModal.value = true;
}; };
const closeModal = () => { const closeModal = () => {
showModal.value = false; showModal.value = false;
pegawaiForm.value = { id: "", pangkat: "", nama: "", noPegawai: "" }; selectedPegawai.value = null;
}; };
const handleSubmit = () => { const handleSubmit = () => {
@ -325,10 +499,16 @@ const handleSubmit = () => {
}; };
const addNewPegawai = () => { const addNewPegawai = () => {
if (pegawaiForm.value.id) { console.log(selectedPegawai.value);
const selectedPegawai = pegawaiList.value.find(p => p.id === pegawaiForm.value.id); if (selectedPegawai.value) {
if (selectedPegawai) { const selectedPegawai_ = pegawaiList.value.find(
const newPegawai = { ...selectedPegawai, tindakan: uuidv4() }; (p) => p.tindakan === selectedPegawai.value
);
if (selectedPegawai_) {
const newPegawai = {
...selectedPegawai_,
tindakan: selectedPegawai_.tindakan,
};
forensicOfficers.value.push(newPegawai); forensicOfficers.value.push(newPegawai);
$swal.fire("Berjaya", "Pegawai baru telah ditambah", "success"); $swal.fire("Berjaya", "Pegawai baru telah ditambah", "success");
closeModal(); closeModal();
@ -341,19 +521,33 @@ const addNewPegawai = () => {
}; };
const updatePegawai = () => { const updatePegawai = () => {
if (isFormValid.value) { console.log("masuk uodate");
const index = forensicOfficers.value.findIndex( if (selectedPegawai.value) {
(officer) => officer.id === pegawaiForm.value.id console.log(selectedPegawai.value);
const selectedPegawai_ = pegawaiList.value.find(
(p) => p.tindakan == selectedPegawai.value
); );
if (index !== -1) { console.log("selectedPegawai_", selectedPegawai_);
forensicOfficers.value[index] = { ...pegawaiForm.value }; if (selectedPegawai_) {
$swal.fire("Berjaya", "Maklumat pegawai telah dikemaskini", "success"); const pegawaiFromSelectedPegawais = forensicOfficers.value.findIndex(
closeModal(); (officer) => officer.tindakan === selectedPegawai.value
);
console.log("pegawaiFromSelectedPegawais", pegawaiFromSelectedPegawais);
if (pegawai_ !== -1) {
forensicOfficers.value[pegawai_] = {
...selectedPegawai_,
tindakan: selectedPegawai_.tindakan,
};
$swal.fire("Berjaya", "Maklumat pegawai telah dikemaskini", "success");
closeModal();
} else {
$swal.fire("Ralat", "Pegawai tidak dijumpai", "error");
}
} else { } else {
$swal.fire("Ralat", "Pegawai tidak dijumpai", "error"); $swal.fire("Ralat", "Pegawai tidak dijumpai", "error");
} }
} else { } else {
$swal.fire("Ralat", "Sila isi semua maklumat yang diperlukan", "error"); $swal.fire("Ralat", "Sila pilih pegawai", "error");
} }
}; };
@ -371,14 +565,14 @@ const confirmDelete = (pegawai) => {
}) })
.then((result) => { .then((result) => {
if (result.isConfirmed) { if (result.isConfirmed) {
deletePegawai(pegawai.id); deletePegawai(pegawai);
} }
}); });
}; };
const deletePegawai = (id) => { const deletePegawai = (pegawai) => {
const index = forensicOfficers.value.findIndex( const index = forensicOfficers.value.findIndex(
(officer) => officer.id === id (officer) => officer.tindakan === pegawai
); );
if (index !== -1) { if (index !== -1) {
forensicOfficers.value.splice(index, 1); forensicOfficers.value.splice(index, 1);
@ -390,6 +584,99 @@ const deletePegawai = (id) => {
const generateReport = (bahanBukti) => { const generateReport = (bahanBukti) => {
console.log("Generate Report for:", bahanBukti); console.log("Generate Report for:", bahanBukti);
navigateTo(`/kemaskini-daftar/laporan/${bahanBukti}`);
};
// Semak Modal Controls
const showSemakModal = ref(false);
const openSemakModal = () => {
showSemakModal.value = true;
};
const closeSemakModal = () => {
showSemakModal.value = false;
};
// User role (you might want to fetch this from your auth system)
const userRole = ref("Pegawai Kaunter"); // Change this to 'ketuaBahagian' to test the other form
// For ketua bahagian form
const kelulusanKetuaBahagian = ref(null);
const handleSemakSubmit = (formData) => {
console.log("Semak form submitted:", formData);
// Here you would typically send the data to your API
let successMessage = "";
if (userRole.value === "Pegawai Kaunter") {
successMessage = "Maklumat semakan telah disimpan";
} else if (userRole.value === "Ketua Bahagian") {
const decision =
formData.kelulusanKetuaBahagian === "Diterima" ? "diterima" : "ditolak";
successMessage = `Permohonan telah ${decision}. Ulasan: ${formData.ulasanKetuaBahagian}`;
}
$swal.fire("Berjaya", successMessage, "success");
closeSemakModal();
};
// Terima Modal Controls
const showTerimaModal = ref(false);
const openTerimaModal = () => {
showTerimaModal.value = true;
};
const closeTerimaModal = () => {
showTerimaModal.value = false;
};
const handleTerimaSubmit = (formData) => {
console.log("Terima form submitted:", formData);
// Here you would typically send the data to your API
let successMessage = "Permohonan telah diterima.";
// Check if any of the radio button answers are 'Tidak'
const hasNegativeResponse = [
"peralatanBaik",
"pegawaiBerkelayakan",
"kaedahDapatDilakukan",
"tugasanDiterima",
].some((field) => formData[field] === "Tidak");
if (hasNegativeResponse) {
successMessage += " Namun, terdapat beberapa perkara yang perlu diberi perhatian.";
}
successMessage += ` Ulasan: ${formData.ulasanPegawaiKaunter}`;
$swal.fire("Berjaya", successMessage, "success");
closeTerimaModal();
};
// Tolak Modal Controls
const showTolakModal = ref(false);
const openTolakModal = () => {
showTolakModal.value = true;
};
const closeTolakModal = () => {
showTolakModal.value = false;
};
const handleTolakSubmit = (formData) => {
console.log("Tolak form submitted:", formData);
// Here you would typically send the data to your API
let rejectionReason = formData.sebabPenolakan;
if (rejectionReason === "Lain-lain") {
rejectionReason += `: ${formData.lainLainSebab}`;
}
const successMessage = `Permohonan telah ditolak. Sebab: ${rejectionReason}`;
$swal.fire("Berjaya", successMessage, "success");
closeTolakModal();
}; };
</script> </script>

137
yarn.lock
View File

@ -969,6 +969,13 @@
dependencies: dependencies:
regenerator-runtime "^0.14.0" regenerator-runtime "^0.14.0"
"@babel/runtime@^7.12.5", "@babel/runtime@^7.14.0":
version "7.25.6"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.6.tgz#9afc3289f7184d8d7f98b099884c26317b9264d2"
integrity sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==
dependencies:
regenerator-runtime "^0.14.0"
"@babel/standalone@^7.22.9": "@babel/standalone@^7.22.9":
version "7.22.10" version "7.22.10"
resolved "https://registry.yarnpkg.com/@babel/standalone/-/standalone-7.22.10.tgz#0a39a85488d61d301751cc074ea77c44aacb9d07" resolved "https://registry.yarnpkg.com/@babel/standalone/-/standalone-7.22.10.tgz#0a39a85488d61d301751cc074ea77c44aacb9d07"
@ -2241,6 +2248,11 @@
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==
"@types/raf@^3.4.0":
version "3.4.3"
resolved "https://registry.yarnpkg.com/@types/raf/-/raf-3.4.3.tgz#85f1d1d17569b28b8db45e16e996407a56b0ab04"
integrity sha512-c4YAvMedbPZ5tEyxzQdMoOhhJ4RD3rngZIdwC2/qDN3d7JpEhB6fiBRKVY1lg5B7Wk+uPBjn5f39j1/2MY1oOw==
"@types/resize-observer-browser@^0.1.7": "@types/resize-observer-browser@^0.1.7":
version "0.1.7" version "0.1.7"
resolved "https://registry.yarnpkg.com/@types/resize-observer-browser/-/resize-observer-browser-0.1.7.tgz#294aaadf24ac6580b8fbd1fe3ab7b59fe85f9ef3" resolved "https://registry.yarnpkg.com/@types/resize-observer-browser/-/resize-observer-browser-0.1.7.tgz#294aaadf24ac6580b8fbd1fe3ab7b59fe85f9ef3"
@ -2958,6 +2970,11 @@ at-least-node@^1.0.0:
resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2"
integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==
atob@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
attr-accept@^2.2.2: attr-accept@^2.2.2:
version "2.2.2" version "2.2.2"
resolved "https://registry.yarnpkg.com/attr-accept/-/attr-accept-2.2.2.tgz#646613809660110749e92f2c10833b70968d929b" resolved "https://registry.yarnpkg.com/attr-accept/-/attr-accept-2.2.2.tgz#646613809660110749e92f2c10833b70968d929b"
@ -3019,6 +3036,11 @@ balanced-match@^1.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
base64-arraybuffer@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz#1c37589a7c4b0746e34bd1feb951da2df01c1bdc"
integrity sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==
base64-js@^1.3.1: base64-js@^1.3.1:
version "1.5.1" version "1.5.1"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
@ -3094,6 +3116,11 @@ browserslist@^4.0.0, browserslist@^4.21.4, browserslist@^4.21.5, browserslist@^4
node-releases "^2.0.13" node-releases "^2.0.13"
update-browserslist-db "^1.0.11" update-browserslist-db "^1.0.11"
btoa@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/btoa/-/btoa-1.2.1.tgz#01a9909f8b2c93f6bf680ba26131eb30f7fa3d73"
integrity sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==
buffer-crc32@^0.2.1, buffer-crc32@^0.2.13: buffer-crc32@^0.2.1, buffer-crc32@^0.2.13:
version "0.2.13" version "0.2.13"
resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
@ -3197,6 +3224,20 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001464, caniuse-lite@^1.0.30001517:
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001519.tgz#3e7b8b8a7077e78b0eb054d69e6edf5c7df35601" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001519.tgz#3e7b8b8a7077e78b0eb054d69e6edf5c7df35601"
integrity sha512-0QHgqR+Jv4bxHMp8kZ1Kn8CH55OikjKJ6JmKkZYP1F3D7w+lnFXF70nG5eNfsZS89jadi5Ywy5UCSKLAglIRkg== integrity sha512-0QHgqR+Jv4bxHMp8kZ1Kn8CH55OikjKJ6JmKkZYP1F3D7w+lnFXF70nG5eNfsZS89jadi5Ywy5UCSKLAglIRkg==
canvg@^3.0.6:
version "3.0.10"
resolved "https://registry.yarnpkg.com/canvg/-/canvg-3.0.10.tgz#8e52a2d088b6ffa23ac78970b2a9eebfae0ef4b3"
integrity sha512-qwR2FRNO9NlzTeKIPIKpnTY6fqwuYSequ8Ru8c0YkYU7U0oW+hLUvWadLvAu1Rl72OMNiFhoLu4f8eUjQ7l/+Q==
dependencies:
"@babel/runtime" "^7.12.5"
"@types/raf" "^3.4.0"
core-js "^3.8.3"
raf "^3.4.1"
regenerator-runtime "^0.13.7"
rgbcolor "^1.0.1"
stackblur-canvas "^2.0.0"
svg-pathdata "^6.0.3"
chalk@^2.4.2: chalk@^2.4.2:
version "2.4.2" version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
@ -3456,6 +3497,11 @@ core-js-pure@^3.30.2:
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.32.0.tgz#5d79f85da7a4373e9a06494ccbef995a4c639f8b" resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.32.0.tgz#5d79f85da7a4373e9a06494ccbef995a4c639f8b"
integrity sha512-qsev1H+dTNYpDUEURRuOXMvpdtAnNEvQWS/FMJ2Vb5AY8ZP4rAPQldkE27joykZPJTe0+IVgHZYh1P5Xu1/i1g== integrity sha512-qsev1H+dTNYpDUEURRuOXMvpdtAnNEvQWS/FMJ2Vb5AY8ZP4rAPQldkE27joykZPJTe0+IVgHZYh1P5Xu1/i1g==
core-js@^3.6.0, core-js@^3.8.3:
version "3.38.1"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.38.1.tgz#aa375b79a286a670388a1a363363d53677c0383e"
integrity sha512-OP35aUorbU3Zvlx7pjsFdu1rGNnD4pgw/CWoYzRY3t2EzoVT7shKHY1dlAy3f41cGIO7ZDPQimhGFTlEYkG/Hw==
core-util-is@~1.0.0: core-util-is@~1.0.0:
version "1.0.3" version "1.0.3"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
@ -3533,6 +3579,13 @@ css-declaration-sorter@^6.3.1:
resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz#28beac7c20bad7f1775be3a7129d7eae409a3a71" resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz#28beac7c20bad7f1775be3a7129d7eae409a3a71"
integrity sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g== integrity sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==
css-line-break@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/css-line-break/-/css-line-break-2.1.0.tgz#bfef660dfa6f5397ea54116bb3cb4873edbc4fa0"
integrity sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==
dependencies:
utrie "^1.0.2"
css-loader@^5.0.0: css-loader@^5.0.0:
version "5.2.7" version "5.2.7"
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.2.7.tgz#9b9f111edf6fb2be5dc62525644cbc9c232064ae" resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.2.7.tgz#9b9f111edf6fb2be5dc62525644cbc9c232064ae"
@ -3946,6 +3999,11 @@ domhandler@^5.0.2, domhandler@^5.0.3:
dependencies: dependencies:
domelementtype "^2.3.0" domelementtype "^2.3.0"
dompurify@^2.2.0:
version "2.5.6"
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.5.6.tgz#8402b501611eaa7fb3786072297fcbe2787f8592"
integrity sha512-zUTaUBO8pY4+iJMPE1B9XlO2tXVYIcEA4SNGtvDELzTSCQO7RzH+j7S180BmhmJId78lqGU2z19vgVx2Sxs/PQ==
domutils@^2.8.0: domutils@^2.8.0:
version "2.8.0" version "2.8.0"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135"
@ -4670,6 +4728,11 @@ fetch-blob@^3.1.2, fetch-blob@^3.1.4:
node-domexception "^1.0.0" node-domexception "^1.0.0"
web-streams-polyfill "^3.0.3" web-streams-polyfill "^3.0.3"
fflate@^0.4.8:
version "0.4.8"
resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.4.8.tgz#f90b82aefbd8ac174213abb338bd7ef848f0f5ae"
integrity sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==
file-entry-cache@^6.0.1: file-entry-cache@^6.0.1:
version "6.0.1" version "6.0.1"
resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027"
@ -5158,6 +5221,14 @@ html-tags@^3.3.1:
resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.3.1.tgz#a04026a18c882e4bba8a01a3d39cfe465d40b5ce" resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.3.1.tgz#a04026a18c882e4bba8a01a3d39cfe465d40b5ce"
integrity sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ== integrity sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==
html2canvas@^1.0.0-rc.5:
version "1.4.1"
resolved "https://registry.yarnpkg.com/html2canvas/-/html2canvas-1.4.1.tgz#7cef1888311b5011d507794a066041b14669a543"
integrity sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==
dependencies:
css-line-break "^2.1.0"
text-segmentation "^1.0.3"
http-assert@^1.3.0: http-assert@^1.3.0:
version "1.5.0" version "1.5.0"
resolved "https://registry.yarnpkg.com/http-assert/-/http-assert-1.5.0.tgz#c389ccd87ac16ed2dfa6246fd73b926aa00e6b8f" resolved "https://registry.yarnpkg.com/http-assert/-/http-assert-1.5.0.tgz#c389ccd87ac16ed2dfa6246fd73b926aa00e6b8f"
@ -5705,6 +5776,21 @@ jsonwebtoken@^8.5.1:
ms "^2.1.1" ms "^2.1.1"
semver "^5.6.0" semver "^5.6.0"
jspdf@^2.5.1:
version "2.5.1"
resolved "https://registry.yarnpkg.com/jspdf/-/jspdf-2.5.1.tgz#00c85250abf5447a05f3b32ab9935ab4a56592cc"
integrity sha512-hXObxz7ZqoyhxET78+XR34Xu2qFGrJJ2I2bE5w4SM8eFaFEkW2xcGRVUss360fYelwRSid/jT078kbNvmoW0QA==
dependencies:
"@babel/runtime" "^7.14.0"
atob "^2.1.2"
btoa "^1.2.1"
fflate "^0.4.8"
optionalDependencies:
canvg "^3.0.6"
core-js "^3.6.0"
dompurify "^2.2.0"
html2canvas "^1.0.0-rc.5"
"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.2: "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.2:
version "3.3.5" version "3.3.5"
resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz#4766bd05a8e2a11af222becd19e15575e52a853a" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz#4766bd05a8e2a11af222becd19e15575e52a853a"
@ -6959,6 +7045,11 @@ perfect-scrollbar@^1.5.5:
resolved "https://registry.yarnpkg.com/perfect-scrollbar/-/perfect-scrollbar-1.5.5.tgz#41a211a2fb52a7191eff301432134ea47052b27f" resolved "https://registry.yarnpkg.com/perfect-scrollbar/-/perfect-scrollbar-1.5.5.tgz#41a211a2fb52a7191eff301432134ea47052b27f"
integrity sha512-dzalfutyP3e/FOpdlhVryN4AJ5XDVauVWxybSkLZmakFE2sS3y3pc4JnSprw8tGmHvkaG5Edr5T7LBTZ+WWU2g== integrity sha512-dzalfutyP3e/FOpdlhVryN4AJ5XDVauVWxybSkLZmakFE2sS3y3pc4JnSprw8tGmHvkaG5Edr5T7LBTZ+WWU2g==
performance-now@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==
picocolors@^0.2.1: picocolors@^0.2.1:
version "0.2.1" version "0.2.1"
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f"
@ -7698,6 +7789,13 @@ radix3@^1.0.1:
resolved "https://registry.yarnpkg.com/radix3/-/radix3-1.0.1.tgz#de0ac16234f8a63288645854a54fc26e45a4a8eb" resolved "https://registry.yarnpkg.com/radix3/-/radix3-1.0.1.tgz#de0ac16234f8a63288645854a54fc26e45a4a8eb"
integrity sha512-y+AcwZ3HcUIGc9zGsNVf5+BY/LxL+z+4h4J3/pp8jxSmy1STaCocPS3qrj4tA5ehUSzqtqK+0Aygvz/r/8vy4g== integrity sha512-y+AcwZ3HcUIGc9zGsNVf5+BY/LxL+z+4h4J3/pp8jxSmy1STaCocPS3qrj4tA5ehUSzqtqK+0Aygvz/r/8vy4g==
raf@^3.4.1:
version "3.4.1"
resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39"
integrity sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==
dependencies:
performance-now "^2.1.0"
randombytes@^2.1.0: randombytes@^2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
@ -7791,6 +7889,11 @@ regenerate@^1.4.2:
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a"
integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==
regenerator-runtime@^0.13.7:
version "0.13.11"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9"
integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==
regenerator-runtime@^0.14.0: regenerator-runtime@^0.14.0:
version "0.14.0" version "0.14.0"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45"
@ -7906,6 +8009,11 @@ reusify@^1.0.4:
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
rgbcolor@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/rgbcolor/-/rgbcolor-1.0.1.tgz#d6505ecdb304a6595da26fa4b43307306775945d"
integrity sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw==
rimraf@^3.0.2: rimraf@^3.0.2:
version "3.0.2" version "3.0.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
@ -8194,6 +8302,11 @@ stable@^0.1.8:
resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf"
integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==
stackblur-canvas@^2.0.0:
version "2.7.0"
resolved "https://registry.yarnpkg.com/stackblur-canvas/-/stackblur-canvas-2.7.0.tgz#af931277d0b5096df55e1f91c530043e066989b6"
integrity sha512-yf7OENo23AGJhBriGx0QivY5JP6Y1HbrrDI6WLt6C5auYZXlQrheoY8hD4ibekFKz1HOfE48Ww8kMWMnJD/zcQ==
standard-as-callback@^2.1.0: standard-as-callback@^2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/standard-as-callback/-/standard-as-callback-2.1.0.tgz#8953fc05359868a77b5b9739a665c5977bb7df45" resolved "https://registry.yarnpkg.com/standard-as-callback/-/standard-as-callback-2.1.0.tgz#8953fc05359868a77b5b9739a665c5977bb7df45"
@ -8394,6 +8507,11 @@ supports-preserve-symlinks-flag@^1.0.0:
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
svg-pathdata@^6.0.3:
version "6.0.3"
resolved "https://registry.yarnpkg.com/svg-pathdata/-/svg-pathdata-6.0.3.tgz#80b0e0283b652ccbafb69ad4f8f73e8d3fbf2cac"
integrity sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw==
svg-tags@^1.0.0: svg-tags@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764" resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764"
@ -8592,6 +8710,13 @@ terser@^5.0.0, terser@^5.17.4:
commander "^2.20.0" commander "^2.20.0"
source-map-support "~0.5.20" source-map-support "~0.5.20"
text-segmentation@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/text-segmentation/-/text-segmentation-1.0.3.tgz#52a388159efffe746b24a63ba311b6ac9f2d7943"
integrity sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==
dependencies:
utrie "^1.0.2"
text-table@^0.2.0: text-table@^0.2.0:
version "0.2.0" version "0.2.0"
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
@ -8960,6 +9085,18 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1:
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
utrie@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/utrie/-/utrie-1.0.2.tgz#d42fe44de9bc0119c25de7f564a6ed1b2c87a645"
integrity sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==
dependencies:
base64-arraybuffer "^1.0.2"
uuid@^10.0.0:
version "10.0.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-10.0.0.tgz#5a95aa454e6e002725c79055fd42aaba30ca6294"
integrity sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==
v-calendar@^3.0.3: v-calendar@^3.0.3:
version "3.0.3" version "3.0.3"
resolved "https://registry.yarnpkg.com/v-calendar/-/v-calendar-3.0.3.tgz#f04c625d3c3352d5685099bb4ad3e24d0530a7d4" resolved "https://registry.yarnpkg.com/v-calendar/-/v-calendar-3.0.3.tgz#f04c625d3c3352d5685099bb4ad3e24d0530a7d4"