From 0042fbb56545a737f006c55fdc9b71acfa86edcd Mon Sep 17 00:00:00 2001 From: Ikki Date: Mon, 18 Nov 2024 22:07:53 +0530 Subject: [PATCH] cleanup --- .../shop/sub-controllers/adminController.js | 44 --- .../shop/sub-controllers/agentController.js | 300 --------------- .../sub-controllers/analyticcontroller.js | 51 --- .../shop/sub-controllers/couponController.js | 178 --------- .../shop/sub-controllers/damagecontroller.js | 202 ----------- .../deliveryPersonController.js | 269 -------------- .../sub-controllers/giftCardController.js | 311 ---------------- .../sub-controllers/inventoryController.js | 343 ------------------ .../shop/sub-controllers/invoiceController.js | 217 ----------- .../loyaltyPointsController.js | 264 -------------- .../shop/sub-controllers/orderController.js | 297 --------------- .../orderTrackingController.js | 205 ----------- .../shop/sub-controllers/paymentController.js | 161 -------- .../sub-controllers/referralController.js | 202 ----------- .../shop/sub-controllers/returnController.js | 229 ------------ .../shippingAddressController.js | 249 ------------- .../sub-controllers/supplierController.js | 176 --------- .../shop/sub-controllers/ticketController.js | 277 -------------- .../sub-controllers/warehouseController.js | 330 ----------------- .../middleware/sub-ware/agentMiddleware.js | 23 -- .../sub-ware/authSupplierMiddleware.js | 10 - .../middleware/sub-ware/giftCardMiddleware.js | 28 -- .../sub-ware/inventoryMiddleware.js | 38 -- .../middleware/sub-ware/ticketMiddleware.js | 22 -- backend/middleware/sub-ware/validate.js | 15 - backend/middleware/sub-ware/validateCoupon.js | 21 -- .../sub-ware/validatePaymentInvoice.js | 25 -- .../sub-ware/validationMiddleware.js | 28 -- .../sub-ware/warehouseMiddleware.js | 67 ---- backend/model/shop/sub-model/Agent.js | 39 -- .../model/shop/sub-model/DeliveryPerson.js | 44 --- backend/model/shop/sub-model/GiftCard.js | 37 -- .../model/shop/sub-model/InventoryModel.js | 57 --- backend/model/shop/sub-model/OrderHistory.js | 43 --- backend/model/shop/sub-model/OrderTracking.js | 83 ----- backend/model/shop/sub-model/Referral.js | 32 -- backend/model/shop/sub-model/ReturnProduct.js | 42 --- .../model/shop/sub-model/ShippingAddress.js | 37 -- backend/model/shop/sub-model/Supplier.js | 58 --- backend/model/shop/sub-model/TIcket.js | 46 --- backend/model/shop/sub-model/Warehouse.js | 63 ---- backend/model/shop/sub-model/couponModel.js | 61 ---- backend/model/shop/sub-model/damagemodal.js | 27 -- backend/model/shop/sub-model/invoice.js | 47 --- .../model/shop/sub-model/loyaltyPointModel.js | 25 -- backend/model/shop/sub-model/payment.js | 34 -- .../model/shop/sub-model/productanalysis.jsx | 29 -- backend/model/shop/sub-model/useranalysis.js | 25 -- .../shop/sub-model/useranalysiscontroller.js | 172 --------- backend/routes/sub-routes/agentRoutes.js | 39 -- backend/routes/sub-routes/couponRoutes.js | 34 -- backend/routes/sub-routes/giftCardRoutes.js | 38 -- backend/routes/sub-routes/invoiceRoutes.js | 39 -- .../routes/sub-routes/loyaltyPointsRoutes.js | 77 ---- backend/routes/sub-routes/paymentRoutes.js | 34 -- backend/routes/sub-routes/referralRoutes.js | 35 -- backend/routes/sub-routes/returnRoutes.js | 33 -- backend/routes/sub-routes/routesdamage | 54 --- backend/routes/sub-routes/supplierRoutes.js | 50 --- backend/routes/sub-routes/ticketRoutes.js | 54 --- .../services/sub-service/couponValidator.js | 23 -- backend/services/sub-service/giftCardUtils.js | 54 --- backend/services/sub-service/hashPassword.js | 9 - backend/services/sub-service/logger.js | 10 - backend/services/sub-service/referralFunc.js | 136 ------- backend/services/sub-service/referralUtils.js | 8 - .../components/Pages/Admin-Dashboard.jsx | 33 -- .../components/Pages/Admin-Warehouse.jsx | 311 ---------------- .../components/Pages/Admin-login.jsx | 284 --------------- .../components/Pages/AdminTicket.jsx | 124 ------- .../components/Pages/AdminTicketDetails.jsx | 92 ----- .../components/Pages/AdminTicketList.jsx | 38 -- .../AgroShopAI/components/Pages/Affiliate.jsx | 43 --- .../AgroShopAI/components/Pages/BulkPage.jsx | 50 --- .../components/Pages/BundleCard.jsx | 31 -- .../AgroShopAI/components/Pages/BundleData.js | 43 --- .../components/Pages/BundleHeader.jsx | 34 -- .../components/Pages/BundleList.jsx | 24 -- .../components/Pages/BundleLoyaltyMessage.jsx | 13 - .../components/Pages/BundleOverview.jsx | 80 ---- .../components/Pages/BundlePriceBreakdown.jsx | 29 -- .../components/Pages/BundleProductList.jsx | 33 -- .../components/Pages/BundleRelatedItems.jsx | 28 -- .../components/Pages/ConfirmationMessage.jsx | 25 -- .../components/Pages/DeleteModal.jsx | 29 -- .../Pages/DiscountCouponManagement.jsx | 120 ------ .../AgroShopAI/components/Pages/EditModal.jsx | 44 --- .../components/Pages/FarmerSuccessStories.jsx | 47 --- .../Pages/FeaturedProductsSection.jsx | 27 -- .../components/Pages/GiftBenefit.jsx | 40 -- .../AgroShopAI/components/Pages/GiftCard.jsx | 225 ------------ .../AgroShopAI/components/Pages/GiftFaq.jsx | 27 -- .../AgroShopAI/components/Pages/GiftIdeas.jsx | 52 --- .../components/Pages/GiftLetter.jsx | 28 -- .../AgroShopAI/components/Pages/GiftTest.jsx | 30 -- .../components/Pages/HeroSection.jsx | 13 - .../components/Pages/NotficationHeader.jsx | 35 -- .../components/Pages/NotificationPage.jsx | 205 ----------- .../components/Pages/Order-history.jsx | 307 ---------------- .../components/Pages/ProductForm.jsx | 202 ----------- .../components/Pages/ProductList.jsx | 39 -- .../components/Pages/ProductManagement.jsx | 114 ------ .../components/Pages/ReturnPage.jsx | 148 -------- .../components/Pages/SellerDashboard.jsx | 115 ------ .../AgroShopAI/components/Pages/StoryCard.jsx | 25 -- .../components/Pages/StoryHeader.jsx | 9 - .../components/Pages/StoryModal.jsx | 21 -- .../components/Pages/StorySearchBar.jsx | 13 - .../AgroShopAI/components/Pages/THeader.jsx | 31 -- .../components/Pages/TSearchAndFilter.jsx | 43 --- .../components/Pages/TicketDetailModal.jsx | 46 --- .../components/Pages/TicketFilters.jsx | 42 --- .../components/Pages/TicketForm.jsx | 104 ------ .../components/Pages/TicketList.jsx | 60 --- .../components/Pages/TicketUser.jsx | 95 ----- .../components/Pages/Ticketbanner.jsx | 22 -- .../AgroShopAI/components/Pages/Trending.jsx | 120 ------ .../components/Pages/WareInventoryTable.jsx | 78 ---- .../components/Pages/WareSearchAndFilter.jsx | 52 --- .../Pages/components/AboutUsSection.jsx | 36 -- .../Pages/components/ActiveSessions.jsx | 33 -- .../Pages/components/ActivityLog.jsx | 22 -- .../Pages/components/AffiliateDashboard.jsx | 63 ---- .../Pages/components/AffiliateHeader.jsx | 67 ---- .../Pages/components/AffiliateJoinSection.jsx | 50 --- .../AffiliateMarketingMaterials.jsx | 62 ---- .../Pages/components/AffiliateTerms.jsx | 24 -- .../components/Pages/components/Analysis.jsx | 12 - .../components/Pages/components/Banner.jsx | 37 -- .../Pages/components/CouponForm.jsx | 141 ------- .../Pages/components/CouponTable.jsx | 47 --- .../components/Pages/components/CsvUpload.jsx | 46 --- .../Pages/components/DashboardStats.jsx | 22 -- .../components/DeleteConfirmationModal.jsx | 26 -- .../components/Pages/components/Filter.jsx | 78 ---- .../components/Pages/components/FilterBar.jsx | 26 -- .../Pages/components/FlashSaleHeader.jsx | 32 -- .../Pages/components/GrievanceList.jsx | 322 ---------------- .../components/Pages/components/Header.jsx | 16 - .../components/Pages/components/Message.jsx | 12 - .../Pages/components/NavigationButtons.jsx | 33 -- .../Pages/components/Notifications.jsx | 86 ----- .../Pages/components/PasswordForm.jsx | 94 ----- .../Pages/components/PersonalInfo.jsx | 86 ----- .../Pages/components/PolicySection.jsx | 35 -- .../Pages/components/PopularProducts.jsx | 17 - .../Pages/components/ProductCard.jsx | 69 ---- .../Pages/components/ProductCarousel.jsx | 83 ----- .../Pages/components/ProductEntry.jsx | 105 ------ .../Pages/components/ProductGrid.jsx | 12 - .../Pages/components/ProductList.jsx | 13 - .../Pages/components/ProductStepForm.jsx | 132 ------- .../Pages/components/ProfileManage.jsx | 107 ------ .../Pages/components/ProfileSection.jsx | 123 ------- .../Pages/components/QuickBuyModal.jsx | 24 -- .../Pages/components/ReturnAdminFilter.jsx | 22 -- .../Pages/components/ReturnAdminHeader.jsx | 9 - .../Pages/components/ReturnAdminHistory.jsx | 26 -- .../Pages/components/ReturnAdminModal.jsx | 81 ----- .../components/ReturnAdminProductCard.jsx | 20 - .../Pages/components/ReturnFilter.jsx | 21 -- .../Pages/components/ReturnHeader.jsx | 16 - .../Pages/components/ReturnHistory.jsx | 39 -- .../Pages/components/ReturnModal.jsx | 84 ----- .../Pages/components/ReturnPage.jsx | 182 ---------- .../Pages/components/ReturnProductCard.jsx | 38 -- .../components/Pages/components/SalePage.jsx | 187 ---------- .../Pages/components/SalesTrend.jsx | 21 -- .../Pages/components/SearchAndSort.jsx | 63 ---- .../Pages/components/SecuritySettings.jsx | 36 -- .../Pages/components/SellerAnalyticsPage.jsx | 12 - .../Pages/components/SellerDashboardPage.jsx | 62 ---- .../components/Pages/components/SellerNav.jsx | 38 -- .../components/SellerOrderManagementPage.jsx | 13 - .../SellerProductManagementPage.jsx | 76 ---- .../Pages/components/SellerSettingsPage.jsx | 93 ----- .../Pages/components/Sellerheader.jsx | 11 - .../components/Pages/components/Sidebar.jsx | 113 ------ .../components/Pages/components/StatCard.jsx | 10 - .../Pages/components/StatisticComponent.jsx | 102 ------ .../Pages/components/SuccessPage.jsx | 113 ------ .../components/Pages/components/THeader.jsx | 32 -- .../Pages/components/TProductCard.jsx | 59 --- .../components/Pages/components/TabNav.jsx | 30 -- .../Pages/components/TimeRangeSelector.jsx | 19 - .../Pages/components/UserRegistrations.jsx | 19 - .../AgroShopAI/components/ReviewSection.jsx | 2 +- frontend/src/AgroShopAI/pages/Review.jsx | 173 --------- frontend/src/AgroShopAI/pages/ReviewItem.jsx | 18 - frontend/src/AgroShopAI/pages/Reviewpage.jsx | 41 --- frontend/src/MainContent.jsx | 34 +- 191 files changed, 2 insertions(+), 14339 deletions(-) delete mode 100644 backend/controllers/shop/sub-controllers/adminController.js delete mode 100644 backend/controllers/shop/sub-controllers/agentController.js delete mode 100644 backend/controllers/shop/sub-controllers/analyticcontroller.js delete mode 100644 backend/controllers/shop/sub-controllers/couponController.js delete mode 100644 backend/controllers/shop/sub-controllers/damagecontroller.js delete mode 100644 backend/controllers/shop/sub-controllers/deliveryPersonController.js delete mode 100644 backend/controllers/shop/sub-controllers/giftCardController.js delete mode 100644 backend/controllers/shop/sub-controllers/inventoryController.js delete mode 100644 backend/controllers/shop/sub-controllers/invoiceController.js delete mode 100644 backend/controllers/shop/sub-controllers/loyaltyPointsController.js delete mode 100644 backend/controllers/shop/sub-controllers/orderController.js delete mode 100644 backend/controllers/shop/sub-controllers/orderTrackingController.js delete mode 100644 backend/controllers/shop/sub-controllers/paymentController.js delete mode 100644 backend/controllers/shop/sub-controllers/referralController.js delete mode 100644 backend/controllers/shop/sub-controllers/returnController.js delete mode 100644 backend/controllers/shop/sub-controllers/shippingAddressController.js delete mode 100644 backend/controllers/shop/sub-controllers/supplierController.js delete mode 100644 backend/controllers/shop/sub-controllers/ticketController.js delete mode 100644 backend/controllers/shop/sub-controllers/warehouseController.js delete mode 100644 backend/middleware/sub-ware/agentMiddleware.js delete mode 100644 backend/middleware/sub-ware/authSupplierMiddleware.js delete mode 100644 backend/middleware/sub-ware/giftCardMiddleware.js delete mode 100644 backend/middleware/sub-ware/inventoryMiddleware.js delete mode 100644 backend/middleware/sub-ware/ticketMiddleware.js delete mode 100644 backend/middleware/sub-ware/validate.js delete mode 100644 backend/middleware/sub-ware/validateCoupon.js delete mode 100644 backend/middleware/sub-ware/validatePaymentInvoice.js delete mode 100644 backend/middleware/sub-ware/validationMiddleware.js delete mode 100644 backend/middleware/sub-ware/warehouseMiddleware.js delete mode 100644 backend/model/shop/sub-model/Agent.js delete mode 100644 backend/model/shop/sub-model/DeliveryPerson.js delete mode 100644 backend/model/shop/sub-model/GiftCard.js delete mode 100644 backend/model/shop/sub-model/InventoryModel.js delete mode 100644 backend/model/shop/sub-model/OrderHistory.js delete mode 100644 backend/model/shop/sub-model/OrderTracking.js delete mode 100644 backend/model/shop/sub-model/Referral.js delete mode 100644 backend/model/shop/sub-model/ReturnProduct.js delete mode 100644 backend/model/shop/sub-model/ShippingAddress.js delete mode 100644 backend/model/shop/sub-model/Supplier.js delete mode 100644 backend/model/shop/sub-model/TIcket.js delete mode 100644 backend/model/shop/sub-model/Warehouse.js delete mode 100644 backend/model/shop/sub-model/couponModel.js delete mode 100644 backend/model/shop/sub-model/damagemodal.js delete mode 100644 backend/model/shop/sub-model/invoice.js delete mode 100644 backend/model/shop/sub-model/loyaltyPointModel.js delete mode 100644 backend/model/shop/sub-model/payment.js delete mode 100644 backend/model/shop/sub-model/productanalysis.jsx delete mode 100644 backend/model/shop/sub-model/useranalysis.js delete mode 100644 backend/model/shop/sub-model/useranalysiscontroller.js delete mode 100644 backend/routes/sub-routes/agentRoutes.js delete mode 100644 backend/routes/sub-routes/couponRoutes.js delete mode 100644 backend/routes/sub-routes/giftCardRoutes.js delete mode 100644 backend/routes/sub-routes/invoiceRoutes.js delete mode 100644 backend/routes/sub-routes/loyaltyPointsRoutes.js delete mode 100644 backend/routes/sub-routes/paymentRoutes.js delete mode 100644 backend/routes/sub-routes/referralRoutes.js delete mode 100644 backend/routes/sub-routes/returnRoutes.js delete mode 100644 backend/routes/sub-routes/routesdamage delete mode 100644 backend/routes/sub-routes/supplierRoutes.js delete mode 100644 backend/routes/sub-routes/ticketRoutes.js delete mode 100644 backend/services/sub-service/couponValidator.js delete mode 100644 backend/services/sub-service/giftCardUtils.js delete mode 100644 backend/services/sub-service/hashPassword.js delete mode 100644 backend/services/sub-service/logger.js delete mode 100644 backend/services/sub-service/referralFunc.js delete mode 100644 backend/services/sub-service/referralUtils.js delete mode 100644 frontend/src/AgroShopAI/components/Pages/Admin-Dashboard.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/Admin-Warehouse.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/Admin-login.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/AdminTicket.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/AdminTicketDetails.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/AdminTicketList.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/Affiliate.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/BulkPage.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/BundleCard.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/BundleData.js delete mode 100644 frontend/src/AgroShopAI/components/Pages/BundleHeader.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/BundleList.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/BundleLoyaltyMessage.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/BundleOverview.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/BundlePriceBreakdown.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/BundleProductList.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/BundleRelatedItems.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/ConfirmationMessage.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/DeleteModal.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/DiscountCouponManagement.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/EditModal.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/FarmerSuccessStories.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/FeaturedProductsSection.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/GiftBenefit.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/GiftCard.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/GiftFaq.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/GiftIdeas.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/GiftLetter.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/GiftTest.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/HeroSection.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/NotficationHeader.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/NotificationPage.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/Order-history.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/ProductForm.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/ProductList.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/ProductManagement.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/ReturnPage.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/SellerDashboard.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/StoryCard.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/StoryHeader.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/StoryModal.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/StorySearchBar.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/THeader.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/TSearchAndFilter.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/TicketDetailModal.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/TicketFilters.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/TicketForm.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/TicketList.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/TicketUser.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/Ticketbanner.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/Trending.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/WareInventoryTable.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/WareSearchAndFilter.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/AboutUsSection.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/ActiveSessions.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/ActivityLog.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/AffiliateDashboard.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/AffiliateHeader.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/AffiliateJoinSection.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/AffiliateMarketingMaterials.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/AffiliateTerms.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/Analysis.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/Banner.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/CouponForm.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/CouponTable.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/CsvUpload.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/DashboardStats.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/DeleteConfirmationModal.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/Filter.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/FilterBar.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/FlashSaleHeader.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/GrievanceList.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/Header.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/Message.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/NavigationButtons.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/Notifications.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/PasswordForm.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/PersonalInfo.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/PolicySection.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/PopularProducts.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/ProductCard.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/ProductCarousel.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/ProductEntry.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/ProductGrid.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/ProductList.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/ProductStepForm.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/ProfileManage.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/ProfileSection.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/QuickBuyModal.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/ReturnAdminFilter.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/ReturnAdminHeader.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/ReturnAdminHistory.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/ReturnAdminModal.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/ReturnAdminProductCard.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/ReturnFilter.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/ReturnHeader.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/ReturnHistory.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/ReturnModal.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/ReturnPage.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/ReturnProductCard.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/SalePage.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/SalesTrend.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/SearchAndSort.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/SecuritySettings.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/SellerAnalyticsPage.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/SellerDashboardPage.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/SellerNav.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/SellerOrderManagementPage.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/SellerProductManagementPage.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/SellerSettingsPage.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/Sellerheader.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/Sidebar.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/StatCard.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/StatisticComponent.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/SuccessPage.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/THeader.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/TProductCard.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/TabNav.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/TimeRangeSelector.jsx delete mode 100644 frontend/src/AgroShopAI/components/Pages/components/UserRegistrations.jsx delete mode 100644 frontend/src/AgroShopAI/pages/Review.jsx delete mode 100644 frontend/src/AgroShopAI/pages/ReviewItem.jsx delete mode 100644 frontend/src/AgroShopAI/pages/Reviewpage.jsx diff --git a/backend/controllers/shop/sub-controllers/adminController.js b/backend/controllers/shop/sub-controllers/adminController.js deleted file mode 100644 index 61f9054d..00000000 --- a/backend/controllers/shop/sub-controllers/adminController.js +++ /dev/null @@ -1,44 +0,0 @@ -const Payment = require("../models/payment"); -const Invoice = require("../models/invoice"); - -// Admin view all payments -const adminViewPayments = async (req, res) => { - try { - const payments = await Payment.find() - .populate("orderId") - .populate("userId"); - res.status(200).json(payments); - } catch (error) { - res.status(500).json({ message: error.message }); - } -}; - -// Admin view all invoices -const adminViewInvoices = async (req, res) => { - try { - const invoices = await Invoice.find() - .populate("orderId") - .populate("userId"); - res.status(200).json(invoices); - } catch (error) { - res.status(500).json({ message: error.message }); - } -}; - -// Admin filter/sort payments -const adminFilterPayments = async (req, res) => { - const { status, startDate, endDate } = req.query; - const filters = {}; - if (status) filters.paymentStatus = status; - if (startDate && endDate) - filters.paymentDate = { $gte: startDate, $lte: endDate }; - - try { - const payments = await Payment.find(filters); - res.status(200).json(payments); - } catch (error) { - res.status(500).json({ message: error.message }); - } -}; - -module.exports = { adminViewPayments, adminViewInvoices, adminFilterPayments }; diff --git a/backend/controllers/shop/sub-controllers/agentController.js b/backend/controllers/shop/sub-controllers/agentController.js deleted file mode 100644 index ad4ac2a3..00000000 --- a/backend/controllers/shop/sub-controllers/agentController.js +++ /dev/null @@ -1,300 +0,0 @@ -const Agent = require("../../../model/shop/sub-model/Agent"); -const Ticket = require("../../../model/shop/sub-model/TIcket"); // Assuming Ticket model is defined - -// Create a new agent -exports.createAgent = async (req, res) => { - try { - const { name, email, role } = req.body; - - // Validate input - if (!name || !email || !role) { - return res - .status(400) - .json({ message: "Name, email, and role are required" }); - } - - // Check if email already exists - const existingAgent = await Agent.findOne({ email }); - if (existingAgent) { - return res - .status(400) - .json({ message: "Agent with this email already exists" }); - } - - const agent = new Agent({ name, email, role }); - await agent.save(); - - res.status(201).json({ message: "Agent created successfully", agent }); - } catch (err) { - res.status(500).json({ message: "Error creating agent", error: err }); - } -}; - -// Get all agents -exports.getAllAgents = async (req, res) => { - try { - const agents = await Agent.find(); - - if (agents.length === 0) { - return res.status(404).json({ message: "No agents found" }); - } - - res.status(200).json(agents); - } catch (err) { - res.status(500).json({ message: "Error fetching agents", error: err }); - } -}; - -// Get agent by ID -exports.getAgentById = async (req, res) => { - try { - const agent = await Agent.findById(req.params.id); - - if (!agent) { - return res.status(404).json({ message: "Agent not found" }); - } - - res.status(200).json(agent); - } catch (err) { - res.status(400).json({ message: "Invalid agent ID", error: err }); - } -}; - -// Update agent by ID -exports.updateAgent = async (req, res) => { - try { - const { name, email, role, status } = req.body; - - // Ensure at least one field to update is provided - if (!name && !email && !role && !status) { - return res.status(400).json({ message: "No fields provided to update" }); - } - - const agent = await Agent.findByIdAndUpdate( - req.params.id, - { name, email, role, status }, - { new: true, runValidators: true } - ); - - if (!agent) { - return res.status(404).json({ message: "Agent not found" }); - } - - res.status(200).json(agent); - } catch (err) { - res.status(500).json({ message: "Error updating agent", error: err }); - } -}; - -// Delete agent by ID -exports.deleteAgent = async (req, res) => { - try { - const agent = await Agent.findById(req.params.id); - - if (!agent) { - return res.status(404).json({ message: "Agent not found" }); - } - - // Ensure agent is not assigned to any active tickets before deletion - if (agent.assigned_tickets.length > 0) { - return res - .status(400) - .json({ - message: "Agent cannot be deleted as they have active tickets", - }); - } - - await Agent.findByIdAndDelete(req.params.id); - res.status(200).json({ message: "Agent deleted successfully" }); - } catch (err) { - res.status(500).json({ message: "Error deleting agent", error: err }); - } -}; - -// Assign a ticket to an agent -exports.assignTicketToAgent = async (req, res) => { - try { - const { ticketId } = req.body; - const agent = await Agent.findById(req.params.id); - const ticket = await Ticket.findById(ticketId); - - // Check if agent and ticket exist - if (!agent || !ticket) { - return res.status(404).json({ message: "Agent or Ticket not found" }); - } - - // Check if agent is inactive - if (agent.status === "inactive") { - return res - .status(400) - .json({ message: "Cannot assign ticket to an inactive agent" }); - } - - // Prevent assigning ticket if it is already assigned - if (ticket.status === "assigned") { - return res - .status(400) - .json({ message: "Ticket is already assigned to another agent" }); - } - - // Assign the ticket to the agent - agent.assigned_tickets.push(ticketId); - await agent.save(); - - // Update ticket status to 'assigned' - ticket.status = "assigned"; - await ticket.save(); - - res - .status(200) - .json({ message: "Ticket assigned to agent successfully", agent }); - } catch (err) { - res - .status(500) - .json({ message: "Error assigning ticket to agent", error: err }); - } -}; - -// Unassign a ticket from an agent -exports.unassignTicketFromAgent = async (req, res) => { - try { - const { ticketId } = req.body; - const agent = await Agent.findById(req.params.id); - const ticket = await Ticket.findById(ticketId); - - // Check if agent and ticket exist - if (!agent || !ticket) { - return res.status(404).json({ message: "Agent or Ticket not found" }); - } - - // Check if the ticket is assigned to this agent - if (!agent.assigned_tickets.includes(ticketId)) { - return res - .status(400) - .json({ message: "Ticket is not assigned to this agent" }); - } - - // Remove ticket from agent's assigned tickets - agent.assigned_tickets = agent.assigned_tickets.filter( - (id) => id.toString() !== ticketId - ); - await agent.save(); - - // Update ticket status to 'unassigned' - ticket.status = "unassigned"; - await ticket.save(); - - res - .status(200) - .json({ message: "Ticket unassigned from agent successfully", agent }); - } catch (err) { - res - .status(500) - .json({ message: "Error unassigning ticket from agent", error: err }); - } -}; - -// Change the status of an agent (active/inactive) -exports.changeAgentStatus = async (req, res) => { - try { - const { status } = req.body; - - // Ensure status is valid - if (!["active", "inactive"].includes(status)) { - return res - .status(400) - .json({ message: "Invalid status value, must be active or inactive" }); - } - - const agent = await Agent.findById(req.params.id); - - if (!agent) { - return res.status(404).json({ message: "Agent not found" }); - } - - agent.status = status; - await agent.save(); - - res - .status(200) - .json({ message: `Agent status updated to ${status}`, agent }); - } catch (err) { - res - .status(500) - .json({ message: "Error changing agent status", error: err }); - } -}; - -// Assign multiple tickets to an agent -exports.assignMultipleTickets = async (req, res) => { - try { - const { ticketIds } = req.body; // Expecting an array of ticket IDs - const agent = await Agent.findById(req.params.id); - - // Check if agent exists - if (!agent) { - return res.status(404).json({ message: "Agent not found" }); - } - - // Validate ticket IDs - const tickets = await Ticket.find({ _id: { $in: ticketIds } }); - - // Ensure all ticket IDs are valid - if (tickets.length !== ticketIds.length) { - return res.status(400).json({ message: "Some tickets were not found" }); - } - - // Check if any ticket is already assigned - const assignedTickets = tickets.filter( - (ticket) => ticket.status === "assigned" - ); - if (assignedTickets.length > 0) { - return res - .status(400) - .json({ message: "Some tickets are already assigned" }); - } - - // Assign tickets to agent - agent.assigned_tickets.push(...ticketIds); - await agent.save(); - - // Update ticket status to 'assigned' - for (let ticket of tickets) { - ticket.status = "assigned"; - await ticket.save(); - } - - res - .status(200) - .json({ - message: "Multiple tickets assigned to agent successfully", - agent, - }); - } catch (err) { - res - .status(500) - .json({ message: "Error assigning multiple tickets", error: err }); - } -}; - -// Handle Agent Role-based Access (admin vs support) -exports.checkAgentRole = async (req, res, next) => { - try { - const agent = await Agent.findById(req.params.id); - if (!agent) { - return res.status(404).json({ message: "Agent not found" }); - } - - if (agent.role !== "admin") { - return res - .status(403) - .json({ - message: "Permission denied, only admin can perform this action", - }); - } - - next(); - } catch (err) { - res.status(500).json({ message: "Error checking agent role", error: err }); - } -}; diff --git a/backend/controllers/shop/sub-controllers/analyticcontroller.js b/backend/controllers/shop/sub-controllers/analyticcontroller.js deleted file mode 100644 index 805ee9cd..00000000 --- a/backend/controllers/shop/sub-controllers/analyticcontroller.js +++ /dev/null @@ -1,51 +0,0 @@ -const ProductAnalysis = require("../models/ProductAnalysis"); - -exports.createProductAnalysis = async (req, res) => { - try { - const { productId, views, sales, ratings, feedback } = req.body; - const productAnalysis = new ProductAnalysis({ - productId, - views, - sales, - ratings, - feedback, - }); - await productAnalysis.save(); - res.status(201).json(productAnalysis); - } catch (error) { - res - .status(400) - .json({ message: "Error creating product analysis data", error }); - } -}; - -exports.getProductAnalysis = async (req, res) => { - try { - const productAnalysis = await ProductAnalysis.findById(req.params.id); - if (!productAnalysis) - return res.status(404).json({ message: "Product analysis not found" }); - res.status(200).json(productAnalysis); - } catch (error) { - res - .status(400) - .json({ message: "Error retrieving product analysis", error }); - } -}; - -exports.updateProductAnalysis = async (req, res) => { - try { - const updatedData = req.body; - const productAnalysis = await ProductAnalysis.findByIdAndUpdate( - req.params.id, - updatedData, - { new: true } - ); - if (!productAnalysis) - return res.status(404).json({ message: "Product analysis not found" }); - res.status(200).json(productAnalysis); - } catch (error) { - res - .status(400) - .json({ message: "Error updating product analysis data", error }); - } -}; diff --git a/backend/controllers/shop/sub-controllers/couponController.js b/backend/controllers/shop/sub-controllers/couponController.js deleted file mode 100644 index 1cead2f0..00000000 --- a/backend/controllers/shop/sub-controllers/couponController.js +++ /dev/null @@ -1,178 +0,0 @@ -const Coupon = require("../../../model/shop/sub-model/couponModel"); -const { validateCoupon } = require("../../../services/sub-service/couponValidator"); - -// Controller to Create a Coupon -exports.createCoupon = async (req, res) => { - try { - const coupon = new Coupon(req.body); - await coupon.save(); - res.status(201).json({ message: "Coupon created successfully", coupon }); - } catch (err) { - res.status(400).json({ error: err.message }); - } -}; - -// Controller to Get All Coupons -exports.getCoupons = async (req, res) => { - try { - const { status, minOrderAmount, startDate, endDate } = req.query; - const filters = {}; - - if (status) filters.status = status; - if (minOrderAmount) filters.minOrderAmount = { $gte: minOrderAmount }; - if (startDate || endDate) { - filters.startDate = { $gte: startDate || new Date() }; - filters.endDate = { $lte: endDate || new Date() }; - } - - const coupons = await Coupon.find(filters); - res.status(200).json(coupons); - } catch (err) { - res.status(400).json({ error: err.message }); - } -}; - -// Controller to Get Coupon by Code -exports.getCouponByCode = async (req, res) => { - try { - const coupon = await Coupon.findOne({ code: req.params.code }); - if (!coupon) { - return res.status(404).json({ error: "Coupon not found" }); - } - res.status(200).json(coupon); - } catch (err) { - res.status(400).json({ error: err.message }); - } -}; - -// Controller to Update Coupon -exports.updateCoupon = async (req, res) => { - try { - const updatedCoupon = await Coupon.findOneAndUpdate( - { code: req.params.code }, - { $set: req.body, updatedAt: Date.now() }, - { new: true } - ); - if (!updatedCoupon) { - return res.status(404).json({ error: "Coupon not found" }); - } - res.status(200).json(updatedCoupon); - } catch (err) { - res.status(400).json({ error: err.message }); - } -}; - -// Controller to Delete Coupon -exports.deleteCoupon = async (req, res) => { - try { - const deletedCoupon = await Coupon.findOneAndDelete({ - code: req.params.code, - }); - if (!deletedCoupon) { - return res.status(404).json({ error: "Coupon not found" }); - } - res.status(200).json({ message: "Coupon deleted successfully" }); - } catch (err) { - res.status(400).json({ error: err.message }); - } -}; - -// Controller to Validate Coupon -exports.validateCoupon = async (req, res, next) => { - const { code, orderAmount } = req.body; - try { - const coupon = await Coupon.findOne({ code }); - if (!coupon) return res.status(404).json({ error: "Coupon not found" }); - - // Validate coupon using helper function - const isValid = await validateCoupon(coupon, orderAmount); - if (!isValid) return res.status(400).json({ error: "Coupon is invalid" }); - - req.coupon = coupon; // Attach coupon to the request object for use in further steps - next(); - } catch (err) { - res.status(500).json({ error: "Error validating coupon" }); - } -}; - -// Controller to Track Coupon Usage (Increment Usage Count) -exports.incrementUsageCount = async (req, res) => { - try { - const { code } = req.body; - const coupon = await Coupon.findOne({ code }); - if (!coupon) return res.status(404).json({ error: "Coupon not found" }); - - // Increment the usage count by 1 - coupon.usageCount += 1; - - // Check if the usage limit has been reached - if (coupon.usageCount > coupon.usageLimit) { - return res.status(400).json({ error: "Coupon usage limit exceeded" }); - } - - await coupon.save(); - res.status(200).json({ message: "Coupon usage count incremented", coupon }); - } catch (err) { - res.status(400).json({ error: err.message }); - } -}; - -// Controller to Activate/Deactivate Coupon -exports.toggleCouponStatus = async (req, res) => { - try { - const { code } = req.params; - const { status } = req.body; // 'active' or 'inactive' - - if (!["active", "inactive"].includes(status)) { - return res.status(400).json({ error: "Invalid status value" }); - } - - const coupon = await Coupon.findOneAndUpdate( - { code }, - { status, updatedAt: Date.now() }, - { new: true } - ); - if (!coupon) { - return res.status(404).json({ error: "Coupon not found" }); - } - - res.status(200).json({ message: "Coupon status updated", coupon }); - } catch (err) { - res.status(400).json({ error: err.message }); - } -}; - -// Controller to Apply Coupon to an Order -exports.applyCouponToOrder = async (req, res) => { - const { code, orderAmount } = req.body; - try { - const coupon = await Coupon.findOne({ code }); - if (!coupon) return res.status(404).json({ error: "Coupon not found" }); - - const isValid = await validateCoupon(coupon, orderAmount); - if (!isValid) { - return res - .status(400) - .json({ error: "Coupon is invalid for this order" }); - } - - const discount = - coupon.discountType === "percentage" - ? (coupon.discountValue / 100) * orderAmount - : coupon.discountValue; - - // Apply max discount if it exists - const finalDiscount = coupon.maxDiscount - ? Math.min(discount, coupon.maxDiscount) - : discount; - - res - .status(200) - .json({ - message: "Coupon applied successfully", - discount: finalDiscount, - }); - } catch (err) { - res.status(400).json({ error: err.message }); - } -}; diff --git a/backend/controllers/shop/sub-controllers/damagecontroller.js b/backend/controllers/shop/sub-controllers/damagecontroller.js deleted file mode 100644 index 6c95eb5d..00000000 --- a/backend/controllers/shop/sub-controllers/damagecontroller.js +++ /dev/null @@ -1,202 +0,0 @@ -const MalfunctioningProduct = require("../models/MalfunctioningProduct"); -const mongoose = require("mongoose"); - -// Create malfunctioning product -exports.createMalfunctioningProduct = async (req, res) => { - try { - const { productId, description, actionsTaken, createdBy } = req.body; - - // Validate if productId exists and is valid - if (!mongoose.Types.ObjectId.isValid(productId)) { - return res.status(400).json({ message: "Invalid product ID" }); - } - - // Check if the user exists - const userExists = await User.findById(createdBy); - if (!userExists) { - return res.status(404).json({ message: "User not found" }); - } - - const newProduct = new MalfunctioningProduct({ - productId, - description, - actionsTaken, - createdBy, - }); - - await newProduct.save(); - res.status(201).json(newProduct); - } catch (error) { - console.error(error); - res - .status(400) - .json({ - message: "Error creating malfunctioning product", - error: error.message, - }); - } -}; - -// Get malfunctioning product by ID -exports.getMalfunctioningProduct = async (req, res) => { - try { - const productId = req.params.id; - - // Validate if productId exists and is valid - if (!mongoose.Types.ObjectId.isValid(productId)) { - return res.status(400).json({ message: "Invalid product ID format" }); - } - - const product = await MalfunctioningProduct.findById(productId).populate( - "productId" - ); - - // Handle case where product is not found - if (!product) { - return res - .status(404) - .json({ message: "Malfunctioning product not found" }); - } - - res.status(200).json(product); - } catch (error) { - console.error(error); - res - .status(500) - .json({ - message: "Error retrieving malfunctioning product", - error: error.message, - }); - } -}; - -// Update malfunctioning product -exports.updateMalfunctioningProduct = async (req, res) => { - try { - const updatedData = req.body; - const productId = req.params.id; - - // Validate if productId exists and is valid - if (!mongoose.Types.ObjectId.isValid(productId)) { - return res.status(400).json({ message: "Invalid product ID format" }); - } - - // Check if any field is being updated and validate - if ( - !updatedData.productId && - !updatedData.description && - !updatedData.actionsTaken - ) { - return res.status(400).json({ message: "No valid fields to update" }); - } - - const product = await MalfunctioningProduct.findByIdAndUpdate( - productId, - updatedData, - { new: true } - ); - - // Handle case where product is not found - if (!product) { - return res.status(404).json({ message: "Product not found" }); - } - - res.status(200).json(product); - } catch (error) { - console.error(error); - res - .status(500) - .json({ - message: "Error updating malfunctioning product", - error: error.message, - }); - } -}; - -// Delete malfunctioning product -exports.deleteMalfunctioningProduct = async (req, res) => { - try { - const productId = req.params.id; - - // Validate if productId exists and is valid - if (!mongoose.Types.ObjectId.isValid(productId)) { - return res.status(400).json({ message: "Invalid product ID format" }); - } - - const product = await MalfunctioningProduct.findByIdAndDelete(productId); - - // Handle case where product is not found - if (!product) { - return res - .status(404) - .json({ message: "Malfunctioning product not found" }); - } - - res.status(200).json({ message: "Product deleted successfully" }); - } catch (error) { - console.error(error); - res - .status(500) - .json({ - message: "Error deleting malfunctioning product", - error: error.message, - }); - } -}; - -// Get all malfunctioning products with pagination and search -exports.getAllMalfunctioningProducts = async (req, res) => { - try { - const { page = 1, limit = 10, search = "" } = req.query; - const skip = (page - 1) * limit; - - const query = search - ? { description: { $regex: search, $options: "i" } } - : {}; - - const products = await MalfunctioningProduct.find(query) - .skip(skip) - .limit(parseInt(limit)) - .populate("productId") - .exec(); - - const totalCount = await MalfunctioningProduct.countDocuments(query); - - res.status(200).json({ - totalCount, - totalPages: Math.ceil(totalCount / limit), - currentPage: page, - products, - }); - } catch (error) { - console.error(error); - res - .status(500) - .json({ - message: "Error fetching malfunctioning products", - error: error.message, - }); - } -}; - -// Get count of malfunctioning products by status -exports.getMalfunctioningProductCountByStatus = async (req, res) => { - try { - const { status } = req.params; - - if (!["pending", "in progress", "resolved"].includes(status)) { - return res.status(400).json({ message: "Invalid status" }); - } - - const count = await MalfunctioningProduct.countDocuments({ status }); - res.status(200).json({ count }); - } catch (error) { - console.error(error); - res - .status(500) - .json({ - message: "Error fetching count by status", - error: error.message, - }); - } -}; diff --git a/backend/controllers/shop/sub-controllers/deliveryPersonController.js b/backend/controllers/shop/sub-controllers/deliveryPersonController.js deleted file mode 100644 index ea24cc4b..00000000 --- a/backend/controllers/shop/sub-controllers/deliveryPersonController.js +++ /dev/null @@ -1,269 +0,0 @@ -const DeliveryPerson = require("../../../model/shop/sub-model/DeliveryPerson"); -const { hashPassword } = require("../../../services/sub-service/hashPassword"); -const { - validateEmail, - validatePhoneNumber, -} = require("../../../services/sub-service/couponValidator"); - -exports.successResponse = (res, statusCode, message, data = {}) => { - res.status(statusCode).json({ - status: "success", - message, - data, - }); -}; - -exports.errorResponse = (res, statusCode, message, error = {}) => { - res.status(statusCode).json({ - status: "error", - message, - error, - }); -}; - -// Create a new Delivery Person -exports.createDeliveryPerson = async (req, res) => { - try { - const { - name, - email, - phone_number, - status, - assigned_routes, - vehicle_details, - profile_picture, - password, - } = req.body; - - // Validate required fields - if (!name || !email || !phone_number || !status) { - return errorResponse(res, 400, "All required fields must be provided."); - } - - // Validate email and phone number formats - if (!validateEmail(email)) - return errorResponse(res, 400, "Invalid email format."); - if (!validatePhoneNumber(phone_number)) - return errorResponse(res, 400, "Invalid phone number format."); - - // Check if email already exists - const existingEmail = await DeliveryPerson.findOne({ email }); - if (existingEmail) return errorResponse(res, 400, "Email already exists."); - - // Hash password if provided - const hashedPassword = password ? await hashPassword(password) : undefined; - - const newDeliveryPerson = new DeliveryPerson({ - name, - email, - phone_number, - status, - assigned_routes, - vehicle_details, - profile_picture, - password: hashedPassword, - }); - - await newDeliveryPerson.save(); - successResponse( - res, - 201, - "Delivery person created successfully.", - newDeliveryPerson - ); - } catch (error) { - errorResponse(res, 500, error.message); - } -}; - -// Get all Delivery Persons with pagination -exports.getAllDeliveryPersons = async (req, res) => { - try { - const { page = 1, limit = 10 } = req.query; - const deliveryPersons = await DeliveryPerson.find() - .select("name status vehicle_details.vehicle_type") - .limit(parseInt(limit)) - .skip((parseInt(page) - 1) * parseInt(limit)); - const count = await DeliveryPerson.countDocuments(); - - successResponse(res, 200, "Delivery persons retrieved successfully.", { - deliveryPersons, - totalPages: Math.ceil(count / limit), - currentPage: parseInt(page), - }); - } catch (error) { - errorResponse(res, 500, error.message); - } -}; - -// Get a Delivery Person by ID -exports.getDeliveryPersonById = async (req, res) => { - try { - const deliveryPerson = await DeliveryPerson.findById( - req.params.id - ).populate("assigned_routes"); - if (!deliveryPerson) - return errorResponse(res, 404, "Delivery person not found."); - successResponse( - res, - 200, - "Delivery person retrieved successfully.", - deliveryPerson - ); - } catch (error) { - errorResponse(res, 500, error.message); - } -}; - -// Update a Delivery Person -exports.updateDeliveryPerson = async (req, res) => { - try { - const updates = req.body; - - // Validate and hash password if provided - if (updates.password) - updates.password = await hashPassword(updates.password); - - // Validate email and phone number if updated - if (updates.email && !validateEmail(updates.email)) - return errorResponse(res, 400, "Invalid email format."); - if (updates.phone_number && !validatePhoneNumber(updates.phone_number)) - return errorResponse(res, 400, "Invalid phone number format."); - - // Check if email already exists (excluding current delivery person) - if (updates.email) { - const existingEmail = await DeliveryPerson.findOne({ - email: updates.email, - _id: { $ne: req.params.id }, - }); - if (existingEmail) - return errorResponse(res, 400, "Email already exists."); - } - - const updatedDeliveryPerson = await DeliveryPerson.findByIdAndUpdate( - req.params.id, - updates, - { new: true } - ); - if (!updatedDeliveryPerson) - return errorResponse(res, 404, "Delivery person not found."); - successResponse( - res, - 200, - "Delivery person updated successfully.", - updatedDeliveryPerson - ); - } catch (error) { - errorResponse(res, 500, error.message); - } -}; - -// Soft delete (deactivate) a Delivery Person -exports.deleteDeliveryPerson = async (req, res) => { - try { - const deliveryPerson = await DeliveryPerson.findById(req.params.id); - if (!deliveryPerson) - return errorResponse(res, 404, "Delivery person not found."); - - deliveryPerson.status = "inactive"; - await deliveryPerson.save(); - successResponse(res, 200, "Delivery person deactivated successfully."); - } catch (error) { - errorResponse(res, 500, error.message); - } -}; - -// Activate or Deactivate Delivery Person -exports.toggleStatus = async (req, res) => { - try { - const { status } = req.body; - if (!["active", "inactive"].includes(status)) - return errorResponse(res, 400, "Invalid status."); - - const deliveryPerson = await DeliveryPerson.findById(req.params.id); - if (!deliveryPerson) - return errorResponse(res, 404, "Delivery person not found."); - - deliveryPerson.status = status; - await deliveryPerson.save(); - successResponse(res, 200, "Delivery person status updated successfully.", { - status: deliveryPerson.status, - }); - } catch (error) { - errorResponse(res, 500, error.message); - } -}; - -// Helper functions for response handling -const validateVehicleDetails = (vehicleDetails) => { - const { vehicle_type, vehicle_number } = vehicleDetails; - if (vehicle_type && typeof vehicle_type !== "string") return false; - if (vehicle_number && typeof vehicle_number !== "string") return false; - return true; -}; - -// Search Delivery Person by name -exports.searchDeliveryPersonByName = async (req, res) => { - try { - const { name } = req.query; - const deliveryPersons = await DeliveryPerson.find({ - name: { $regex: name, $options: "i" }, - }); - successResponse( - res, - 200, - "Search results retrieved successfully.", - deliveryPersons - ); - } catch (error) { - errorResponse(res, 500, error.message); - } -}; - -// Get all assigned routes for a Delivery Person -exports.getAssignedRoutes = async (req, res) => { - try { - const deliveryPerson = await DeliveryPerson.findById( - req.params.id - ).populate("assigned_routes"); - if (!deliveryPerson) - return errorResponse(res, 404, "Delivery person not found."); - successResponse( - res, - 200, - "Assigned routes retrieved successfully.", - deliveryPerson.assigned_routes - ); - } catch (error) { - errorResponse(res, 500, error.message); - } -}; - -// Change Delivery Person's vehicle details -exports.updateVehicleDetails = async (req, res) => { - try { - const { vehicle_details } = req.body; - - // Validate vehicle details format - if (vehicle_details && !validateVehicleDetails(vehicle_details)) { - return errorResponse(res, 400, "Invalid vehicle details format."); - } - - const updatedDeliveryPerson = await DeliveryPerson.findByIdAndUpdate( - req.params.id, - { vehicle_details }, - { new: true } - ); - - if (!updatedDeliveryPerson) - return errorResponse(res, 404, "Delivery person not found."); - successResponse( - res, - 200, - "Vehicle details updated successfully.", - updatedDeliveryPerson.vehicle_details - ); - } catch (error) { - errorResponse(res, 500, error.message); - } -}; diff --git a/backend/controllers/shop/sub-controllers/giftCardController.js b/backend/controllers/shop/sub-controllers/giftCardController.js deleted file mode 100644 index da430178..00000000 --- a/backend/controllers/shop/sub-controllers/giftCardController.js +++ /dev/null @@ -1,311 +0,0 @@ -// controllers/giftCardController.js -const GiftCard = require("../../../model/shop/sub-model/GiftCard"); - -// Create a new gift card -exports.createGiftCard = async (req, res) => { - try { - const { value, userId, expiryDate } = req.body; - - if (value <= 0) { - return res - .status(400) - .json({ message: "Gift card value must be greater than 0" }); - } - - const cardNumber = generateCardNumber(); - - const newGiftCard = new GiftCard({ - cardNumber, - value, - userId, - expiryDate, - }); - - await newGiftCard.save(); - res - .status(201) - .json({ - message: "Gift card created successfully", - giftCard: newGiftCard, - }); - } catch (err) { - res - .status(500) - .json({ message: "Error creating gift card", error: err.message }); - } -}; - -// Redeem a gift card -exports.redeemGiftCard = async (req, res) => { - try { - const { cardNumber } = req.body; - - const giftCard = await GiftCard.findOne({ cardNumber }); - - if (!giftCard) { - return res.status(404).json({ message: "Gift card not found" }); - } - - if (giftCard.status === "redeemed") { - return res.status(400).json({ message: "Gift card already redeemed" }); - } - - if (giftCard.status === "expired") { - return res.status(400).json({ message: "Gift card is expired" }); - } - - if (giftCard.expiryDate < new Date()) { - giftCard.status = "expired"; - await giftCard.save(); - return res.status(400).json({ message: "Gift card has expired" }); - } - - if (giftCard.value <= 0) { - return res.status(400).json({ message: "Gift card value is invalid" }); - } - - giftCard.status = "redeemed"; - await giftCard.save(); - - res - .status(200) - .json({ message: "Gift card redeemed successfully", giftCard }); - } catch (err) { - res - .status(500) - .json({ message: "Error redeeming gift card", error: err.message }); - } -}; - -// Fetch gift card details -exports.getGiftCardDetails = async (req, res) => { - try { - const { cardNumber } = req.params; - const giftCard = await GiftCard.findOne({ cardNumber }); - - if (!giftCard) { - return res.status(404).json({ message: "Gift card not found" }); - } - - res.status(200).json({ giftCard }); - } catch (err) { - res - .status(500) - .json({ - message: "Error fetching gift card details", - error: err.message, - }); - } -}; - -// Fetch all active gift cards for a user -exports.getUserGiftCards = async (req, res) => { - try { - const { userId } = req.params; - - const giftCards = await GiftCard.find({ userId, status: "active" }); - - if (giftCards.length === 0) { - return res - .status(404) - .json({ message: "No active gift cards found for this user" }); - } - - res.status(200).json({ giftCards }); - } catch (err) { - res - .status(500) - .json({ message: "Error fetching user gift cards", error: err.message }); - } -}; - -// Extend gift card expiration -exports.extendGiftCardExpiry = async (req, res) => { - try { - const { cardNumber, newExpiryDate } = req.body; - - const giftCard = await GiftCard.findOne({ cardNumber }); - - if (!giftCard) { - return res.status(404).json({ message: "Gift card not found" }); - } - - if (giftCard.status === "redeemed") { - return res - .status(400) - .json({ message: "Cannot extend expiry of redeemed card" }); - } - - if (giftCard.status === "expired") { - return res - .status(400) - .json({ message: "Cannot extend expiry of expired card" }); - } - - giftCard.expiryDate = new Date(newExpiryDate); - await giftCard.save(); - - res - .status(200) - .json({ message: "Gift card expiry extended successfully", giftCard }); - } catch (err) { - res - .status(500) - .json({ - message: "Error extending gift card expiry", - error: err.message, - }); - } -}; - -// Deactivate a gift card -exports.deactivateGiftCard = async (req, res) => { - try { - const { cardNumber } = req.body; - - const giftCard = await GiftCard.findOne({ cardNumber }); - - if (!giftCard) { - return res.status(404).json({ message: "Gift card not found" }); - } - - if (giftCard.status === "redeemed") { - return res - .status(400) - .json({ message: "Cannot deactivate redeemed card" }); - } - - giftCard.status = "expired"; - await giftCard.save(); - - res - .status(200) - .json({ message: "Gift card deactivated successfully", giftCard }); - } catch (err) { - res - .status(500) - .json({ message: "Error deactivating gift card", error: err.message }); - } -}; - -// Delete a gift card (force delete) -exports.deleteGiftCard = async (req, res) => { - try { - const { cardNumber } = req.body; - - const giftCard = await GiftCard.findOne({ cardNumber }); - - if (!giftCard) { - return res.status(404).json({ message: "Gift card not found" }); - } - - await giftCard.remove(); - res.status(200).json({ message: "Gift card deleted successfully" }); - } catch (err) { - res - .status(500) - .json({ message: "Error deleting gift card", error: err.message }); - } -}; - -// Reactivate an expired gift card -exports.reactivateGiftCard = async (req, res) => { - try { - const { cardNumber } = req.body; - - const giftCard = await GiftCard.findOne({ cardNumber }); - - if (!giftCard) { - return res.status(404).json({ message: "Gift card not found" }); - } - - if (giftCard.status === "redeemed") { - return res - .status(400) - .json({ message: "Cannot reactivate redeemed card" }); - } - - if (giftCard.status === "active") { - return res.status(400).json({ message: "Gift card is already active" }); - } - - giftCard.status = "active"; - giftCard.expiryDate = new Date(); // Reset the expiry date to a new default - await giftCard.save(); - - res - .status(200) - .json({ message: "Gift card reactivated successfully", giftCard }); - } catch (err) { - res - .status(500) - .json({ message: "Error reactivating gift card", error: err.message }); - } -}; - -// Update the value of a gift card -exports.updateGiftCardValue = async (req, res) => { - try { - const { cardNumber, newValue } = req.body; - - if (newValue <= 0) { - return res - .status(400) - .json({ message: "New value must be greater than 0" }); - } - - const giftCard = await GiftCard.findOne({ cardNumber }); - - if (!giftCard) { - return res.status(404).json({ message: "Gift card not found" }); - } - - giftCard.value = newValue; - await giftCard.save(); - - res - .status(200) - .json({ message: "Gift card value updated successfully", giftCard }); - } catch (err) { - res - .status(500) - .json({ message: "Error updating gift card value", error: err.message }); - } -}; - -// Search for gift cards by value range -exports.searchGiftCardsByValue = async (req, res) => { - try { - const { minValue, maxValue } = req.query; - - if (minValue <= 0 || maxValue <= 0) { - return res - .status(400) - .json({ message: "Value range must be greater than 0" }); - } - - const giftCards = await GiftCard.find({ - value: { $gte: minValue, $lte: maxValue }, - }); - - if (giftCards.length === 0) { - return res - .status(404) - .json({ message: "No gift cards found within this value range" }); - } - - res.status(200).json({ giftCards }); - } catch (err) { - res - .status(500) - .json({ - message: "Error searching gift cards by value", - error: err.message, - }); - } -}; - -// Helper function to generate a unique card number -const generateCardNumber = () => { - return `GC-${Math.random().toString(36).substr(2, 9).toUpperCase()}`; -}; diff --git a/backend/controllers/shop/sub-controllers/inventoryController.js b/backend/controllers/shop/sub-controllers/inventoryController.js deleted file mode 100644 index 21b3148d..00000000 --- a/backend/controllers/shop/sub-controllers/inventoryController.js +++ /dev/null @@ -1,343 +0,0 @@ -const Inventory = require("../../../model/shop/sub-model/InventoryModel"); -const Product = require("../../../model/shop/product"); -const Supplier = require("../../../model/shop/sub-model/SuppierModel"); -const mongoose = require("mongoose"); - - -exports.createInventoryItem = async (req, res) => { - try { - const { - productId, - currentStockLevel, - reorderLevel, - warehouseLocation, - supplierId, - performedBy, - } = req.body; - - // Ensure product exists - const product = await Product.findById(productId); - if (!product) { - return res.status(400).json({ message: "Product not found" }); - } - - // Optional: Check if supplier exists (if provided) - if (supplierId) { - const supplier = await Supplier.findById(supplierId); - if (!supplier) { - return res.status(400).json({ message: "Supplier not found" }); - } - } - - const newInventoryItem = new Inventory({ - productId, - currentStockLevel, - reorderLevel, - warehouseLocation, - supplierId, - }); - - // Adding audit log for creation - newInventoryItem.auditLog.push({ - action: "Inventory Item Created", - performedBy, - quantityChanged: currentStockLevel, - notes: `Initial stock for ${product.name}`, - }); - - await newInventoryItem.save(); - res - .status(201) - .json({ - message: "Inventory item created successfully", - newInventoryItem, - }); - } catch (error) { - res.status(500).json({ message: "Error creating inventory item", error }); - } -}; - -// Controller for updating stock level -exports.updateStockLevel = async (req, res) => { - try { - const { inventoryId, newStockLevel, performedBy, notes } = req.body; - - if (newStockLevel < 0) { - return res - .status(400) - .json({ message: "Stock level cannot be negative" }); - } - - const inventory = await Inventory.findById(inventoryId); - if (!inventory) { - return res.status(404).json({ message: "Inventory item not found" }); - } - - const quantityChanged = newStockLevel - inventory.currentStockLevel; - inventory.currentStockLevel = newStockLevel; - inventory.auditLog.push({ - action: "Stock Level Updated", - performedBy, - quantityChanged, - notes, - }); - - await inventory.save(); - res - .status(200) - .json({ message: "Stock level updated successfully", inventory }); - } catch (error) { - res.status(500).json({ message: "Error updating stock level", error }); - } -}; - -// Controller to fetch inventory by product -exports.fetchInventoryByProduct = async (req, res) => { - try { - const { productId } = req.params; - const inventoryItem = await Inventory.findOne({ productId }) - .populate("productId") - .populate("supplierId"); - - if (!inventoryItem) { - return res - .status(404) - .json({ message: "Inventory not found for this product" }); - } - - res.status(200).json({ inventoryItem }); - } catch (error) { - res - .status(500) - .json({ message: "Error fetching inventory by product", error }); - } -}; - -// Controller to fetch inventory by warehouse -exports.fetchInventoryByWarehouse = async (req, res) => { - try { - const { warehouseLocation } = req.params; - const inventoryItems = await Inventory.find({ warehouseLocation }) - .populate("productId") - .populate("supplierId"); - - if (!inventoryItems || inventoryItems.length === 0) { - return res - .status(404) - .json({ message: "No inventory found for this warehouse" }); - } - - res.status(200).json({ inventoryItems }); - } catch (error) { - res - .status(500) - .json({ message: "Error fetching inventory by warehouse", error }); - } -}; - -// Controller to fetch all inventory -exports.fetchAllInventory = async (req, res) => { - try { - const inventoryItems = await Inventory.find() - .populate("productId") - .populate("supplierId"); - - if (!inventoryItems || inventoryItems.length === 0) { - return res.status(404).json({ message: "No inventory items found" }); - } - - res.status(200).json({ inventoryItems }); - } catch (error) { - res.status(500).json({ message: "Error fetching all inventory", error }); - } -}; - -// Controller to delete an inventory item -exports.deleteInventoryItem = async (req, res) => { - try { - const { inventoryId } = req.params; - const inventory = await Inventory.findById(inventoryId); - - if (!inventory) { - return res.status(404).json({ message: "Inventory item not found" }); - } - - await inventory.remove(); - res.status(200).json({ message: "Inventory item deleted successfully" }); - } catch (error) { - res.status(500).json({ message: "Error deleting inventory item", error }); - } -}; - -// Controller for bulk updating stock levels -exports.bulkUpdateStockLevels = async (req, res) => { - try { - const { updates, performedBy } = req.body; - - const updatedItems = []; - for (const update of updates) { - const { inventoryId, newStockLevel, notes } = update; - const inventory = await Inventory.findById(inventoryId); - - if (!inventory) { - return res - .status(404) - .json({ message: `Inventory item with ID ${inventoryId} not found` }); - } - - const quantityChanged = newStockLevel - inventory.currentStockLevel; - inventory.currentStockLevel = newStockLevel; - inventory.auditLog.push({ - action: "Stock Level Updated (Bulk)", - performedBy, - quantityChanged, - notes, - }); - - await inventory.save(); - updatedItems.push(inventory); - } - - res - .status(200) - .json({ - message: "Bulk stock levels updated successfully", - updatedItems, - }); - } catch (error) { - res - .status(500) - .json({ message: "Error updating stock levels in bulk", error }); - } -}; - -// Controller for bulk creation of inventory items -exports.bulkCreateInventoryItems = async (req, res) => { - try { - const { items, performedBy } = req.body; - const createdItems = []; - - for (const item of items) { - const { - productId, - currentStockLevel, - reorderLevel, - warehouseLocation, - supplierId, - } = item; - - // Ensure product exists - const product = await Product.findById(productId); - if (!product) { - return res - .status(400) - .json({ message: `Product with ID ${productId} not found` }); - } - - // Optional: Check if supplier exists (if provided) - if (supplierId) { - const supplier = await Supplier.findById(supplierId); - if (!supplier) { - return res - .status(400) - .json({ message: `Supplier with ID ${supplierId} not found` }); - } - } - - const newInventoryItem = new Inventory({ - productId, - currentStockLevel, - reorderLevel, - warehouseLocation, - supplierId, - }); - - newInventoryItem.auditLog.push({ - action: "Inventory Item Created (Bulk)", - performedBy, - quantityChanged: currentStockLevel, - notes: `Initial stock for ${product.name}`, - }); - - await newInventoryItem.save(); - createdItems.push(newInventoryItem); - } - - res - .status(201) - .json({ - message: "Bulk inventory items created successfully", - createdItems, - }); - } catch (error) { - res - .status(500) - .json({ message: "Error creating inventory items in bulk", error }); - } -}; - -// Controller for logging actions in inventory audit trail -exports.logInventoryAction = async (req, res) => { - try { - const { inventoryId, action, performedBy, quantityChanged, notes } = - req.body; - - const inventory = await Inventory.findById(inventoryId); - if (!inventory) { - return res.status(404).json({ message: "Inventory item not found" }); - } - - inventory.auditLog.push({ - action, - performedBy, - quantityChanged, - notes, - }); - - await inventory.save(); - res.status(200).json({ message: "Action logged successfully" }); - } catch (error) { - res.status(500).json({ message: "Error logging action", error }); - } -}; - -// Controller for handling expired inventory (e.g., perishable items) -exports.handleExpiredInventory = async (req, res) => { - try { - const { productId } = req.params; - const expiredInventory = await Inventory.find({ - productId, - currentStockLevel: { $gt: 0 }, - lastRestockedDate: { $lt: new Date() }, - }); - - if (expiredInventory.length === 0) { - return res - .status(404) - .json({ message: "No expired inventory found for this product" }); - } - - for (const inventory of expiredInventory) { - inventory.currentStockLevel = 0; // Mark stock as zero - inventory.auditLog.push({ - action: "Expired Inventory Removed", - performedBy: "System", - quantityChanged: -inventory.currentStockLevel, - notes: "Inventory marked as expired", - }); - - await inventory.save(); - } - - res - .status(200) - .json({ - message: "Expired inventory handled successfully", - expiredInventory, - }); - } catch (error) { - res - .status(500) - .json({ message: "Error handling expired inventory", error }); - } -}; diff --git a/backend/controllers/shop/sub-controllers/invoiceController.js b/backend/controllers/shop/sub-controllers/invoiceController.js deleted file mode 100644 index 41cc8388..00000000 --- a/backend/controllers/shop/sub-controllers/invoiceController.js +++ /dev/null @@ -1,217 +0,0 @@ -const Invoice = require("../models/invoice"); -const Joi = require("joi"); - -// Validation Schemas -const invoiceSchema = Joi.object({ - orderId: Joi.string().required(), - userId: Joi.string().required(), - amount: Joi.number().min(0).required(), - dueDate: Joi.date().required(), - paymentId: Joi.string().optional(), -}); - -const statusUpdateSchema = Joi.object({ - status: Joi.string() - .valid("Paid", "Unpaid", "Overdue", "Cancelled") - .required(), -}); - -// Generate invoice after payment confirmation -const generateInvoice = async (req, res) => { - const { error, value } = invoiceSchema.validate(req.body); - if (error) return res.status(400).json({ message: error.message }); - - const { orderId, userId, amount, dueDate, paymentId } = value; - - const newInvoice = new Invoice({ - invoiceId: `INV${Date.now()}`, - orderId, - userId, - amount, - dueDate, - paymentId, - }); - - try { - const invoice = await newInvoice.save(); - res.status(201).json(invoice); - } catch (error) { - console.error(`Error generating invoice: ${error.message}`); - res.status(500).json({ message: "Internal server error" }); - } -}; - -// Retrieve invoices by user, order, status, or date range with pagination -const getInvoices = async (req, res) => { - const { - userId, - orderId, - status, - startDate, - endDate, - page = 1, - limit = 10, - sortBy = "invoiceDate", - order = "desc", - } = req.query; - - try { - const filters = {}; - if (userId) filters.userId = userId; - if (orderId) filters.orderId = orderId; - if (status) filters.status = status; - - if (startDate || endDate) { - filters.invoiceDate = {}; - if (startDate) filters.invoiceDate.$gte = new Date(startDate); - if (endDate) filters.invoiceDate.$lte = new Date(endDate); - } - - const invoices = await Invoice.find(filters) - .sort({ [sortBy]: order === "asc" ? 1 : -1 }) - .skip((page - 1) * limit) - .limit(Number(limit)); - - res.status(200).json(invoices); - } catch (error) { - console.error(`Error fetching invoices: ${error.message}`); - res.status(500).json({ message: "Internal server error" }); - } -}; - -// Retrieve a single invoice by ID -const getInvoiceById = async (req, res) => { - try { - const invoice = await Invoice.findById(req.params.id); - if (!invoice) return res.status(404).json({ message: "Invoice not found" }); - res.status(200).json(invoice); - } catch (error) { - console.error(`Error fetching invoice by ID: ${error.message}`); - res.status(500).json({ message: "Internal server error" }); - } -}; - -// Update invoice status with validation -const updateInvoiceStatus = async (req, res) => { - const { error, value } = statusUpdateSchema.validate(req.body); - if (error) return res.status(400).json({ message: error.message }); - - try { - const invoice = await Invoice.findByIdAndUpdate( - req.params.id, - { status: value.status }, - { new: true } - ); - if (!invoice) return res.status(404).json({ message: "Invoice not found" }); - res.status(200).json(invoice); - } catch (error) { - console.error(`Error updating invoice status: ${error.message}`); - res.status(500).json({ message: "Internal server error" }); - } -}; - -// Delete an invoice by ID -const deleteInvoice = async (req, res) => { - try { - const invoice = await Invoice.findByIdAndDelete(req.params.id); - if (!invoice) return res.status(404).json({ message: "Invoice not found" }); - res.status(200).json({ message: "Invoice deleted successfully" }); - } catch (error) { - console.error(`Error deleting invoice: ${error.message}`); - res.status(500).json({ message: "Internal server error" }); - } -}; - -// Mark overdue invoices -const markOverdueInvoices = async (req, res) => { - try { - const overdueInvoices = await Invoice.updateMany( - { dueDate: { $lt: new Date() }, status: "Unpaid" }, - { status: "Overdue" } - ); - res - .status(200) - .json({ - message: `${overdueInvoices.nModified} invoices marked as overdue`, - }); - } catch (error) { - console.error(`Error marking overdue invoices: ${error.message}`); - res.status(500).json({ message: "Internal server error" }); - } -}; - -// Summary of invoices by status -const invoiceSummary = async (req, res) => { - const { userId } = req.query; - - try { - const match = userId ? { userId } : {}; - - const summary = await Invoice.aggregate([ - { $match: match }, - { - $group: { - _id: "$status", - totalAmount: { $sum: "$amount" }, - count: { $sum: 1 }, - }, - }, - ]); - - const summaryData = summary.reduce((acc, item) => { - acc[item._id] = { totalAmount: item.totalAmount, count: item.count }; - return acc; - }, {}); - - res.status(200).json(summaryData); - } catch (error) { - console.error(`Error generating invoice summary: ${error.message}`); - res.status(500).json({ message: "Internal server error" }); - } -}; - -// Bulk invoice generation -const generateBulkInvoices = async (req, res) => { - const { invoices } = req.body; - - if (!Array.isArray(invoices) || invoices.length === 0) { - return res.status(400).json({ message: "Invalid invoices data" }); - } - - const validationErrors = invoices - .map((invoiceData, index) => { - const { error } = invoiceSchema.validate(invoiceData); - return error ? { index, message: error.message } : null; - }) - .filter(Boolean); - - if (validationErrors.length > 0) { - return res - .status(400) - .json({ message: "Validation errors", errors: validationErrors }); - } - - try { - const invoiceDocuments = invoices.map((invoiceData) => ({ - ...invoiceData, - invoiceId: `INV${Date.now() + Math.floor(Math.random() * 1000)}`, - })); - - const createdInvoices = await Invoice.insertMany(invoiceDocuments); - res.status(201).json(createdInvoices); - } catch (error) { - console.error(`Error generating bulk invoices: ${error.message}`); - res.status(500).json({ message: "Internal server error" }); - } -}; - -module.exports = { - generateInvoice, - getInvoices, - getInvoiceById, - updateInvoiceStatus, - deleteInvoice, - markOverdueInvoices, - invoiceSummary, - generateBulkInvoices, -}; diff --git a/backend/controllers/shop/sub-controllers/loyaltyPointsController.js b/backend/controllers/shop/sub-controllers/loyaltyPointsController.js deleted file mode 100644 index f2c6c5a7..00000000 --- a/backend/controllers/shop/sub-controllers/loyaltyPointsController.js +++ /dev/null @@ -1,264 +0,0 @@ -const LoyaltyPoint = require("../../../model/shop/sub-model/loyaltyPointModel"); -const User = require("../../../model/user"); - -// Award points to a user -exports.awardPoints = async (req, res) => { - try { - const { userId, points, earnedBy } = req.body; - - const user = await User.findById(userId); - if (!user) return res.status(404).json({ message: "User not found" }); - - const newPoints = new LoyaltyPoint({ userId, points, earnedBy }); - await newPoints.save(); - - user.loyaltyPoints += points; - await user.save(); - - res - .status(200) - .json({ message: "Points awarded successfully", points: newPoints }); - } catch (error) { - res.status(500).json({ message: "Server error", error }); - } -}; - -// Get a user's loyalty points balance -exports.getPoints = async (req, res) => { - try { - const { userId } = req.params; - - const points = await LoyaltyPoint.aggregate([ - { $match: { userId: mongoose.Types.ObjectId(userId) } }, - { $group: { _id: "$userId", totalPoints: { $sum: "$points" } } }, - ]); - - if (!points.length) - return res.status(404).json({ message: "No points found for this user" }); - - res.status(200).json({ totalPoints: points[0].totalPoints }); - } catch (error) { - res.status(500).json({ message: "Server error", error }); - } -}; - -// Get transaction history of loyalty points -exports.getTransactionHistory = async (req, res) => { - try { - const { userId } = req.params; - - const transactions = await LoyaltyPoint.find({ userId }).sort({ - timestamp: -1, - }); - - if (!transactions.length) - return res - .status(404) - .json({ message: "No transaction history found for this user" }); - - res.status(200).json({ transactions }); - } catch (error) { - res.status(500).json({ message: "Server error", error }); - } -}; - -// Delete a specific loyalty point entry -exports.deletePoints = async (req, res) => { - try { - const { transactionId } = req.params; - - const deletedTransaction = await LoyaltyPoint.findByIdAndDelete( - transactionId - ); - if (!deletedTransaction) - return res.status(404).json({ message: "Transaction not found" }); - - res - .status(200) - .json({ - message: "Loyalty points transaction deleted", - transaction: deletedTransaction, - }); - } catch (error) { - res.status(500).json({ message: "Server error", error }); - } -}; - -// Update a specific loyalty point transaction -exports.updatePoints = async (req, res) => { - try { - const { transactionId } = req.params; - const { points, earnedBy } = req.body; - - const updatedTransaction = await LoyaltyPoint.findByIdAndUpdate( - transactionId, - { points, earnedBy }, - { new: true } - ); - - if (!updatedTransaction) - return res.status(404).json({ message: "Transaction not found" }); - - res - .status(200) - .json({ - message: "Loyalty points transaction updated", - transaction: updatedTransaction, - }); - } catch (error) { - res.status(500).json({ message: "Server error", error }); - } -}; - -// Filter transactions by earning type (e.g., 'purchase', 'referral') -exports.filterTransactionsByType = async (req, res) => { - try { - const { userId } = req.params; - const { type } = req.query; - - const transactions = await LoyaltyPoint.find({ userId, earnedBy: type }); - - if (!transactions.length) - return res - .status(404) - .json({ message: `No transactions found for ${type}` }); - - res.status(200).json({ transactions }); - } catch (error) { - res.status(500).json({ message: "Server error", error }); - } -}; - -// Get total points earned by referral actions -exports.getPointsByReferrals = async (req, res) => { - try { - const { userId } = req.params; - - const referralPoints = await LoyaltyPoint.aggregate([ - { - $match: { - userId: mongoose.Types.ObjectId(userId), - earnedBy: "referral", - }, - }, - { $group: { _id: "$userId", totalReferralPoints: { $sum: "$points" } } }, - ]); - - if (!referralPoints.length) - return res - .status(404) - .json({ message: "No referral points found for this user" }); - - res - .status(200) - .json({ totalReferralPoints: referralPoints[0].totalReferralPoints }); - } catch (error) { - res.status(500).json({ message: "Server error", error }); - } -}; - -// Get total points earned by purchase actions -exports.getPointsByPurchases = async (req, res) => { - try { - const { userId } = req.params; - - const purchasePoints = await LoyaltyPoint.aggregate([ - { - $match: { - userId: mongoose.Types.ObjectId(userId), - earnedBy: "purchase", - }, - }, - { $group: { _id: "$userId", totalPurchasePoints: { $sum: "$points" } } }, - ]); - - if (!purchasePoints.length) - return res - .status(404) - .json({ message: "No purchase points found for this user" }); - - res - .status(200) - .json({ totalPurchasePoints: purchasePoints[0].totalPurchasePoints }); - } catch (error) { - res.status(500).json({ message: "Server error", error }); - } -}; - -// Redeem points (reduce points based on redemption) -exports.redeemPoints = async (req, res) => { - try { - const { userId, pointsToRedeem } = req.body; - - const user = await User.findById(userId); - if (!user) return res.status(404).json({ message: "User not found" }); - - const totalPoints = await LoyaltyPoint.aggregate([ - { $match: { userId: mongoose.Types.ObjectId(userId) } }, - { $group: { _id: "$userId", totalPoints: { $sum: "$points" } } }, - ]); - - if (totalPoints[0].totalPoints < pointsToRedeem) { - return res - .status(400) - .json({ message: "Insufficient points for redemption" }); - } - - const redemption = new LoyaltyPoint({ - userId, - points: -pointsToRedeem, - earnedBy: "redemption", - }); - await redemption.save(); - - res - .status(200) - .json({ message: "Points redeemed successfully", redemption }); - } catch (error) { - res.status(500).json({ message: "Server error", error }); - } -}; - -// Calculate loyalty point summary (overall breakdown) -exports.getLoyaltySummary = async (req, res) => { - try { - const { userId } = req.params; - - const totalPoints = await LoyaltyPoint.aggregate([ - { $match: { userId: mongoose.Types.ObjectId(userId) } }, - { $group: { _id: "$userId", totalPoints: { $sum: "$points" } } }, - ]); - - const referralPoints = await LoyaltyPoint.aggregate([ - { - $match: { - userId: mongoose.Types.ObjectId(userId), - earnedBy: "referral", - }, - }, - { $group: { _id: "$userId", totalReferralPoints: { $sum: "$points" } } }, - ]); - - const purchasePoints = await LoyaltyPoint.aggregate([ - { - $match: { - userId: mongoose.Types.ObjectId(userId), - earnedBy: "purchase", - }, - }, - { $group: { _id: "$userId", totalPurchasePoints: { $sum: "$points" } } }, - ]); - - res.status(200).json({ - totalPoints: totalPoints.length ? totalPoints[0].totalPoints : 0, - referralPoints: referralPoints.length - ? referralPoints[0].totalReferralPoints - : 0, - purchasePoints: purchasePoints.length - ? purchasePoints[0].totalPurchasePoints - : 0, - }); - } catch (error) { - res.status(500).json({ message: "Server error", error }); - } -}; diff --git a/backend/controllers/shop/sub-controllers/orderController.js b/backend/controllers/shop/sub-controllers/orderController.js deleted file mode 100644 index 503e9180..00000000 --- a/backend/controllers/shop/sub-controllers/orderController.js +++ /dev/null @@ -1,297 +0,0 @@ -const OrderHistory = require("../../../model/shop/sub-model/OrderHistory"); -const Product = require("../../../model/shop/product"); -const User = require("../../../model/user"); - - -exports.createOrder = async (req, res) => { - try { - const { userId, items, shippingAddress, paymentDetails } = req.body; - - // Validate user - const user = await User.findById(userId); - if (!user) return res.status(400).json({ message: "User not found" }); - - // Validate product availability and calculate total amount - let totalAmount = 0; - for (const item of items) { - const product = await Product.findById(item.productId); - if (!product) - return res - .status(400) - .json({ message: `Product with ID ${item.productId} not found` }); - totalAmount += product.price * item.quantity; - } - - const order = new OrderHistory({ - userId, - items, - shippingAddress, - totalAmount, - paymentStatus: paymentDetails.status || "Pending", - }); - - await order.save(); - res.status(201).json({ message: "Order created successfully", order }); - } catch (err) { - res.status(500).json({ message: "Server Error", error: err.message }); - } -}; - - - -exports.getOrders = async (req, res) => { - try { - const userId = req.user.id; // Assume authentication middleware sets req.user - - const orders = await OrderHistory.find({ userId }) - .populate("items.productId") - .select("orderId orderDate orderStatus totalAmount items shippingAddress") - .exec(); - - if (!orders) return res.status(404).json({ message: "No orders found" }); - res.status(200).json(orders); - } catch (err) { - res.status(500).json({ message: "Server Error", error: err.message }); - } -}; - - - -exports.updateOrderStatus = async (req, res) => { - try { - const { orderId } = req.params; - const { orderStatus, trackingNumber } = req.body; - const userId = req.user.id; // Assume authentication middleware - - // Fetch the order - const order = await OrderHistory.findById(orderId); - if (!order) return res.status(404).json({ message: "Order not found" }); - - // Ensure that the user is allowed to update the order - if (order.userId.toString() !== userId && !req.user.isAdmin) { - return res.status(403).json({ message: "Unauthorized" }); - } - - // Update order status and tracking number if provided - order.orderStatus = orderStatus; - if (trackingNumber) { - order.trackingNumber = trackingNumber; - } - - await order.save(); - res - .status(200) - .json({ message: "Order status updated successfully", order }); - } catch (err) { - res.status(500).json({ message: "Server Error", error: err.message }); - } -}; - - - -exports.deleteOrder = async (req, res) => { - try { - const { orderId } = req.params; - const userId = req.user.id; // Assume authentication middleware - - // Fetch the order - const order = await OrderHistory.findById(orderId); - if (!order) return res.status(404).json({ message: "Order not found" }); - - // Ensure that the user is allowed to delete the order - if (order.userId.toString() !== userId && !req.user.isAdmin) { - return res.status(403).json({ message: "Unauthorized" }); - } - - // Check order status (e.g., only allow deletion if "Pending") - if (order.orderStatus !== "Pending") { - return res - .status(400) - .json({ message: "Cannot delete non-pending orders" }); - } - - await order.remove(); - res.status(200).json({ message: "Order deleted successfully" }); - } catch (err) { - res.status(500).json({ message: "Server Error", error: err.message }); - } -}; - - - -exports.getOrderById = async (req, res) => { - try { - const { orderId } = req.params; - const userId = req.user.id; // Assume authentication middleware sets req.user - - const order = await OrderHistory.findOne({ _id: orderId, userId }) - .populate("items.productId", "name price") - .exec(); - - if (!order) return res.status(404).json({ message: "Order not found" }); - - res.status(200).json(order); - } catch (err) { - res.status(500).json({ message: "Server Error", error: err.message }); - } -}; - - - -exports.addItemToOrder = async (req, res) => { - try { - const { orderId } = req.params; - const { productId, quantity } = req.body; - - const order = await OrderHistory.findById(orderId); - if (!order) return res.status(404).json({ message: "Order not found" }); - - const product = await Product.findById(productId); - if (!product) return res.status(400).json({ message: "Product not found" }); - if (product.stock < quantity) - return res.status(400).json({ message: "Insufficient stock" }); - - // Add item to order - const item = { productId, quantity, price: product.price }; - order.items.push(item); - order.totalAmount += product.price * quantity; - - await order.save(); - res.status(200).json({ message: "Item added to order", order }); - } catch (err) { - res.status(500).json({ message: "Server Error", error: err.message }); - } -}; - - - -exports.removeItemFromOrder = async (req, res) => { - try { - const { orderId, itemId } = req.params; - - const order = await OrderHistory.findById(orderId); - if (!order) return res.status(404).json({ message: "Order not found" }); - - const itemIndex = order.items.findIndex( - (item) => item._id.toString() === itemId - ); - if (itemIndex === -1) - return res.status(404).json({ message: "Item not found in order" }); - - const item = order.items[itemIndex]; - order.totalAmount -= item.price * item.quantity; - order.items.splice(itemIndex, 1); // Remove item from array - - await order.save(); - res.status(200).json({ message: "Item removed from order", order }); - } catch (err) { - res.status(500).json({ message: "Server Error", error: err.message }); - } -}; - - - -exports.updateOrderItemQuantity = async (req, res) => { - try { - const { orderId, itemId } = req.params; - const { quantity } = req.body; - - const order = await OrderHistory.findById(orderId); - if (!order) return res.status(404).json({ message: "Order not found" }); - - const item = order.items.find((item) => item._id.toString() === itemId); - if (!item) - return res.status(404).json({ message: "Item not found in order" }); - - const product = await Product.findById(item.productId); - if (product.stock < quantity) - return res.status(400).json({ message: "Insufficient stock" }); - - // Update totalAmount by adjusting only the quantity difference - order.totalAmount += (quantity - item.quantity) * item.price; - item.quantity = quantity; - - await order.save(); - res.status(200).json({ message: "Order item quantity updated", order }); - } catch (err) { - res.status(500).json({ message: "Server Error", error: err.message }); - } -}; - - - -exports.bulkUpdateOrderStatus = async (req, res) => { - try { - const { orderIds, orderStatus } = req.body; - - const updatedOrders = await OrderHistory.updateMany( - { _id: { $in: orderIds } }, - { $set: { orderStatus } } - ); - - res - .status(200) - .json({ message: "Order statuses updated successfully", updatedOrders }); - } catch (err) { - res.status(500).json({ message: "Server Error", error: err.message }); - } -}; - -exports.getOrderStatusHistory = async (req, res) => { - try { - const { orderId } = req.params; - - const order = await OrderHistory.findById(orderId).select("statusHistory"); - if (!order) return res.status(404).json({ message: "Order not found" }); - - res.status(200).json(order.statusHistory); - } catch (err) { - res.status(500).json({ message: "Server Error", error: err.message }); - } -}; - - - -exports.getOrdersByStatus = async (req, res) => { - try { - const { status } = req.params; - - const orders = await OrderHistory.find({ orderStatus: status }) - .populate("userId", "name email") // Optionally populate user details - .exec(); - - if (orders.length === 0) - return res - .status(404) - .json({ message: "No orders with the specified status" }); - - res.status(200).json(orders); - } catch (err) { - res.status(500).json({ message: "Server Error", error: err.message }); - } -}; - - - -exports.getAllOrdersForAdmin = async (req, res) => { - try { - const { page = 1, limit = 10 } = req.query; - - const orders = await OrderHistory.find() - .populate("userId", "name email") - .limit(limit * 1) - .skip((page - 1) * limit) - .exec(); - - const count = await OrderHistory.countDocuments(); - - res.status(200).json({ - totalOrders: count, - totalPages: Math.ceil(count / limit), - currentPage: page, - orders, - }); - } catch (err) { - res.status(500).json({ message: "Server Error", error: err.message }); - } -}; diff --git a/backend/controllers/shop/sub-controllers/orderTrackingController.js b/backend/controllers/shop/sub-controllers/orderTrackingController.js deleted file mode 100644 index 2623cbd2..00000000 --- a/backend/controllers/shop/sub-controllers/orderTrackingController.js +++ /dev/null @@ -1,205 +0,0 @@ -const OrderTracking = require("../../../model/shop/sub-model/OrderTracking"); - -// Create new order tracking information -exports.createOrderTracking = async (req, res) => { - try { - const orderTracking = new OrderTracking(req.body); - await orderTracking.save(); - res.status(201).json(orderTracking); - } catch (error) { - res.status(400).json({ message: error.message }); - } -}; - - -// Retrieve tracking information for a specific order -exports.getOrderTracking = async (req, res) => { - try { - const orderTracking = await OrderTracking.findOne({ - orderId: req.params.orderId, - }); - if (!orderTracking) { - return res.status(404).json({ message: "Order tracking not found" }); - } - res.status(200).json(orderTracking); - } catch (error) { - res.status(500).json({ message: error.message }); - } -}; - - -// Update tracking information for an order -exports.updateOrderTracking = async (req, res) => { - try { - const orderTracking = await OrderTracking.findOneAndUpdate( - { orderId: req.params.orderId }, - { ...req.body, updatedAt: Date.now() }, - { new: true } - ); - if (!orderTracking) { - return res.status(404).json({ message: "Order tracking not found" }); - } - res.status(200).json(orderTracking); - } catch (error) { - res.status(400).json({ message: error.message }); - } -}; - - -// Delete tracking information for an order -exports.deleteOrderTracking = async (req, res) => { - try { - const orderTracking = await OrderTracking.findOneAndDelete({ - orderId: req.params.orderId, - }); - if (!orderTracking) { - return res.status(404).json({ message: "Order tracking not found" }); - } - res.status(200).json({ message: "Order tracking deleted successfully" }); - } catch (error) { - res.status(500).json({ message: error.message }); - } -}; - - -// Retrieve all order tracking information -exports.getAllOrderTrackings = async (req, res) => { - try { - const orderTrackings = await OrderTracking.find({}); - res.status(200).json(orderTrackings); - } catch (error) { - res.status(500).json({ message: error.message }); - } -}; - - -// Retrieve order tracking information filtered by status -exports.getOrdersByStatus = async (req, res) => { - try { - const { status } = req.params; - const orders = await OrderTracking.find({ status }); - res.status(200).json(orders); - } catch (error) { - res.status(500).json({ message: error.message }); - } -}; - - -// Retrieve recently updated orders (within the last 24 hours) -exports.getRecentUpdates = async (req, res) => { - try { - const yesterday = new Date(); - yesterday.setDate(yesterday.getDate() - 1); - - const recentOrders = await OrderTracking.find({ - updatedAt: { $gte: yesterday }, - }); - - res.status(200).json(recentOrders); - } catch (error) { - res.status(500).json({ message: error.message }); - } -}; - - -// Retrieve orders by specific carrier -exports.getOrdersByCarrier = async (req, res) => { - try { - const { carrier } = req.params; - const orders = await OrderTracking.find({ carrier }); - res.status(200).json(orders); - } catch (error) { - res.status(500).json({ message: error.message }); - } -}; - - -// Retrieve orders with estimated delivery within a date range -exports.getOrdersByEstimatedDeliveryRange = async (req, res) => { - try { - const { startDate, endDate } = req.query; - const orders = await OrderTracking.find({ - estimatedDelivery: { - $gte: new Date(startDate), - $lte: new Date(endDate), - }, - }); - res.status(200).json(orders); - } catch (error) { - res.status(500).json({ message: error.message }); - } -}; - - -exports.getOverdueOrders = async (req, res) => { - try { - const today = new Date(); - const overdueOrders = await OrderTracking.find({ - estimatedDelivery: { $lt: today }, - status: { $ne: "Delivered" }, - }); - res.status(200).json(overdueOrders); - } catch (error) { - res.status(500).json({ message: error.message }); - } -}; - - -// Bulk update the status of multiple orders -exports.bulkUpdateStatus = async (req, res) => { - try { - const { orderIds, status } = req.body; - const result = await OrderTracking.updateMany( - { orderId: { $in: orderIds } }, - { status, updatedAt: Date.now() } - ); - res - .status(200) - .json({ message: `${result.nModified} orders updated successfully` }); - } catch (error) { - res.status(500).json({ message: error.message }); - } -}; - - -// Retrieve orders updated within a specific date range -exports.getOrdersUpdatedWithinRange = async (req, res) => { - try { - const { startDate, endDate } = req.query; - const orders = await OrderTracking.find({ - updatedAt: { - $gte: new Date(startDate), - $lte: new Date(endDate), - }, - }); - res.status(200).json(orders); - } catch (error) { - res.status(500).json({ message: error.message }); - } -}; - - -// Retrieve orders by a range of tracking numbers -exports.getOrdersByTrackingNumberRange = async (req, res) => { - try { - const { startTrackingNumber, endTrackingNumber } = req.query; - const orders = await OrderTracking.find({ - trackingNumber: { $gte: startTrackingNumber, $lte: endTrackingNumber }, - }); - res.status(200).json(orders); - } catch (error) { - res.status(500).json({ message: error.message }); - } -}; - - -// Retrieve orders with selected fields -exports.getOrdersWithSelectedFields = async (req, res) => { - try { - const fields = req.query.fields.split(",").join(" "); - const orders = await OrderTracking.find({}, fields); - res.status(200).json(orders); - } catch (error) { - res.status(500).json({ message: error.message }); - } -}; diff --git a/backend/controllers/shop/sub-controllers/paymentController.js b/backend/controllers/shop/sub-controllers/paymentController.js deleted file mode 100644 index 0bc6569d..00000000 --- a/backend/controllers/shop/sub-controllers/paymentController.js +++ /dev/null @@ -1,161 +0,0 @@ -const Payment = require("../models/payment"); - -// Retrieve all payments -const getAllPayments = async (req, res) => { - try { - const payments = await Payment.find(); - res.status(200).json(payments); - } catch (error) { - res.status(500).json({ message: error.message }); - } -}; - -// Retrieve payment by ID -const getPaymentById = async (req, res) => { - try { - const payment = await Payment.findById(req.params.id); - if (!payment) return res.status(404).json({ message: "Payment not found" }); - res.status(200).json(payment); - } catch (error) { - res.status(500).json({ message: error.message }); - } -}; - -// Create a new payment -const createPayment = async (req, res) => { - const { orderId, userId, amount, paymentMethod, transactionId } = req.body; - - const newPayment = new Payment({ - paymentId: `PAY${Date.now()}`, - orderId, - userId, - amount, - paymentMethod, - transactionId, - }); - - try { - const payment = await newPayment.save(); - res.status(201).json(payment); - } catch (error) { - res.status(400).json({ message: error.message }); - } -}; - -// Update payment status -const updatePaymentStatus = async (req, res) => { - const { paymentStatus } = req.body; - try { - const payment = await Payment.findByIdAndUpdate( - req.params.id, - { paymentStatus }, - { new: true } - ); - if (!payment) return res.status(404).json({ message: "Payment not found" }); - res.status(200).json(payment); - } catch (error) { - res.status(500).json({ message: error.message }); - } -}; -const Payment = require("../models/payment"); - -// Update Payment Method -const updatePaymentMethod = async (req, res) => { - const { paymentMethod } = req.body; - try { - if (!["Credit Card", "PayPal", "Bank Transfer"].includes(paymentMethod)) { - return res.status(400).json({ message: "Invalid payment method" }); - } - const payment = await Payment.findByIdAndUpdate( - req.params.id, - { paymentMethod }, - { new: true } - ); - if (!payment) return res.status(404).json({ message: "Payment not found" }); - res.status(200).json(payment); - } catch (error) { - res.status(500).json({ message: error.message }); - } -}; - -// Retrieve Payments by Date Range -const getPaymentsByDateRange = async (req, res) => { - const { startDate, endDate } = req.query; - try { - const payments = await Payment.find({ - paymentDate: { - $gte: new Date(startDate), - $lte: new Date(endDate), - }, - }); - if (!payments.length) - return res - .status(404) - .json({ message: "No payments found in this date range" }); - res.status(200).json(payments); - } catch (error) { - res.status(500).json({ message: error.message }); - } -}; - -// Retrieve Payments by Amount Range -const getPaymentsByAmountRange = async (req, res) => { - const { minAmount, maxAmount } = req.query; - try { - const payments = await Payment.find({ - amount: { $gte: minAmount, $lte: maxAmount }, - }); - if (!payments.length) - return res - .status(404) - .json({ message: "No payments found in this amount range" }); - res.status(200).json(payments); - } catch (error) { - res.status(500).json({ message: error.message }); - } -}; - -// Retrieve Payment by Transaction ID -const getPaymentByTransactionId = async (req, res) => { - try { - const payment = await Payment.findOne({ - transactionId: req.params.transactionId, - }); - if (!payment) - return res - .status(404) - .json({ message: "Payment not found with this transaction ID" }); - res.status(200).json(payment); - } catch (error) { - res.status(500).json({ message: error.message }); - } -}; - -// Count Payments by Status -const countPaymentsByStatus = async (req, res) => { - try { - const counts = await Payment.aggregate([ - { - $group: { - _id: "$paymentStatus", - count: { $sum: 1 }, - }, - }, - ]); - res.status(200).json(counts); - } catch (error) { - res.status(500).json({ message: error.message }); - } -}; - -module.exports = { - getAllPayments, - getPaymentById, - createPayment, - updatePaymentStatus, - updatePaymentMethod, - getPaymentsByDateRange, - getPaymentsByAmountRange, - getPaymentByTransactionId, - countPaymentsByStatus, -}; diff --git a/backend/controllers/shop/sub-controllers/referralController.js b/backend/controllers/shop/sub-controllers/referralController.js deleted file mode 100644 index ba4285c3..00000000 --- a/backend/controllers/shop/sub-controllers/referralController.js +++ /dev/null @@ -1,202 +0,0 @@ - -const Referral = require("../../../model/shop/sub-model/Referral"); -const User = require("../../../model/user"); -const { - generateUniqueCode, - validateReferralCodeFormat, -} = require("../../../services/sub-service/referralUtils"); -const { logInfo, logError } = require("../../../services/sub-service/logger"); - -// Create a referral code and handle errors -exports.createReferral = async (req, res) => { - try { - const { referrerId } = req.body; - - const referrer = await User.findById(referrerId); - if (!referrer) { - logError("Referrer not found"); - return res.status(404).json({ message: "Referrer user not found" }); - } - - const existingReferral = await Referral.findOne({ - referrerId, - status: "pending", - }); - if (existingReferral) { - logInfo("Active referral code already exists for this user"); - return res - .status(400) - .json({ message: "Active referral code already exists" }); - } - - const referralCode = generateUniqueCode(); - const newReferral = new Referral({ referrerId, referralCode }); - - await newReferral.save(); - logInfo( - `Referral created for referrerId: ${referrerId}, code: ${referralCode}` - ); - res - .status(201) - .json({ message: "Referral created successfully", referralCode }); - } catch (error) { - logError("Error creating referral", error); - res.status(500).json({ message: "Error creating referral", error }); - } -}; - -// Get referral status -exports.checkReferralStatus = async (req, res) => { - try { - const { code } = req.params; - - if (!validateReferralCodeFormat(code)) { - logError("Invalid referral code format"); - return res.status(400).json({ message: "Invalid referral code format" }); - } - - const referral = await Referral.findOne({ referralCode: code }); - if (!referral) { - logInfo("Referral code not found"); - return res.status(404).json({ message: "Referral code not found" }); - } - - res.status(200).json({ status: referral.status }); - } catch (error) { - logError("Error checking referral status", error); - res.status(500).json({ message: "Error checking referral status", error }); - } -}; - -// Complete a referral process -exports.completeReferral = async (req, res) => { - try { - const { code, refereeId } = req.body; - - if (!validateReferralCodeFormat(code)) { - logError("Invalid referral code format"); - return res.status(400).json({ message: "Invalid referral code format" }); - } - - const referral = await Referral.findOne({ referralCode: code }); - if (!referral) { - logInfo("Referral code not found"); - return res.status(404).json({ message: "Referral code not found" }); - } - - if (referral.status === "completed") { - logInfo("Referral code already used"); - return res.status(400).json({ message: "Referral code already used" }); - } - - const referee = await User.findById(refereeId); - if (!referee) { - logInfo("Referee user not found"); - return res.status(404).json({ message: "Referee user not found" }); - } - - if (referral.referrerId.toString() === refereeId) { - logInfo("Cannot use your own referral code"); - return res - .status(400) - .json({ message: "Cannot use your own referral code" }); - } - - referral.status = "completed"; - referral.refereeId = refereeId; - await referral.save(); - logInfo(`Referral code ${code} completed successfully by ${refereeId}`); - - res.status(200).json({ message: "Referral completed successfully" }); - } catch (error) { - logError("Error completing referral", error); - res.status(500).json({ message: "Error completing referral", error }); - } -}; - -// Get referrals for specific referrer with extra filters and pagination -exports.getReferralsByReferrer = async (req, res) => { - try { - const { referrerId } = req.params; - const { status, page = 1, limit = 10 } = req.query; - - const referrer = await User.findById(referrerId); - if (!referrer) { - logError("Referrer user not found"); - return res.status(404).json({ message: "Referrer user not found" }); - } - - const filter = { referrerId }; - if (status) filter.status = status; - - const referrals = await Referral.find(filter) - .skip((page - 1) * limit) - .limit(parseInt(limit)); - const totalCount = await Referral.countDocuments(filter); - - res.status(200).json({ - referrals, - totalPages: Math.ceil(totalCount / limit), - currentPage: page, - }); - } catch (error) { - logError("Error retrieving referrals by referrer", error); - res.status(500).json({ message: "Error retrieving referrals", error }); - } -}; - -// List all referrals for admin with advanced filtering and sorting -exports.listAllReferrals = async (req, res) => { - try { - const { - page = 1, - limit = 10, - sortBy = "createdAt", - order = "desc", - } = req.query; - - const referrals = await Referral.find() - .sort({ [sortBy]: order === "asc" ? 1 : -1 }) - .skip((page - 1) * limit) - .limit(parseInt(limit)); - const totalCount = await Referral.countDocuments(); - - res.status(200).json({ - referrals, - totalPages: Math.ceil(totalCount / limit), - currentPage: page, - }); - } catch (error) { - logError("Error retrieving all referrals", error); - res.status(500).json({ message: "Error retrieving referrals", error }); - } -}; - -// Cancel a pending referral -exports.cancelReferral = async (req, res) => { - try { - const { code } = req.body; - - const referral = await Referral.findOne({ referralCode: code }); - if (!referral) { - logInfo("Referral code not found"); - return res.status(404).json({ message: "Referral code not found" }); - } - - if (referral.status !== "pending") { - logInfo("Only pending referrals can be canceled"); - return res - .status(400) - .json({ message: "Only pending referrals can be canceled" }); - } - - referral.status = "canceled"; - await referral.save(); - logInfo(`Referral code ${code} canceled successfully`); - - res.status(200).json({ message: "Referral canceled successfully" }); - } catch (error) { - logError("Error canceling referral", error); - res.status(500).json({ message: "Error canceling referral", error }); - } -}; diff --git a/backend/controllers/shop/sub-controllers/returnController.js b/backend/controllers/shop/sub-controllers/returnController.js deleted file mode 100644 index 21da8d57..00000000 --- a/backend/controllers/shop/sub-controllers/returnController.js +++ /dev/null @@ -1,229 +0,0 @@ - -const ReturnProduct = require('../models/ReturnProduct'); -const Product = require('../models/Product'); -const User = require('../models/User'); - -// Create Return (POST /api/returns) -exports.createReturn = async (req, res) => { - try { - const { productId, returnDate, condition } = req.body; - const userId = req.user.id; // Assuming user authentication is in place - - const product = await Product.findById(productId); - if (!product) { - return res.status(404).json({ message: 'Product not found.' }); - } - - // Check if the product has already been returned - const existingReturn = await ReturnProduct.findOne({ productId, userId, status: 'returned' }); - if (existingReturn) { - return res.status(400).json({ message: 'Product has already been returned.' }); - } - - const returnRequest = new ReturnProduct({ - productId, - userId, - returnDate, - condition, - status: 'pending' - }); - - await returnRequest.save(); - res.status(201).json({ message: 'Return request created successfully.', returnRequest }); - } catch (err) { - res.status(500).json({ message: 'Server error.', error: err.message }); - } -}; - -// Update Return Status (PATCH /api/returns/:id) -exports.updateReturnStatus = async (req, res) => { - try { - const { status } = req.body; - const returnId = req.params.id; - - if (!['approved', 'rejected'].includes(status)) { - return res.status(400).json({ message: 'Invalid status.' }); - } - - const returnRequest = await ReturnProduct.findById(returnId); - if (!returnRequest) { - return res.status(404).json({ message: 'Return request not found.' }); - } - - // Ensure that only admins can update the status - if (!req.user.isAdmin) { - return res.status(403).json({ message: 'Admin access required.' }); - } - - returnRequest.status = status; - returnRequest.updatedAt = Date.now(); - await returnRequest.save(); - - res.status(200).json({ message: 'Return status updated successfully.', returnRequest }); - } catch (err) { - res.status(500).json({ message: 'Server error.', error: err.message }); - } -}; - -// Get Return Information (GET /api/returns/:id) -exports.getReturnInformation = async (req, res) => { - try { - const returnId = req.params.id; - const returnRequest = await ReturnProduct.findById(returnId) - .populate('productId') - .populate('userId'); - - if (!returnRequest) { - return res.status(404).json({ message: 'Return request not found.' }); - } - - // Check if the user is authorized to view return details - if (req.user.id !== returnRequest.userId.toString() && !req.user.isAdmin) { - return res.status(403).json({ message: 'Unauthorized access.' }); - } - - res.status(200).json(returnRequest); - } catch (err) { - res.status(500).json({ message: 'Server error.', error: err.message }); - } -}; - -// Get User’s Return History (GET /api/returns/user/:userId) -exports.getUserReturnHistory = async (req, res) => { - try { - const userId = req.params.userId; - - if (req.user.id !== userId && !req.user.isAdmin) { - return res.status(403).json({ message: 'Unauthorized access.' }); - } - - const returnHistory = await ReturnProduct.find({ userId }) - .populate('productId') - .populate('userId'); - - if (!returnHistory.length) { - return res.status(404).json({ message: 'No return history found.' }); - } - - res.status(200).json(returnHistory); - } catch (err) { - res.status(500).json({ message: 'Server error.', error: err.message }); - } -}; - -// Get All Pending Returns (GET /api/returns/pending) -exports.getPendingReturns = async (req, res) => { - try { - if (!req.user.isAdmin) { - return res.status(403).json({ message: 'Admin access required.' }); - } - - const pendingReturns = await ReturnProduct.find({ status: 'pending' }) - .populate('productId') - .populate('userId'); - - if (!pendingReturns.length) { - return res.status(404).json({ message: 'No pending returns found.' }); - } - - res.status(200).json(pendingReturns); - } catch (err) { - res.status(500).json({ message: 'Server error.', error: err.message }); - } -}; - -// Cancel Return Request (PATCH /api/returns/cancel/:id) -exports.cancelReturnRequest = async (req, res) => { - try { - const returnId = req.params.id; - const returnRequest = await ReturnProduct.findById(returnId); - - if (!returnRequest) { - return res.status(404).json({ message: 'Return request not found.' }); - } - - // Check if the return request is still pending - if (returnRequest.status !== 'pending') { - return res.status(400).json({ message: 'Return request cannot be canceled once it is processed.' }); - } - - // Ensure that the user is the one who made the return request - if (returnRequest.userId.toString() !== req.user.id) { - return res.status(403).json({ message: 'You are not authorized to cancel this return request.' }); - } - - returnRequest.status = 'canceled'; - returnRequest.updatedAt = Date.now(); - await returnRequest.save(); - - res.status(200).json({ message: 'Return request canceled successfully.', returnRequest }); - } catch (err) { - res.status(500).json({ message: 'Server error.', error: err.message }); - } - }; - - // Get All Returned Products (GET /api/returns/returned) -exports.getAllReturnedProducts = async (req, res) => { - try { - if (!req.user.isAdmin) { - return res.status(403).json({ message: 'Admin access required.' }); - } - - const returnedProducts = await ReturnProduct.find({ status: 'returned' }) - .populate('productId') - .populate('userId'); - - if (!returnedProducts.length) { - return res.status(404).json({ message: 'No returned products found.' }); - } - - res.status(200).json(returnedProducts); - } catch (err) { - res.status(500).json({ message: 'Server error.', error: err.message }); - } - }; - - // Get All Damaged Products (GET /api/returns/damaged) -exports.getAllDamagedProducts = async (req, res) => { - try { - if (!req.user.isAdmin) { - return res.status(403).json({ message: 'Admin access required.' }); - } - - const damagedProducts = await ReturnProduct.find({ condition: 'damaged' }) - .populate('productId') - .populate('userId'); - - if (!damagedProducts.length) { - return res.status(404).json({ message: 'No damaged products found.' }); - } - - res.status(200).json(damagedProducts); - } catch (err) { - res.status(500).json({ message: 'Server error.', error: err.message }); - } - }; - - // Get Return Requests for a Specific Product (GET /api/returns/product/:productId) -exports.getReturnRequestsForProduct = async (req, res) => { - try { - const { productId } = req.params; - - if (!req.user.isAdmin) { - return res.status(403).json({ message: 'Admin access required.' }); - } - - const returnRequests = await ReturnProduct.find({ productId }) - .populate('productId') - .populate('userId'); - - if (!returnRequests.length) { - return res.status(404).json({ message: 'No return requests found for this product.' }); - } - - res.status(200).json(returnRequests); - } catch (err) { - res.status(500).json({ message: 'Server error.', error: err.message }); - } - }; - \ No newline at end of file diff --git a/backend/controllers/shop/sub-controllers/shippingAddressController.js b/backend/controllers/shop/sub-controllers/shippingAddressController.js deleted file mode 100644 index b69f1acd..00000000 --- a/backend/controllers/shop/sub-controllers/shippingAddressController.js +++ /dev/null @@ -1,249 +0,0 @@ -// controllers/shippingAddressController.js -const ShippingAddress = require("../../../model/shop/sub-model/ShippingAddress"); - -// Add a new shipping address -exports.addShippingAddress = async (req, res) => { - try { - const { addressLine1, addressLine2, city, state, postalCode, country } = - req.body; - - const newAddress = new ShippingAddress({ - addressLine1, - addressLine2, - city, - state, - postalCode, - country, - user: req.user._id, // assuming user authentication middleware is in place - }); - - await newAddress.save(); - res - .status(201) - .json({ - message: "Shipping address added successfully", - address: newAddress, - }); - } catch (error) { - res.status(500).json({ message: "Server error", error: error.message }); - } -}; - -// Get all shipping addresses for a user -exports.getShippingAddresses = async (req, res) => { - try { - const addresses = await ShippingAddress.find({ user: req.user._id }); - res.status(200).json(addresses); - } catch (error) { - res.status(500).json({ message: "Server error", error: error.message }); - } -}; - -// Update a specific shipping address -exports.updateShippingAddress = async (req, res) => { - try { - const { id } = req.params; - const { addressLine1, addressLine2, city, state, postalCode, country } = - req.body; - - const updatedAddress = await ShippingAddress.findOneAndUpdate( - { _id: id, user: req.user._id }, - { addressLine1, addressLine2, city, state, postalCode, country }, - { new: true } - ); - - if (!updatedAddress) { - return res - .status(404) - .json({ message: "Address not found or not authorized" }); - } - - res - .status(200) - .json({ - message: "Shipping address updated successfully", - address: updatedAddress, - }); - } catch (error) { - res.status(500).json({ message: "Server error", error: error.message }); - } -}; - -// Delete a specific shipping address -exports.deleteShippingAddress = async (req, res) => { - try { - const { id } = req.params; - - const deletedAddress = await ShippingAddress.findOneAndDelete({ - _id: id, - user: req.user._id, - }); - - if (!deletedAddress) { - return res - .status(404) - .json({ message: "Address not found or not authorized" }); - } - - res.status(200).json({ message: "Shipping address deleted successfully" }); - } catch (error) { - res.status(500).json({ message: "Server error", error: error.message }); - } -}; - -// Set a primary shipping address -exports.setPrimaryAddress = async (req, res) => { - try { - const { id } = req.params; - - // Find the user's addresses and set all addresses to not primary - await ShippingAddress.updateMany( - { user: req.user._id }, - { $set: { isPrimary: false } } - ); - - // Set the specified address as primary - const primaryAddress = await ShippingAddress.findOneAndUpdate( - { _id: id, user: req.user._id }, - { $set: { isPrimary: true } }, - { new: true } - ); - - if (!primaryAddress) { - return res - .status(404) - .json({ message: "Address not found or not authorized" }); - } - - res - .status(200) - .json({ - message: "Primary address set successfully", - address: primaryAddress, - }); - } catch (error) { - res.status(500).json({ message: "Server error", error: error.message }); - } -}; - -// Get a specific shipping address by ID -exports.getShippingAddressById = async (req, res) => { - try { - const { id } = req.params; - - const address = await ShippingAddress.findOne({ - _id: id, - user: req.user._id, - }); - - if (!address) { - return res - .status(404) - .json({ message: "Address not found or not authorized" }); - } - - res.status(200).json({ address }); - } catch (error) { - res.status(500).json({ message: "Server error", error: error.message }); - } -}; - -// Get primary shipping address -exports.getPrimaryAddress = async (req, res) => { - try { - const primaryAddress = await ShippingAddress.findOne({ - user: req.user._id, - isPrimary: true, - }); - - if (!primaryAddress) { - return res.status(404).json({ message: "No primary address found" }); - } - - res.status(200).json({ address: primaryAddress }); - } catch (error) { - res.status(500).json({ message: "Server error", error: error.message }); - } -}; - - - -// Set a default address -exports.setDefaultAddress = async (req, res) => { - try { - const { id } = req.params; - - // Reset all addresses' default status for the user - await ShippingAddress.updateMany( - { user: req.user._id }, - { $set: { isDefault: false } } - ); - - // Set the specified address as default - const defaultAddress = await ShippingAddress.findOneAndUpdate( - { _id: id, user: req.user._id }, - { $set: { isDefault: true } }, - { new: true } - ); - - if (!defaultAddress) { - return res.status(404).json({ message: 'Address not found or not authorized' }); - } - - res.status(200).json({ message: 'Default address set successfully', address: defaultAddress }); - } catch (error) { - res.status(500).json({ message: 'Server error', error: error.message }); - } -}; - -// Search addresses by field (e.g., city, state, country) -exports.searchAddresses = async (req, res) => { - try { - const { city, state, country } = req.query; - const searchCriteria = { user: req.user._id }; - - if (city) searchCriteria.city = city; - if (state) searchCriteria.state = state; - if (country) searchCriteria.country = country; - - const addresses = await ShippingAddress.find(searchCriteria); - res.status(200).json(addresses); - } catch (error) { - res.status(500).json({ message: 'Server error', error: error.message }); - } -}; - -// Archive a specific address -exports.archiveAddress = async (req, res) => { - try { - const { id } = req.params; - - const archivedAddress = await ShippingAddress.findOneAndUpdate( - { _id: id, user: req.user._id }, - { $set: { isArchived: true } }, - { new: true } - ); - - if (!archivedAddress) { - return res.status(404).json({ message: 'Address not found or not authorized' }); - } - - res.status(200).json({ message: 'Address archived successfully', address: archivedAddress }); - } catch (error) { - res.status(500).json({ message: 'Server error', error: error.message }); - } -}; - -// Retrieve only active (non-archived) addresses -exports.getActiveAddresses = async (req, res) => { - try { - const activeAddresses = await ShippingAddress.find({ - user: req.user._id, - isArchived: { $ne: true }, - }); - - res.status(200).json(activeAddresses); - } catch (error) { - res.status(500).json({ message: 'Server error', error: error.message }); - } -}; diff --git a/backend/controllers/shop/sub-controllers/supplierController.js b/backend/controllers/shop/sub-controllers/supplierController.js deleted file mode 100644 index c088b5b5..00000000 --- a/backend/controllers/shop/sub-controllers/supplierController.js +++ /dev/null @@ -1,176 +0,0 @@ -const Supplier = require("../models/Supplier"); - -exports.createSupplier = async (req, res) => { - try { - const { name, contactInfo, address, productsSupplied, status } = req.body; - const supplier = new Supplier({ - name, - contactInfo, - address, - productsSupplied, - status, - }); - await supplier.save(); - res.status(201).json(supplier); - } catch (err) { - res.status(500).json({ message: "Error creating supplier", error: err }); - } -}; - -// Get all Suppliers with pagination and sorting -exports.getAllSuppliers = async (req, res) => { - try { - const { page = 1, limit = 10, sort = "createdAt" } = req.query; - const suppliers = await Supplier.find() - .sort(sort) - .skip((page - 1) * limit) - .limit(Number(limit)); - res.json(suppliers); - } catch (err) { - res.status(500).json({ message: "Error fetching suppliers", error: err }); - } -}; - -// Get a Supplier by ID -exports.getSupplierById = async (req, res) => { - try { - const supplier = await Supplier.findById(req.params.id); - if (!supplier) { - return res.status(404).json({ message: "Supplier not found" }); - } - res.json(supplier); - } catch (err) { - res.status(500).json({ message: "Error fetching supplier", error: err }); - } -}; - -// Update a Supplier -exports.updateSupplier = async (req, res) => { - try { - const { name, contactInfo, address, productsSupplied, status } = req.body; - const supplier = await Supplier.findByIdAndUpdate( - req.params.id, - { - name, - contactInfo, - address, - productsSupplied, - status, - updatedAt: Date.now(), - }, - { new: true } - ); - if (!supplier) { - return res.status(404).json({ message: "Supplier not found" }); - } - res.json(supplier); - } catch (err) { - res.status(500).json({ message: "Error updating supplier", error: err }); - } -}; - -// Soft delete a Supplier (set status to inactive) -exports.deleteSupplier = async (req, res) => { - try { - const supplier = await Supplier.findByIdAndUpdate( - req.params.id, - { status: "inactive" }, - { new: true } - ); - if (!supplier) { - return res.status(404).json({ message: "Supplier not found" }); - } - res.json(supplier); - } catch (err) { - res.status(500).json({ message: "Error deleting supplier", error: err }); - } -}; - -const Supplier = require("../models/Supplier"); -const Product = require("../models/Product"); // Assuming there's a Product model - -// Add a product to a supplier -exports.addProductToSupplier = async (req, res) => { - try { - const { productId } = req.body; - const supplier = await Supplier.findById(req.params.id); - if (!supplier) { - return res.status(404).json({ message: "Supplier not found" }); - } - - supplier.productsSupplied.push(productId); - await supplier.save(); - - res.status(200).json(supplier); - } catch (err) { - res - .status(500) - .json({ message: "Error adding product to supplier", error: err }); - } -}; - -// Remove a product from a supplier -exports.removeProductFromSupplier = async (req, res) => { - try { - const { productId } = req.body; - const supplier = await Supplier.findById(req.params.id); - if (!supplier) { - return res.status(404).json({ message: "Supplier not found" }); - } - - supplier.productsSupplied = supplier.productsSupplied.filter( - (product) => product.toString() !== productId - ); - await supplier.save(); - - res.status(200).json(supplier); - } catch (err) { - res - .status(500) - .json({ message: "Error removing product from supplier", error: err }); - } -}; - -// Get all products supplied by a supplier -exports.getProductsSupplied = async (req, res) => { - try { - const supplier = await Supplier.findById(req.params.id).populate( - "productsSupplied" - ); - if (!supplier) { - return res.status(404).json({ message: "Supplier not found" }); - } - res.json(supplier.productsSupplied); - } catch (err) { - res.status(500).json({ message: "Error fetching products", error: err }); - } -}; - -exports.searchSuppliers = async (req, res) => { - try { - const { name, status, email, phone } = req.query; - const query = {}; - - if (name) query.name = { $regex: name, $options: "i" }; - if (status) query.status = status; - if (email) query["contactInfo.email"] = email; - if (phone) query["contactInfo.phone"] = phone; - - const suppliers = await Supplier.find(query); - res.json(suppliers); - } catch (err) { - res.status(500).json({ message: "Error searching suppliers", error: err }); - } -}; - -exports.getSuppliersByStatus = async (req, res) => { - try { - const { status } = req.params; - const suppliers = await Supplier.find({ status }); - res.json(suppliers); - } catch (err) { - res - .status(500) - .json({ message: "Error fetching suppliers by status", error: err }); - } -}; diff --git a/backend/controllers/shop/sub-controllers/ticketController.js b/backend/controllers/shop/sub-controllers/ticketController.js deleted file mode 100644 index 2fa3385e..00000000 --- a/backend/controllers/shop/sub-controllers/ticketController.js +++ /dev/null @@ -1,277 +0,0 @@ -const Ticket = require("../../../model/shop/sub-model/TIcket"); -const User = require("../../../model/user"); -const Agent = require("../models/Agent"); - -const asyncHandler = require("express-async-handler"); - -// Create a new ticket -const createTicket = asyncHandler(async (req, res) => { - const { userId, subject, description, priority } = req.body; - - if (!userId || !subject || !description || !priority) { - return res.status(400).json({ message: "Missing required fields" }); - } - - const ticketId = `TKT-${Date.now()}`; - - const ticket = await Ticket.create({ - ticketId, - userId, - subject, - description, - priority, - }); - - res.status(201).json(ticket); -}); - -// Fetch ticket details by ticketId -const getTicketDetails = asyncHandler(async (req, res) => { - const { ticketId } = req.params; - - const ticket = await Ticket.findOne({ ticketId }) - .populate("userId") - .populate("assignedAgentId"); - - if (!ticket) { - return res.status(404).json({ message: "Ticket not found" }); - } - - res.status(200).json(ticket); -}); - -// Fetch all tickets for a user -const getUserTickets = asyncHandler(async (req, res) => { - const { userId } = req.params; - - const tickets = await Ticket.find({ userId }).populate("assignedAgentId"); - - if (tickets.length === 0) { - return res.status(404).json({ message: "No tickets found for this user" }); - } - - res.status(200).json(tickets); -}); - -// Fetch all tickets assigned to an agent -const getAssignedTickets = asyncHandler(async (req, res) => { - const { agentId } = req.params; - - const tickets = await Ticket.find({ assignedAgentId: agentId }); - - if (tickets.length === 0) { - return res - .status(404) - .json({ message: "No tickets assigned to this agent" }); - } - - res.status(200).json(tickets); -}); - -// Update ticket status -const updateTicketStatus = asyncHandler(async (req, res) => { - const { ticketId } = req.params; - const { status } = req.body; - - if ( - !status || - !["open", "in-progress", "resolved", "closed"].includes(status) - ) { - return res.status(400).json({ message: "Invalid status" }); - } - - const ticket = await Ticket.findOne({ ticketId }); - - if (!ticket) { - return res.status(404).json({ message: "Ticket not found" }); - } - - if ( - ticket.assignedAgentId && - ticket.assignedAgentId.toString() !== req.user.id - ) { - return res - .status(403) - .json({ message: "You are not authorized to update this ticket" }); - } - - // Only allow status changes from 'open' to 'in-progress', 'in-progress' to 'resolved', and 'resolved' to 'closed' - const validStatusChanges = { - open: ["in-progress"], - "in-progress": ["resolved"], - resolved: ["closed"], - }; - - if (!validStatusChanges[ticket.status]?.includes(status)) { - return res - .status(400) - .json({ message: `Cannot move from ${ticket.status} to ${status}` }); - } - - ticket.status = status; - ticket.updatedAt = Date.now(); - - await ticket.save(); - - res.status(200).json(ticket); -}); - -// Assign a ticket to a support agent -const assignTicket = asyncHandler(async (req, res) => { - const { ticketId } = req.params; - const { agentId } = req.body; - - if (!agentId) { - return res.status(400).json({ message: "Agent ID is required" }); - } - - const ticket = await Ticket.findOne({ ticketId }); - - if (!ticket) { - return res.status(404).json({ message: "Ticket not found" }); - } - - const agent = await Agent.findById(agentId); - - if (!agent) { - return res.status(404).json({ message: "Agent not found" }); - } - - ticket.assignedAgentId = agentId; - ticket.updatedAt = Date.now(); - - await ticket.save(); - - res.status(200).json(ticket); -}); - -// Close a ticket (status "closed") -const closeTicket = asyncHandler(async (req, res) => { - const { ticketId } = req.params; - - const ticket = await Ticket.findOne({ ticketId }); - - if (!ticket) { - return res.status(404).json({ message: "Ticket not found" }); - } - - if (ticket.status === "closed") { - return res.status(400).json({ message: "Ticket is already closed" }); - } - - ticket.status = "closed"; - ticket.updatedAt = Date.now(); - - await ticket.save(); - - res.status(200).json(ticket); -}); - -// Delete a ticket (soft delete or permanent) -const deleteTicket = asyncHandler(async (req, res) => { - const { ticketId } = req.params; - - const ticket = await Ticket.findOne({ ticketId }); - - if (!ticket) { - return res.status(404).json({ message: "Ticket not found" }); - } - - // You can choose to either permanently delete or soft delete - await ticket.remove(); // Soft delete - - res.status(200).json({ message: "Ticket deleted successfully" }); -}); - -// Get all tickets (Admin only) -const getAllTickets = asyncHandler(async (req, res) => { - const tickets = await Ticket.find() - .populate("assignedAgentId") - .populate("userId"); - - if (tickets.length === 0) { - return res.status(404).json({ message: "No tickets found" }); - } - - res.status(200).json(tickets); -}); - -// Update ticket priority -const updateTicketPriority = asyncHandler(async (req, res) => { - const { ticketId } = req.params; - const { priority } = req.body; - - if (!["low", "medium", "high"].includes(priority)) { - return res.status(400).json({ message: "Invalid priority level" }); - } - - const ticket = await Ticket.findOne({ ticketId }); - - if (!ticket) { - return res.status(404).json({ message: "Ticket not found" }); - } - - ticket.priority = priority; - ticket.updatedAt = Date.now(); - - await ticket.save(); - - res.status(200).json(ticket); -}); - -// Fetch tickets by status -const getTicketsByStatus = asyncHandler(async (req, res) => { - const { status } = req.params; - - if (!["open", "in-progress", "resolved", "closed"].includes(status)) { - return res.status(400).json({ message: "Invalid status" }); - } - - const tickets = await Ticket.find({ status }) - .populate("assignedAgentId") - .populate("userId"); - - if (tickets.length === 0) { - return res - .status(404) - .json({ message: `No tickets with status: ${status}` }); - } - - res.status(200).json(tickets); -}); - -// Fetch tickets by priority -const getTicketsByPriority = asyncHandler(async (req, res) => { - const { priority } = req.params; - - if (!["low", "medium", "high"].includes(priority)) { - return res.status(400).json({ message: "Invalid priority level" }); - } - - const tickets = await Ticket.find({ priority }) - .populate("assignedAgentId") - .populate("userId"); - - if (tickets.length === 0) { - return res - .status(404) - .json({ message: `No tickets with priority: ${priority}` }); - } - - res.status(200).json(tickets); -}); - -module.exports = { - createTicket, - getTicketDetails, - getUserTickets, - getAssignedTickets, - updateTicketStatus, - assignTicket, - closeTicket, - deleteTicket, - getAllTickets, - updateTicketPriority, - getTicketsByStatus, - getTicketsByPriority, -}; diff --git a/backend/controllers/shop/sub-controllers/warehouseController.js b/backend/controllers/shop/sub-controllers/warehouseController.js deleted file mode 100644 index 2e8dbfe4..00000000 --- a/backend/controllers/shop/sub-controllers/warehouseController.js +++ /dev/null @@ -1,330 +0,0 @@ -const Warehouse = require("../../../model/shop/sub-model/Warehouse"); -const InventoryItem = require("../../../model/shop/sub-model/InventoryModel"); - -// 1. Create Warehouse Logic -exports.createWarehouse = async (req, res) => { - try { - const { - warehouseId, - warehouseName, - address, - capacity, - currentOccupancy, - inventoryItems, - contactInfo, - } = req.body; - - // Validate unique Warehouse Name and Warehouse ID - const existingWarehouse = await Warehouse.findOne({ - $or: [{ warehouseId }, { warehouseName }], - }); - if (existingWarehouse) { - return res - .status(400) - .json({ message: "Warehouse ID or Name must be unique" }); - } - - // Create new warehouse - const warehouse = new Warehouse({ - warehouseId, - warehouseName, - address, - capacity, - currentOccupancy, - inventoryItems, - contactInfo, - lastUpdated: new Date(), - }); - - await warehouse.save(); - - return res - .status(201) - .json({ message: "Warehouse created successfully", warehouse }); - } catch (error) { - return res.status(500).json({ message: "Server error", error }); - } -}; - -// 2. Update Warehouse Logic -exports.updateWarehouse = async (req, res) => { - try { - const { warehouseId } = req.params; - const { - warehouseName, - address, - capacity, - currentOccupancy, - inventoryItems, - contactInfo, - } = req.body; - - const warehouse = await Warehouse.findOne({ warehouseId }); - if (!warehouse) { - return res.status(404).json({ message: "Warehouse not found" }); - } - - // Update warehouse data - warehouse.warehouseName = warehouseName || warehouse.warehouseName; - warehouse.address = address || warehouse.address; - warehouse.capacity = capacity || warehouse.capacity; - warehouse.currentOccupancy = currentOccupancy || warehouse.currentOccupancy; - warehouse.inventoryItems = inventoryItems || warehouse.inventoryItems; - warehouse.contactInfo = contactInfo || warehouse.contactInfo; - warehouse.lastUpdated = new Date(); - - await warehouse.save(); - - return res - .status(200) - .json({ message: "Warehouse updated successfully", warehouse }); - } catch (error) { - return res.status(500).json({ message: "Server error", error }); - } -}; - -// 3. Get Warehouse Inventory -exports.getWarehouseInventory = async (req, res) => { - try { - const { warehouseId } = req.params; - - const warehouse = await Warehouse.findOne({ warehouseId }); - if (!warehouse) { - return res.status(404).json({ message: "Warehouse not found" }); - } - - return res.status(200).json({ inventoryItems: warehouse.inventoryItems }); - } catch (error) { - return res.status(500).json({ message: "Server error", error }); - } -}; - -// 4. Check Warehouse Capacity -exports.checkWarehouseCapacity = async (req, res) => { - try { - const { warehouseId } = req.params; - - const warehouse = await Warehouse.findOne({ warehouseId }); - if (!warehouse) { - return res.status(404).json({ message: "Warehouse not found" }); - } - - if (warehouse.currentOccupancy > warehouse.capacity) { - return res.status(400).json({ - message: "Current Occupancy exceeds Warehouse Capacity", - status: "Over Capacity", - currentOccupancy: warehouse.currentOccupancy, - capacity: warehouse.capacity, - }); - } - - return res.status(200).json({ - message: "Warehouse is within capacity", - status: "Within Capacity", - currentOccupancy: warehouse.currentOccupancy, - capacity: warehouse.capacity, - }); - } catch (error) { - return res.status(500).json({ message: "Server error", error }); - } -}; - -// 5. Delete Warehouse Logic -exports.deleteWarehouse = async (req, res) => { - try { - const { warehouseId } = req.params; - - const warehouse = await Warehouse.findOne({ warehouseId }); - if (!warehouse) { - return res.status(404).json({ message: "Warehouse not found" }); - } - - await warehouse.remove(); - - return res.status(200).json({ message: "Warehouse deleted successfully" }); - } catch (error) { - return res.status(500).json({ message: "Server error", error }); - } -}; - -// 6. Get All Warehouses -exports.getAllWarehouses = async (req, res) => { - try { - const warehouses = await Warehouse.find(); - return res.status(200).json(warehouses); - } catch (error) { - return res.status(500).json({ message: "Server error", error }); - } -}; - -// 7. Search Warehouse by Name or ID -exports.searchWarehouse = async (req, res) => { - try { - const { query } = req.params; - const warehouses = await Warehouse.find({ - $or: [ - { warehouseId: { $regex: query, $options: "i" } }, - { warehouseName: { $regex: query, $options: "i" } }, - ], - }); - - if (warehouses.length === 0) { - return res.status(404).json({ message: "No matching warehouses found" }); - } - - return res.status(200).json(warehouses); - } catch (error) { - return res.status(500).json({ message: "Server error", error }); - } -}; - -// 8. Add New Inventory Item -exports.addInventoryItem = async (req, res) => { - try { - const { warehouseId } = req.params; - const { itemName, quantity, price } = req.body; - - const warehouse = await Warehouse.findOne({ warehouseId }); - if (!warehouse) { - return res.status(404).json({ message: "Warehouse not found" }); - } - - // Create new inventory item - const inventoryItem = new InventoryItem({ - itemName, - quantity, - price, - warehouseId, - }); - - await inventoryItem.save(); - - // Add the inventory item to the warehouse - warehouse.inventoryItems.push(inventoryItem); - await warehouse.save(); - - return res - .status(201) - .json({ message: "Inventory item added successfully", inventoryItem }); - } catch (error) { - return res.status(500).json({ message: "Server error", error }); - } -}; - -// 9. Update Inventory Item -exports.updateInventoryItem = async (req, res) => { - try { - const { warehouseId, itemId } = req.params; - const { quantity, price } = req.body; - - const warehouse = await Warehouse.findOne({ warehouseId }); - if (!warehouse) { - return res.status(404).json({ message: "Warehouse not found" }); - } - - const inventoryItem = await InventoryItem.findOne({ - _id: itemId, - warehouseId, - }); - if (!inventoryItem) { - return res.status(404).json({ message: "Inventory item not found" }); - } - - inventoryItem.quantity = quantity || inventoryItem.quantity; - inventoryItem.price = price || inventoryItem.price; - - await inventoryItem.save(); - - return res - .status(200) - .json({ message: "Inventory item updated successfully", inventoryItem }); - } catch (error) { - return res.status(500).json({ message: "Server error", error }); - } -}; - -// 10. Get Inventory Item by ID -exports.getInventoryItemById = async (req, res) => { - try { - const { warehouseId, itemId } = req.params; - - const warehouse = await Warehouse.findOne({ warehouseId }); - if (!warehouse) { - return res.status(404).json({ message: "Warehouse not found" }); - } - - const inventoryItem = await InventoryItem.findOne({ - _id: itemId, - warehouseId, - }); - if (!inventoryItem) { - return res.status(404).json({ message: "Inventory item not found" }); - } - - return res.status(200).json({ inventoryItem }); - } catch (error) { - return res.status(500).json({ message: "Server error", error }); - } -}; - -// 11. Delete Inventory Item -exports.deleteInventoryItem = async (req, res) => { - try { - const { warehouseId, itemId } = req.params; - - const warehouse = await Warehouse.findOne({ warehouseId }); - if (!warehouse) { - return res.status(404).json({ message: "Warehouse not found" }); - } - - const inventoryItem = await InventoryItem.findOne({ - _id: itemId, - warehouseId, - }); - if (!inventoryItem) { - return res.status(404).json({ message: "Inventory item not found" }); - } - - // Remove item from the warehouse - warehouse.inventoryItems = warehouse.inventoryItems.filter( - (item) => item._id.toString() !== itemId - ); - await warehouse.save(); - - // Delete the inventory item - await inventoryItem.remove(); - - return res - .status(200) - .json({ message: "Inventory item deleted successfully" }); - } catch (error) { - return res.status(500).json({ message: "Server error", error }); - } -}; - -// 12. Check Stock Level of Item -exports.checkStockLevel = async (req, res) => { - try { - const { warehouseId, itemId } = req.params; - - const warehouse = await Warehouse.findOne({ warehouseId }); - if (!warehouse) { - return res.status(404).json({ message: "Warehouse not found" }); - } - - const inventoryItem = await InventoryItem.findOne({ - _id: itemId, - warehouseId, - }); - if (!inventoryItem) { - return res.status(404).json({ message: "Inventory item not found" }); - } - - return res.status(200).json({ - message: "Inventory item stock level", - stockLevel: inventoryItem.quantity, - }); - } catch (error) { - return res.status(500).json({ message: "Server error", error }); - } -}; diff --git a/backend/middleware/sub-ware/agentMiddleware.js b/backend/middleware/sub-ware/agentMiddleware.js deleted file mode 100644 index 63144e91..00000000 --- a/backend/middleware/sub-ware/agentMiddleware.js +++ /dev/null @@ -1,23 +0,0 @@ -const Agent = require('../models/Agent'); - -// Middleware to check if the agent exists -exports.checkAgentExists = async (req, res, next) => { - try { - const agent = await Agent.findById(req.params.id); - if (!agent) { - return res.status(404).json({ message: 'Agent not found' }); - } - next(); - } catch (err) { - res.status(400).json({ message: 'Error checking agent existence', error: err }); - } -}; - -// Middleware to check agent permissions (e.g., only admins can assign tickets) -exports.checkPermissions = (req, res, next) => { - const agentRole = req.user.role; // Assuming user role is stored in the request context - if (agentRole !== 'admin') { - return res.status(403).json({ message: 'Permission denied' }); - } - next(); -}; diff --git a/backend/middleware/sub-ware/authSupplierMiddleware.js b/backend/middleware/sub-ware/authSupplierMiddleware.js deleted file mode 100644 index adce51f9..00000000 --- a/backend/middleware/sub-ware/authSupplierMiddleware.js +++ /dev/null @@ -1,10 +0,0 @@ -const isAdmin = (req, res, next) => { - // Assuming user object is attached to request after authentication - if (req.user && req.user.role === "admin") { - next(); - } else { - return res.status(403).json({ message: "Access forbidden: Admins only" }); - } -}; - -module.exports = isAdmin; diff --git a/backend/middleware/sub-ware/giftCardMiddleware.js b/backend/middleware/sub-ware/giftCardMiddleware.js deleted file mode 100644 index 3c7782fa..00000000 --- a/backend/middleware/sub-ware/giftCardMiddleware.js +++ /dev/null @@ -1,28 +0,0 @@ -const GiftCard = require("../../model/shop/sub-model/GiftCard"); - -// Validate if gift card is active and not expired -exports.validateGiftCard = async (req, res, next) => { - const { cardNumber } = req.body; - - const giftCard = await GiftCard.findOne({ cardNumber }); - - if (!giftCard) { - return res.status(404).json({ message: "Gift card not found" }); - } - - if (giftCard.status === "redeemed") { - return res.status(400).json({ message: "Gift card already redeemed" }); - } - - if (giftCard.status === "expired") { - return res.status(400).json({ message: "Gift card has expired" }); - } - - if (giftCard.expiryDate < new Date()) { - giftCard.status = "expired"; - await giftCard.save(); - return res.status(400).json({ message: "Gift card has expired" }); - } - - next(); -}; diff --git a/backend/middleware/sub-ware/inventoryMiddleware.js b/backend/middleware/sub-ware/inventoryMiddleware.js deleted file mode 100644 index 16638dd9..00000000 --- a/backend/middleware/sub-ware/inventoryMiddleware.js +++ /dev/null @@ -1,38 +0,0 @@ -const Inventory = require("../../model/shop/sub-model/InventoryModel"); -const Product = require("../../model/shop/product"); - -// Middleware to validate if product exists before creating inventory -exports.validateProductExistence = async (req, res, next) => { - const { productId } = req.body; - - const product = await Product.findById(productId); - if (!product) { - return res.status(400).json({ message: "Product not found" }); - } - - next(); -}; - -// Middleware to ensure valid stock level when updating -exports.validateStockLevel = (req, res, next) => { - const { newStockLevel } = req.body; - - if (newStockLevel < 0) { - return res.status(400).json({ message: "Stock level cannot be negative" }); - } - - next(); -}; - -// Middleware to ensure reorder level is logical (not negative) -exports.validateReorderLevel = (req, res, next) => { - const { reorderLevel } = req.body; - - if (reorderLevel < 0) { - return res - .status(400) - .json({ message: "Reorder level cannot be negative" }); - } - - next(); -}; diff --git a/backend/middleware/sub-ware/ticketMiddleware.js b/backend/middleware/sub-ware/ticketMiddleware.js deleted file mode 100644 index f09df616..00000000 --- a/backend/middleware/sub-ware/ticketMiddleware.js +++ /dev/null @@ -1,22 +0,0 @@ -const Ticket = require("../models/Ticket"); - -// Middleware to ensure only the user who created the ticket can update it -const checkTicketOwnership = async (req, res, next) => { - const { ticketId } = req.params; - - const ticket = await Ticket.findOne({ ticketId }); - - if (!ticket) { - return res.status(404).json({ message: "Ticket not found" }); - } - - if (ticket.userId.toString() !== req.user.id) { - return res - .status(403) - .json({ message: "You are not authorized to update this ticket" }); - } - - next(); -}; - -module.exports = { checkTicketOwnership }; diff --git a/backend/middleware/sub-ware/validate.js b/backend/middleware/sub-ware/validate.js deleted file mode 100644 index 792c4a16..00000000 --- a/backend/middleware/sub-ware/validate.js +++ /dev/null @@ -1,15 +0,0 @@ - -const { check, validationResult } = require('express-validator'); - -exports.validateDeliveryPerson = [ - check('email').isEmail().withMessage('Email is invalid'), - check('phone_number').isMobilePhone().withMessage('Phone number is invalid'), - check('status').isIn(['active', 'inactive']).withMessage('Status must be active or inactive'), - (req, res, next) => { - const errors = validationResult(req); - if (!errors.isEmpty()) { - return res.status(400).json({ errors: errors.array() }); - } - next(); - } -]; diff --git a/backend/middleware/sub-ware/validateCoupon.js b/backend/middleware/sub-ware/validateCoupon.js deleted file mode 100644 index 528959ce..00000000 --- a/backend/middleware/sub-ware/validateCoupon.js +++ /dev/null @@ -1,21 +0,0 @@ -const { validateCoupon } = require('../../middleware/sub-ware/validateCoupon'); - -module.exports = async (req, res, next) => { - const { code, orderAmount } = req.body; - try { - const coupon = await Coupon.findOne({ code }); - if (!coupon) { - return res.status(404).json({ error: 'Coupon not found' }); - } - - const isValid = await validateCoupon(coupon, orderAmount); - if (!isValid) { - return res.status(400).json({ error: 'Coupon is invalid' }); - } - - req.coupon = coupon; // Attach coupon to the request object for use in further steps - next(); - } catch (err) { - res.status(500).json({ error: 'Error validating coupon' }); - } -}; diff --git a/backend/middleware/sub-ware/validatePaymentInvoice.js b/backend/middleware/sub-ware/validatePaymentInvoice.js deleted file mode 100644 index e208773e..00000000 --- a/backend/middleware/sub-ware/validatePaymentInvoice.js +++ /dev/null @@ -1,25 +0,0 @@ -const validatePaymentData = (req, res, next) => { - const { orderId, userId, amount, paymentMethod, transactionId } = req.body; - - if (!orderId || !userId || !amount || !paymentMethod || !transactionId) { - return res - .status(400) - .json({ message: "All fields are required for payment" }); - } - - next(); -}; - -const validateInvoiceData = (req, res, next) => { - const { orderId, userId, amount, dueDate, paymentId } = req.body; - - if (!orderId || !userId || !amount || !dueDate || !paymentId) { - return res - .status(400) - .json({ message: "All fields are required for invoice" }); - } - - next(); -}; - -module.exports = { validatePaymentData, validateInvoiceData }; diff --git a/backend/middleware/sub-ware/validationMiddleware.js b/backend/middleware/sub-ware/validationMiddleware.js deleted file mode 100644 index c569037d..00000000 --- a/backend/middleware/sub-ware/validationMiddleware.js +++ /dev/null @@ -1,28 +0,0 @@ -const Joi = require('joi'); - -// Validation schema for supplier data -const supplierValidationSchema = Joi.object({ - name: Joi.string().required(), - contactInfo: Joi.object({ - email: Joi.string().email().required(), - phone: Joi.string().required(), - }).required(), - address: Joi.object({ - street: Joi.string().required(), - city: Joi.string().required(), - state: Joi.string().required(), - postalCode: Joi.string().required(), - }).required(), - productsSupplied: Joi.array().items(Joi.string()).required(), - status: Joi.string().valid('active', 'inactive').default('active'), -}); - -const validateSupplierData = (req, res, next) => { - const { error } = supplierValidationSchema.validate(req.body); - if (error) { - return res.status(400).json({ message: 'Validation Error', details: error.details }); - } - next(); -}; - -module.exports = validateSupplierData; diff --git a/backend/middleware/sub-ware/warehouseMiddleware.js b/backend/middleware/sub-ware/warehouseMiddleware.js deleted file mode 100644 index 6d79ded9..00000000 --- a/backend/middleware/sub-ware/warehouseMiddleware.js +++ /dev/null @@ -1,67 +0,0 @@ -const Warehouse = require("../models/Warehouse"); - -// Middleware to check if warehouse exists by ID -const checkWarehouseExists = async (req, res, next) => { - const { warehouseId } = req.params; - const warehouse = await Warehouse.findOne({ warehouseId }); - if (!warehouse) { - return res.status(404).json({ message: "Warehouse not found" }); - } - req.warehouse = warehouse; - next(); -}; - -// Middleware to validate warehouse fields during updates -const validateWarehouseFields = (req, res, next) => { - const { capacity, currentOccupancy, address } = req.body; - - // Validate capacity - if (capacity <= 0) { - return res - .status(400) - .json({ message: "Capacity must be a positive number" }); - } - - // Validate that currentOccupancy does not exceed capacity - if (currentOccupancy > capacity) { - return res - .status(400) - .json({ message: "Current Occupancy cannot exceed Warehouse Capacity" }); - } - - // Validate address fields - if ( - !address || - !address.street || - !address.city || - !address.state || - !address.zip || - !address.country - ) { - return res.status(400).json({ message: "Address fields must be complete" }); - } - - next(); -}; - -// Middleware to validate unique warehouse ID or name -const validateUniqueWarehouse = async (req, res, next) => { - const { warehouseId, warehouseName } = req.body; - - const existingWarehouse = await Warehouse.findOne({ - $or: [{ warehouseId }, { warehouseName }], - }); - if (existingWarehouse) { - return res - .status(400) - .json({ message: "Warehouse ID or Name must be unique" }); - } - - next(); -}; - -module.exports = { - checkWarehouseExists, - validateWarehouseFields, - validateUniqueWarehouse, -}; diff --git a/backend/model/shop/sub-model/Agent.js b/backend/model/shop/sub-model/Agent.js deleted file mode 100644 index 5c525382..00000000 --- a/backend/model/shop/sub-model/Agent.js +++ /dev/null @@ -1,39 +0,0 @@ -const mongoose = require("mongoose"); - -const agentSchema = new mongoose.Schema({ - name: { - type: String, - required: true, - }, - email: { - type: String, - required: true, - unique: true, - validate: { - validator: (v) => /@/.test(v), // simple email validation - message: (props) => `${props.value} is not a valid email!`, - }, - }, - assigned_tickets: [ - { - type: mongoose.Schema.Types.ObjectId, - ref: "Ticket", - }, - ], - status: { - type: String, - enum: ["active", "inactive"], - default: "active", - }, - role: { - type: String, - enum: ["admin", "support"], - default: "support", - }, - created_at: { - type: Date, - default: Date.now, - }, -}); - -module.exports = mongoose.model("Agent", agentSchema); diff --git a/backend/model/shop/sub-model/DeliveryPerson.js b/backend/model/shop/sub-model/DeliveryPerson.js deleted file mode 100644 index 03d9afe3..00000000 --- a/backend/model/shop/sub-model/DeliveryPerson.js +++ /dev/null @@ -1,44 +0,0 @@ -// models/DeliveryPerson.js -const mongoose = require("mongoose"); - -const deliveryPersonSchema = new mongoose.Schema({ - name: { - type: String, - required: true, - }, - email: { - type: String, - required: true, - unique: true, - }, - phone_number: { - type: String, - required: true, - }, - status: { - type: String, - enum: ["active", "inactive"], - required: true, - }, - assigned_routes: [{ type: mongoose.Schema.Types.ObjectId, ref: "Route" }], - vehicle_details: { - vehicle_type: { type: String }, - vehicle_number: { type: String }, - }, - created_at: { - type: Date, - default: Date.now, - }, - updated_at: { - type: Date, - default: Date.now, - }, - password: { - type: String -}, - profile_picture: { - type: String - }, -}); - -module.exports = mongoose.model("DeliveryPerson", deliveryPersonSchema); diff --git a/backend/model/shop/sub-model/GiftCard.js b/backend/model/shop/sub-model/GiftCard.js deleted file mode 100644 index e0c713bb..00000000 --- a/backend/model/shop/sub-model/GiftCard.js +++ /dev/null @@ -1,37 +0,0 @@ - -const mongoose = require('mongoose'); - -const giftCardSchema = new mongoose.Schema({ - cardNumber: { - type: String, - required: true, - unique: true, - }, - value: { - type: Number, - required: true, - min: 0.01, - }, - status: { - type: String, - enum: ['active', 'redeemed', 'expired'], - default: 'active', - }, - userId: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true, - }, - expiryDate: { - type: Date, - required: true, - }, - createdAt: { - type: Date, - default: Date.now, - }, -}); - -const GiftCard = mongoose.model('GiftCard', giftCardSchema); - -module.exports = GiftCard; diff --git a/backend/model/shop/sub-model/InventoryModel.js b/backend/model/shop/sub-model/InventoryModel.js deleted file mode 100644 index 734e6c13..00000000 --- a/backend/model/shop/sub-model/InventoryModel.js +++ /dev/null @@ -1,57 +0,0 @@ -const mongoose = require('mongoose'); - -const inventorySchema = new mongoose.Schema({ - productId: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Product', // Reference to the Product collection - required: true - }, - currentStockLevel: { - type: Number, - required: true, - min: 0 // Stock can't be negative - }, - reorderLevel: { - type: Number, - required: true, - min: 0 // Threshold can't be negative - }, - lastRestockedDate: { - type: Date, - default: Date.now - }, - supplierId: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Supplier', // Optional link to Supplier schema - }, - warehouseLocation: { - type: String, - required: true // Warehouse location field - }, - reorderNotificationSent: { - type: Boolean, - default: false // Indicates if a reorder alert has been triggered - }, - auditLog: [{ - action: String, // Describes the action (e.g., "Stock Update", "Reorder Triggered") - actionDate: { - type: Date, - default: Date.now - }, - performedBy: String, // User who performed the action - quantityChanged: Number, // Amount of stock changed - notes: String // Additional details about the action - }], - lastCheckedDate: { - type: Date, - default: Date.now // Timestamp for the last reorder level check - } -}); - -// Virtual to get the last audit entry -inventorySchema.virtual('latestAuditEntry').get(function () { - return this.auditLog.length > 0 ? this.auditLog[this.auditLog.length - 1] : null; -}); - -const Inventory = mongoose.model('Inventory', inventorySchema); -module.exports = Inventory; diff --git a/backend/model/shop/sub-model/OrderHistory.js b/backend/model/shop/sub-model/OrderHistory.js deleted file mode 100644 index dffbfab0..00000000 --- a/backend/model/shop/sub-model/OrderHistory.js +++ /dev/null @@ -1,43 +0,0 @@ -const mongoose = require("mongoose"); - - -const OrderHistorySchema = new mongoose.Schema( - { - userId: { - type: mongoose.Schema.Types.ObjectId, - ref: "User", - required: true, - }, - orderDate: { type: Date, default: Date.now }, - orderStatus: { - type: String, - enum: ["Pending", "Shipped", "Delivered"], - default: "Pending", - }, - totalAmount: { type: Number, required: true }, - shippingAddress: { type: String, required: true }, - paymentStatus: { - type: String, - enum: ["Paid", "Pending"], - default: "Pending", - }, - items: [ - { - productId: { - type: mongoose.Schema.Types.ObjectId, - ref: "Product", - required: true, - }, - quantity: { type: Number, required: true }, - pricePerUnit: { type: Number, required: true }, - }, - ], - trackingNumber: { type: String, optional: true }, - }, - { timestamps: true } -); - -const OrderHistory = mongoose.model("OrderHistory", OrderHistorySchema); - -module.exports = OrderHistory; - diff --git a/backend/model/shop/sub-model/OrderTracking.js b/backend/model/shop/sub-model/OrderTracking.js deleted file mode 100644 index 52c5e585..00000000 --- a/backend/model/shop/sub-model/OrderTracking.js +++ /dev/null @@ -1,83 +0,0 @@ -const mongoose = require("mongoose"); - -const Schema = mongoose.Schema; - -const OrderTrackingSchema = new Schema({ - orderId: { - type: Schema.Types.ObjectId, - ref: "OrderHistory", - required: true, - }, - trackingNumber: { - type: String, - required: true, - }, - status: { - type: String, - enum: ["Pending", "Shipped", "Delivered"], - required: true, - }, - carrier: { - type: String, - required: true, - }, - estimatedDelivery: { - type: Date, - }, - updatedAt: { - type: Date, - default: Date.now, - }, -}); - -// Schema Methods - -// Update the status of the order and update the updatedAt timestamp -OrderTrackingSchema.methods.updateStatus = function(newStatus) { - this.status = newStatus; - this.updatedAt = Date.now(); - return this.save(); -}; - -// Check if the order is overdue based on the estimated delivery date -OrderTrackingSchema.methods.isOverdue = function() { - if (this.estimatedDelivery && this.status !== "Delivered") { - const today = new Date(); - return today > this.estimatedDelivery; - } - return false; -}; - -// Format estimated delivery date in a user-friendly format (e.g., MM/DD/YYYY) -OrderTrackingSchema.methods.formatEstimatedDelivery = function() { - if (!this.estimatedDelivery) return "N/A"; - const options = { year: 'numeric', month: 'short', day: 'numeric' }; - return this.estimatedDelivery.toLocaleDateString(undefined, options); -}; - -// Schema Statics - -// Find orders by status -OrderTrackingSchema.statics.findByStatus = function(status) { - return this.find({ status }); -}; - -// Find all overdue orders -OrderTrackingSchema.statics.findOverdueOrders = function() { - const today = new Date(); - return this.find({ - estimatedDelivery: { $lt: today }, - status: { $ne: "Delivered" }, - }); -}; - -// Bulk update status for multiple orders by order IDs -OrderTrackingSchema.statics.bulkUpdateStatus = function(orderIds, newStatus) { - return this.updateMany( - { orderId: { $in: orderIds } }, - { status: newStatus, updatedAt: Date.now() } - ); -}; - -// Export the model -module.exports = mongoose.model("OrderTracking", OrderTrackingSchema); diff --git a/backend/model/shop/sub-model/Referral.js b/backend/model/shop/sub-model/Referral.js deleted file mode 100644 index 3f05b8ea..00000000 --- a/backend/model/shop/sub-model/Referral.js +++ /dev/null @@ -1,32 +0,0 @@ - -const mongoose = require("mongoose"); -const { Schema } = mongoose; - -const referralSchema = new Schema({ - referrerId: { - type: Schema.Types.ObjectId, - ref: "User", - required: true, - }, - refereeId: { - type: Schema.Types.ObjectId, - ref: "User", - required: false, - }, - referralCode: { - type: String, - required: true, - unique: true, - }, - status: { - type: String, - enum: ["pending", "completed"], - default: "pending", - }, - timestamp: { - type: Date, - default: Date.now, - }, -}); - -module.exports = mongoose.model("Referral", referralSchema); diff --git a/backend/model/shop/sub-model/ReturnProduct.js b/backend/model/shop/sub-model/ReturnProduct.js deleted file mode 100644 index 9a5b7023..00000000 --- a/backend/model/shop/sub-model/ReturnProduct.js +++ /dev/null @@ -1,42 +0,0 @@ - -const mongoose = require('mongoose'); - -const returnProductSchema = new mongoose.Schema( - { - productId: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Product', - required: true - }, - userId: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true - }, - returnDate: { - type: Date, - required: true - }, - condition: { - type: String, - enum: ['good', 'damaged'], - required: true - }, - status: { - type: String, - enum: ['pending', 'returned', 'approved', 'rejected'], - default: 'pending' - }, - createdAt: { - type: Date, - default: Date.now - }, - updatedAt: { - type: Date, - default: Date.now - } - }, - { timestamps: true } -); - -module.exports = mongoose.model('ReturnProduct', returnProductSchema); diff --git a/backend/model/shop/sub-model/ShippingAddress.js b/backend/model/shop/sub-model/ShippingAddress.js deleted file mode 100644 index 9cdf9858..00000000 --- a/backend/model/shop/sub-model/ShippingAddress.js +++ /dev/null @@ -1,37 +0,0 @@ - -const mongoose = require('mongoose'); -const Schema = mongoose.Schema; - -const ShippingAddressSchema = new Schema({ - addressLine1: { - type: String, - required: true - }, - addressLine2: { - type: String, - required: false - }, - city: { - type: String, - required: true - }, - state: { - type: String, - required: true - }, - postalCode: { - type: String, - required: true - }, - country: { - type: String, - required: true - }, - user: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', // assuming a 'User' model exists for users - required: true - } -}, { timestamps: true }); - -module.exports = mongoose.model('ShippingAddress', ShippingAddressSchema); diff --git a/backend/model/shop/sub-model/Supplier.js b/backend/model/shop/sub-model/Supplier.js deleted file mode 100644 index 7d466d78..00000000 --- a/backend/model/shop/sub-model/Supplier.js +++ /dev/null @@ -1,58 +0,0 @@ -const mongoose = require("mongoose"); - -const supplierSchema = new mongoose.Schema( - { - name: { - type: String, - required: true, - }, - contactInfo: { - email: { - type: String, - required: true, - unique: true, - }, - phone: { - type: String, - required: true, - }, - }, - address: { - street: { - type: String, - required: true, - }, - city: { - type: String, - required: true, - }, - state: { - type: String, - required: true, - }, - postalCode: { - type: String, - required: true, - }, - }, - productsSupplied: [ - { type: mongoose.Schema.Types.ObjectId, ref: "Product" }, - ], - status: { - type: String, - required: true, - default: "active", - }, - createdAt: { - type: Date, - default: Date.now, - }, - updatedAt: { - type: Date, - default: Date.now, - }, - }, - { timestamps: true } -); - -module.exports = mongoose.model("Supplier", supplierSchema); diff --git a/backend/model/shop/sub-model/TIcket.js b/backend/model/shop/sub-model/TIcket.js deleted file mode 100644 index 53af2a83..00000000 --- a/backend/model/shop/sub-model/TIcket.js +++ /dev/null @@ -1,46 +0,0 @@ -const mongoose = require("mongoose"); - -const ticketSchema = new mongoose.Schema({ - ticketId: { - type: String, - required: true, - unique: true, - }, - userId: { - type: mongoose.Schema.Types.ObjectId, - ref: "User", - required: true, - }, - subject: { - type: String, - required: true, - }, - description: { - type: String, - required: true, - }, - status: { - type: String, - enum: ["open", "in-progress", "resolved"], - default: "open", - }, - priority: { - type: String, - enum: ["low", "medium", "high"], - default: "medium", - }, - assignedAgentId: { - type: mongoose.Schema.Types.ObjectId, - ref: "Agent", - }, - createdAt: { - type: Date, - default: Date.now, - }, - updatedAt: { - type: Date, - default: Date.now, - }, -}); - -module.exports = mongoose.model("Ticket", ticketSchema); diff --git a/backend/model/shop/sub-model/Warehouse.js b/backend/model/shop/sub-model/Warehouse.js deleted file mode 100644 index e691f85a..00000000 --- a/backend/model/shop/sub-model/Warehouse.js +++ /dev/null @@ -1,63 +0,0 @@ -const mongoose = require("mongoose"); - -const warehouseSchema = new mongoose.Schema({ - warehouseId: { - type: String, - unique: true, - required: true - }, - warehouseName: { - type: String, - unique: true, - required: true }, - address: { - street: { - type: String, - required: true - }, - city: { - type: String - , required: true - }, - state: { - type: String, - required: true - }, - zip: { - type: String, - required: true - }, - country: { - type: String, - required: true - }, - }, - capacity: { - type: Number, - required: true - }, - currentOccupancy: { - type: Number, - default: 0 - }, - inventoryItems: [ - { - type: mongoose.Schema.Types.ObjectId, - ref: "InventoryItem" -}, - ], - contactInfo: { - phone: { - type: String - }, - email: { - type: String - }, - }, - lastUpdated: { - type: Date, - default: Date.now - }, -}); - -module.exports = mongoose.model("Warehouse", warehouseSchema); diff --git a/backend/model/shop/sub-model/couponModel.js b/backend/model/shop/sub-model/couponModel.js deleted file mode 100644 index e873895f..00000000 --- a/backend/model/shop/sub-model/couponModel.js +++ /dev/null @@ -1,61 +0,0 @@ -const mongoose = require("mongoose"); - -const couponSchema = new mongoose.Schema({ - code: { - type: String, - unique: true, - required: true - }, - description: { - type: String, - required: true - }, - discountType: { - type: String, - enum: ["percentage", "fixed"], - required: true - }, - discountValue: { - type: Number, - required: true - }, - minOrderAmount: { - type: Number, - default: 0 - }, - maxDiscount: { - type: Number, - default: 0 - }, - startDate: { - type: Date, - required: true - }, - endDate: { - type: Date, - required: true - }, - status: { - type: String, - enum: ["active", "inactive"], - default: "active" - }, - usageLimit: { - type: Number, - required: true - }, - usageCount: { - type: Number, - default: 0 - }, - createdAt: { - type: Date, - default: Date.now - }, - updatedAt: { - type: Date, - default: Date.now - } -}); - -module.exports = mongoose.model("Coupon", couponSchema); diff --git a/backend/model/shop/sub-model/damagemodal.js b/backend/model/shop/sub-model/damagemodal.js deleted file mode 100644 index 815e8e56..00000000 --- a/backend/model/shop/sub-model/damagemodal.js +++ /dev/null @@ -1,27 +0,0 @@ -const mongoose = require('mongoose'); - -const malfunctioningProductSchema = new mongoose.Schema({ - productId: { type: mongoose.Schema.Types.ObjectId, ref: 'Product', required: true }, - description: { type: String, required: true }, - status: { type: String, enum: ['pending', 'in progress', 'resolved'], default: 'pending' }, - reportedDate: { type: Date, default: Date.now }, - resolvedDate: { type: Date }, - actionsTaken: { type: String }, - createdBy: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true } -}); - -module.exports = mongoose.model('MalfunctioningProduct', malfunctioningProductSchema); - - - -const damagedProductSchema = new mongoose.Schema({ - productId: { type: mongoose.Schema.Types.ObjectId, ref: 'Product', required: true }, - damageType: { type: String, enum: ['crack', 'scratches', 'water damage', 'other'], required: true }, - damageDescription: { type: String, required: true }, - damageSeverity: { type: String, enum: ['minor', 'moderate', 'severe'], required: true }, - reportedDate: { type: Date, default: Date.now }, - status: { type: String, enum: ['reported', 'under review', 'resolved'], default: 'reported' }, - createdBy: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true } -}); - -module.exports = mongoose.model('DamagedProduct', damagedProductSchema); diff --git a/backend/model/shop/sub-model/invoice.js b/backend/model/shop/sub-model/invoice.js deleted file mode 100644 index 5ea2f010..00000000 --- a/backend/model/shop/sub-model/invoice.js +++ /dev/null @@ -1,47 +0,0 @@ -const mongoose = require("mongoose"); - - -const invoiceSchema = new mongoose.Schema( - { - invoiceId: { type: String, required: true, unique: true }, - orderId: { - type: mongoose.Schema.Types.ObjectId, - ref: "Order", - required: true, - }, - userId: { - type: mongoose.Schema.Types.ObjectId, - ref: "User", - required: true, - index: true, // Adds index for faster query on user invoices - }, - amount: { type: Number, required: true, min: 0 }, - invoiceDate: { type: Date, default: Date.now }, - dueDate: { - type: Date, - required: true, - default: function () { - return new Date(+new Date() + 7 * 24 * 60 * 60 * 1000); // Default due date is 7 days from invoice date - }, - }, - status: { - type: String, - enum: ["Paid", "Unpaid", "Overdue", "Cancelled"], - default: "Unpaid", - }, - paymentId: { - type: mongoose.Schema.Types.ObjectId, - ref: "Payment", - sparse: true, // Allows null value indexing for unpaid invoices - }, - }, - { timestamps: true } -); - -// Virtual field to check if invoice is overdue -invoiceSchema.virtual("isOverdue").get(function () { - return this.status === "Unpaid" && this.dueDate < new Date(); -}); - -const Invoice = mongoose.model("Invoice", invoiceSchema); -module.exports = Invoice; diff --git a/backend/model/shop/sub-model/loyaltyPointModel.js b/backend/model/shop/sub-model/loyaltyPointModel.js deleted file mode 100644 index 44cfec6e..00000000 --- a/backend/model/shop/sub-model/loyaltyPointModel.js +++ /dev/null @@ -1,25 +0,0 @@ -const mongoose = require("mongoose"); - -const loyaltyPointSchema = new mongoose.Schema({ - userId: { - type: mongoose.Schema.Types.ObjectId, - required: true, - ref: "User", - }, - points: { - type: Number, - required: true, - default: 0, - }, - earnedBy: { - type: String, - enum: ["purchase", "referral"], - required: true, - }, - timestamp: { - type: Date, - default: Date.now, - }, -}); - -module.exports = mongoose.model("LoyaltyPoint", loyaltyPointSchema); diff --git a/backend/model/shop/sub-model/payment.js b/backend/model/shop/sub-model/payment.js deleted file mode 100644 index 44182dd7..00000000 --- a/backend/model/shop/sub-model/payment.js +++ /dev/null @@ -1,34 +0,0 @@ -const mongoose = require("mongoose"); - -const paymentSchema = new mongoose.Schema( - { - paymentId: { type: String, required: true, unique: true }, - orderId: { - type: mongoose.Schema.Types.ObjectId, - ref: "Order", - required: true, - }, - userId: { - type: mongoose.Schema.Types.ObjectId, - ref: "User", - required: true, - }, - amount: { type: Number, required: true }, - paymentMethod: { - type: String, - enum: ["Credit Card", "PayPal", "Bank Transfer"], - required: true, - }, - paymentStatus: { - type: String, - default: "Pending", - enum: ["Pending", "Completed", "Failed"], - }, - paymentDate: { type: Date, default: Date.now }, - transactionId: { type: String, required: true }, - }, - { timestamps: true } -); - -const Payment = mongoose.model("Payment", paymentSchema); -module.exports = Payment; diff --git a/backend/model/shop/sub-model/productanalysis.jsx b/backend/model/shop/sub-model/productanalysis.jsx deleted file mode 100644 index a106cec4..00000000 --- a/backend/model/shop/sub-model/productanalysis.jsx +++ /dev/null @@ -1,29 +0,0 @@ -const mongoose = require('mongoose'); - -const productAnalysisSchema = new mongoose.Schema({ - productId: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Product', - required: true, - }, - views: { - type: Number, - default: 0, - }, - sales: { - type: Number, - default: 0, - }, - ratings: { - type: Number, - default: 0, - }, - feedback: { - type: [String], - default: [], - }, -}); - -const ProductAnalysis = mongoose.model('ProductAnalysis', productAnalysisSchema); - -module.exports = ProductAnalysis; diff --git a/backend/model/shop/sub-model/useranalysis.js b/backend/model/shop/sub-model/useranalysis.js deleted file mode 100644 index a9779a7e..00000000 --- a/backend/model/shop/sub-model/useranalysis.js +++ /dev/null @@ -1,25 +0,0 @@ -const mongoose = require('mongoose'); - -const userAnalysisSchema = new mongoose.Schema({ - userId: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true, - }, - activityLog: { - type: [String], - default: [], - }, - interactions: { - type: Number, - default: 0, - }, - preferences: { - type: Object, - default: {}, - }, -}); - -const UserAnalysis = mongoose.model('UserAnalysis', userAnalysisSchema); - -module.exports = UserAnalysis; diff --git a/backend/model/shop/sub-model/useranalysiscontroller.js b/backend/model/shop/sub-model/useranalysiscontroller.js deleted file mode 100644 index 620ead7b..00000000 --- a/backend/model/shop/sub-model/useranalysiscontroller.js +++ /dev/null @@ -1,172 +0,0 @@ -const UserAnalysis = require("../models/UserAnalysis"); -const mongoose = require("mongoose"); - -// Utility function to validate ObjectId -const isValidObjectId = (id) => mongoose.Types.ObjectId.isValid(id); - -// Create User Analysis -exports.createUserAnalysis = async (req, res) => { - try { - const { userId, activityLog, interactions, preferences } = req.body; - - // Input validation - if ( - !userId || - !activityLog || - !Array.isArray(activityLog) || - !interactions || - !preferences - ) { - return res - .status(400) - .json({ - message: - "Missing required fields: userId, activityLog, interactions, preferences", - }); - } - - // Check if the userId is valid - if (!isValidObjectId(userId)) { - return res.status(400).json({ message: "Invalid userId format" }); - } - - // Create new UserAnalysis record - const userAnalysis = new UserAnalysis({ - userId, - activityLog, - interactions, - preferences, - }); - await userAnalysis.save(); - res.status(201).json(userAnalysis); - } catch (error) { - console.error(error); // For debugging purposes - if (error.code === 11000) { - return res - .status(409) - .json({ message: "Duplicate entry detected for user analysis" }); - } - res - .status(500) - .json({ message: "Error creating user analysis data", error }); - } -}; - -// Get User Analysis by ID -exports.getUserAnalysis = async (req, res) => { - try { - const { id } = req.params; - - // Check if the id is a valid ObjectId - if (!isValidObjectId(id)) { - return res - .status(400) - .json({ message: "Invalid UserAnalysis ID format" }); - } - - const userAnalysis = await UserAnalysis.findById(id); - - if (!userAnalysis) { - return res.status(404).json({ message: "User analysis not found" }); - } - - res.status(200).json(userAnalysis); - } catch (error) { - console.error(error); // For debugging purposes - res - .status(500) - .json({ message: "Error retrieving user analysis data", error }); - } -}; - -// Update User Analysis by ID -exports.updateUserAnalysis = async (req, res) => { - try { - const { id } = req.params; - const updatedData = req.body; - - // Check if the id is a valid ObjectId - if (!isValidObjectId(id)) { - return res - .status(400) - .json({ message: "Invalid UserAnalysis ID format" }); - } - - // Input validation: Ensure there is at least one field to update - if (!updatedData || Object.keys(updatedData).length === 0) { - return res.status(400).json({ message: "No data provided to update" }); - } - - // Check for fields that shouldn't be updated or are invalid - if (updatedData.userId && !isValidObjectId(updatedData.userId)) { - return res.status(400).json({ message: "Invalid userId format" }); - } - - const userAnalysis = await UserAnalysis.findByIdAndUpdate(id, updatedData, { - new: true, - }); - - if (!userAnalysis) { - return res.status(404).json({ message: "User analysis not found" }); - } - - res.status(200).json(userAnalysis); - } catch (error) { - console.error(error); // For debugging purposes - if (error.code === 11000) { - return res - .status(409) - .json({ message: "Duplicate entry detected during update" }); - } - res - .status(500) - .json({ message: "Error updating user analysis data", error }); - } -}; - -// Delete User Analysis by ID (Optional - In case we want to support deleting analysis data) -exports.deleteUserAnalysis = async (req, res) => { - try { - const { id } = req.params; - - // Check if the id is a valid ObjectId - if (!isValidObjectId(id)) { - return res - .status(400) - .json({ message: "Invalid UserAnalysis ID format" }); - } - - const userAnalysis = await UserAnalysis.findByIdAndDelete(id); - - if (!userAnalysis) { - return res.status(404).json({ message: "User analysis not found" }); - } - - res.status(200).json({ message: "User analysis deleted successfully" }); - } catch (error) { - console.error(error); // For debugging purposes - res - .status(500) - .json({ message: "Error deleting user analysis data", error }); - } -}; - -// Get all User Analysis records (Optional - If we want to list all data) -exports.getAllUserAnalysis = async (req, res) => { - try { - const userAnalysis = await UserAnalysis.find(); - - if (userAnalysis.length === 0) { - return res - .status(404) - .json({ message: "No user analysis data available" }); - } - - res.status(200).json(userAnalysis); - } catch (error) { - console.error(error); // For debugging purposes - res - .status(500) - .json({ message: "Error retrieving all user analysis data", error }); - } -}; diff --git a/backend/routes/sub-routes/agentRoutes.js b/backend/routes/sub-routes/agentRoutes.js deleted file mode 100644 index 28067322..00000000 --- a/backend/routes/sub-routes/agentRoutes.js +++ /dev/null @@ -1,39 +0,0 @@ -const express = require('express'); -const router = express.Router(); -const agentController = require('../../controllers/shop/sub-controllers/agentController'); -const { checkAgentRole } = require('../../middleware/sub-ware/agentMiddleware'); - -// Routes for Agent management - -// Get all agents -router.get('/agents', agentController.getAllAgents); - -// Create a new agent -router.post('/agents', agentController.createAgent); - -// Get agent by ID -router.get('/agents/:id', agentController.getAgentById); - -// Update agent details by ID -router.put('/agents/:id', agentController.updateAgent); - -// Delete agent by ID -router.delete('/agents/:id', agentController.deleteAgent); - -// Assign a ticket to an agent -router.patch('/agents/:id/assign-ticket', agentController.assignTicketToAgent); - -// Unassign a ticket from an agent -router.patch('/agents/:id/unassign-ticket', agentController.unassignTicketFromAgent); - -// Change the status of an agent (active/inactive) -router.patch('/agents/:id/status', agentController.changeAgentStatus); - -// Assign multiple tickets to an agent -router.patch('/agents/:id/assign-multiple-tickets', agentController.assignMultipleTickets); - -// Role-based access check for certain admin actions -router.use('/agents/:id', checkAgentRole); - -// Export the router -module.exports = router; diff --git a/backend/routes/sub-routes/couponRoutes.js b/backend/routes/sub-routes/couponRoutes.js deleted file mode 100644 index 1c62e3b0..00000000 --- a/backend/routes/sub-routes/couponRoutes.js +++ /dev/null @@ -1,34 +0,0 @@ -const express = require('express'); -const router = express.Router(); -const couponController = require('../../controllers/shop/sub-controllers/couponController'); - -// Route to create a new coupon -router.post('/create', couponController.createCoupon); - -// Route to fetch all coupons -router.get('/', couponController.getCoupons); - -// Route to get a specific coupon by its code -router.get('/:code', couponController.getCouponByCode); - -// Route to update a coupon -router.put('/:code', couponController.updateCoupon); - -// Route to delete a coupon -router.delete('/:code', couponController.deleteCoupon); - -// Route to validate a coupon before applying to an order -router.post('/validate', couponController.validateCoupon, (req, res) => { - res.status(200).json({ message: 'Coupon is valid', coupon: req.coupon }); -}); - -// Route to track coupon usage -router.post('/usage', couponController.incrementUsageCount); - -// Route to activate or deactivate a coupon -router.put('/:code/status', couponController.toggleCouponStatus); - -// Route to apply coupon to an order -router.post('/apply', couponController.applyCouponToOrder); - -module.exports = router; diff --git a/backend/routes/sub-routes/giftCardRoutes.js b/backend/routes/sub-routes/giftCardRoutes.js deleted file mode 100644 index 817e403f..00000000 --- a/backend/routes/sub-routes/giftCardRoutes.js +++ /dev/null @@ -1,38 +0,0 @@ - -const express = require('express'); -const router = express.Router(); - -// Import the GiftCard Controller -const GiftCardController = require('../../controllers/shop/sub-controllers/giftCardController'); - -// Middleware to validate gift cards (to check status, expiry, etc.) -const validateGiftCard = require('../../middleware/sub-ware/giftCardMiddleware'); - -// Route to create a new gift card -router.post('/api/gift-cards', GiftCardController.createGiftCard); - -// Route to get details of a specific gift card by card number -router.get('/api/gift-cards/:cardNumber', GiftCardController.getGiftCardDetails); - -// Route to redeem a gift card by card number -router.post('/api/gift-cards/redeem', validateGiftCard, GiftCardController.redeemGiftCard); - -// Route to fetch all gift cards for a user (e.g., list of user's gift cards) -router.get('/api/gift-cards/user/:userId', GiftCardController.getUserGiftCards); - -// Route to search gift cards within a specific value range -router.get('/api/gift-cards/search', GiftCardController.searchGiftCardsByValue); - -// Route to delete a gift card (forceful deletion) -router.delete('/api/gift-cards/:cardNumber', GiftCardController.deleteGiftCard); - -// Route to deactivate (expire) a gift card before redemption -router.patch('/api/gift-cards/deactivate/:cardNumber', GiftCardController.deactivateGiftCard); - -// Route to fetch all gift cards (Admin-only route) -router.get('/api/gift-cards', GiftCardController.getAllGiftCards); - -// Route to get statistics on redeemed gift cards -router.get('/api/gift-cards/stats', GiftCardController.getGiftCardStats); - -module.exports = router; diff --git a/backend/routes/sub-routes/invoiceRoutes.js b/backend/routes/sub-routes/invoiceRoutes.js deleted file mode 100644 index a6f30c3d..00000000 --- a/backend/routes/sub-routes/invoiceRoutes.js +++ /dev/null @@ -1,39 +0,0 @@ -const express = require("express"); -const router = express.Router(); - -const { - generateInvoice, - getInvoices, - getInvoiceById, - updateInvoiceStatus, - deleteInvoice, - markOverdueInvoices, - invoiceSummary, - generateBulkInvoices, -} = require("../controllers/invoiceController"); - -// Route to generate a new invoice after payment confirmation -router.post("/generate", generateInvoice); - -// Route to retrieve invoices by user, order, status, or date range with pagination and sorting -router.get("/", getInvoices); - -// Route to retrieve a specific invoice by its ID -router.get("/:id", getInvoiceById); - -// Route to update an invoice's status -router.patch("/:id/status", updateInvoiceStatus); - -// Route to delete an invoice by its ID -router.delete("/:id", deleteInvoice); - -// Route to mark overdue invoices (based on the current date) -router.patch("/mark-overdue", markOverdueInvoices); - -// Route to get an invoice summary (by status, optionally by user) -router.get("/summary", invoiceSummary); - -// Route to generate bulk invoices at once -router.post("/generate-bulk", generateBulkInvoices); - -module.exports = router; diff --git a/backend/routes/sub-routes/loyaltyPointsRoutes.js b/backend/routes/sub-routes/loyaltyPointsRoutes.js deleted file mode 100644 index f8dd54fd..00000000 --- a/backend/routes/sub-routes/loyaltyPointsRoutes.js +++ /dev/null @@ -1,77 +0,0 @@ -const express = require("express"); -const loyaltyPointsController = require("../../controllers/shop/sub-controllers/loyaltyPointsController"); -const authMiddleware = require("../middleware/authMiddleware"); // Middleware to check valid user - -const router = express.Router(); - -// Route to award points to a user -router.post( - "/api/loyalty-points", - authMiddleware, - loyaltyPointsController.awardPoints -); - -// Route to get a user's total loyalty points -router.get( - "/api/loyalty-points/:userId", - authMiddleware, - loyaltyPointsController.getPoints -); - -// Route to get a user's transaction history of loyalty points -router.get( - "/api/loyalty-points/:userId/history", - authMiddleware, - loyaltyPointsController.getTransactionHistory -); - -// Route to delete a specific loyalty points transaction -router.delete( - "/api/loyalty-points/:transactionId", - authMiddleware, - loyaltyPointsController.deletePoints -); - -// Route to update a specific loyalty points transaction -router.put( - "/api/loyalty-points/:transactionId", - authMiddleware, - loyaltyPointsController.updatePoints -); - -// Route to filter transactions by type (e.g., 'purchase', 'referral') -router.get( - "/api/loyalty-points/:userId/filter", - authMiddleware, - loyaltyPointsController.filterTransactionsByType -); - -// Route to get total points earned through referrals -router.get( - "/api/loyalty-points/:userId/referrals", - authMiddleware, - loyaltyPointsController.getPointsByReferrals -); - -// Route to get total points earned through purchases -router.get( - "/api/loyalty-points/:userId/purchases", - authMiddleware, - loyaltyPointsController.getPointsByPurchases -); - -// Route to redeem points -router.post( - "/api/loyalty-points/redeem", - authMiddleware, - loyaltyPointsController.redeemPoints -); - -// Route to get loyalty points summary (overall points, referral points, and purchase points) -router.get( - "/api/loyalty-points/:userId/summary", - authMiddleware, - loyaltyPointsController.getLoyaltySummary -); - -module.exports = router; diff --git a/backend/routes/sub-routes/paymentRoutes.js b/backend/routes/sub-routes/paymentRoutes.js deleted file mode 100644 index 47c456df..00000000 --- a/backend/routes/sub-routes/paymentRoutes.js +++ /dev/null @@ -1,34 +0,0 @@ -const express = require("express"); -const router = express.Router(); -const { - getAllPayments, - getPaymentById, - getPaymentsByUserId, - getPaymentsByStatus, - createPayment, - updatePaymentStatus, - deletePayment, - updatePaymentMethod, - getPaymentsByDateRange, - getPaymentsByAmountRange, - getPaymentByTransactionId, - countPaymentsByStatus, -} = require("../controllers/paymentController"); - -// Payment routes -router.get("/", getAllPayments); // Retrieve all payments -router.get("/:id", getPaymentById); // Retrieve payment by ID -router.get("/user/:userId", getPaymentsByUserId); // Retrieve payments by User ID -router.get("/status/:status", getPaymentsByStatus); // Retrieve payments by Status -router.post("/", createPayment); // Create a new payment -router.patch("/:id/status", updatePaymentStatus); // Update payment status -router.patch("/:id/method", updatePaymentMethod); // Update payment method -router.delete("/:id", deletePayment); // Delete payment - -// Additional routes for edge cases -router.get("/date-range", getPaymentsByDateRange); // Retrieve payments by date range -router.get("/amount-range", getPaymentsByAmountRange); // Retrieve payments by amount range -router.get("/transaction/:transactionId", getPaymentByTransactionId); // Retrieve payment by transaction ID -router.get("/count/status", countPaymentsByStatus); // Count payments by status - -module.exports = router; diff --git a/backend/routes/sub-routes/referralRoutes.js b/backend/routes/sub-routes/referralRoutes.js deleted file mode 100644 index ea7b5096..00000000 --- a/backend/routes/sub-routes/referralRoutes.js +++ /dev/null @@ -1,35 +0,0 @@ -const express = require("express"); -const router = express.Router(); -const referralController = require("../controllers/referralController"); - -// Route to create a new referral -// Endpoint: POST /api/referrals -router.post("/", - referralController.createReferral); - -// Route to check referral status by code -// Endpoint: GET /api/referrals/status/:code -router.get("/status/:code", - referralController.checkReferralStatus); - -// Route to complete a referral when a referral code is used by a referee -// Endpoint: POST /api/referrals/complete -router.post("/complete", - referralController.completeReferral); - -// Route to get all referrals by a specific referrer, with optional status filter and pagination -// Endpoint: GET /api/referrals/referrer/:referrerId -router.get("/referrer/:referrerId", - referralController.getReferralsByReferrer); - -// Route for admin to list all referrals with pagination and sorting -// Endpoint: GET /api/referrals -router.get("/", - referralController.listAllReferrals); - -// Route to cancel a pending referral by code -// Endpoint: POST /api/referrals/cancel -router.post("/cancel", - referralController.cancelReferral); - -module.exports = router; diff --git a/backend/routes/sub-routes/returnRoutes.js b/backend/routes/sub-routes/returnRoutes.js deleted file mode 100644 index e7a32ccc..00000000 --- a/backend/routes/sub-routes/returnRoutes.js +++ /dev/null @@ -1,33 +0,0 @@ -const express = require('express'); -const router = express.Router(); -const { createReturn, updateReturnStatus, getReturnInformation, getUserReturnHistory, getPendingReturns, cancelReturnRequest, getAllReturnedProducts, getAllDamagedProducts, getReturnRequestsForProduct } = require('../../controllers/shop/sub-controllers/returnController'); -const { authenticateUser, authorizeAdmin } = require('../middleware/auth'); - -// Route to create a return request -router.post('/returns', authenticateUser, createReturn); - -// Route to update return status (Admin only) -router.patch('/returns/:id', authenticateUser, authorizeAdmin, updateReturnStatus); - -// Route to get return information -router.get('/returns/:id', authenticateUser, getReturnInformation); - -// Route to get a user's return history -router.get('/returns/user/:userId', authenticateUser, getUserReturnHistory); - -// Route to get all pending returns (Admin only) -router.get('/returns/pending', authenticateUser, authorizeAdmin, getPendingReturns); - -// Route to cancel return request -router.patch('/returns/cancel/:id', authenticateUser, cancelReturnRequest); - -// Route to get all returned products (Admin only) -router.get('/returns/returned', authenticateUser, authorizeAdmin, getAllReturnedProducts); - -// Route to get all damaged products (Admin only) -router.get('/returns/damaged', authenticateUser, authorizeAdmin, getAllDamagedProducts); - -// Route to get return requests for a specific product (Admin only) -router.get('/returns/product/:productId', authenticateUser, authorizeAdmin, getReturnRequestsForProduct); - -module.exports = router; diff --git a/backend/routes/sub-routes/routesdamage b/backend/routes/sub-routes/routesdamage deleted file mode 100644 index 0b829c77..00000000 --- a/backend/routes/sub-routes/routesdamage +++ /dev/null @@ -1,54 +0,0 @@ -const express = require("express"); -const router = express.Router(); -const MalfunctioningProductController = require("../controllers/MalfunctioningProductController"); -const { - validateMalfunctioningProduct, - validateUpdateMalfunctioningProduct, -} = require("../middlewares/validationMiddleware"); -const authenticate = require("../middlewares/authenticationMiddleware"); - -// Create malfunctioning product -router.post( - "/", - authenticate, - validateMalfunctioningProduct, - MalfunctioningProductController.createMalfunctioningProduct -); - -// Get malfunctioning product by ID -router.get( - "/:id", - authenticate, - MalfunctioningProductController.getMalfunctioningProduct -); - -// Update malfunctioning product -router.put( - "/:id", - authenticate, - validateUpdateMalfunctioningProduct, - MalfunctioningProductController.updateMalfunctioningProduct -); - -// Delete malfunctioning product -router.delete( - "/:id", - authenticate, - MalfunctioningProductController.deleteMalfunctioningProduct -); - -// Get all malfunctioning products (with pagination and search) -router.get( - "/", - authenticate, - MalfunctioningProductController.getAllMalfunctioningProducts -); - -// Get count of malfunctioning products by status -router.get( - "/count/:status", - authenticate, - MalfunctioningProductController.getMalfunctioningProductCountByStatus -); - -module.exports = router; diff --git a/backend/routes/sub-routes/supplierRoutes.js b/backend/routes/sub-routes/supplierRoutes.js deleted file mode 100644 index b0fd6295..00000000 --- a/backend/routes/sub-routes/supplierRoutes.js +++ /dev/null @@ -1,50 +0,0 @@ -const express = require("express"); -const router = express.Router(); -const supplierController = require("../controllers/supplierController"); -const productController = require("../controllers/productController"); -const supplierSearchController = require("../controllers/supplierSearchController"); -const supplierFilterController = require("../controllers/supplierFilterController"); -const validateSupplierData = require("../middlewares/validationMiddleware"); -const isAdmin = require("../middlewares/authMiddleware"); - -// Routes for suppliers -router.post( - "/api/suppliers", - isAdmin, - validateSupplierData, - supplierController.createSupplier -); // Admin only -router.get("/api/suppliers", supplierController.getAllSuppliers); -router.get("/api/suppliers/:id", supplierController.getSupplierById); -router.put( - "/api/suppliers/:id", - isAdmin, - validateSupplierData, - supplierController.updateSupplier -); // Admin only -router.delete("/api/suppliers/:id", isAdmin, supplierController.deleteSupplier); // Admin only - -// Routes for managing products supplied by a supplier -router.post( - "/api/suppliers/:id/products", - isAdmin, - productController.addProductToSupplier -); // Admin only -router.delete( - "/api/suppliers/:id/products", - isAdmin, - productController.removeProductFromSupplier -); // Admin only -router.get( - "/api/suppliers/:id/products", - productController.getProductsSupplied -); - -// Routes for searching and filtering suppliers -router.get("/api/suppliers/search", supplierSearchController.searchSuppliers); -router.get( - "/api/suppliers/status/:status", - supplierFilterController.getSuppliersByStatus -); - -module.exports = router; diff --git a/backend/routes/sub-routes/ticketRoutes.js b/backend/routes/sub-routes/ticketRoutes.js deleted file mode 100644 index b9a244aa..00000000 --- a/backend/routes/sub-routes/ticketRoutes.js +++ /dev/null @@ -1,54 +0,0 @@ -const express = require("express"); -const router = express.Router(); -const { - createTicket, - getTicketDetails, - getUserTickets, - getAssignedTickets, - updateTicketStatus, - assignTicket, - closeTicket, - deleteTicket, - getAllTickets, - updateTicketPriority, - getTicketsByStatus, - getTicketsByPriority, -} = require("../../controllers/shop/sub-controllers/ticketController"); - -// Route to create a new ticket -router.post("/tickets", createTicket); - -// Route to get ticket details by ticketId -router.get("/tickets/:ticketId", getTicketDetails); - -// Route to get all tickets for a user -router.get("/user/:userId/tickets", getUserTickets); - -// Route to get all tickets assigned to an agent -router.get("/agent/:agentId/tickets", getAssignedTickets); - -// Route to update ticket status (open, in-progress, resolved, closed) -router.put("/tickets/:ticketId/status", updateTicketStatus); - -// Route to assign a ticket to a support agent -router.put("/tickets/:ticketId/assign", assignTicket); - -// Route to close a ticket -router.put("/tickets/:ticketId/close", closeTicket); - -// Route to delete a ticket -router.delete("/tickets/:ticketId", deleteTicket); - -// Route to get all tickets (Admin only) -router.get("/tickets", getAllTickets); - -// Route to update ticket priority (low, medium, high) -router.put("/tickets/:ticketId/priority", updateTicketPriority); - -// Route to get tickets by status (open, in-progress, resolved, closed) -router.get("/tickets/status/:status", getTicketsByStatus); - -// Route to get tickets by priority (low, medium, high) -router.get("/tickets/priority/:priority", getTicketsByPriority); - -module.exports = router; diff --git a/backend/services/sub-service/couponValidator.js b/backend/services/sub-service/couponValidator.js deleted file mode 100644 index 0ff1e6a0..00000000 --- a/backend/services/sub-service/couponValidator.js +++ /dev/null @@ -1,23 +0,0 @@ -const validateCoupon = async (coupon, orderAmount) => { - const currentDate = new Date(); - - // Check if coupon is expired - if (currentDate < coupon.startDate || currentDate > coupon.endDate) { - return false; - } - - // Check if minimum order amount is met - if (orderAmount < coupon.minOrderAmount) { - return false; - } - - // Check if coupon usage limit has been exceeded - if (coupon.usageCount >= coupon.usageLimit) { - return false; - } - - return true; - }; - - module.exports = { validateCoupon }; - \ No newline at end of file diff --git a/backend/services/sub-service/giftCardUtils.js b/backend/services/sub-service/giftCardUtils.js deleted file mode 100644 index 3e79cbc2..00000000 --- a/backend/services/sub-service/giftCardUtils.js +++ /dev/null @@ -1,54 +0,0 @@ -// Check if a gift card has expired based on its expiry date -exports.isExpired = (expiryDate) => { - const currentDate = new Date(); - return new Date(expiryDate) < currentDate; -}; - -// Format a gift card's value into a currency string (e.g., $100.00) -exports.formatGiftCardValue = (value) => { - return `$${value.toFixed(2)}`; -}; - -// Validate if the gift card value is positive -exports.isValidGiftCardValue = (value) => { - return value > 0; -}; - -// Helper function to generate a random expiration date (within 1 year) -exports.generateRandomExpiryDate = () => { - const currentDate = new Date(); - const randomMonths = Math.floor(Math.random() * 12) + 1; // Expiry in 1 to 12 months - currentDate.setMonth(currentDate.getMonth() + randomMonths); - return currentDate; -}; - -// Helper function to validate card number format (GC-XXXXXXX) -exports.isValidCardNumber = (cardNumber) => { - const regex = /^GC-[A-Z0-9]{9}$/; - return regex.test(cardNumber); -}; - -// Generate a random status for the card (active, redeemed, expired) -exports.generateRandomStatus = () => { - const statuses = ["active", "redeemed", "expired"]; - return statuses[Math.floor(Math.random() * statuses.length)]; -}; - -// Helper function to generate random user ID (for user association) -exports.generateUserId = () => { - return `USR-${Math.random().toString(36).substr(2, 7).toUpperCase()}`; -}; - -// Check if the gift card can be redeemed (it must be active and not expired) -exports.canRedeem = (giftCard) => { - if (giftCard.status !== "active") { - return false; - } - - return !this.isExpired(giftCard.expiryDate); -}; - -// Utility to get the current date in ISO string format -exports.getCurrentDate = () => { - return new Date().toISOString(); -}; diff --git a/backend/services/sub-service/hashPassword.js b/backend/services/sub-service/hashPassword.js deleted file mode 100644 index 0c0a30a2..00000000 --- a/backend/services/sub-service/hashPassword.js +++ /dev/null @@ -1,9 +0,0 @@ - -const bcrypt = require('bcrypt'); - -const hashPassword = async (password) => { - const salt = await bcrypt.genSalt(10); - return bcrypt.hash(password, salt); -}; - -module.exports = { hashPassword }; diff --git a/backend/services/sub-service/logger.js b/backend/services/sub-service/logger.js deleted file mode 100644 index 12b5d108..00000000 --- a/backend/services/sub-service/logger.js +++ /dev/null @@ -1,10 +0,0 @@ - - -exports.logInfo = (message) => { - console.log(`[INFO] ${message}`); - }; - - exports.logError = (message, error) => { - console.error(`[ERROR] ${message}`, error); - }; - \ No newline at end of file diff --git a/backend/services/sub-service/referralFunc.js b/backend/services/sub-service/referralFunc.js deleted file mode 100644 index d66f1d5c..00000000 --- a/backend/services/sub-service/referralFunc.js +++ /dev/null @@ -1,136 +0,0 @@ -const crypto = require("crypto"); - -// Generate a unique referral code with a specified length -function generateReferralCode(length = 8) { - return crypto - .randomBytes(length) - .toString("hex") - .slice(0, length) - .toUpperCase(); -} - -// Check if the referral code format is valid (alphanumeric and of correct length) -function isReferralCodeValid(code, length = 8) { - const regex = new RegExp(`^[A-Z0-9]{${length}}$`); - return regex.test(code); -} - -// Calculate the expiration date of a referral, adding days from the creation date -function calculateExpiryDate(days = 30) { - const expiryDate = new Date(); - expiryDate.setDate(expiryDate.getDate() + days); - return expiryDate; -} - -// Format date to a readable string format -function formatDate(date) { - return `${date.getFullYear()}-${(date.getMonth() + 1) - .toString() - .padStart(2, "0")}-${date.getDate().toString().padStart(2, "0")}`; -} - -// Utility to log referral creation or status changes -function logReferralAction(referralCode, action, referrerId, refereeId = null) { - console.log(`[${new Date().toISOString()}] Referral Action: ${action}`); - console.log(`Referral Code: ${referralCode}`); - console.log(`Referrer ID: ${referrerId}`); - if (refereeId) console.log(`Referee ID: ${refereeId}`); - console.log("------------------------------"); -} - -// Utility function to check if a referral is expired -function isReferralExpired(referral) { - const currentDate = new Date(); - return currentDate > referral.expiryDate; -} - -// Send notification email to the referrer -async function sendReferralNotificationEmail(email, message) { - try { - // Here, you'd use a real email service like SendGrid, Mailgun, etc. - console.log(`Sending email to ${email} with message: ${message}`); - // Example: await emailService.send({ to: email, subject: 'Referral Update', text: message }); - return true; - } catch (error) { - console.error("Failed to send email:", error); - return false; - } -} - -// Validate referrer and referee IDs -function validateUserIds(referrerId, refereeId) { - if (!referrerId || !refereeId) { - throw new Error("Both referrer and referee IDs must be provided"); - } - if (referrerId === refereeId) { - throw new Error("Referrer and referee cannot be the same person"); - } -} - -// Helper to calculate loyalty points based on a referral action -function calculateLoyaltyPoints(actionType) { - switch (actionType) { - case "purchase": - return 10; - case "referral": - return 20; - case "review": - return 5; - default: - return 0; - } -} - -// Fetch paginated results from a referral list (for admin or reporting) -function getPaginatedResults(referralList, page, limit) { - const startIndex = (page - 1) * limit; - const endIndex = page * limit; - return referralList.slice(startIndex, endIndex); -} - -// Generate a secure hash for sensitive referral data -function hashReferralData(data) { - return crypto.createHash("sha256").update(data).digest("hex"); -} - -// Utility function to update referral status -function updateReferralStatus(referral, status) { - if (!["pending", "completed", "expired", "cancelled"].includes(status)) { - throw new Error("Invalid status value"); - } - referral.status = status; -} - -// Utility function to validate status input -function isValidStatus(status) { - return ["pending", "completed", "expired", "cancelled"].includes(status); -} - -// Utility to handle common referral errors -function handleReferralError(error) { - if (error.message.includes("duplicate")) { - return { message: "Duplicate referral code", status: 400 }; - } else if (error.message.includes("expired")) { - return { message: "Referral code has expired", status: 400 }; - } else { - return { message: "An unexpected error occurred", status: 500 }; - } -} - -// Export all utility functions -module.exports = { - generateReferralCode, - isReferralCodeValid, - calculateExpiryDate, - formatDate, - logReferralAction, - isReferralExpired, - sendReferralNotificationEmail, - validateUserIds, - calculateLoyaltyPoints, - getPaginatedResults, - hashReferralData, - updateReferralStatus, - isValidStatus, - handleReferralError, -}; diff --git a/backend/services/sub-service/referralUtils.js b/backend/services/sub-service/referralUtils.js deleted file mode 100644 index 6f9f37f9..00000000 --- a/backend/services/sub-service/referralUtils.js +++ /dev/null @@ -1,8 +0,0 @@ - -exports.generateUniqueCode = () => { - return Math.random().toString(36).substring(2, 10).toUpperCase(); -}; - -exports.validateReferralCodeFormat = (code) => { - return /^[A-Z0-9]{8}$/.test(code); -}; diff --git a/frontend/src/AgroShopAI/components/Pages/Admin-Dashboard.jsx b/frontend/src/AgroShopAI/components/Pages/Admin-Dashboard.jsx deleted file mode 100644 index b61a8644..00000000 --- a/frontend/src/AgroShopAI/components/Pages/Admin-Dashboard.jsx +++ /dev/null @@ -1,33 +0,0 @@ -import { Sidebar } from "./components/Sidebar"; -import { Header } from "./components/Header"; -import { GrievanceList } from "./components/GrievanceList"; -import { DashboardStats } from "./components/DashboardStats"; -import { useState } from "react"; -import StatisticComponent from "./components/StatisticComponent"; -import ReturnPanel from "./components/ReturnPage"; -import AdminProductManagement from "./ProductManagement"; -import ProfileEdit from "./components/ProfileManage"; -export default function AdminDashboard() { - const [activeView, setActiveView] = useState("dashboard"); // Track active view - - // Function to handle view change from Sidebar - const handleViewChange = (view) => { - setActiveView(view); - }; - - return ( -
- -
-
- {/* Render content based on active view */} - {activeView === "dashboard" && } - {activeView === "grievances" && } - {activeView === "analytics" && } - {activeView === "return" && } - {activeView === "product" && } - {activeView === "settings" && } -
-
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/Admin-Warehouse.jsx b/frontend/src/AgroShopAI/components/Pages/Admin-Warehouse.jsx deleted file mode 100644 index fd7db140..00000000 --- a/frontend/src/AgroShopAI/components/Pages/Admin-Warehouse.jsx +++ /dev/null @@ -1,311 +0,0 @@ - -import React, { useState, useEffect } from 'react' - -// Dummy data for inventory items -const dummyInventory = [ - { id: 1, sku: 'FRT001', name: 'Organic Apples', stock: 500, category: 'Fruits', seller: 'Green Farms', location: 'Warehouse A' }, - { id: 2, sku: 'VEG002', name: 'Fresh Carrots', stock: 750, category: 'Vegetables', seller: 'Veggie Co.', location: 'Warehouse B' }, - { id: 3, sku: 'GRN003', name: 'Whole Wheat', stock: 1000, category: 'Grains', seller: 'Grain Growers', location: 'Warehouse C' }, - { id: 4, sku: 'DRY004', name: 'Organic Cashews', stock: 250, category: 'Dry Fruits', seller: 'Nutty Delights', location: 'Warehouse A' }, - { id: 5, sku: 'HRB005', name: 'Fresh Basil', stock: 100, category: 'Herbs', seller: 'Herb Haven', location: 'Warehouse B' }, -] - -export default function WarehouseInventory() { - const [inventory, setInventory] = useState(dummyInventory) - const [selectedItems, setSelectedItems] = useState([]) - const [searchTerm, setSearchTerm] = useState('') - const [filterCategory, setFilterCategory] = useState('') - const [sortColumn, setSortColumn] = useState('') - const [sortDirection, setSortDirection] = useState('asc') - const [editItem, setEditItem] = useState(null) - const [showDeleteModal, setShowDeleteModal] = useState(false) - const [itemToDelete, setItemToDelete] = useState(null) - const [showUploadModal, setShowUploadModal] = useState(false) - - // Filter and sort inventory - const filteredInventory = inventory - .filter(item => - item.name.toLowerCase().includes(searchTerm.toLowerCase()) && - (filterCategory === '' || item.category === filterCategory) - ) - .sort((a, b) => { - if (sortColumn === '') return 0 - const aValue = a[sortColumn] - const bValue = b[sortColumn] - if (aValue < bValue) return sortDirection === 'asc' ? -1 : 1 - if (aValue > bValue) return sortDirection === 'asc' ? 1 : -1 - return 0 - }) - - const handleSort = (column) => { - if (column === sortColumn) { - setSortDirection(sortDirection === 'asc' ? 'desc' : 'asc') - } else { - setSortColumn(column) - setSortDirection('asc') - } - } - - const handleEdit = (item) => { - setEditItem({ ...item }) - } - - const handleDelete = (id) => { - setItemToDelete(id) - setShowDeleteModal(true) - } - - const confirmDelete = () => { - if (itemToDelete) { - setInventory(inventory.filter(item => item.id !== itemToDelete)) - setShowDeleteModal(false) - setItemToDelete(null) - } - } - - const handleSave = () => { - setInventory(inventory.map(item => item.id === editItem.id ? editItem : item)) - setEditItem(null) - } - - const handleBulkDelete = () => { - setInventory(inventory.filter(item => !selectedItems.includes(item.id))) - setSelectedItems([]) - } - - const toggleSelectAll = () => { - if (selectedItems.length === filteredInventory.length) { - setSelectedItems([]) - } else { - setSelectedItems(filteredInventory.map(item => item.id)) - } - } - - const handleFileUpload = (event) => { - const file = event.target.files?.[0] - if (file) { - // Simulating file upload and processing - setTimeout(() => { - const newItems = [ - { id: inventory.length + 1, sku: 'NEW001', name: 'Uploaded Product', stock: 100, category: 'New', seller: 'New Seller', location: 'Warehouse D' }, - { id: inventory.length + 2, sku: 'NEW002', name: 'Another Upload', stock: 200, category: 'New', seller: 'New Seller', location: 'Warehouse E' }, - ] - setInventory([...inventory, ...newItems]) - setShowUploadModal(false) - }, 2000) - } - } - - return ( -
- {/* Flashy Banner */} -
-

AgroShop Warehouse Inventory

-

Manage your agricultural products efficiently

-
- -
- {/* Main Content Container */} -
- {/* Search and Filter */} -
-
- setSearchTerm(e.target.value)} - /> -
- - - {selectedItems.length > 0 && ( - - )} -
- - {/* Inventory Table */} -
- - - - - - - - - - - - - - - {filteredInventory.map(item => ( - - - - - - - - - - - ))} - -
- - handleSort('sku')}>SKU handleSort('name')}>Product Name handleSort('stock')}>Stock handleSort('category')}>Category handleSort('seller')}>Seller handleSort('location')}>LocationActions
- { - if (selectedItems.includes(item.id)) { - setSelectedItems(selectedItems.filter(id => id !== item.id)) - } else { - setSelectedItems([...selectedItems, item.id]) - } - }} - /> - {item.sku}{item.name}{item.stock}{item.category}{item.seller}{item.location} - - -
-
-
-
- - {/* Edit Modal */} - {editItem && ( -
-
-

Edit Item

-
- - setEditItem({ ...editItem, name: e.target.value })} - /> -
-
- - setEditItem({ ...editItem, stock: parseInt(e.target.value) })} - /> -
-
- - -
-
-
- )} - - {/* Delete Confirmation Modal */} - {showDeleteModal && ( -
-
-

Confirm Deletion

-

Are you sure you want to delete this item?

-
- - -
-
-
- )} - - {/* Upload Modal */} - {showUploadModal && ( -
-
-

Upload Inventory

-

Select a CSV file to upload new inventory items.

- -
- -
-
-
- )} -
- ) -} \ No newline at end of file diff --git a/frontend/src/AgroShopAI/components/Pages/Admin-login.jsx b/frontend/src/AgroShopAI/components/Pages/Admin-login.jsx deleted file mode 100644 index 490b5758..00000000 --- a/frontend/src/AgroShopAI/components/Pages/Admin-login.jsx +++ /dev/null @@ -1,284 +0,0 @@ -import { useState } from 'react'; - -export default function AdminLogin() { - const [email, setEmail] = useState(''); - const [password, setPassword] = useState(''); - const [error, setError] = useState(''); - const [isLoading, setIsLoading] = useState(false); - const [isRemembered, setIsRemembered] = useState(false); - - // Handles form submission - const handleSubmit = (e) => { - e.preventDefault(); - if (!email || !password) { - setError('Please fill in both fields.'); - return; - } - setIsLoading(true); - setError(''); - - // Simulate login attempt - setTimeout(() => { - if (email === 'admin@example.com' && password === 'admin123') { - setIsLoading(false); - alert('Login successful!'); - } else { - setError('Invalid credentials'); - setIsLoading(false); - } - }, 1500); - }; - - // Validates email format - const validateEmail = (email) => { - const regex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; - return regex.test(email); - }; - - // Checks password strength - const isPasswordStrong = (password) => { - return password.length >= 8; - }; - - // Helper function to toggle remember me state - const toggleRememberMe = () => { - setIsRemembered(!isRemembered); - }; - - // Resets the form - const handleReset = () => { - setEmail(''); - setPassword(''); - setError(''); - setIsRemembered(false); - }; - - // Displays a welcome message - const displayWelcomeMessage = (email) => { - return `Welcome back, ${email.split('@')[0]}!`; - }; - - // Checks if a field is empty - const isFieldEmpty = (fieldValue) => { - return fieldValue.trim() === ''; - }; - - // Displays the loading spinner - const displayLoading = () => { - return isLoading ? ( - - ) : null; - }; - - - - - const clearErrorAfterTimeout = () => { - setTimeout(() => { - setError(''); - }, 5000); - }; - - const validateFormFields = () => { - if (isFieldEmpty(email)) { - setError('Email field is required.'); - return false; - } - if (isFieldEmpty(password)) { - setError('Password field is required.'); - return false; - } - if (!validateEmail(email)) { - setError('Invalid email format.'); - return false; - } - if (!isPasswordStrong(password)) { - setError('Password should be at least 8 characters long.'); - return false; - } - return true; - }; - - - - const authenticateUser = () => { - setIsLoading(true); - setTimeout(() => { - if (email === 'admin@example.com' && password === 'admin123') { - setIsLoading(false); - alert('Login successful!'); - } else { - setError('Invalid credentials'); - setIsLoading(false); - } - }, 1500); - }; - - - const handleFormClick = (e) => { - if (e.target.name === 'loginButton') { - handleSubmit(e); - } - }; - - - const fetchLoginAnalytics = () => { - console.log('Fetching login analytics...'); - // Simulate API call - setTimeout(() => { - console.log('Analytics data fetched.'); - }, 2000); - }; - - - const logCurrentFormState = () => { - console.log('Current Form State:', { - email, - password, - isRemembered, - error, - isLoading, - }); - }; - - - const validateOnServer = (email, password) => { - return new Promise((resolve, reject) => { - setTimeout(() => { - if (email === 'admin@example.com' && password === 'admin123') { - resolve('Server validation successful'); - } else { - reject('Server validation failed'); - } - }, 1500); - }); - }; - - const serverCommunication = () => { - console.log('Sending data to the server...'); - validateOnServer(email, password) - .then((response) => { - console.log(response); - alert('Server validation passed'); - }) - .catch((error) => { - console.error(error); - setError('Server validation failed'); - }); - }; - - - - const trackLoginAttempt = () => { - console.log('Tracking login attempt...'); - setTimeout(() => { - console.log('Login attempt tracked.'); - }, 1000); - }; - - - - const handleLogout = () => { - setEmail(''); - setPassword(''); - setError(''); - setIsRemembered(false); - alert('Logged out successfully'); - }; - - return ( -
-
-
-
-
- - - - - -
-

- AgriAdmin Login -

-

- Access your agriculture e-commerce dashboard -

-
-
-
-
- - setEmail(e.target.value)} - /> -
-
- - setPassword(e.target.value)} - /> -
-
- - {error &&

{error}

} -
- -
-
-
- - -
-
- -
-
-
-
-
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/AdminTicket.jsx b/frontend/src/AgroShopAI/components/Pages/AdminTicket.jsx deleted file mode 100644 index 2ea1378c..00000000 --- a/frontend/src/AgroShopAI/components/Pages/AdminTicket.jsx +++ /dev/null @@ -1,124 +0,0 @@ -import React, { useState } from "react"; -import Header from "./THeader"; -import SearchAndFilter from "./TSearchAndFilter"; -import TicketList from "./AdminTicketList"; -import TicketDetails from "./AdminTicketDetails"; - -const dummyTickets = [ - { - id: 1, - subject: "Order not received", - status: "Open", - agent: "John Doe", - createdAt: "2023-05-15", - priority: "High", - description: - "I placed an order for fertilizer 5 days ago and haven't received it yet.", - user: "farmer@example.com", - }, - { - id: 2, - subject: "Wrong seeds delivered", - status: "In-Progress", - agent: "Jane Smith", - createdAt: "2023-05-14", - priority: "Medium", - description: "I ordered tomato seeds but received cucumber seeds instead.", - user: "gardener@example.com", - }, - { - id: 3, - subject: "Pesticide information needed", - status: "Open", - agent: "Unassigned", - createdAt: "2023-05-13", - priority: "Low", - description: - "I need more information about the organic pesticides you offer.", - user: "organic@example.com", - }, - { - id: 4, - subject: "Billing discrepancy", - status: "Open", - agent: "Bob Johnson", - createdAt: "2023-05-12", - priority: "High", - description: "I was charged twice for my last order of plant pots.", - user: "plantlover@example.com", - }, - { - id: 5, - subject: "Product quality issue", - status: "In-Progress", - agent: "Jane Smith", - createdAt: "2023-05-11", - priority: "Medium", - description: - "The soil I received seems to be of lower quality than advertised.", - user: "gardenexpert@example.com", - }, -]; - -const TicketManagement = () => { - const [tickets, setTickets] = useState(dummyTickets); - const [selectedTicket, setSelectedTicket] = useState(null); - const [searchTerm, setSearchTerm] = useState(""); - const [statusFilter, setStatusFilter] = useState("All"); - const [priorityFilter, setPriorityFilter] = useState("All"); - - const filteredTickets = tickets.filter((ticket) => { - return ( - ticket.subject.toLowerCase().includes(searchTerm.toLowerCase()) && - (statusFilter === "All" || ticket.status === statusFilter) && - (priorityFilter === "All" || ticket.priority === priorityFilter) - ); - }); - - const updateTicketStatus = (id, newStatus) => { - setTickets( - tickets.map((ticket) => - ticket.id === id ? { ...ticket, status: newStatus } : ticket - ) - ); - }; - - const assignTicket = (id, agent) => { - setTickets( - tickets.map((ticket) => - ticket.id === id ? { ...ticket, agent } : ticket - ) - ); - }; - - return ( -
-
- -
-
- -
-
- -
-
-
- ); -}; - -export default TicketManagement; diff --git a/frontend/src/AgroShopAI/components/Pages/AdminTicketDetails.jsx b/frontend/src/AgroShopAI/components/Pages/AdminTicketDetails.jsx deleted file mode 100644 index 316f7864..00000000 --- a/frontend/src/AgroShopAI/components/Pages/AdminTicketDetails.jsx +++ /dev/null @@ -1,92 +0,0 @@ -const TicketDetails = ({ - selectedTicket, - updateTicketStatus, - assignTicket, -}) => { - if (!selectedTicket) - return

Select a ticket to view details

; - - return ( -
-

- #{selectedTicket.id} - {selectedTicket.subject} -

-
-
-

User:

-

{selectedTicket.user}

-
-
-

Status:

-

- {selectedTicket.status} -

-
-
-

Priority:

-

{selectedTicket.priority}

-
-
-

Agent:

-

{selectedTicket.agent}

-
-
-

Created:

-

{selectedTicket.createdAt}

-
-
-
-

Description:

-

{selectedTicket.description}

-
- -
-

Update Status:

-
- - - -
-
- -
-

Assign Agent:

- -
-
- ); -}; - -export default TicketDetails; diff --git a/frontend/src/AgroShopAI/components/Pages/AdminTicketList.jsx b/frontend/src/AgroShopAI/components/Pages/AdminTicketList.jsx deleted file mode 100644 index 7932bce0..00000000 --- a/frontend/src/AgroShopAI/components/Pages/AdminTicketList.jsx +++ /dev/null @@ -1,38 +0,0 @@ -const TicketList = ({ filteredTickets, setSelectedTicket }) => ( -
-

Ticket List

-
- {filteredTickets.map((ticket) => ( -
setSelectedTicket(ticket)} - > -

- #{ticket.id} - {ticket.subject} -

-
- - Status:{" "} - - {ticket.status} - - - Agent: {ticket.agent} - Created: {ticket.createdAt} -
-
- ))} -
-
-); - -export default TicketList; diff --git a/frontend/src/AgroShopAI/components/Pages/Affiliate.jsx b/frontend/src/AgroShopAI/components/Pages/Affiliate.jsx deleted file mode 100644 index 1ea85323..00000000 --- a/frontend/src/AgroShopAI/components/Pages/Affiliate.jsx +++ /dev/null @@ -1,43 +0,0 @@ -import React, { useState } from 'react'; -import AffiliateHeader from './components/AffiliateHeader'; -import AffiliateJoinSection from './components/AffiliateJoinSection'; -import AffiliateDashboard from './components/AffiliateDashboard'; -import AffiliateMarketingMaterials from './components/AffiliateMarketingMaterials'; -import AffiliateTerms from './components/AffiliateTerms'; - - -export default function AffiliateProgramPage() { - const [isLoggedIn, setIsLoggedIn] = useState(false); - const [dateRange, setDateRange] = useState('last7days'); - - const dummyData = { - clicks: 1250, - signUps: 75, - conversions: 30, - commissions: 450.0, - }; - - const handleLogin = (e) => { - e.preventDefault(); - setIsLoggedIn(true); - }; - - return ( -
- -
- - - - -
- -
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/BulkPage.jsx b/frontend/src/AgroShopAI/components/Pages/BulkPage.jsx deleted file mode 100644 index 8fbbec52..00000000 --- a/frontend/src/AgroShopAI/components/Pages/BulkPage.jsx +++ /dev/null @@ -1,50 +0,0 @@ -import React, { useState, useEffect } from "react"; -import { ArrowRight, Star, ShoppingCart } from "lucide-react"; -import BundleHeader from "./BundleHeader"; -import BundleList from "./BundleList"; -import BundleRelatedItems from "./BundleRelatedItems"; -import BundleLoyaltyMessage from "./BundleLoyaltyMessage"; -import { dummyBundles, relatedBundles } from "./BundleData.js"; - -export default function BundledProducts() { - const [bundles, setBundles] = useState(dummyBundles); - const [isLoyaltyMember, setIsLoyaltyMember] = useState(false); - - useEffect(() => { - const checkLoyaltyStatus = () => { - setIsLoyaltyMember(Math.random() > 0.5); - }; - checkLoyaltyStatus(); - }, []); - - const handleCustomize = (bundleId, productId, newPrice) => { - setBundles( - bundles.map((bundle) => { - if (bundle.id === bundleId) { - const updatedProducts = bundle.products.map((product) => - product.id === productId - ? { ...product, price: parseFloat(newPrice) } - : product - ); - return { ...bundle, products: updatedProducts }; - } - return bundle; - }) - ); - }; - - return ( -
- -
- - - {!isLoyaltyMember && } -
-
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/BundleCard.jsx b/frontend/src/AgroShopAI/components/Pages/BundleCard.jsx deleted file mode 100644 index 3cef10ee..00000000 --- a/frontend/src/AgroShopAI/components/Pages/BundleCard.jsx +++ /dev/null @@ -1,31 +0,0 @@ -import React from "react"; -import BundleProductList from "./BundleProductList"; -import BundlePriceBreakdown from "./BundlePriceBreakdown"; - -export default function BundleCard({ bundle, handleCustomize }) { - return ( -
-
-

{bundle.name}

- {bundle.popular && ( - - Popular - - )} - {bundle.loyaltyOnly && ( - - Loyalty Exclusive - - )} -
-
- - -
-
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/BundleData.js b/frontend/src/AgroShopAI/components/Pages/BundleData.js deleted file mode 100644 index 700370c5..00000000 --- a/frontend/src/AgroShopAI/components/Pages/BundleData.js +++ /dev/null @@ -1,43 +0,0 @@ -const dummyBundles = [ - { - id: 1, - name: "Vegetable Garden Starter Kit", - products: [ - { id: 101, name: "Tomato Seeds", price: 2.99, image: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTrs2SNL4lNOnoRgBlf0GRJWQl1yKHoVObKWQ&s" }, - { id: 102, name: "Cucumber Seeds", price: 2.49, image: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ0Vwa7PEYpsxTqVB7Rk8XvlIfDKJGwxGNoUA&s" }, - { id: 103, name: "Lettuce Seeds", price: 1.99, image: "https://rukminim2.flixcart.com/image/850/1000/xif0q/plant-seed/r/h/s/500-lettuce-seeds-nutritious-strong-vitality-500-seeds-cybexis-original-imagj7zpsdzbusmy.jpeg?q=90&crop=false" }, - ], - discount: 0.15, - popular: true, - }, - { - id: 2, - name: "Organic Fertilizer Pack", - products: [ - { id: 201, name: "Compost", price: 9.99, image: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRKrbmfitL_ySlrc4X1i1NfR0_9mgMHBd5Yng&s" }, - { id: 202, name: "Worm Castings", price: 14.99, image: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRWEIMyLgEpGv5yvvUAwQMfDzBr4HAEaYZk_A&s" }, - ], - discount: 0.1, - popular: false, - }, - { - id: 3, - name: "Herb Garden Deluxe", - products: [ - { id: 301, name: "Basil Seeds", price: 2.99, image: "https://www.indianhealthyrecipes.com/wp-content/uploads/2022/05/how-to-use-sabja-seeds-005.webp" }, - { id: 302, name: "Cilantro Seeds", price: 2.49, image: "https://i.etsystatic.com/24334654/r/il/ee104f/2746663992/il_570xN.2746663992_kug2.jpg" }, - { id: 303, name: "Mint Seeds", price: 2.99, image: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS7FO1mXAwhcF9nlI7muH4gZUAAoA07m_QObQ&s" }, - { id: 304, name: "Herb Planter", price: 19.99, image: "https://m.media-amazon.com/images/I/81Bn7zfkySL.jpg" }, - ], - discount: 0.2, - popular: true, - loyaltyOnly: true, - }, - ] - - const relatedBundles = [ - { id: 4, name: "Gardening Tools Set", price: 49.99, image: "https://m.media-amazon.com/images/I/91qFY3-tD9L.jpg" }, - { id: 5, name: "Pest Control Kit", price: 29.99, image: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRHZI-60B7w_gP-kSTjhHkhx8zv7Ash3Y6HWg&s" }, - ] - -export {dummyBundles,relatedBundles} diff --git a/frontend/src/AgroShopAI/components/Pages/BundleHeader.jsx b/frontend/src/AgroShopAI/components/Pages/BundleHeader.jsx deleted file mode 100644 index 52db6526..00000000 --- a/frontend/src/AgroShopAI/components/Pages/BundleHeader.jsx +++ /dev/null @@ -1,34 +0,0 @@ -import React from "react"; -import { ShoppingCart } from "lucide-react"; - -export default function BundleHeader({ title, subtitle, onCartClick }) { - return ( -
-
-
-

{title}

- {subtitle && ( -

{subtitle}

- )} -
- -
- - - -
-
- - {/* Optional decorative line */} -
-
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/BundleList.jsx b/frontend/src/AgroShopAI/components/Pages/BundleList.jsx deleted file mode 100644 index 448b272a..00000000 --- a/frontend/src/AgroShopAI/components/Pages/BundleList.jsx +++ /dev/null @@ -1,24 +0,0 @@ -import React from "react"; -import BundleCard from "./BundleCard"; - -export default function BundleList({ - bundles, - isLoyaltyMember, - handleCustomize, -}) { - return ( -
-

Featured Bundles

- {bundles.map( - (bundle) => - (!bundle.loyaltyOnly || (bundle.loyaltyOnly && isLoyaltyMember)) && ( - - ) - )} -
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/BundleLoyaltyMessage.jsx b/frontend/src/AgroShopAI/components/Pages/BundleLoyaltyMessage.jsx deleted file mode 100644 index 9cda9b20..00000000 --- a/frontend/src/AgroShopAI/components/Pages/BundleLoyaltyMessage.jsx +++ /dev/null @@ -1,13 +0,0 @@ -import React from "react"; - -export default function BundleLoyaltyMessage() { - return ( -
-

Not a loyalty member?

-

Sign up now to access exclusive bundles and additional discounts!

-
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/BundleOverview.jsx b/frontend/src/AgroShopAI/components/Pages/BundleOverview.jsx deleted file mode 100644 index 345c92bc..00000000 --- a/frontend/src/AgroShopAI/components/Pages/BundleOverview.jsx +++ /dev/null @@ -1,80 +0,0 @@ -import React, { useState } from 'react' - -export default function BundleOverview({ bundle, onCustomizePrice }) { - const [showDetails, setShowDetails] = useState(false) - - const toggleDetails = () => setShowDetails(!showDetails) - - const calculateTotalPrice = (products) => - products.reduce((total, product) => total + product.price, 0) - - const calculateDiscountedPrice = (products, discount) => { - const totalPrice = calculateTotalPrice(products) - return totalPrice - totalPrice * discount - } - - return ( -
-
-
-

{bundle.name}

- {bundle.popular && ( - - Popular - - )} - {bundle.loyaltyOnly && ( - - Loyalty Exclusive - - )} -
- -
- - {showDetails && ( -
-
-

Products in this bundle:

-
    - {bundle.products.map((product) => ( -
  • - {product.name} - {product.name} - onCustomizePrice(bundle.id, product.id, e.target.value)} - className="ml-auto w-20 p-1 border border-gray-300 rounded" - /> -
  • - ))} -
-
-
-

Price Breakdown:

-

Original Price: ${calculateTotalPrice(bundle.products).toFixed(2)}

-

Bundle Price: ${calculateDiscountedPrice(bundle.products, bundle.discount).toFixed(2)}

-

- You Save: $ - {( - calculateTotalPrice(bundle.products) - - calculateDiscountedPrice(bundle.products, bundle.discount) - ).toFixed(2)}{' '} - ({(bundle.discount * 100).toFixed(0)}% off) -

-
-
- )} -
- ) -} diff --git a/frontend/src/AgroShopAI/components/Pages/BundlePriceBreakdown.jsx b/frontend/src/AgroShopAI/components/Pages/BundlePriceBreakdown.jsx deleted file mode 100644 index 558551f6..00000000 --- a/frontend/src/AgroShopAI/components/Pages/BundlePriceBreakdown.jsx +++ /dev/null @@ -1,29 +0,0 @@ -import React from "react"; - -export default function BundlePriceBreakdown({ bundle }) { - const calculateTotalPrice = (products) => - products.reduce((total, product) => total + product.price, 0); - const calculateDiscountedPrice = (bundle) => { - const totalPrice = calculateTotalPrice(bundle.products); - return totalPrice - totalPrice * bundle.discount; - }; - - return ( -
-

Price Breakdown:

-

Original Price: ${calculateTotalPrice(bundle.products).toFixed(2)}

-

Bundle Price: ${calculateDiscountedPrice(bundle).toFixed(2)}

-

- You Save: $ - {( - calculateTotalPrice(bundle.products) - - calculateDiscountedPrice(bundle) - ).toFixed(2)}{" "} - ({(bundle.discount * 100).toFixed(0)}% off) -

- -
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/BundleProductList.jsx b/frontend/src/AgroShopAI/components/Pages/BundleProductList.jsx deleted file mode 100644 index 7b8d62ce..00000000 --- a/frontend/src/AgroShopAI/components/Pages/BundleProductList.jsx +++ /dev/null @@ -1,33 +0,0 @@ -import React from "react"; - -export default function BundleProductList({ - products, - bundleId, - handleCustomize, -}) { - return ( -
-

Products in this bundle:

- -
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/BundleRelatedItems.jsx b/frontend/src/AgroShopAI/components/Pages/BundleRelatedItems.jsx deleted file mode 100644 index 43084349..00000000 --- a/frontend/src/AgroShopAI/components/Pages/BundleRelatedItems.jsx +++ /dev/null @@ -1,28 +0,0 @@ -import React from "react"; - -export default function BundleRelatedItems({ relatedBundles }) { - return ( -
-

You Might Also Like

-
- {relatedBundles.map((bundle) => ( -
- {bundle.name} -

{bundle.name}

-

${bundle.price.toFixed(2)}

- -
- ))} -
-
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/ConfirmationMessage.jsx b/frontend/src/AgroShopAI/components/Pages/ConfirmationMessage.jsx deleted file mode 100644 index 4eb785dc..00000000 --- a/frontend/src/AgroShopAI/components/Pages/ConfirmationMessage.jsx +++ /dev/null @@ -1,25 +0,0 @@ -import React from "react"; - -export default function ConfirmationMessage({ - showConfirmation, - newTicketId, - setShowConfirmation, -}) { - return ( - showConfirmation && ( -
-

Ticket Submitted Successfully!

-

Your ticket ID is: {newTicketId}

- -
- ) - ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/DeleteModal.jsx b/frontend/src/AgroShopAI/components/Pages/DeleteModal.jsx deleted file mode 100644 index 8944f4d0..00000000 --- a/frontend/src/AgroShopAI/components/Pages/DeleteModal.jsx +++ /dev/null @@ -1,29 +0,0 @@ - -import React from 'react'; - -export default function DeleteModal({ showDeleteModal, confirmDelete, setShowDeleteModal }) { - return ( - showDeleteModal && ( -
-
-

Confirm Deletion

-

Are you sure you want to delete this item?

-
- - -
-
-
- ) - ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/DiscountCouponManagement.jsx b/frontend/src/AgroShopAI/components/Pages/DiscountCouponManagement.jsx deleted file mode 100644 index 2b698580..00000000 --- a/frontend/src/AgroShopAI/components/Pages/DiscountCouponManagement.jsx +++ /dev/null @@ -1,120 +0,0 @@ -import React, { useState } from 'react' -import CouponTable from './components/CouponTable' -import CouponForm from './components/CouponForm' -import DeleteConfirmationModal from './components//DeleteConfirmationModal' -import FilterBar from './components/FilterBar' - -export default function DiscountCouponManagement() { - const [coupons, setCoupons] = useState([ - { id: 1, code: 'SUMMER10', type: 'Percentage', value: 10, startDate: '2023-06-01', endDate: '2023-08-31', status: 'active', usageLimit: 100 }, - { id: 2, code: 'WELCOME20', type: 'Percentage', value: 20, startDate: '2023-01-01', endDate: '2023-12-31', status: 'active', usageLimit: 1000 }, - { id: 3, code: 'FLASH50', type: 'Fixed Amount', value: 50, startDate: '2023-07-01', endDate: '2023-07-02', status: 'expired', usageLimit: 500 }, - ]) - - const [showForm, setShowForm] = useState(false) - const [editingCoupon, setEditingCoupon] = useState(null) - const [deleteConfirmation, setDeleteConfirmation] = useState(null) - - const [formData, setFormData] = useState({ - code: '', - description: '', - type: 'Percentage', - value: 0, - minOrderAmount: 0, - maxDiscount: 0, - startDate: '', - endDate: '', - usageLimit: 0, - status: 'active' - }) - - const [filter, setFilter] = useState({ status: 'all', dateRange: '', discountType: '' }) - - const handleFilterChange = (e) => { - setFilter({ ...filter, [e.target.name]: e.target.value }) - } - - const handleFormChange = (e) => { - setFormData({ ...formData, [e.target.name]: e.target.value }) - } - - const handleSubmit = (e) => { - e.preventDefault() - if (editingCoupon) { - setCoupons(coupons.map(coupon => coupon.id === editingCoupon.id ? { ...coupon, ...formData } : coupon)) - } else { - setCoupons([...coupons, { id: coupons.length + 1, ...formData }]) - } - setShowForm(false) - setEditingCoupon(null) - setFormData({ - code: '', - description: '', - type: 'Percentage', - value: 0, - minOrderAmount: 0, - maxDiscount: 0, - startDate: '', - endDate: '', - usageLimit: 0, - status: 'active' - }) - } - - const handleEdit = (coupon) => { - setEditingCoupon(coupon) - setFormData(coupon) - setShowForm(true) - } - - const handleDelete = (coupon) => { - setDeleteConfirmation(coupon) - } - - const confirmDelete = () => { - setCoupons(coupons.filter(c => c.id !== deleteConfirmation.id)) - setDeleteConfirmation(null) - } - - return ( -
-

Discount and Coupon Management

- - -
- -
- - -
- - {showForm && ( - setShowForm(false)} - editingCoupon={editingCoupon} - /> - )} -
- - {deleteConfirmation && ( - setDeleteConfirmation(null)} - onConfirm={confirmDelete} - /> - )} -
- ) -} diff --git a/frontend/src/AgroShopAI/components/Pages/EditModal.jsx b/frontend/src/AgroShopAI/components/Pages/EditModal.jsx deleted file mode 100644 index 226a174b..00000000 --- a/frontend/src/AgroShopAI/components/Pages/EditModal.jsx +++ /dev/null @@ -1,44 +0,0 @@ -// EditModal.js -import React from 'react'; - -export default function EditModal({ editItem, setEditItem, handleSave }) { - return ( -
-
-

Edit Item

-
- - setEditItem({ ...editItem, name: e.target.value })} - /> -
-
- - setEditItem({ ...editItem, stock: parseInt(e.target.value) })} - /> -
-
- - -
-
-
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/FarmerSuccessStories.jsx b/frontend/src/AgroShopAI/components/Pages/FarmerSuccessStories.jsx deleted file mode 100644 index 9f089bc5..00000000 --- a/frontend/src/AgroShopAI/components/Pages/FarmerSuccessStories.jsx +++ /dev/null @@ -1,47 +0,0 @@ -export default function FarmerSuccessStories() { - const [searchTerm, setSearchTerm] = useState(""); - const [selectedStory, setSelectedStory] = useState(null); - - const filteredStories = dummyStories.filter( - (story) => - story.name.toLowerCase().includes(searchTerm.toLowerCase()) || - story.location.toLowerCase().includes(searchTerm.toLowerCase()) || - story.cropType.toLowerCase().includes(searchTerm.toLowerCase()) || - story.technology.toLowerCase().includes(searchTerm.toLowerCase()) - ); - - return ( -
-
- -
-
-

- Discover inspiring stories of farmers who have embraced sustainable - practices and innovative technologies to transform their - agricultural journey. -

-
- - - -
- {filteredStories.map((story) => ( - - ))} -
-
- - {selectedStory && ( - setSelectedStory(null)} - /> - )} -
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/FeaturedProductsSection.jsx b/frontend/src/AgroShopAI/components/Pages/FeaturedProductsSection.jsx deleted file mode 100644 index 1e829a7a..00000000 --- a/frontend/src/AgroShopAI/components/Pages/FeaturedProductsSection.jsx +++ /dev/null @@ -1,27 +0,0 @@ -import React from 'react' - -export default function FeaturedProductsSection() { - return ( -
-
-

Featured Products

-
- {featuredProducts.map(product => ( -
- {product.name} -

{product.name}

-

{product.price}

- -
- ))} -
-
-
- ) -} diff --git a/frontend/src/AgroShopAI/components/Pages/GiftBenefit.jsx b/frontend/src/AgroShopAI/components/Pages/GiftBenefit.jsx deleted file mode 100644 index 3483eb7d..00000000 --- a/frontend/src/AgroShopAI/components/Pages/GiftBenefit.jsx +++ /dev/null @@ -1,40 +0,0 @@ -import React from 'react' - -function GiftBenefit() { - return ( -
- {/* Gift Card Benefits */} -
-

Gift Card Benefits

-
    -
  • - - - - Use on any product in our store -
  • -
  • - - - - No expiration date -
  • -
  • - - - - Easily transferable to friends and family -
  • -
  • - - - - Perfect gift for the gardening enthusiast -
  • -
-
-
- ) -} - -export default GiftBenefit diff --git a/frontend/src/AgroShopAI/components/Pages/GiftCard.jsx b/frontend/src/AgroShopAI/components/Pages/GiftCard.jsx deleted file mode 100644 index 9524f6c2..00000000 --- a/frontend/src/AgroShopAI/components/Pages/GiftCard.jsx +++ /dev/null @@ -1,225 +0,0 @@ -import React, { useState, useEffect } from 'react' -import GiftBenefit from './GiftBenefit' -import GiftIdeas from './GiftIdeas' -import GiftTest from './GiftTest' -import GiftFaq from './GiftFaq' -import GiftLetter from './GiftLetter' - -export default function GiftCard() { - const [giftCardNumber, setGiftCardNumber] = useState('') - const [pin, setPin] = useState('') - const [message, setMessage] = useState('') - const [isSuccess, setIsSuccess] = useState(false) - const [isMenuOpen, setIsMenuOpen] = useState(false) - - const handleApplyGiftCard = () => { - e.preventDefault() - if (giftCardNumber.length === 16 && (pin.length === 0 || pin.length === 4)) { - setMessage('Gift card applied successfully! Balance: $50.00') - setIsSuccess(true) - } else { - setMessage('Invalid gift card code or PIN') - setIsSuccess(false) - } - } - - useEffect(() => { - const timer = setTimeout(() => { - setMessage('') - }, 5000) - return () => clearTimeout(timer) - }, [message]) - - return ( -
- {/* Header */} -
-
-

AgroShop

- - -
-
- - {/* Mobile Menu */} - {isMenuOpen && ( -
- -
- )} - - {/* Main Content */} -
- {/* Hero Section */} -
-

Give the Gift of Green

-

Perfect for any gardening enthusiast in your life!

- - Get a Gift Card - -
- - {/* Sale Banner */} -
-

Spring Sale! 20% Off All Seeds

-

Use code: SPRING20 at checkout

-
- - {/* Gift Card Section */} -
-

Apply Gift Card

-
-
- - setGiftCardNumber(e.target.value)} - className="w-full border-2 border-green-300 rounded-lg shadow-sm p-3 focus:ring-2 focus:ring-green-500 focus:border-transparent transition duration-300" - required - maxLength={16} - placeholder="Enter 16-digit gift card number" - /> -
-
- - setPin(e.target.value)} - className="w-full border-2 border-green-300 rounded-lg shadow-sm p-3 focus:ring-2 focus:ring-green-500 focus:border-transparent transition duration-300" - maxLength={4} - placeholder="Enter 4-digit PIN (if applicable)" - /> -
- -
- {message && ( -
- {message} -
- )} -
- - - - {/* Featured Products */} -
-

Featured Products

-
- {[ - { name: 'Organic Tomato Seeds', price: 19.99, image: 'https://rukminim2.flixcart.com/image/850/1000/xif0q/plant-seed/7/9/s/60-1deshi-tomato-seeds2g-bdsresolve-original-imagsghfzcxe3y27.jpeg?q=20&crop=false' }, - { name: 'Garden Tool Set', price: 49.99, image: 'https://nurserylive.com/cdn/shop/products/nurserylive-combo-packs-tools-basic-garden-tool-kit-gardening-tools-16968613363852.jpg?v=1634214058' }, - { name: 'Eco-Friendly Fertilizer', price: 29.99, image: 'https://www.planetnatural.com/wp-content/uploads/2012/12/fertilizer-products-1.jpg' } - ].map((product, index) => ( -
- {product.name} -

{product.name}

-

${product.price.toFixed(2)}

- -
- ))} -
-
- - - - - - - - - -
- - {/* Footer */} - -
- ) -} \ No newline at end of file diff --git a/frontend/src/AgroShopAI/components/Pages/GiftFaq.jsx b/frontend/src/AgroShopAI/components/Pages/GiftFaq.jsx deleted file mode 100644 index 5a15bae2..00000000 --- a/frontend/src/AgroShopAI/components/Pages/GiftFaq.jsx +++ /dev/null @@ -1,27 +0,0 @@ -import React from 'react' - -function GiftFaq() { - return ( -
- {/* FAQ Section */} -
-

Frequently Asked Questions

-
- {[ - { question: 'How do I purchase a gift card?', answer: 'You can purchase a gift card online through our website or in-store at any of our physical locations.' }, - { question: 'Can I use my gift card for online purchases?', answer: 'Yes, gift cards can be used for both online and in-store purchases.' }, - { question: 'Do gift cards expire?', answer: 'No, our gift cards do not have an expiration date.' }, - { question: 'Can I check my gift card balance?', answer: 'Yes, you can check your balance online or by calling our customer service.' }, - ].map((faq, index) => ( -
-

{faq.question}

-

{faq.answer}

-
- ))} -
-
-
- ) -} - -export default GiftFaq \ No newline at end of file diff --git a/frontend/src/AgroShopAI/components/Pages/GiftIdeas.jsx b/frontend/src/AgroShopAI/components/Pages/GiftIdeas.jsx deleted file mode 100644 index 409ea7b1..00000000 --- a/frontend/src/AgroShopAI/components/Pages/GiftIdeas.jsx +++ /dev/null @@ -1,52 +0,0 @@ -import React from 'react' - -function GiftIdeas() { - return ( -
- {/* Gift Ideas */} -
-

Gift Ideas for Garden Lovers

-
-
- - - -
-

Gardening Books

-

Inspire with knowledge and tips

-
-
-
- - - -
-

Magnifying Glass

-

For examining plants up close

-
-
-
- - - -
-

Seed Storage Box

-

Organize and preserve seeds

-
-
-
- - - -
-

Garden Planner

-

Plan and track garden progress

-
-
-
-
-
- ) -} - -export default GiftIdeas \ No newline at end of file diff --git a/frontend/src/AgroShopAI/components/Pages/GiftLetter.jsx b/frontend/src/AgroShopAI/components/Pages/GiftLetter.jsx deleted file mode 100644 index ddb798ae..00000000 --- a/frontend/src/AgroShopAI/components/Pages/GiftLetter.jsx +++ /dev/null @@ -1,28 +0,0 @@ -import React from 'react' - -function GiftLetter() { - return ( -
-
-

Sign Up for Our Newsletter

-

Get the latest deals and gardening tips delivered to your inbox!

-
- - -
-
-
- ) -} - -export default GiftLetter \ No newline at end of file diff --git a/frontend/src/AgroShopAI/components/Pages/GiftTest.jsx b/frontend/src/AgroShopAI/components/Pages/GiftTest.jsx deleted file mode 100644 index d5f81f21..00000000 --- a/frontend/src/AgroShopAI/components/Pages/GiftTest.jsx +++ /dev/null @@ -1,30 +0,0 @@ -import React from 'react' - -function GiftTest() { - return ( -
- {/* Testimonials */} -
-

What Our Customers Say

-
- {[ - { name: 'Sarah L.', text: 'The AgroShop gift card was the perfect present for my gardening-obsessed friend!', avatar: '/placeholder.svg?height=50&width=50' }, - { name: 'Mike T.', text: 'I love the flexibility of the gift card. I was able to get exactly what I needed for my vegetable garden.', avatar: '/placeholder.svg?height=50&width=50' }, - { name: 'Emily R.', text: 'The gift card process was smooth, and I received excellent customer service when I had questions.', avatar: '/placeholder.svg?height=50&width=50' }, - { name: 'David K.', text: 'AgroShop has become my go-to for all things gardening. The gift card is a great way to share the love!', avatar: '/placeholder.svg?height=50&width=50' }, - ].map((testimonial, index) => ( -
-
- {testimonial.name} -

{testimonial.name}

-
-

"{testimonial.text}"

-
- ))} -
-
-
- ) -} - -export default GiftTest \ No newline at end of file diff --git a/frontend/src/AgroShopAI/components/Pages/HeroSection.jsx b/frontend/src/AgroShopAI/components/Pages/HeroSection.jsx deleted file mode 100644 index c50845e5..00000000 --- a/frontend/src/AgroShopAI/components/Pages/HeroSection.jsx +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react' - -export default function HeroSection() { - return ( -
-
-

Welcome to Agroshop

-

Your one-stop shop for all agricultural needs

- Shop Now -
-
- ) -} diff --git a/frontend/src/AgroShopAI/components/Pages/NotficationHeader.jsx b/frontend/src/AgroShopAI/components/Pages/NotficationHeader.jsx deleted file mode 100644 index e95aec96..00000000 --- a/frontend/src/AgroShopAI/components/Pages/NotficationHeader.jsx +++ /dev/null @@ -1,35 +0,0 @@ -import React from "react"; - -export default function Header() { - return ( -
-
-

Agroshop

- -
-
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/NotificationPage.jsx b/frontend/src/AgroShopAI/components/Pages/NotificationPage.jsx deleted file mode 100644 index 32d423e5..00000000 --- a/frontend/src/AgroShopAI/components/Pages/NotificationPage.jsx +++ /dev/null @@ -1,205 +0,0 @@ -import React, { useState } from 'react' - - -const initialNotices = [ - { id: 1, title: 'New Organic Fertilizers', content: 'Check out our latest range of organic fertilizers, now available!', date: '2024-03-10', active: true }, - { id: 2, title: 'Seasonal Seed Sale', content: 'Get 20% off on all vegetable seeds this week.', date: '2024-03-08', active: true }, - { id: 3, title: 'Farming Workshop', content: 'Join our expert-led workshop on sustainable farming practices this Saturday.', date: '2024-03-05', active: false }, - { id: 4, title: 'New Irrigation Systems', content: 'Explore our new range of water-efficient irrigation systems.', date: '2024-03-03', active: true }, - { id: 5, title: 'Pest Control Webinar', content: 'Register for our upcoming webinar on organic pest control methods.', date: '2024-03-01', active: true }, -] - -// Dummy data for featured products -const featuredProducts = [ - { id: 1, name: 'Organic Tomato Seeds', price: '$4.99', image: '/placeholder.svg?height=100&width=100' }, - { id: 2, name: 'Premium Soil Mix', price: '$19.99', image: '/placeholder.svg?height=100&width=100' }, - { id: 3, name: 'Eco-Friendly Pesticide', price: '$24.99', image: '/placeholder.svg?height=100&width=100' }, - { id: 4, name: 'Garden Tool Set', price: '$49.99', image: '/placeholder.svg?height=100&width=100' }, -] - -export default function Notification() { - const [notices, setNotices] = useState(initialNotices) - const [newNotice, setNewNotice] = useState({ title: '', content: '', date: '' }) - const [isAdmin, setIsAdmin] = useState(false) - const [showNotification, setShowNotification] = useState(false) - - const handleInputChange = (e) => { - const { name, value } = e.target - setNewNotice(prev => ({ ...prev, [name]: value })) - } - - const addNotice = () => { - if (newNotice.title && newNotice.content && newNotice.date) { - setNotices(prev => [ - { id: prev.length + 1, ...newNotice, active: true }, - ...prev, - ]) - setNewNotice({ title: '', content: '', date: '' }) - setShowNotification(true) - setTimeout(() => setShowNotification(false), 3000) - } - } - - const toggleNoticeStatus = (id) => { - setNotices(prev => - prev.map(notice => - notice.id === id ? { ...notice, active: !notice.active } : notice - ) - ) - } - - const deleteNotice = (id) => { - setNotices(prev => prev.filter(notice => notice.id !== id)) - } - - return ( -
-
-
-

Agroshop

- -
-
- -
-
-

Welcome to Agroshop

-

Your one-stop shop for all agricultural needs

- Shop Now -
-
- -
- - -
-
-

Latest Notices

- {isAdmin && ( -
-

Add New Notice

-
- - - - -
-
- )} -
- {notices - .filter(notice => isAdmin || notice.active) - .map(notice => ( -
-

{notice.title}

-

Posted on: {notice.date}

-

{notice.content}

- {isAdmin && ( -
- - -
- )} -
- ))} -
-
-
-

Featured Products

-
- {featuredProducts.map(product => ( -
- {product.name} -

{product.name}

-

{product.price}

- -
- ))} -
-
-
-
- -
-
-
-

About Agroshop

-

Your trusted partner in agricultural solutions. We provide high-quality products and expert advice for all your farming needs.

-
-
-

Quick Links

- -
-
-

Contact Us

-

123 Farm Road, Greenville, AG 12345

-

Phone: (555) 123-4567

-

Email: info@agroshop.com

-
-
-
- - {showNotification && ( -
- New notice added successfully! -
- )} -
- ) -} \ No newline at end of file diff --git a/frontend/src/AgroShopAI/components/Pages/Order-history.jsx b/frontend/src/AgroShopAI/components/Pages/Order-history.jsx deleted file mode 100644 index 0555949b..00000000 --- a/frontend/src/AgroShopAI/components/Pages/Order-history.jsx +++ /dev/null @@ -1,307 +0,0 @@ -import { useState } from "react"; - -// Dummy data -const dummyOrders = [ - { - id: "ORD-001", - date: "2023-05-15", - totalAmount: 156.99, - paymentStatus: "Paid", - items: [ - { name: "Organic Tomatoes", quantity: 2, price: 4.99 }, - { name: "Fresh Basil", quantity: 1, price: 2.99 }, - { name: "Free-range Eggs", quantity: 2, price: 5.99 }, - ], - shippingDetails: { - address: "123 Green St", - city: "Farmville", - postalCode: "12345", - }, - }, - { - id: "ORD-002", - date: "2023-05-18", - totalAmount: 89.97, - paymentStatus: "Pending", - items: [ - { name: "Organic Apples", quantity: 3, price: 3.99 }, - { name: "Whole Grain Bread", quantity: 2, price: 4.99 }, - { name: "Grass-fed Beef", quantity: 1, price: 15.99 }, - ], - shippingDetails: { - address: "456 Harvest Rd", - city: "Croptown", - postalCode: "67890", - }, - }, - { - id: "ORD-003", - date: "2023-05-20", - totalAmount: 210.95, - paymentStatus: "Paid", - items: [ - { name: "Organic Milk", quantity: 2, price: 4.99 }, - { name: "Heirloom Carrots", quantity: 1, price: 3.99 }, - { name: "Artisanal Cheese", quantity: 1, price: 12.99 }, - ], - shippingDetails: { - address: "789 Orchard Ln", - city: "Grainville", - postalCode: "13579", - }, - }, - { - id: "ORD-004", - date: "2023-05-22", - totalAmount: 45.98, - paymentStatus: "Failed", - items: [ - { name: "Organic Spinach", quantity: 2, price: 3.99 }, - { name: "Free-range Chicken", quantity: 1, price: 12.99 }, - { name: "Organic Honey", quantity: 1, price: 8.99 }, - ], - shippingDetails: { - address: "101 Meadow Ave", - city: "Pastureland", - postalCode: "24680", - }, - }, - { - id: "ORD-005", - date: "2023-05-25", - totalAmount: 178.95, - paymentStatus: "Paid", - items: [ - { name: "Organic Strawberries", quantity: 3, price: 5.99 }, - { name: "Grass-fed Yogurt", quantity: 2, price: 4.99 }, - { name: "Organic Quinoa", quantity: 1, price: 7.99 }, - ], - shippingDetails: { - address: "202 Sunny Fields", - city: "Harvestville", - postalCode: "35791", - }, - }, -]; - -// Modal component for order details -const OrderDetailsModal = ({ order, onClose }) => { - return ( -
-
-

- Order Details - #{order.id} -

-
-
-

Date

-

{order.date}

-
-
-

Total Amount

-

${order.totalAmount.toFixed(2)}

-
-
-

Status

-

- {order.paymentStatus} -

-
-
- -

Items

-
    - {order.items.map((item, index) => ( -
  • - - {item.name} (x{item.quantity}) - - - ${(item.price * item.quantity).toFixed(2)} - -
  • - ))} -
- -

- Shipping Details -

-
-

{order.shippingDetails.address}

-

- {order.shippingDetails.city}, {order.shippingDetails.postalCode} -

-
- - -
-
- ); -}; - -// Main component -export default function OrderHistory() { - const [currentPage, setCurrentPage] = useState(1); - const [selectedOrder, setSelectedOrder] = (useState < Order) | (null > null); - const ordersPerPage = 5; - const totalPages = Math.ceil(dummyOrders.length / ordersPerPage); - - const getCurrentPageOrders = () => { - const startIndex = (currentPage - 1) * ordersPerPage; - const endIndex = startIndex + ordersPerPage; - return dummyOrders.slice(startIndex, endIndex); - }; - - return ( -
-

- AgroShop Order History -

- -
-
- - - - - - - - - - - - {getCurrentPageOrders().map((order) => ( - - - - - - - - ))} - -
- Order ID - - Date - - Total Amount - - Payment Status - - Actions -
- {order.id} - - {order.date} - - ${order.totalAmount.toFixed(2)} - - - {order.paymentStatus} - - - -
-
- - {/* Pagination */} -
-
- - -
-
-
-

- Showing{" "} - - {(currentPage - 1) * ordersPerPage + 1} - {" "} - to{" "} - - {Math.min(currentPage * ordersPerPage, dummyOrders.length)} - {" "} - of {dummyOrders.length}{" "} - results -

-
-
- -
-
-
-
- - {selectedOrder && ( - setSelectedOrder(null)} - /> - )} -
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/ProductForm.jsx b/frontend/src/AgroShopAI/components/Pages/ProductForm.jsx deleted file mode 100644 index 492e78d2..00000000 --- a/frontend/src/AgroShopAI/components/Pages/ProductForm.jsx +++ /dev/null @@ -1,202 +0,0 @@ -// ProductForm.js -import React, { useState } from 'react' - -export default function ProductForm({ selectedProduct, isCreating, isEditing, handleSubmit }) { - const [product, setProduct] = useState(selectedProduct) - const [errors, setErrors] = useState({}) - - const handleInputChange = (e) => { - const { name, value } = e.target - setProduct(prev => ({ - ...prev, - [name]: name === 'price' || name === 'stockQuantity' ? parseFloat(value) : value - })) - setErrors(prev => ({ ...prev, [name]: '' })) - } - - const handleImageUpload = (e) => { - if (e.target.files) { - const newImages = Array.from(e.target.files).map(file => URL.createObjectURL(file)) - setProduct(prev => ({ - ...prev, - images: [...prev.images, ...newImages] - })) - } - } - - const removeImage = (index) => { - const newImages = product.images.filter((_, i) => i !== index) - setProduct(prev => ({ - ...prev, - images: newImages - })) - } - - const validateForm = () => { - const newErrors = {} - if (!product.name) newErrors.name = 'Product name is required' - if (!product.category) newErrors.category = 'Category is required' - if (product.price <= 0) newErrors.price = 'Price must be greater than 0' - if (!product.description) newErrors.description = 'Description is required' - if (!product.sku) newErrors.sku = 'SKU is required' - if (product.stockQuantity < 0) newErrors.stockQuantity = 'Stock quantity cannot be negative' - - setErrors(newErrors) - return Object.keys(newErrors).length === 0 - } - - const onSubmit = (e) => { - e.preventDefault() - if (!validateForm()) return - handleSubmit(product) - } - - return ( -
-

- {isCreating ? 'Create New Product' : 'Edit Product'} -

-
-
- - - {errors.name &&

{errors.name}

} -
- -
- - - {errors.category &&

{errors.category}

} -
- -
- - - {errors.price &&

{errors.price}

} -
- -
- - - {errors.description &&

{errors.description}

} -
- -
- - - {errors.sku &&

{errors.sku}

} -
- -
- - - {errors.stockQuantity &&

{errors.stockQuantity}

} -
- -
- - -
- -
- {selectedProduct.images.map((image, index) => ( -
- {`Product - -
- ))} -
- -
- - -
-
-
- ) -} diff --git a/frontend/src/AgroShopAI/components/Pages/ProductList.jsx b/frontend/src/AgroShopAI/components/Pages/ProductList.jsx deleted file mode 100644 index aec40dcc..00000000 --- a/frontend/src/AgroShopAI/components/Pages/ProductList.jsx +++ /dev/null @@ -1,39 +0,0 @@ -// ProductList.js -import React from 'react' - -export default function ProductList({ products, handleSelectProduct, handleCreateNewProduct }) { - return ( -
-
-

Product List

- -
-
-
    - {products.map(product => ( -
  • -
    - {product.name} -
    -

    {product.name}

    -

    ${product.price.toFixed(2)} - Stock: {product.stockQuantity}

    -
    -
    - -
  • - ))} -
-
-
- ) -} diff --git a/frontend/src/AgroShopAI/components/Pages/ProductManagement.jsx b/frontend/src/AgroShopAI/components/Pages/ProductManagement.jsx deleted file mode 100644 index c00dc2c0..00000000 --- a/frontend/src/AgroShopAI/components/Pages/ProductManagement.jsx +++ /dev/null @@ -1,114 +0,0 @@ -// AdminProductManagement.js -import React, { useState } from 'react' -import ProductList from './ProductList' -import ProductForm from './ProductForm' - -const dummyProducts = [ - { - id: '1', - name: 'Organic Apples', - category: 'fruits', - price: 2.99, - description: 'Fresh, juicy organic apples from local farms.', - sku: 'APP001', - stockQuantity: 100, - images: ['/placeholder.svg?height=150&width=150', '/placeholder.svg?height=150&width=150'] - }, - { - id: '2', - name: 'Farm Fresh Eggs', - category: 'dairy', - price: 4.50, - description: 'Free-range eggs from happy chickens.', - sku: 'EGG002', - stockQuantity: 50, - images: ['/placeholder.svg?height=150&width=150'] - }, - { - id: '3', - name: 'Organic Carrots', - category: 'vegetables', - price: 1.99, - description: 'Crunchy and sweet organic carrots.', - sku: 'CAR003', - stockQuantity: 200, - images: ['/placeholder.svg?height=150&width=150'] - } -] - -export default function AdminProductManagement() { - const [products, setProducts] = useState(dummyProducts) - const [selectedProduct, setSelectedProduct] = useState(null) - const [isEditing, setIsEditing] = useState(false) - const [isCreating, setIsCreating] = useState(false) - - const handleSelectProduct = (product) => { - setSelectedProduct(product) - setIsEditing(true) - setIsCreating(false) - } - - const handleCreateNewProduct = () => { - setSelectedProduct({ - id: `NEW${Date.now()}`, // Generate new unique ID - name: '', - category: '', - price: 0, - description: '', - sku: '', - stockQuantity: 0, - images: [] - }) - setIsCreating(true) - setIsEditing(false) - } - - const handleSubmit = (product) => { - if (isCreating) { - setProducts([...products, product]) - } else { - const updatedProducts = products.map(p => - p.id === product.id ? product : p - ) - setProducts(updatedProducts) - } - setIsEditing(false) - setIsCreating(false) - setSelectedProduct(null) - } - - return ( -
-
-
-

AgroShop Admin

-

Product Management Dashboard

-
- -
- {/* Product List */} - - - {/* Product Edit/Create Form */} - {(isEditing || isCreating) && selectedProduct && ( - - )} -
- {/* Flashy Banner */} -
-

Boost Your Agricultural Business!

-

Manage your products efficiently with AgroShop's powerful admin tools.

-
-
-
- ) -} diff --git a/frontend/src/AgroShopAI/components/Pages/ReturnPage.jsx b/frontend/src/AgroShopAI/components/Pages/ReturnPage.jsx deleted file mode 100644 index 16d8de78..00000000 --- a/frontend/src/AgroShopAI/components/Pages/ReturnPage.jsx +++ /dev/null @@ -1,148 +0,0 @@ -import { useState } from "react"; -import ReturnHeader from "./components/ReturnAdminHeader"; -import ReturnFilter from "./components/ReturnAdminFilter"; -import ReturnProductCard from "./components/ReturnAdminProductCard"; -import ReturnModal from "./components/ReturnAdminModal"; -import ReturnHistory from "./components/ReturnAdminHistory"; - -export default function ReturnPage() { - const [products, setProducts] = useState(dummyProducts); - const [selectedProduct, setSelectedProduct] = useState(null); - const [isModalOpen, setIsModalOpen] = useState(false); - const [returnDate, setReturnDate] = useState(""); - const [condition, setCondition] = useState("Good"); - const [comment, setComment] = useState(""); - const [filter, setFilter] = useState("All"); - const [history, setHistory] = useState([]); - const [sortOption, setSortOption] = useState("Name"); - - const handleReturn = (product) => { - setSelectedProduct(product); - setIsModalOpen(true); - }; - - const handleSubmitReturn = (e) => { - e.preventDefault(); - const updatedProducts = products.map((p) => - p.id === selectedProduct.id ? { ...p, status: "Pending" } : p - ); - setProducts(updatedProducts); - setIsModalOpen(false); - setSelectedProduct(null); - setReturnDate(""); - setCondition("Good"); - setComment(""); - setHistory([ - ...history, - { ...selectedProduct, returnDate: new Date().toLocaleString(), comment }, - ]); - }; - - const handleSort = (option) => { - setSortOption(option); - const sortedProducts = [...products].sort((a, b) => { - if (option === "Name") return a.name.localeCompare(b.name); - if (option === "Start Date") - return new Date(a.startDate) - new Date(b.startDate); - if (option === "End Date") - return new Date(a.endDate) - new Date(b.endDate); - return 0; - }); - setProducts(sortedProducts); - }; - - const filteredProducts = - filter === "All" ? products : products.filter((p) => p.status === filter); - - return ( -
- -
-
-

- Return Rented Equipment -

- -
-
- - -
-
- {filteredProducts.map((product) => ( - - ))} -
- -
- -
- ); -} - -const dummyProducts = [ - { - id: 1, - user: { name: "John Doe", email: "john@example.com", phone: "+1234567890" }, - orderId: "ORD-001", - product: { name: "Organic Fertilizer", quantity: 2, price: 29.99 }, - reason: "Received wrong product", - submissionDate: "2023-06-01", - status: "pending", - comments: [], - }, - { - id: 2, - user: { - name: "Jane Smith", - email: "jane@example.com", - phone: "+1987654321", - }, - orderId: "ORD-002", - product: { name: "Heirloom Tomato Seeds", quantity: 1, price: 14.99 }, - reason: "Product damaged during shipping", - submissionDate: "2023-05-28", - status: "approved", - comments: ["Approved for return. Please send return label to customer."], - }, - { - id: 3, - user: { - name: "Bob Johnson", - email: "bob@example.com", - phone: "+1122334455", - }, - orderId: "ORD-003", - product: { name: "Drip Irrigation Kit", quantity: 1, price: 89.99 }, - reason: "Changed mind", - submissionDate: "2023-05-25", - status: "rejected", - comments: ["Return window has expired."], - }, -]; diff --git a/frontend/src/AgroShopAI/components/Pages/SellerDashboard.jsx b/frontend/src/AgroShopAI/components/Pages/SellerDashboard.jsx deleted file mode 100644 index 801d0966..00000000 --- a/frontend/src/AgroShopAI/components/Pages/SellerDashboard.jsx +++ /dev/null @@ -1,115 +0,0 @@ -import React, { useState } from "react"; -import Header from "./components/Sellerheader"; -import Nav from "./components/SellerNav"; -import SellerDashboardPage from "./components/SellerDashboardPage"; -import SellerProductManagementPage from "./components/SellerProductManagementPage"; -import SellerOrderManagementPage from "./components/SellerOrderManagementPage"; -import SellerAnalyticsPage from "./components/SellerAnalyticsPage"; -import SellerSettingsPage from "./components/SellerSettingsPage"; - -export default function SellerAccountPage() { - const [activeTab, setActiveTab] = useState("dashboard"); - const [products, setProducts] = useState(initialProducts); - const [orders] = useState(initialOrders); - const [searchTerm, setSearchTerm] = useState(""); - const [expandedProduct, setExpandedProduct] = useState(null); - - const filteredProducts = products.filter((product) => - product.name.toLowerCase().includes(searchTerm.toLowerCase()) - ); - - const handleAddProduct = () => { - const newProduct = { - id: products.length + 1, - name: "New Product", - price: 0, - stock: 0, - }; - setProducts([...products, newProduct]); - }; - - const handleDeleteProduct = (id) => { - setProducts(products.filter((product) => product.id !== id)); - }; - - const toggleProductExpansion = (id) => { - setExpandedProduct(expandedProduct === id ? null : id); - }; - - return ( -
-
-
- ); -} - -const sellerInfo = { - name: "Ravi Singh", - storeName: "Swaraj Krishi Udyog", - email: "contact@swarajkrishi.com", - joinDate: "July 8, 2023", - sellerId: "S99887", - location: "Madhya Pradesh, India", - phone: "(91) 98765 43210", - returnPolicy: "We take pride in the quality of our products. If you are not satisfied with your order, please contact us within 24 hours of receipt. We will gladly replace the items or issue a full refund. Due to the perishable nature of our products, returns are not accepted, but we will ensure your satisfaction with the purchase.", - shippingPolicy: "We offer free shipping on orders over ₹2000. Most orders are processed and shipped within 2-3 business days. During peak harvest seasons, this may extend to 4-5 days. We currently ship across India, with delivery times depending on the location.", - paymentMethods: ["Credit Card", "UPI", "Amazon Pay"], - profilePicture: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTlie4MsQ9pJSSKY7DoEpxn3uBAq-rT7in1sA&s', - tagline: "Farm Fresh, Straight from the Fields", - sellerType: "Business", - customerService: "Monday-Saturday, 9AM-6PM IST", - socialMedia: { - facebook: "https://facebook.com/swarajkrishi", - instagram: "https://instagram.com/swarajkrishi", - twitter: "https://twitter.com/swarajkrishi", - }, - about: "Swaraj Krishi Udyog is a family-run agricultural enterprise located in the heart of Madhya Pradesh, India. We specialize in a wide range of organic fruits, vegetables, and grains, cultivated using sustainable farming practices. Our mission is to promote healthy living by offering fresh, organic produce while contributing to a greener, cleaner environment.", - - policies: { - shipping: "We offer free shipping on orders over ₹2000. Most orders are processed and shipped within 2-3 business days. During peak harvest seasons, this may extend to 4-5 days. We currently ship across India, with delivery times depending on the location.", - returns: "We take pride in the quality of our products. If you are not satisfied with your order, please contact us within 24 hours of receipt. We will gladly replace the items or issue a full refund. Due to the perishable nature of our products, returns are not accepted, but we will ensure your satisfaction with the purchase.", - support: "Customer support is available Monday to Saturday, 9 AM to 6 PM IST. You can reach us via email at support@swarajkrishi.com or by phone at (91) 98765 43210. We aim to respond to all queries within 24 hours." - } -}; - - -const initialProducts = [ - { id: 1, name: "Organic Tomatoes", price: 2.99, stock: 100 }, - { id: 2, name: "Fresh Lettuce", price: 1.99, stock: 50 }, - { id: 3, name: "Free-range Eggs", price: 3.99, stock: 200 }, -]; - -const initialOrders = [ - { id: 1, date: "2024-03-01", status: "Shipped", total: 29.99 }, - { id: 2, date: "2024-02-28", status: "Processing", total: 15.99 }, - { id: 3, date: "2024-02-27", status: "Delivered", total: 45.99 }, -]; diff --git a/frontend/src/AgroShopAI/components/Pages/StoryCard.jsx b/frontend/src/AgroShopAI/components/Pages/StoryCard.jsx deleted file mode 100644 index d7b861ec..00000000 --- a/frontend/src/AgroShopAI/components/Pages/StoryCard.jsx +++ /dev/null @@ -1,25 +0,0 @@ -function StoryCard({ story, onClick }) { - return ( -
- {story.name} -
-

{story.name}

-

{story.location}

-

- {story.cropType} | {story.technology} -

-

{story.summary}

- -
-
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/StoryHeader.jsx b/frontend/src/AgroShopAI/components/Pages/StoryHeader.jsx deleted file mode 100644 index 8ecd9712..00000000 --- a/frontend/src/AgroShopAI/components/Pages/StoryHeader.jsx +++ /dev/null @@ -1,9 +0,0 @@ -function Header() { - return ( -
-
-

Farmer Success Stories

-
-
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/StoryModal.jsx b/frontend/src/AgroShopAI/components/Pages/StoryModal.jsx deleted file mode 100644 index 70fd23fb..00000000 --- a/frontend/src/AgroShopAI/components/Pages/StoryModal.jsx +++ /dev/null @@ -1,21 +0,0 @@ -function StoryModal({ story, onClose }) { - return ( -
-
-

{story.name}'s Story

- {story.name} -

{story.fullStory}

- -
-
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/StorySearchBar.jsx b/frontend/src/AgroShopAI/components/Pages/StorySearchBar.jsx deleted file mode 100644 index e98e71f5..00000000 --- a/frontend/src/AgroShopAI/components/Pages/StorySearchBar.jsx +++ /dev/null @@ -1,13 +0,0 @@ -function SearchBar({ searchTerm, setSearchTerm }) { - return ( -
- setSearchTerm(e.target.value)} - value={searchTerm} - /> -
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/THeader.jsx b/frontend/src/AgroShopAI/components/Pages/THeader.jsx deleted file mode 100644 index c1080388..00000000 --- a/frontend/src/AgroShopAI/components/Pages/THeader.jsx +++ /dev/null @@ -1,31 +0,0 @@ -import { useEffect, useState } from "react"; - -const Header = () => { - const [isHovering, setIsHovering] = useState(false); - - // Hover effect to create visual interaction - const handleMouseEnter = () => setIsHovering(true); - const handleMouseLeave = () => setIsHovering(false); - - return ( -
-
-

- AgroShop Admin - Ticket Management -

-

- Manage tickets efficiently and provide exceptional service. -

-
-
- ); -}; - -export default Header; diff --git a/frontend/src/AgroShopAI/components/Pages/TSearchAndFilter.jsx b/frontend/src/AgroShopAI/components/Pages/TSearchAndFilter.jsx deleted file mode 100644 index ef371cb7..00000000 --- a/frontend/src/AgroShopAI/components/Pages/TSearchAndFilter.jsx +++ /dev/null @@ -1,43 +0,0 @@ -const SearchAndFilter = ({ - searchTerm, - setSearchTerm, - statusFilter, - setStatusFilter, - priorityFilter, - setPriorityFilter, -}) => ( -
-

Search and Filter

-
- setSearchTerm(e.target.value)} - /> - - -
-
-); - -export default SearchAndFilter; diff --git a/frontend/src/AgroShopAI/components/Pages/TicketDetailModal.jsx b/frontend/src/AgroShopAI/components/Pages/TicketDetailModal.jsx deleted file mode 100644 index de963499..00000000 --- a/frontend/src/AgroShopAI/components/Pages/TicketDetailModal.jsx +++ /dev/null @@ -1,46 +0,0 @@ -import React from "react"; - -export default function TicketDetailModal({ - selectedTicket, - setSelectedTicket, -}) { - return ( - selectedTicket && ( -
-
-
-

- Ticket Details -

-
-

- ID: {selectedTicket.id} -
- Subject: {selectedTicket.subject} -
- Status: {selectedTicket.status} -
- Priority: {selectedTicket.priority} -
- Description: {selectedTicket.description} -
- Created At: {selectedTicket.createdAt} -
- Agent: {selectedTicket.agent} -

-
- -
-
-
- ) - ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/TicketFilters.jsx b/frontend/src/AgroShopAI/components/Pages/TicketFilters.jsx deleted file mode 100644 index c9440fca..00000000 --- a/frontend/src/AgroShopAI/components/Pages/TicketFilters.jsx +++ /dev/null @@ -1,42 +0,0 @@ -import React from "react"; - -export default function TicketFilters({ - filterStatus, - setFilterStatus, - filterPriority, - setFilterPriority, - searchTerm, - setSearchTerm, -}) { - return ( -
- - - setSearchTerm(e.target.value)} - className="rounded-md border-gray-300 shadow-sm focus:border-green-500 focus:ring-green-500" - /> -
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/TicketForm.jsx b/frontend/src/AgroShopAI/components/Pages/TicketForm.jsx deleted file mode 100644 index 434e10f6..00000000 --- a/frontend/src/AgroShopAI/components/Pages/TicketForm.jsx +++ /dev/null @@ -1,104 +0,0 @@ -import React, { useState } from "react"; - -export default function TicketForm({ - newTicket, - handleInputChange, - handleSubmit, -}) { - const [selectedFile, setSelectedFile] = useState(null); // To store the selected file - - const handleFileChange = (e) => { - const file = e.target.files[0]; // Get the first file selected by the user - if (file) { - setSelectedFile(file); // Store the file in state - } - }; - - return ( -
-

- Create New Support Ticket -

-
-
- - -
-
- - -
-
- - -
-
- - - {selectedFile && ( -
- Selected File: {selectedFile.name} -
- )} -
- -
-
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/TicketList.jsx b/frontend/src/AgroShopAI/components/Pages/TicketList.jsx deleted file mode 100644 index bf084ca7..00000000 --- a/frontend/src/AgroShopAI/components/Pages/TicketList.jsx +++ /dev/null @@ -1,60 +0,0 @@ -import React from "react"; - -export default function TicketList({ filteredTickets, setSelectedTicket }) { - return ( -
- - - - - - - - - - - - - {filteredTickets.map((ticket) => ( - setSelectedTicket(ticket)} - className="cursor-pointer hover:bg-gray-50" - > - - - - - - - - ))} - -
- ID - - Subject - - Status - - Priority - - Agent - - Created At -
- {ticket.id} - - {ticket.subject} - - {ticket.status} - - {ticket.priority} - - {ticket.agent} - - {ticket.createdAt} -
-
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/TicketUser.jsx b/frontend/src/AgroShopAI/components/Pages/TicketUser.jsx deleted file mode 100644 index 6a239a47..00000000 --- a/frontend/src/AgroShopAI/components/Pages/TicketUser.jsx +++ /dev/null @@ -1,95 +0,0 @@ -import React, { useState, useEffect } from "react"; -import TicketForm from "./TicketForm"; -import ConfirmationMessage from "./ConfirmationMessage"; -import TicketFilters from "./TicketFilters"; -import TicketList from "./TicketList"; -import TicketDetailModal from "./TicketDetailModal"; -import HeaderBanner from "./Ticketbanner"; -// Dummy ticket data -const dummyTickets = [ - { id: 'T001', subject: 'Order Delay', status: 'Open', priority: 'High', agent: 'John Doe', createdAt: '2023-05-10 09:30' }, - { id: 'T002', subject: 'Product Inquiry', status: 'In-Progress', priority: 'Medium', agent: 'Jane Smith', createdAt: '2023-05-09 14:15' }, - { id: 'T003', subject: 'Refund Request', status: 'Resolved', priority: 'Low', agent: 'Mike Johnson', createdAt: '2023-05-08 11:45' }, -]; - -export default function SupportPage() { - const [newTicket, setNewTicket] = useState({ - subject: "", - description: "", - priority: "Low", - }); - const [showConfirmation, setShowConfirmation] = useState(false); - const [newTicketId, setNewTicketId] = useState(null); - const [filterStatus, setFilterStatus] = useState("All"); - const [filterPriority, setFilterPriority] = useState("All"); - const [searchTerm, setSearchTerm] = useState(""); - const [tickets, setTickets] = useState(dummyTickets); // Set initial tickets from dummyTickets - const [selectedTicket, setSelectedTicket] = useState(null); - const [selectedFile, setSelectedFile] = useState(null); // To store the selected file - - const handleInputChange = (e) => { - setNewTicket({ ...newTicket, [e.target.name]: e.target.value }); - }; - - const handleFileChange = (e) => { - const file = e.target.files[0]; - if (file) { - setSelectedFile(file); // Store the selected file in state - } - }; - - const handleSubmit = (e) => { - e.preventDefault(); - const newTicketData = { - ...newTicket, - id: `T${String(tickets.length + 1).padStart(3, '0')}`, // Generate a readable ticket ID - status: "Open", // Default status - agent: "Unassigned", // Placeholder for agent - createdAt: new Date().toLocaleString(), // Current date and time - file: selectedFile, // Attach the file to the new ticket - }; - setTickets([newTicketData, ...tickets]); - setNewTicketId(newTicketData.id); - setShowConfirmation(true); - setNewTicket({ subject: "", description: "", priority: "Low" }); - setSelectedFile(null); // Clear the file after submission - }; - - const filteredTickets = tickets.filter((ticket) => { - const statusMatch = - filterStatus === "All" || ticket.status === filterStatus; - const priorityMatch = - filterPriority === "All" || ticket.priority === filterPriority; - const searchMatch = - ticket.subject.toLowerCase().includes(searchTerm.toLowerCase()) || - ticket.id.toString().includes(searchTerm); - return statusMatch && priorityMatch && searchMatch; - }); - - return ( -
- - - - - - -
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/Ticketbanner.jsx b/frontend/src/AgroShopAI/components/Pages/Ticketbanner.jsx deleted file mode 100644 index 607666ab..00000000 --- a/frontend/src/AgroShopAI/components/Pages/Ticketbanner.jsx +++ /dev/null @@ -1,22 +0,0 @@ -import React from "react"; - -const HeaderBanner = () => { - return ( -
-
-
-

Welcome to Support Center

-

- We're here to help you. Submit your tickets and get fast support! -

-
- -
-
-
- ); -}; - -export default HeaderBanner; diff --git a/frontend/src/AgroShopAI/components/Pages/Trending.jsx b/frontend/src/AgroShopAI/components/Pages/Trending.jsx deleted file mode 100644 index a3b34f2a..00000000 --- a/frontend/src/AgroShopAI/components/Pages/Trending.jsx +++ /dev/null @@ -1,120 +0,0 @@ -import React, { useState } from "react"; -import Header from "./components/THeader"; -import Banner from "./components/Banner"; -import SearchAndSort from "./components/SearchAndSort"; -import ProductGrid from "./components/ProductGrid"; - -export default function TrendingProductsPage() { - const [sortBy, setSortBy] = useState("trending"); - const [searchTerm, setSearchTerm] = useState(""); - const [isLoading, setIsLoading] = useState(false); - - // Filtering products based on search term - const filteredProducts = trendingProducts.filter((product) => - product.name.toLowerCase().includes(searchTerm.toLowerCase()) - ); - - // Sorting products based on selected criteria - const sortedProducts = [...filteredProducts].sort((a, b) => { - if (sortBy === "price") return a.price - b.price; - if (sortBy === "rating") return b.rating - a.rating; - return 0; - }); - - // Simulate loading state - const fetchData = async () => { - setIsLoading(true); - setTimeout(() => { - setIsLoading(false); - }, 2000); - }; - - React.useEffect(() => { - fetchData(); - }, []); - - return ( -
-
- -
- {/* Search and Sort Component */} - - {/* Loading state and Product Grid */} - {isLoading ? ( -
- Loading... -
- ) : ( - - )} -
-
- ); -} - -const trendingProducts = [ - { - id: 1, - name: "Smart Irrigation System", - price: 299.99, - rating: 4.8, - reviews: 120, - image: - "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTTkXzsfqi9x6H46rC1Ir7k2WEQ1V0lVv8ONA&s", - tag: "Trending Now", - }, - { - id: 2, - name: "Organic Fertilizer Pack", - price: 49.99, - rating: 4.5, - reviews: 85, - image: "https://m.media-amazon.com/images/I/91Y3l-BVm-L.jpg", - tag: "Hot Deal", - }, - { - id: 3, - name: "Drone Crop Sprayer", - price: 1299.99, - rating: 4.9, - reviews: 200, - image: - "https://5.imimg.com/data5/ANDROID/Default/2022/4/AA/WY/ED/14166347/product-jpeg-500x500.jpg", - tag: "Top Rated", - }, - { - id: 4, - name: "Soil pH Tester", - price: 29.99, - rating: 4.2, - reviews: 60, - image: "https://m.media-amazon.com/images/I/71933Pfn55L.jpg", - tag: "Trending Now", - }, - { - id: 5, - name: "Hydroponic Growing Kit", - price: 199.99, - rating: 4.7, - reviews: 150, - image: - "https://m.media-amazon.com/images/I/81n3GQOCOQL._AC_UF1000,1000_QL80_.jpg", - tag: "Hot Deal", - }, - { - id: 6, - name: "Weather Station", - price: 149.99, - rating: 4.6, - reviews: 95, - image: - "https://5.imimg.com/data5/YN/KT/YB/SELLER-5098190/weather-station.jpg", - tag: "Top Rated", - }, -]; diff --git a/frontend/src/AgroShopAI/components/Pages/WareInventoryTable.jsx b/frontend/src/AgroShopAI/components/Pages/WareInventoryTable.jsx deleted file mode 100644 index 0cc33213..00000000 --- a/frontend/src/AgroShopAI/components/Pages/WareInventoryTable.jsx +++ /dev/null @@ -1,78 +0,0 @@ -// InventoryTable.js -import React from 'react'; - -export default function InventoryTable({ - filteredInventory, - selectedItems, - toggleSelectAll, - handleSort, - handleEdit, - handleDelete, - setSelectedItems -}) { - return ( -
- - - - - - - - - - - - - - - {filteredInventory.map(item => ( - - - - - - - - - - - ))} - -
- - handleSort('sku')}>SKU handleSort('name')}>Product Name handleSort('stock')}>Stock handleSort('category')}>Category handleSort('seller')}>Seller handleSort('location')}>LocationActions
- { - if (selectedItems.includes(item.id)) { - setSelectedItems(selectedItems.filter(id => id !== item.id)); - } else { - setSelectedItems([...selectedItems, item.id]); - } - }} - /> - {item.sku}{item.name}{item.stock}{item.category}{item.seller}{item.location} - - -
-
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/WareSearchAndFilter.jsx b/frontend/src/AgroShopAI/components/Pages/WareSearchAndFilter.jsx deleted file mode 100644 index e805ad55..00000000 --- a/frontend/src/AgroShopAI/components/Pages/WareSearchAndFilter.jsx +++ /dev/null @@ -1,52 +0,0 @@ - -import React from 'react'; - -export default function SearchAndFilter({ - searchTerm, - setSearchTerm, - filterCategory, - setFilterCategory, - setShowUploadModal, - selectedItems, - handleBulkDelete, -}) { - return ( -
-
- setSearchTerm(e.target.value)} - /> -
- - - {selectedItems.length > 0 && ( - - )} -
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/components/AboutUsSection.jsx b/frontend/src/AgroShopAI/components/Pages/components/AboutUsSection.jsx deleted file mode 100644 index 05e8a3aa..00000000 --- a/frontend/src/AgroShopAI/components/Pages/components/AboutUsSection.jsx +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react'; - -export default function AboutUsSection({ sellerData, editMode, handleEdit, handleSave, handleChange }) { - return ( -
-

About Us

- {editMode.about ? ( -
- -
-
- - -
- -
- - ); -} - -export default ReturnModal; diff --git a/frontend/src/AgroShopAI/components/Pages/components/ReturnPage.jsx b/frontend/src/AgroShopAI/components/Pages/components/ReturnPage.jsx deleted file mode 100644 index c3abda42..00000000 --- a/frontend/src/AgroShopAI/components/Pages/components/ReturnPage.jsx +++ /dev/null @@ -1,182 +0,0 @@ - -import React, { useState } from 'react' - - - -export default function ReturnPanel() { - const [requests, setRequests] = useState(dummyRequests) - const [filterStatus, setFilterStatus] = useState('all') - const [sortBy, setSortBy] = useState('date') - const [newComment, setNewComment] = useState('') - - const filteredRequests = requests.filter(request => - filterStatus === 'all' ? true : request.status === filterStatus - ).sort((a, b) => - sortBy === 'date' - ? new Date(b.submissionDate).getTime() - new Date(a.submissionDate).getTime() - : a.status.localeCompare(b.status) - ) - - const handleStatusChange = (id, newStatus) => { - setRequests(requests.map(request => - request.id === id ? { ...request, status: newStatus } : request - )) - } - - const handleAddComment = (id) => { - if (newComment.trim()) { - setRequests(requests.map(request => - request.id === id - ? { ...request, comments: [...request.comments, newComment.trim()] } - : request - )) - setNewComment('') - } - } - - return ( -
-

AgroShop Return Panel

- -
-
- - -
-
- - -
-
- - {filteredRequests.map(request => ( -
-
-
-

{request.user.name}

-

{request.user.email} | {request.user.phone}

-
- - {request.status.charAt(0).toUpperCase() + request.status.slice(1)} - -
- -
-

Order ID: {request.orderId}

-

Product: {request.product.name}

-

Quantity: {request.product.quantity}

-

Price: ${request.product.price.toFixed(2)}

-

Reason: {request.reason}

-

Submission Date: {request.submissionDate}

-
- -
-

Comments:

- {request.comments.map((comment, index) => ( -

{comment}

- ))} -
- setNewComment(e.target.value)} - /> - -
-
- -
- {request.status === 'pending' && ( - <> - - - - )} - {request.status === 'approved' && ( - - )} -
-
- ))} -
- ) -} - - -const dummyRequests = [ - { - id: 1, - user: { name: 'John Doe', email: 'john@example.com', phone: '+1234567890' }, - orderId: 'ORD-001', - product: { name: 'Organic Fertilizer', quantity: 2, price: 29.99 }, - reason: 'Received wrong product', - submissionDate: '2023-06-01', - status: 'pending', - comments: [] - }, - { - id: 2, - user: { name: 'Jane Smith', email: 'jane@example.com', phone: '+1987654321' }, - orderId: 'ORD-002', - product: { name: 'Heirloom Tomato Seeds', quantity: 1, price: 14.99 }, - reason: 'Product damaged during shipping', - submissionDate: '2023-05-28', - status: 'approved', - comments: ['Approved for return. Please send return label to customer.'] - }, - { - id: 3, - user: { name: 'Bob Johnson', email: 'bob@example.com', phone: '+1122334455' }, - orderId: 'ORD-003', - product: { name: 'Drip Irrigation Kit', quantity: 1, price: 89.99 }, - reason: 'Changed mind', - submissionDate: '2023-05-25', - status: 'rejected', - comments: ['Return window has expired.'] - } - ] \ No newline at end of file diff --git a/frontend/src/AgroShopAI/components/Pages/components/ReturnProductCard.jsx b/frontend/src/AgroShopAI/components/Pages/components/ReturnProductCard.jsx deleted file mode 100644 index fb87ff48..00000000 --- a/frontend/src/AgroShopAI/components/Pages/components/ReturnProductCard.jsx +++ /dev/null @@ -1,38 +0,0 @@ -function ReturnProductCard({ product, handleReturn }) { - return ( -
- {product.name} -

{product.name}

-

Model: {product.model}

-

Start: {product.startDate}

-

End: {product.endDate}

-
- - {product.status} - - {product.status === "Eligible" && ( - - )} -
-
- ); -} - -export default ReturnProductCard; diff --git a/frontend/src/AgroShopAI/components/Pages/components/SalePage.jsx b/frontend/src/AgroShopAI/components/Pages/components/SalePage.jsx deleted file mode 100644 index 5344e57d..00000000 --- a/frontend/src/AgroShopAI/components/Pages/components/SalePage.jsx +++ /dev/null @@ -1,187 +0,0 @@ -import React, { useState, useEffect } from "react"; -import FlashSaleHeader from "./FlashSaleHeader"; -import Filter from "./Filter"; -import ProductList from "./ProductList"; -import QuickBuyModal from "./QuickBuyModal"; - -const flashSaleEndTime = new Date(Date.now() + 6 * 60 * 60 * 1000); - -export default function FlashSale() { - const [timeLeft, setTimeLeft] = useState(getTimeLeft(flashSaleEndTime)); - const [filteredProducts, setFilteredProducts] = useState(products); - const [filterCriteria, setFilterCriteria] = useState({}); - const [modalOpen, setModalOpen] = useState(false); - const [selectedProduct, setSelectedProduct] = useState(null); - - useEffect(() => { - const timer = setInterval(() => { - setTimeLeft(getTimeLeft(flashSaleEndTime)); - }, 1000); - - return () => clearInterval(timer); - }, []); - - useEffect(() => { - applyFilters(); - }, [filterCriteria]); - - function applyFilters() { - const { - name, - brand, - priceRange = { min: 0, max: Infinity }, - timeLeft, - } = filterCriteria; - - const filtered = products.filter((product) => { - const timeRemaining = getTimeLeft(product.endTime).hours; - - return ( - (!name || product.name.toLowerCase().includes(name.toLowerCase())) && - (!brand || product.brand.toLowerCase().includes(brand.toLowerCase())) && - (priceRange.min === undefined || - product.discountedPrice >= priceRange.min) && - (priceRange.max === undefined || - product.discountedPrice <= priceRange.max) && - (!timeLeft || timeRemaining <= timeLeft) - ); - }); - - setFilteredProducts(filtered); - } - - function handleFilterChange(criteria) { - setFilterCriteria(criteria); - } - - function handleQuickBuy(product) { - setSelectedProduct(product); - setModalOpen(true); - } - - function getTimeLeft(endTime) { - const total = Date.parse(endTime) - Date.parse(new Date()); - const seconds = Math.floor((total / 1000) % 60); - const minutes = Math.floor((total / 1000 / 60) % 60); - const hours = Math.floor((total / (1000 * 60 * 60)) % 24); - - return { - total, - hours, - minutes, - seconds, - }; - } - - return ( -
-
-

- Agroshop Flash Sale -

- - - -
- {modalOpen && ( - setModalOpen(false)} - /> - )} -
- ); -} - -const products = [ - { - id: 1, - name: "Compact Tractor", - brand: "FarmPower", - originalPrice: 12999.99, - discountedPrice: 9999.99, // Discounted price not exceeding $10,000 - image: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQEqGgcHg947RkBqvdUu5fKUjko9cg5JZrD7w&s", - endTime: new Date(Date.now() + 5 * 60 * 60 * 1000), // 5 hours from now - }, - { - id: 2, - name: "Electric Lawn Mower", - brand: "EcoMow", - originalPrice: 799.99, - discountedPrice: 699.99, - image: "https://hips.hearstapps.com/hmg-prod/images/pop-electric-lawnmowers-65f34fd591853.jpg?crop=0.502xw:1.00xh;0.383xw,0&resize=640:*", - endTime: new Date(Date.now() + 6 * 60 * 60 * 1000), // 6 hours from now - }, - { - id: 3, - name: "Solar-Powered Water Pump", - brand: "SunFlow", - originalPrice: 249.99, - discountedPrice: 199.99, - image: "https://www.agrisolar.co.nz/wp-content/uploads/2021/07/The-Agri-Solar-XM-500-Surface-Pump-300x300.jpg", - endTime: new Date(Date.now() + 7 * 60 * 60 * 1000), // 7 hours from now - }, - { - id: 4, - name: "Portable Greenhouse", - brand: "GardenPro", - originalPrice: 149.99, - discountedPrice: 129.99, - image: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQYO1Cm2xju9h7s6hR0JJeXJ7927APOj1-slA&s", - endTime: new Date(Date.now() + 8 * 60 * 60 * 1000), // 8 hours from now - }, - { - id: 5, - name: "Hydroponic Grow Kit", - brand: "HydroGrow", - originalPrice: 199.99, - discountedPrice: 149.99, - image: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ2pqUB9FxVdyUKUWeBxln7DvyAgJGNbYMk5w&s", - endTime: new Date(Date.now() + 9 * 60 * 60 * 1000), // 9 hours from now - }, - { - id: 6, - name: "Automatic Seed Planter", - brand: "PlantMate", - originalPrice: 499.99, - discountedPrice: 399.99, - image: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSqZIz4ZcbOrFikJ47pfWWOCxDv5Cy4w_jJhQ&s", - endTime: new Date(Date.now() + 10 * 60 * 60 * 1000), // 10 hours from now - }, - { - id: 7, - name: "Heavy-Duty Compost Bin", - brand: "EcoCycle", - originalPrice: 899.99, - discountedPrice: 699.99, - image: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRKfHvn6iDMjCn8HlV28qOaWZ29bJHW2NGj0A&s", - endTime: new Date(Date.now() + 11 * 60 * 60 * 1000), // 11 hours from now - }, - { - id: 8, - name: "Garden Sprayer", - brand: "SprayMaster", - originalPrice: 129.99, - discountedPrice: 119.99, - image: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQWSPfrgmp8GY0X5f_7ZeYwwk7fCSeCzGAnzQ&s", - endTime: new Date(Date.now() + 12 * 60 * 60 * 1000), // 12 hours from now - }, - { - id: 9, - name: "High-Pressure Washer", - brand: "CleanTech", - originalPrice: 399.99, - discountedPrice: 299.99, - image: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTh2LiQyQ2R-_Y5tZtcaSQMfUCsJA1EHFD27A&s", - endTime: new Date(Date.now() + 13 * 60 * 60 * 1000), // 13 hours from now - }, - { - id: 10, - name: "Garden Tiller", - brand: "TillMaster", - originalPrice: 329.99, - discountedPrice: 279.99, - image: "https://powerequipment.honda.com/-/media/Images/pages/tillers/additional-resources-tiller-shopping.jpg", - endTime: new Date(Date.now() + 14 * 60 * 60 * 1000), // 14 hours from now - }, -]; diff --git a/frontend/src/AgroShopAI/components/Pages/components/SalesTrend.jsx b/frontend/src/AgroShopAI/components/Pages/components/SalesTrend.jsx deleted file mode 100644 index 8aab23bc..00000000 --- a/frontend/src/AgroShopAI/components/Pages/components/SalesTrend.jsx +++ /dev/null @@ -1,21 +0,0 @@ -import React from 'react'; - -export default function SalesTrend({ data, maxSales }) { - return ( -
-

Sales Trend

- - {data.map((sale, index) => ( - - ))} - -
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/components/SearchAndSort.jsx b/frontend/src/AgroShopAI/components/Pages/components/SearchAndSort.jsx deleted file mode 100644 index 7daa7f2f..00000000 --- a/frontend/src/AgroShopAI/components/Pages/components/SearchAndSort.jsx +++ /dev/null @@ -1,63 +0,0 @@ -import { Search, ChevronDown } from "lucide-react"; - -export default function SearchAndSort({ - searchTerm, - setSearchTerm, - sortBy, - setSortBy, -}) { - return ( -
- {/* Search Input */} -
- - setSearchTerm(e.target.value)} - aria-label="Search products" - /> - -
- - {/* Sort By Dropdown */} -
- - - -
- - {/* Filter Button */} -
- -
-
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/components/SecuritySettings.jsx b/frontend/src/AgroShopAI/components/Pages/components/SecuritySettings.jsx deleted file mode 100644 index d388a5d7..00000000 --- a/frontend/src/AgroShopAI/components/Pages/components/SecuritySettings.jsx +++ /dev/null @@ -1,36 +0,0 @@ -import React, { useState } from 'react'; - -const SecuritySettings = () => { - const [twoFactorAuth, setTwoFactorAuth] = useState(false); - const [changePassword, setChangePassword] = useState(false); - - const handleToggle2FA = () => { - setTwoFactorAuth(!twoFactorAuth); - }; - - const handleChangePassword = () => { - setChangePassword(true); - // Implement password change functionality here - }; - - return ( -
-

Security Settings

-
- -
-
- -
-
- ); -}; - -export default SecuritySettings; diff --git a/frontend/src/AgroShopAI/components/Pages/components/SellerAnalyticsPage.jsx b/frontend/src/AgroShopAI/components/Pages/components/SellerAnalyticsPage.jsx deleted file mode 100644 index 11966cc7..00000000 --- a/frontend/src/AgroShopAI/components/Pages/components/SellerAnalyticsPage.jsx +++ /dev/null @@ -1,12 +0,0 @@ -import React from 'react' - -const SellerAnalyticsPage = () => { - return ( -
-

Analytics

- " Add analytical tools here " -
- ) -} - -export default SellerAnalyticsPage diff --git a/frontend/src/AgroShopAI/components/Pages/components/SellerDashboardPage.jsx b/frontend/src/AgroShopAI/components/Pages/components/SellerDashboardPage.jsx deleted file mode 100644 index 11517b29..00000000 --- a/frontend/src/AgroShopAI/components/Pages/components/SellerDashboardPage.jsx +++ /dev/null @@ -1,62 +0,0 @@ -import React from 'react'; - -const SellerDashboardPage = ({ sellerInfo }) => { - return ( -
- {/* Dashboard Header */} -
-

Dashboard

-

Welcome, {sellerInfo.name}!

-
- - {/* Main Content Container */} -
- - {/* Store Information Section */} -
-

Store Information

-

Store Name: {sellerInfo.storeName}

-

Email: {sellerInfo.email}

-

Join Date: {sellerInfo.joinDate}

-
- - {/* Seller Profile Section */} -
-

Seller Profile

-

Seller ID: {sellerInfo.sellerId}

-

Location: {sellerInfo.location}

-

Phone: {sellerInfo.phone}

-
- - {/* Store Policies Section */} -
-

Store Policies

-

Return Policy: {sellerInfo.returnPolicy}

-

Shipping Policy: {sellerInfo.shippingPolicy}

-

Payment Methods: {sellerInfo.paymentMethods.join(', ')}

-
- - {/* Quick Links Section */} -
-

Quick Links

- -
-
-
- ); -} - -export default SellerDashboardPage; diff --git a/frontend/src/AgroShopAI/components/Pages/components/SellerNav.jsx b/frontend/src/AgroShopAI/components/Pages/components/SellerNav.jsx deleted file mode 100644 index 2f55b79f..00000000 --- a/frontend/src/AgroShopAI/components/Pages/components/SellerNav.jsx +++ /dev/null @@ -1,38 +0,0 @@ -import React from 'react' - -const Nav = ({ activeTab, setActiveTab }) => { - return ( - - ) -} - -export default Nav diff --git a/frontend/src/AgroShopAI/components/Pages/components/SellerOrderManagementPage.jsx b/frontend/src/AgroShopAI/components/Pages/components/SellerOrderManagementPage.jsx deleted file mode 100644 index 3c114aa9..00000000 --- a/frontend/src/AgroShopAI/components/Pages/components/SellerOrderManagementPage.jsx +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react' - -const SellerOrderManagementPage = ({ orders }) => { - return ( -
-

Order Management

- "To be added" - -
- ) -} - -export default SellerOrderManagementPage diff --git a/frontend/src/AgroShopAI/components/Pages/components/SellerProductManagementPage.jsx b/frontend/src/AgroShopAI/components/Pages/components/SellerProductManagementPage.jsx deleted file mode 100644 index 3f5faaff..00000000 --- a/frontend/src/AgroShopAI/components/Pages/components/SellerProductManagementPage.jsx +++ /dev/null @@ -1,76 +0,0 @@ -import React, { useState } from 'react'; -import FeaturedProductsCarousel from './ProductCarousel' -const SellerProductManagementPage = ({ - products, - searchTerm, - setSearchTerm, - handleAddProduct, - handleDeleteProduct, - expandedProduct, - toggleProductExpansion, -}) => { - return ( -
-

Product Management

- - {/* Search and Add Product Section */} -
- setSearchTerm(e.target.value)} - placeholder="Search products" - className="p-3 w-2/3 border border-gray-300 rounded-l-md" - /> - -
- - {/* Product List */} - - -
- ); -} - -export default SellerProductManagementPage; diff --git a/frontend/src/AgroShopAI/components/Pages/components/SellerSettingsPage.jsx b/frontend/src/AgroShopAI/components/Pages/components/SellerSettingsPage.jsx deleted file mode 100644 index 5c635e26..00000000 --- a/frontend/src/AgroShopAI/components/Pages/components/SellerSettingsPage.jsx +++ /dev/null @@ -1,93 +0,0 @@ -import React, { useState } from 'react'; -import ProfileSection from './ProfileSection'; -import AboutUsSection from './AboutUsSection'; -import PolicySection from './PolicySection'; - -export default function SellerSettingPage({ initialSellerData }) { - const [sellerData, setSellerData] = useState(initialSellerData); - const [editMode, setEditMode] = useState({ - info: false, - about: false, - shipping: false, - returns: false, - support: false - }); - - const handleEdit = (section) => { - setEditMode((prev) => ({ ...prev, [section]: !prev[section] })); - }; - - const handleSave = (section) => { - // In a real application, save changes to the backend - setEditMode((prev) => ({ ...prev, [section]: false })); - }; - - const handleChange = (e) => { - const { name, value } = e.target; - setSellerData((prev) => ({ ...prev, [name]: value })); - }; - - const handlePolicyChange = (e, policy) => { - setSellerData((prev) => ({ - ...prev, - policies: { ...prev.policies, [policy]: e.target.value } - })); - }; - - const handleFileChange = (e) => { - const file = e.target.files[0]; - if (file) { - const reader = new FileReader(); - reader.onloadend = () => { - setSellerData((prev) => ({ ...prev, profilePicture: reader.result })); - }; - reader.readAsDataURL(file); - } - }; - - return ( -
- - -
- - - -
-
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/components/Sellerheader.jsx b/frontend/src/AgroShopAI/components/Pages/components/Sellerheader.jsx deleted file mode 100644 index 571acfbb..00000000 --- a/frontend/src/AgroShopAI/components/Pages/components/Sellerheader.jsx +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react' - -const Header = () => { - return ( -
-

Seller Dashboard

-
- ) -} - -export default Header diff --git a/frontend/src/AgroShopAI/components/Pages/components/Sidebar.jsx b/frontend/src/AgroShopAI/components/Pages/components/Sidebar.jsx deleted file mode 100644 index 368b45bf..00000000 --- a/frontend/src/AgroShopAI/components/Pages/components/Sidebar.jsx +++ /dev/null @@ -1,113 +0,0 @@ -import { - ShoppingCart, - MessageSquare, - BarChart2, - Settings, - Users, - TrendingUp, - CornerDownLeft, - FolderKanban -} from "lucide-react"; - -export const Sidebar = ({ onViewChange, activeView }) => { - return ( - - ); -}; diff --git a/frontend/src/AgroShopAI/components/Pages/components/StatCard.jsx b/frontend/src/AgroShopAI/components/Pages/components/StatCard.jsx deleted file mode 100644 index 2d0ad250..00000000 --- a/frontend/src/AgroShopAI/components/Pages/components/StatCard.jsx +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react'; - -export default function StatCard({ title, value, color }) { - return ( -
-

{title}

-

{value}

-
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/components/StatisticComponent.jsx b/frontend/src/AgroShopAI/components/Pages/components/StatisticComponent.jsx deleted file mode 100644 index b19b41a9..00000000 --- a/frontend/src/AgroShopAI/components/Pages/components/StatisticComponent.jsx +++ /dev/null @@ -1,102 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import TimeRangeSelector from './TimeRangeSelector'; -import StatCard from './StatCard'; -import SalesTrend from './SalesTrend'; -import UserRegistrations from './UserRegistrations'; -import PopularProducts from './PopularProducts'; -import Analysis from './Analysis'; - -// Dummy data -const dummyData = { - daily: { - totalUsers: 1000, - activeSellers: 150, - totalSales: 5000, - pendingOrders: 20, - totalProducts: 500, - salesTrend: [100, 120, 80, 140, 90, 160, 130], - popularProducts: [ - { name: 'Pesticides', sales: 50 }, - { name: 'Tomato Seeds', sales: 30 }, - { name: 'Equipment', sales: 20 }, - ], - userRegistrations: [10, 15, 8, 12, 20, 18, 14], - }, - weekly: { - totalUsers: 5000, - activeSellers: 600, - totalSales: 25000, - pendingOrders: 100, - totalProducts: 2000, - salesTrend: [700, 900, 800, 1000, 1200, 950, 1100], - popularProducts: [ - { name: 'Tomato Seeds', sales: 200 }, - { name: 'Fertilizer', sales: 150 }, - { name: 'Pesticides', sales: 100 }, - ], - userRegistrations: [50, 70, 60, 80, 90, 75, 85], - }, - monthly: { - totalUsers: 20000, - activeSellers: 2500, - totalSales: 100000, - pendingOrders: 500, - totalProducts: 8000, - salesTrend: [3000, 3500, 4000, 3800, 4200, 4500, 4300], - popularProducts: [ - { name: 'Fertilizer', sales: 800 }, - { name: 'Insecticide', sales: 600 }, - { name: 'Equipment', sales: 500 }, - ], - userRegistrations: [200, 250, 300, 280, 320, 350, 330], - }, -}; - -export default function StatisticComponent() { - const [timeRange, setTimeRange] = useState('daily'); - const [data, setData] = useState(dummyData.daily); - - useEffect(() => { - setData(dummyData[timeRange]); - }, [timeRange]); - - const analyzeData = () => { - const totalSalesChange = data.salesTrend[data.salesTrend.length - 1] - data.salesTrend[0]; - const userRegistrationChange = data.userRegistrations[data.userRegistrations.length - 1] - data.userRegistrations[0]; - - return { - salesTrend: totalSalesChange > 0 ? 'increasing' : 'decreasing', - userRegistrationTrend: userRegistrationChange > 0 ? 'increasing' : 'decreasing', - topProduct: data.popularProducts[0].name, - }; - }; - - const analysis = analyzeData(); - const maxSales = Math.max(...data.salesTrend); - const maxRegistrations = Math.max(...data.userRegistrations); - - return ( -
-

Admin Dashboard Statistics

- - - -
- - - - - -
- -
- - -
- - - - -
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/components/SuccessPage.jsx b/frontend/src/AgroShopAI/components/Pages/components/SuccessPage.jsx deleted file mode 100644 index 7f0f98cf..00000000 --- a/frontend/src/AgroShopAI/components/Pages/components/SuccessPage.jsx +++ /dev/null @@ -1,113 +0,0 @@ - - -import { useState } from 'react' - -const dummyStories = [ - { - id: 1, - name: "Vivek", - location: "New Delhi, India", - cropType: "Organic Vegetables", - technology: "Hydroponics", - summary: "Increased yield by 40% using hydroponic systems", - fullStory: "John Doe, a third-generation farmer from California, embraced hydroponic technology to grow organic vegetables. Despite initial challenges, he persevered and saw a 40% increase in yield within the first year. His success has inspired many local farmers to adopt sustainable practices.", - image: "https://media.istockphoto.com/id/1166954334/photo/portrait-of-happy-senior-farmer.jpg?s=612x612&w=0&k=20&c=dn2yLIXXkXSWTsv2HdEiJHqSyQhbNT77SHc0dxetUrI=" - }, - { - id: 2, - name: "Maria Garcia", - location: "Andalusia, Spain", - cropType: "Olive Trees", - technology: "Precision Agriculture", - summary: "Reduced water usage by 30% with precision irrigation", - fullStory: "Maria Garcia, an olive farmer from Andalusia, implemented precision agriculture techniques to optimize her irrigation systems. By using soil sensors and weather data, she reduced water usage by 30% while maintaining high-quality olive production. Her story showcases the power of technology in preserving traditional farming practices.", - image: "https://st5.depositphotos.com/4435155/66403/i/1600/depositphotos_664032036-stock-photo-portrait-female-farmer-who-cultivating.jpg" - }, - { - id: 3, - name: "Raj Patel", - location: "Gujarat, India", - cropType: "Cotton", - technology: "Organic Farming", - summary: "Transitioned to organic cotton, increasing profit margins", - fullStory: "Raj Patel, a cotton farmer from Gujarat, made the bold decision to transition to organic farming methods. Despite initial yield reductions, he persevered and saw increased profit margins due to premium pricing for organic cotton. His success has led to a community-wide shift towards sustainable farming practices in his region.", - image: "https://img.etimg.com/thumb/width-420,height-315,imgsize-23777,resizemode-75,msid-13090201/opinion/interviews/science-of-food-is-hijacked-to-highest-bidder-raj-patel/new-section/raj-patel.jpg" - } -] - -export default function FarmerSuccessStories() { - const [searchTerm, setSearchTerm] = useState('') - const [selectedStory, setSelectedStory] = useState(null) - - const filteredStories = dummyStories.filter(story => - story.name.toLowerCase().includes(searchTerm.toLowerCase()) || - story.location.toLowerCase().includes(searchTerm.toLowerCase()) || - story.cropType.toLowerCase().includes(searchTerm.toLowerCase()) || - story.technology.toLowerCase().includes(searchTerm.toLowerCase()) - ) - - return ( -
-
-
-

Farmer Success Stories

-
-
- -
-
-

- Discover inspiring stories of farmers who have embraced sustainable practices and innovative technologies to transform their agricultural journey. -

-
- -
- setSearchTerm(e.target.value)} - /> -
- -
- {filteredStories.map(story => ( -
- {story.name} -
-

{story.name}

-

{story.location}

-

{story.cropType} | {story.technology}

-

{story.summary}

- -
-
- ))} -
-
- - {selectedStory && ( -
-
-

{selectedStory.name}'s Story

- {selectedStory.name} -

{selectedStory.fullStory}

- -
-
- )} - - -
- ) -} \ No newline at end of file diff --git a/frontend/src/AgroShopAI/components/Pages/components/THeader.jsx b/frontend/src/AgroShopAI/components/Pages/components/THeader.jsx deleted file mode 100644 index 1e34520c..00000000 --- a/frontend/src/AgroShopAI/components/Pages/components/THeader.jsx +++ /dev/null @@ -1,32 +0,0 @@ -export default function Header() { - return ( -
-
- {/* Logo and Title */} -
- AgroShop Logo -

AgroShop

-
- - {/* Navigation Links */} - - - {/* Mobile Menu Button */} -
- -
-
-
- ) -} diff --git a/frontend/src/AgroShopAI/components/Pages/components/TProductCard.jsx b/frontend/src/AgroShopAI/components/Pages/components/TProductCard.jsx deleted file mode 100644 index c9d405a3..00000000 --- a/frontend/src/AgroShopAI/components/Pages/components/TProductCard.jsx +++ /dev/null @@ -1,59 +0,0 @@ -import { Star } from "lucide-react"; - -export default function ProductCard({ product }) { - return ( -
- {/* Product Image and Tag */} -
- {product.name} - - {product.tag} - -
- - {/* Product Details */} -
-
-

- {product.name} -

- - {product.stock} in stock - -
- - {/* Rating and Reviews */} -
- - - {product.rating} - - - ({product.reviews} reviews) - -
- - {/* Price */} -

- ${product.price.toFixed(2)} -

- - {/* Add to Cart Button */} - -
- - {/* Hover Effect */} -
- - Free shipping on orders over $50! - -
-
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/components/TabNav.jsx b/frontend/src/AgroShopAI/components/Pages/components/TabNav.jsx deleted file mode 100644 index 4177288f..00000000 --- a/frontend/src/AgroShopAI/components/Pages/components/TabNav.jsx +++ /dev/null @@ -1,30 +0,0 @@ -const TabNav = ({ activeTab, setActiveTab }) => { - return ( -
- -
- ); -}; - -export default TabNav; diff --git a/frontend/src/AgroShopAI/components/Pages/components/TimeRangeSelector.jsx b/frontend/src/AgroShopAI/components/Pages/components/TimeRangeSelector.jsx deleted file mode 100644 index fda071be..00000000 --- a/frontend/src/AgroShopAI/components/Pages/components/TimeRangeSelector.jsx +++ /dev/null @@ -1,19 +0,0 @@ -import React from 'react'; - -export default function TimeRangeSelector({ timeRange, setTimeRange }) { - return ( -
- - -
- ); -} diff --git a/frontend/src/AgroShopAI/components/Pages/components/UserRegistrations.jsx b/frontend/src/AgroShopAI/components/Pages/components/UserRegistrations.jsx deleted file mode 100644 index 31c45a25..00000000 --- a/frontend/src/AgroShopAI/components/Pages/components/UserRegistrations.jsx +++ /dev/null @@ -1,19 +0,0 @@ -import React from 'react'; - -export default function UserRegistrations({ data, maxRegistrations }) { - return ( -
-

User Registrations

- - - `${index * 14 + 7},${60 - (reg / maxRegistrations) * 60}` - ).join(' ')} - fill="none" - stroke="#2196F3" - strokeWidth="2" - /> - -
- ); -} diff --git a/frontend/src/AgroShopAI/components/ReviewSection.jsx b/frontend/src/AgroShopAI/components/ReviewSection.jsx index 72afcb74..e67f79f3 100644 --- a/frontend/src/AgroShopAI/components/ReviewSection.jsx +++ b/frontend/src/AgroShopAI/components/ReviewSection.jsx @@ -1,4 +1,4 @@ -// ReviewSection.js + import React, { useState } from 'react'; const ReviewSection = ({ product_id,reviews, setReviews }) => { diff --git a/frontend/src/AgroShopAI/pages/Review.jsx b/frontend/src/AgroShopAI/pages/Review.jsx deleted file mode 100644 index 2718108d..00000000 --- a/frontend/src/AgroShopAI/pages/Review.jsx +++ /dev/null @@ -1,173 +0,0 @@ -import React, { useState } from "react"; - -const ReviewForm = ({ productId, onReviewSubmit }) => { - const [rating, setRating] = useState(1); - const [comment, setComment] = useState(""); - const [loading, setLoading] = useState(false); - const [error, setError] = useState(""); - const [success, setSuccess] = useState(""); - const [image, setImage] = useState(null); - - // Helper function to handle image upload - const handleImageChange = (e) => { - const file = e.target.files[0]; - if (file && file.size < 5000000) { - // Limit file size to 5MB - setImage(file); - } else { - setError("Image size exceeds 5MB"); - } - }; - - // Helper function for validation - const validateForm = () => { - if (!comment.trim()) { - setError("Comment cannot be empty"); - return false; - } - if (rating < 1 || rating > 5) { - setError("Rating must be between 1 and 5"); - return false; - } - return true; - }; - - // Handle form submission - const handleSubmit = async (e) => { - e.preventDefault(); - - // Clear previous error and success messages - setError(""); - setSuccess(""); - - // Validate the form - if (!validateForm()) return; - - setLoading(true); - - const reviewData = { - productId, - rating, - comment, - image, - }; - - try { - const response = await fetch("/api/reviews", { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify(reviewData), - }); - - if (!response.ok) { - throw new Error("Failed to submit review"); - } - - const newReview = await response.json(); - onReviewSubmit(newReview); - - // Reset form after successful submission - setRating(1); - setComment(""); - setImage(null); - setSuccess("Review submitted successfully!"); - } catch (error) { - console.error("Error submitting review:", error); - setError("Failed to submit review, please try again later."); - } finally { - setLoading(false); - } - }; - - // Clear error and success messages after 5 seconds - const clearMessages = () => { - setTimeout(() => { - setError(""); - setSuccess(""); - }, 5000); - }; - - // Clear messages when form changes - React.useEffect(() => { - clearMessages(); - }, [comment, rating, image]); - - return ( -
-

Write a Review

- - {/* Display error message */} - {error &&
{error}
} - - {/* Display success message */} - {success &&
{success}
} - -
- {/* Rating selection */} -
- - -
- - {/* Comment text area */} -
- -