(
116 | null
117 | );
118 |
119 | const handleCategoryHover = (categoryId: string) => {
120 | setHoveredCategory(categoryId);
121 | setHoveredSubCategory(null);
122 | };
123 |
124 | const handleSubCategoryHover = (subCategoryId: string) => {
125 | setHoveredSubCategory(subCategoryId);
126 | };
127 |
128 | return (
129 |
130 | {groceryCategories
131 | .concat(fashionCategories, furnitureCategories)
132 | .map((category) => (
133 |
handleCategoryHover(category.id)}
137 | // onMouseLeave={() => handleCategoryHover(null)}
138 | >
139 |
140 | {category.title}
141 |
142 | {hoveredCategory === category.id && (
143 |
144 | {category.subCategories.map((subCategory) => (
145 |
handleSubCategoryHover(subCategory.id)}
149 | // onMouseLeave={() => handleSubCategoryHover(null)}
150 | >
151 |
152 | {subCategory.name}
153 |
154 | {hoveredSubCategory === subCategory.id && (
155 |
156 | {subCategory.subItem.map((item) => (
157 | -
158 | {item.subName}
159 |
160 | ))}
161 |
162 | )}
163 |
164 | ))}
165 |
166 | )}
167 |
168 | ))}
169 |
170 | );
171 | };
172 |
173 | export default NestedHoverNavlink;
174 |
--------------------------------------------------------------------------------
/src/components/Checkout.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from 'react';
2 | import { Link, useParams } from 'react-router-dom';
3 | // import { useHistory } from 'react-router-dom'; // Assuming you're using React Router for navigation
4 |
5 | const Checkout: React.FC = () => {
6 | const { id } = useParams();
7 | console.log(id)
8 |
9 | // State for form fields
10 | const [name, setName] = useState('');
11 | const [email, setEmail] = useState('');
12 | const [address, setAddress] = useState('');
13 |
14 | useEffect(() => {
15 | window.scrollTo(0, 0)
16 | }, [])
17 |
18 | return (
19 |
20 |
Checkout
21 |
22 | {/* Shipping Address */}
23 |
24 |
Shipping Address
25 |
47 |
48 |
49 | {/* Payment Method */}
50 |
53 |
54 |
55 | {/* Place Order Button */}
56 |
62 |
63 | );
64 | };
65 |
66 | export const Payment: React.FC = () => {
67 | // const history = useHistory();
68 |
69 | // State for form fields
70 | const [paymentMethod, setPaymentMethod] = useState('');
71 | const [cardNumber, setCardNumber] = useState('');
72 | const [expiryDate, setExpiryDate] = useState('');
73 | const [cvv, setCVV] = useState('');
74 |
75 |
76 | // Function to render payment method form based on the selected payment method
77 | const renderPaymentMethodForm = () => {
78 | switch (paymentMethod) {
79 | case 'credit-card':
80 | case 'debit-card':
81 | return (
82 |
83 | setCardNumber(e.target.value)}
87 | placeholder="Card Number"
88 | className="w-full border border-gray-300 rounded-md px-4 py-2 mb-2"
89 | />
90 | setExpiryDate(e.target.value)}
94 | placeholder="Expiry Date"
95 | className="w-full border border-gray-300 rounded-md px-4 py-2 mb-2"
96 | />
97 | setCVV(e.target.value)}
101 | placeholder="CVV"
102 | className="w-full border border-gray-300 rounded-md px-4 py-2 mb-2"
103 | />
104 |
105 | );
106 | case 'paypal':
107 | return (
108 |
109 | {/* PayPal form fields */}
110 |
111 | );
112 | default:
113 | return null;
114 | }
115 | };
116 |
117 | return (
118 |
119 |
120 | {/* Shipping Address */}
121 |
122 |
125 |
126 |
127 | {/* Payment Method */}
128 |
129 |
Payment Method
130 |
141 |
142 |
143 | {/* Payment Method Details */}
144 |
145 | {renderPaymentMethodForm()}
146 |
147 |
148 | );
149 | };
150 | export default Checkout
--------------------------------------------------------------------------------
/src/components/Header.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | accountLinks,
3 | headerMoreBtnData,
4 | searchIcon,
5 | } from "../assets/globalUtlities";
6 | import logo from "/imgs/shopeaseLogo.webp";
7 | import { BiChevronDown } from "react-icons/bi";
8 | import { AiOutlineHome } from "react-icons/ai";
9 | import { PiDotsThreeVerticalBold } from "react-icons/pi";
10 | import { CgDarkMode, CgProfile } from 'react-icons/cg'
11 | import { MdOutlineMenu } from "react-icons/md";
12 | import { BsCart } from 'react-icons/bs'
13 | import { Link } from "react-router-dom";
14 | import { RootState } from "../redux/store";
15 | import { useDispatch, useSelector } from "react-redux";
16 | import { FC, useState } from "react";
17 | import { toggleDarkMode } from "../redux/actions/DarkModeAction";
18 |
19 | interface HeaderProps {
20 | toggleDarkMode: () => void
21 |
22 | }
23 |
24 | export const Header: FC = () => {
25 |
26 | const menuItems = [
27 | { title: "Home", link: "/" },
28 | { title: "Products", link: "/products" },
29 | { title: "Categories", link: "/categories" },
30 | // Add more menu items as needed
31 | ];
32 |
33 | const cart = useSelector((state: RootState) => state.cart);
34 | const dispatch = useDispatch()
35 | const darkMode = useSelector((state: RootState) => state?.dark)
36 |
37 | const [toggleMenu, setToggleMenu] = useState(false)
38 | const [showHoverItem, setShowHoverItem] = useState(false);
39 | console.log(darkMode)
40 | const handleDarkMode = () => {
41 | dispatch(toggleDarkMode())
42 | }
43 | return (
44 |
148 | );
149 | }
150 |
--------------------------------------------------------------------------------
/public/imgs/logo.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/assets/headerCategoryData.ts:
--------------------------------------------------------------------------------
1 | import { headerCategoriesProps } from "../types/layoutTypes";
2 |
3 | export const headerCategories:headerCategoriesProps= [
4 | {
5 | title: "Grocery",
6 | img: "./imgs/headerCatogeryImgs/grocery.webp",
7 | subCategories: [
8 | {
9 | category: "Fruits & Vegetables",
10 | title: "Grocery",
11 | subItems: [
12 | { name: "Fresh Fruits", id: "fruits" },
13 | { name: "Fresh Vegetables", id: "vegetables" },
14 | { name: "Exotic Fruits", id: "exotic-fruits" },
15 | // Add more sub-items as needed
16 | ],
17 | },
18 | {
19 | category: "Dairy & Eggs",
20 | title: "Grocery",
21 | subItems: [
22 | { name: "Milk", id: "milk" },
23 | { name: "Cheese", id: "cheese" },
24 | { name: "Eggs", id: "eggs" },
25 | // Add more sub-items as needed
26 | ],
27 | },
28 | {
29 | category: "Bakery & Snacks",
30 | title: "Grocery",
31 | subItems: [
32 | { name: "Bread", id: "bread" },
33 | { name: "Cakes & Pastries", id: "cakes-pastries" },
34 | { name: "Chips & Namkeen", id: "chips-namkeen" },
35 | // Add more sub-items as needed
36 | ],
37 | },
38 | {
39 | category: "Cooking Essentials",
40 | title: "Grocery",
41 | subItems: [
42 | { name: "Bread", id: "bread" },
43 | { name: "Cakes & Pastries", id: "cakes-pastries" },
44 | { name: "Chips & Namkeen", id: "chips-namkeen" },
45 | // Add more sub-items as needed
46 | ],
47 | },
48 | {
49 | category: "Sweets & Chocolates",
50 | title: "Grocery",
51 | subItems: [
52 | { name: "Bread", id: "bread" },
53 | { name: "Cakes & Pastries", id: "cakes-pastries" },
54 | { name: "Chips & Namkeen", id: "chips-namkeen" },
55 | // Add more sub-items as needed
56 | ],
57 | },
58 | {
59 | category: "Frozen Foods",
60 | title: "Grocery",
61 | subItems: [
62 | { name: "Bread", id: "bread" },
63 | { name: "Cakes & Pastries", id: "cakes-pastries" },
64 | { name: "Chips & Namkeen", id: "chips-namkeen" },
65 | // Add more sub-items as needed
66 | ],
67 | },
68 | ],
69 | },
70 | {
71 | title: "Electronics",
72 | img: "./imgs/headerCatogeryImgs/electronics.webp",
73 | subCategories: [
74 | {
75 | category: "Smartphones",
76 | title: "Electronics",
77 | subItems: [
78 | { name: "Apple", id: "apple" },
79 | { name: "Samsung", id: "samsung" },
80 | { name: "Xiaomi", id: "xiaomi" },
81 | // Add more sub-items as needed
82 | ],
83 | },
84 | {
85 | category: "Laptops",
86 | title: "Electronics",
87 | subItems: [
88 | { name: "HP", id: "hp" },
89 | { name: "Dell", id: "dell" },
90 | { name: "Lenovo", id: "lenovo" },
91 | // Add more sub-items as needed
92 | ],
93 | },
94 | {
95 | category: "Tv",
96 | title: "Electronics",
97 | subItems: [
98 | { name: "HP", id: "hp" },
99 | { name: "Dell", id: "dell" },
100 | { name: "Lenovo", id: "lenovo" },
101 | // Add more sub-items as needed
102 | ],
103 | },
104 | {
105 | category: "Refrigerator",
106 | title: "Electronics",
107 | subItems: [
108 | { name: "HP", id: "hp" },
109 | { name: "Dell", id: "dell" },
110 | { name: "Lenovo", id: "lenovo" },
111 | // Add more sub-items as needed
112 | ],
113 | },
114 | {
115 | category: "Cameras",
116 | title: "Electronics",
117 | subItems: [
118 | { name: "HP", id: "hp" },
119 | { name: "Dell", id: "dell" },
120 | { name: "Lenovo", id: "lenovo" },
121 | // Add more sub-items as needed
122 | ],
123 | },
124 | {
125 | category: "Speakers",
126 | title: "Electronics",
127 | subItems: [
128 | { name: "HP", id: "hp" },
129 | { name: "Dell", id: "dell" },
130 | { name: "Lenovo", id: "lenovo" },
131 | // Add more sub-items as needed
132 | ],
133 | },
134 | ],
135 | },
136 | {
137 | title: "Fashions",
138 | img: "./imgs/headerCatogeryImgs/fashions.webp",
139 | subCategories: [
140 | {
141 | category: "Skincare",
142 | title: "Beauty",
143 | subItems: [
144 | { name: "Cleansers", id: "cleansers" },
145 | { name: "Moisturizers", id: "moisturizers" },
146 | { name: "Serums", id: "serums" },
147 | // Add more sub-items as needed
148 | ],
149 | },
150 | {
151 | category: "Clothing",
152 | title: "Beauty",
153 | subItems: [
154 | { name: "Cleansers", id: "cleansers" },
155 | { name: "Moisturizers", id: "moisturizers" },
156 | { name: "Serums", id: "serums" },
157 | // Add more sub-items as needed
158 | ],
159 | },
160 | {
161 | category: "Footwear",
162 | title: "Beauty",
163 | subItems: [
164 | { name: "Cleansers", id: "cleansers" },
165 | { name: "Moisturizers", id: "moisturizers" },
166 | { name: "Serums", id: "serums" },
167 | // Add more sub-items as needed
168 | ],
169 | },
170 | {
171 | category: "Accessories",
172 | title: "Beauty",
173 | subItems: [
174 | { name: "Cleansers", id: "cleansers" },
175 | { name: "Moisturizers", id: "moisturizers" },
176 | { name: "Serums", id: "serums" },
177 | // Add more sub-items as needed
178 | ],
179 | },
180 | ],
181 | },
182 | {
183 | title: "Furnniture",
184 | img: "./imgs/headerCatogeryImgs/furnniture.webp",
185 | subCategories : [
186 | {
187 | category: "Sofas & Sectionals",
188 | title: "Furnniture",
189 | subItems: [
190 | { name: "Sofas", id: "sofas" },
191 | { name: "Coffee Tables", id: "coffee-tables" },
192 | { name: "Bookshelves", id: "bookshelves" },
193 | // Add more sub-items as needed
194 | ],
195 | },
196 | {
197 | category: "Beds",
198 | title: "Furnniture",
199 | subItems: [
200 | { name: "Beds", id: "beds" },
201 | { name: "Dressers", id: "dressers" },
202 | { name: "Nightstands", id: "nightstands" },
203 | // Add more sub-items as needed
204 | ],
205 | },
206 | {
207 | category: "Dining Sets",
208 | title: "Furnniture",
209 | subItems: [
210 | { name: "Beds", id: "beds" },
211 | { name: "Dressers", id: "dressers" },
212 | { name: "Nightstands", id: "nightstands" },
213 | // Add more sub-items as needed
214 | ],
215 | },
216 | {
217 | category: "Tables",
218 | title: "Furnniture",
219 | subItems: [
220 | { name: "Beds", id: "beds" },
221 | { name: "Dressers", id: "dressers" },
222 | { name: "Nightstands", id: "nightstands" },
223 | // Add more sub-items as needed
224 | ],
225 | },
226 | ]
227 | },
228 | {
229 | title:"Beauty",
230 | img:"./imgs/headerCatogeryImgs/beauty.webp",
231 | subCategories : [
232 | {
233 | category: "Skincare",
234 | title: "Furnniture",
235 | subItems: [
236 | { name: "Sofas", id: "sofas" },
237 | { name: "Coffee Tables", id: "coffee-tables" },
238 | { name: "Bookshelves", id: "bookshelves" },
239 | // Add more sub-items as needed
240 | ],
241 | },
242 | {
243 | category: "Makeup",
244 | title: "Furnniture",
245 | subItems: [
246 | { name: "Beds", id: "beds" },
247 | { name: "Dressers", id: "dressers" },
248 | { name: "Nightstands", id: "nightstands" },
249 | // Add more sub-items as needed
250 | ],
251 | },
252 | {
253 | category: "Haircare",
254 | title: "Furnniture",
255 | subItems: [
256 | { name: "Beds", id: "beds" },
257 | { name: "Dressers", id: "dressers" },
258 | { name: "Nightstands", id: "nightstands" },
259 | // Add more sub-items as needed
260 | ],
261 | },
262 | {
263 | category: "Fragrances",
264 | title: "Furnniture",
265 | subItems: [
266 | { name: "Beds", id: "beds" },
267 | { name: "Dressers", id: "dressers" },
268 | { name: "Nightstands", id: "nightstands" },
269 | // Add more sub-items as needed
270 | ],
271 | },
272 | {
273 | category: "Beauty Accessories",
274 | title: "Furnniture",
275 | subItems: [
276 | { name: "Beds", id: "beds" },
277 | { name: "Dressers", id: "dressers" },
278 | { name: "Nightstands", id: "nightstands" },
279 | // Add more sub-items as needed
280 | ],
281 | },
282 |
283 | ]
284 |
285 | }
286 | ];
287 |
288 |
289 |
290 |
291 |
292 |
293 |
--------------------------------------------------------------------------------
/src/components/ProductDetails.tsx:
--------------------------------------------------------------------------------
1 | import { useState, FC, useEffect } from "react";
2 | import { useDispatch, useSelector } from "react-redux/es/exports";
3 | import { Link, useParams } from "react-router-dom";
4 | import { rowProductsData } from "../assets/globalUtlities";
5 | // import { ProductDetailsProps, } from "../types/layoutTypes";
6 | import { CartState, RootState } from "../redux/store";
7 | import { ProductProps } from "../types/productTypes";
8 | import { MdLocalOffer, MdLocationSearching, MdOutlineDelete } from "react-icons/md";
9 | import { BsHeart } from "react-icons/bs";
10 | import { RiEditBoxLine } from "react-icons/ri";
11 | import { addToCart } from "../redux/actions/cartActions";
12 |
13 | const ProductDatails: FC = () => {
14 | const { id } = useParams();
15 | const dispatch = useDispatch();
16 | const darkMode = useSelector((state: RootState) => state?.dark)
17 |
18 | const [showDetails, setShowDetials] = useState([]);
19 | const cartProducts = useSelector((state: { cart: CartState }) => state.cart);
20 | console.log(cartProducts);
21 | const getProductDetails = () => {
22 | if (id) {
23 | const filteredItem = rowProductsData?.filter(
24 | (data) => data.id === parseInt(id)
25 | );
26 | setShowDetials(filteredItem || []);
27 | }
28 | };
29 |
30 | useEffect(() => {
31 | window.scrollTo(0, 0);
32 | getProductDetails();
33 | }, [id, cartProducts]);
34 |
35 | const [userReview, setUserReview] = useState('');
36 | const [reviews, setReviews] = useState([]);
37 |
38 | const handleReviewSubmit = () => {
39 | if (userReview.trim() !== "") {
40 | setReviews([...reviews, userReview]);
41 | } // Add user review to reviews array
42 | setUserReview(''); // Clear the input after submitting review
43 | };
44 |
45 | return (
46 |
47 | {showDetails.length > 0 &&
48 | showDetails.map((item) => (
49 | // ProductDetails section
50 |
51 |
52 | {/* Left side with item details */}
53 |
54 |
55 |

56 |
57 |
58 |
59 |
60 |
65 |
71 |
72 |
73 |
74 |
75 |
SAMSUNG Evo Plus 256 GB MicroSDXC Class 10
76 |
77 | 4.4 ★ 4,41,04,486 Ratings & 9,287 Reviews
78 |
79 |
80 |
Special price
81 |
₹1,689 ₹4,999 66% off
82 |
Available offers:
83 |
84 |
85 |
86 |
5% Cashback on ShopEase Axis Bank Card (T&C)
87 |
88 |
89 |
90 |
10% off on HDFC Bank Credit Card EMI Transactions, up to ₹1,500 on orders of ₹7,500 and above
91 | (T&C)
92 |
93 |
94 |
95 |
96 |
Special Price: Get extra 29% off (price inclusive of cashback/coupon) (T&C)
97 |
98 |
99 |
100 |
101 |
Combo Offer: Buy 2 items save ₹20; Buy 3-4 save ₹30; Buy 5+ save ₹50 (See all products, T&C)
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
10 Years Domestic Warranty
111 |
Know More
112 |
113 |
114 |
Delivery
115 |
116 |
117 |
118 |
Change
119 |
120 |
Delivery by Tomorrow, Wednesday | Free ₹70? if ordered before 4:35 PM
121 |
View Details
122 |
123 |
124 |
Capacity
125 |
126 |
64 GB
127 |
128 GB
128 |
256 GB
129 |
512 GB
130 |
131 |
132 |
133 |
Highlights
134 |
135 | - For Camera, Computer, Gaming Console, Mobile, Tablet
136 | - Capacity: 256 GB
137 | - MicroSDXC
138 | - Class 10
139 | - Read Speed: 130 MB/s
140 |
141 |
142 |
143 |
Services
144 |
10 Years Domestic Warranty
145 |
Cash on Delivery available?
146 |
Seller
147 |
MPDSLERetail4.9
148 |
7 Days Service Center Replacement/Repair?
149 |
GST invoice available?
150 |
151 |
152 |
153 |
154 |
155 |
Ratings & Reviews
156 |
157 |
Rate Product
158 |
162 |
1,04,486 Ratings & 9,287 Reviews
163 |
164 |
165 |
5★
166 |
64,106
167 |
168 | {/* */}
169 |
170 |
171 |
172 | {/* */}
173 |
174 |
175 |
4
176 |
Nice product
177 |
178 |
179 |
Product Received in Good condition. But...
180 |
Thank you for reading my Review.🙂
181 |
ShopEase Customer
182 |
Certified Buyer, Aduthurai
183 |
10 months ago
184 |
83158
185 |
186 |
187 | {/* */}
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 | ))}
197 |
198 | {/* Right side with reviews and other details */}
199 |
200 |
User Reviews
201 | {/* Reviews section */}
202 |
203 |
204 | setUserReview(e.target.value)}
209 | className="w-full p-2 border border-gray-300 rounded-md outline-none focus:border-primary"
210 | />
211 |
217 |
218 | {/* Display reviews */}
219 | {reviews.length === 0 ? (
220 |
No reviews yet.
221 | ) : (
222 | reviews.map((review, index) => (
223 |
224 |
{review}
225 |
226 |
227 |
228 | ))
229 | )}
230 | {/* Input for adding a review */}
231 |
232 |
233 |
234 |
235 |
236 | );
237 | };
238 |
239 | export default ProductDatails
240 |
--------------------------------------------------------------------------------