From aac195133328fa1632239133f534f0c4dbd654f4 Mon Sep 17 00:00:00 2001 From: Ikki Date: Mon, 28 Oct 2024 23:46:43 +0530 Subject: [PATCH] todays-special-carousel --- frontend/package.json | 2 + .../src/components/Pages/TodaysSpecial.jsx | 282 ++++++++++++------ 2 files changed, 192 insertions(+), 92 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 30175db5..47cee436 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -24,12 +24,14 @@ "framer-motion": "^11.5.6", "gsap": "^3.12.5", "js-cookie": "^3.0.5", + "lucide-react": "^0.454.0", "react": "^18.3.1", "react-dom": "^18.3.1", "react-icons": "^5.2.1", "react-intersection-observer": "^9.13.0", "react-lazy-load-image-component": "^1.6.2", "react-pageflip": "^2.0.3", + "react-responsive": "^10.0.0", "react-router-dom": "^6.24.1", "split-type": "^0.3.4", "tailwind-merge": "^2.5.2", diff --git a/frontend/src/components/Pages/TodaysSpecial.jsx b/frontend/src/components/Pages/TodaysSpecial.jsx index a8cae56b..bd402ee4 100644 --- a/frontend/src/components/Pages/TodaysSpecial.jsx +++ b/frontend/src/components/Pages/TodaysSpecial.jsx @@ -1,4 +1,6 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useCallback } from 'react'; +import { ChevronLeft, ChevronRight } from 'lucide-react'; +import { useMediaQuery } from 'react-responsive'; import cappuccino from '../../assets/TSimg/cappuccino.webp'; import lemonade from '../../assets/TSimg/lemonade.webp'; import pasta_primavera from '../../assets/TSimg/pasta_primavera.webp'; @@ -9,110 +11,206 @@ import latte from '../../assets/TSimg/latte.webp'; import iced_tea from '../../assets/TSimg/iced_tea.webp'; import caesar_salad from '../../assets/TSimg/caesar_salad.webp'; - -const menuItems = { - coffee: [ - { name: "Espresso", description: "Rich and bold coffee shot.", image: espresso, originalPrice: "$3.00", offerPrice: "$2.50" }, - { name: "Cappuccino", description: "Creamy coffee with frothy milk.", image: cappuccino, originalPrice: "$3.50", offerPrice: "$3.00" }, - { name: "Latte", description: "Smooth coffee with steamed milk.", image: latte, originalPrice: "$4.00", offerPrice: "$3.50" }, - ], - drinks: [ - { name: "Mango Smoothie", description: "Refreshing mango blend.", image: mango_smoothie, originalPrice: "$4.50", offerPrice: "$4.00" }, - { name: "Lemonade", description: "Zesty and chilled lemonade.", image: lemonade, originalPrice: "$2.50", offerPrice: "$2.00" }, - { name: "Iced Tea", description: "Cool iced tea with lemon.", image: iced_tea, originalPrice: "$2.00", offerPrice: "$1.50" }, - ], - food: [ - { name: "Cheese Sandwich", description: "Toasted sandwich with cheese.", image: cheese_sandwich, originalPrice: "$3.50", offerPrice: "$3.00" }, - { name: "Pasta Primavera", description: "Veggies and pasta in a light sauce.", image: pasta_primavera, originalPrice: "$5.50", offerPrice: "$5.00" }, - { name: "Caesar Salad", description: "Crispy salad with Caesar dressing.", image: caesar_salad, originalPrice: "$5.00", offerPrice: "$4.50" }, - ], -}; +// Sample data for today's specials +const todaysSpecials = [ + { + name: "Espresso", + description: "Rich and bold coffee shot.", + originalPrice: "$3.00", + offerPrice: "$2.50", + image: espresso + }, + { + name: "Cappuccino", + description: "Creamy coffee with frothy milk.", + originalPrice: "$3.50", + offerPrice: "$3.00", + image: cappuccino + }, + { + name: "Latte", + description: "Smooth coffee with steamed milk.", + originalPrice: "$4.00", + offerPrice: "$3.50", + image: latte + }, + { + name: "Mango Smoothie", + description: "Refreshing mango blend.", + originalPrice: "$4.50", + offerPrice: "$4.00", + image: mango_smoothie + }, + { + name: "Lemonade", + description: "Zesty and chilled lemonade.", + originalPrice: "$2.50", + offerPrice: "$2.00", + image: lemonade + }, + { + name: "Iced Tea", + description: "Cool iced tea with lemon.", + originalPrice: "$2.00", + offerPrice: "$1.50", + image: iced_tea + }, + { + name: "Cheese Sandwich", + description: "Toasted sandwich with cheese.", + originalPrice: "$3.50", + offerPrice: "$3.00", + image: cheese_sandwich + }, + { + name: "Pasta Primavera", + description: "Veggies and pasta in a light sauce.", + originalPrice: "$5.50", + offerPrice: "$5.00", + image: pasta_primavera + }, + { + name: "Caesar Salad", + description: "Crispy salad with Caesar dressing.", + originalPrice: "$5.00", + offerPrice: "$4.50", + image: caesar_salad + } +]; + +const infiniteSpecials = todaysSpecials; + +const SpecialCard = ({ special, index, onMouseEnter, onMouseLeave }) => ( +
+ {special.name} +

{special.name}

+

{special.description}

+
+

{special.originalPrice}

+

{special.offerPrice}

+
+
+); const TodaysSpecial = () => { + const [currentIndex, setCurrentIndex] = useState(1); // Start at the first real special + const [isTransitioning, setIsTransitioning] = useState(false); + const [isHovered, setIsHovered] = useState(false); // New state to track hover + const isSmallScreen = useMediaQuery({ query: '(max-width: 640px)' }); + const isLargeScreen = useMediaQuery({ query: '(min-width: 641px)' }); + + const specialsWidth = isSmallScreen ? 100 : 100 / 3; + + const nextSpecial = useCallback(() => { + if (!isHovered) { // Only change if not hovering + setIsTransitioning(true); + setCurrentIndex((prevIndex) => { + if (prevIndex === infiniteSpecials.length - 2) { + setTimeout(() => { + setIsTransitioning(false); + setCurrentIndex(1); + }, 500); + return prevIndex; + } + return prevIndex + 1; + }); + } + }, [isHovered]); + + const prevSpecial = useCallback(() => { + if (!isHovered) { // Only change if not hovering + setIsTransitioning(true); + setCurrentIndex((prevIndex) => { + if (prevIndex === 1) { + setTimeout(() => { + setIsTransitioning(false); + setCurrentIndex(infiniteSpecials.length - 2); + }, 500); + return prevIndex; + } + return prevIndex - 1; + }); + } + }, [isHovered]); - const [todaysSpecial, setTodaysSpecial] = useState({ coffee: {}, drink: {}, food: {} }); - const [hoveredItem, setHoveredItem] = useState(null); // State to track the hovered item - - // Function to update today's special (cycling through 3 items) - const updateTodaysSpecial = () => { - const today = new Date(); - const dayIndex = today.getDay(); // Get the day of the week (0-6) - const cycleIndex = dayIndex % 3; // Cycle through 3 items every 3 days + useEffect(() => { + const timer = setInterval(nextSpecial, 4000); + return () => clearInterval(timer); + }, [nextSpecial]); - setTodaysSpecial({ - coffee: menuItems.coffee[cycleIndex], - drink: menuItems.drinks[cycleIndex], - food: menuItems.food[cycleIndex], - }); + // Mouse event handlers + const handleMouseEnter = () => { + setIsHovered(true); }; - useEffect(() => { - updateTodaysSpecial(); - }, []); + const handleMouseLeave = () => { + setIsHovered(false); + }; return ( -
-

- Today's Special -

-
- {/* Coffee Card */} -
setHoveredItem('coffee')} - onMouseLeave={() => setHoveredItem(null)} - > - - {todaysSpecial.coffee.name} - -

{todaysSpecial.coffee.name}

-

{todaysSpecial.coffee.description}

- - -
-

{todaysSpecial.coffee.originalPrice}

-

{todaysSpecial.coffee.offerPrice}

+
+
+

+ Today's Specials +

+
+
+
+ {infiniteSpecials.map((special, index) => ( +
+ +
+ ))} +
-
- - {/* Food Card */} -
setHoveredItem('food')} - onMouseLeave={() => setHoveredItem(null)} - > - {todaysSpecial.food.name} -

{todaysSpecial.food.name}

-

{todaysSpecial.food.description}

- -
-

{todaysSpecial.food.originalPrice}

-

{todaysSpecial.food.offerPrice}

-
+ {/* Conditional rendering for previous button */} + {currentIndex > 1 && ( + + )} + + {/* Conditional rendering for next button */} + {currentIndex < infiniteSpecials.length - 2 && ( + + )}
- - {/* Drink Card */} -
setHoveredItem('drink')} - onMouseLeave={() => setHoveredItem(null)} - > - {todaysSpecial.drink.name} - -

{todaysSpecial.drink.name}

-

{todaysSpecial.drink.description}

- -
-

{todaysSpecial.drink.originalPrice}

-

{todaysSpecial.drink.offerPrice}

-
+
+ {infiniteSpecials + .slice(1, isLargeScreen ? infiniteSpecials.length - 1 : infiniteSpecials.length) + .map((_, index) => ( +
setCurrentIndex(index + 1)} + className={`w-2 h-2 mx-1 rounded-full ${currentIndex === index + 1 ? 'bg-red-600' : 'bg-gray-400'}`} + /> + ))}
-
+
); };