0% found this document useful (0 votes)
24 views83 pages

doc1

Uploaded by

akshayya.sawant
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
24 views83 pages

doc1

Uploaded by

akshayya.sawant
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 83

const express = require('express');

const multer = require('multer');


const mongoose = require('mongoose');
const Product = require('./models/Product');
const cors = require('cors');

const app = express();


app.use(cors());
app.use(express.json());

// Setup multer for image uploads


const storage = multer.diskStorage({
destination: (req, file, cb) => cb(null, 'uploads/'),
filename: (req, file, cb) => cb(null, Date.now() + '-' + file.originalname),
});

const upload = multer({ storage });

// MongoDB connection
mongoose.connect('mongodb://localhost:27017/farmconnect', { useNewUrlParser: true,
useUnifiedTopology: true });

// POST route to add products


app.post('/api/add-product', upload.single('image'), async (req, res) => {
try {
const newProduct = new Product({
name: req.body.name,
description: req.body.description,
price: req.body.price,
category: req.body.category,
quantity: req.body.quantity,
imageUrl: `/uploads/${req.file.filename}`, // Store image path
farmerEmail: req.body.farmerEmail,
});
await newProduct.save();
res.json({ success: true, message: 'Product added successfully!' });
} catch (error) {
console.error(error);
res.json({ success: false, message: 'Error adding product.' });
}
});

// GET route to fetch products by category


app.get('/api/products/:category', async (req, res) => {
try {
const products = await Product.find({ category: req.params.category });
res.json(products);
} catch (error) {
console.error(error);
res.status(500).send('Error fetching products');
}
});

app.listen(5000, () => {
console.log('Server is running on port 5000');
});

const mongoose = require('mongoose');

const productSchema = new mongoose.Schema({


name: String,
description: String,
price: Number,
category: String,
quantity: Number,
imageUrl: String,
farmerEmail: String, // For tracking the farmer
});

module.exports = mongoose.model('Product', productSchema);

import React, { useState } from "react";


import './ProductSellingForm.css';

function ProductSellingPage() {
const [productName, setProductName] = useState("");
const [description, setDescription] = useState("");
const [price, setPrice] = useState("");
const [category, setCategory] = useState("");
const [quantity, setQuantity] = useState("");
const [image, setImage] = useState(null);

const handleSubmit = async (event) => {


event.preventDefault();
const formData = new FormData();
formData.append("name", productName);
formData.append("description", description);
formData.append("price", price);
formData.append("category", category);
formData.append("quantity", quantity);
formData.append("image", image);
formData.append("farmerEmail", "[email protected]"); // Replace with the actual farmer's
email

try {
const response = await fetch("http://localhost:5000/api/add-product", {
method: "POST",
body: formData,
});
const data = await response.json();
if (data.success) {
alert("Product added successfully!");
} else {
alert(data.message);
}
} catch (error) {
console.error("Error uploading product:", error);
}
};

return (
<div className="product-selling-page-container">
<form className="product-selling-form" onSubmit={handleSubmit}>
<h2>Sell Your Product</h2>
<input
type="text"
placeholder="Product Name"
value={productName}
onChange={(e) => setProductName(e.target.value)}
required
/>
<textarea
placeholder="Description"
value={description}
onChange={(e) => setDescription(e.target.value)}
required
/>
<input
type="number"
placeholder="Price"
value={price}
onChange={(e) => setPrice(e.target.value)}
required
/>
<select value={category} onChange={(e) => setCategory(e.target.value)} required>
<option value="">Select Category</option>
<option value="fruits">Fruits</option>
<option value="vegetables">Vegetables</option>
<option value="grains">Grains</option>
<option value="dairy">Dairy</option>
<option value="others">Others</option>
</select>
<input
type="number"
placeholder="Quantity"
value={quantity}
onChange={(e) => setQuantity(e.target.value)}
required
/>
<input
type="file"
accept="image/*"
onChange={(e) => setImage(e.target.files[0])}
required
/>
<button type="submit">Submit Product</button>
</form>
</div>
);
}

export default ProductSellingPage;

import React, { useEffect, useState } from 'react';


import { useParams } from 'react-router-dom';
import './Products.css';

const Products = () => {


const { category } = useParams();
const [products, setProducts] = useState([]);

useEffect(() => {
const fetchProducts = async () => {
const response = await fetch(`http://localhost:5000/api/products/${category}`);
const data = await response.json();
setProducts(data);
};
fetchProducts();
}, [category]);

return (
<div className="products-container">
<h2>{category.charAt(0).toUpperCase() + category.slice(1)} Products</h2>
<div className="products-list">
{products.map((product) => (
<div key={product._id} className="product-card">
<img src={`http://localhost:5000${product.imageUrl}`} alt={product.name} />
<h3>{product.name}</h3>
<p>{product.description}</p>
<p>Price: ₹{product.price}</p>
<p>Quantity: {product.quantity} kg</p>
</div>
))}
</div>
</div>
);
};

export default Products;


const express = require('express');
const mongoose = require('mongoose');
const bcrypt = require('bcrypt');
const bodyParser = require('body-parser');
const cors = require('cors');

// Initialize express
const app = express();
app.use(cors());
app.use(bodyParser.json());

// MongoDB connection
mongoose.connect('mongodb://localhost:27017/farmerswebsite', {
useNewUrlParser: true,
useUnifiedTopology: true,
}).then(() => console.log('MongoDB connected'))
.catch(err => console.log('MongoDB connection error:', err));

// Buyer Schema
const buyerSchema = new mongoose.Schema({
firstName: { type: String, required: true },
lastName: { type: String, required: true },
address: { type: String, required: true },
phoneNumber: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
});

const Buyer = mongoose.model('Buyer', buyerSchema);


// Farmer Schema
const farmerSchema = new mongoose.Schema({
firstName: { type: String, required: true },
lastName: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
});

const Farmer = mongoose.model('Farmer', farmerSchema);

// Password Validation
const validatePassword = (password) => {
const passwordRegex = /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{6,}$/; // At least one letter, one number,
min 6 chars
return passwordRegex.test(password);
};

// Buyer Registration Route


app.post('/api/register', async (req, res) => {
const { firstName, lastName, address, phoneNumber, email, password } = req.body;

try {
// Validate phone number
if (!/^\d{10}$/.test(phoneNumber)) {
return res.status(400).json({ success: false, message: 'Phone number must be exactly 10 digits!' });
}

// Check if the buyer already exists by email


const existingBuyer = await Buyer.findOne({ email });
if (existingBuyer) {
return res.status(400).json({ success: false, message: 'Buyer already exists with this email.' });
}
// Validate password
if (!validatePassword(password)) {
return res.status(400).json({ success: false, message: 'Password must be at least 6 characters long
and contain at least one letter and one number.' });
}

// Hash the password


const hashedPassword = await bcrypt.hash(password, 10);

// Create a new buyer


const newBuyer = new Buyer({ firstName, lastName, address, phoneNumber, email, password:
hashedPassword });

// Save the buyer to the database


await newBuyer.save();
res.status(201).json({ success: true, message: 'Buyer registered successfully!' });
} catch (error) {
console.error('Registration error:', error);
res.status(500).json({ success: false, message: 'Error registering buyer' });
}
});
// Get buyer details by ID
app.get('/api/buyer/:id', async (req, res) => {
try {
const buyer = await Buyer.findById(req.params.id);
if (!buyer) {
return res.status(404).json({ success: false, message: 'Buyer not found' });
}
res.json({ success: true, buyer });
} catch (error) {
console.error('Error fetching buyer details:', error);
res.status(500).json({ success: false, message: 'Error fetching buyer details' });
}
});

// Farmer Registration Route


app.post('/api/farmer-register', async (req, res) => {
const { firstName, lastName, email, password } = req.body;

try {
// Check if the farmer already exists by email
const existingFarmer = await Farmer.findOne({ email });
if (existingFarmer) {
return res.status(400).json({ success: false, message: 'Farmer already exists with this email.' });
}

// Validate password
if (!validatePassword(password)) {
return res.status(400).json({ success: false, message: 'Password must be at least 6 characters long
and contain at least one letter and one number.' });
}

// Hash the password


const hashedPassword = await bcrypt.hash(password, 10);

// Create a new farmer


const newFarmer = new Farmer({ firstName, lastName, email, password: hashedPassword });

// Save the farmer to the database


await newFarmer.save();
res.status(201).json({ success: true, message: 'Farmer registered successfully!' });
} catch (error) {
console.error('Registration error:', error);
res.status(500).json({ success: false, message: 'Error registering farmer' });
}
});
// Buyer Login Route
app.post('/api/login', async (req, res) => {
const { email, password } = req.body;

try {
// Find the buyer by email
const buyer = await Buyer.findOne({ email });
if (!buyer) {
return res.status(400).json({ success: false, message: 'Invalid email or password' });
}

// Check the password


const isMatch = await bcrypt.compare(password, buyer.password);
if (!isMatch) {
return res.status(400).json({ success: false, message: 'Invalid email or password' });
}

res.json({ success: true, message: 'Login successful!', buyer });


} catch (error) {
console.error('Login error:', error);
res.status(500).json({ success: false, message: 'Error logging in' });
}
});

// Farmer Login Route


app.post('/api/farmer-login', async (req, res) => {
const { email, password } = req.body;

try {
// Find the farmer by email
const farmer = await Farmer.findOne({ email });
if (!farmer) {
return res.status(400).json({ success: false, message: 'Invalid email or password' });
}

// Check the password


const isMatch = await bcrypt.compare(password, farmer.password);
if (!isMatch) {
return res.status(400).json({ success: false, message: 'Invalid email or password' });
}

res.json({ success: true, message: 'Login successful!', farmer });


} catch (error) {
console.error('Login error:', error);
res.status(500).json({ success: false, message: 'Error logging in' });
}
});

const Product = require('./models/Product');

// POST route for adding a new product


app.post('/api/products', async (req, res) => {
const { name, description, price, category, quantity, imageUrl, farmerEmail } = req.body;

try {
const newProduct = new Product({ name, description, price, category, quantity, imageUrl,
farmerEmail });
await newProduct.save();
res.status(201).json({ success: true, message: 'Product added successfully' });
} catch (error) {
res.status(500).json({ success: false, message: 'Error adding product' });
}
});
// GET route for retrieving products by category
app.get('/api/products', async (req, res) => {
const { category } = req.query;

try {
const products = await Product.find({ category });
res.json({ success: true, products });
} catch (error) {
res.status(500).json({ success: false, message: 'Error fetching products' });
}
});

// Start the server


const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});

// const express = require('express');


// const mongoose = require('mongoose');
// const bcrypt = require('bcrypt');
// const bodyParser = require('body-parser');
// const cors = require('cors');
// const multer = require('multer');
// const path = require('path');

// // Initialize express
// const app = express();
// app.use(cors());
// app.use(bodyParser.json());
// app.use('/uploads', express.static('uploads')); // Serve static files from the 'uploads' directory
// // MongoDB connection
// mongoose.connect('mongodb://localhost:27017/farmerswebsite', {
// useNewUrlParser: true,
// useUnifiedTopology: true,
// }).then(() => console.log('MongoDB connected'))
// .catch(err => console.log('MongoDB connection error:', err));

// // Setup multer for image upload


// const storage = multer.diskStorage({
// destination: (req, file, cb) => {
// cb(null, './uploads/'); // Directory to save uploaded files
// },
// filename: (req, file, cb) => {
// cb(null, Date.now() + path.extname(file.originalname)); // Name the file with a timestamp
// }
// });

// // Validate file type


// const fileFilter = (req, file, cb) => {
// const filetypes = /jpeg|jpg|png|gif/; // Allow only image files
// const mimetype = filetypes.test(file.mimetype);
// const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
// if (mimetype && extname) {
// return cb(null, true);
// } else {
// cb('Error: File type not supported!', false);
// }
// };

// const upload = multer({


// storage: storage,
// limits: { fileSize: 1024 * 1024 * 5 }, // Limit files to 5MB
// fileFilter: fileFilter
// });

// // Buyer Schema
// const buyerSchema = new mongoose.Schema({
// firstName: { type: String, required: true },
// lastName: { type: String, required: true },
// address: { type: String, required: true },
// phoneNumber: { type: String, required: true },
// email: { type: String, required: true, unique: true },
// password: { type: String, required: true },
// });

// const Buyer = mongoose.model('Buyer', buyerSchema);

// // Farmer Schema
// const farmerSchema = new mongoose.Schema({
// firstName: { type: String, required: true },
// lastName: { type: String, required: true },
// email: { type: String, required: true, unique: true },
// password: { type: String, required: true },
// });

// const Farmer = mongoose.model('Farmer', farmerSchema);

// // Product Schema (includes image path and farmer details)


// const productSchema = new mongoose.Schema({
// name: { type: String, required: true },
// description: { type: String, required: true },
// price: { type: Number, required: true },
// unit: { type: String, required: true },
// category: { type: String, required: true },
// quantity: { type: Number, required: true },
// imageUrl: { type: String, required: true },
// farmerDetails: {
// farmerName: { type: String, required: true },
// location: { type: String, required: true },
// totalArea: { type: String, required: true },
// areaUnderCultivation: { type: String, required: true },
// cropCycle: { type: String, required: true },
// agricultureMethod: { type: String, required: true },
// },
// });

// const Product = mongoose.model('Product', productSchema);

// // POST route for adding a new product (including image upload)


// app.post('/api/products', upload.single('productImage'), async (req, res) => {
// const { name, description, price, unit, category, quantity, farmerDetails } = req.body;
// const imageUrl = req.file.path; // Get the image file path from multer

// try {
// const newProduct = new Product({
// name,
// description,
// price,
// unit,
// category,
// quantity,
// imageUrl,
// farmerDetails: JSON.parse(farmerDetails), // Parse farmerDetails from string
// });
// await newProduct.save();
// res.status(201).json({ success: true, message: 'Product added successfully' });
// } catch (error) {
// res.status(500).json({ success: false, message: 'Error adding product', error });
// }
// });

// // GET route for retrieving products by category


// app.get('/api/products', async (req, res) => {
// const { category } = req.query;

// try {
// const products = await Product.find(category ? { category } : {});
// res.json({ success: true, products });
// } catch (error) {
// res.status(500).json({ success: false, message: 'Error fetching products' });
// }
// });

// // GET route for retrieving products by farmer's email


// app.get('/api/farmer-products', async (req, res) => {
// const { email } = req.query;

// try {
// const products = await Product.find({ 'farmerDetails.email': email });
// res.json({ success: true, products });
// } catch (error) {
// res.status(500).json({ success: false, message: 'Error fetching products' });
// }
// });

// // PUT route for updating a product


// app.put('/api/products/:id', upload.single('productImage'), async (req, res) => {
// const productId = req.params.id;
// const { name, description, price, unit, category, quantity, farmerDetails } = req.body;

// // If an image is uploaded, use the new image; otherwise, keep the old one
// const imageUrl = req.file ? req.file.path : undefined;

// try {
// const product = await Product.findById(productId);

// if (!product) {
// return res.status(404).json({ success: false, message: 'Product not found' });
// }

// // Update product fields only if provided in the request body


// product.name = name || product.name;
// product.description = description || product.description;
// product.price = price || product.price;
// product.unit = unit || product.unit;
// product.category = category || product.category;
// product.quantity = quantity || product.quantity;
// if (imageUrl) product.imageUrl = imageUrl;
// product.farmerDetails = farmerDetails ? JSON.parse(farmerDetails) : product.farmerDetails; //
Parse only if provided

// await product.save();
// res.json({ success: true, message: 'Product updated successfully' });
// } catch (error) {
// res.status(500).json({ success: false, message: 'Error updating product', error });
// }
// });

// // DELETE route for deleting a product


// app.delete('/api/products/:id', async (req, res) => {
// const productId = req.params.id;
// try {
// const deletedProduct = await Product.findByIdAndDelete(productId);

// if (!deletedProduct) {
// return res.status(404).json({ success: false, message: 'Product not found' });
// }

// res.json({ success: true, message: 'Product deleted successfully' });


// } catch (error) {
// res.status(500).json({ success: false, message: 'Error deleting product', error });
// }
// });

// // Centralized error handling middleware


// app.use((err, req, res, next) => {
// console.error(err.stack);
// res.status(500).send({ success: false, message: 'Internal Server Error' });
// });

// // Start the server


// const PORT = process.env.PORT || 5000;
// app.listen(PORT, () => {
// console.log(`Server is running on port ${PORT}`);
// });

// import React, { useRef } from 'react';


// import { useNavigate } from 'react-router-dom';
// import FarmerNavBar from './FarmerNavBar';
// import './FarmerDashboard.css';
// import aboutImage from './assets/farmer.jpg';
// import subscriptionImage from './assets/subscription-image.png';

// const FarmerDashboard = () => {


// const navigate = useNavigate();
// const salesAnalyticsRef = useRef(null);

// const handleLogout = () => {


// navigate('/');
// };

// const handleOrders = () => {


// navigate('/orders');
// };

// const handleSellProducts = () => {


// navigate('/sell');
// };

// const handleSalesAnalytics = () => {


// navigate('/analytics');
// };

// const handleAccount = () => {


// navigate('/account');
// };

// const handleShopNowClick = () => {


// if (salesAnalyticsRef.current) {
// salesAnalyticsRef.current.scrollIntoView({ behavior: 'smooth' });
// }
// };
// return (
// <div className="dashboard-container">
// <FarmerNavBar
// onOrdersClick={handleOrders}
// onSellClick={handleSellProducts}
// onAccountClick={handleAccount}
// onLogout={handleLogout}
// />

// <div className="hero-section">
// <div className="hero-content">
// <h1>Empowering Farmers, Connecting You to Your Market</h1>
// <p>
// Sell your produce, connect with buyers, and grow your business with FarmConnect.
// </p>
// <button className="shop-now-btn" onClick={handleShopNowClick}>Get
Started</button>
// </div>
// </div>

// <div className="featured-categories" ref={salesAnalyticsRef}>


// <h2>Dashboard Categories</h2>
// <div className="categories-container">
// <div className="category">
// <h3>Sell Your Produce</h3>
// <p>Connect directly with buyers and sell your fresh produce with ease.</p>
// <button onClick={handleSellProducts} className="go-to-sell-btn">Go to
Sell</button>
// </div>
// <div className="category">
// <h3>Your Products</h3>
// <p>Manage and showcase your products effectively to attract customers.</p>
// <button onClick={handleSalesAnalytics} className="view-products-btn">View
Products</button>
// </div>
// <div className="category">
// <h3>Your Orders</h3>
// <p>Keep track of all your orders and streamline your sales process.</p>
// <button onClick={handleOrders} className="view-orders-btn">View
Orders</button>
// </div>
// </div>
// </div>

// <div className="about-us-section">
// <div className="about-us-content">
// <h2>About Us</h2>
// <p><b>
// At FarmConnect, we empower farmers to directly connect with consumers,
enhancing their market reach. Our platform ensures that your high-quality agricultural products are
easily accessible, enabling you to grow your business while providing fresh produce to your
community.
// </b></p>
// </div>
// <img src={aboutImage} alt="About Us" className="about-us-image" />
// </div>

// <div className="subscription-section">
// <div className="subscription-content">
// <div className="subscription-image">
// <img src={subscriptionImage} alt="Subscription Benefits" />
// </div>
// <div className="subscription-text">
// <h2>Join Our Subscription Plan</h2>
// <p>Unlock exclusive benefits to maximize your farming potential!</p>
// <ul className="subscription-benefits">
// <li><b>Enjoy special offers on our services and tools.</b></li>
// <li><b>Connect with fellow farmers to share experiences and advice.</b></li>
// <li><b>Receive alerts on market trends to make informed decisions.</b></li>
// <li><b>Gain tools and information that enhance your productivity.</b></li>
// </ul>
// <button className="subscribe-btn">Subscribe Now</button>
// </div>
// </div>
// </div>
// </div>
// );
// };

// export default FarmerDashboard;


To protect the API route and ensure that only the logged-in farmer can access their products, we can
implement authentication and authorization using a middleware in Express. This typically involves
verifying a token (e.g., JWT) to authenticate the user and restricting access to only the appropriate
farmer.
Steps to Implement Route Protection:
1. Install necessary packages: If you're not already using JWT (JSON Web Token) for
authentication, install the required package:
bash
Copy code
npm install jsonwebtoken
2. Create Authentication Middleware: The middleware will verify if a valid token is provided
and if the farmer is authenticated.
js
Copy code
const jwt = require('jsonwebtoken');
const Farmer = require('../models/Farmer'); // Assuming you have a Farmer model

const protect = async (req, res, next) => {


let token;

// Check for token in headers


if (req.headers.authorization && req.headers.authorization.startsWith('Bearer')) {
try {
// Get token from header
token = req.headers.authorization.split(' ')[1];

// Verify token
const decoded = jwt.verify(token, process.env.JWT_SECRET);

// Find the farmer by ID (decoded from the token)


req.user = await Farmer.findById(decoded.id).select('-password'); // Assuming Farmer's ID is
encoded in the token

next();
} catch (error) {
res.status(401).json({ message: 'Not authorized, token failed' });
}
}

if (!token) {
res.status(401).json({ message: 'Not authorized, no token' });
}
};

module.exports = { protect };
3. Add the Middleware to the Protected Route: Now, use this middleware to protect the route
where the farmer fetches their products.
js
Copy code
const { protect } = require('./middleware/authMiddleware');

app.get('/api/farmer/products', protect, async (req, res) => {


try {
const farmerId = req.user._id; // Use the authenticated farmer's ID
const products = await Product.find({ farmerId }); // Fetch products for this farmer
res.json(products);
} catch (error) {
res.status(500).json({ message: 'Server Error' });
}
});
4. Generate JWT when the Farmer Logs In: When a farmer logs in, you should generate a
JWT and send it back to the frontend to be stored (e.g., in localStorage or as a cookie).
Example login controller that generates a JWT:
js
Copy code
const jwt = require('jsonwebtoken');
// Function to generate token
const generateToken = (id) => {
return jwt.sign({ id }, process.env.JWT_SECRET, { expiresIn: '30d' });
};

// Farmer login route (simplified)


app.post('/api/farmer/login', async (req, res) => {
const { email, password } = req.body;

// Find farmer by email


const farmer = await Farmer.findOne({ email });

if (farmer && (await farmer.matchPassword(password))) {


res.json({
_id: farmer._id,
name: farmer.name,
email: farmer.email,
token: generateToken(farmer._id), // Return token
});
} else {
res.status(401).json({ message: 'Invalid email or password' });
}
});
5. Store the Token on the Frontend: When the farmer logs in, you should store the token in
localStorage or a cookie. This token is then sent in the Authorization header of every request
to protected routes.
Example using axios to set the token in headers:
jsx
Copy code
import axios from 'axios';

const loginFarmer = async (email, password) => {


const config = {
headers: {
'Content-Type': 'application/json',
},
};

const { data } = await axios.post('/api/farmer/login', { email, password }, config);

localStorage.setItem('farmerToken', data.token); // Store token in localStorage


};

// Example of sending token with the request for products


const fetchFarmerProducts = async () => {
const token = localStorage.getItem('farmerToken');

const config = {
headers: {
Authorization: `Bearer ${token}`, // Send token in the Authorization header
},
};

const { data } = await axios.get('/api/farmer/products', config);


return data;
};
6. Frontend Token Handling: On the frontend, when the farmer is logged in, you will use the
token stored in localStorage to authenticate and fetch the farmer-specific data:
jsx
Copy code
useEffect(() => {
const fetchProducts = async () => {
try {
const token = localStorage.getItem('farmerToken');
const config = {
headers: {
Authorization: `Bearer ${token}`,
},
};
const response = await axios.get('/api/farmer/products', config);
setProducts(response.data);
} catch (error) {
console.error("Error fetching farmer's products", error);
}
};

fetchProducts();
}, []);
Explanation:
 Backend:
o The protect middleware checks if a valid token is present in the request's
Authorization header.
o If valid, the middleware decodes the token to get the farmer's ID and attaches it to the
request object (req.user).
o The route handler for fetching products then uses the farmer's ID to retrieve only the
farmer's products.
 Frontend:
o The token is stored after the farmer logs in.

o When fetching products for the farmer, the token is included in the request headers,
ensuring only authorized farmers can access their data.
By implementing this protection, only authenticated farmers can view their products on the "Your
Products" page.
const express = require('express');

const mongoose = require('mongoose');

const bcrypt = require('bcrypt');

const bodyParser = require('body-parser');

const cors = require('cors');

// Initialize express

const app = express();

app.use(cors());

app.use(bodyParser.json());

// MongoDB connection

mongoose.connect('mongodb://localhost:27017/farmerswebsite', {

useNewUrlParser: true,

useUnifiedTopology: true,

}).then(() => console.log('MongoDB connected'))

.catch(err => console.log('MongoDB connection error:', err));

// Buyer Schema

const buyerSchema = new mongoose.Schema({

firstName: { type: String, required: true },

lastName: { type: String, required: true },

address: { type: String, required: true },

phoneNumber: { type: String, required: true },

email: { type: String, required: true, unique: true },

password: { type: String, required: true },

});

const Buyer = mongoose.model('Buyer', buyerSchema);

// Farmer Schema

const farmerSchema = new mongoose.Schema({


firstName: { type: String, required: true },

lastName: { type: String, required: true },

email: { type: String, required: true, unique: true },

password: { type: String, required: true },

});

const Farmer = mongoose.model('Farmer', farmerSchema);

// Password Validation

const validatePassword = (password) => {

const passwordRegex = /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{6,}$/; // At least one letter, one number, min 6


chars

return passwordRegex.test(password);

};

// Buyer Registration Route

app.post('/api/register', async (req, res) => {

const { firstName, lastName, address, phoneNumber, email, password } = req.body;

try {

// Validate phone number

if (!/^\d{10}$/.test(phoneNumber)) {

return res.status(400).json({ success: false, message: 'Phone number must be exactly 10 digits!' });

// Check if the buyer already exists by email

const existingBuyer = await Buyer.findOne({ email });

if (existingBuyer) {

return res.status(400).json({ success: false, message: 'Buyer already exists with this email.' });

// Validate password

if (!validatePassword(password)) {

return res.status(400).json({ success: false, message: 'Password must be at least 6 characters long and
contain at least one letter and one number.' });
}

// Hash the password

const hashedPassword = await bcrypt.hash(password, 10);

// Create a new buyer

const newBuyer = new Buyer({ firstName, lastName, address, phoneNumber, email, password:
hashedPassword });

// Save the buyer to the database

await newBuyer.save();

res.status(201).json({ success: true, message: 'Buyer registered successfully!' });

} catch (error) {

console.error('Registration error:', error);

res.status(500).json({ success: false, message: 'Error registering buyer' });

});

// Get buyer details by ID

app.get('/api/buyer/:id', async (req, res) => {

try {

const buyer = await Buyer.findById(req.params.id);

if (!buyer) {

return res.status(404).json({ success: false, message: 'Buyer not found' });

res.json({ success: true, buyer });

} catch (error) {

console.error('Error fetching buyer details:', error);

res.status(500).json({ success: false, message: 'Error fetching buyer details' });

});

// Farmer Registration Route

app.post('/api/farmer-register', async (req, res) => {

const { firstName, lastName, email, password } = req.body;


try {

// Check if the farmer already exists by email

const existingFarmer = await Farmer.findOne({ email });

if (existingFarmer) {

return res.status(400).json({ success: false, message: 'Farmer already exists with this email.' });

// Validate password

if (!validatePassword(password)) {

return res.status(400).json({ success: false, message: 'Password must be at least 6 characters long and
contain at least one letter and one number.' });

// Hash the password

const hashedPassword = await bcrypt.hash(password, 10);

// Create a new farmer

const newFarmer = new Farmer({ firstName, lastName, email, password: hashedPassword });

// Save the farmer to the database

await newFarmer.save();

res.status(201).json({ success: true, message: 'Farmer registered successfully!' });

} catch (error) {

console.error('Registration error:', error);

res.status(500).json({ success: false, message: 'Error registering farmer' });

});

// Buyer Login Route

app.post('/api/login', async (req, res) => {

const { email, password } = req.body;

try {
// Find the buyer by email

const buyer = await Buyer.findOne({ email });

if (!buyer) {

return res.status(400).json({ success: false, message: 'Invalid email or password' });

// Check the password

const isMatch = await bcrypt.compare(password, buyer.password);

if (!isMatch) {

return res.status(400).json({ success: false, message: 'Invalid email or password' });

res.json({ success: true, message: 'Login successful!', buyer });

} catch (error) {

console.error('Login error:', error);

res.status(500).json({ success: false, message: 'Error logging in' });

});

// Farmer Login Route

app.post('/api/farmer-login', async (req, res) => {

const { email, password } = req.body;

try {

// Find the farmer by email

const farmer = await Farmer.findOne({ email });

if (!farmer) {

return res.status(400).json({ success: false, message: 'Invalid email or password' });

// Check the password

const isMatch = await bcrypt.compare(password, farmer.password);

if (!isMatch) {

return res.status(400).json({ success: false, message: 'Invalid email or password' });


}

res.json({ success: true, message: 'Login successful!', farmer });

} catch (error) {

console.error('Login error:', error);

res.status(500).json({ success: false, message: 'Error logging in' });

});

// Start the server

const PORT = process.env.PORT || 5000;

app.listen(PORT, () => {

console.log(`Server is running on port ${PORT}`);

});
Cart.css

/* Cart.css */

/* General styling for the cart page container */

.cart-page-container {

padding: 20px;

max-width: 800px;

margin: auto;

background-color: #f9f9f9;

border-radius: 8px;

box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);

.cart-page-container h1 {

text-align: center;

color: #333;

margin-bottom: 20px;

.cart-items {

display: flex;

flex-direction: column;

/* Individual cart item styling */

.cart-item {

display: flex;

background-color: #fff;

border: 1px solid #ddd;

border-radius: 5px;

padding: 15px;

margin-bottom: 15px;
transition: transform 0.3s ease, box-shadow 0.3s ease;

/* Scale effect on hover */

.cart-item:hover {

transform: scale(1.02);

box-shadow: 0 8px 25px rgba(0, 0, 0, 0.2);

/* Image styling within the cart item */

.cart-item-image {

width: 100px; /* Fixed width for the image */

height: auto; /* Maintain aspect ratio */

margin-right: 20px; /* Space between image and text */

border-radius: 4px; /* Rounded corners for image */

/* Cart item details styling */

.cart-item-details {

flex: 1; /* Allow details to take up remaining space */

/* Button styling */

.cart-item button {

background-color: #ff3d00; /* Eye-catching color for remove button */

color: white; /* White text for contrast */

border: none; /* No border */

padding: 10px 15px; /* Spacing inside button */

border-radius: 5px; /* Rounded corners */

cursor: pointer; /* Pointer cursor on hover */

transition: background-color 0.3s ease; /* Smooth transition for background color */

/* Change button color on hover */


.cart-item button:hover {

background-color: #e63900; /* Darker shade on hover */

/* Styling for empty cart message */

.cart-page-container p {

text-align: center; /* Centered text for empty cart message */

color: #666; /* Grey color for subtlety */

font-size: 18px; /* Larger font for emphasis */

/* Add this to your existing Cart.css */

/* Styling for quantity controls */

.quantity-controls {

display: flex; /* Use flexbox for layout */

align-items: center; /* Center items vertically */

margin: 10px 0; /* Space above and below the controls */

/* Button styling for quantity controls */

.quantity-controls button {

background-color: #007bff; /* Bootstrap primary color */

color: white; /* White text for contrast */

border: none; /* No border */

padding: 8px 12px; /* Spacing inside button */

border-radius: 5px; /* Rounded corners */

cursor: pointer; /* Pointer cursor on hover */

transition: background-color 0.3s ease; /* Smooth transition for background color */

margin: 0 5px; /* Spacing between buttons */

/* Change button color on hover */

.quantity-controls button:hover {

background-color: #0056b3; /* Darker shade on hover */


}

/* Ensure images are properly visible */

.cart-item-image {

width: 120px; /* Adjusted width for better visibility */

height: auto; /* Maintain aspect ratio */

margin-right: 20px; /* Space between image and text */

border-radius: 4px; /* Rounded corners for image */

object-fit: cover; /* Ensures the image fits well within the container */

Farmer login

import React, { useState } from 'react';

import { useNavigate } from 'react-router-dom'; // for redirecting after login

import farmerLoginBackground from './assets/farmerpagebck.jpg'; // Import your background image

import { toast, ToastContainer } from 'react-toastify'; // Import toast for notifications

import 'react-toastify/dist/ReactToastify.css'; // Toastify styles

const FarmerLogin = () => {

const [email, setEmail] = useState('');

const [password, setPassword] = useState('');

const [loading, setLoading] = useState(false);

const [error, setError] = useState('');

const navigate = useNavigate();

// const handleLogin = async (e) => {

// e.preventDefault();

// // Basic email validation

// if (!/\S+@\S+\.\S+/.test(email)) {

// setErrorMessage('Invalid email address');

// return;

// }
// setErrorMessage('');

// setLoading(true);

const handleLogin = async (e) => {

e.preventDefault();

try {

const response = await fetch('http://localhost:5000/api/farmer-login', {

method: 'POST',

headers: { 'Content-Type': 'application/json' },

body: JSON.stringify({ email, password }),

});

const data = await response.json();

if (data.success) {

localStorage.setItem('token', data.token); // Store JWT token

localStorage.setItem('farmer', JSON.stringify(data.farmer)); // Store farmer details

toast.success('Login successful!', { position: "top-center", autoClose: 2000 });

setTimeout(() => navigate('/farmer-dashboard'), 2000); // Redirect to dashboard

} else {

setError('Invalid email or password');

} catch (error) {

console.error(error);

setError('An error occurred during login');

};

// try {

// // Call the correct farmer login API endpoint

// const response = await fetch('http://localhost:5000/api/farmer-login', {

// method: 'POST',

// headers: {

// 'Content-Type': 'application/json',
// },

// body: JSON.stringify({ email, password }),

// });

// const data = await response.json();

// if (response.ok) {

// // Show success toast

// toast.success('Login successful!', { position: "top-center", autoClose: 2000 });

// console.log('Farmer Login:', data); // Log response data for debugging

// // Store the token in localStorage

// localStorage.setItem('farmerToken', data.token);

// // Store farmer info in localStorage (optional)

// localStorage.setItem('farmer', JSON.stringify(data.farmer));

// // Redirect to farmer dashboard on successful login

// navigate('/farmer-dashboard');

// } else {

// // If response is not OK, show an error

// setErrorMessage(data.message || 'Login failed');

// }

// } catch (error) {

// console.error('Login error:', error); // Log error for debugging

// setErrorMessage('An error occurred. Please try again.');

// // } finally {

// // setLoading(false);

// // }

// };

return (

<div

style={{
position: 'relative',

display: 'flex',

flexDirection: 'column',

justifyContent: 'center',

alignItems: 'center',

height: '100vh',

backgroundImage: `url(${farmerLoginBackground})`,

backgroundSize: 'cover',

backgroundPosition: 'center',

backgroundRepeat: 'no-repeat',

}}

>

<div

style={{

position: 'absolute',

top: 0,

left: 0,

width: '100%',

height: '100%',

backgroundColor: 'rgba(0, 0, 0, 0.5)', // Semi-transparent overlay

zIndex: 1,

}}

></div>

<div

style={{

position: 'relative',

zIndex: 2,

textAlign: 'center',

color: '#fff',

fontFamily: 'Cooper Black',

}}

>

<h2
style={{

fontSize: '32px',

marginBottom: '20px',

textShadow: '2px 2px 4px rgba(0, 0, 0, 0.5)',

}}

>

Farmer Login

</h2>

<form

onSubmit={handleLogin}

style={{

display: 'flex',

flexDirection: 'column',

alignItems: 'center',

}}

>

<input

type="email"

placeholder="Email"

value={email}

onChange={(e) => setEmail(e.target.value)}

style={{

margin: '10px',

padding: '10px',

width: '300px',

borderRadius: '5px',

border: '1px solid #ccc',

boxShadow: '0px 2px 4px rgba(0, 0, 0, 0.1)',

backgroundColor: '#fff',

}}

required

/>

<input
type="password"

placeholder="Password"

value={password}

onChange={(e) => setPassword(e.target.value)}

style={{

margin: '10px',

padding: '10px',

width: '300px',

borderRadius: '5px',

border: '1px solid #ccc',

boxShadow: '0px 2px 4px rgba(0, 0, 0, 0.1)',

backgroundColor: '#fff',

}}

required

/>

{errorMessage && (

<p

style={{

color: 'red',

marginTop: '10px',

}}

>

{errorMessage}

</p>

)}

<button

type="submit"

style={{

width: '300px',

padding: '12px',

fontSize: '24px',

backgroundColor: loading ? '#94d3a2' : '#38a169',


color: 'white',

border: 'none',

borderRadius: '5px',

cursor: loading ? 'not-allowed' : 'pointer',

transition: 'background-color 0.3s',

boxShadow: '0px 4px 6px rgba(0, 0, 0, 0.1)',

fontFamily: 'Segoe UI Black',

}}

disabled={loading}

>

{loading ? 'Logging in...' : 'Login'}

</button>

</form>

<ToastContainer /> {/* Added ToastContainer for toast notifications */}

</div>

</div>

);

};

export default FarmerLogin;

farmer and buyer login

// // Buyer Login Route

// app.post('/api/login', async (req, res) => {

// const { email, password } = req.body;

// try {

// // Find the buyer by email

// const buyer = await Buyer.findOne({ email });

// if (!buyer) {

// return res.status(400).json({ success: false, message: 'Invalid email or password' });

// }
// // Check the password

// const isMatch = await bcrypt.compare(password, buyer.password);

// if (!isMatch) {

// return res.status(400).json({ success: false, message: 'Invalid email or password' });

// }

// res.json({ success: true, message: 'Login successful!', buyer });

// } catch (error) {

// console.error('Login error:', error);

// res.status(500).json({ success: false, message: 'Error logging in' });

// }

// });

// // Farmer Login Route

// app.post('/api/farmer-login', async (req, res) => {

// const { email, password } = req.body;

// try {

// // Find the farmer by email

// const farmer = await Farmer.findOne({ email });

// if (!farmer) {

// return res.status(400).json({ success: false, message: 'Invalid email or password' });

// }

// // Check the password

// const isMatch = await bcrypt.compare(password, farmer.password);

// if (!isMatch) {

// return res.status(400).json({ success: false, message: 'Invalid email or password' });

// }

// res.json({ success: true, message: 'Login successful!', farmer });

// } catch (error) {
// console.error('Login error:', error);

// res.status(500).json({ success: false, message: 'Error logging in' });

// }

// });

Product selling page

import React, { useState } from "react";

import './ProductSellingPage.css';

function ProductSellingPage() {

const [productName, setProductName] = useState("");

const [description, setDescription] = useState("");

const [price, setPrice] = useState("");

const [category, setCategory] = useState("");

const [quantity, setQuantity] = useState("");

const [unit, setUnit] = useState(""); // New field for kg/dozen

const [imageFile, setImageFile] = useState(null);

// State for farmer details

const [farmerDetails, setFarmerDetails] = useState({

farmerName: "",

location: "",

totalArea: "",

areaUnderCultivation: "",

cropCycle: "",

agricultureMethod: "",

});

const handleImageUpload = (e) => {

setImageFile(e.target.files[0]); // Store image file

};

const handleFarmerDetailsChange = (e) => {

const { name, value } = e.target;


setFarmerDetails((prevDetails) => ({ ...prevDetails, [name]: value }));

};

// const handleSubmit = async (e) => {

// e.preventDefault();

// const formData = new FormData();

// formData.append("name", productName);

// formData.append("description", description);

// formData.append("price", price);

// formData.append("category", category);

// formData.append("quantity", quantity);

// formData.append("unit", unit); // Append unit (kg or dozen)

// formData.append("productImage", imageFile); // Append image file

// formData.append("farmerDetails", JSON.stringify(farmerDetails)); // Append farmer details as string

// try {

// const response = await fetch("http://localhost:5000/api/products", {

// method: "POST",

// body: formData, // Send form data

// });

// const data = await response.json();

// if (data.success) {

// alert("Product added successfully!");

// } else {

// alert("Failed to add product.");

// }

// } catch (error) {

// console.error("Error adding product:", error);

// }

// };

const handleSubmit = async (e) => {

e.preventDefault();
const formData = new FormData();

formData.append("name", productName);

formData.append("description", description);

formData.append("price", price);

formData.append("category", category);

formData.append("quantity", quantity);

formData.append("unit", unit);

formData.append("productImage", imageFile);

formData.append("farmerDetails", JSON.stringify(farmerDetails));

try {

const token = 'your_jwt_secret'; // Retrieve your token from local storage or context

const response = await fetch("http://localhost:5000/api/products", {

method: "POST",

headers: {

'Authorization': `Bearer ${token}`, // Include the token in the request headers

},

body: formData,

});

const data = await response.json();

if (data.success) {

alert("Product added successfully!");

} else {

alert("Failed to add product.");

} catch (error) {

console.error("Error adding product:", error);

};

return (

<div className="product-selling-page-container">

<div className="form-container">

<form className="product-selling-form" onSubmit={handleSubmit}>


<h2>Sell Your Product</h2>

<label>Product Name:</label>

<input

type="text"

placeholder="Enter product name"

value={productName}

onChange={(e) => setProductName(e.target.value)}

required

/>

<label>Description:</label>

<textarea

placeholder="Enter product description"

value={description}

onChange={(e) => setDescription(e.target.value)}

required

/>

<label>Price (in ₹):</label>

<input

type="number"

placeholder="Enter product price"

value={price}

onChange={(e) => setPrice(e.target.value)}

required

/>

<label>Category:</label>

<select

value={category}

onChange={(e) => setCategory(e.target.value)}

required

>
<option value="">Select Category</option>

<option value="fruits">Fruits</option>

<option value="vegetables">Vegetables</option>

<option value="grains">Grains</option>

</select>

<label>Quantity:</label>

<input

type="number"

placeholder="Enter available quantity"

value={quantity}

onChange={(e) => setQuantity(e.target.value)}

required

/>

<label>Unit:</label>

<select

value={unit}

onChange={(e) => setUnit(e.target.value)}

required

>

<option value="">Select Unit</option>

<option value="kg">Kilogram (kg)</option>

<option value="dozen">Dozen</option>

</select>

<label>Upload Product Image:</label>

<input

type="file"

accept="image/*"

onChange={handleImageUpload}

required

/>
<button type="submit" className="submit-button">

Submit Product

</button>

</form>

<form className="farmer-details-form">

<h2>Farmer Details</h2>

<label>Farmer Name:</label>

<input

type="text"

name="farmerName"

placeholder="Enter farmer name"

value={farmerDetails.farmerName}

onChange={handleFarmerDetailsChange}

required

/>

<label>Location:</label>

<input

type="text"

name="location"

placeholder="Enter location"

value={farmerDetails.location}

onChange={handleFarmerDetailsChange}

required

/>

<label>Total Area:</label>

<input

type="text"

name="totalArea"

placeholder="Enter total area"

value={farmerDetails.totalArea}
onChange={handleFarmerDetailsChange}

required

/>

<label>Area Under Cultivation:</label>

<input

type="text"

name="areaUnderCultivation"

placeholder="Enter area under cultivation"

value={farmerDetails.areaUnderCultivation}

onChange={handleFarmerDetailsChange}

required

/>

<label>Crop Cycle:</label>

<input

type="text"

name="cropCycle"

placeholder="Enter crop cycle"

value={farmerDetails.cropCycle}

onChange={handleFarmerDetailsChange}

required

/>

<label>Agriculture Method:</label>

<input

type="text"

name="agricultureMethod"

placeholder="Enter agriculture method"

value={farmerDetails.agricultureMethod}

onChange={handleFarmerDetailsChange}

required

/>

</form>
</div>

</div>

);

export default ProductSellingPage;

// import React, { useState, useContext } from "react";

// import { ProductContext } from './ProductContext'; // Importing the context

// import { useNavigate } from 'react-router-dom'; // For navigation

// import './ProductSellingPage.css';

// function ProductSellingPage() {

// const { addProduct } = useContext(ProductContext); // Accessing addProduct from context

// const navigate = useNavigate(); // For navigating after submission

// const [productName, setProductName] = useState("");

// const [description, setDescription] = useState("");

// const [price, setPrice] = useState("");

// const [category, setCategory] = useState("");

// const [quantity, setQuantity] = useState("");

// const [unit, setUnit] = useState("");

// const [imageFile, setImageFile] = useState(null);

// const [farmerDetails, setFarmerDetails] = useState({

// farmerName: "",

// location: "",

// totalArea: "",

// areaUnderCultivation: "",

// cropCycle: "",

// agricultureMethod: "",

// });

// const handleImageUpload = (e) => {


// setImageFile(e.target.files[0]);

// };

// const handleFarmerDetailsChange = (e) => {

// const { name, value } = e.target;

// setFarmerDetails((prevDetails) => ({ ...prevDetails, [name]: value }));

// };

// const handleSubmit = async (e) => {

// e.preventDefault();

// const newProduct = {

// id: Date.now(),

// productName,

// description,

// price,

// category,

// quantity,

// unit,

// imageFile,

// farmerDetails

// };

// addProduct(newProduct); // Add the product to the global state

// navigate('/analytics'); // Redirect to Analytics page

// };

// return (

// <div className="product-selling-page-container">

// <div className="form-container">

// <form className="product-selling-form" onSubmit={handleSubmit}>

// <h2>Sell Your Product</h2>

// {/* Same product form */}


// {/* ... */}

// <button type="submit" className="submit-button">

// Submit Product

// </button>

// </form>

// </div>

// </div>

// );

// }

// export default ProductSellingPage;

// Add item to cart

app.post('/api/cart', async (req, res) => {

const { productId, quantity, buyerId } = req.body;

const existingCartItem = await CartItem.findOne({ productId, buyerId });

if (existingCartItem) {

existingCartItem.quantity += quantity;

await existingCartItem.save();

} else {

const newCartItem = new CartItem({ productId, quantity, buyerId });

await newCartItem.save();

res.status(201).json({ success: true, message: 'Item added to cart' });

});

// Get cart items for a buyer

app.get('/api/cart/:buyerId', async (req, res) => {

const cartItems = await CartItem.find({ buyerId: req.params.buyerId }).populate('productId');

res.json({ success: true, cartItems });

});

// Remove item from cart


app.delete('/api/cart/:id', async (req, res) => {

await CartItem.findByIdAndDelete(req.params.id);

res.json({ success: true, message: 'Item removed from cart' });

});

import React, { useEffect, useState } from 'react';

import { useNavigate } from 'react-router-dom';

import './Cart.css'; // CSS for styling the cart page

import { ToastContainer, toast } from 'react-toastify';

import 'react-toastify/dist/ReactToastify.css';

import BuyerNavBar from './BuyerNavBar';

const Cart = () => {

const [cartItems, setCartItems] = useState([]);

const navigate = useNavigate();

// Load cart items from localStorage

useEffect(() => {

const items = JSON.parse(localStorage.getItem('cartItems')) || [];

setCartItems(items);

}, []);

// Function to remove item from cart

const removeFromCart = (id) => {

const updatedItems = cartItems.filter(item => item._id !== id);

setCartItems(updatedItems);

localStorage.setItem('cartItems', JSON.stringify(updatedItems));

toast.success('Item removed from cart!', {

position: 'top-right',

autoClose: 3000,

hideProgressBar: false,

closeOnClick: true,

pauseOnHover: true,

draggable: true,

progress: undefined,
});

};

// Function to update quantity

const updateQuantity = (id, newQuantity) => {

if (newQuantity < 1) return; // Prevent negative quantity

const updatedItems = cartItems.map(item =>

item._id === id ? { ...item, quantity: newQuantity } : item

);

setCartItems(updatedItems);

localStorage.setItem('cartItems', JSON.stringify(updatedItems));

};

return (

<>

<BuyerNavBar

onWishlistClick={() => navigate('/wishlist')}

onCartClick={() => navigate('/cart')}

onAccountClick={() => navigate('/account')}

onLogout={() => navigate('/buyer-login')}

/>

<div className="cart-page-container">

<h1>Your Cart</h1>

{cartItems.length === 0 ? (

<p>Your cart is empty.</p>

):(

<div className="cart-items">

{cartItems.map(item => (

<div key={item._id} className="cart-item">

<img src={`http://localhost:5000/${item.imageUrl}`} alt={item.name} className="cart-


item-image" />

<div className="cart-item-details">

<h3>{item.name}</h3>

<p>Price: ₹{item.price} / {item.unit}</p>


<div className="quantity-controls">

<button onClick={() => updateQuantity(item._id, item.quantity - 1)}>-</button>

<span>{item.quantity}</span>

<button onClick={() => updateQuantity(item._id, item.quantity + 1)}>+</button>

</div>

<button onClick={() => removeFromCart(item._id)}>Remove</button>

</div>

</div>

))}

</div>

)}

<ToastContainer />

</div>

</>

);

};

export default Cart;


const express = require('express');

const mongoose = require('mongoose');

const bcrypt = require('bcrypt');

const bodyParser = require('body-parser');

const cors = require('cors');

const multer = require('multer');

const path = require('path');

// Initialize express

const app = express();

app.use(cors());

app.use(bodyParser.json());

app.use('/uploads', express.static('uploads')); // Serve static files from the 'uploads' directory

//MongoDB connection

mongoose.connect('mongodb://localhost:27017/farmerswebsite', {

useNewUrlParser: true,

useUnifiedTopology: true,

}).then(() => console.log('MongoDB connected'))

.catch(err => console.log('MongoDB connection error:', err));

// Setup multer for image upload

const storage = multer.diskStorage({

destination: (req, file, cb) => {

cb(null, './uploads/'); // Directory to save uploaded files

},

filename: (req, file, cb) => {

cb(null, Date.now() + path.extname(file.originalname)); // Name the file with a timestamp

}
});

// Validate file type

const fileFilter = (req, file, cb) => {

const filetypes = /jpeg|jpg|png|gif/; // Allow only image files

const mimetype = filetypes.test(file.mimetype);

const extname = filetypes.test(path.extname(file.originalname).toLowerCase());

if (mimetype && extname) {

return cb(null, true);

} else {

cb('Error: File type not supported!', false);

};

const upload = multer({

storage: storage,

limits: { fileSize: 1024 * 1024 * 5 }, // Limit files to 5MB

fileFilter: fileFilter

});

// Buyer Schema

const buyerSchema = new mongoose.Schema({

firstName: { type: String, required: true },

lastName: { type: String, required: true },

address: { type: String, required: true },

phoneNumber: { type: String, required: true },

email: { type: String, required: true, unique: true },

password: { type: String, required: true },

});

const Buyer = mongoose.model('Buyer', buyerSchema);

// Farmer Schema

const farmerSchema = new mongoose.Schema({

firstName: { type: String, required: true },


lastName: { type: String, required: true },

email: { type: String, required: true, unique: true },

password: { type: String, required: true },

});

const Farmer = mongoose.model('Farmer', farmerSchema);

// Product Schema (includes image path and farmer details)

const productSchema = new mongoose.Schema({

name: { type: String, required: true },

description: { type: String, required: true },

price: { type: Number, required: true },

unit: { type: String, required: true },

category: { type: String, required: true },

quantity: { type: Number, required: true },

imageUrl: { type: String, required: true },

farmerDetails: {

farmerName: { type: String, required: true },

location: { type: String, required: true },

totalArea: { type: String, required: true },

areaUnderCultivation: { type: String, required: true },

cropCycle: { type: String, required: true },

agricultureMethod: { type: String, required: true },

},

});

const Product = mongoose.model('Product', productSchema);

// Cart Schema

const cartSchema = new mongoose.Schema({

userId: { type: mongoose.Schema.Types.ObjectId, ref: 'Buyer', required: true },

items: [

{
productId: { type: mongoose.Schema.Types.ObjectId, ref: 'Product', required: true },

name: { type: String, required: true },

price: { type: Number, required: true },

quantity: { type: Number, required: true },

imageUrl: { type: String, required: true }

});

const Cart = mongoose.model('Cart', cartSchema);

// Password Validation

const validatePassword = (password) => {

const passwordRegex = /^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{6,}$/;

return passwordRegex.test(password);

};

// Buyer Registration Route

app.post('/api/register', async (req, res) => {

const { firstName, lastName, address, phoneNumber, email, password } = req.body;

try {

// Validate phone number

if (!/^\d{10}$/.test(phoneNumber)) {

return res.status(400).json({ success: false, message: 'Phone number must be exactly 10 digits!' });

// Check if the buyer already exists by email

const existingBuyer = await Buyer.findOne({ email });

if (existingBuyer) {

return res.status(400).json({ success: false, message: 'Buyer already exists with this email.' });

// Validate password
if (!validatePassword(password)) {

return res.status(400).json({ success: false, message: 'Password must be at least 6 characters long and
contain at least one letter and one number.' });

// Hash the password

const hashedPassword = await bcrypt.hash(password, 10);

// Create a new buyer

const newBuyer = new Buyer({ firstName, lastName, address, phoneNumber, email, password:
hashedPassword });

// Save the buyer to the database

await newBuyer.save();

res.status(201).json({ success: true, message: 'Buyer registered successfully!' });

} catch (error) {

console.error('Registration error:', error);

res.status(500).json({ success: false, message: 'Error registering buyer' });

});

// // Get buyer details by ID

// app.get('/api/buyer/:id', async (req, res) => {

// try {

// const buyer = await Buyer.findById(req.params.id);

// if (!buyer) {

// return res.status(404).json({ success: false, message: 'Buyer not found' });

// }

// res.json({ success: true, buyer });

// } catch (error) {

// console.error('Error fetching buyer details:', error);

// res.status(500).json({ success: false, message: 'Error fetching buyer details' });

// }

// });

app.post('/api/farmer-register', async (req, res) => {


const { firstName, lastName, email, password } = req.body; // Ensure you're expecting the correct fields

// Check if all fields are provided

if (!firstName || !lastName || !email || !password ) {

return res.status(400).json({ success: false, message: 'All fields are required' });

try {

// Check if the farmer already exists by email

const existingFarmer = await Farmer.findOne({ email });

if (existingFarmer) {

return res.status(400).json({ success: false, message: 'Farmer already exists with this email.' });

// Validate password

if (!validatePassword(password)) {

return res.status(400).json({ success: false, message: 'Password must be at least 6 characters long and contain
at least one letter and one number.' });

// Hash the password

const hashedPassword = await bcrypt.hash(password, 10);

// Create a new farmer

const newFarmer = new Farmer({ firstName, lastName, email, password: hashedPassword });

// Save the farmer to the database

await newFarmer.save();

res.status(201).json({ success: true, message: 'Farmer registered successfully!' });

} catch (error) {

console.error('Registration error:', error);

res.status(500).json({ success: false, message: 'Error registering farmer' });

});
const jwt = require('jsonwebtoken');

const JWT_SECRET = 'your_jwt_secret'; // Replace with your secret key

// // JWT middleware to authenticate routes

// const authenticateJWT = (req, res, next) => {

// const token = req.headers.authorization && req.headers.authorization.split(' ')[1]; // Extract token from


header

// if (!token) {

// return res.status(401).json({ success: false, message: 'Access token missing or invalid' });

// }

// try {

// // Verify the token

// const decoded = jwt.verify(token, JWT_SECRET);

// req.user = decoded; // Attach decoded token data (like user id) to request object

// next(); // Proceed to the next middleware or route handler

// } catch (error) {

// return res.status(403).json({ success: false, message: 'Invalid or expired token' });

// }

// };

const authenticateJWT = (req, res, next) => {

const token = req.headers.authorization.split(' ')[1];

if (!token) {

return res.status(401).json({ success: false, message: 'Access token missing' });

jwt.verify(token, JWT_SECRET, (err, user) => {

if (err) {

return res.status(403).json({ success: false, message: 'Invalid or expired token' });

}
console.log('Decoded Token:', user); // Log the token to verify its contents

req.user = user;

next();

});

};

// Use authenticateJWT middleware in your protected routes

app.get('/api/buyer-details', authenticateJWT, async (req, res) => {

try {

const buyer = await Buyer.findById(req.user.id); // Use the user ID from the decoded JWT

if (!buyer) {

return res.status(404).json({ success: false, message: 'Buyer not found' });

res.json({ success: true, buyer });

} catch (error) {

res.status(500).json({ success: false, message: 'Error fetching buyer details' });

});

// Buyer Login Route

app.post('/api/login', async (req, res) => {

const { email, password } = req.body;

try {

const buyer = await Buyer.findOne({ email });

if (!buyer) {

return res.status(400).json({ success: false, message: 'Invalid email or password' });

const isMatch = await bcrypt.compare(password, buyer.password);

if (!isMatch) {

return res.status(400).json({ success: false, message: 'Invalid email or password' });

}
// Generate JWT Token

const token = jwt.sign({ id: buyer._id, email: buyer.email }, JWT_SECRET, { expiresIn: '1h' });

res.json({ success: true, message: 'Login successful!', token, buyer });

} catch (error) {

res.status(500).json({ success: false, message: 'Error logging in' });

});

// Farmer Login Route

app.post('/api/farmer-login', async (req, res) => {

const { email, password } = req.body;

try {

const farmer = await Farmer.findOne({ email });

if (!farmer) {

return res.status(400).json({ success: false, message: 'Invalid email or password' });

const isMatch = await bcrypt.compare(password, farmer.password);

if (!isMatch) {

return res.status(400).json({ success: false, message: 'Invalid email or password' });

// Generate JWT Token

const token = jwt.sign({ id: farmer._id, email: farmer.email }, JWT_SECRET, { expiresIn: '1h' });

res.json({ success: true, message: 'Login successful!', token, farmer });

} catch (error) {

res.status(500).json({ success: false, message: 'Error logging in' });

});

// Protect buyer-details route with JWT


app.get('/api/buyer-details', authenticateJWT, async (req, res) => {

try {

const buyer = await Buyer.findById(req.user.id);

if (!buyer) {

return res.status(404).json({ success: false, message: 'Buyer not found' });

res.json({ success: true, buyer });

} catch (error) {

res.status(500).json({ success: false, message: 'Error fetching buyer details' });

});

// // POST route for adding a new product (including image upload)

// app.post('/api/products', upload.single('productImage'), async (req, res) => {

// const { name, description, price, unit, category, quantity, farmerDetails } = req.body;

// const imageUrl = req.file.path; // Get the image file path from multer

// try {

// const newProduct = new Product({

// name,

// description,

// price,

// unit,

// category,

// quantity,

// imageUrl,

// farmerDetails: JSON.parse(farmerDetails), // Parse farmerDetails from string

// });

// await newProduct.save();

// res.status(201).json({ success: true, message: 'Product added successfully' });

// } catch (error) {

// res.status(500).json({ success: false, message: 'Error adding product', error });

// }

// });
const ensureFarmer = (req, res, next) => {

if (req.user.role !== 'farmer') {

return res.status(403).json({ success: false, message: 'Only farmers can perform this action' });

next();

};

app.post('/api/products', authenticateJWT, upload.single('productImage'), async (req, res) => {

const { name, description, price, unit, category, quantity, farmerDetails } = req.body;

const imageUrl = req.file ? req.file.path : undefined;

try {

// Ensure that only users with the role of 'farmer' can add products

if (req.user.role !== 'farmer') {

return res.status(403).json({ success: false, message: 'Only farmers can add products' });

// Parse farmerDetails only if it's a string

const parsedFarmerDetails = typeof farmerDetails === 'string' ? JSON.parse(farmerDetails) : farmerDetails;

const newProduct = new Product({

name,

description,

price,

unit,

category,

quantity,

imageUrl,

farmerDetails: parsedFarmerDetails, // Use parsed farmerDetails

});

await newProduct.save();

res.status(201).json({ success: true, message: 'Product added successfully' });

} catch (error) {
console.error('Error adding product:', error);

res.status(500).json({ success: false, message: 'Error adding product', error: error.message });

});

app.get('/api/products', authenticateJWT, async (req, res) => {

const { category } = req.query;

try {

const products = await Product.find(category ? { category } : {});

res.json({ success: true, products });

} catch (error) {

res.status(500).json({ success: false, message: 'Error fetching products' });

});

// GET route for retrieving products by farmer's email

app.get('/api/farmer-products', async (req, res) => {

const { email } = req.query;

try {

const products = await Product.find({ 'farmerDetails.email': email });

res.json({ success: true, products });

} catch (error) {

res.status(500).json({ success: false, message: 'Error fetching products' });

});

// // Route to get buyer details using email

// app.get('/api/buyer-details', async (req, res) => {

// const { email } = req.query; // Get email from query parameters

// try {

// const buyer = await Buyer.findOne({ email });


// if (!buyer) {

// return res.status(404).json({ success: false, message: 'Buyer not found' });

// }

// res.json({ success: true, buyer });

// } catch (error) {

// console.error('Error fetching buyer details:', error);

// res.status(500).json({ success: false, message: 'Server error' });

// }

// });

// Consolidated buyer details route

app.get('/api/buyer-details', authenticateJWT, async (req, res) => {

try {

const buyer = await Buyer.findById(req.user.id);

if (!buyer) {

return res.status(404).json({ success: false, message: 'Buyer not found' });

res.json({ success: true, buyer });

} catch (error) {

res.status(500).json({ success: false, message: 'Error fetching buyer details' });

});

// PUT route for updating a product

app.put('/api/products/:id', upload.single('productImage'), async (req, res) => {

const productId = req.params.id;

const { name, description, price, unit, category, quantity, farmerDetails } = req.body;

// If an image is uploaded, use the new image; otherwise, keep the old one

const imageUrl = req.file ? req.file.path : undefined;

try {

const product = await Product.findById(productId);

if (!product) {
return res.status(404).json({ success: false, message: 'Product not found' });

// Update product fields only if provided in the request body

product.name = name || product.name;

product.description = description || product.description;

product.price = price || product.price;

product.unit = unit || product.unit;

product.category = category || product.category;

product.quantity = quantity || product.quantity;

if (imageUrl) product.imageUrl = imageUrl;

product.farmerDetails = farmerDetails ? JSON.parse(farmerDetails) : product.farmerDetails; // Parse only if


provided

await product.save();

res.json({ success: true, message: 'Product updated successfully' });

} catch (error) {

res.status(500).json({ success: false, message: 'Error updating product', error });

});

// DELETE route for deleting a product

app.delete('/api/products/:id', async (req, res) => {

const productId = req.params.id;

try {

const deletedProduct = await Product.findByIdAndDelete(productId);

if (!deletedProduct) {

return res.status(404).json({ success: false, message: 'Product not found' });

res.json({ success: true, message: 'Product deleted successfully' });

} catch (error) {
res.status(500).json({ success: false, message: 'Error deleting product', error });

});

// Centralized error handling middleware

app.use((err, req, res, next) => {

console.error(err.stack);

res.status(500).send({ success: false, message: 'Internal Server Error' });

});

app.get('/api/farmer-details', async (req, res) => {

try {

const farmerId = req.user.id; // Assuming the farmer's ID is stored in the session or token

const farmer = await Farmer.findById(farmerId); // Query the database for farmer details

if (!farmer) {

return res.status(404).json({ success: false, message: 'Farmer not found' });

res.json({ success: true, farmer });

} catch (error) {

res.status(500).json({ success: false, message: 'Server error' });

});

// Add item to cart

app.post('/api/cart', authenticateJWT, async (req, res) => {

const { productId, quantity } = req.body;

try {

let cart = await Cart.findOne({ userId: req.user.id });

// If no cart exists for the user, create a new one

if (!cart) {
cart = new Cart({ userId: req.user.id, items: [] });

// Check if the item already exists in the cart

const existingItem = cart.items.find(item => item.productId.toString() === productId);

if (existingItem) {

// Update quantity if item already exists

existingItem.quantity += quantity;

} else {

// Add new item to cart

const product = await Product.findById(productId);

cart.items.push({

productId: product._id,

name: product.name,

price: product.price,

quantity,

imageUrl: product.imageUrl

});

await cart.save();

res.json({ success: true, message: 'Item added to cart', cart });

} catch (error) {

res.status(500).json({ success: false, message: 'Error adding item to cart', error });

});

// Get cart items for a user

app.get('/api/cart', authenticateJWT, async (req, res) => {

try {

const cart = await Cart.findOne({ userId: req.user.id }).populate('items.productId');

if (!cart) {

return res.status(404).json({ success: false, message: 'Cart not found' });


}

res.json({ success: true, cart: cart.items });

} catch (error) {

res.status(500).json({ success: false, message: 'Error fetching cart', error });

});

// Remove item from cart

app.delete('/api/cart/:itemId', authenticateJWT, async (req, res) => {

const { itemId } = req.params;

try {

const cart = await Cart.findOne({ userId: req.user.id });

if (!cart) return res.status(404).json({ success: false, message: 'Cart not found' });

cart.items = cart.items.filter(item => item._id.toString() !== itemId);

await cart.save();

res.json({ success: true, message: 'Item removed from cart' });

} catch (error) {

res.status(500).json({ success: false, message: 'Error removing item from cart', error });

});

// Start the server

const PORT = process.env.PORT || 5000;

app.listen(PORT, () => {

console.log(`Server is running on port ${PORT}`);

});
token

// Use authenticateJWT middleware in your protected routes

app.get('/api/buyer-details', authenticateJWT, async (req, res) => {

try {

const buyer = await Buyer.findById(req.user.id); // Use the user ID from the decoded JWT

if (!buyer) {

return res.status(404).json({ success: false, message: 'Buyer not found' });

res.json({ success: true, buyer });

} catch (error) {

res.status(500).json({ success: false, message: 'Error fetching buyer details' });

});

const authenticateJWT = (req, res, next) => {

const token = req.headers.authorization.split(' ')[1];

if (!token) {

return res.status(401).json({ success: false, message: 'Access token missing' });

jwt.verify(token, JWT_SECRET, (err, user) => {

if (err) {

return res.status(403).json({ success: false, message: 'Invalid or expired token' });

console.log('Decoded Token:', user); // Log the token to verify its contents


req.user = user;

next();

});

};

 User Authentication: Ensure you have a system to authenticate users and store their identifier (e.g., userID,
email) in localStorage when they log in.

 Backend Storage (optional): If you're using a backend, you can store the cart in a database associated with
the user and fetch it using API requests instead of localStorage.

import "../styles/components/orderCard.css";

import { Link } from "react-router-dom";

export const OrderSuccessCard = ({ paymentId }) => {

function getRandomInt(max) {

return Math.floor(Math.random() * max);

return (

<>

<div className="order-box flex-column">

<img

src="https://res.cloudinary.com/dvuh4fz9d/image/upload/v1657615696/check_xyzqdd.png"

className="success-tick-img"

/>

<h2 className="text-center">Your Order Has Been Placed Successfully</h2>

<h3 className="text-center payment-text">

Order ID: {"OD" + getRandomInt(9999999999)}

</h3>

<h3 className="text-center payment-text">Payment ID: {paymentId}</h3>

<h4 className="text-center email-msg-text">

You will receive order details soon on your email

</h4>

<Link to="/products" className="btn btn-solid btn-continue-shopping">

Continue Shopping{" "}

<i className="material-icons mg-left-xsm">shopping_basket</i>

</Link>

</div>
</>

);

};

// Buyer Schema

const buyerSchema = new mongoose.Schema({

firstName: { type: String, required: true },

lastName: { type: String, required: true },

// streetAddress: { type: String, default: null },

// landmark: { type: String, default: null },

// city: { type: String, default: null },

// state: { type: String, default: null },

// postalCode: { type: String, default: null },

// country: { type: String, default: null },

// apartmentNumber: { type: String, default: null },

// buildingName: { type: String, default: null },

address: { type: String, required: true },

phoneNumber: { type: String, required: true },

email: { type: String, required: true, unique: true },

password: { type: String, required: true },

subscription: { type: mongoose.Schema.Types.ObjectId, ref: 'UserSubscription', default: null },

});

// import React, { useEffect, useState } from 'react';

// import { useNavigate } from 'react-router-dom';

// import './Checkout.css'; // Custom CSS for CheckoutPage

// import BuyerNavBar from './BuyerNavBar'; // Import BuyerNavBar component

// const CheckoutPage = () => {

// const [buyer, setBuyer] = useState(null);

// const [cartItems, setCartItems] = useState([]);

// const [totalPrice, setTotalPrice] = useState(0);

// const [selectedAddress, setSelectedAddress] = useState(null);

// const deliveryFee = 45;


// const freeDeliveryThreshold = 300;

// const isSubscribed = false; // Replace with your logic for checking subscription status

// const navigate = useNavigate();

// useEffect(() => {

// // Fetch buyer details from backend using email from localStorage

// const buyerFromStorage = JSON.parse(localStorage.getItem('buyer'));

// if (buyerFromStorage && buyerFromStorage.email) {

// fetch(`http://localhost:5000/api/buyer-details?email=${buyerFromStorage.email}`)

// .then(res => res.json())

// .then(data => {

// if (data.success) {

// setBuyer(data.buyer);

// setSelectedAddress(data.buyer.address); // Set default address selection

// } else {

// console.error('Error fetching buyer details:', data.message);

// }

// })

// .catch(error => {

// console.error('Error fetching buyer details:', error);

// });

// }

// // Retrieve cart items from localStorage

// const savedCartItems = JSON.parse(localStorage.getItem('cartItems')) || [];

// setCartItems(savedCartItems);

// calculateTotalPrice(savedCartItems);

// }, []);

// const calculateTotalPrice = (items) => {

// const total = items.reduce((acc, item) => acc + (item.productId.price * item.quantity), 0);

// setTotalPrice(total);

// };
// // Calculate delivery charge based on subscription status

// const deliveryCharge = isSubscribed ? 0 : (totalPrice > freeDeliveryThreshold ? 0 : deliveryFee);

// const handleProceedToPayment = () => {

// if (!buyer || !selectedAddress) {

// alert('Please select an address for delivery.');

// return;

// }

// // Proceed to payment (You can integrate Razorpay here)

// navigate('/payment');

// };

// const handleDefaultAddressSelection = () => {

// setSelectedAddress(buyer.address);

// };

// return (

// <>

// <BuyerNavBar />

// <div className="checkout-page-container">

// <h1>Checkout</h1>

// <div className="card-container">

// {/* Buyer Details Section */}

// <div className="buyer-details-section">

// {buyer ? (

// <div className="buyer-details">

// <h2>Delivery Address</h2>

// <div className="address-option">

// <p><strong>Name:</strong> {buyer.firstName} {buyer.lastName}</p>

// <p><strong>Email:</strong> {buyer.email}</p>

// <p><strong>Phone Number:</strong> {buyer.phoneNumber}</p>

// <p><strong>Address:</strong> {buyer.address}</p>

// </div>
// <div className="default-address-selection">

// <button

// className={`address-select-button ${selectedAddress === buyer.address ? 'selected'


: ''}`}

// onClick={handleDefaultAddressSelection}

// >

// {selectedAddress === buyer.address ? 'Default Address Selected' : 'Select as Default


Address'}

// </button>

// </div>

// </div>

// ):(

// <p>Loading buyer details...</p>

// )}

// </div>

// {/* Order Summary Section */}

// <div className="order-summary-section">

// <h2>Order Summary</h2>

// <div className="checkout-items">

// {cartItems.map(item => (

// <div key={item.productId._id} className="checkout-item">

// <img src={item.productId.imageUrl ? `http://localhost:5000/$


{item.productId.imageUrl}` : 'path/to/fallback-image.png'} alt={item.productId.name} className="checkout-
item-image" />

// <div className="checkout-item-details">

// <h3>{item.productId.name}</h3>

// <p>Quantity: {item.quantity}</p>

// <p>Price: ₹{item.productId.price} / {item.productId.unit}</p>

// <p>Total: ₹{(item.productId.price * item.quantity).toFixed(2)}</p>

// </div>

// </div>

// ))}

// </div>

// <div className="price-details-card">

// <div className="price-detail">
// <p>Subtotal</p>

// <p>₹{totalPrice.toFixed(2)}</p>

// </div>

// <div className="price-detail">

// <p>Delivery Fee</p>

// <p>{deliveryCharge === 0 ? 'Free' : `₹${deliveryCharge}`}</p>

// </div>

// <div className="price-detail total">

// <p>Total Amount</p>

// <p>₹{(totalPrice + deliveryCharge).toFixed(2)}</p>

// </div>

// <button className="proceed-payment-button" onClick={handleProceedToPayment}>

// Proceed to Payment

// </button>

// </div>

// </div>

// </div>

// </div>

// </>

// );

// };

// export default CheckoutPage;

You might also like