Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Featuer : SuperSaver Item slider component added #175

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions client/package-lock.json

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

1 change: 1 addition & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"react-icons": "^5.3.0",
"react-material-ui-carousel": "^3.4.2",
"react-redux": "^9.1.0",
"react-responsive": "^10.0.0",
"react-router-dom": "^6.22.0",
"react-social-login-buttons": "^4.1.0",
"redux": "^5.0.1",
Expand Down
87 changes: 27 additions & 60 deletions client/src/components/BuyCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import React, { useState, useEffect } from 'react';
import { useCart } from '../actions/CartControl';
import { useNavigate } from 'react-router-dom';

function BuyCard({ bogo, mrp, discountPrice, imageUrl, productName, discount, id, cart, setCart, setTotal, total, vendorSide }) {
function BuyCard({ bogo, mrp, discountPrice, imageUrl, productName, discount, id }) {
const [count, setCount] = useState(0);
const { addToCart, removeFromCart, cartItems } = useCart();
const { addToCart, cartItems } = useCart();
const navigate = useNavigate();

useEffect(() => {
Expand All @@ -15,70 +15,37 @@ function BuyCard({ bogo, mrp, discountPrice, imageUrl, productName, discount, id
}, [cartItems, id]);

return (
<div className='card w-56 flex justify-center align-middle flex-col border-2 rounded-[15px] relative hover:scale-105 transition transform ease-in-out duration-300'>
<div className='bg-slate-200 w-full flex justify-center rounded-t-[15px] align-top cursor-pointer' onClick={() => {
navigate(`/product/${id}`)
}}>
<img src={imageUrl} alt="" />
<div className='card w-full flex flex-col border-2 rounded-[15px] relative hover:scale-105 transition-transform duration-300'>
<div className='bg-slate-200 w-full flex justify-center rounded-t-[15px] cursor-pointer' onClick={() => navigate(`/product/${id}`)}>
<img
src={imageUrl}
alt={productName}
className="object-contain w-full h-48" // Using object-contain for better aspect ratio handling
loading="lazy" // Optional: Enables lazy loading for performance
style={{ maxHeight: '300px', width: 'auto' }} // Ensures max height and maintains aspect ratio
/>
</div>
<div className='p-2 flex-1'>
<span className="flex-grow cursor-pointer hover:underline" onClick={() => {
navigate(`/product/${id}`)
}}>{productName}</span>
<span style={{
color: '#54B22C'
}}>{bogo && '(Buy 1 Get 1 FREE)'}</span>
<span className="flex-grow cursor-pointer hover:underline" onClick={() => navigate(`/product/${id}`)}>{productName}</span>
{bogo && <span style={{ color: '#54B22C' }}>(Buy 1 Get 1 FREE)</span>}
</div>
<div className='flex p-2 justify-between mt-5 w-full'>
<div>
{'₹'}{discountPrice || 'Error'}
{' '}
<span className='line-through text-xs'>
{'₹'}{mrp || 'Error'}
</span>
{'₹'}{discountPrice || 'Error'} {' '}
<span className='line-through text-xs'>{'₹'}{mrp || 'Error'}</span>
</div>
<div>
<button
className="bg-[#F3F9FB] border-2 border-[#54B22C] text-[#249B3E] w-20 rounded"
onClick={() => {
setCount(count + 1);
addToCart({ id, productName, discountPrice, count: count + 1, imageUrl });
}}
disabled={count > 0}
>
{count === 0 ? 'ADD' : `Added x${count}`}
</button>
</div>
{!vendorSide && (count === 0 && (
<div className='mr-2' onClick={() => {
setCount(count + 1);
addToCart({ id, productName, discountPrice, count: count + 1, imageUrl });
}}>
<button style={{
backgroundColor: '#F3F9FB',
borderColor: '#54B22C',
color: '#249B3E',
width: '60px',
borderRadius: '5px',
border: '1px solid',
}}>ADD</button>
</div>
))}
{count > 0 && (
<div className='mr-2 flex gap-2'>
<span
style={{
cursor: 'pointer',
marginTop: '1px',
userSelect: 'none'
}} onClick={() => {
if (count >= 1 && count < 10)
setCount(count + 1);
addToCart({ id, productName, discountPrice, imageUrl, count: count + 1 });
}}>+</span>
<div><input type="text" className='w-6 border-2 indent-1' value={count} /></div>
<span
style={{
cursor: 'pointer',
marginTop: '1px',
userSelect: 'none'
}}
onClick={() => {
if (count >= 1) {
setCount(count - 1);
removeFromCart({ id });
}
}}> - </span>
</div>
)}
</div>
<div className='absolute' style={{
top: '0',
Expand Down
112 changes: 85 additions & 27 deletions client/src/components/BuyCards.jsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,97 @@
import React from "react";
import BuyCard from "./BuyCard";
import React, { useState, useEffect, useCallback } from 'react';
import { ChevronLeft, ChevronRight } from 'lucide-react';
import { useMediaQuery } from 'react-responsive';
import BuyCard from './BuyCard';
import './BuyPage.css';

function BuyCards({ bogo }) {
const BuyCards = () => {
const [currentIndex, setCurrentIndex] = useState(0);
const isSmallScreen = useMediaQuery({ query: '(max-width: 640px)' });

const dummyData = [
{ id: 100, productName: "B Natural Mixed Fruit Juice ", mrp: "200", discountPrice: "150", bogo: true, imageUrl: "juice.svg"},
{ id: 101, productName: "Hen Fruit White Protein Rich Eggs", mrp: "250", discountPrice: "200", imageUrl: "eggs.png"},
{ id: 102, productName: "Go Cheese Slices 200 g", mrp: "180", discountPrice: "140" , imageUrl: "Go_cheese.png"},
{ id: 105, productName: "Soan Papdi by Charlie's 200 g", mrp: "150", discountPrice: "120", imageUrl: "soan_papdi.png"},
{ id: 106, productName: "Cremica Chocolate Thicker Syrup", mrp: "300", discountPrice: "250" , imageUrl: "chocolate_syrup.png"},
{ id: 100, productName: "B Natural Mixed Fruit Juice", mrp: "200", discountPrice: "150", bogo: true, imageUrl: "juice.svg" },
{ id: 101, productName: "Fit Hen Fruit White Protein Rich Eggs", mrp: "250", discountPrice: "200", imageUrl: "eggs.png" },
{ id: 102, productName: "Go get cheesy Cheese Slices 200 g", mrp: "180", discountPrice: "140", imageUrl: "Go_cheese.png" },
{ id: 105, productName: "Sweet Soan Papdi by Charlie's 200 g", mrp: "150", discountPrice: "120", imageUrl: "soan_papdi.png" },
{ id: 106, productName: "Cremica Chocolate Thicker Syrup", mrp: "300", discountPrice: "250", imageUrl: "chocolate_syrup.png" },
];

const productWidth = isSmallScreen ? 100 : 33.33; // 3 cards visible on larger screens

const nextProduct = () => {
setCurrentIndex((prevIndex) => (prevIndex + 1) % (dummyData.length + 2)); // Update for seamless cycling
};

const prevProduct = () => {
setCurrentIndex((prevIndex) => (prevIndex - 1 + (dummyData.length + 2)) % (dummyData.length + 2)); // Update for seamless cycling
};

useEffect(() => {
const timer = setInterval(nextProduct, 5000);
return () => clearInterval(timer);
}, []);

return (
<>
<div className="mt-5 px-10">
<div className="container mx-auto mt-5 flex justify-center md:justify-start items-center ">
<div className="grid-box">
{dummyData.map((item, index) => (
<BuyCard
id={item.id}
key={index}
bogo={item.bogo}
productName={item.productName}
mrp={item.mrp}
discountPrice={item.discountPrice}
imageUrl={'/'+item.imageUrl}>

</BuyCard>
))
}
<section className="py-16 px-4 overflow-hidden">
<div className="max-w-7xl mx-auto">
<h2 className="text-4xl font-bold text-center mb-12 text-gray-800">Our Products</h2>
<div className="relative flex justify-center items-center">
<button
onClick={prevProduct}
className="absolute top-1/2 -left-10 transform -translate-y-1/2 rounded-full p-2 shadow-md bg-white hover:bg-gray-100"
>
<ChevronLeft className="w-6 h-6 text-gray-600" />
</button>
<div className="overflow-hidden w-full max-w-4xl">
<div
className="flex transition-transform duration-500 ease-in-out"
style={{
transform: `translateX(-${(currentIndex * 100) / 3}%)`,
}}
>
{/* Duplicating the items for continuous scrolling */}
{dummyData.map((item) => (
<div
key={item.id}
className="flex-shrink-0 w-1/3 px-2"
>
<BuyCard
id={item.id}
bogo={item.bogo}
productName={item.productName}
mrp={item.mrp}
discountPrice={item.discountPrice}
imageUrl={'/' + item.imageUrl}
/>
</div>
))}
{dummyData.map((item) => ( // Duplicate items to create continuous effect
<div
key={`duplicate-${item.id}`}
className="flex-shrink-0 w-1/3 px-2"
>
<BuyCard
id={item.id}
bogo={item.bogo}
productName={item.productName}
mrp={item.mrp}
discountPrice={item.discountPrice}
imageUrl={'/' + item.imageUrl}
/>
</div>
))}
</div>
</div>
<button
onClick={nextProduct}
className="absolute top-1/2 -right-10 transform -translate-y-1/2 rounded-full p-2 shadow-md bg-white hover:bg-gray-100"
>
<ChevronRight className="w-6 h-6 text-gray-600" />
</button>
</div>
</div>
</>
</section>
);
}
};

export default BuyCards;