diff --git a/client/src/pages/HBFormPage.tsx b/client/src/pages/HBFormPage.tsx index 73146ec..13d33de 100644 --- a/client/src/pages/HBFormPage.tsx +++ b/client/src/pages/HBFormPage.tsx @@ -1,12 +1,12 @@ -import { useEffect, useState } from 'react'; -import { Button } from "@nextui-org/react"; +import { useEffect, useState } from "react"; +import { Button, Modal, ModalBody, ModalContent, ModalHeader } from "@nextui-org/react"; import { ArrowUTurnLeftIcon } from "../icons"; import { useNavigate } from "react-router-dom"; import { Formik, Form } from "formik"; import * as Yup from "yup"; import config from "../config"; import NextUIFormikInput from "../components/NextUIFormikInput"; -import axios from "axios"; +import instance from "../security/http"; import InsertImage from "../components/InsertImage"; import { retrieveUserInformation } from "../security/users"; @@ -81,34 +81,130 @@ export default function HBFormPage() { } }, [userId]); + const [hasHandedInForm, setHasHandedInForm] = useState(false); + + useEffect(() => { + instance.get(`${config.serverAddress}/hbcform/has-handed-in-form/${userId}`) + .then(response => { + const hasHandedInForm = response.data.hasHandedInForm; + setHasHandedInForm(hasHandedInForm); + }) + .catch(error => { + console.error("Error checking if user has handed in form:", error); + + }); + }, [userId]); + + const [isModalOpen, setIsModalOpen] = useState(false); const navigate = useNavigate(); const handleSubmit = async ( values: any, { setSubmitting, resetForm, setFieldError, setFieldValue }: any ) => { - const formData = new FormData(); - formData.append("electricalBill", values.electricalBill); - formData.append("waterBill", values.waterBill); - formData.append("totalBill", values.totalBill); - formData.append("noOfDependents", values.noOfDependents); - formData.append("avgBill", values.avgBill); + if (hasHandedInForm) { + setIsModalOpen(true); + } else { + const formData = new FormData(); + formData.append("electricalBill", values.electricalBill); + formData.append("waterBill", values.waterBill); + formData.append("totalBill", values.totalBill); + formData.append("noOfDependents", values.noOfDependents); + formData.append("avgBill", values.avgBill); - if (values.ebPicture) { - formData.append("ebPicture", values.ebPicture); + if (values.ebPicture) { + formData.append("ebPicture", values.ebPicture); + } + + if (values.wbPicture) { + formData.append("wbPicture", values.wbPicture); + } + + if (userId != null) { + formData.append("userId", userId); + } + + try { + const response = await instance.post( + config.serverAddress + "/hbcform", + formData, + { + headers: { + "Content-Type": "multipart/form-data", + }, + } + ); + if (response.status === 200) { + console.log("Form created successfully:", response.data); + resetForm(); // Clear form after successful submit + setFieldValue("ebPicture", null); + setFieldValue("wbPicture", null); + navigate(-1); + } else { + console.error("Error creating form:", response.statusText); + } + } catch (error: any) { + if (error.response && error.response.data && error.response.data.errors) { + const errors = error.response.data.errors; + Object.keys(errors).forEach((key) => { + setFieldError(key, errors[key]); + }); + } else { + console.error("Unexpected error:", error); + } + } finally { + setSubmitting(false); + } } + }; - if (values.wbPicture) { - formData.append("wbPicture", values.wbPicture); - } - - if (userId != null) { - formData.append("userId", userId); - } + // Handler for image selection + const handleImageSelection = (name: string, file: File | null) => { + setImagesSelected(prevState => ({ + ...prevState, + [name]: !!file, + })); + }; + const handleModalSubmit = async ({ + values, + resetForm, + setFieldError, + setFieldValue + }: any) => { try { - const response = await axios.post( - config.serverAddress + "/hbcform", + // Fetch the current form ID associated with the userId + const responses = await instance.get(`${config.serverAddress}/hbcform/has-handed-in-form/${userId}`); + const formId = responses.data.formId; // Make sure your API response includes the formId + + if (formId) { + // Delete the form entry using the formId + await instance.delete(`${config.serverAddress}/hbcform/${formId}`); + console.log("Old form data deleted successfully"); + } + // Prepare the new form data + const formData = new FormData(); + formData.append("electricalBill", values.electricalBill); + formData.append("waterBill", values.waterBill); + formData.append("totalBill", values.totalBill); + formData.append("noOfDependents", values.noOfDependents); + formData.append("avgBill", values.avgBill); + + if (values.ebPicture) { + formData.append("ebPicture", values.ebPicture); + } + + if (values.wbPicture) { + formData.append("wbPicture", values.wbPicture); + } + + if (userId != null) { + formData.append("userId", userId); + } + + // Submit the new form data + const response = await instance.post( + `${config.serverAddress}/hbcform`, formData, { headers: { @@ -116,6 +212,7 @@ export default function HBFormPage() { }, } ); + if (response.status === 200) { console.log("Form created successfully:", response.data); resetForm(); // Clear form after successful submit @@ -135,16 +232,12 @@ export default function HBFormPage() { console.error("Unexpected error:", error); } } finally { - setSubmitting(false); + setIsModalOpen(false); // Close the modal after submission } }; - // Handler for image selection - const handleImageSelection = (name: string, file: File | null) => { - setImagesSelected(prevState => ({ - ...prevState, - [name]: !!file, - })); + const handleModalCancel = () => { + navigate(-1) }; return ( @@ -251,6 +344,44 @@ export default function HBFormPage() { + + + + Confirmation + + +
+

This form has been submitted before. If you submit again, the previous entry will be deleted. Are you sure you want to resubmit?

+
+
+ + +
+
+
+
); }} diff --git a/server/routes/hbcform.js b/server/routes/hbcform.js index 9d83d1c..511e488 100644 --- a/server/routes/hbcform.js +++ b/server/routes/hbcform.js @@ -1,6 +1,6 @@ -const express = require('express'); +const express = require("express"); const router = express.Router(); -const { HBCform } = require('../models'); +const { HBCform } = require("../models"); const { Op } = require("sequelize"); const yup = require("yup"); const multer = require("multer"); @@ -14,27 +14,27 @@ async function processFile(file) { const maxSize = 5 * 1024 * 1024; // 5MB limit for compressed image size let processedBuffer; - if (mimetype.startsWith('image/')) { + if (mimetype.startsWith("image/")) { // Handle image files const metadata = await sharp(buffer).metadata(); // Compress the image based on its format - if (metadata.format === 'jpeg') { + if (metadata.format === "jpeg") { processedBuffer = await sharp(buffer) .jpeg({ quality: 80 }) // Compress to JPEG .toBuffer(); - } else if (metadata.format === 'png') { + } else if (metadata.format === "png") { processedBuffer = await sharp(buffer) .png({ quality: 80 }) // Compress to PNG .toBuffer(); - } else if (metadata.format === 'webp') { + } else if (metadata.format === "webp") { processedBuffer = await sharp(buffer) .webp({ quality: 80 }) // Compress to WebP .toBuffer(); } else { // For other image formats (e.g., TIFF), convert to JPEG processedBuffer = await sharp(buffer) - .toFormat('jpeg') + .toFormat("jpeg") .jpeg({ quality: 80 }) .toBuffer(); } @@ -43,9 +43,9 @@ async function processFile(file) { if (processedBuffer.length > maxSize) { throw new Error(`Compressed file too large: ${(processedBuffer.length / 1000000).toFixed(2)}MB`); } - } else if (mimetype === 'application/pdf') { + } else if (mimetype === "application/pdf") { // Handle PDF files - console.log('Processing PDF'); + console.log("Processing PDF"); processedBuffer = buffer; // Store the PDF as is // Optionally, process PDF using pdf-lib or other libraries } else { @@ -54,16 +54,16 @@ async function processFile(file) { return processedBuffer; } catch (err) { - console.error('Error processing file:', err); + console.error("Error processing file:", err); throw err; } } router.post( - '/', + "/", upload.fields([ - { name: 'ebPicture', maxCount: 1 }, - { name: 'wbPicture', maxCount: 1 }, + { name: "ebPicture", maxCount: 1 }, + { name: "wbPicture", maxCount: 1 }, ]), async (req, res) => { let data = req.body; @@ -115,7 +115,7 @@ router.get("/", async (req, res) => { } let list = await HBCform.findAll({ where: condition, - order: [['createdAt', 'ASC']] + order: [["createdAt", "ASC"]] }); res.json(list); }); @@ -186,7 +186,7 @@ router.delete("/:id", async (req, res) => { }); // Endpoint for sending emails related to home bill contest -router.post('/send-homebill-contest-email', async (req, res) => { +router.post("/send-homebill-contest-email", async (req, res) => { const { email, name } = req.body; try { await sendThankYouEmail(email, name); @@ -197,4 +197,19 @@ router.post('/send-homebill-contest-email', async (req, res) => { } }); +router.get("/has-handed-in-form/:userId", async (req, res) => { + const userId = req.params.userId; + try { + const form = await HBCform.findOne({ where: { userId } }); + if (form) { + res.json({ hasHandedInForm: true, formId: form.id }); + } else { + res.json({ hasHandedInForm: false }); + } + } catch (err) { + console.error("Error checking if user has handed in form:", err); + res.status(500).json({ message: "Failed to check if user has handed in form", error: err }); + } +}); + module.exports = router; \ No newline at end of file