diff --git a/server/config/cloudinaryConfig.js b/server/config/cloudinaryConfig.js index cf949e4..e8139fb 100644 --- a/server/config/cloudinaryConfig.js +++ b/server/config/cloudinaryConfig.js @@ -1,14 +1,26 @@ -const config = require("cloudinary").config; -const uploader = require("cloudinary").uploader; -const dotenv = require("dotenv"); +const cloudinary = require('cloudinary').v2; +const dotenv = require('dotenv'); dotenv.config(); const cloudinaryConfig = (req, res, next) => { - config({ + cloudinary.config({ cloud_name: process.env.CLOUDINARY_CLOUD_NAME, api_key: process.env.CLOUDINARY_API_KEY, api_secret: process.env.CLOUDINARY_API_SECRET, }); next(); }; -module.exports = { cloudinaryConfig, uploader }; + +const uploadImage = async (filePath) => { + try { + const result = await cloudinary.uploader.upload(filePath, { + folder: 'canteen_images', // Specify the folder where images should be uploaded + }); + return result; + } catch (error) { + throw new Error('Error uploading image to Cloudinary'); + } +}; + +module.exports = { cloudinaryConfig, uploadImage }; + diff --git a/server/controllers/canteenController.js b/server/controllers/canteenController.js index 41eba08..f3d5b1b 100644 --- a/server/controllers/canteenController.js +++ b/server/controllers/canteenController.js @@ -3,6 +3,7 @@ const Breakfast = require('../models/breakfast'); const Lunch = require('../models/lunch'); const Dinner = require('../models/dinner'); const Canteen = require("../models/canteenLoginInfo"); +const { uploader } = require('../config/cloudinaryConfig'); @@ -180,6 +181,37 @@ const removeDinnerDish = asyncHandler(async (req, res, next) => { res.json({ message: 'Dish removed successfully' }); }); +// Controller function to update canteen details + + +const updateCanteen = async (req, res, next) => { + try { + const canteenId = req.params.id; + const { name, email, collegeName, canteenImage } = req.body; + + // Process the uploaded file if exists + if (req.file) { + const filePath = `public/uploads/${req.file.originalname}`; + const uploadedImage = await uploader.upload(filePath); + req.body.canteenImage = uploadedImage.url; // Update the canteenImage with the uploaded file URL + } + + // Find the canteen by ID and update + const canteen = await Canteen.findByIdAndUpdate(canteenId, req.body, { new: true }); + + // If canteen not found, return error + if (!canteen) { + return res.status(404).json({ success: false, message: "Canteen not found" }); + } + + // Return success response + res.status(200).json({ success: true, message: "Canteen updated successfully", data: canteen }); + } catch (error) { + // Handle errors + console.error("Error updating canteen:", error); + res.status(500).json({ success: false, error: "Internal Server Error" }); + } +}; module.exports = { getCanteenDashboard, @@ -193,4 +225,5 @@ module.exports = { getBreakfast, getLunch, getDinner, + updateCanteen, }; diff --git a/server/middleware/multer.middleware.js b/server/middleware/multer.middleware.js index a385092..a294166 100644 --- a/server/middleware/multer.middleware.js +++ b/server/middleware/multer.middleware.js @@ -1,5 +1,8 @@ -const multer = require("multer"); +const multer = require('multer'); const storage = multer.memoryStorage(); -const multerUploads = multer({ storage }).single("image"); +const multerUploads = multer({ + storage, + limits: { fileSize: 50 * 1024 * 1024 } // Set limit to 50MB +}).single("image"); module.exports = multerUploads; diff --git a/server/models/canteenLoginInfo.js b/server/models/canteenLoginInfo.js index af22b92..d75ac33 100644 --- a/server/models/canteenLoginInfo.js +++ b/server/models/canteenLoginInfo.js @@ -14,15 +14,18 @@ const canteenSchema = new Schema({ type: String, required: true, }, - accountType : { - type : String, - enum : ["User" , "Canteen"], - required : true, + accountType: { + type: String, + enum: ["User", "Canteen"], + required: true, }, password: { type: String, required: true, }, + canteenImage: { + type: String, // Assuming you're storing the URL or base64 string of the image + }, }); const Canteen = mongoose.model('Canteen', canteenSchema); diff --git a/server/routes/canteen.js b/server/routes/canteen.js index e4b574e..28ed8db 100644 --- a/server/routes/canteen.js +++ b/server/routes/canteen.js @@ -4,6 +4,7 @@ const router = express.Router(); // Import canteen controller functions const canteenController = require('../controllers/canteenController'); const { auth, isCanteen } = require('../middlewares/auth'); +const multerUploads = require('../middleware/multer.middleware'); router.get('/getcanteen' , canteenController.getAllCanteen); @@ -37,4 +38,7 @@ router.post('/:id/dinner/add',auth,isCanteen, canteenController.addDinnerDish); // Route to remove a dinner dish for a specific canteen router.delete('/:id/dinner/remove',auth,isCanteen, canteenController.removeDinnerDish); +//router to update profile +router.put('/:id/update', auth, isCanteen, multerUploads, canteenController.updateCanteen); + module.exports = router; diff --git a/server/server.js b/server/server.js index 0339668..df517fb 100644 --- a/server/server.js +++ b/server/server.js @@ -6,7 +6,7 @@ const cors = require("cors"); var cookieParser = require("cookie-parser"); const PORT = process.env.PORT || 4000; const cloudinaryConfig = require("./config/cloudinaryConfig"); - +const bodyParser = require('body-parser'); app.use( cors({ @@ -16,7 +16,8 @@ app.use( app.use(cookieParser()); app.use(express.json()); app.use("*", cloudinaryConfig.cloudinaryConfig); - +app.use(bodyParser.json({ limit: '50mb' })); +app.use(bodyParser.urlencoded({ limit: '50mb', extended: true })); //mounting routes const studentRoutes = require("./routes/student"); const canteenRoutes = require("./routes/canteen"); diff --git a/src/App.js b/src/App.js index f4066a8..c01776a 100644 --- a/src/App.js +++ b/src/App.js @@ -11,6 +11,7 @@ import News from './pages/News'; import NotFound from './pages/NotFound'; import Loader from './components/Loader/Loader'; import { ThemeProvider } from './themeContext'; +import EditProfile from './pages/EditProfile'; const Layout = ({ children }) => { return ( @@ -34,6 +35,7 @@ function App() { } /> } /> } /> + } /> } /> diff --git a/src/components/CanteenCard.jsx b/src/components/CanteenCard.jsx index 302d38a..40669d3 100644 --- a/src/components/CanteenCard.jsx +++ b/src/components/CanteenCard.jsx @@ -1,8 +1,8 @@ import React, { useState } from "react"; import { Link } from "react-router-dom"; -import myHotel from "../assets/myHotel.jpg" +import myHotel from "../assets/myHotel.jpg"; -const CanteenCard = ({ canteen }) => { +const CanteenCard = ({ canteen }) => { const [selectedRecipes, setSelectedRecipes] = useState({}); const handleAddToMenu = (recipeId) => { @@ -13,46 +13,45 @@ const CanteenCard = ({ canteen }) => { }; return ( -
-
- - {canteen.name} - -
-
- -
- {canteen.name} -
-
- - - View Menu - +
+ +
+ {canteen.name} +
+
+ + View Menu + + +
-
); }; diff --git a/src/pages/AddFoodItem.jsx b/src/pages/AddFoodItem.jsx index 476c6ab..2bc0e77 100644 --- a/src/pages/AddFoodItem.jsx +++ b/src/pages/AddFoodItem.jsx @@ -83,10 +83,10 @@ function AddFoodItem() { }; return ( -
+

Add Food Item

diff --git a/src/pages/EditProfile.jsx b/src/pages/EditProfile.jsx new file mode 100644 index 0000000..aa5192d --- /dev/null +++ b/src/pages/EditProfile.jsx @@ -0,0 +1,194 @@ +import React, { useState, useEffect } from 'react'; +import { useParams, useNavigate } from 'react-router-dom'; +import Navbar from '../components/Navbar'; + +const EditProfile = () => { + const { _id } = useParams(); // Assuming you have canteen ID in the URL + const navigate = useNavigate(); // useNavigate hook for navigation + const [edit, setEditable] = useState(false); + const [formData, setFormData] = useState({ + name: '', + email: '', + collegeName: '', + canteenImage: '', // Placeholder for the image URL or base64 string + }); + const [loading, setLoading] = useState(true); + const token = localStorage.getItem("token"); + + const fetchCanteenData = async () => { + try { + const getCanteen = await fetch(`http://localhost:8000/api/v1/getcanteen`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, + }); + const res = await getCanteen.json(); + const canteenData = res.data.find(canteen => canteen._id === _id); + if (canteenData) { + setFormData({ + name: canteenData.name, + email: canteenData.email, + collegeName: canteenData.collegeName, + canteenImage: canteenData.canteenImage || '', // Set the default value or an empty string + }); + } + } catch (error) { + console.error('Error fetching canteen data:', error); + } finally { + setLoading(false); + } + }; + + useEffect(() => { + fetchCanteenData(); + }, [_id]); + + const handleChange = (e) => { + const { name, value } = e.target; + setFormData((prevData) => ({ + ...prevData, + [name]: value, + })); + }; + + const handleImageChange = (e) => { + const file = e.target.files[0]; + if (file) { + const reader = new FileReader(); + reader.onloadend = () => { + setFormData((prevData) => ({ + ...prevData, + canteenImage: reader.result, + })); + }; + reader.readAsDataURL(file); + } + }; + + const handleSubmit = async (e) => { + e.preventDefault(); + try { + const response = await fetch(`http://localhost:8000/api/v1/${_id}/update`, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${token}` + }, + body: JSON.stringify(formData), + }); + const result = await response.json(); + console.log(result); + window.location.reload(); + } catch (error) { + console.error('Error updating profile:', error); + } + }; + + if (loading) { + return
Loading...
; + } + + return ( + <> + +
+

Edit Profile

+ + +
+ + +
+
+ + +
+
+ + +
+
+ + + {formData.canteenImage ? ( + Canteen + ) : ( +

No image available

+ )} +
+
+ {!edit && ( + + )} + {edit && ( + <> + + + + )} +
+ +
+ + ); +}; + +export default EditProfile; diff --git a/src/pages/Login.jsx b/src/pages/Login.jsx index e1fe578..c6901e9 100644 --- a/src/pages/Login.jsx +++ b/src/pages/Login.jsx @@ -32,7 +32,7 @@ function Login() { setLoading(true); // const apiUrl = `${process.env.REACT_APP_BASE_URL}/studentLogin`; - const apiUrl = `http://localhost:3000/api/v1/studentLogin`; + const apiUrl = `${process.env.REACT_APP_BASE_URL}/studentLogin`; // Assuming the response contains a token @@ -60,6 +60,8 @@ function Login() { .post(apiUrl, formData) .then((response) => { setLoading(false); + localStorage.setItem("canteenId", response.data.cantId); + localStorage.setItem("token", response.data.token); toast.success("User Logged in "); navigate( `/section/${response.data.cantId}` diff --git a/src/pages/SectionPage.jsx b/src/pages/SectionPage.jsx index 993a0db..1f57497 100644 --- a/src/pages/SectionPage.jsx +++ b/src/pages/SectionPage.jsx @@ -1,14 +1,15 @@ - import React, { useState, useEffect } from 'react'; -import { useParams } from "react-router-dom"; +import { useParams, useNavigate } from "react-router-dom"; import Modal from '../components/Modal'; import Navbar from '../components/Navbar'; import Loader from '../components/Loader/Loader'; import Footer from '../components/Footer'; import AddFoodItem from './AddFoodItem'; +import EditProfile from './EditProfile'; const SectionPage = () => { const { _id } = useParams(); + const navigate = useNavigate(); const [showModal, setShowModal] = useState(false); const [selectedSection, setSelectedSection] = useState(''); const [formData, setFormData] = useState(null); @@ -16,10 +17,8 @@ const SectionPage = () => { const [selectedLunchRecipes, setSelectedLunchRecipes] = useState([]); const [selectedDinnerRecipes, setSelectedDinnerRecipes] = useState([]); const [loading, setLoading] = useState(false); - const [canteenData, setCanteenData] = useState(); - const getCanteenData = async () => { try { setLoading(true); @@ -33,30 +32,24 @@ const SectionPage = () => { } ); const res = await getCanteen.json(); - setCanteenData(res); - } - catch (error) { + setCanteenData(res.data.find(canteen => canteen._id === _id)); + } catch (error) { console.error(error); - } - finally { + } finally { setLoading(false); } }; + useEffect(() => { getCanteenData(); - }, []) + }, [_id]); const handleSectionClick = (sectionName) => { setSelectedSection(sectionName); setShowModal(true); - }; - const handleFormSubmit = (data) => { - - - // Determine the selected section and update the corresponding state variable if (selectedSection === 'Breakfast') { setSelectedBreakfastRecipes([...selectedBreakfastRecipes, data]); } else if (selectedSection === 'Lunch') { @@ -64,42 +57,31 @@ const SectionPage = () => { } else if (selectedSection === 'Dinner') { setSelectedDinnerRecipes([...selectedDinnerRecipes, data]); } - setFormData(data); - setShowModal(false); // Close the modal after form submission + setShowModal(false); }; return (
-

Select Today's Menu

- { - loading ? ( - - ) : ( - <> - {/*
- - - -
- */} - - - - - ) - } +
+ {loading ? ( + + ) : ( + <> + + + + )} +
); }; export default SectionPage; - diff --git a/src/pages/Signup.jsx b/src/pages/Signup.jsx index 38d9ba3..01b6c62 100644 --- a/src/pages/Signup.jsx +++ b/src/pages/Signup.jsx @@ -86,9 +86,10 @@ function Signup() { ) { if (formData.accountType === "User") { - // const apiUrl = `http://localhost:8000/api/v1/studentSignup`; - const apiUrl = `http://localhost:8000/api/v1/studentSignup`; - try { + // const apiUrl = `${process.env.REACT_APP_BASE_URL}/studentSignup`; + const apiUrl = `${process.env.REACT_APP_BASE_URL}/studentSignup`; + try { + setLoading(true); const response = await axios.post(apiUrl, formData); @@ -102,8 +103,10 @@ function Signup() { setLoading(false); } } else { - const apiUrl = `http://localhost:8000/api/v1/canteenSignup`; - // const apiUrl = `http://localhost:8000/api/v1/canteenSignup`; + + const apiUrl = `${process.env.REACT_APP_BASE_URL}/canteenSignup` + // const apiUrl = `${process.env.REACT_APP_BASE_URL}/canteenSignup`; + try { setLoading(true);