From 84307de6f7129fb13abc40cb0c7c902cabab7303 Mon Sep 17 00:00:00 2001 From: harshbhar0629 Date: Wed, 30 Oct 2024 12:40:16 +0530 Subject: [PATCH] Adding functionality upload image to cloudinary --- backend/.env.example | 6 +++++- backend/config/cloudinary.js | 18 ++++++++++++++++++ backend/controller/admin.controller.js | 17 +++++++++++++++++ backend/controller/customer.controller.js | 15 +++++++++++++++ backend/index.js | 11 +++++++++++ backend/package.json | 2 ++ backend/utils/imageUploader.js | 17 +++++++++++++++++ frontend/src/components/Pages/Signup.jsx | 9 ++++++++- 8 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 backend/config/cloudinary.js create mode 100644 backend/utils/imageUploader.js diff --git a/backend/.env.example b/backend/.env.example index 8c71fad6..6339d82e 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -8,4 +8,8 @@ GOOGLE_CLIENT_SECRET=your_google_client_secret FRONTEND_URL=your_frontend_url CALLBACK_URL=http://localhost:3000/auth/google/callback PROD_CALLBACK_URL=https://play-cafe.vercel.app/auth/google/callback -NODE_ENV=development \ No newline at end of file +NODE_ENV=development +FOLDER_NAME = "files" +CLOUD_NAME="" +CLOUD_API_KEY="" +CLOUD_SECRET="" \ No newline at end of file diff --git a/backend/config/cloudinary.js b/backend/config/cloudinary.js new file mode 100644 index 00000000..5b928ecc --- /dev/null +++ b/backend/config/cloudinary.js @@ -0,0 +1,18 @@ +/** @format */ + +const cloudinary = require("cloudinary").v2; //! Cloudinary is being required + +exports.cloudinaryConnect = () => { + try { + cloudinary.config({ + // Configuring the Cloudinary to Upload MEDIA + cloud_name: process.env.CLOUD_NAME, + api_key: process.env.CLOUD_API_KEY, + api_secret: process.env.CLOUD_SECRET, + }); + console.log("Cloud connect successfully") + } catch (error) { + console.log("Error in connection of cloud"); + console.log(error.message); + } +}; diff --git a/backend/controller/admin.controller.js b/backend/controller/admin.controller.js index dbd74083..611b28c4 100644 --- a/backend/controller/admin.controller.js +++ b/backend/controller/admin.controller.js @@ -3,6 +3,7 @@ const { z } = require("zod"); const Admin = require("../models/admin.model"); const logger = require("../config/logger"); const jwt = require("jsonwebtoken"); +const {uploadImageToCloudinary} = require("../utils/imageUploader") // Define the schema const adminSchema = z.object({ @@ -26,10 +27,26 @@ async function createAdmin(req, res) { try { const hashedPassword = await bcrypt.hash(req.body.password, 10); + + const { file } = req.body; + let thumbnailImage; + let fileComming = false; + // Upload the Thumbnail to Cloudinary + if (file !== "") { + fileComming = true; + thumbnailImage = await uploadImageToCloudinary( + file, + process.env.FOLDER_NAME + ); + console.log(thumbnailImage); + } + + const admin = new Admin({ name: req.body.name, email: req.body.email, password: hashedPassword, + profilePicture: fileComming? thumbnailImage.secure_url : "null", }); await admin.save(); res.status(201).json({ message: "Admin created successfully" }); diff --git a/backend/controller/customer.controller.js b/backend/controller/customer.controller.js index b6195ece..b076ebbe 100644 --- a/backend/controller/customer.controller.js +++ b/backend/controller/customer.controller.js @@ -5,6 +5,7 @@ const { z } = require("zod"); const Customer = require("../models/customer.model"); const jwt = require("jsonwebtoken"); const { sendRegisterVerificationMail } = require("../config/nodemailer"); +const { uploadImageToCloudinary } = require("../utils/imageUploader"); // Define the schema const customerSchema = z.object({ @@ -29,6 +30,19 @@ async function createCustomer(req, res) { const otp = crypto.randomInt(100000, 999999).toString(); const otpExpiry = new Date(Date.now() + 5 * 60 * 1000); // 5 mins from now + const { file } = req.body; + let fileComming = false; + let thumbnailImage; + if (file !== "") { + fileComming = true; + // Upload the Thumbnail to Cloudinary + thumbnailImage = await uploadImageToCloudinary( + file, + process.env.FOLDER_NAME + ); + console.log(thumbnailImage); + } + const hashedPassword = await bcrypt.hash(req.body.password, 10); const customer = new Customer({ name: req.body.name, @@ -37,6 +51,7 @@ async function createCustomer(req, res) { otp, otpExpiry, isVerified: false, + profilePicture: fileComming? thumbnailImage.secure_url: "null", }); await customer.save(); diff --git a/backend/index.js b/backend/index.js index 5dfeab5a..9b35aef6 100644 --- a/backend/index.js +++ b/backend/index.js @@ -11,6 +11,8 @@ const app = express(); const port = process.env.PORT || 3000; const session = require("express-session"); const MongoStore = require("connect-mongo"); +const fileUpload = require("express-fileupload"); +const { cloudinaryConnect } = require("./config/cloudinary"); // CORS configuration const corsOptions = { @@ -22,6 +24,12 @@ app.use(cors(corsOptions)); app.use(express.json()); app.use('/api', newsletterRoute); +app.use( + fileUpload({ + useTempFiles: true, + tempFileDir: __dirname + "/tmp/", + }) +); // MongoDB connection mongoose @@ -37,6 +45,9 @@ mongoose process.exit(1); }); +// call to cloud setup +cloudinaryConnect(); + // Enable CORS preflight for the create reservation route only // Uncomment if needed // app.options("/api/reservation/create", cors(corsOptions)); diff --git a/backend/package.json b/backend/package.json index 11a318f0..a59711f6 100644 --- a/backend/package.json +++ b/backend/package.json @@ -16,10 +16,12 @@ "description": "", "dependencies": { "bcrypt": "^5.1.1", + "cloudinary": "^2.5.1", "connect-mongo": "^5.1.0", "cors": "^2.8.5", "dotenv": "^16.4.5", "express": "^4.21.0", + "express-fileupload": "^1.5.1", "express-session": "^1.18.1", "jsonwebtoken": "^9.0.2", "mongoose": "^8.7.0", diff --git a/backend/utils/imageUploader.js b/backend/utils/imageUploader.js new file mode 100644 index 00000000..f9d7d18c --- /dev/null +++ b/backend/utils/imageUploader.js @@ -0,0 +1,17 @@ +/** @format */ + +const cloudinary = require("cloudinary").v2; + +exports.uploadImageToCloudinary = async (file, folder, height, quality) => { + const options = { folder }; + if (height) { + options.height = height; + } + if (quality) { + options.quality = quality; + } + + options.resource_type = "auto"; + + return await cloudinary.uploader.upload(file.tempFilePath, options); +}; diff --git a/frontend/src/components/Pages/Signup.jsx b/frontend/src/components/Pages/Signup.jsx index 37498c37..357a37c9 100644 --- a/frontend/src/components/Pages/Signup.jsx +++ b/frontend/src/components/Pages/Signup.jsx @@ -11,7 +11,7 @@ const Signup = () => { const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const [passwordStrength, setPasswordStrength] = useState(0); - const [data, setData] = useState({ name: '', email: '', password: '' }); + const [data, setData] = useState({ name: '', email: '', password: '', file: '' }); const [hidden, setHidden] = useState(true); const handleChange = (e) => { @@ -112,6 +112,13 @@ const Signup = () => { type="text" onChange={handleChange} /> +