Fix api and menu name

This commit is contained in:
Md Afiq Iskandar 2024-11-20 05:24:18 +08:00
parent a37bba93fe
commit 8f4c7ad0b6
29 changed files with 119 additions and 1825 deletions

View File

@ -1,82 +1,84 @@
export default [
{
header: "Utama",
description: "",
child: [
"header": "Utama",
"description": "",
"child": [
{
title: "Dashboard",
path: "/dashboard",
icon: "ic:outline-dashboard",
child: [],
meta: {},
},
"title": "Dashboard",
"path": "/dashboard",
"icon": "ic:outline-dashboard",
"child": [],
"meta": {}
}
],
meta: {},
"meta": {}
},
{
header: "Pentadbiran",
description: "Urus aplikasi anda",
child: [
"header": "Pentadbiran",
"description": "Urus aplikasi anda",
"child": [
{
title: "Konfigurasi",
icon: "ic:outline-settings",
child: [
"title": "Konfigurasi",
"icon": "ic:outline-settings",
"child": [
{
title: "Persekitaran",
path: "/devtool/config/environment",
},
],
"title": "Persekitaran",
"path": "/devtool/config/environment"
}
]
},
{
title: "Penyunting Menu",
icon: "ci:menu-alt-03",
path: "/devtool/menu-editor",
child: [],
"title": "Penyunting Menu",
"icon": "ci:menu-alt-03",
"path": "/devtool/menu-editor",
"child": []
},
{
title: "Urus Pengguna",
path: "/devtool/user-management",
icon: "ph:user-circle-gear",
child: [
"title": "Urus Pengguna",
"path": "/devtool/user-management",
"icon": "ph:user-circle-gear",
"child": [
{
title: "Senarai Pengguna",
path: "/devtool/user-management/user",
icon: "",
child: [],
"title": "Senarai Pengguna",
"path": "/devtool/user-management/user",
"icon": "",
"child": []
},
{
title: "Senarai Peranan",
path: "/devtool/user-management/role",
icon: "",
child: [],
},
],
"title": "Senarai Peranan",
"path": "/devtool/user-management/role",
"icon": "",
"child": []
}
]
},
{
title: "Kandungan",
icon: "mdi:pencil-ruler",
child: [
"title": "Kandungan",
"icon": "mdi:pencil-ruler",
"child": [
{
title: "Penyunting",
path: "/devtool/content-editor",
"title": "Penyunting",
"path": "/devtool/content-editor"
},
{
title: "Templat",
path: "/devtool/content-editor/template",
},
],
"title": "Templat",
"path": "/devtool/content-editor/template"
}
]
},
{
title: "Penyunting API",
path: "/devtool/api-editor",
icon: "material-symbols:api-rounded",
child: [],
},
"title": "Penyunting API",
"path": "/devtool/api-editor",
"icon": "material-symbols:api-rounded",
"child": []
}
],
meta: {
auth: {
role: ["Developer"],
},
},
},
];
"meta": {
"auth": {
"role": [
"Developer"
]
}
}
}
];

View File

@ -324,4 +324,4 @@ const deleteAPI = async (apiURL) => {
<template #footer></template>
</rs-modal>
</div>
</template>
</template>

View File

@ -126,6 +126,16 @@ const openModalEdit = (menu) => {
};
const saveEditMenu = async () => {
// Check title regex to ensure no weird symbol only letters, numbers, spaces, underscores and dashes
if (!/^[a-zA-Z0-9\s_-]+$/.test(showModalEditForm.value.title)) {
nuxtApp.$swal.fire({
title: "Error",
text: "Title contains invalid characters. Only letters, numbers, spaces, underscores and dashes are allowed.",
icon: "error",
});
return;
}
// Clean the name and title ensure not spacing at the beginning or end
showModalEditForm.value.title = showModalEditForm.value.title.trim();
showModalEditForm.value.name = showModalEditForm.value.name.trim();
@ -170,6 +180,16 @@ const openModalAdd = () => {
};
const saveAddMenu = async () => {
// Check title regex to ensure no weird symbol only letters, numbers, spaces, underscores and dashes
if (!/^[a-zA-Z0-9\s_-]+$/.test(showModalAddForm.value.title)) {
nuxtApp.$swal.fire({
title: "Error",
text: "Title contains invalid characters. Only letters, numbers, spaces, underscores and dashes are allowed.",
icon: "error",
});
return;
}
// Clean the name and title ensure not spacing at the beginning or end
showModalAddForm.value.title = showModalAddForm.value.title.trim();
showModalAddForm.value.name = showModalAddForm.value.name.trim();
@ -642,11 +662,9 @@ watch(
<FormKit
type="text"
label="Title"
:validation="[['required'], ['matches', '/^[a-zA-Z0-9]+$/']]"
:validation="[['required']]"
:validation-messages="{
required: 'Title is required',
matches:
'Title contains invalid characters. Only letters and numbers are allowed.',
}"
v-model="showModalEditForm.title"
/>
@ -695,11 +713,9 @@ watch(
<FormKit
type="text"
label="Title"
:validation="[['required'], ['matches', '/^[a-zA-Z0-9]+$/']]"
:validation="[['required']]"
:validation-messages="{
required: 'Title is required',
matches:
'Title contains invalid characters. Only letters and numbers are allowed.',
}"
v-model="showModalAddForm.title"
/>
@ -742,4 +758,4 @@ watch(
<template #footer> </template>
</rs-modal>
</div>
</template>
</template>

View File

@ -43,6 +43,8 @@ export default defineEventHandler(async (event) => {
"textarea",
"submit",
"button",
"mask",
"form",
];
// Find all FormKit components
@ -259,6 +261,28 @@ export default defineEventHandler(async (event) => {
// Validate template structure
const validateTemplateStructure = (code) => {
// Add new validation for script tags inside template
const templateContent1 = code.match(
/<template>([\s\S]*)<\/template>/
)?.[1];
if (templateContent1) {
const scriptInTemplate = templateContent1.match(/<script\b[^>]*>/i);
if (scriptInTemplate) {
const lineNumber = templateContent1
.slice(0, scriptInTemplate.index)
.split("\n").length;
const column =
scriptInTemplate.index -
templateContent1.lastIndexOf("\n", scriptInTemplate.index);
throw {
message: "Script tags are not allowed inside template section",
line: lineNumber,
column: column,
};
}
}
// Check for root level template and script tags
const rootTemplateCount = (
code.match(/^[\s\S]*<template>[\s\S]*<\/template>/g) || []
@ -274,28 +298,28 @@ export default defineEventHandler(async (event) => {
}
// Extract template content for further validation
const templateContent = code.match(
const templateContent2 = code.match(
/<template>([\s\S]*)<\/template>/
)?.[1];
if (templateContent) {
if (templateContent2) {
const tagStack = [];
const tagRegex = /<\/?([a-zA-Z][a-zA-Z0-9:-]*)\s*([^>]*?)(\/?)>/g;
let match;
let lineNumber = 1;
let lastIndex = 0;
while ((match = tagRegex.exec(templateContent)) !== null) {
while ((match = tagRegex.exec(templateContent2)) !== null) {
const [fullTag, tagName, attributes, selfClosing] = match;
// Calculate line number
lineNumber += (
templateContent.slice(lastIndex, match.index).match(/\n/g) || []
templateContent2.slice(lastIndex, match.index).match(/\n/g) || []
).length;
lastIndex = match.index;
// Skip comments
if (templateContent.slice(match.index).startsWith("<!--")) {
const commentEnd = templateContent.indexOf("-->", match.index);
if (templateContent2.slice(match.index).startsWith("<!--")) {
const commentEnd = templateContent2.indexOf("-->", match.index);
if (commentEnd !== -1) {
tagRegex.lastIndex = commentEnd + 3;
continue;
@ -307,7 +331,7 @@ export default defineEventHandler(async (event) => {
message: `Malformed tag found: ${fullTag}`,
line: lineNumber,
column:
match.index - templateContent.lastIndexOf("\n", match.index),
match.index - templateContent2.lastIndexOf("\n", match.index),
};
}
@ -318,7 +342,7 @@ export default defineEventHandler(async (event) => {
name: tagName,
line: lineNumber,
column:
match.index - templateContent.lastIndexOf("\n", match.index),
match.index - templateContent2.lastIndexOf("\n", match.index),
});
} else {
if (tagStack.length === 0) {
@ -326,7 +350,7 @@ export default defineEventHandler(async (event) => {
message: `Unexpected closing tag </${tagName}> found without matching opening tag`,
line: lineNumber,
column:
match.index - templateContent.lastIndexOf("\n", match.index),
match.index - templateContent2.lastIndexOf("\n", match.index),
};
}
@ -336,7 +360,7 @@ export default defineEventHandler(async (event) => {
message: `Mismatched tags: expected closing tag for "${lastTag.name}" but found "${tagName}"`,
line: lineNumber,
column:
match.index - templateContent.lastIndexOf("\n", match.index),
match.index - templateContent2.lastIndexOf("\n", match.index),
};
}
tagStack.pop();

View File

@ -1,91 +0,0 @@
export default defineEventHandler(async (event) => {
// Get the `noSiri` from the request parameters
const { noSiri } = event.context.params;
try {
// Fetch the permohonan by `no_siri` from the Prisma database
const permohonan = await prisma.permohonan.findUnique({
where: {
no_siri: noSiri, // Unique identifier for permohonan
},
include: {
// Include related fields if necessary
pemohon: {
select: {
user: {
select: {
userFullName: true,
},
},
pangkat_pemohon: true,
no_pegawai_pemohon: true,
},
},
penghantar: true,
report: {
select: {
jenis_barang: true,
lookup_report_jenis_barangTolookup: {
select: {
lookupID: true,
lookupValue: true,
},
},
tanda_barang: true,
keadaan_barang: true,
kuantiti_barang: true,
},
},
},
});
// If no permohonan found, return a 404 response
if (!permohonan) {
return {
statusCode: 404,
message: `Permohonan with noSiri ${noSiri} not found`,
};
}
// Map and return the data as expected by the frontend
return {
statusCode: 200,
data: {
namaPemohon: permohonan.pemohon?.user?.userFullName || "", // Get namaPemohon from userID
pangkatPemohon: permohonan.pemohon?.pangkat_pemohon || "",
noPegawaiPemohon: permohonan.pemohon?.no_pegawai_pemohon || "",
namaPenghantar: permohonan.penghantar?.nama_penghantar || "",
pangkatPenghantar: permohonan.penghantar?.pangkat_penghantar || "",
noPegawaiPenghantar: permohonan.penghantar?.no_pegawai_penghantar || "",
ringkasanKenyataanKes: permohonan.ringkasan_kenyataan_kes || "",
bilangan: permohonan.bilangan || 0,
barangList: permohonan.report.map((barang) => ({
jenisBarangDetail:
barang.lookup_report_jenis_barangTolookup.lookupID || "",
jenisBarangDetailLabel:
barang.lookup_report_jenis_barangTolookup.lookupValue || "",
tandaBarang: barang.tanda_barang || "",
keadaanBarang: barang.keadaan_barang || "",
kuantitiBarang: barang.kuantiti_barang || 0,
})),
noKertasSiasatan: permohonan.no_kertas_siasatan || "",
noLaporanPolis: permohonan.no_laporan_polis || "",
tarikhTemujanji:
permohonan.tarikh_temujanji?.toISOString().split("T")[0] || "",
slotMasa: permohonan.slot_masa
? new Date(permohonan.slot_masa).toLocaleTimeString("en-US", {
hour: "2-digit",
minute: "2-digit",
hour12: false,
})
: "",
isPenghantarSameAsPemohon: !permohonan.penghantar,
},
};
} catch (error) {
console.error("Error fetching permohonan:", error);
return {
statusCode: 500,
message: "An error occurred while fetching the permohonan data.",
};
}
});

View File

@ -1,54 +0,0 @@
export default defineEventHandler(async (event) => {
const { noSiri } = event.context.params; // Extract the noSiri from the URL
const body = await readBody(event); // Read the request body
const { ringkasanKenyataanKes, noKertasSiasatan, noLaporanPolis } = body;
// 1. Validate the input fields (all three fields must be provided)
if (!ringkasanKenyataanKes || !noKertasSiasatan || !noLaporanPolis) {
return {
statusCode: 400,
message:
"Setiap medan mandatori yang bertanda * telah diisi. (Ralat CMN-E001)",
};
}
try {
// 2. Check if the permohonan exists by its `no_siri`
const existingPermohonan = await prisma.permohonan.findUnique({
where: { no_siri: noSiri },
});
// If no `permohonan` is found, return a 404 error
if (!existingPermohonan) {
return {
statusCode: 404,
message: `Permohonan with noSiri ${noSiri} not found.`,
};
}
// 3. Proceed to update only the allowed fields (ringkasanKenyataanKes, noKertasSiasatan, noLaporanPolis)
const updatedPermohonan = await prisma.permohonan.update({
where: { no_siri: noSiri },
data: {
ringkasan_kenyataan_kes: ringkasanKenyataanKes,
no_kertas_siasatan: noKertasSiasatan,
no_laporan_polis: noLaporanPolis,
modified_at: new Date(), // Update the modified_at timestamp
},
});
// 4. Return success response
return {
statusCode: 200,
message: "Permohonan telah berjaya dikemaskini.",
data: updatedPermohonan,
};
} catch (error) {
console.error("Error updating permohonan:", error);
return {
statusCode: 500,
message: "Gagal mengemaskini permohonan. Sila cuba lagi.",
};
}
});

View File

@ -1,103 +0,0 @@
// Path: /api/report/[reportID].get.js
export default defineEventHandler(async (event) => {
const { reportID } = event.context.params;
try {
const report = await prisma.report.findUnique({
where: { reportID: parseInt(reportID) },
include: {
permohonan: {
include: {
penghantar: true,
pemohon: {
include: {
user: true,
},
},
},
},
lookup_report_jenis_barangTolookup: true,
lookup_report_dapatanTolookup: {
select: {
lookupID: true,
lookupValue: true,
},
},
report_doc_support: {
include: {
document: true,
},
},
},
});
console.log(report);
if (!report) {
return { statusCode: 404, message: "Report not found" };
}
// Format the data for the frontend
const reportData = {
kesId: report.permohonan.no_siri,
tagNo: report.tanda_barang,
jenisBrg: report.lookup_report_jenis_barangTolookup.lookupValue,
jenisPemeriksaan: "Forensik", // Assuming it's static for now
pegawai: {
PENYIASAT: {
nama: report.permohonan.pemohon?.user?.userFullName || "",
pangkat: report.permohonan.pemohon?.pangkat_pemohon || "",
noPegawai: report.permohonan.pemohon?.no_pegawai_pemohon || "",
},
PENGHANTAR: {
nama: report.permohonan.penghantar_sama_dengan_pemohon
? report.permohonan.pemohon?.user?.userFullName || ""
: report.permohonan.penghantar?.nama_penghantar || "",
pangkat: report.permohonan.penghantar_sama_dengan_pemohon
? report.permohonan.pemohon?.pangkat_pemohon || ""
: report.permohonan.penghantar?.pangkat_penghantar || "",
noPegawai: report.permohonan.penghantar_sama_dengan_pemohon
? report.permohonan.pemohon?.no_pegawai_pemohon || ""
: report.permohonan.penghantar?.no_pegawai_penghantar || "",
},
PEMERIKSA: {
nama: report.permohonan.pemerikasa?.user?.userFullName || "",
pangkat: report.permohonan.pemerikasa?.pangkat_pemerikasa || "",
noPegawai: report.permohonan.pemerikasa?.no_pegawai_pemerikasa || "",
},
PENERIMA: {
nama: report.permohonan.penerima?.user?.userFullName || "",
pangkat: report.permohonan.penerima?.pangkat_penerima || "",
noPegawai: report.permohonan.penerima?.no_pegawai_penerima || "",
},
// Fill in other roles accordingly
},
peralatan: report.peralatan,
langkah2: report.langkah_langkah,
dapatan: {
value: report.lookup_report_dapatanTolookup?.lookupID,
label: report.lookup_report_dapatanTolookup?.lookupValue,
},
documentTambahan: report.report_doc_support
? [
{
nama: report.report_doc_support[0].document.documentName,
file: report.report_doc_support[0].document.documentURL,
},
]
: [
{
nama: "",
file: "",
}
],
};
return { statusCode: 200, data: reportData };
} catch (error) {
console.log(error);
return { statusCode: 500, message: error.message };
}
});

View File

@ -1,63 +0,0 @@
// Path: /api/report/[reportID].post.js
export default defineEventHandler(async (event) => {
const { reportID } = event.context.params;
const body = await readBody(event);
const {
peralatan,
langkah2,
dapatan, // This should correspond to lookupID in the `lookup` table
documentTambahan, // Array of documents
} = body;
console.log(body);
try {
// Update the report in the database
const updatedReport = await prisma.report.update({
where: { reportID: parseInt(reportID) },
data: {
peralatan,
langkah_langkah: langkah2,
dapatan: parseInt(dapatan), // Assuming this is a lookupID from the `lookup` table
},
});
// Handle document uploads (if necessary)
if (documentTambahan && documentTambahan.length > 0) {
// Create documents first
const createdDocuments = await prisma.document.createMany({
data: documentTambahan.map((doc) => ({
documentName: doc.nama,
})),
skipDuplicates: true,
});
// Get the IDs of the newly created documents
const newDocumentIds = await prisma.document.findMany({
where: {
documentName: {
in: documentTambahan.map((doc) => doc.nama),
},
},
select: {
documentID: true,
documentName: true,
},
});
// Update report_doc_support table
await prisma.report_doc_support.createMany({
data: newDocumentIds.map((doc) => ({
reportID: updatedReport.reportID,
documentID: doc.documentID,
})),
});
}
return { statusCode: 200, message: "Report updated successfully" };
} catch (error) {
console.log(error);
return { statusCode: 500, message: "Failed to update report" };
}
});

View File

@ -1,57 +0,0 @@
// path: /api/lookup?type=jenis_barang
export default defineEventHandler(async (event) => {
const { type } = getQuery(event); // Get lookup type from query params, e.g., jenis_barang, dapatan
if (!type) {
return {
statusCode: 400,
message: "Lookup type is required",
};
}
try {
const lookups = await prisma.lookup.findMany({
where: {
lookupTitle: type,
lookupStatus: "ACTIVE",
},
select: {
lookupID: true,
lookupTitle: true,
lookupValue: true,
},
});
if (!lookups) {
return {
statusCode: 404,
message: "Lookup data not found",
};
}
// Convert snake_case to Title Case: e.g., jenis_barang_siber -> Jenis Barang Siber
const defaultTitle = type
.split("_")
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
.join(" ");
// Transform the lookups data to the required format
const transformedLookups = [
{ label: `Sila Pilih ${defaultTitle}`, value: null }, // Add an empty option as the first item
...lookups.map((lookup) => ({
label: lookup.lookupValue,
value: lookup.lookupID,
})),
];
return {
statusCode: 200,
data: transformedLookups,
};
} catch (error) {
return {
statusCode: 500,
message: "Error fetching lookup data",
error: error.message,
};
}
});

View File

@ -1,56 +0,0 @@
export default defineEventHandler(async (event) => {
const { noSiri } = event.context.params; // Get the noSiri from the request parameters
try {
// Find the permohonan by its `no_siri`
const permohonan = await prisma.permohonan.findUnique({
where: { no_siri: noSiri },
});
if (!permohonan) {
return {
statusCode: 404,
message: `Permohonan with noSiri ${noSiri} not found.`,
};
}
// Delete pemohonan
await prisma.pemohon.delete({
where: {
id: permohonan.pemohonID,
},
});
// Delete penghantar
await prisma.penghantar.delete({
where: {
id: permohonan.penghantarID,
},
});
// Delete report
await prisma.report.deleteMany({
where: {
permohonanID: permohonan.id,
},
});
// Delete permohonan
await prisma.permohonan.delete({
where: {
id: permohonan.id,
},
});
return {
statusCode: 200,
message: "Permohonan and related data successfully deleted.",
};
} catch (error) {
console.error("Error deleting permohonan:", error);
return {
statusCode: 500,
message: "Failed to delete permohonan. Please try again.",
};
}
});

View File

@ -1,93 +0,0 @@
export default defineEventHandler(async (event) => {
// Get the `noSiri` from the request parameters
const { noSiri } = event.context.params;
try {
// Fetch the permohonan by `no_siri` from the Prisma database
const permohonan = await prisma.permohonan.findUnique({
where: {
no_siri: noSiri, // Unique identifier for permohonan
},
include: {
// Include related fields if necessary
pemohon: {
select: {
user: {
select: {
userFullName: true,
},
},
pangkat_pemohon: true,
no_pegawai_pemohon: true,
},
},
penghantar: true,
report: {
select: {
jenis_barang: true,
lookup_report_jenis_barangTolookup: {
select: {
lookupID: true,
lookupValue: true,
},
},
tanda_barang: true,
keadaan_barang: true,
kuantiti_barang: true,
},
},
},
});
// If no permohonan found, return a 404 response
if (!permohonan) {
return {
statusCode: 404,
message: `Permohonan with noSiri ${noSiri} not found`,
};
}
// Map and return the data as expected by the frontend
return {
statusCode: 200,
data: {
namaPemohon: permohonan.pemohon?.user?.userFullName || "", // Get namaPemohon from userID
pangkatPemohon: permohonan.pemohon?.pangkat_pemohon || "",
noPegawaiPemohon: permohonan.pemohon?.no_pegawai_pemohon || "",
namaPenghantar: permohonan.penghantar?.nama_penghantar || "",
pangkatPenghantar: permohonan.penghantar?.pangkat_penghantar || "",
noPegawaiPenghantar: permohonan.penghantar?.no_pegawai_penghantar || "",
ringkasanKenyataanKes: permohonan.ringkasan_kenyataan_kes || "",
bilangan: permohonan.bilangan || 0,
barangList: permohonan.report.map((barang) => ({
jenisBarangDetail:
barang.lookup_report_jenis_barangTolookup.lookupID || "",
jenisBarangDetailLabel:
barang.lookup_report_jenis_barangTolookup.lookupValue || "",
tandaBarang: barang.tanda_barang || "",
keadaanBarang: barang.keadaan_barang || "",
kuantitiBarang: barang.kuantiti_barang || 0,
})),
noKertasSiasatan: permohonan.no_kertas_siasatan || "",
noLaporanPolis: permohonan.no_laporan_polis || "",
tarikhTemujanji:
permohonan.tarikh_temujanji?.toISOString().split("T")[0] || "",
slotMasa: permohonan.slot_masa
? new Date(permohonan.slot_masa).toLocaleTimeString("en-US", {
hour: "2-digit",
minute: "2-digit",
hour12: false,
})
: "",
isPenghantarSameAsPemohon: !permohonan.penghantar,
},
};
} catch (error) {
// Handle any unexpected errors
console.error("Error fetching permohonan:", error);
return {
statusCode: 500,
message: "Something went wrong while fetching permohonan data",
};
}
});

View File

@ -1,202 +0,0 @@
export default defineEventHandler(async (event) => {
const body = await readBody(event);
const { userID } = event.context.user;
const { noSiri } = event.context.params; // Permohonan identifier from URL
const {
namaPemohon,
pangkatPemohon,
noPegawaiPemohon,
namaPenghantar,
pangkatPenghantar,
noPegawaiPenghantar,
ringkasanKenyataanKes,
isPenghantarSameAsPemohon,
bilangan,
barangList,
noKertasSiasatan,
noLaporanPolis,
tarikhTemujanji,
slotMasa,
isDraft,
} = body;
// 1. Mandatory fields validation
const mandatoryFields = [
namaPemohon,
pangkatPemohon,
noPegawaiPemohon,
ringkasanKenyataanKes,
bilangan,
noKertasSiasatan,
noLaporanPolis,
tarikhTemujanji,
slotMasa,
...barangList,
];
if (mandatoryFields.some((field) => !field || field === "")) {
return {
statusCode: 400,
message:
"Setiap medan mandatori yang bertanda * telah diisi. (Ralat CMN-E001)",
};
}
// 2. Validate date for the appointment
const appointmentDate = new Date(tarikhTemujanji);
const currentDate = new Date();
if (appointmentDate <= currentDate) {
return {
statusCode: 400,
message:
"Perlu memastikan tarikh janji temu yang dimasukkan adalah tarikh selepas tarikh semasa. (Ralat CMN-E002)",
};
}
// 3. Check if the session is expired
const sessionExpired = false; // Implement session logic here
if (sessionExpired) {
return {
statusCode: 401,
message:
"Sesi aktif pengguna berada dalam sistem telah tamat. (Ralat CMN-E005)",
};
}
// 4. Check for invalid symbols in text fields
const hasInvalidSymbols = (text) => /[^a-zA-Z0-9\s]/.test(text); // Allow alphanumeric and spaces
const fieldsToCheck = [
namaPemohon,
pangkatPemohon,
noPegawaiPemohon,
...barangList.map((barang) => barang.tandaBarang),
];
if (fieldsToCheck.some((field) => hasInvalidSymbols(field))) {
return {
statusCode: 400,
message:
"Perlu memastikan tiada penggunaan simbol dalam medan yang ditetapkan. (Ralat CMN-E011)",
};
}
// 5. Update the permohonan in the database
let permohonanStatus = isDraft ? "Permohonan Draf" : "Permohonan Dihantar";
try {
// Update the existing `permohonan` record
const updatedPermohonan = await prisma.permohonan.update({
where: {
no_siri: noSiri,
},
data: {
status_permohonan: permohonanStatus,
pemohon: {
update: {
userID: userID,
pangkat_pemohon: pangkatPemohon,
no_pegawai_pemohon: noPegawaiPemohon,
},
},
penghantar: isPenghantarSameAsPemohon
? null
: {
update: {
nama_penghantar: namaPenghantar,
pangkat_penghantar: pangkatPenghantar,
no_pegawai_penghantar: noPegawaiPenghantar,
},
},
ringkasan_kenyataan_kes: ringkasanKenyataanKes,
bilangan: parseInt(bilangan),
penghantar_sama_dengan_pemohon: isPenghantarSameAsPemohon ? 1 : 0,
no_kertas_siasatan: noKertasSiasatan,
no_laporan_polis: noLaporanPolis,
tarikh_temujanji: new Date(tarikhTemujanji),
slot_masa: new Date(`1970-01-01T${slotMasa}`),
modified_at: new Date(),
},
});
// Delete old barang and create new ones
await prisma.report.deleteMany({
where: { permohonanID: updatedPermohonan.id },
});
for (const barang of barangList) {
await prisma.report.create({
data: {
permohonanID: updatedPermohonan.id,
jenis_barang: barang.jenisBarangDetail,
kuantiti_barang: parseInt(barang.kuantitiBarang),
tanda_barang: barang.tandaBarang,
keadaan_barang: barang.keadaanBarang,
create_by: userID,
create_at: new Date(),
},
});
}
// 6. Send confirmation email if not a draft
if (!isDraft) {
await sendEmail({
to: [
/* pemohon, pegawai_kaunter, ketua_bahagian */
],
subject: `Kemaskini Permohonan: ${noSiri}`,
body: `
Case ID: ${noSiri}
Appointment Date: ${tarikhTemujanji}
Time Slot: ${slotMasa}
Barang: ${barangList
.map(
(barang) =>
`${barang.tandaBarang} - ${barang.kuantitiBarang} units`
)
.join(", ")}
Pemohon Details: ${namaPemohon} (${pangkatPemohon})
${
isPenghantarSameAsPemohon
? ""
: `Penghantar Details: ${namaPenghantar} (${pangkatPenghantar})`
}
Ringkasan Kenyataan Kes: ${ringkasanKenyataanKes}
`,
});
}
return {
statusCode: 200,
message: isDraft
? "Rekod telah berjaya disimpan. (Status CMN-S001)"
: "Permohonan pemeriksaan forensik telah dikemaskini. (Status FOR-S001)",
};
} catch (error) {
console.log(error);
return {
statusCode: 500,
message: "Terdapat masalah. Silakan cuba lagi.",
};
}
});
// Helper function to generate case reference number
const generateCaseReferenceID = () => {
const now = new Date();
const year = now.getFullYear().toString();
const month = String(now.getMonth() + 1).padStart(2, "0"); // JS month is zero-indexed
const day = String(now.getDate()).padStart(2, "0");
const uniqueSerial = String(Math.floor(Math.random() * 1000000)).padStart(
6,
"0"
);
return `${year}${month}${day}-${uniqueSerial}`;
};
const sendEmail = async ({ to, subject, body }) => {
console.log("Sending email to", to);
return true;
};

View File

@ -1,42 +0,0 @@
export default defineEventHandler(async (event) => {
const { noSiri } = event.context.params;
const body = await readBody(event);
const { pegawaiID } = body;
try {
// Ensure that the permohonan exists
const permohonan = await prisma.permohonan.findUnique({
where: { no_siri: noSiri },
});
if (!permohonan) {
return { statusCode: 404, message: "Permohonan tidak dijumpai." };
}
// Ensure that the pegawai is not already assigned
const existingAssignment =
await prisma.permohonan_assign_forensik.findFirst({
where: {
permohonanID: permohonan.id,
pegawai_forensikID: pegawaiID,
},
});
if (existingAssignment) {
return { statusCode: 400, message: "Pegawai sudah ditugaskan." };
}
// Assign the pegawai to this permohonan
await prisma.permohonan_assign_forensik.create({
data: {
permohonanID: permohonan.id,
pegawai_forensikID: pegawaiID,
},
});
return { statusCode: 200, message: "Pegawai berjaya ditambah." };
} catch (error) {
console.error(error);
return { statusCode: 500, message: "Error adding forensic officer." };
}
});

View File

@ -1,51 +0,0 @@
export default defineEventHandler(async (event) => {
const { noSiri } = event.context.params;
try {
// Fetch the list of assigned officers
const assignedOfficers = await prisma.permohonan_assign_forensik.findMany({
where: { permohonan: { no_siri: noSiri } },
select: { pegawai_forensikID: true },
});
const assignedOfficerIDs = assignedOfficers.map(
(officer) => officer.pegawai_forensikID
);
// Fetch all pegawai forensik that are not assigned to this permohonan
const availablePegawai = await prisma.user.findMany({
where: {
userID: { notIn: assignedOfficerIDs },
userStatus: "ACTIVE",
userrole: {
some: {
role: {
roleName: "Pegawai Forensik",
},
},
},
},
select: {
userID: true,
userFullName: true,
userUsername: true,
},
});
return {
statusCode: 200,
data: [
{ value: "", label: "Sila Pilih Pegawai" },
...availablePegawai.map((pegawai) => ({
value: pegawai.userID,
label: `${pegawai.userFullName}`,
})),
],
};
} catch (error) {
return {
statusCode: 500,
message: "Error fetching available forensic officers.",
};
}
});

View File

@ -1,27 +0,0 @@
export default defineEventHandler(async (event) => {
const { noSiri } = event.context.params;
const body = await readBody(event);
const { assignID } = body;
try {
// Fetch the existing permohonan
const permohonan = await prisma.permohonan.findUnique({
where: { no_siri: noSiri },
});
if (!permohonan) {
return { statusCode: 404, message: "Permohonan tidak dijumpai." };
}
// Delete the pegawai assignment
await prisma.permohonan_assign_forensik.delete({
where: {
assignID: assignID,
},
});
return { statusCode: 200, message: "Pegawai berjaya dipadamkan." };
} catch (error) {
return { statusCode: 500, message: "Error deleting forensic officer." };
}
});

View File

@ -1,46 +0,0 @@
export default defineEventHandler(async (event) => {
const { noSiri } = event.context.params;
const body = await readBody(event);
const { oldPegawaiID, newPegawaiID, assignID } = body;
try {
// Fetch the existing permohonan
const permohonan = await prisma.permohonan.findUnique({
where: { no_siri: noSiri },
});
if (!permohonan) {
return { statusCode: 404, message: "Permohonan tidak dijumpai." };
}
// Check if the new pegawai is already assigned
const existingAssignment =
await prisma.permohonan_assign_forensik.findFirst({
where: {
permohonanID: permohonan.id,
pegawai_forensikID: newPegawaiID,
},
});
console.log("existingAssignment", existingAssignment);
if (existingAssignment) {
return { statusCode: 400, message: "Pegawai baru sudah ditugaskan." };
}
// Update the old pegawai with the new pegawai
await prisma.permohonan_assign_forensik.update({
where: {
assignID: assignID,
},
data: {
pegawai_forensikID: newPegawaiID,
},
});
return { statusCode: 200, message: "Pegawai berjaya dikemaskini." };
} catch (error) {
console.log(error);
return { statusCode: 500, message: "Error updating forensic officer." };
}
});

View File

@ -1,45 +0,0 @@
export default defineEventHandler(async (event) => {
const { noSiri } = event.context.params;
try {
// Fetch the permohonan by noSiri
const permohonan = await prisma.permohonan.findUnique({
where: { no_siri: noSiri },
select: {
permohonan_assign_forensik: {
include: {
user: {
select: {
userID: true,
userFullName: true,
userUsername: true,
},
},
},
},
},
});
if (!permohonan) {
return { statusCode: 404, message: "Permohonan tidak dijumpai." };
}
// Return the list of assigned forensic officers
const forensicOfficers = permohonan.permohonan_assign_forensik.map(
(assignment) => ({
nama: assignment.user.userFullName,
tindakan: {
userID: assignment.user.userID,
assignID: assignment.assignID,
},
})
);
return {
statusCode: 200,
data: forensicOfficers,
};
} catch (error) {
return { statusCode: 500, message: "Error fetching forensic officers." };
}
});

View File

@ -1,38 +0,0 @@
// File: /api/permohonan/[noSiri]/reports.get.js
export default defineEventHandler(async (event) => {
const { noSiri } = event.context.params;
try {
const permohonan = await prisma.permohonan.findUnique({
where: { no_siri: noSiri },
select: {
report: {
include: {
lookup_report_jenis_barangTolookup: true, // To get the jenis barang lookup data
},
},
},
});
if (!permohonan) {
return { statusCode: 404, message: "Permohonan tidak dijumpai." };
}
// Map reports to the frontend format
const reports = permohonan.report.map((report) => ({
jenisBarang: report.lookup_report_jenis_barangTolookup.lookupValue,
tagNo: report.tanda_barang,
keadaan: report.keadaan_barang,
kuantiti: report.kuantiti_barang,
tindakan: report.reportID,
}));
return {
statusCode: 200,
data: reports,
};
} catch (error) {
return { statusCode: 500, message: "Error fetching reports." };
}
});

View File

@ -1,61 +0,0 @@
// File: /api/permohonan/[noSiri]/semak.put.js
export default defineEventHandler(async (event) => {
const { noSiri } = event.context.params;
const body = await readBody(event); // Get form data from frontend
try {
// Get the current user (assuming user authentication is handled)
const user = event.context.user;
// Find the permohonan by its noSiri
const permohonan = await prisma.permohonan.findUnique({
where: { no_siri: noSiri },
});
if (!permohonan) {
return { statusCode: 404, message: "Permohonan tidak dijumpai." };
}
// Update or create the permohonan semakan entry
await prisma.permohonan_semakan.upsert({
where: {
permohonanID: permohonan.id,
},
update: {
peralatan_keadaan_baik: body.peralatanBaik === "Ya" ? 1 : 0,
pegawai_berkelayakan: body.pegawaiBerkelayakan === "Ya" ? 1 : 0,
kaedah_dpt_dilakukan: body.kaedahDapatDilakukan === "Ya" ? 1 : 0,
subkontrak_diperlukan: body.subkontrakDiperlukan === "Ya" ? 1 : 0,
tugasan_diterima: body.tugasanDiterima === "Ya" ? 1 : 0,
ulasan_pegawai: body.ulasanPegawaiKaunter,
disemak_oleh: user.userID, // Use the authenticated user ID
create_at: new Date(),
},
create: {
permohonanID: permohonan.id,
peralatan_keadaan_baik: body.peralatanBaik === "Ya" ? 1 : 0,
pegawai_berkelayakan: body.pegawaiBerkelayakan === "Ya" ? 1 : 0,
kaedah_dpt_dilakukan: body.kaedahDapatDilakukan === "Ya" ? 1 : 0,
subkontrak_diperlukan: body.subkontrakDiperlukan === "Ya" ? 1 : 0,
tugasan_diterima: body.tugasanDiterima === "Ya" ? 1 : 0,
ulasan_pegawai: body.ulasanPegawaiKaunter,
disemak_oleh: user.userID,
create_at: new Date(),
},
});
// Update the status of the permohonan to "Permohonan Disemak"
await prisma.permohonan.update({
where: { no_siri: noSiri },
data: { status_permohonan: "Permohonan Disemak" },
});
return {
statusCode: 200,
message: "Maklumat semakan berjaya dikemaskini.",
};
} catch (error) {
console.error(error);
return { statusCode: 500, message: "Gagal mengemaskini maklumat semakan." };
}
});

View File

@ -1,49 +0,0 @@
export default defineEventHandler(async (event) => {
// Extract the `noSiri` from the URL params
const { noSiri } = event.context.params;
try {
// Fetch the Semakan status
const semakan = await prisma.permohonan_semakan.findFirst({
where: {
permohonan: {
no_siri: noSiri,
},
},
select: {
semakanID: true, // Checking if semakan exists
},
});
// Fetch the Penerimaan status
const penerimaan = await prisma.permohonan_penerimaan.findFirst({
where: {
permohonan: {
no_siri: noSiri,
},
},
select: {
penerimaanID: true, // Checking if penerimaan exists
},
});
// Determine statuses based on existence
const statusSemakan = semakan ? "Selesai" : "Belum Disemak";
const statusPenerimaan = penerimaan ? "Diterima" : "Belum Diterima";
// Return the statuses
return {
statusCode: 200,
data: {
statusSemakan,
statusPenerimaan,
},
};
} catch (error) {
// Return an error if something goes wrong
return {
statusCode: 500,
message: "Gagal mendapatkan status",
};
}
});

View File

@ -1,64 +0,0 @@
// File: /api/permohonan/[noSiri]/terima.put.js
export default defineEventHandler(async (event) => {
const { noSiri } = event.context.params;
const body = await readBody(event); // Get form data from frontend
try {
// Get the current user (assuming user authentication is handled)
const user = event.context.user;
// Find the permohonan by its noSiri
const permohonan = await prisma.permohonan.findUnique({
where: { no_siri: noSiri },
});
if (!permohonan) {
return { statusCode: 404, message: "Permohonan tidak dijumpai." };
}
// Create or update the permohonan penerimaan entry
await prisma.permohonan_penerimaan.upsert({
where: {
permohonanID: permohonan.id,
},
update: {
peralatan_keadaan_baik: body.peralatanBaik === "Ya" ? 1 : 0,
pegawai_berkelayakan: body.pegawaiBerkelayakan === "Ya" ? 1 : 0,
kaedah_dpt_dilakukan: body.kaedahDapatDilakukan === "Ya" ? 1 : 0,
subkontrak_diperlukan: body.subkontrakDiperlukan === "Ya" ? 1 : 0,
tugasan_diterima: body.tugasanDiterima === "Ya" ? 1 : 0,
ulasan_pegawai: body.ulasanPegawaiKaunter,
diterima_oleh: user.userID,
create_at: new Date(), // Store current date
},
create: {
permohonanID: permohonan.id,
peralatan_keadaan_baik: body.peralatanBaik === "Ya" ? 1 : 0,
pegawai_berkelayakan: body.pegawaiBerkelayakan === "Ya" ? 1 : 0,
kaedah_dpt_dilakukan: body.kaedahDapatDilakukan === "Ya" ? 1 : 0,
subkontrak_diperlukan: body.subkontrakDiperlukan === "Ya" ? 1 : 0,
tugasan_diterima: body.tugasanDiterima === "Ya" ? 1 : 0,
ulasan_pegawai: body.ulasanPegawaiKaunter,
diterima_oleh: user.userID,
create_at: new Date(),
},
});
// Update the status of the permohonan to "Diterima"
await prisma.permohonan.update({
where: { no_siri: noSiri },
data: { status_permohonan: "Permohonan Diterima" },
});
return {
statusCode: 200,
message: "Maklumat penerimaan berjaya dikemaskini.",
};
} catch (error) {
console.error(error);
return {
statusCode: 500,
message: "Gagal mengemaskini maklumat penerimaan.",
};
}
});

View File

@ -1,56 +0,0 @@
// File: /api/permohonan/[noSiri]/tolak.put.js
export default defineEventHandler(async (event) => {
const { noSiri } = event.context.params;
const body = await readBody(event); // Get form data from frontend
try {
// Get the current user (assuming user authentication is handled)
const user = event.context.user;
// Find the permohonan by its noSiri
const permohonan = await prisma.permohonan.findUnique({
where: { no_siri: noSiri },
});
if (!permohonan) {
return { statusCode: 404, message: "Permohonan tidak dijumpai." };
}
// Create or update the permohonan penolakan entry
await prisma.permohonan_penolakan.upsert({
where: {
permohonanID: permohonan.id,
},
update: {
sebab_penolakan: parseInt(body.sebabPenolakan), // Assuming lookupID is passed
lain_sebab: body.lainLainSebab || null,
ditolak_oleh: user.userID,
create_at: new Date(),
},
create: {
permohonanID: permohonan.id,
sebab_penolakan: parseInt(body.sebabPenolakan),
lain_sebab: body.lainLainSebab || null,
ditolak_oleh: user.userID,
create_at: new Date(),
},
});
// Update the status of the permohonan to "Permohonan Ditolak"
await prisma.permohonan.update({
where: { no_siri: noSiri },
data: { status_permohonan: "Permohonan Ditolak" },
});
return {
statusCode: 200,
message: "Maklumat penolakan berjaya dikemaskini.",
};
} catch (error) {
console.error(error);
return {
statusCode: 500,
message: "Gagal mengemaskini maklumat penolakan.",
};
}
});

View File

@ -1,194 +0,0 @@
export default defineEventHandler(async (event) => {
const body = await readBody(event);
const { userID } = event.context.user;
const {
namaPemohon,
pangkatPemohon,
noPegawaiPemohon,
namaPenghantar,
pangkatPenghantar,
noPegawaiPenghantar,
ringkasanKenyataanKes,
isPenghantarSameAsPemohon,
bilangan,
barangList,
noKertasSiasatan,
noLaporanPolis,
tarikhTemujanji,
slotMasa,
isDraft,
} = body;
// 1. Mandatory fields validation
const mandatoryFields = [
namaPemohon,
pangkatPemohon,
noPegawaiPemohon,
ringkasanKenyataanKes,
bilangan,
noKertasSiasatan,
noLaporanPolis,
tarikhTemujanji,
slotMasa,
...barangList,
];
if (mandatoryFields.some((field) => !field || field === "")) {
return {
statusCode: 400,
message:
"Setiap medan mandatori yang bertanda * telah diisi. (Ralat CMN-E001)",
};
}
// 2. Validate date for the appointment
const appointmentDate = new Date(tarikhTemujanji);
const currentDate = new Date();
if (appointmentDate <= currentDate) {
return {
statusCode: 400,
message:
"Perlu memastikan tarikh janji temu yang dimasukkan adalah tarikh selepas tarikh semasa. (Ralat CMN-E002)",
};
}
// 3. Check if the session is expired
const sessionExpired = false; // Implement session logic here
if (sessionExpired) {
return {
statusCode: 401,
message:
"Sesi aktif pengguna berada dalam sistem telah tamat. (Ralat CMN-E005)",
};
}
// 4. Check for invalid symbols in text fields
const hasInvalidSymbols = (text) => /[^a-zA-Z0-9\s]/.test(text); // Allow alphanumeric and spaces
const fieldsToCheck = [
namaPemohon,
pangkatPemohon,
noPegawaiPemohon,
...barangList.map((barang) => barang.tandaBarang),
];
if (fieldsToCheck.some((field) => hasInvalidSymbols(field))) {
return {
statusCode: 400,
message:
"Perlu memastikan tiada penggunaan simbol dalam medan yang ditetapkan. (Ralat CMN-E011)",
};
}
// 5. Insert data into the database
const caseReferenceID = generateCaseReferenceID();
let permohonanStatus = isDraft ? "Permohonan Draf" : "Permohonan Dihantar";
try {
// Insert into `permohonan` table
const newPermohonan = await prisma.permohonan.create({
data: {
no_siri: caseReferenceID,
status_permohonan: permohonanStatus,
pemohon: {
create: {
userID: userID, // Assuming the user is authenticated, replace with actual user ID
pangkat_pemohon: pangkatPemohon,
no_pegawai_pemohon: noPegawaiPemohon,
},
},
penghantar: {
create: {
nama_penghantar: namaPenghantar,
pangkat_penghantar: pangkatPenghantar,
no_pegawai_penghantar: noPegawaiPenghantar,
},
},
ringkasan_kenyataan_kes: ringkasanKenyataanKes,
bilangan: parseInt(bilangan),
penghantar_sama_dengan_pemohon: isPenghantarSameAsPemohon ? 1 : 0,
no_kertas_siasatan: noKertasSiasatan,
no_laporan_polis: noLaporanPolis,
tarikh_temujanji: new Date(tarikhTemujanji),
slot_masa: new Date(`1970-01-01T${slotMasa}`), // Convert slotMasa string to Time
create_at: new Date(),
},
});
// Insert related `report` and `document` data
for (const barang of barangList) {
await prisma.report.create({
data: {
permohonanID: newPermohonan.id,
jenis_barang: barang.jenisBarangDetail,
kuantiti_barang: parseInt(barang.kuantitiBarang),
tanda_barang: barang.tandaBarang,
keadaan_barang: barang.keadaanBarang,
create_by: userID,
create_at: new Date(),
},
});
}
// 6. Send confirmation email
if (!isDraft) {
await sendEmail({
to: [
/* pemohon, pegawai_kaunter, ketua_bahagian */
],
subject: `Permohonan Baru: ${caseReferenceID}`,
body: `
Case ID: ${caseReferenceID}
Appointment Date: ${tarikhTemujanji}
Time Slot: ${slotMasa}
Barang: ${barangList
.map(
(barang) =>
`${barang.tandaBarang} - ${barang.kuantitiBarang} units`
)
.join(", ")}
Pemohon Details: ${namaPemohon} (${pangkatPemohon})
${
isPenghantarSameAsPemohon
? ""
: `Penghantar Details: ${namaPenghantar} (${pangkatPenghantar})`
}
Ringkasan Kenyataan Kes: ${ringkasanKenyataanKes}
`,
});
}
return {
statusCode: 200,
message: isDraft
? "Rekod telah berjaya disimpan. (Status CMN-S001)"
: "Permohonan pemeriksaan forensik telah dihantar. (Status FOR-S001)",
};
} catch (error) {
console.log(error);
return {
statusCode: 500,
message: "Terdapat masalah. Silakan cuba lagi.",
};
}
});
// Helper function to generate case reference number
const generateCaseReferenceID = () => {
const now = new Date();
const year = now.getFullYear().toString();
const month = String(now.getMonth() + 1).padStart(2, "0"); // JS month is zero-indexed
const day = String(now.getDate()).padStart(2, "0");
const uniqueSerial = String(Math.floor(Math.random() * 1000000)).padStart(
6,
"0"
);
return `${year}${month}${day}-${uniqueSerial}`;
};
const sendEmail = async ({ to, subject, body }) => {
console.log("Sending email to", to);
return true;
};

View File

@ -1,44 +0,0 @@
// File: server/api/permohonan/index.get.js
export default defineEventHandler(async () => {
try {
const permohonan = await prisma.permohonan.findMany({
where: {
status_permohonan: {
notIn: ["Permohonan Ditolak"],
},
},
select: {
id: true,
no_siri: true,
create_at: true,
status_permohonan: true,
},
orderBy: {
create_at: "desc",
},
});
return {
statusCode: 200,
message: "Success",
data: permohonan.map((item, index) => {
// Convert UTC to GMT+8
const gmt8Date = new Date(
item.create_at.getTime() + 8 * 60 * 60 * 1000
);
return {
no: index + 1,
noSiri: item.no_siri,
tarikhMasa: gmt8Date.toISOString().replace("T", " ").slice(0, 19),
status: item.status_permohonan,
butiran: item.id,
};
}),
};
} catch (error) {
return {
statusCode: 500,
message: "Failed to fetch permohonan data.",
};
}
});

View File

@ -1,34 +0,0 @@
export default defineEventHandler(async (event) => {
const { temujanjiID } = event.context.params;
try {
// Check if temujanji_detail exists before deleting
const detailExists = await prisma.temujanji_detail.findFirst({
where: { temujanjiID: parseInt(temujanjiID) },
});
if (detailExists) {
await prisma.temujanji_detail.deleteMany({
where: { temujanjiID: parseInt(temujanjiID) },
});
}
const pemohonExists = await prisma.pemohon.findFirst({
where: { temujanjiID: parseInt(temujanjiID) },
});
if (pemohonExists) {
await prisma.pemohon.delete({
where: { temujanjiID: parseInt(temujanjiID) },
});
}
await prisma.temujanji.delete({
where: { temujanjiID: parseInt(temujanjiID) },
});
return { statusCode: 200, message: "Berjaya" };
} catch (error) {
return { statusCode: 500, message: error.message };
}
});

View File

@ -1,64 +0,0 @@
export default defineEventHandler(async (event) => {
const { temujanjiID } = event.context.params;
try {
// Fetch the appointment data and related details from temujanji_detail
const appointment = await prisma.temujanji.findUnique({
where: { temujanjiID: parseInt(temujanjiID) },
include: {
pemohon: true, // Include pemohon (applicant) details
temujanji_detail: true,
},
});
console.log(appointment);
if (!appointment) {
return {
statusCode: 404,
message: "Temujanji tidak dijumpai.",
};
}
// Format the data to fit the front-end expectations
return {
statusCode: 200,
data: {
temujanjiID: appointment.temujanjiID,
jenisDokumen: appointment.temujanji_detail.jenisDokumen,
negara: appointment.temujanji_detail.negara,
namaPemilik: appointment.temujanji_detail.namaPemilik,
noDokumen: appointment.temujanji_detail.noDokumen,
kewarganegaraan: appointment.temujanji_detail.kewarganegaraan,
tarikhLahir: appointment.temujanji_detail.tarikhLahir,
jantina: appointment.temujanji_detail.jantina,
tarikhLuputDokumen: appointment.temujanji_detail.tarikhLuputDokumen,
skorPersamaanMuka: appointment.temujanji_detail.skorPersamaanMuka,
skorPersamaanCapJari: appointment.temujanji_detail.skorPersamaanCapJari,
umur: appointment.temujanji_detail.umur,
tinggi: appointment.temujanji_detail.tinggi,
warnaRambut: appointment.temujanji_detail.warnaRambut,
bangsa: appointment.temujanji_detail.bangsa,
etnik: appointment.temujanji_detail.etnik,
bentukKepala: appointment.temujanji_detail.bentukKepala,
mata: appointment.temujanji_detail.mata,
telinga: appointment.temujanji_detail.telinga,
hidung: appointment.temujanji_detail.hidung,
mulut: appointment.temujanji_detail.mulut,
parut: appointment.temujanji_detail.parut,
sejarahPerjalanan: appointment.temujanji_detail.sejarahPerjalanan,
persamaanTandaTangan: appointment.temujanji_detail.persamaanTandaTangan,
pemeriksaanLain: appointment.temujanji_detail.pemeriksaanLain,
dapatan: appointment.temujanji_detail.dapatan,
laporanSystemTdb:
appointment.temujanji_detail?.document?.documentURL || null,
},
};
} catch (error) {
console.error("Error fetching temujanji:", error);
return {
statusCode: 500,
message: "Error fetching appointment data.",
};
}
});

View File

@ -1,101 +0,0 @@
export default defineEventHandler(async (event) => {
const { temujanjiID } = event.context.params;
const body = await readBody(event);
try {
// Get temujanji details ID
const temujanjiDetailsID = await prisma.temujanji.findFirst({
where: { temujanjiID: parseInt(temujanjiID) },
select: {
temujanjiID: true,
temujanjiDetailID: true,
noSiri: true,
jenisSemakan: true,
tarikh: true,
masa: true,
status: true,
},
});
console.log(temujanjiDetailsID);
// Update the main `temujanji` table and related details in `temujanji_detail`
await prisma.temujanji_detail.update({
where: {
temujanjiDetailID: temujanjiDetailsID.temujanjiDetailID,
},
data: {
negara: body.negara,
namaPemilik: body.namaPemilik,
noDokumen: body.noDokumen,
kewarganegaraan: body.kewarganegaraan,
tarikhLahir: new Date(body.tarikhLahir),
jantina: body.jantina,
tarikhLuputDokumen: new Date(body.tarikhLuputDokumen),
skorPersamaanMuka: parseFloat(body.skorPersamaanMuka),
skorPersamaanCapJari: parseFloat(body.skorPersamaanCapJari),
umur: body.umur ? parseInt(body.umur) : null,
tinggi: body.tinggi ? parseFloat(body.tinggi) : null,
warnaRambut: body.warnaRambut || null,
bangsa: body.bangsa || null,
etnik: body.etnik || null,
bentukKepala: body.bentukKepala || null,
mata: body.mata || null,
telinga: body.telinga || null,
hidung: body.hidung || null,
mulut: body.mulut || null,
parut: body.parut || null,
sejarahPerjalanan: body.sejarahPerjalanan || null,
persamaanTandaTangan: body.persamaanTandaTangan || null,
pemeriksaanLain: body.pemeriksaanLain || null,
dapatan: body.dapatan,
modified_at: new Date(),
},
});
// insert temujanji_log
await prisma.temujanji_log.create({
data: {
temujanjiID: parseInt(temujanjiID),
jenisSemakan: temujanjiDetailsID.jenisSemakan,
tarikh: temujanjiDetailsID.tarikh,
masa: temujanjiDetailsID.masa,
negara: body.negara,
namaPemilik: body.namaPemilik,
noDokumen: body.noDokumen,
kewarganegaraan: body.kewarganegaraan,
tarikhLahir: new Date(body.tarikhLahir),
jantina: body.jantina,
tarikhLuputDokumen: new Date(body.tarikhLuputDokumen),
skorPersamaanMuka: parseFloat(body.skorPersamaanMuka),
skorPersamaanCapJari: parseFloat(body.skorPersamaanCapJari),
umur: body.umur ? parseInt(body.umur) : null,
tinggi: body.tinggi ? parseFloat(body.tinggi) : null,
warnaRambut: body.warnaRambut || null,
bangsa: body.bangsa || null,
etnik: body.etnik || null,
bentukKepala: body.bentukKepala || null,
mata: body.mata || null,
telinga: body.telinga || null,
hidung: body.hidung || null,
mulut: body.mulut || null,
parut: body.parut || null,
sejarahPerjalanan: body.sejarahPerjalanan || null,
persamaanTandaTangan: body.persamaanTandaTangan || null,
pemeriksaanLain: body.pemeriksaanLain || null,
dapatan: body.dapatan,
},
});
return {
statusCode: 200,
message: "Temujanji berjaya dikemaskini.",
};
} catch (error) {
console.error("Error updating temujanji:", error);
return {
statusCode: 500,
message: "Gagal mengemaskini temujanji.",
};
}
});

View File

@ -1,31 +0,0 @@
export default defineEventHandler(async (event) => {
try {
const appointments = await prisma.temujanji.findMany({
include: {
pemohon: {
include: {
user: true,
},
}, // Join with pemohon table to get applicant details
},
});
return {
statusCode: 200,
data: appointments.map((appointment, index) => ({
no: index + 1,
kesId: appointment.temujanjiID,
namaPemohon: appointment.pemohon.user.userFullName,
caraSemakan: appointment.jenisSemakan,
status: appointment.status || "Pending",
tindakan: appointment.temujanjiID,
})),
};
} catch (error) {
console.log(error);
return {
statusCode: 500,
message: "Failed to fetch appointments.",
};
}
});

View File

@ -1,82 +0,0 @@
export default defineEventHandler(async (event) => {
const body = await readBody(event);
const { userID } = event.context.user;
const { pemohon, jenisSemakan, tarikh, masa, gambarSubjek, gambarCapJari } =
body;
try {
// Validate required fields
if (
!pemohon.nama ||
!pemohon.jawatan ||
!pemohon.noPegawai ||
!jenisSemakan ||
!tarikh ||
!masa
) {
return {
statusCode: 400,
message: "Sila isi semua medan yang diperlukan.",
};
}
// Save the appointment (temujanji) into the database using Prisma
const temujanjiBaru = await prisma.temujanji.create({
data: {
jenisSemakan: jenisSemakan,
tarikh: new Date(tarikh),
masa: new Date(`${tarikh}T${masa}:00`) ?? new Date(),
status: "Temujanji Diterima",
gambarSubjek: gambarSubjek
? await saveDocument(gambarSubjek, "Subjek")
: undefined,
gambarCapJari: gambarCapJari
? await saveDocument(gambarCapJari, "Cap Jari")
: undefined,
pemohon: {
create: {
userID: userID,
pangkat_pemohon: pemohon.jawatan,
no_pegawai_pemohon: pemohon.noPegawai,
},
},
temujanji_detail: {
create: {
create_at: new Date(),
},
},
},
});
return {
statusCode: 200,
message: "Temujanji berjaya ditambah.",
data: temujanjiBaru,
};
} catch (error) {
console.error("Error adding appointment:", error);
return {
statusCode: 500,
message: "Terdapat ralat semasa menambah temujanji.",
};
}
});
// Helper function to save uploaded documents to the database
async function saveDocument(file, fileType) {
try {
const savedDocument = await prisma.document.create({
data: {
name: file.name,
url: `/uploads/${file.name}`,
type: fileType,
size: file.size,
},
});
return savedDocument.id;
} catch (error) {
console.error("Error saving document:", error);
throw new Error("Gagal menyimpan dokumen.");
}
}