diff --git a/backend/config/cloudinary.js b/backend/config/cloudinary.js new file mode 100644 index 0000000..5b928ec --- /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 dbd7408..611b28c 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 3f494f2..3233712 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 3c597f1..ea991c6 100644 --- a/backend/index.js +++ b/backend/index.js @@ -11,6 +11,10 @@ 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 = { origin: ["http://localhost:5173", "https://play-cafe.vercel.app"], @@ -23,6 +27,12 @@ app.use(cors(corsOptions)); app.use(express.json()); app.use('/api', newsletterRoute); +app.use( + fileUpload({ + useTempFiles: true, + tempFileDir: __dirname + "/tmp/", + }) +); // MongoDB connection mongoose @@ -38,6 +48,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 11a318f..a59711f 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 0000000..f9d7d18 --- /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 37498c3..357a37c 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} /> +