diff --git a/src/App.tsx b/src/App.tsx
index 19593e4..f6ff5f6 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -25,6 +25,7 @@ import ResetPassword from './pages/ResetPassword';
import NewPassword from './pages/NewPassword';
import { ProductDetail } from './pages/product/ProductDetail';
+import BuyerProfile from './pages/BuyerProfile';
const App = () => {
const { data, error, isLoading } = useGetProductsQuery();
const dispatch = useDispatch();
@@ -88,6 +89,10 @@ const App = () => {
path: 'products/:id',
element: ,
},
+ {
+ path: 'buyer-profile',
+ element: ,
+ }
],
},
{
diff --git a/src/containers/buyer/Account.tsx b/src/containers/buyer/Account.tsx
new file mode 100644
index 0000000..1040834
--- /dev/null
+++ b/src/containers/buyer/Account.tsx
@@ -0,0 +1,78 @@
+// components/menu/Menu1.jsx
+import { FaUserEdit, FaHourglassHalf } from "react-icons/fa";
+import { FaTruckFast } from "react-icons/fa6";
+import { MdOutlineFeedback } from "react-icons/md";
+import { PiKeyReturn } from "react-icons/pi";
+import { useDispatch } from "react-redux";
+import { setActiveMenu } from "../../redux/slices/buyerDashboard";
+
+
+const image: string = 'https://images.unsplash.com/photo-1533636721434-0e2d61030955?q=80&w=1740&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D'
+
+const Account = () => {
+ const dispatch = useDispatch();
+ return (
+
+ {/* User Profile Section */}
+
+
+
+
+
+
dispatch(setActiveMenu("profile"))}/>
+
+
+ {/* Cards Section */}
+
+ {/* Pending Card */}
+
dispatch(setActiveMenu("pendingpayments"))}>
+
+ 5
+
+
+
+
Pending Payments
+
+
+
+ {/* All Card */}
+
dispatch(setActiveMenu("intransit"))}
+ >
+
+ 5
+
+
+
+
In Transit
+
+
+
+ {/* Feedback Card */}
+
dispatch(setActiveMenu("feedback"))}
+ >
+
+
+
Feedback
+
+
+
+ {/* Refund & Return Card */}
+
dispatch(setActiveMenu("returnrefund"))}
+ >
+
+
+
Return & Refund
+
+
+
+
+ );
+};
+
+export default Account;
diff --git a/src/containers/buyer/FeedBack.tsx b/src/containers/buyer/FeedBack.tsx
new file mode 100644
index 0000000..2ebf9fa
--- /dev/null
+++ b/src/containers/buyer/FeedBack.tsx
@@ -0,0 +1,153 @@
+import React, { useState } from 'react';
+import FeedbackModal from './FeedbackModal';
+
+type Rating = number;
+
+interface Product {
+ id: string;
+ name: string;
+ price: string;
+ manufacturer: string;
+ ratings: Rating[];
+}
+
+const productsData: Product[] = [
+ {
+ id: '1',
+ name: 'Product 1',
+ price: '$100',
+ manufacturer: 'Manufacturer A',
+ ratings: [],
+ },
+ {
+ id: '2',
+ name: 'Product 2',
+ price: '$200',
+ manufacturer: 'Manufacturer B',
+ ratings: [4, 5],
+ },
+ {
+ id: '3',
+ name: 'Product 3',
+ price: '$300',
+ manufacturer: 'Manufacturer C',
+ ratings: [3],
+ },
+];
+
+const FeedBack: React.FC = () => {
+ const [products, setProducts] = useState(productsData);
+ const [modalOpen, setModalOpen] = useState(false);
+ const [currentProduct, setCurrentProduct] = useState(null);
+ const [currentPage, setCurrentPage] = useState(1);
+ const productsPerPage = 2;
+
+ const indexOfLastProduct = currentPage * productsPerPage;
+ const indexOfFirstProduct = indexOfLastProduct - productsPerPage;
+ const currentProducts = products.slice(indexOfFirstProduct, indexOfLastProduct);
+
+ const totalPages = Math.ceil(products.length / productsPerPage);
+
+ const paginate = (pageNumber: number) => setCurrentPage(pageNumber);
+
+ const calculateAverageRating = (ratings: Rating[]): string => {
+ if (ratings.length === 0) return 'No ratings';
+ const sum = ratings.reduce((a, b) => a + b, 0);
+ return (sum / ratings.length).toFixed(1);
+ };
+
+ const handleAddFeedback = (product: Product) => {
+ setCurrentProduct(product);
+ setModalOpen(true);
+ };
+
+ const handleModalClose = () => {
+ setModalOpen(false);
+ setCurrentProduct(null);
+ };
+
+ const handleFeedbackSubmit = (feedback: { message: string; image: File | null; rating: number }) => {
+ console.log('Feedback submitted for product:', currentProduct?.id);
+ console.log('Feedback details:', feedback);
+ };
+
+ const handleDeleteFeedback = (productId: string, feedbackIndex: number) => {
+ setProducts((prevProducts) =>
+ prevProducts.map((product) =>
+ product.id === productId
+ ? {
+ ...product,
+ ratings: product.ratings.filter((_, index) => index !== feedbackIndex),
+ }
+ : product
+ )
+ );
+ };
+
+ return (
+
+
Product List
+ {currentProducts.map((product) => (
+
+
+
+
{product.name}
+
Average Rating: {calculateAverageRating(product.ratings)}
+
+
+ {product.ratings.length === 0 ? (
+
+ ) : (
+
+ {product.ratings.map((rating, index) => (
+
+
+ Feedback {index + 1}: {rating} stars
+
+
+
+ ))}
+
+ )}
+
+
+
+ ))}
+
+ {Array.from({ length: totalPages }, (_, index) => (
+
+ ))}
+
+ {currentProduct && (
+
+ )}
+
+ );
+};
+
+export default FeedBack;
diff --git a/src/containers/buyer/FeedbackModal.tsx b/src/containers/buyer/FeedbackModal.tsx
new file mode 100644
index 0000000..8412cce
--- /dev/null
+++ b/src/containers/buyer/FeedbackModal.tsx
@@ -0,0 +1,98 @@
+import React, { useState } from 'react';
+
+interface FeedbackModalProps {
+ productName: string;
+ isOpen: boolean;
+ onClose: () => void;
+ onSubmit: (feedback: { message: string; image: File | null; rating: number }) => void;
+}
+
+const FeedbackModal: React.FC = ({ productName, isOpen, onClose, onSubmit }) => {
+ const [message, setMessage] = useState('');
+ const [image, setImage] = useState(null);
+ const [rating, setRating] = useState(0);
+
+ const handleImageChange = (e: React.ChangeEvent) => {
+ if (e.target.files && e.target.files[0]) {
+ setImage(e.target.files[0]);
+ }
+ };
+
+ const handleSubmit = (e: React.FormEvent) => {
+ e.preventDefault();
+ onSubmit({ message, image, rating });
+ onClose();
+ };
+
+ if (!isOpen) return null;
+
+ return (
+
+
+
Add Feedback for {productName}
+
+
+
+ );
+};
+
+export default FeedbackModal;
diff --git a/src/containers/buyer/InTransit.tsx b/src/containers/buyer/InTransit.tsx
new file mode 100644
index 0000000..28c5839
--- /dev/null
+++ b/src/containers/buyer/InTransit.tsx
@@ -0,0 +1,113 @@
+import { useState } from "react";
+import { useDispatch } from "react-redux";
+import { setActiveMenu } from "../../redux/slices/buyerDashboard";
+
+function InTransitOrders() {
+ const dispatch = useDispatch();
+
+ // Dummy orders data
+ const orders = [
+ {
+ id: "764376473647634736",
+ status: "Pending",
+ date: "07/14/2024",
+ totalPrice: "$566",
+ },
+ {
+ id: "998877665544332211",
+ status: "Processing",
+ date: "07/15/2024",
+ totalPrice: "$780",
+ },
+ {
+ id: "554433221199887766",
+ status: "Pending",
+ date: "07/16/2024",
+ totalPrice: "$350",
+ },
+ {
+ id: "332211998877665544",
+ status: "Shipped",
+ date: "07/17/2024",
+ totalPrice: "$450",
+ },
+ {
+ id: "123456789012345678",
+ status: "Pending",
+ date: "07/18/2024",
+ totalPrice: "$1200",
+ },
+ {
+ id: "112233445566778899",
+ status: "Shipped",
+ date: "07/19/2024",
+ totalPrice: "$980",
+ },
+ {
+ id: "223344556677889900",
+ status: "Processing",
+ date: "07/20/2024",
+ totalPrice: "$610",
+ },
+ ];
+
+ // Filter orders to only include those with status "Shipped" or "Processing"
+ const inTransitOrders = orders.filter(order => order.status === "Shipped" || order.status === "Processing");
+
+ const [currentPage, setCurrentPage] = useState(1);
+ const ordersPerPage = 3;
+
+ const indexOfLastOrder = currentPage * ordersPerPage;
+ const indexOfFirstOrder = indexOfLastOrder - ordersPerPage;
+ const currentOrders = inTransitOrders.slice(indexOfFirstOrder, indexOfLastOrder);
+
+ const totalPages = Math.ceil(inTransitOrders.length / ordersPerPage);
+
+ const paginate = (pageNumber:any) => setCurrentPage(pageNumber);
+
+ return (
+
+
In Transit Orders
+
+ {currentOrders.map((order) => (
+
+
+
+
+
Status:
+
{order.status}
+
+
+
+
{order.date}
+
+
Total Price:
+
{order.totalPrice}
+
+
+
+
+ ))}
+
+
+ {Array.from({ length: totalPages }, (_, index) => (
+
+ ))}
+
+
+ );
+}
+
+export default InTransitOrders;
diff --git a/src/containers/buyer/OderDetails.tsx b/src/containers/buyer/OderDetails.tsx
new file mode 100644
index 0000000..9d34bb6
--- /dev/null
+++ b/src/containers/buyer/OderDetails.tsx
@@ -0,0 +1,90 @@
+function OrderDetails() {
+ return (
+
+
Order Details
+
+ {/* Order Information */}
+
+
+
+ Order ID:
+ 764376473647634736
+
+
+ Status:
+ Pending
+
+
+
+
+ Date:
+ 03/24/2024
+
+
+ Total Price:
+ $566
+
+
+
+
+ {/* Order Items */}
+
+
Items
+
+
+
+
+
Product Name
+
+
+ Quantity:
+ 2
+
+
+ Price:
+ $150
+
+
+
+ {/* Repeat for more items */}
+
+
+
+
Another Product
+
+
+ Quantity:
+ 1
+
+
+ Price:
+ $266
+
+
+
+
+
+ {/* Actions */}
+
+
+
+
+
+
+ );
+ }
+
+ export default OrderDetails;
+
\ No newline at end of file
diff --git a/src/containers/buyer/Orders.tsx b/src/containers/buyer/Orders.tsx
new file mode 100644
index 0000000..8cccce6
--- /dev/null
+++ b/src/containers/buyer/Orders.tsx
@@ -0,0 +1,118 @@
+import { useState } from "react";
+import { useDispatch } from "react-redux";
+import { setActiveMenu } from "../../redux/slices/buyerDashboard";
+
+function Orders() {
+ const dispatch = useDispatch();
+
+ const orders = [
+ {
+ id: "764376473647634736",
+ status: "Pending",
+ date: "34/67/2024",
+ totalPrice: "$566",
+ },
+ {
+ id: "123456789012345678",
+ status: "Completed",
+ date: "12/01/2024",
+ totalPrice: "$1200",
+ },
+ {
+ id: "987654321098765432",
+ status: "Cancelled",
+ date: "23/03/2024",
+ totalPrice: "$450",
+ },
+ {
+ id: "112233445566778899",
+ status: "Shipped",
+ date: "15/05/2024",
+ totalPrice: "$780",
+ },
+ {
+ id: "998877665544332211",
+ status: "Processing",
+ date: "29/07/2024",
+ totalPrice: "$350",
+ },
+ ];
+
+ const [currentPage, setCurrentPage] = useState(1);
+ const [filter, setFilter] = useState("All");
+
+ const ordersPerPage = 3;
+
+ const handleFilterChange = (e:any) => {
+ setFilter(e.target.value);
+ setCurrentPage(1); // Reset to first page when filter changes
+ };
+
+ const filteredOrders = orders.filter((order) => {
+ if (filter === "All") return true;
+ if (filter === "Pending Payments") return order.status === "Pending";
+ if (filter === "In Transit") return order.status === "Shipped" || order.status === "Processing";
+ return true;
+ });
+
+ const indexOfLastOrder = currentPage * ordersPerPage;
+ const indexOfFirstOrder = indexOfLastOrder - ordersPerPage;
+ const currentOrders = filteredOrders.slice(indexOfFirstOrder, indexOfLastOrder);
+
+ const totalPages = Math.ceil(filteredOrders.length / ordersPerPage);
+
+ const paginate = (pageNumber:any) => setCurrentPage(pageNumber);
+
+ return (
+
+
My Orders
+
+
+
+
+ {currentOrders.map((order) => (
+
+
+
+
+
Status:
+
{order.status}
+
+
+
+
{order.date}
+
+
Total Price:
+
{order.totalPrice}
+
+
+
+
+ ))}
+
+
+ {Array.from({ length: totalPages }, (_, index) => (
+
+ ))}
+
+
+ );
+}
+
+export default Orders;
diff --git a/src/containers/buyer/PendingPayments.tsx b/src/containers/buyer/PendingPayments.tsx
new file mode 100644
index 0000000..a87446c
--- /dev/null
+++ b/src/containers/buyer/PendingPayments.tsx
@@ -0,0 +1,98 @@
+import { useState } from "react";
+import { useDispatch } from "react-redux";
+import { setActiveMenu } from "../../redux/slices/buyerDashboard";
+
+function PendingPayments() {
+ const dispatch = useDispatch();
+
+ // Dummy orders data
+ const orders = [
+ {
+ id: "764376473647634736",
+ status: "Pending",
+ date: "07/14/2024",
+ totalPrice: "$566",
+ },
+ {
+ id: "998877665544332211",
+ status: "Pending",
+ date: "07/15/2024",
+ totalPrice: "$780",
+ },
+ {
+ id: "554433221199887766",
+ status: "Pending",
+ date: "07/16/2024",
+ totalPrice: "$350",
+ },
+ {
+ id: "332211998877665544",
+ status: "Pending",
+ date: "07/17/2024",
+ totalPrice: "$450",
+ },
+ {
+ id: "123456789012345678",
+ status: "Pending",
+ date: "07/18/2024",
+ totalPrice: "$1200",
+ },
+ ];
+
+ const [currentPage, setCurrentPage] = useState(1);
+ const ordersPerPage = 3;
+
+ const indexOfLastOrder = currentPage * ordersPerPage;
+ const indexOfFirstOrder = indexOfLastOrder - ordersPerPage;
+ const currentOrders = orders.slice(indexOfFirstOrder, indexOfLastOrder);
+
+ const totalPages = Math.ceil(orders.length / ordersPerPage);
+
+ const paginate = (pageNumber:any) => setCurrentPage(pageNumber);
+
+ return (
+
+
Pending Payments
+
+ {currentOrders.map((order) => (
+
+
+
+
+
Status:
+
{order.status}
+
+
+
+
{order.date}
+
+
Total Price:
+
{order.totalPrice}
+
+
+
+
+ ))}
+
+
+ {Array.from({ length: totalPages }, (_, index) => (
+
+ ))}
+
+
+ );
+}
+
+export default PendingPayments;
diff --git a/src/containers/buyer/Profile.tsx b/src/containers/buyer/Profile.tsx
new file mode 100644
index 0000000..329869a
--- /dev/null
+++ b/src/containers/buyer/Profile.tsx
@@ -0,0 +1,81 @@
+import { useState } from 'react';
+
+function Profile() {
+ const [email, setEmail] = useState('');
+ const [profilePhoto] = useState(null);
+ const [firstName, setFirstName] = useState('');
+ const [lastName, setLastName] = useState('');
+
+ const handleSubmit = () => {
+ console.log({ email, profilePhoto, firstName, lastName });
+ };
+
+ return (
+
+ );
+}
+
+export default Profile;
diff --git a/src/containers/buyer/ResetPassword.tsx b/src/containers/buyer/ResetPassword.tsx
new file mode 100644
index 0000000..5088701
--- /dev/null
+++ b/src/containers/buyer/ResetPassword.tsx
@@ -0,0 +1,61 @@
+function ResetPassword() {
+ return (
+
+ );
+}
+
+export default ResetPassword;
diff --git a/src/containers/buyer/ReturnRefund.tsx b/src/containers/buyer/ReturnRefund.tsx
new file mode 100644
index 0000000..dfad87c
--- /dev/null
+++ b/src/containers/buyer/ReturnRefund.tsx
@@ -0,0 +1,7 @@
+function ReturnRefund() {
+ return (
+ Return and Refund
+ )
+}
+
+export default ReturnRefund
\ No newline at end of file
diff --git a/src/containers/buyer/Shipping.tsx b/src/containers/buyer/Shipping.tsx
new file mode 100644
index 0000000..b965bb4
--- /dev/null
+++ b/src/containers/buyer/Shipping.tsx
@@ -0,0 +1,7 @@
+function Shipping() {
+ return (
+ Shipping
+ )
+}
+
+export default Shipping
\ No newline at end of file
diff --git a/src/pages/BuyerProfile.tsx b/src/pages/BuyerProfile.tsx
new file mode 100644
index 0000000..867b7ad
--- /dev/null
+++ b/src/pages/BuyerProfile.tsx
@@ -0,0 +1,93 @@
+import Footer from "../components/footer/Footer";
+import Navbar from "../components/navbar/Navbar";
+import Account from "../containers/buyer/Account";
+import Shipping from "../containers/buyer/Shipping";
+import ResetPassword from "../containers/buyer/ResetPassword";
+import Orders from "../containers/buyer/Orders";
+import { setActiveMenu } from "../redux/slices/buyerDashboard";
+import { useSelector } from "react-redux";
+import { useDispatch } from "react-redux";
+import PendingPayments from "../containers/buyer/PendingPayments";
+import FeedBack from "../containers/buyer/FeedBack";
+import InTransit from "../containers/buyer/InTransit";
+import ReturnRefund from "../containers/buyer/ReturnRefund";
+import Profile from "../containers/buyer/Profile";
+import OrderDetails from "../containers/buyer/OderDetails";
+
+
+function BuyerProfile() {
+const activeMenu = useSelector((state:any) => state.activeMenu.activeMenu);
+const dispatch = useDispatch();
+
+ const renderContent = () => {
+ switch (activeMenu) {
+ case "account":
+ return ;
+ case "orders":
+ return ;
+ case "shipping":
+ return ;
+ case "pendingpayments":
+ return ;
+ case "returnrefund":
+ return ;
+ case "feedback":
+ return ;
+ case "intransit":
+ return ;
+ case "reset":
+ return ;
+ case "profile":
+ return ;
+ case "order-details":
+ return ;
+ default:
+ return Select a menu item
;
+ }
+ };
+ //BuyerProfile
+ return (
+
+
+
+
+
+ Buyer Dashboard
+
+
+ - dispatch(setActiveMenu("account"))}
+ >
+ My Account
+
+ - dispatch(setActiveMenu("orders"))}
+ >
+ My Orders
+
+ - dispatch(setActiveMenu("shipping"))}
+ >
+ Shipping Address
+
+ - dispatch(setActiveMenu("reset"))}
+ >
+ Reset Password
+
+
+
+
+ {renderContent()}
+
+
+
+
+ );
+}
+
+export default BuyerProfile;
diff --git a/src/redux/slices/buyerDashboard.tsx b/src/redux/slices/buyerDashboard.tsx
new file mode 100644
index 0000000..0f7dcc7
--- /dev/null
+++ b/src/redux/slices/buyerDashboard.tsx
@@ -0,0 +1,19 @@
+import { createSlice } from "@reduxjs/toolkit";
+
+const initialState = {
+ activeMenu: "account",
+};
+
+const activeMenuSlice = createSlice({
+ name: "activeMenu",
+ initialState,
+ reducers: {
+ setActiveMenu: (state, action) => {
+ state.activeMenu = action.payload;
+ },
+ },
+});
+
+export const { setActiveMenu } = activeMenuSlice.actions;
+
+export default activeMenuSlice.reducer;
diff --git a/src/redux/store.ts b/src/redux/store.ts
index f650c7c..7d40334 100644
--- a/src/redux/store.ts
+++ b/src/redux/store.ts
@@ -6,6 +6,7 @@ import registerReducer from './slices/registerSlice';
import userReducer from './slices/userSlice';
import productReducer from './slices/productsSlice';
import categoriesReducer from './slices/categorySlice';
+import activeMenuReducer from './slices/buyerDashboard';
export const store = configureStore({
reducer: {
@@ -13,6 +14,7 @@ export const store = configureStore({
user: userReducer,
register: registerReducer,
category: categoriesReducer,
+ activeMenu: activeMenuReducer,
[mavericksApi.reducerPath]: mavericksApi.reducer,
},
middleware: getDefaultMiddleware => getDefaultMiddleware().concat(mavericksApi.middleware),