From 0b5f901c035386b67dc5fc5854f51dde92c73cca Mon Sep 17 00:00:00 2001 From: janiduimesh Date: Sun, 17 Mar 2024 22:01:44 +1100 Subject: [PATCH 1/8] supplier management routes schema(order.js,supplier.js) crud routes (orders.js,suppliers.js) --- backend/index.js | 5 + backend/supplierManagement/models/order.js | 17 ++++ backend/supplierManagement/models/supplier.js | 17 ++++ backend/supplierManagement/routes/orders.js | 89 ++++++++++++++++++ .../supplierManagement/routes/suppliers.js | 91 +++++++++++++++++++ 5 files changed, 219 insertions(+) create mode 100644 backend/supplierManagement/models/order.js create mode 100644 backend/supplierManagement/models/supplier.js create mode 100644 backend/supplierManagement/routes/orders.js create mode 100644 backend/supplierManagement/routes/suppliers.js diff --git a/backend/index.js b/backend/index.js index 6e8f3aef..a6404fc8 100644 --- a/backend/index.js +++ b/backend/index.js @@ -4,6 +4,8 @@ const app = express(); const cors = require("cors"); const test = require("./trackingParcel/parcelRoutes/routes"); const saveParcelRoute = require("./trackingParcel/parcelRoutes/saveParcelRoute"); +const supplierRouter = require('./routes/suppliers.js'); +const orderRouter = require('./routes/orders.js'); // Middleware section app.use(cors()); @@ -27,5 +29,8 @@ app.listen(port, () => { console.log(`Server is running on port ${port}`); }); +app.use("/supplier",supplierRouter); +app.use("/order",orderRouter); + app.use(test); app.use(saveParcelRoute); diff --git a/backend/supplierManagement/models/order.js b/backend/supplierManagement/models/order.js new file mode 100644 index 00000000..91f3dbb8 --- /dev/null +++ b/backend/supplierManagement/models/order.js @@ -0,0 +1,17 @@ +const mongoose=require('mongoose'); + +const Schema=mongoose.Schema; + +const oredrSchema=new Schema({ + + oid:{type:Number,unique:true,required:true}, + supplier:{type:String,required:true}, + date:{type:Date,required:true}, + bname:{type:String,required:true}, + quantity:{type:Number,required:true} + +}) + +const order=mongoose.model("order",oredrSchema); + +module.exports = order; \ No newline at end of file diff --git a/backend/supplierManagement/models/supplier.js b/backend/supplierManagement/models/supplier.js new file mode 100644 index 00000000..541f82fc --- /dev/null +++ b/backend/supplierManagement/models/supplier.js @@ -0,0 +1,17 @@ +const mongoose=require('mongoose'); + +const Schema=mongoose.Schema; + +const supplierSchema=new Schema({ + + name:{type:String,required:true}, + nic:{type:String,unique:true,required:true}, + address:{type:String,required:true}, + mobile:{type:Number,required:true}, + wname:{type:String,required:false} + +}) + +const supplier=mongoose.model("Supplier",supplierSchema); + +module.exports = supplier; \ No newline at end of file diff --git a/backend/supplierManagement/routes/orders.js b/backend/supplierManagement/routes/orders.js new file mode 100644 index 00000000..4e6d7fe2 --- /dev/null +++ b/backend/supplierManagement/routes/orders.js @@ -0,0 +1,89 @@ +const router= require( 'express').Router(); +let order=require('../models/order') + +router.route('/add').post((req, res)=>{ + + const oid =req.body.oid; + const supplier =req.body.supplier; + const date = req.body.date; + const bname = req.body.bname; + const quantity = req.body.quantity ; + + const newOrder=new order({ + + oid, + supplier, + date, + bname, + quantity + }) + + newOrder.save() + .then(()=>{ + res.json("order submitted") + }).catch((err)=> {res.status(400).send("unable to submit order")}) +}) +//get all orders +router.route("/").get((req, res) => { + + order.find().then((orders)=>{ + res.json(orders) + + }).catch((err)=>{ + console.log(err) + }) +}) + + + +router.route("/update/:oid").put(async(req,res)=>{ + + let orderId=req.params.oid; + const{oid,supplier,date,bname,quantity}=req.body; + + const updateOrder={ + oid, + supplier, + date, + bname, + quantity + } + const update=await order.findOneAndUpdate({ oid: orderId }, updateOrder, { new: true }); + if(!update){ + return res.status(404).send('No order found') + }else{ + + return res.status(200).send({status:"order updated"}); + } +}) + +//delete one order +router.route("/delete/:oid").delete(async(req,res)=>{ + + let orderId=req.params.oid; + await order.findOneAndDelete(orderId).then(()=>{ + + res.status(200).send({status:'order Deleted'}); + + }).catch((err)=> { + res.status(500).send({status:"Error in order deleting"}); + console.log(err); + }) +}) +//get one order +router.route("/get/:oid").get(async(req,res)=>{ + let orderId = req.params.oid; // Corrected variable name + try { + const foundOrder = await order.findOne({ oid: orderId }); + + if (!foundOrder) { + return res.status(404).send({ status: 'Order not found' }); + } + + return res.status(200).send({ status: 'Order fetched', order: foundOrder }); + } catch (error) { + console.error(error); + return res.status(500).send({ status: "Error in fetch", error: error.message }); + } +}); +module.exports=router; diff --git a/backend/supplierManagement/routes/suppliers.js b/backend/supplierManagement/routes/suppliers.js new file mode 100644 index 00000000..c77a0dcd --- /dev/null +++ b/backend/supplierManagement/routes/suppliers.js @@ -0,0 +1,91 @@ +const router= require( 'express').Router(); +let supplier=require('../models/supplier') + +router.route('/add').post((req, res)=>{ + + const name =req.body.name; + const nic =req.body.nic; + const address = req.body.address; + const mobile = Number(req.body.mobile); + const wname = req.body.wname ; + + const newSupplier=new supplier({ + + name, + nic, + address, + mobile, + wname + }) + + newSupplier.save() + .then(()=>{ + res.json("Supplier added") + }).catch((err)=> {res.status(400).send("unable to add Supplier")}) +}) + +/***************************** */ +//to get all the data from database +router.route("/").get((req, res) => { + + supplier.find().then((suppliers)=>{ + res.json(suppliers) + + }).catch((err)=>{ + console.log(err) + }) +}) + + +//update a specific record in the database +router.route("/update/:nic").put(async(req,res)=>{ + + let userNic=req.params.nic; + const{name,nic,address,mobile,wname}=req.body; + + const updateSupplier={ + name, + nic, + address, + mobile, + wname + } + const update=await supplier.findOneAndUpdate({ nic: userNic }, updateSupplier, { new: true }); + if(!update){ + return res.status(404).send('No User found') + }else{ + + return res.status(200).send({status:"user updated"}); + } +}) + +//delete a specific record from the database +router.route("/delete/:nic").delete(async(req,res)=>{ + + let userNic=req.params.nic; + await supplier.findOneAndDelete(userNic).then(()=>{ + + res.status(200).send({status:'Deleted'}); + + }).catch((err)=> { + res.status(500).send({status:"Error in deleting"}); + console.log(err); + }) +}) +//get one supplier details +router.route("/get/:nic").get(async(req,res)=>{ + let userId = req.params.nic; + try { + const founduser = await supplier.findOne({ nic: userId }); + + if (!founduser) { + return res.status(404).send({ status: 'user not found' }); + } + + return res.status(200).send({ status: 'user fetched', order: founduser }); + } catch (error) { + console.error(error); + return res.status(500).send({ status: "Error in fetch", error: error.message }); + } +}); +module.exports=router; From d1a9242b1a2e5cb7d60f5aeae7720644223931b1 Mon Sep 17 00:00:00 2001 From: janiduimesh Date: Fri, 19 Apr 2024 19:48:02 +0530 Subject: [PATCH 2/8] Update supplier.js Update both Schemas --- backend/supplierManagement/models/supplier.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/supplierManagement/models/supplier.js b/backend/supplierManagement/models/supplier.js index 541f82fc..99b6bae5 100644 --- a/backend/supplierManagement/models/supplier.js +++ b/backend/supplierManagement/models/supplier.js @@ -8,7 +8,8 @@ const supplierSchema=new Schema({ nic:{type:String,unique:true,required:true}, address:{type:String,required:true}, mobile:{type:Number,required:true}, - wname:{type:String,required:false} + email:{type:String,required:true}, + wname:{type:String,required:true} }) From ec9e2e49723380dcb5dcd469688d7840435f4203 Mon Sep 17 00:00:00 2001 From: janiduimesh Date: Fri, 19 Apr 2024 19:57:18 +0530 Subject: [PATCH 3/8] new Order backend --- backend/supplierManagement/routes/orders.js | 38 +++++++++++++++------ 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/backend/supplierManagement/routes/orders.js b/backend/supplierManagement/routes/orders.js index 4e6d7fe2..b4c88379 100644 --- a/backend/supplierManagement/routes/orders.js +++ b/backend/supplierManagement/routes/orders.js @@ -23,7 +23,7 @@ router.route('/add').post((req, res)=>{ res.json("order submitted") }).catch((err)=> {res.status(400).send("unable to submit order")}) }) -//get all orders + router.route("/").get((req, res) => { order.find().then((orders)=>{ @@ -57,20 +57,38 @@ router.route("/update/:oid").put(async(req,res)=>{ } }) -//delete one order + router.route("/delete/:oid").delete(async(req,res)=>{ + try{ let orderId=req.params.oid; - await order.findOneAndDelete(orderId).then(()=>{ + const deleteorder = await order.findOneAndDelete({oid:orderId}); + + if (deleteorder) { + res.status(200).send({ status: 'Deleted' }); + + } else { + res.status(404).send({ status: "Supplier not found" }); + }} + catch (err) { + res.status(500).send({ status: "Error in deleting" }); + console.log(err); + } +}) + +// delete all +router.route('/delete'). delete(async(req, res) => { + try { + await order.deleteMany({}); // Delete all documents in the Order collection + res.status(200).send({ status: 'All orders deleted' }); + console.log(res); + } catch (err) { + res.status(500).send({ status: 'Error in deleting' }); + console.error(err); + } +}); - res.status(200).send({status:'order Deleted'}); - }).catch((err)=> { - res.status(500).send({status:"Error in order deleting"}); - console.log(err); - }) -}) -//get one order router.route("/get/:oid").get(async(req,res)=>{ let orderId = req.params.oid; // Corrected variable name try { From e5c09bed6f4312d4c8784d1e86e8f7aa6f9d4684 Mon Sep 17 00:00:00 2001 From: janiduimesh Date: Fri, 19 Apr 2024 20:06:14 +0530 Subject: [PATCH 4/8] Order Form --- frontend/src/supplierComponents/AddOrder.js | 156 ++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 frontend/src/supplierComponents/AddOrder.js diff --git a/frontend/src/supplierComponents/AddOrder.js b/frontend/src/supplierComponents/AddOrder.js new file mode 100644 index 00000000..cdc367c8 --- /dev/null +++ b/frontend/src/supplierComponents/AddOrder.js @@ -0,0 +1,156 @@ +import React, { useState, useRef } from "react"; +import axios from 'axios'; +import emailjs from '@emailjs/browser'; +import { useNavigate, useParams } from "react-router-dom"; +import DatePicker from "react-datepicker"; +import "react-datepicker/dist/react-datepicker.css"; + +function AddOrder() { + // State variables + const [oid, setOid] = useState(""); + const [supplier, setSupplier] = useState(""); + const [bname, setBname] = useState(""); + const [quantity, setQuantity] = useState(""); + const [selectedDate, setSelectedDate] = useState(new Date()); + const [errors, setErrors] = useState({}); + const form = useRef(); + + // Function to send data to the server + + const navigate= useNavigate(); + + const sendData = (e) => { + e.preventDefault(); + const newOrder = { + oid, + supplier, + date: selectedDate, + bname, + quantity + }; + + axios.post('http://localhost:5000/order/add', newOrder) + .then(() => { + alert("Successfully added the order"); + navigate('/allOrders'); + }) + .catch((err) => { + alert(err); + }); + }; + + // Function to send email + const sendEmail = (e) => { + e.preventDefault(); + emailjs.sendForm('service_emxur9p', 'template_7o4wl1g', form.current, { + publicKey: 'LTu5eL1Qw36dHobjH', + }).then( + () => { + console.log('SUCCESS!'); + }, + (error) => { + console.log('FAILED...', error.text); + }, + ); + }; + + // Function to handle form submission + const handleSubmit = (e) => { + e.preventDefault(); + const errors = validateForm(); + if (Object.keys(errors).length === 0) { + sendData(e); + sendEmail(e); + } else { + setErrors(errors); + } + }; + + // Function to validate form fields + const validateForm = () => { + const errors = {}; + if (!oid.trim()) { + errors.oid = "Order ID is required"; + } + if (!supplier.trim()) { + errors.supplier = "Supplier name is required"; + } + if (!bname.trim()) { + errors.bname = "Brand name is required"; + } + if (!quantity.trim()) { + errors.quantity = "Quantity is required"; + } + return errors; + }; + + return ( +
+
+
+

Add New Order

+
+ + setOid(e.target.value)} + /> + {errors.oid &&
{errors.oid}
} +
+
+ + setSupplier(e.target.value)} + /> + {errors.supplier &&
{errors.supplier}
} +
+
+ + setSelectedDate(date)} + dateFormat="dd/MM/yyyy" + className="form-control" + /> +
+
+ + setBname(e.target.value)} + /> + {errors.bname &&
{errors.bname}
} +
+
+ + setQuantity(e.target.value)} + /> + {errors.quantity &&
{errors.quantity}
} +
+ +
+
+
+ ); +} + +export default AddOrder; From d75134a30d119029ff5c215c9d50bd77b55477ef Mon Sep 17 00:00:00 2001 From: janiduimesh Date: Fri, 19 Apr 2024 20:30:14 +0530 Subject: [PATCH 5/8] Frontend --- frontend/src/supplierComponents/AddSupp.js | 154 +++++++++++++++++++ frontend/src/supplierComponents/AllOrders.js | 110 +++++++++++++ frontend/src/supplierComponents/AllSup.js | 106 +++++++++++++ 3 files changed, 370 insertions(+) create mode 100644 frontend/src/supplierComponents/AddSupp.js create mode 100644 frontend/src/supplierComponents/AllOrders.js create mode 100644 frontend/src/supplierComponents/AllSup.js diff --git a/frontend/src/supplierComponents/AddSupp.js b/frontend/src/supplierComponents/AddSupp.js new file mode 100644 index 00000000..f0f21705 --- /dev/null +++ b/frontend/src/supplierComponents/AddSupp.js @@ -0,0 +1,154 @@ +import React, { useState } from "react"; +import axios from 'axios'; +import { useNavigate, useParams } from "react-router-dom"; + + +function AddSupp() { + const [name, setName] = useState(""); + const [nic, setNic] = useState(""); + const [address, setAddress] = useState(""); + const [mobile, setMobile] = useState(""); + const [email, setEmail] = useState(""); + const [wname, setWname] = useState(""); + + const [errors, setErrors] = useState({}); + + function validateForm() { + const errors = {}; + if (!name.trim()) { + errors.name = "Name is required"; + } + if (!nic.trim()) { + errors.nic = "NIC is required"; + } + if (!address.trim()) { + errors.address = "Address is required"; + } + if (!mobile.trim()) { + errors.mobile = "Mobile number is required"; + } else if (!/^\d{10}$/.test(mobile.trim())) { + errors.mobile = "Mobile number must be 10 digits"; + } + if (!email.trim()) { + errors.email = "Email is required"; + } else if (!/\S+@\S+\.\S+/.test(email.trim())) { + errors.email = "Invalid email address"; + } + + if (!wname.trim()) { + errors.wname = "Warehouse name is required"; + } + setErrors(errors); + return Object.keys(errors).length === 0; + } + const navigate= useNavigate(); + + function sendData(e) { + e.preventDefault(); + + if (validateForm()) { + const newSupplier = { name, nic, address, mobile,email, wname }; + + axios.post('http://localhost:5000/supplier/add', newSupplier) + .then(() => { + alert("Successfully added the supplier"); + navigate('/'); + }) + .catch((err) => { + alert(err); + }); + } + } + + return ( +
+
+
+

Add New Supplier

+
+ + setName(e.target.value)} + + /> + {errors.name &&
{errors.name}
} +
+ +
+ + setNic(e.target.value)} + + /> + {errors.nic &&
{errors.nic}
} +
+ +
+ + setAddress(e.target.value)} + /> + {errors.address &&
{errors.address}
} +
+ +
+ + setMobile(e.target.value)} + /> + {errors.mobile &&
{errors.mobile}
} +
+
+ + setEmail(e.target.value)} + /> + {errors.email &&
{errors.email}
} +
+ +
+ + setWname(e.target.value)} + /> + {errors.wname &&
{errors.wname}
} +
+ +
+
+
+ + ); +} + +export default AddSupp; diff --git a/frontend/src/supplierComponents/AllOrders.js b/frontend/src/supplierComponents/AllOrders.js new file mode 100644 index 00000000..f6cfc07c --- /dev/null +++ b/frontend/src/supplierComponents/AllOrders.js @@ -0,0 +1,110 @@ +import React, {useState,useEffect, useRef} from "react"; +import axios from "axios"; +import { Link } from "react-router-dom"; +import {useReactToPrint} from "react-to-print"; + + export default function AllOrders(){ + + const [orders,setOrders]=useState([]); + + useEffect(()=>{ + + function getOrders(){ + + axios.get('http://localhost:5000/order/').then((res)=>{ + + setOrders(res.data) + }).catch((err)=>{ + + alert(err) + }) + } + getOrders(); + },[]) + + + const deleteOrder = (oid) => { + const isConfirmed = window.confirm("Are you sure you want to delete this Order?"); + if (isConfirmed) { + axios.delete(`http://localhost:5000/order/delete/${oid}`) + .then((res) => { + window.location.reload(); + + + }) + .catch((err) => { + alert(err); + }); + } + }; + const clearAll = () => { + const isConfirmed = window.confirm("Are you sure you want to delete all orders?"); + if (isConfirmed) { + axios.delete(`http://localhost:5000/order/delete`) + .then((res) => { + window.location.reload(); + alert("All orders deleted"); + }) + .catch((err) => { + alert(err); + }); + } + }; + + + const ComponentsRef = useRef(); + + const handlePrint = useReactToPrint({ + content:()=> ComponentsRef.current, + DocumentTitle:"Order Report", + onafterprint:(e)=>alert("Printed") + + }) + + return( + +
+
+

All Orders

+ + + + +
+ +
+ + + + + + + + + + + + + {orders.map((order, index) => ( + + + + + + + + + + Edit + + + + ))} + +
Order IDsupllierDateBrand NameQuantity
{order.oid}{order.supplier}{order.date}{order.bname}{order.quantity}
+
+
+ + ) + + } \ No newline at end of file diff --git a/frontend/src/supplierComponents/AllSup.js b/frontend/src/supplierComponents/AllSup.js new file mode 100644 index 00000000..5a761988 --- /dev/null +++ b/frontend/src/supplierComponents/AllSup.js @@ -0,0 +1,106 @@ +import React, {useState,useEffect} from "react"; +import axios from "axios"; +import { Link } from "react-router-dom"; + + export default function AllSup(){ + + const [suppliers,setSuppliers]=useState([]); + + useEffect(()=>{ + + function getSuppliers(){ + + axios.get('http://localhost:5000/supplier/').then((res)=>{ + + setSuppliers(res.data) + }).catch((err)=>{ + + alert(err) + }) + } + getSuppliers(); + },[]) + + const deleteSupplier = (nic) => { + const isConfirmed = window.confirm("Are you sure you want to delete this supplier?"); + if (isConfirmed) { + axios.delete(`http://localhost:5000/supplier/delete/${nic}`) + .then((res) => { + window.location.reload(); + + }) + .catch((err) => { + alert(err); + }); + } + }; + + + const [searchQuery, setSearchQuery] = useState(""); + const [noResults, setNoResults]=useState(false); + + const handleSearch = (e) => { + const filteredSuppliers = suppliers.filter((supplier) => + Object.values(supplier).some((field) => + field.toString().toLowerCase().includes(searchQuery.toLowerCase()) + ) + ); + setSuppliers(filteredSuppliers); + setNoResults(filteredSuppliers.length === 0); + }; + + + return( + +
+

All Suppliers

+ +
+ setSearchQuery(e.target.value)} + type="text" + name="search" + placeholder="Search Supplier"> + + +
+
+ {noResults ? ( + +
+

No user

+
+ ):( + + + + + + + + + + + + + {suppliers.map((supplier, index) => ( + + + + + + + + + + ))} + +
NameNICAddressMobileEmailWarehouse Name
{supplier.name}{supplier.nic}{supplier.address}{supplier.mobile}{supplier.email}{supplier.wname} + Edit + +
+ )} +
+
+ ) + + } \ No newline at end of file From 371c2d0181d62e7e3bd680773a2cc28b758289c6 Mon Sep 17 00:00:00 2001 From: janiduimesh Date: Fri, 19 Apr 2024 21:54:15 +0530 Subject: [PATCH 6/8] Frontend of update both suppler and order --- .../src/supplierComponents/UpdateOrder.js | 138 +++++++++++++++ .../src/supplierComponents/UpdateSupplier.js | 159 ++++++++++++++++++ 2 files changed, 297 insertions(+) create mode 100644 frontend/src/supplierComponents/UpdateOrder.js create mode 100644 frontend/src/supplierComponents/UpdateSupplier.js diff --git a/frontend/src/supplierComponents/UpdateOrder.js b/frontend/src/supplierComponents/UpdateOrder.js new file mode 100644 index 00000000..8b056c7b --- /dev/null +++ b/frontend/src/supplierComponents/UpdateOrder.js @@ -0,0 +1,138 @@ +import React, { useState, useEffect } from "react"; +import axios from "axios"; +import { useNavigate, useParams } from "react-router-dom"; + +function UpdateOrder() { + const { oid } = useParams(); + const [values, setValues] = useState({ + oid: oid || "", + supplier: "", + date: "", + bname: "", + quantity: "" + }); + + const [errors, setErrors] = useState({}); // State to hold validation errors + + useEffect(() => { + axios.get(`http://localhost:5000/order/get/${oid}`) + .then((res) => { + console.log("Response data:", res.data); + + setValues({ + ...values, + oid: res.data.order.oid, + supplier: res.data.order.supplier, + date: res.data.order.date, + bname: res.data.order.bname, + quantity: res.data.order.quantity + }); + console.log("Updated values:", values); + }) + .catch((err) => { + console.error("Error fetching supplier:", err); + setValues({ ...values, oid: "Error fetching NIC" }); + }); + },[oid]); + + const navigate= useNavigate(); + + const handleSubmit = (e) => { + e.preventDefault(); + // Validate form fields + const validationErrors = {}; + if (!values.supplier.trim()) { + validationErrors.supplier = "Supplier is required"; + } + if (!values.bname.trim()) { + validationErrors.bname = "Brand Name is required"; + } + if (!values.quantity.toString().trim()) { + validationErrors.quantity = "Quantity is required"; + } + + if (Object.keys(validationErrors).length === 0) { + // If no errors, submit the form + axios.put(`http://localhost:5000/order/update/${oid}`, values) + .then((res) => { + console.log("order updated successfully:", res.data); + navigate('/allOrders'); + }) + .catch((err) => { + console.error("Error updating order:", err); + }); + } else { + // If there are errors, set the errors state + setErrors(validationErrors); + } + } + + + return ( +
+
+

Update Order Details

+
+
+ + +
+
+ + setValues({ ...values, supplier: e.target.value })} + /> + {errors.supplier &&
{errors.supplier}
} +
+
+ + +
+ +
+ + setValues({ ...values, bname: e.target.value })} /> + {errors.bname &&
{errors.bname}
} +
+
+ + setValues({ ...values, quantity: e.target.value })} + /> + {errors.quantity &&
{errors.quantity}
} +
+ +
+
+
+ ); +} + +export default UpdateOrder; diff --git a/frontend/src/supplierComponents/UpdateSupplier.js b/frontend/src/supplierComponents/UpdateSupplier.js new file mode 100644 index 00000000..7759bf1e --- /dev/null +++ b/frontend/src/supplierComponents/UpdateSupplier.js @@ -0,0 +1,159 @@ +import React, { useState, useEffect } from "react"; +import axios from "axios"; +import { useNavigate, useParams } from "react-router-dom"; + +function UpdateSupplier() { + const { nic } = useParams(); + const [values, setValues] = useState({ + name: "", + nic: nic || "", + address: "", + mobile: "", + email:"", + wname: "" + }); + + const [errors, setErrors] = useState({}); // State to hold validation errors + + useEffect(() => { + axios.get(`http://localhost:5000/supplier/get/${nic}`) + .then((res) => { + console.log("Response data:", res.data); + + setValues({ + ...values, + name: res.data.order.name, + address: res.data.order.address, + mobile: res.data.order.mobile, + email: res.data.order.email, + wname: res.data.order.wname + }); + console.log("Updated values:", values); + }) + .catch((err) => { + console.error("Error fetching supplier:", err); + setValues({ ...values, nic: "Error fetching NIC" }); + }); + },[nic]); + + const navigate= useNavigate(); + + const handleSubmit = (e) => { + e.preventDefault(); + + // Validate form fields + const validationErrors = {}; + const nicRegex = /^\d{12}$/; + const mobileRegex = /^\d{10}$/; + + if (!values.name.trim()) { + validationErrors.name = "Name is required"; + } + if (!nicRegex.test(values.nic.trim())) { + validationErrors.nic = "NIC should be 12 digits"; + } + if (!values.address.trim()) { + validationErrors.address = "Address is required"; + } + if (!mobileRegex.test(values.mobile.toString().trim())) { + validationErrors.mobile = "Mobile number should be 10 digits"; + } + if (values.email && !/^\S+@\S+\.\S+$/.test(values.email)) { + validationErrors.email = "Invalid email address"; + } + + if (Object.keys(validationErrors).length === 0) { + // If no errors, submit the form + axios.put(`http://localhost:5000/supplier/update/${nic}`, values) + .then((res) => { + console.log("Supplier updated successfully:", res.data); + navigate('/'); + }) + .catch((err) => { + console.error("Error updating supplier:", err); + }); + } else { + // If there are errors, set the errors state + setErrors(validationErrors); + } + } + + return ( +
+
+

Update Supplier Details

+
+
+ + setValues({ ...values, name: e.target.value })} + /> + {errors.name &&
{errors.name}
} +
+
+ + + {errors.nic &&
{errors.nic}
} +
+
+ + setValues({ ...values, address: e.target.value })} + /> + {errors.address &&
{errors.address}
} +
+
+ + setValues({ ...values, mobile: e.target.value })} + /> + {errors.mobile &&
{errors.mobile}
} +
+
+ + setValues({ ...values, email: e.target.value })} + /> + {errors.email &&
{errors.email}
} +
+
+ + setValues({ ...values, wname: e.target.value })} + /> +
+ +
+
+
+ ); +} + +export default UpdateSupplier; From 14daee54a2693d485c75d06e7733b9bc87482f12 Mon Sep 17 00:00:00 2001 From: janiduimesh Date: Fri, 19 Apr 2024 22:52:54 +0530 Subject: [PATCH 7/8] form changes --- frontend/src/supplierComponents/AddOrder.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontend/src/supplierComponents/AddOrder.js b/frontend/src/supplierComponents/AddOrder.js index cdc367c8..f16c009b 100644 --- a/frontend/src/supplierComponents/AddOrder.js +++ b/frontend/src/supplierComponents/AddOrder.js @@ -109,6 +109,7 @@ function AddOrder() { id="supplier" placeholder="Enter Supplier name" value={supplier} + name="supplier" onChange={(e) => setSupplier(e.target.value)} /> {errors.supplier &&
{errors.supplier}
} @@ -130,6 +131,7 @@ function AddOrder() { id="bname" placeholder="Enter Brand Name" value={bname} + name="bname" onChange={(e) => setBname(e.target.value)} /> {errors.bname &&
{errors.bname}
} @@ -142,6 +144,7 @@ function AddOrder() { id="quantity" placeholder="Enter Quantity" value={quantity} + name="quantity" onChange={(e) => setQuantity(e.target.value)} /> {errors.quantity &&
{errors.quantity}
} From b3c6957d0940665a0d948fa582b4ee47787cfa75 Mon Sep 17 00:00:00 2001 From: janiduimesh Date: Wed, 15 May 2024 14:58:13 +0530 Subject: [PATCH 8/8] new new updates --- .../supplierManagement/routes/suppliers.js | 81 +++++++++++++++---- frontend/src/supplierComponents/AddOrder.js | 11 ++- frontend/src/supplierComponents/AddSupp.js | 14 +++- frontend/src/supplierComponents/AllOrders.js | 7 +- frontend/src/supplierComponents/AllSup.js | 10 ++- .../src/supplierComponents/UpdateOrder.js | 9 ++- .../src/supplierComponents/UpdateSupplier.js | 4 +- frontend/src/supplierComponents/sendmail.js | 78 ++++++++++++++++++ 8 files changed, 183 insertions(+), 31 deletions(-) create mode 100644 frontend/src/supplierComponents/sendmail.js diff --git a/backend/supplierManagement/routes/suppliers.js b/backend/supplierManagement/routes/suppliers.js index c77a0dcd..77e6ca9a 100644 --- a/backend/supplierManagement/routes/suppliers.js +++ b/backend/supplierManagement/routes/suppliers.js @@ -1,4 +1,6 @@ const router= require( 'express').Router(); +const nodemailer = require('nodemailer'); +require('dotenv').config(); let supplier=require('../models/supplier') router.route('/add').post((req, res)=>{ @@ -7,7 +9,8 @@ router.route('/add').post((req, res)=>{ const nic =req.body.nic; const address = req.body.address; const mobile = Number(req.body.mobile); - const wname = req.body.wname ; + const email= req.body.email; + const wname = req.body.wname; const newSupplier=new supplier({ @@ -15,17 +18,16 @@ router.route('/add').post((req, res)=>{ nic, address, mobile, + email, wname }) - + newSupplier.save() .then(()=>{ res.json("Supplier added") }).catch((err)=> {res.status(400).send("unable to add Supplier")}) }) -/***************************** */ -//to get all the data from database router.route("/").get((req, res) => { supplier.find().then((suppliers)=>{ @@ -37,17 +39,18 @@ router.route("/").get((req, res) => { }) -//update a specific record in the database + router.route("/update/:nic").put(async(req,res)=>{ let userNic=req.params.nic; - const{name,nic,address,mobile,wname}=req.body; + const{name,nic,address,mobile,email,wname}=req.body; const updateSupplier={ name, nic, address, mobile, + email, wname } const update=await supplier.findOneAndUpdate({ nic: userNic }, updateSupplier, { new: true }); @@ -59,20 +62,28 @@ router.route("/update/:nic").put(async(req,res)=>{ } }) -//delete a specific record from the database -router.route("/delete/:nic").delete(async(req,res)=>{ - let userNic=req.params.nic; - await supplier.findOneAndDelete(userNic).then(()=>{ +router.route("/delete/:nic").delete(async (req, res) => { + try { + const userNic = req.params.nic; + + const deletedSupplier = await supplier.findOneAndDelete({ nic: userNic }); + + if (deletedSupplier) { + res.status(200).send({ status: 'Deleted' }); + + } else { + res.status(404).send({ status: "Supplier not found" }); + } + } catch (err) { + res.status(500).send({ status: "Error in deleting" }); + console.log(err); + } +}); + + - res.status(200).send({status:'Deleted'}); - }).catch((err)=> { - res.status(500).send({status:"Error in deleting"}); - console.log(err); - }) -}) -//get one supplier details router.route("/get/:nic").get(async(req,res)=>{ let userId = req.params.nic; try { @@ -88,4 +99,40 @@ router.route("/get/:nic").get(async(req,res)=>{ return res.status(500).send({ status: "Error in fetch", error: error.message }); } }); + + + +const transporter = nodemailer.createTransport({ + service: 'Gmail', + host: "smtp.gmail.com", + port: 587, + secure: false, + requireTLS: true, + auth: { + user: process.env.GMAIL_USER, + pass: process.env.GMAIL_PASS + } + }); + + router.route("/Sendmail").post(async(req, res) => { + const { name, email, message } = req.body; + + const mailOptions = { + from: process.env.GMAIL_USER, + to: email, + subject: 'New message from your website contact form', + text: `Name: ${name}\nEmail: ${email}\n\nMessage:\n${message}` + }; + + transporter.sendMail(mailOptions, (error, info) => { + if (error) { + console.log(error); + console.error('Error sending email:', error); + res.status(500).send('Error sending email'); + } else { + console.log('Email sent successfully:', info.response); + res.status(200).send('Email sent successfully'); + } + }); + }); module.exports=router; diff --git a/frontend/src/supplierComponents/AddOrder.js b/frontend/src/supplierComponents/AddOrder.js index f16c009b..cd61b4da 100644 --- a/frontend/src/supplierComponents/AddOrder.js +++ b/frontend/src/supplierComponents/AddOrder.js @@ -14,6 +14,7 @@ function AddOrder() { const [selectedDate, setSelectedDate] = useState(new Date()); const [errors, setErrors] = useState({}); const form = useRef(); + // Function to send data to the server @@ -71,7 +72,10 @@ function AddOrder() { const errors = {}; if (!oid.trim()) { errors.oid = "Order ID is required"; + } else if (isNaN(oid.trim())) { + errors.oid = "Order ID must be a number"; } + if (!supplier.trim()) { errors.supplier = "Supplier name is required"; } @@ -80,13 +84,16 @@ function AddOrder() { } if (!quantity.trim()) { errors.quantity = "Quantity is required"; + } else if (parseInt(quantity) <= 0) { + errors.quantity = "Quantity should not be a negative value"; } return errors; }; return ( +
-
+

Add New Order

@@ -121,6 +128,7 @@ function AddOrder() { onChange={date => setSelectedDate(date)} dateFormat="dd/MM/yyyy" className="form-control" + minDate={new Date()} />
@@ -153,6 +161,7 @@ function AddOrder() {
+
); } diff --git a/frontend/src/supplierComponents/AddSupp.js b/frontend/src/supplierComponents/AddSupp.js index f0f21705..4f1c6e69 100644 --- a/frontend/src/supplierComponents/AddSupp.js +++ b/frontend/src/supplierComponents/AddSupp.js @@ -17,10 +17,16 @@ function AddSupp() { const errors = {}; if (!name.trim()) { errors.name = "Name is required"; + } else if (!/^[a-zA-Z\s]+$/.test(name.trim())) { + errors.name = "Name must contain only letters and spaces"; } + if (!nic.trim()) { errors.nic = "NIC is required"; + } else if (!/^\d{12}$/.test(nic)) { + errors.nic = "NIC should be 12 digits"; } + if (!address.trim()) { errors.address = "Address is required"; } @@ -61,8 +67,9 @@ function AddSupp() { } return ( +
-
+

Add New Supplier

@@ -124,7 +131,7 @@ function AddSupp() { type="text" className={`form-control ${errors.email && 'is-invalid'}`} id="name" - placeholder="Enter Mobile" + placeholder="Enter Email" value={email} onChange={(e) => setEmail(e.target.value)} /> @@ -143,10 +150,11 @@ function AddSupp() { /> {errors.wname &&
{errors.wname}
}
- +
+
); } diff --git a/frontend/src/supplierComponents/AllOrders.js b/frontend/src/supplierComponents/AllOrders.js index f6cfc07c..1754d4ff 100644 --- a/frontend/src/supplierComponents/AllOrders.js +++ b/frontend/src/supplierComponents/AllOrders.js @@ -66,13 +66,13 @@ import {useReactToPrint} from "react-to-print";

All Orders

- +
-
+
@@ -81,7 +81,7 @@ import {useReactToPrint} from "react-to-print"; - + @@ -104,6 +104,7 @@ import {useReactToPrint} from "react-to-print";
supllier Date Brand NameQuantityQuantity.
+ ) diff --git a/frontend/src/supplierComponents/AllSup.js b/frontend/src/supplierComponents/AllSup.js index 5a761988..c96bc821 100644 --- a/frontend/src/supplierComponents/AllSup.js +++ b/frontend/src/supplierComponents/AllSup.js @@ -53,17 +53,17 @@ import { Link } from "react-router-dom"; return(
-

All Suppliers

- +

All Suppliers

+
setSearchQuery(e.target.value)} type="text" name="search" placeholder="Search Supplier"> - +
-
+
{noResults ? (
@@ -93,6 +93,8 @@ import { Link } from "react-router-dom"; Edit + Mail + ))} diff --git a/frontend/src/supplierComponents/UpdateOrder.js b/frontend/src/supplierComponents/UpdateOrder.js index 8b056c7b..fb1d38b4 100644 --- a/frontend/src/supplierComponents/UpdateOrder.js +++ b/frontend/src/supplierComponents/UpdateOrder.js @@ -49,7 +49,10 @@ function UpdateOrder() { } if (!values.quantity.toString().trim()) { validationErrors.quantity = "Quantity is required"; + } else if (parseInt(values.quantity) < 0) { + validationErrors.quantity = "Quantity cannot be negative"; } + if (Object.keys(validationErrors).length === 0) { // If no errors, submit the form @@ -69,9 +72,10 @@ function UpdateOrder() { return ( +
-
-

Update Order Details

+
+

Update Order Details

@@ -132,6 +136,7 @@ function UpdateOrder() {
+
); } diff --git a/frontend/src/supplierComponents/UpdateSupplier.js b/frontend/src/supplierComponents/UpdateSupplier.js index 7759bf1e..f3e67298 100644 --- a/frontend/src/supplierComponents/UpdateSupplier.js +++ b/frontend/src/supplierComponents/UpdateSupplier.js @@ -79,8 +79,9 @@ function UpdateSupplier() { } return ( +
-
+

Update Supplier Details

@@ -153,6 +154,7 @@ function UpdateSupplier() {
+
); } diff --git a/frontend/src/supplierComponents/sendmail.js b/frontend/src/supplierComponents/sendmail.js new file mode 100644 index 00000000..8bccd0c9 --- /dev/null +++ b/frontend/src/supplierComponents/sendmail.js @@ -0,0 +1,78 @@ +import React, { useState, useEffect } from "react"; +import axios from "axios"; +import { useNavigate, useParams } from "react-router-dom"; + + +function Sendmail() { + + const { nic } = useParams(); + + const [formData, setFormData] = useState({ + name: '', + nic: nic || "", + email: '', + message: '' + }); + + useEffect(() => { + axios.get(`http://localhost:5000/supplier/get/${nic}`) + .then((res) => { + console.log("Response data:", res.data); + + setFormData({ + ...formData, + name: res.data.order.name, + email: res.data.order.email, + }); + console.log("Updated values:", formData); + }) + .catch((err) => { + console.error("Error fetching supplier:", err); + setFormData({ ...formData, nic: "Error fetching NIC" }); + }); + },[nic]); + + const handleChange = (e) => { + setFormData({ ...formData, [e.target.name]: e.target.value }); + }; + + const handleSubmit = async (e) => { + e.preventDefault(); + try { + await axios.post('http://localhost:5000/supplier/Sendmail', formData); + alert("Email sent successfully!") + console.log('Email sent successfully!'); + + } catch (error) { + console.log(formData); + alert(error) + console.error('Error sending email:', error); + } + }; + + + + return( + + +
+
+
+

Send Mail

+ + + + + + + + +