From 393e744e6b55c9ed3f106890594f9e512bc33b34 Mon Sep 17 00:00:00 2001 From: haseebzaki-07 Date: Sat, 9 Nov 2024 17:09:25 +0530 Subject: [PATCH] Add admin dash components --- backend/model/rent/rentProduct.js | 114 ++--- .../src/AgroRentAI/RentAdminDashboard.jsx | 438 +++++++----------- frontend/src/AgroRentAI/RentUserDashboard.jsx | 4 +- .../AgroRentAI/components/AdminAnalytics.jsx | 121 +++++ .../components/AdminOrderManagement.jsx | 70 +++ .../components/AdminProductManagement.jsx | 58 +++ .../components/AdminUserManagement.jsx | 91 ++++ 7 files changed, 571 insertions(+), 325 deletions(-) create mode 100644 frontend/src/AgroRentAI/components/AdminAnalytics.jsx create mode 100644 frontend/src/AgroRentAI/components/AdminOrderManagement.jsx create mode 100644 frontend/src/AgroRentAI/components/AdminProductManagement.jsx create mode 100644 frontend/src/AgroRentAI/components/AdminUserManagement.jsx diff --git a/backend/model/rent/rentProduct.js b/backend/model/rent/rentProduct.js index 4ed8e838..5c6e1504 100644 --- a/backend/model/rent/rentProduct.js +++ b/backend/model/rent/rentProduct.js @@ -1,71 +1,71 @@ -const mongoose = require('mongoose'); + const mongoose = require('mongoose'); -const reviewSchema = new mongoose.Schema({ - rentalId: String, - rating: { type: Number, required: true, min: 0, max: 5 }, - comment: String, -}); + const reviewSchema = new mongoose.Schema({ + rentalId: String, + rating: { type: Number, required: true, min: 0, max: 5 }, + comment: String, + }); -const rentProductSchema = new mongoose.Schema({ - name: { type: String, required: true }, - description: { type: String, required: true }, - price: { type: Number, required: true }, // Base price for the product (purchase price) - image: { type: String, required: true }, - category: { type: [String], required: true }, + const rentProductSchema = new mongoose.Schema({ + name: { type: String, required: true }, + description: { type: String, required: true }, + price: { type: Number, required: true }, // Base price for the product (purchase price) + image: { type: String, required: true }, + category: { type: [String], required: true }, + - - availabilityStatus: { - type: String, - enum: ['available', 'rented', 'maintenance'], - default: 'available', - }, - - rentalPricePerDay: { - type: Number, - required: true, - min: 0, // Minimum daily rental price - }, + availabilityStatus: { + type: String, + enum: ['available', 'rented', 'maintenance'], + default: 'available', + }, + + rentalPricePerDay: { + type: Number, + required: true, + min: 0, // Minimum daily rental price + }, - rentalDurationOptions: { - type: [String], - required: true, - enum: ['hourly', 'daily', 'weekly', 'monthly'], - }, // Available rental durations + rentalDurationOptions: { + type: [String], + required: true, + enum: ['hourly', 'daily', 'weekly', 'monthly'], + }, // Available rental durations - maxRentalDuration: { - type: Number, - required: true, - min: 1, // Minimum rental period (e.g., in days, weeks, etc.) - }, + maxRentalDuration: { + type: Number, + required: true, + min: 1, // Minimum rental period (e.g., in days, weeks, etc.) + }, - depositAmount: { - type: Number, - default: 0, - }, + depositAmount: { + type: Number, + default: 0, + }, - rentalTerms: { - type: String, - maxlength: 500, - }, + rentalTerms: { + type: String, + maxlength: 500, + }, - rentedQuantity: { - type: Number, - default: 0, - }, + rentedQuantity: { + type: Number, + default: 0, + }, - reviews: [reviewSchema], + reviews: [reviewSchema], - rating: { type: Number, default: 0, min: 0, max: 5 }, -}, { timestamps: true }); + rating: { type: Number, default: 0, min: 0, max: 5 }, + }, { timestamps: true }); -// Method to update product rating based on reviews -rentProductSchema.methods.updateProductRating = function() { - const totalRating = this.reviews.reduce((sum, review) => sum + review.rating, 0); - const averageRating = this.reviews.length ? totalRating / this.reviews.length : 0; - this.rating = averageRating; - return this.save(); -}; + // Method to update product rating based on reviews + rentProductSchema.methods.updateProductRating = function() { + const totalRating = this.reviews.reduce((sum, review) => sum + review.rating, 0); + const averageRating = this.reviews.length ? totalRating / this.reviews.length : 0; + this.rating = averageRating; + return this.save(); + }; -module.exports = mongoose.models.RentProduct || mongoose.model('RentProduct', rentProductSchema); + module.exports = mongoose.models.RentProduct || mongoose.model('RentProduct', rentProductSchema); diff --git a/frontend/src/AgroRentAI/RentAdminDashboard.jsx b/frontend/src/AgroRentAI/RentAdminDashboard.jsx index 1349997d..9aec0d1f 100644 --- a/frontend/src/AgroRentAI/RentAdminDashboard.jsx +++ b/frontend/src/AgroRentAI/RentAdminDashboard.jsx @@ -1,9 +1,13 @@ -import React, { useState, useEffect } from 'react'; -import { Plus, Edit, Trash, BarChart, Bell } from 'lucide-react'; -import { ToastContainer, toast } from 'react-toastify'; -import 'react-toastify/dist/ReactToastify.css'; // Import the CSS for toastify +import React, { useState, useEffect } from "react"; +import { User, BarChart, Box, Package, Bell } from "lucide-react"; +import ProductManagement from "./components/AdminProductManagement"; +import OrderManagement from "./components/AdminOrderManagement"; +import UserManagement from "./components/AdminUserManagement"; +import Analytics from "./components/AdminAnalytics"; + const RentAdminDashboard = () => { + const [activeSection, setActiveSection] = useState("Product Management"); const [products, setProducts] = useState([]); const [orders, setOrders] = useState([]); const [users, setUsers] = useState([]); @@ -17,7 +21,6 @@ const RentAdminDashboard = () => { ? 'https://agrotech-ai-11j3.onrender.com' : 'http://localhost:8080'; - const [showModal, setShowModal] = useState(false); const [newProduct, setNewProduct] = useState({ name: '', @@ -27,6 +30,7 @@ const RentAdminDashboard = () => { rating: 0, category: [], }); + // Fetch data useEffect(() => { const fetchData = async () => { @@ -44,25 +48,121 @@ const RentAdminDashboard = () => { fetchData(); }, []); - // Mock API calls + // Dummy data based on the schema const fetchProducts = async () => { return [ - { id: 1, name: 'Tractor', price: '$300', category: 'Heavy Machinery', availability: 'In Stock' }, - { id: 2, name: 'Lawn Mower', price: '$100', category: 'Gardening', availability: 'In Stock' }, + { + _id: '1', + name: 'Tractor', + description: 'Heavy-duty tractor for large farm operations', + price: 30000, + image: 'tractor.jpg', + category: ['Heavy Machinery'], + availabilityStatus: 'available', + rentalPricePerDay: 200, + rentalDurationOptions: ['daily', 'weekly'], + maxRentalDuration: 30, + depositAmount: 1000, + rentalTerms: 'Damage costs will be deducted from the deposit.', + rentedQuantity: 2, + reviews: [ + { rentalId: '1', rating: 5, comment: 'Great tractor!' }, + ], + rating: 5, + }, + { + _id: '2', + name: 'Lawn Mower', + description: 'Electric lawn mower suitable for small gardens', + price: 500, + image: 'lawnmower.jpg', + category: ['Gardening'], + availabilityStatus: 'available', + rentalPricePerDay: 20, + rentalDurationOptions: ['hourly', 'daily'], + maxRentalDuration: 7, + depositAmount: 50, + rentalTerms: 'Return in good condition.', + rentedQuantity: 5, + reviews: [ + { rentalId: '2', rating: 4, comment: 'Very useful!' }, + ], + rating: 4, + } ]; }; const fetchOrders = async () => { return [ - { id: 1, item: 'Tractor', user: 'John Doe', status: 'Pending Approval', returnDate: '2024-12-01' }, - { id: 2, item: 'Lawn Mower', user: 'Jane Smith', status: 'Active', returnDate: '2024-11-15' }, + { + rentalId: '1', + product: 'Tractor', + quantity: 1, + rentalDuration: 'weekly', + rentalDate: '2024-11-01', + returnDate: '2024-11-08', + status: 'ongoing', + }, + { + rentalId: '2', + product: 'Lawn Mower', + quantity: 2, + rentalDuration: 'daily', + rentalDate: '2024-11-05', + returnDate: '2024-11-06', + status: 'returned', + }, ]; }; const fetchUsers = async () => { return [ - { id: 1, name: 'John Doe', email: 'john@example.com', feedback: 'Excellent service!' }, - { id: 2, name: 'Jane Smith', email: 'jane@example.com', feedback: 'Very helpful!' }, + { + _id: 'u1', + firstName: 'John', + lastName: 'Doe', + username: 'johndoe', + email: 'john@example.com', + address: '123 Farm Lane', + role: 'farmer', + isVerified: true, + rentals: [ + { + rentalId: '1', + product: 'Tractor', + quantity: 1, + rentalDuration: 'weekly', + rentalDate: '2024-11-01', + returnDate: '2024-11-08', + status: 'ongoing', + }, + ], + wishlist: [], + cart: [], + }, + { + _id: 'u2', + firstName: 'Jane', + lastName: 'Smith', + username: 'janesmith', + email: 'jane@example.com', + address: '456 Garden Blvd', + role: 'customer', + isVerified: false, + rentals: [ + { + rentalId: '2', + product: 'Lawn Mower', + quantity: 2, + rentalDuration: 'daily', + rentalDate: '2024-11-05', + returnDate: '2024-11-06', + status: 'returned', + }, + ], + wishlist: [], + cart: [], + } ]; }; @@ -71,267 +171,73 @@ const RentAdminDashboard = () => { popularProducts: ['Tractor', 'Lawn Mower'], revenue: '$1200', rentalFrequency: ['Daily', 'Weekly'], - userBehavior: ['Frequently rented Tractor and Plow'], + userBehavior: ['Frequently rented Tractor and Lawn Mower'], }; - }; - - const handleAddProduct = () => { - setShowModal(true); // Open the modal to add a new product - }; - - const handleInputChange = (e) => { - const { name, value } = e.target; - setNewProduct((prevState) => ({ - ...prevState, - [name]: value, - })); - }; - - const handleCategoryChange = (e) => { - const selectedCategories = Array.from(e.target.selectedOptions, (option) => option.value); - setNewProduct((prevState) => ({ - ...prevState, - category: selectedCategories, - })); - }; - - const handleSubmitProduct = async (e) => { - e.preventDefault(); - - // Call the backend API to create a new product - try { - const response = await fetch(`${ApiUrl}/api/rent-products`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(newProduct), - }); - - if (response.ok) { - const savedProduct = await response.json(); - setProducts([...products, savedProduct]); - setShowModal(false); - toast.success('Product added successfully!'); // Show success toast - } else { - console.error('Failed to add product'); - toast.error('Failed to add product. Please try again!'); // Show error toast - } - } catch (error) { - console.error('Error:', error); - toast.error('Error adding product. Please try again!'); // Show error toast + } + + const handleAddProduct =()=> { + return + } + + const handleUpdateProduct =()=> { + return + } + + const handleDeleteProduct =()=>{ + return + } + + const handleOrderApproval = () => { + return + } + + + const renderSectionContent = () => { + switch (activeSection) { + case "Product Management": + return ; + case "Order Management": + return ; + case "User Management": + return ; + case "Analytics & Reporting": + return ; + default: + return null; } }; - const handleCloseModal = () => { - setShowModal(false); // Close the modal without saving - }; - - const handleUpdateProduct = (id) => { - // Update product logic - }; - - const handleDeleteProduct = (id) => { - setProducts(products.filter((product) => product.id !== id)); - }; - - const handleOrderApproval = (id) => { - setOrders(orders.map((order) => (order.id === id ? { ...order, status: 'Approved' } : order))); - }; - - const handleSendNotification = () => { - // Send notification logic - }; - return ( -
- -

Admin Dashboard

- - {/* Product Management Section */} -
-

Product Management

- -
- {products.map((product) => ( -
-
-

{product.name}

-

{product.price} - {product.category} - {product.availability}

-
-
- - -
-
- ))} -
-
- - {/* Order Management Section */} -
-

Order Management

-
- {orders.map((order) => ( -
-
-

{order.item}

-

User: {order.user} - Status: {order.status} - Return Date: {order.returnDate}

-
- -
- ))} -
-
- {/* Add Product Modal */} - {showModal && ( -
-
-

Add New Product

-
-
- - -
- -
- -