Skip to content

Commit

Permalink
Merge pull request #873 from haseebzaki-07/new_branch_6
Browse files Browse the repository at this point in the history
Add user profile sections
  • Loading branch information
manikumarreddyu authored Nov 8, 2024
2 parents f6b9d7f + 2fd4ce3 commit 52c89d7
Show file tree
Hide file tree
Showing 10 changed files with 450 additions and 66 deletions.
2 changes: 1 addition & 1 deletion backend/controllers/rent/RentWishlistController.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ exports.removeFromWishlist = async (req, res) => {

// Get User Wishlist
exports.getWishlist = async (req, res) => {
const { userId } = req.body; // Accepts userId from body for now
const { userId } = req.query; // Accepts userId from query

try {
const user = await User.findById(userId).populate('wishlist');
Expand Down
20 changes: 20 additions & 0 deletions backend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

170 changes: 119 additions & 51 deletions frontend/src/AgroRentAI/RentUserDashboard.jsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,34 @@
// RentUserDashboard.js
import React, { useState, useEffect } from 'react';

import { User, Clock, CreditCard, Heart, Bell } from 'lucide-react';
import ProfileComponent from './components/AccountInformation';
import RentalHistoryComponent from './components/ReatalHistory';
import PaymentMethodsComponent from './components/PaymentMethods';
import WishlistComponent from './components/Wishlist';
import NotificationsComponent from './components/RentNotifications';
import React, { useState, useEffect } from "react";

import {
User,
Clock,
CreditCard,
Heart,
Bell,
Star,
Shield,
LifeBuoy,
FileText,
Package,
} from "lucide-react";
import ProfileComponent from "./components/AccountInformation";
import RentalHistoryComponent from "./components/RentalHistory";
import PaymentMethodsComponent from "./components/PaymentMethods";
import WishlistComponent from "./components/Wishlist";
import NotificationsComponent from "./components/RentNotifications";
import RatingsReviewsComponent from "./components/RatingReviews";
import SecurityPrivacyComponent from "./components/SecurityPrivacyComponent";
import SupportAssistanceComponent from "./components/SupportAssistance";
import SubscriptionMembershipComponent from "./components/Subscription";
import OrderDeliveryTrackingComponent from "./components/OrderTracking";

const RentUserDashboard = () => {
const [profile, setProfile] = useState({
name: '',
email: '',
address: '',
profilePicture: '',
name: "",
email: "",
address: "",
profilePicture: "",
paymentMethods: [],
});
const [rentals, setRentals] = useState([]);
Expand All @@ -22,56 +37,65 @@ const RentUserDashboard = () => {
const [notifications, setNotifications] = useState([]);
const [activeSection, setActiveSection] = useState("Account Information");

// Fetch user data, rentals, wishlist, and notifications
useEffect(() => {
const fetchData = async () => {
const userData = await fetchUserProfile();
const rentalData = await fetchUserRentals();
const wishlistData = await fetchUserWishlist();
const reviewData = await fetchUserReviews();
const notificationData = await fetchUserNotifications();

setProfile(userData);
setRentals(rentalData);
setWishlist(wishlistData);
setReviews(reviewData);
setNotifications(notificationData);
setProfile(await fetchUserProfile());
setRentals(await fetchUserRentals());
setWishlist(await fetchUserWishlist());
setReviews(await fetchUserReviews());
setNotifications(await fetchUserNotifications());
};

fetchData();
}, []);

// Mock API calls
const fetchUserProfile = async () => ({
name: 'John Doe',
email: 'john@example.com',
address: '123 Main St, Springfield, USA',
profilePicture: '/images/profile.png',
paymentMethods: ['Visa **** 1234', 'Mastercard **** 5678'],
name: "John Doe",
email: "john@example.com",
address: "123 Main St, Springfield, USA",
profilePicture: "/images/profile.png",
paymentMethods: ["Visa **** 1234", "Mastercard **** 5678"],
});

const fetchUserRentals = async () => [
{ id: 1, name: 'Tractor', duration: '5 days', cost: '$150', status: 'Active' },
{ id: 2, name: 'Plow', duration: '2 days', cost: '$80', status: 'Pending' },
{ id: 3, name: 'Seeder', duration: '1 week', cost: '$200', status: 'Completed' },
{
id: 1,
name: "Tractor",
duration: "5 days",
cost: "$150",
status: "Active",
},
{ id: 2, name: "Plow", duration: "2 days", cost: "$80", status: "Pending" },
{
id: 3,
name: "Seeder",
duration: "1 week",
cost: "$200",
status: "Completed",
},
];

const fetchUserWishlist = async () => [
{ id: 1, name: 'Rototiller', price: '$300' },
{ id: 2, name: 'Lawn Mower', price: '$200' },
{ id: 1, name: "Rototiller", price: "$300" },
{ id: 2, name: "Lawn Mower", price: "$200" },
];

const fetchUserReviews = async () => [
{ rentalId: 3, rating: 5, comment: 'Excellent equipment!' },
{ rentalId: 3, rating: 5, comment: "Excellent equipment!" },
];

const fetchUserNotifications = async () => [
{ id: 1, message: 'Your rental for Seeder is due tomorrow!', type: 'reminder' },
{ id: 2, message: '20% discount on new rentals!', type: 'offer' },
{
id: 1,
message: "Your rental for Seeder is due tomorrow!",
type: "reminder",
},
{ id: 2, message: "20% discount on new rentals!", type: "offer" },
];

const handleCancelRental = (id) => {
setRentals(rentals.filter(rental => rental.id !== id));
setRentals(rentals.filter((rental) => rental.id !== id));
};

const handleProfileEdit = () => {
Expand All @@ -81,47 +105,91 @@ const RentUserDashboard = () => {
const renderSectionContent = () => {
switch (activeSection) {
case "Account Information":
return <ProfileComponent profile={profile} handleProfileEdit={handleProfileEdit} />;
return <ProfileComponent profile={profile} />;
case "Rental History":
return <RentalHistoryComponent rentals={rentals} handleCancelRental={handleCancelRental} />;
return <RentalHistoryComponent rentals={rentals} />;
case "Payment Methods & Billing":
return <PaymentMethodsComponent paymentMethods={profile.paymentMethods} />;
return (
<PaymentMethodsComponent paymentMethods={profile.paymentMethods} />
);
case "Saved Items / Wishlist":
return <WishlistComponent wishlist={wishlist} />;
case "Notifications & Alerts":
return <NotificationsComponent notifications={notifications} />;
case "Ratings & Reviews":
return <RatingsReviewsComponent reviews={reviews} />;
case "Security & Privacy":
return <SecurityPrivacyComponent />;
case "Support & Assistance":
return <SupportAssistanceComponent />;
case "Subscription & Membership":
return <SubscriptionMembershipComponent />;
case "Order & Delivery Tracking":
return <OrderDeliveryTrackingComponent rentals={rentals} />;
default:
return null;
}
};

return (
<div className="min-h-screen bg-gray-100 flex">
{/* Sidebar */}
<div className="w-1/4 bg-green-50 p-6">
<h2 className="text-2xl font-extrabold tracking-tight text-green-900 mb-6">Dashboard</h2>
<h2 className="text-2xl font-extrabold tracking-tight text-green-900 mb-6">
Dashboard
</h2>
<ul className="space-y-4">
<li className="cursor-pointer" onClick={() => setActiveSection("Account Information")}>
<li
className="cursor-pointer"
onClick={() => setActiveSection("Account Information")}
>
<User className="inline mr-2" /> Account Information
</li>
<li className="cursor-pointer" onClick={() => setActiveSection("Rental History")}>
<li
className="cursor-pointer"
onClick={() => setActiveSection("Rental History")}
>
<Clock className="inline mr-2" /> Rental History
</li>
<li className="cursor-pointer" onClick={() => setActiveSection("Payment Methods & Billing")}>
<li
className="cursor-pointer"
onClick={() => setActiveSection("Payment Methods & Billing")}
>
<CreditCard className="inline mr-2" /> Payment Methods & Billing
</li>
<li className="cursor-pointer" onClick={() => setActiveSection("Saved Items / Wishlist")}>
<li
className="cursor-pointer"
onClick={() => setActiveSection("Saved Items / Wishlist")}
>
<Heart className="inline mr-2" /> Saved Items / Wishlist
</li>
<li className="cursor-pointer" onClick={() => setActiveSection("Notifications & Alerts")}>
<li
className="cursor-pointer"
onClick={() => setActiveSection("Notifications & Alerts")}
>
<Bell className="inline mr-2" /> Notifications & Alerts
</li>
<li className="cursor-pointer" onClick={() => setActiveSection("Ratings & Reviews")}>
<Star className="inline mr-2" /> Ratings & Reviews
</li>
<li className="cursor-pointer" onClick={() => setActiveSection("Security & Privacy")}>
<Shield className="inline mr-2" /> Security & Privacy
</li>
<li className="cursor-pointer" onClick={() => setActiveSection("Support & Assistance")}>
<LifeBuoy className="inline mr-2" /> Support & Assistance
</li>
<li className="cursor-pointer" onClick={() => setActiveSection("Subscription & Membership")}>
<FileText className="inline mr-2" /> Subscription & Membership
</li>
<li className="cursor-pointer" onClick={() => setActiveSection("Order & Delivery Tracking")}>
<Package className="inline mr-2" /> Order & Delivery Tracking
</li>
</ul>
</div>

{/* Main Content Area */}
<div className="w-3/4 bg-white p-8">
<h2 className="text-2xl font-bold text-green-500 mb-4">{activeSection}</h2>
<h2 className="text-2xl font-bold text-green-500 mb-4">
{activeSection}
</h2>
{renderSectionContent()}
</div>
</div>
Expand Down
48 changes: 48 additions & 0 deletions frontend/src/AgroRentAI/components/OrderTracking.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// OrderDeliveryTrackingComponent.js
import React from 'react';
import { Truck, Package, AlertCircle, CheckCircle, Clock } from 'lucide-react';

const OrderDeliveryTrackingComponent = ({ rentals }) => (
<div className="bg-white p-6 rounded-lg ">
<h3 className="text-2xl font-bold text-green-700 mb-6 flex items-center">
<Truck className="mr-2 text-green-600" />
Order & Delivery Tracking
</h3>
<ul className="space-y-6">
{rentals.map((rental, index) => (
<li key={index} className="p-4 border rounded-lg bg-green-50 shadow-md hover:bg-green-100 transition-colors duration-300">
<div className="flex items-center justify-between mb-4">
<h4 className="text-lg font-semibold text-green-800">{rental.name}</h4>
<p className={`text-sm px-3 py-1 rounded-md ${rental.status === 'Active' ? 'bg-yellow-300 text-yellow-900' : 'bg-green-300 text-green-900'}`}>
{rental.status}
</p>
</div>

{/* Tracking Details */}
<div className="mb-3 text-gray-700">
<p><strong>Expected Delivery:</strong> {rental.expectedDelivery || "N/A"}</p>
<p><strong>Rental Period:</strong> {rental.duration}</p>
<p><strong>Tracking ID:</strong> {rental.trackingId || 'Unavailable'}</p>
</div>

{/* Tracking Progress Bar */}
<div className="my-4">
<p className="text-sm font-semibold mb-2">Delivery Progress:</p>
<div className="relative w-full bg-gray-200 rounded-full h-3">
<div className="absolute top-0 left-0 h-3 rounded-full bg-green-600" style={{ width: `${rental.progress || 0}%` }}></div>
</div>
<p className="text-sm mt-2 text-gray-500">{rental.progress}% Completed</p>
</div>

{/* Contact & Support */}
<div className="flex items-center mt-4">
<Truck className="text-green-700 mr-2" />
<p className="text-gray-600 text-sm">Questions? <a href="/contact-support" className="text-green-600 font-semibold hover:underline">Contact Support</a></p>
</div>
</li>
))}
</ul>
</div>
);

export default OrderDeliveryTrackingComponent;
38 changes: 38 additions & 0 deletions frontend/src/AgroRentAI/components/RatingReviews.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// RatingsReviewsComponent.js
import React from 'react';
import { Star, Tractor } from 'lucide-react'; // Using icons to match the agricultural theme

const RatingsReviewsComponent = ({ reviews }) => (
<div className="bg-white p-6 rounded-lg ">
<h3 className="text-2xl font-bold text-green-700 mb-6 flex items-center">
<Tractor className="mr-2 text-green-700" /> Ratings & Reviews
</h3>

<ul className="space-y-6">
{reviews.map((review, index) => (
<li
key={index}
className="p-4 border rounded-lg shadow-sm bg-green-50 hover:bg-green-100 transition-colors duration-200"
>
<div className="flex items-center mb-2">
<strong className="text-green-700 mr-2">Rental ID:</strong>
<span>{review.rentalId}</span>
</div>

<div className="flex items-center mb-2">
<strong className="text-green-700 mr-2">Rating:</strong>
<span className="flex items-center">
{Array(review.rating).fill(<Star className="text-yellow-500" />)}
</span>
</div>

<p className="text-gray-700">
<strong className="text-green-700">Comment:</strong> {review.comment}
</p>
</li>
))}
</ul>
</div>
);

export default RatingsReviewsComponent;
Loading

0 comments on commit 52c89d7

Please sign in to comment.