From 9415c3e687b36a452b525151dc84a8f507b321d7 Mon Sep 17 00:00:00 2001 From: Jivan052 Date: Fri, 10 Jan 2025 17:37:58 +0530 Subject: [PATCH 01/17] Updated --- src/Pages/cake.js | 10 +++++----- src/Pages/milkshake.js | 10 +++++----- src/Pages/soup.js | 10 +++++----- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/Pages/cake.js b/src/Pages/cake.js index a49f584..cb4ea51 100644 --- a/src/Pages/cake.js +++ b/src/Pages/cake.js @@ -4,7 +4,7 @@ import { addToCart, removeFromCart } from '../Store/cartSlice'; import styled from 'styled-components'; import { motion } from 'framer-motion'; -const CoffeeContainer = styled.div` +const CakeContainer = styled.div` padding: 6rem 2rem 4rem 2rem; // Added top padding for navbar max-width: 1200px; margin: 0 auto; @@ -133,7 +133,7 @@ const QuantityDisplay = styled.span` text-align: center; `; -function Coffee() { +function Cake() { const dispatch = useDispatch(); const [quantities, setQuantities] = useState({}); @@ -231,7 +231,7 @@ function Coffee() { ]; return ( - + ))} </ProductGrid> - </CoffeeContainer> + </CakeContainer> ); } -export default Coffee; \ No newline at end of file +export default Cake; \ No newline at end of file diff --git a/src/Pages/milkshake.js b/src/Pages/milkshake.js index 7bc1e42..03ca4d1 100644 --- a/src/Pages/milkshake.js +++ b/src/Pages/milkshake.js @@ -4,7 +4,7 @@ import { addToCart, removeFromCart } from '../Store/cartSlice'; import styled from 'styled-components'; import { motion } from 'framer-motion'; -const CoffeeContainer = styled.div` +const MilkshakeContainer = styled.div` padding: 6rem 2rem 4rem 2rem; // Added top padding for navbar max-width: 1200px; margin: 0 auto; @@ -133,7 +133,7 @@ const QuantityDisplay = styled.span` text-align: center; `; -function Coffee() { +function Milkshake() { const dispatch = useDispatch(); const [quantities, setQuantities] = useState({}); @@ -267,7 +267,7 @@ function Coffee() { ]; return ( - <CoffeeContainer> + <MilkshakeContainer> <Title initial={{ opacity: 0, y: -50 }} animate={{ opacity: 1, y: 0 }} @@ -299,8 +299,8 @@ function Coffee() { </ProductCard> ))} </ProductGrid> - </CoffeeContainer> + </MilkshakeContainer> ); } -export default Coffee; \ No newline at end of file +export default Milkshake; \ No newline at end of file diff --git a/src/Pages/soup.js b/src/Pages/soup.js index 5f16616..7898e0e 100644 --- a/src/Pages/soup.js +++ b/src/Pages/soup.js @@ -4,7 +4,7 @@ import { addToCart, removeFromCart } from '../Store/cartSlice'; import styled from 'styled-components'; import { motion } from 'framer-motion'; -const CoffeeContainer = styled.div` +const SoupContainer = styled.div` padding: 6rem 2rem 4rem 2rem; // Added top padding for navbar max-width: 1200px; margin: 0 auto; @@ -133,7 +133,7 @@ const QuantityDisplay = styled.span` text-align: center; `; -function Coffee() { +function Soup() { const dispatch = useDispatch(); const [quantities, setQuantities] = useState({}); @@ -232,7 +232,7 @@ function Coffee() { return ( - <CoffeeContainer> + <SoupContainer> <Title initial={{ opacity: 0, y: -50 }} animate={{ opacity: 1, y: 0 }} @@ -264,8 +264,8 @@ function Coffee() { </ProductCard> ))} </ProductGrid> - </CoffeeContainer> + </SoupContainer> ); } -export default Coffee; \ No newline at end of file +export default Soup; \ No newline at end of file From 4a292c157b7f87e9153c244fa7f999784a0d0b86 Mon Sep 17 00:00:00 2001 From: Nishant Rana <126577697+NishantRana07@users.noreply.github.com> Date: Sat, 11 Jan 2025 00:39:42 +0530 Subject: [PATCH 02/17] Update Testimonial.js --- src/Pages/Testimonial.js | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/src/Pages/Testimonial.js b/src/Pages/Testimonial.js index b201855..043ce63 100644 --- a/src/Pages/Testimonial.js +++ b/src/Pages/Testimonial.js @@ -8,10 +8,27 @@ function Testimonial() { <div className="container"> <h1>What Our Customers Say</h1> <div className="carousel-container"> - <div id="carouselExampleSlidesOnly" className="carousel slide" data-bs-ride="carousel"> + <div + id="carouselExampleSlidesOnly" + className="carousel slide" + data-bs-ride="carousel" + data-bs-interval="3000" + data-bs-wrap="true"> <div className="carousel-indicators"> - <button type="button" data-bs-target="#carouselExampleSlidesOnly" data-bs-slide-to="0" className="active" aria-current="true" aria-label="Slide 1"></button> - <button type="button" data-bs-target="#carouselExampleSlidesOnly" data-bs-slide-to="1" aria-label="Slide 2"></button> + <button + type="button" + data-bs-target="#carouselExampleSlidesOnly" + data-bs-slide-to="0" + className="active" + aria-current="true" + aria-label="Slide 1" + ></button> + <button + type="button" + data-bs-target="#carouselExampleSlidesOnly" + data-bs-slide-to="1" + aria-label="Slide 2" + ></button> </div> <div className="carousel-inner"> <div className="carousel-item active"> @@ -59,11 +76,20 @@ function Testimonial() { </div> </div> </div> - <button className="carousel-control-prev" type="button" data-bs-target="#carouselExampleSlidesOnly" data-bs-slide="prev"> + <button + className="carousel-control-prev" + type="button" + data-bs-target="#carouselExampleSlidesOnly" + data-bs-slide="prev" + > <span className="carousel-control-prev-icon" aria-hidden="true"></span> <span className="visually-hidden">Previous</span> </button> - <button className="carousel-control-next" type="button" data-bs-target="#carouselExampleSlidesOnly" data-bs-slide="next"> + <button + className="carousel-control-next" + type="button" + data-bs-target="#carouselExampleSlidesOnly" + data-bs-slide="next"> <span className="carousel-control-next-icon" aria-hidden="true"></span> <span className="visually-hidden">Next</span> </button> @@ -76,7 +102,9 @@ function Testimonial() { } function TestimonialCard({ name, image, rating, text }) { + return ( + <div className="single"> <div className="image"> <img src={image} alt={name} /> From bbdb6355c48e0305cab37d4cffc4458abc74a153 Mon Sep 17 00:00:00 2001 From: Abhinav Shinde <143414991+Abhi9shinde@users.noreply.github.com> Date: Mon, 13 Jan 2025 20:29:54 +0530 Subject: [PATCH 03/17] Footer UI Update --- src/componets/footer.js | 88 +++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 43 deletions(-) diff --git a/src/componets/footer.js b/src/componets/footer.js index f028651..2fc5f7a 100644 --- a/src/componets/footer.js +++ b/src/componets/footer.js @@ -1,13 +1,13 @@ -import React from 'react'; -import styled from 'styled-components'; -import { motion } from 'framer-motion'; -import { Link } from 'react-router-dom'; +import React from "react"; +import styled from "styled-components"; +import { motion } from "framer-motion"; +import { Link } from "react-router-dom"; -// Styled components for the footer (unchanged) +// Styled components for the footer const FooterContainer = styled.footer` - background-color: #78350f; + background: linear-gradient(135deg, #5b2c1a, #8e5234); color: #fffbeb; - padding: 2rem 3rem 2rem; + padding: 1.5rem 2rem; text-align: center; position: relative; bottom: 0; @@ -20,7 +20,7 @@ const FooterContent = styled.div` margin: 0 auto; p { - margin: 0.5rem 0; + margin: 0.2rem 0; font-size: 1rem; line-height: 1.5rem; @@ -38,8 +38,8 @@ const FooterContent = styled.div` const InfoSection = styled.div` display: flex; justify-content: space-between; - margin-top: 1.3rem; - margin-bottom: 1.3rem; + margin: 2rem 0; + text-align: left; @media (max-width: 768px) { flex-direction: column; @@ -54,31 +54,21 @@ const InfoColumn = styled.div` h3 { font-size: 1.2rem; margin-bottom: 1rem; + color: #ffd6a5; } p, a { font-size: 0.9rem; - color: rgb(255, 255, 255); + color: #fffbeb; text-decoration: none; - display: block; margin-bottom: 0.5rem; + display: block; } a:hover { color: #fbbf24; - } - - @media (max-width: 768px) { - h3 { - font-size: 1.2rem; - margin-bottom: 0rem; - } - - p { - font-size: 1rem; - margin: 0rem; - } + text-decoration: underline; } `; @@ -86,7 +76,7 @@ const SocialIcons = styled.div` display: flex; justify-content: center; gap: 1rem; - margin-top: 1rem; + margin-top: 1.5rem; @media (max-width: 768px) { gap: 1.2rem; @@ -99,11 +89,10 @@ const SocialIcon = styled(motion.a)` text-decoration: none; padding: 0.5rem; border-radius: 50%; - transition: color 0.3s ease; + transition: all 0.3s ease; &:hover { color: #fbbf24; - transform: scale(1.2); } @media (max-width: 768px) { @@ -111,6 +100,14 @@ const SocialIcon = styled(motion.a)` } `; +const Divider = styled.hr` + border: none; + height: 2px; + background: #ffd6a5; + margin: 2rem auto; + width: 80%; +`; + function Footer() { return ( <FooterContainer> @@ -123,19 +120,18 @@ function Footer() { rel="noopener noreferrer" whileHover={{ scale: 1.2 }} aria-label="Facebook" - role="link" > - <i className="fab fa-facebook-f"></i> + <i className="fab fa-facebook-f"></i> {/* Facebook icon */} </SocialIcon> <SocialIcon - href="https://twitter.com" + href="https://linkedin.com" target="_blank" rel="noopener noreferrer" whileHover={{ scale: 1.2 }} - aria-label="Twitter" + aria-label="LinkedIn" role="link" > - <i className="fa-brands fa-x-twitter"></i> {/* Updated Twitter icon */} + <i className="fab fa-linkedin-in"></i> {/* LinkedIn icon */} </SocialIcon> <SocialIcon href="https://instagram.com" @@ -143,29 +139,32 @@ function Footer() { rel="noopener noreferrer" whileHover={{ scale: 1.2 }} aria-label="Instagram" - role="link" > - <i className="fab fa-instagram"></i> + <i className="fab fa-instagram"></i> {/* Instagram icon */} </SocialIcon> <SocialIcon - href="https://linkedin.com" + href="https://github.com/Mujtabaa07/coffeeShop" target="_blank" rel="noopener noreferrer" whileHover={{ scale: 1.2 }} - aria-label="LinkedIn" + aria-label="GitHub" role="link" > - <i className="fab fa-linkedin-in"></i> {/* LinkedIn icon */} + <i className="fab fa-github"></i> {/* GitHub icon */} </SocialIcon> </SocialIcons> + {/* Divider */} + <Divider /> + {/* Informational Sections */} <InfoSection> <InfoColumn> <h3>About Us</h3> <p> - Founded in 2010, MsCafe is dedicated to serving the finest coffee with passion and - expertise. We source our beans from sustainable farms across the globe. + Founded in 2010, MsCafe is dedicated to serving the finest coffee + with passion and expertise. We source our beans from sustainable + farms across the globe. </p> </InfoColumn> <InfoColumn> @@ -176,26 +175,29 @@ function Footer() { <Link to="/contact">Contact</Link> <Link to="/testimonial">Testimonial</Link> </InfoColumn> - <InfoColumn> <h3>Contact Us</h3> <p>Email: contact@mscafe.com</p> <p>Phone: (123) 456-7890</p> </InfoColumn> - <InfoColumn> <h3>Location</h3> <p>123 Coffee St, Bean Town, USA</p> <p> - <a href="https://www.google.com/maps" target="_blank" rel="noopener noreferrer"> + <a + href="https://www.google.com/maps" + target="_blank" + rel="noopener noreferrer" + > View on Map </a> </p> </InfoColumn> </InfoSection> + {/* Footer Text */} <p>© {new Date().getFullYear()} MsCafe. All rights reserved.</p> - <p>Made with ♥ by Mscoder</p> + <p>Made with ♥ by MsCoder</p> </FooterContent> </FooterContainer> ); From 5644ec418bafe414e8ba06bc8a88cc221fe965b9 Mon Sep 17 00:00:00 2001 From: Pratibha666 <pratibha.yadav1128@gmail.com> Date: Mon, 13 Jan 2025 20:32:35 +0530 Subject: [PATCH 04/17] hover effect on social media icons --- package.json | 5 ----- src/componets/footer.js | 24 ++++++++++++++++++++---- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index a90c085..6ec8c5a 100644 --- a/package.json +++ b/package.json @@ -12,10 +12,7 @@ "@babel/plugin-transform-private-property-in-object": "^7.25.9", "@babel/preset-env": "^7.26.0", "@babel/preset-react": "^7.26.3", - - "@dotlottie/react-player": "^1.6.19", - "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.0", "@eslint/config-array": "^0.19.1", @@ -36,9 +33,7 @@ "glob": "^11.0.0", "gsap": "^3.12.5", "lottie-react": "^2.4.0", - "openai": "^4.78.0", - "react": "^18.3.1", "react-dom": "^18.3.1", "react-locomotive-scroll": "^0.2.2", diff --git a/src/componets/footer.js b/src/componets/footer.js index f028651..2f534d9 100644 --- a/src/componets/footer.js +++ b/src/componets/footer.js @@ -95,22 +95,38 @@ const SocialIcons = styled.div` const SocialIcon = styled(motion.a)` color: #fffbeb; - font-size: 1.5rem; + font-size: 1.8rem; text-decoration: none; padding: 0.5rem; border-radius: 50%; - transition: color 0.3s ease; + transition: color 0.3s ease, transform 0.3s ease; &:hover { - color: #fbbf24; transform: scale(1.2); } + &[href*="facebook.com"]:hover { + color: #3b5998; /* Facebook Blue */ + } + + &[href*="twitter.com"]:hover { + color: #1da1f2; /* Twitter Blue */ + } + + &[href*="instagram.com"]:hover { + color: #e4405f; /* Instagram Pink */ + } + + &[href*="linkedin.com"]:hover { + color: #0077b5; /* LinkedIn Blue */ + } + @media (max-width: 768px) { font-size: 1.3rem; } `; + function Footer() { return ( <FooterContainer> @@ -135,7 +151,7 @@ function Footer() { aria-label="Twitter" role="link" > - <i className="fa-brands fa-x-twitter"></i> {/* Updated Twitter icon */} + <i className="fab fa-twitter"></i> {/* Updated Twitter icon */} </SocialIcon> <SocialIcon href="https://instagram.com" From 7f7e5fea83f5e9746967e6ce3f3192d043bd172b Mon Sep 17 00:00:00 2001 From: deepeshahlawat <deepeshahlawat001@gmail.com> Date: Tue, 14 Jan 2025 01:30:18 +0530 Subject: [PATCH 05/17] Resolved conflicts --- package-lock.json | 15 ++ package.json | 6 +- src/Pages/Shop.js | 558 ++++++++++++++++++++++------------------- src/Pages/cake.js | 29 ++- src/Pages/coffee.js | 32 ++- src/Pages/milkshake.js | 32 ++- src/Pages/soup.js | 32 ++- 7 files changed, 430 insertions(+), 274 deletions(-) diff --git a/package-lock.json b/package-lock.json index 873ade6..5484b5c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,7 @@ "@emotion/styled": "^11.14.0", "@eslint/config-array": "^0.19.1", "@eslint/object-schema": "^2.1.5", + "@fortawesome/fontawesome-free": "^6.7.2", "@headlessui/react": "^2.1.8", "@heroicons/react": "^2.1.5", "@jridgewell/sourcemap-codec": "^1.5.0", @@ -2622,6 +2623,15 @@ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz", "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==" }, + "node_modules/@fortawesome/fontawesome-free": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.7.2.tgz", + "integrity": "sha512-JUOtgFW6k9u4Y+xeIaEiLr3+cjoUPiAuLXoyKOJSia6Duzb7pq+A76P9ZdPDoAoxHdHzq6gE9/jKBGXlZT8FbA==", + "license": "(CC-BY-4.0 AND OFL-1.1 AND MIT)", + "engines": { + "node": ">=6" + } + }, "node_modules/@headlessui/react": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-2.2.0.tgz", @@ -22185,6 +22195,11 @@ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz", "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==" }, + "@fortawesome/fontawesome-free": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.7.2.tgz", + "integrity": "sha512-JUOtgFW6k9u4Y+xeIaEiLr3+cjoUPiAuLXoyKOJSia6Duzb7pq+A76P9ZdPDoAoxHdHzq6gE9/jKBGXlZT8FbA==" + }, "@headlessui/react": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-2.2.0.tgz", diff --git a/package.json b/package.json index a90c085..d61d996 100644 --- a/package.json +++ b/package.json @@ -12,14 +12,12 @@ "@babel/plugin-transform-private-property-in-object": "^7.25.9", "@babel/preset-env": "^7.26.0", "@babel/preset-react": "^7.26.3", - - "@dotlottie/react-player": "^1.6.19", - "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.0", "@eslint/config-array": "^0.19.1", "@eslint/object-schema": "^2.1.5", + "@fortawesome/fontawesome-free": "^6.7.2", "@headlessui/react": "^2.1.8", "@heroicons/react": "^2.1.5", "@jridgewell/sourcemap-codec": "^1.5.0", @@ -36,9 +34,7 @@ "glob": "^11.0.0", "gsap": "^3.12.5", "lottie-react": "^2.4.0", - "openai": "^4.78.0", - "react": "^18.3.1", "react-dom": "^18.3.1", "react-locomotive-scroll": "^0.2.2", diff --git a/src/Pages/Shop.js b/src/Pages/Shop.js index 01cfaa8..7aaf4f3 100644 --- a/src/Pages/Shop.js +++ b/src/Pages/Shop.js @@ -5,11 +5,13 @@ import { useDispatch } from 'react-redux'; import styled from 'styled-components'; import { motion } from 'framer-motion'; import { addToCart } from '../Store/cartSlice'; -import { useState } from 'react'; +import { useState } from 'react'; import Button from '../componets/Button'; import { toast, ToastContainer } from 'react-toastify'; // Add this import import 'react-toastify/dist/ReactToastify.css'; import DynamicText from "./dynamicText"; +import "@fortawesome/fontawesome-free/css/all.min.css"; + import ButtonGroup from '@mui/material/ButtonGroup'; @@ -188,7 +190,7 @@ const products = [ { id: 32, name: 'Oreo Milkshake', price: 5.2, image: 'https://www.solara.in/cdn/shop/articles/Oreo_Milkshake.jpg?v=1715757748&width=2048', description: 'Creamy and delicious, blended with Oreo cookies, ice cream, and milk.', type: 'cold' }, { id: 33, name: 'Strawberry Oreo Milkshake', price: 2.6, image: 'https://marleysmenu.com/wp-content/uploads/2021/08/Strawberry-Oreo-Milkshake-Featured-Image.jpg', description: 'A sweet blend of strawberries, Oreo cookies, and ice cream, perfect for dessert lovers.', type: 'cold' }, { id: 34, name: 'Mixed Nut and Fruit Milkshake', price: 8.2, image: 'https://images.mrcook.app/recipe-image/018d50f7-344f-7744-97e3-1f89e5a3cf29', description: 'A nutritious blend of mixed nuts, fruits, and milk, creamy and satisfying.', type: 'cold' }, - { id: 35, name: 'Peanut Butter Milkshake', price: 5.8, image: 'https://www.julieseatsandtreats.com/wp-content/uploads/2021/08/Peanut-Butter-Milkshake-Square.jpg', description: "Rich and creamy, made with peanut butter, ice cream, and milk, a peanut butter lover's dream.", type: 'cold'}, + { id: 35, name: 'Peanut Butter Milkshake', price: 5.8, image: 'https://www.julieseatsandtreats.com/wp-content/uploads/2021/08/Peanut-Butter-Milkshake-Square.jpg', description: "Rich and creamy, made with peanut butter, ice cream, and milk, a peanut butter lover's dream.", type: 'cold' }, { id: 36, name: 'Oreo cheese cake', price: 9.2, image: 'https://handletheheat.com/wp-content/uploads/2015/11/oreo-cheesecake-recipe-SQUARE.jpg', description: 'Creamy cheesecake with an Oreo crust and topping, rich and indulgent.', type: 'food' }, { id: 37, name: 'Chocolate cake', price: 7.2, image: 'https://img.freepik.com/free-photo/chocolate-cake_1203-8942.jpg?ga=GA1.1.900909129.1729318722&semt=ais_hybrid', description: 'Moist and decadent, a classic chocolate cake perfect for any celebration.', type: 'food' }, { id: 38, name: 'Red velvet cake', price: 4.2, image: 'https://img.freepik.com/free-photo/top-view-red-strawberry-cake-delicious-with-tea-table-fruit-color-cake-biscuit-sweet_140725-28319.jpg?ga=GA1.1.900909129.1729318722&semt=ais_hybrid', description: 'Rich and velvety, a moist red cake with cream cheese frosting, elegant and delicious.', type: 'food' }, @@ -363,7 +365,7 @@ const products = [ description: "Espresso served with sweetened condensed milk, creating a layered effect.", }, - + { id: 25, name: "Irish Coffee", @@ -373,269 +375,269 @@ const products = [ description: "Coffee with Irish whiskey, sugar, and cream, a warm and boozy treat.", }, - + ]; - // Tea Section - const product1=[{ - id: 19, - name: "Chai", - price: 7.3, - image: - "https://img.freepik.com/free-photo/frappe-glass-slices-bread-with-seeds_23-2148623233.jpg?ga=GA1.1.1542821208.1727756299&semt=ais_hybrid", - description: - "Spiced black tea brewed with milk and sweetened, aromatic and comforting.", - }, - { - id: 20, - name: "Lemon Tea", - price: 4.1, - image: - "https://img.freepik.com/free-photo/cup-hot-mint-tea_144627-34462.jpg?ga=GA1.1.1542821208.1727756299&semt=ais_hybrid ", - description: - "Refreshing black tea infused with lemon, perfect for a soothing experience.", - }, - { - id: 21, - name: "Green Tea", - price: 3.4, - image: - "https://img.freepik.com/free-photo/cup-green-tea_144627-34463.jpg?ga=GA1.1.1542821208.1727756299&semt=ais_hybrid ", - description: - "Light and delicate, made from unfermented tea leaves, rich in antioxidants.", - }, - { - id: 22, - name: "Black Tea", - price: 4.5, - image: - "https://img.freepik.com/free-photo/cup-black-tea_144627-34464.jpg?ga=GA1.1.1542821208.1727756299&semt=ais_hybrid ", - description: - "Strong and full-bodied, made from fully oxidized tea leaves, classic and robust.", - }, - { - id: 23, - name: "Herbal Tea", - price: 5.5, - image: - "https://img.freepik.com/premium-photo/black-tea-cup-glass-mint-tea-leaves-white-isolated_127657-17608.jpg?ga=GA1.1.900909129.1729318722&semt=ais_hybrid ", - description: - "Caffeine-free tea made from herbs, fruits, or spices, naturally soothing.", - }, - { - id: 24, - name: "Iced Tea", - price: 5.6, - image: - "https://img.freepik.com/free-vector/long-island-ice-tea-cocktail-realistic_1284-3888.jpg?ga=GA1.1.900909129.1729318722&semt=ais_hybrid ", - description: - "Refreshing chilled tea, often sweetened and served with lemon, perfect for hot days.", - }, +// Tea Section +const product1 = [{ + id: 19, + name: "Chai", + price: 7.3, + image: + "https://img.freepik.com/free-photo/frappe-glass-slices-bread-with-seeds_23-2148623233.jpg?ga=GA1.1.1542821208.1727756299&semt=ais_hybrid", + description: + "Spiced black tea brewed with milk and sweetened, aromatic and comforting.", +}, +{ + id: 20, + name: "Lemon Tea", + price: 4.1, + image: + "https://img.freepik.com/free-photo/cup-hot-mint-tea_144627-34462.jpg?ga=GA1.1.1542821208.1727756299&semt=ais_hybrid ", + description: + "Refreshing black tea infused with lemon, perfect for a soothing experience.", +}, +{ + id: 21, + name: "Green Tea", + price: 3.4, + image: + "https://img.freepik.com/free-photo/cup-green-tea_144627-34463.jpg?ga=GA1.1.1542821208.1727756299&semt=ais_hybrid ", + description: + "Light and delicate, made from unfermented tea leaves, rich in antioxidants.", +}, +{ + id: 22, + name: "Black Tea", + price: 4.5, + image: + "https://img.freepik.com/free-photo/cup-black-tea_144627-34464.jpg?ga=GA1.1.1542821208.1727756299&semt=ais_hybrid ", + description: + "Strong and full-bodied, made from fully oxidized tea leaves, classic and robust.", +}, +{ + id: 23, + name: "Herbal Tea", + price: 5.5, + image: + "https://img.freepik.com/premium-photo/black-tea-cup-glass-mint-tea-leaves-white-isolated_127657-17608.jpg?ga=GA1.1.900909129.1729318722&semt=ais_hybrid ", + description: + "Caffeine-free tea made from herbs, fruits, or spices, naturally soothing.", +}, +{ + id: 24, + name: "Iced Tea", + price: 5.6, + image: + "https://img.freepik.com/free-vector/long-island-ice-tea-cocktail-realistic_1284-3888.jpg?ga=GA1.1.900909129.1729318722&semt=ais_hybrid ", + description: + "Refreshing chilled tea, often sweetened and served with lemon, perfect for hot days.", +}, ]; - // Milkshake and Smothiee - const product2=[{ - id: 26, - name: "Strawberry smoothie", - price: 6.2, - image: - "https://www.eatingwell.com/thmb/TBp6lbiwoYPhRP4N__4sROiUDhA=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc()/mixed-berry-breakfast-smoothie-7959466-1x1-e0ad2304222e49508cda7b73b21de921.jpg", - description: - "Creamy and sweet, made with fresh strawberries, yogurt, and a touch of honey.", - }, - { - id: 27, - name: "Mango smoothie", - price: 3.2, - image: - "https://cdn.loveandlemons.com/wp-content/uploads/2023/05/mango-smoothie.jpg", - description: - "Tropical and refreshing, blended with ripe mangoes, banana, and coconut milk.", - }, - { - id: 28, - name: "Strawberry banana smoothie", - price: 6.45, - image: - "https://www.purelykaylie.com/wp-content/uploads/2023/07/strawberry-banana-smoothie-bowl-5.jpg", - description: - "A classic combination of strawberries and bananas, creamy and naturally sweet.", - }, - { - id: 29, - name: "Creamy, Nutty Coffee Smoothie", - price: 7.2, - image: - "https://www.seriouseats.com/thmb/dwKjOOPQu1ki3pSf1M4eB7FGVzI=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc()/20240206-SEA-Coffee-Smoothie-hero-27d1864a41cc411ea7ff0c64ada77a2e.jpg", - description: - "A rich blend of coffee, nuts, and cream, perfect for a morning energy boost.", - }, - { - id: 30, - name: "Coffee Smoothie", - price: 6.3, - image: - "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT-Y9in1wQf-XCl9sdyuw5pXWT_CrYn8P5j7A&s", - description: - "Creamy and caffeinated, made with cold brew, banana, and almond milk.", - }, - { - id: 31, - name: "Chocolate Milkshake", - price: 5.2, - image: - "https://www.sharmispassions.com/wp-content/uploads/2012/07/chocolate-milkshake1.jpg", - description: - "Rich and indulgent, made with chocolate ice cream, milk, and whipped cream.", - }, - { - id: 32, - name: "Oreo Milkshake", - price: 5.2, - image: - "https://www.solara.in/cdn/shop/articles/Oreo_Milkshake.jpg?v=1715757748&width=2048", - description: - "Creamy and delicious, blended with Oreo cookies, ice cream, and milk.", - }, - { - id: 33, - name: "Strawberry Oreo Milkshake", - price: 2.6, - image: - "https://marleysmenu.com/wp-content/uploads/2021/08/Strawberry-Oreo-Milkshake-Featured-Image.jpg", - description: - "A sweet blend of strawberries, Oreo cookies, and ice cream, perfect for dessert lovers.", - }, - { - id: 34, - name: "Mixed Nut and Fruit Milkshake", - price: 8.2, - image: - "https://images.mrcook.app/recipe-image/018d50f7-344f-7744-97e3-1f89e5a3cf29", - description: - "A nutritious blend of mixed nuts, fruits, and milk, creamy and satisfying.", - }, - { - id: 35, - name: "Peanut Butter Milkshake", - price: 5.8, - image: - "https://www.julieseatsandtreats.com/wp-content/uploads/2021/08/Peanut-Butter-Milkshake-Square.jpg", - description: - "Rich and creamy, made with peanut butter, ice cream, and milk, a peanut butter lover's dream.", - }, +// Milkshake and Smothiee +const product2 = [{ + id: 26, + name: "Strawberry smoothie", + price: 6.2, + image: + "https://www.eatingwell.com/thmb/TBp6lbiwoYPhRP4N__4sROiUDhA=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc()/mixed-berry-breakfast-smoothie-7959466-1x1-e0ad2304222e49508cda7b73b21de921.jpg", + description: + "Creamy and sweet, made with fresh strawberries, yogurt, and a touch of honey.", +}, +{ + id: 27, + name: "Mango smoothie", + price: 3.2, + image: + "https://cdn.loveandlemons.com/wp-content/uploads/2023/05/mango-smoothie.jpg", + description: + "Tropical and refreshing, blended with ripe mangoes, banana, and coconut milk.", +}, +{ + id: 28, + name: "Strawberry banana smoothie", + price: 6.45, + image: + "https://www.purelykaylie.com/wp-content/uploads/2023/07/strawberry-banana-smoothie-bowl-5.jpg", + description: + "A classic combination of strawberries and bananas, creamy and naturally sweet.", +}, +{ + id: 29, + name: "Creamy, Nutty Coffee Smoothie", + price: 7.2, + image: + "https://www.seriouseats.com/thmb/dwKjOOPQu1ki3pSf1M4eB7FGVzI=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc()/20240206-SEA-Coffee-Smoothie-hero-27d1864a41cc411ea7ff0c64ada77a2e.jpg", + description: + "A rich blend of coffee, nuts, and cream, perfect for a morning energy boost.", +}, +{ + id: 30, + name: "Coffee Smoothie", + price: 6.3, + image: + "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT-Y9in1wQf-XCl9sdyuw5pXWT_CrYn8P5j7A&s", + description: + "Creamy and caffeinated, made with cold brew, banana, and almond milk.", +}, +{ + id: 31, + name: "Chocolate Milkshake", + price: 5.2, + image: + "https://www.sharmispassions.com/wp-content/uploads/2012/07/chocolate-milkshake1.jpg", + description: + "Rich and indulgent, made with chocolate ice cream, milk, and whipped cream.", +}, +{ + id: 32, + name: "Oreo Milkshake", + price: 5.2, + image: + "https://www.solara.in/cdn/shop/articles/Oreo_Milkshake.jpg?v=1715757748&width=2048", + description: + "Creamy and delicious, blended with Oreo cookies, ice cream, and milk.", +}, +{ + id: 33, + name: "Strawberry Oreo Milkshake", + price: 2.6, + image: + "https://marleysmenu.com/wp-content/uploads/2021/08/Strawberry-Oreo-Milkshake-Featured-Image.jpg", + description: + "A sweet blend of strawberries, Oreo cookies, and ice cream, perfect for dessert lovers.", +}, +{ + id: 34, + name: "Mixed Nut and Fruit Milkshake", + price: 8.2, + image: + "https://images.mrcook.app/recipe-image/018d50f7-344f-7744-97e3-1f89e5a3cf29", + description: + "A nutritious blend of mixed nuts, fruits, and milk, creamy and satisfying.", +}, +{ + id: 35, + name: "Peanut Butter Milkshake", + price: 5.8, + image: + "https://www.julieseatsandtreats.com/wp-content/uploads/2021/08/Peanut-Butter-Milkshake-Square.jpg", + description: + "Rich and creamy, made with peanut butter, ice cream, and milk, a peanut butter lover's dream.", +}, ]; - // Cake Section - const product3=[ { - id: 36, - name: "Oreo cheese cake", - price: 9.2, - image: - "https://handletheheat.com/wp-content/uploads/2015/11/oreo-cheesecake-recipe-SQUARE.jpg", - description: - "Creamy cheesecake with an Oreo crust and topping, rich and indulgent.", - }, - { - id: 37, - name: "Chocolate cake", - price: 7.2, - image: - "https://img.freepik.com/free-photo/chocolate-cake_1203-8942.jpg?ga=GA1.1.900909129.1729318722&semt=ais_hybrid", - description: - "Moist and decadent, a classic chocolate cake perfect for any celebration.", - }, - { - id: 38, - name: "Red velvet cake", - price: 4.2, - image: - "https://img.freepik.com/free-photo/top-view-red-strawberry-cake-delicious-with-tea-table-fruit-color-cake-biscuit-sweet_140725-28319.jpg?ga=GA1.1.900909129.1729318722&semt=ais_hybrid", - description: - "Rich and velvety, a moist red cake with cream cheese frosting, elegant and delicious.", - }, - { - id: 39, - name: "Cheese cake", - price: 8.2, - image: - "https://img.freepik.com/premium-photo/citrus-cheesecake-cake-with-kumquats_82780-1574.jpg?ga=GA1.1.900909129.1729318722&semt=ais_hybrid", - description: - "Creamy and smooth, a classic cheesecake with a graham cracker crust, perfect for dessert.", - }, - { - id: 40, - name: "Blueberry cake", - price: 3.2, - image: - "https://img.freepik.com/premium-photo/pieces-pie-from-cottage-cheese-blueberries_116441-1516.jpg?ga=GA1.1.900909129.1729318722&semt=ais_hybrid", - description: - "Moist and bursting with blueberries, a sweet and tangy cake perfect for any occasion.", - }, - { - id: 41, - name: "Strawberry cake", - price: 6, - image: - "https://img.freepik.com/free-photo/delicious-cake-with-strawberries_23-2150797874.jpg?ga=GA1.1.900909129.1729318722&semt=ais_hybrid", - description: - "Light and fluffy, a sweet strawberry cake with creamy frosting, perfect for summer.", - }, +// Cake Section +const product3 = [{ + id: 36, + name: "Oreo cheese cake", + price: 9.2, + image: + "https://handletheheat.com/wp-content/uploads/2015/11/oreo-cheesecake-recipe-SQUARE.jpg", + description: + "Creamy cheesecake with an Oreo crust and topping, rich and indulgent.", +}, +{ + id: 37, + name: "Chocolate cake", + price: 7.2, + image: + "https://img.freepik.com/free-photo/chocolate-cake_1203-8942.jpg?ga=GA1.1.900909129.1729318722&semt=ais_hybrid", + description: + "Moist and decadent, a classic chocolate cake perfect for any celebration.", +}, +{ + id: 38, + name: "Red velvet cake", + price: 4.2, + image: + "https://img.freepik.com/free-photo/top-view-red-strawberry-cake-delicious-with-tea-table-fruit-color-cake-biscuit-sweet_140725-28319.jpg?ga=GA1.1.900909129.1729318722&semt=ais_hybrid", + description: + "Rich and velvety, a moist red cake with cream cheese frosting, elegant and delicious.", +}, +{ + id: 39, + name: "Cheese cake", + price: 8.2, + image: + "https://img.freepik.com/premium-photo/citrus-cheesecake-cake-with-kumquats_82780-1574.jpg?ga=GA1.1.900909129.1729318722&semt=ais_hybrid", + description: + "Creamy and smooth, a classic cheesecake with a graham cracker crust, perfect for dessert.", +}, +{ + id: 40, + name: "Blueberry cake", + price: 3.2, + image: + "https://img.freepik.com/premium-photo/pieces-pie-from-cottage-cheese-blueberries_116441-1516.jpg?ga=GA1.1.900909129.1729318722&semt=ais_hybrid", + description: + "Moist and bursting with blueberries, a sweet and tangy cake perfect for any occasion.", +}, +{ + id: 41, + name: "Strawberry cake", + price: 6, + image: + "https://img.freepik.com/free-photo/delicious-cake-with-strawberries_23-2150797874.jpg?ga=GA1.1.900909129.1729318722&semt=ais_hybrid", + description: + "Light and fluffy, a sweet strawberry cake with creamy frosting, perfect for summer.", +}, ]; - // Soup Section - const product4=[{ - id: 42, - name: "Salad", - price: 7.3, - image: - "https://img.freepik.com/free-photo/dietary-salad-with-tomatoes-feta-lettuce-spinach-pine-nuts_2829-20128.jpg?ga=GA1.1.900909129.1729318722&semt=ais_hybrid", - description: - "Fresh and healthy, a mix of greens, vegetables, and a tangy dressing, perfect for a light meal.", - }, - { - id: 43, - name: "Tomato soup", - price: 6.7, - image: - "https://img.freepik.com/free-photo/portrait-shooting-tomato-soup-with-crackers-cheese-tomatoes-bread-table_141793-2858.jpg?ga=GA1.1.900909129.1729318722&semt=ais_hybrid", - description: - "Warm and comforting, a classic tomato soup perfect for a cozy meal, often served with grilled cheese.", - }, - { - id: 44, - name: "Chicken Noodle soup", - price: 8.2, - image: - "https://img.freepik.com/free-photo/delicious-noodle-soup-with-chicken-uncooked-pasta-small-brown-bowl-spoon-garlic-dark-background_140725-140085.jpg?ga=GA1.1.900909129.1729318722&semt=ais_hybrid", - description: - "Hearty and soothing, a classic soup with chicken, noodles, and vegetables, perfect for cold days.", - }, - { - id: 45, - name: "Miso soup", - price: 7.5, - image: - "https://img.freepik.com/free-photo/top-view-japanese-food-bowls-arrangement_23-2148809848.jpg?ga=GA1.1.900909129.1729318722&semt=ais_hybrid", - description: - "Savory and umami-rich, a traditional Japanese soup made with miso paste and dashi broth.", - }, - { - id: 46, - name: "Cold cucumber soup", - price: 7.34, - image: - "https://img.freepik.com/free-photo/cold-cucumber-soup-with-dried-tomatoes-mozzarella_2829-14287.jpg?ga=GA1.1.900909129.1729318722&semt=ais_hybrid", - description: - "Refreshing and cool, a chilled soup made with cucumbers, yogurt, and herbs, perfect for summer.", - }, - { - id: 47, - name: "Tom Yum Soup", - price: 9.2, - image: - "https://img.freepik.com/free-photo/tom-yum-kung-thai-hot-spicy-soup-shrimp-with-lemon-grass-lemon-galangal-chilli-wooden-table-thailand-food_1150-21078.jpg?ga=GA1.1.900909129.1729318722&semt=ais_hybrid", - description: - "Spicy and aromatic, a Thai soup with lemongrass, kaffir lime leaves, and chilies, often with shrimp.", - }, +// Soup Section +const product4 = [{ + id: 42, + name: "Salad", + price: 7.3, + image: + "https://img.freepik.com/free-photo/dietary-salad-with-tomatoes-feta-lettuce-spinach-pine-nuts_2829-20128.jpg?ga=GA1.1.900909129.1729318722&semt=ais_hybrid", + description: + "Fresh and healthy, a mix of greens, vegetables, and a tangy dressing, perfect for a light meal.", +}, +{ + id: 43, + name: "Tomato soup", + price: 6.7, + image: + "https://img.freepik.com/free-photo/portrait-shooting-tomato-soup-with-crackers-cheese-tomatoes-bread-table_141793-2858.jpg?ga=GA1.1.900909129.1729318722&semt=ais_hybrid", + description: + "Warm and comforting, a classic tomato soup perfect for a cozy meal, often served with grilled cheese.", +}, +{ + id: 44, + name: "Chicken Noodle soup", + price: 8.2, + image: + "https://img.freepik.com/free-photo/delicious-noodle-soup-with-chicken-uncooked-pasta-small-brown-bowl-spoon-garlic-dark-background_140725-140085.jpg?ga=GA1.1.900909129.1729318722&semt=ais_hybrid", + description: + "Hearty and soothing, a classic soup with chicken, noodles, and vegetables, perfect for cold days.", +}, +{ + id: 45, + name: "Miso soup", + price: 7.5, + image: + "https://img.freepik.com/free-photo/top-view-japanese-food-bowls-arrangement_23-2148809848.jpg?ga=GA1.1.900909129.1729318722&semt=ais_hybrid", + description: + "Savory and umami-rich, a traditional Japanese soup made with miso paste and dashi broth.", +}, +{ + id: 46, + name: "Cold cucumber soup", + price: 7.34, + image: + "https://img.freepik.com/free-photo/cold-cucumber-soup-with-dried-tomatoes-mozzarella_2829-14287.jpg?ga=GA1.1.900909129.1729318722&semt=ais_hybrid", + description: + "Refreshing and cool, a chilled soup made with cucumbers, yogurt, and herbs, perfect for summer.", +}, +{ + id: 47, + name: "Tom Yum Soup", + price: 9.2, + image: + "https://img.freepik.com/free-photo/tom-yum-kung-thai-hot-spicy-soup-shrimp-with-lemon-grass-lemon-galangal-chilli-wooden-table-thailand-food_1150-21078.jpg?ga=GA1.1.900909129.1729318722&semt=ais_hybrid", + description: + "Spicy and aromatic, a Thai soup with lemongrass, kaffir lime leaves, and chilies, often with shrimp.", +}, ]; const SearchFilterContainer = styled.div` @@ -702,9 +704,18 @@ function Shop() { const [itemsNo, setItemsNo] = useState(9); + const [likedProducts, setLikedProducts] = useState({}); + + const toggleHeart = (productId) => { + setLikedProducts((prevState) => ({ + ...prevState, + [productId]: !prevState[productId], + })); + }; + const handleItemsNo = () => { const s = products.length; - if (s === itemsNo) { + if (s == itemsNo) { setItemsNo(9); } else { setItemsNo(Math.min(itemsNo + 9, s)); @@ -825,7 +836,30 @@ function Shop() { > <div style={{ position: "relative" }}> <ProductImage src={product.image} alt={product.name} /> - <Overlay className="overlay"> + + <div + onClick={() => toggleHeart(product.id)} + style={{ + position: 'absolute', + top: '10px', + right: '10px', + cursor: 'pointer', + fontSize: '24px', + color: likedProducts[product.id] ? 'red' : 'gray', + zIndex: 2, + }} + > + <i className={`fa-heart ${likedProducts[product.id] ? 'fas' : 'far'}`}></i> + </div> + + <Overlay className="overlay" style={{ + position: 'absolute', + top: 0, + left: 0, + width: '100%', + height: '100%', + zIndex: 1, + }}> <OverlayText>{product.description}</OverlayText> </Overlay> </div> diff --git a/src/Pages/cake.js b/src/Pages/cake.js index 8cc9e9f..372d50a 100644 --- a/src/Pages/cake.js +++ b/src/Pages/cake.js @@ -3,6 +3,7 @@ import { useDispatch } from 'react-redux'; import { addToCart, removeFromCart } from '../Store/cartSlice'; import styled from 'styled-components'; import { motion } from 'framer-motion'; +import "@fortawesome/fontawesome-free/css/all.min.css"; const CakeContainer = styled.div` padding: 6rem 2rem 4rem 2rem; @@ -156,6 +157,14 @@ function Cake() { const dispatch = useDispatch(); const [quantities, setQuantities] = useState({}); const [searchQuery, setSearchQuery] = useState(''); + const [likedProducts, setLikedProducts] = useState({}); + + const toggleHeart = (productId) => { + setLikedProducts((prevState) => ({ + ...prevState, + [productId]: !prevState[productId], + })); + }; const handleAddToCart = (product) => { if (!quantities[product.id]) { @@ -261,7 +270,25 @@ function Cake() { <ProductGrid> {filteredProducts.map((product) => ( <ProductCard key={product.id}> - <ProductImage src={product.image} alt={product.name} /> + <div style={{ position: 'relative' }}> + <ProductImage src={product.image} alt={product.name} /> + <div + onClick={() => toggleHeart(product.id)} + style={{ + position: 'absolute', + top: '10px', + right: '10px', + cursor: 'pointer', + fontSize: '24px', + color: likedProducts[product.id] ? 'red' : 'gray', + }} + > + <i + className={`fa-heart ${likedProducts[product.id] ? 'fas' : 'far' + }`} + ></i> + </div> + </div> <ProductInfo> <ProductName>{product.name}</ProductName> <ProductPrice>${product.price.toFixed(2)}</ProductPrice> diff --git a/src/Pages/coffee.js b/src/Pages/coffee.js index 81566c1..3b62449 100644 --- a/src/Pages/coffee.js +++ b/src/Pages/coffee.js @@ -3,6 +3,7 @@ import { useDispatch } from 'react-redux'; import { addToCart, removeFromCart } from '../Store/cartSlice'; import styled from 'styled-components'; import { motion } from 'framer-motion'; +import "@fortawesome/fontawesome-free/css/all.min.css"; const CoffeeContainer = styled.div` padding: 6rem 2rem 4rem 2rem; // Added top padding for navbar @@ -173,6 +174,14 @@ function Coffee() { const dispatch = useDispatch(); const [quantities, setQuantities] = useState({}); const [searchQuery, setSearchQuery] = useState(''); + const [likedProducts, setLikedProducts] = useState({}); + + const toggleHeart = (productId) => { + setLikedProducts((prevState) => ({ + ...prevState, + [productId]: !prevState[productId], + })); + }; const handleAddToCart = (product) => { if (!quantities[product.id]) { @@ -410,7 +419,26 @@ const filteredProducts = products.filter((product) => <ProductGrid> {filteredProducts.map((product) => ( <ProductCard key={product.id}> - <ProductImage src={product.image} alt={product.name} /> + <div style={{ position: 'relative' }}> + <ProductImage src={product.image} alt={product.name} /> + + <div + onClick={() => toggleHeart(product.id)} + style={{ + position: 'absolute', + top: '10px', + right: '10px', + cursor: 'pointer', + fontSize: '24px', + color: likedProducts[product.id] ? 'red' : 'gray', + }} + > + <i + className={`fa-heart ${likedProducts[product.id] ? 'fas' : 'far' + }`} + ></i> + </div> + </div> <ProductInfo> <ProductName>{product.name}</ProductName> <ProductPrice>${product.price.toFixed(2)}</ProductPrice> @@ -418,7 +446,7 @@ const filteredProducts = products.filter((product) => <Button onClick={() => handleAddToCart(product)}> Add to Cart </Button> - + ) : ( <QuantityControls> <QuantityButton onClick={() => handleDecrement(product)}>-</QuantityButton> diff --git a/src/Pages/milkshake.js b/src/Pages/milkshake.js index cc9c099..2e7901a 100644 --- a/src/Pages/milkshake.js +++ b/src/Pages/milkshake.js @@ -3,6 +3,7 @@ import { useDispatch } from 'react-redux'; import { addToCart, removeFromCart } from '../Store/cartSlice'; import styled from 'styled-components'; import { motion } from 'framer-motion'; +import "@fortawesome/fontawesome-free/css/all.min.css"; const MilkshakeContainer = styled.div` padding: 6rem 2rem 4rem 2rem; // Added top padding for navbar @@ -175,6 +176,14 @@ function Milkshake() { const dispatch = useDispatch(); const [quantities, setQuantities] = useState({}); const [searchQuery, setSearchQuery] = useState(''); + const [likedProducts, setLikedProducts] = useState({}); + + const toggleHeart = (productId) => { + setLikedProducts((prevState) => ({ + ...prevState, + [productId]: !prevState[productId], + })); + }; const handleAddToCart = (product) => { if (!quantities[product.id]) { @@ -334,7 +343,26 @@ const filteredProducts = products.filter((product) => <ProductGrid> {filteredProducts.map((product) => ( <ProductCard key={product.id}> - <ProductImage src={product.image} alt={product.name} /> + <div style={{ position: 'relative' }}> + <ProductImage src={product.image} alt={product.name} /> + + <div + onClick={() => toggleHeart(product.id)} + style={{ + position: 'absolute', + top: '10px', + right: '10px', + cursor: 'pointer', + fontSize: '24px', + color: likedProducts[product.id] ? 'red' : 'gray', + }} + > + <i + className={`fa-heart ${likedProducts[product.id] ? 'fas' : 'far' + }`} + ></i> + </div> + </div> <ProductInfo> <ProductName>{product.name}</ProductName> <ProductPrice>${product.price.toFixed(2)}</ProductPrice> @@ -342,7 +370,7 @@ const filteredProducts = products.filter((product) => <Button onClick={() => handleAddToCart(product)}> Add to Cart </Button> - + ) : ( <QuantityControls> <QuantityButton onClick={() => handleDecrement(product)}>-</QuantityButton> diff --git a/src/Pages/soup.js b/src/Pages/soup.js index 7dd3c36..5e99146 100644 --- a/src/Pages/soup.js +++ b/src/Pages/soup.js @@ -3,6 +3,7 @@ import { useDispatch } from 'react-redux'; import { addToCart, removeFromCart } from '../Store/cartSlice'; import styled from 'styled-components'; import { motion } from 'framer-motion'; +import "@fortawesome/fontawesome-free/css/all.min.css"; const SoupContainer = styled.div` padding: 6rem 2rem 4rem 2rem; // Added top padding for navbar @@ -174,6 +175,14 @@ function Soup() { const dispatch = useDispatch(); const [quantities, setQuantities] = useState({}); const [searchQuery, setSearchQuery] = useState(''); + const [likedProducts, setLikedProducts] = useState({}); + + const toggleHeart = (productId) => { + setLikedProducts((prevState) => ({ + ...prevState, + [productId]: !prevState[productId], + })); + }; const handleAddToCart = (product) => { if (!quantities[product.id]) { @@ -296,7 +305,26 @@ const filteredProducts = products.filter((product) => <ProductGrid> {filteredProducts.map((product) => ( <ProductCard key={product.id}> - <ProductImage src={product.image} alt={product.name} /> + <div style={{ position: 'relative' }}> + <ProductImage src={product.image} alt={product.name} /> + + <div + onClick={() => toggleHeart(product.id)} + style={{ + position: 'absolute', + top: '10px', + right: '10px', + cursor: 'pointer', + fontSize: '24px', + color: likedProducts[product.id] ? 'red' : 'gray', + }} + > + <i + className={`fa-heart ${likedProducts[product.id] ? 'fas' : 'far' + }`} + ></i> + </div> + </div> <ProductInfo> <ProductName>{product.name}</ProductName> <ProductPrice>${product.price.toFixed(2)}</ProductPrice> @@ -304,7 +332,7 @@ const filteredProducts = products.filter((product) => <Button onClick={() => handleAddToCart(product)}> Add to Cart </Button> - + ) : ( <QuantityControls> <QuantityButton onClick={() => handleDecrement(product)}>-</QuantityButton> From f76234d21fd8c4a805b69cf426797381a4f2a791 Mon Sep 17 00:00:00 2001 From: Abhinav Shinde <143414991+Abhi9shinde@users.noreply.github.com> Date: Tue, 14 Jan 2025 18:24:57 +0530 Subject: [PATCH 06/17] fixed arrow in faq --- package-lock.json | 16 +++- package.json | 1 + src/Pages/Faq.js | 188 ++++++++++++++++--------------------------- src/componets/faq.js | 188 ++++++++++++++++--------------------------- 4 files changed, 156 insertions(+), 237 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5484b5c..c57441a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,6 +42,7 @@ "openai": "^4.78.0", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-icons": "^5.4.0", "react-locomotive-scroll": "^0.2.2", "react-redux": "^9.1.2", "react-router-dom": "^6.26.2", @@ -2627,7 +2628,6 @@ "version": "6.7.2", "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.7.2.tgz", "integrity": "sha512-JUOtgFW6k9u4Y+xeIaEiLr3+cjoUPiAuLXoyKOJSia6Duzb7pq+A76P9ZdPDoAoxHdHzq6gE9/jKBGXlZT8FbA==", - "license": "(CC-BY-4.0 AND OFL-1.1 AND MIT)", "engines": { "node": ">=6" } @@ -16366,6 +16366,14 @@ "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" }, + "node_modules/react-icons": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.4.0.tgz", + "integrity": "sha512-7eltJxgVt7X64oHh6wSWNwwbKTCtMfK35hcjvJS0yxEAhPM8oUKdS3+kqaW1vicIltw+kR2unHaa12S9pPALoQ==", + "peerDependencies": { + "react": "*" + } + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -31941,6 +31949,12 @@ "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" }, + "react-icons": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.4.0.tgz", + "integrity": "sha512-7eltJxgVt7X64oHh6wSWNwwbKTCtMfK35hcjvJS0yxEAhPM8oUKdS3+kqaW1vicIltw+kR2unHaa12S9pPALoQ==", + "requires": {} + }, "react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", diff --git a/package.json b/package.json index d61d996..5ff7236 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "openai": "^4.78.0", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-icons": "^5.4.0", "react-locomotive-scroll": "^0.2.2", "react-redux": "^9.1.2", "react-router-dom": "^6.26.2", diff --git a/src/Pages/Faq.js b/src/Pages/Faq.js index 1a0eae0..38dc287 100644 --- a/src/Pages/Faq.js +++ b/src/Pages/Faq.js @@ -1,6 +1,7 @@ -import React from 'react'; -import styled from 'styled-components'; -import { motion } from 'framer-motion'; +import React, { useState } from "react"; +import styled from "styled-components"; +import { motion } from "framer-motion"; +import { FaChevronDown, FaChevronUp } from "react-icons/fa"; // Importing arrows from react-icons const FAQContainer = styled.div` padding: 6rem 2rem 4rem 2rem; @@ -15,7 +16,7 @@ const FAQHeading = styled(motion.h1)` margin-bottom: 2rem; text-align: center; color: #78350f; - font-family: 'Playfair Display', serif; + font-family: "Playfair Display", serif; display: flex; flex-wrap: wrap; flex-direction: column; @@ -54,7 +55,7 @@ const FAQItem = styled(motion.div)` &:hover { transform: translateY(-10px); box-shadow: 0 15px 40px rgba(0, 0, 0, 0.2); - background-color:rgb(241, 224, 198)/* Coffee color */ + background-color: rgb(241, 224, 198); /* Coffee color */ } `; @@ -62,22 +63,44 @@ const Question = styled(motion.h3)` font-size: 1.5rem; margin-bottom: 1rem; color: #78350f; - font-family: 'Playfair Display', serif; + font-family: "Playfair Display", serif; cursor: pointer; font-weight: 550; + display: flex; + align-items: center; /* Aligns text and arrow horizontally */ + justify-content: space-between; /* Distributes space between question text and arrow */ + width: 100%; /* Ensure the question occupies full width */ `; const Answer = styled(motion.p)` font-size: 1.1rem; color: #6b4423; line-height: 1.6; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; max-height: 0; overflow: hidden; transition: max-height 0.4s ease-out; `; +const ArrowIcon = styled.div` + font-size: 2rem; /* Ensures arrow is large enough */ + transition: transform 1s ease; + transform: ${({ isOpen }) => (isOpen ? "rotate(180deg)" : "rotate(180deg)")}; + margin-left: 1rem; + display: inline-block; + vertical-align: middle; +`; + function FAQ() { + const [isOpen, setIsOpen] = useState({}); // state to track which FAQ is open + + const toggleAnswer = (index) => { + setIsOpen((prevState) => ({ + ...prevState, + [index]: !prevState[index], + })); + }; + return ( <FAQContainer> <FAQHeading @@ -88,121 +111,50 @@ function FAQ() { Frequently Asked Questions (FAQs) </FAQHeading> <FAQContent> - <FAQItem - initial={{ opacity: 0, y: 50 }} - animate={{ opacity: 1, y: 0 }} - transition={{ duration: 0.5, delay: 0.4 }} - onClick={() => { - const answer = document.getElementById('answer1'); - if (answer.style.maxHeight) { - answer.style.maxHeight = null; - } else { - answer.style.maxHeight = answer.scrollHeight + 'px'; - } - }} - > - <Question - initial={{ opacity: 0, x: -50 }} - animate={{ opacity: 1, x: 0 }} - transition={{ duration: 0.5, delay: 0.4 }} - > - How do I place an order? - </Question> - <Answer id="answer1" - initial={{ opacity: 0, x: 50 }} - animate={{ opacity: 1, x: 0 }} - transition={{ duration: 0.5, delay: 0.6 }} - > - To place an order, browse our collection and click the 'Add to Cart' button. When you're ready, proceed to checkout. - </Answer> - </FAQItem> - <FAQItem - initial={{ opacity: 0, y: 50 }} - animate={{ opacity: 1, y: 0 }} - transition={{ duration: 0.5, delay: 0.4 }} - onClick={() => { - const answer = document.getElementById('answer2'); - if (answer.style.maxHeight) { - answer.style.maxHeight = null; - } else { - answer.style.maxHeight = answer.scrollHeight + 'px'; - } - }} - > - <Question - initial={{ opacity: 0, x: -50 }} - animate={{ opacity: 1, x: 0 }} - transition={{ duration: 0.5 , delay: 0.4 }} - > - Can I modify my order after placing it? - </Question> - <Answer id="answer2" - initial={{ opacity: 0, x: 50 }} - animate={{ opacity: 1, x: 0 }} - transition={{ duration: 0.5, delay: 0.6 }} - > - Unfortunately, once an order is placed, it cannot be modified. However, you can cancel it and place a new one if needed. - </Answer> - </FAQItem> - <FAQItem - initial={{ opacity: 0, y: 50 }} - animate={{ opacity: 1, y: 0 }} - transition={{ duration: 0.5, delay: 0.6 }} - onClick={() => { - const answer = document.getElementById('answer3'); - if (answer.style.maxHeight) { - answer.style.maxHeight = null; - } else { - answer.style.maxHeight = answer.scrollHeight + 'px'; - } - }} - > - <Question - initial={{ opacity: 0, x: -50 }} - animate={{ opacity: 1, x: 0 }} + {[1, 2, 3, 4].map((index) => ( + <FAQItem + key={index} + initial={{ opacity: 0, y: 50 }} + animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5, delay: 0.4 }} + onClick={() => toggleAnswer(index)} > - What payment methods do you accept? - </Question> - <Answer id="answer3" - initial={{ opacity: 0, x: 50 }} - animate={{ opacity: 1, x: 0 }} - transition={{ duration: 0.5, delay: 0.6 }} - > - We accept various payment methods including credit cards, PayPal, and bank transfers. - </Answer> - </FAQItem> - <FAQItem - initial={{ opacity: 0, y: 50 }} - animate={{ opacity: 1, y: 0 }} - transition={{ duration: 0.5, delay: 0.8 }} - onClick={() => { - const answer = document.getElementById('answer4'); - if (answer.style.maxHeight) { - answer.style.maxHeight = null; - } else { - answer.style.maxHeight = answer.scrollHeight + 'px'; - } - }} - > - <Question - initial={{ opacity: 0, x: -50 }} - animate={{ opacity: 1, x: 0 }} - transition={{ duration: 0.5, delay: 0.4 }} - > - How can I track my order? - </Question> - <Answer id="answer4" - initial={{ opacity: 0, x: 50 }} - animate={{ opacity: 1, x: 0 }} - transition={{ duration: 0.5, delay: 0.6 }} - > - After your order is shipped, you will receive a tracking number via email to monitor your shipment. - </Answer> - </FAQItem> + <Question + initial={{ opacity: 0, x: -50 }} + animate={{ opacity: 1, x: 0 }} + transition={{ duration: 0.5, delay: 0.4 }} + > + {index === 1 && "How do I place an order?"} + {index === 2 && "Can I modify my order after placing it?"} + {index === 3 && "What payment methods do you accept?"} + {index === 4 && "How can I track my order?"} + <ArrowIcon isOpen={isOpen[index]}> + {isOpen[index] ? <FaChevronDown /> : <FaChevronUp />} + </ArrowIcon> + </Question> + <Answer + id={`answer${index}`} + initial={{ opacity: 0, x: 50 }} + animate={{ opacity: 1, x: 0 }} + transition={{ duration: 0.5, delay: 0.6 }} + style={{ + maxHeight: isOpen[index] ? "200px" : "0", // max-height for opening/closing + }} + > + {index === 1 && + 'To place an order, browse our collection and click the "Add to Cart" button. When you\'re ready, proceed to checkout.'} + {index === 2 && + "Unfortunately, once an order is placed, it cannot be modified. However, you can cancel it and place a new one if needed."} + {index === 3 && + "We accept various payment methods including credit cards, PayPal, and bank transfers."} + {index === 4 && + "After your order is shipped, you will receive a tracking number via email to monitor your shipment."} + </Answer> + </FAQItem> + ))} </FAQContent> </FAQContainer> ); } -export default FAQ; \ No newline at end of file +export default FAQ; diff --git a/src/componets/faq.js b/src/componets/faq.js index 1a0eae0..38dc287 100644 --- a/src/componets/faq.js +++ b/src/componets/faq.js @@ -1,6 +1,7 @@ -import React from 'react'; -import styled from 'styled-components'; -import { motion } from 'framer-motion'; +import React, { useState } from "react"; +import styled from "styled-components"; +import { motion } from "framer-motion"; +import { FaChevronDown, FaChevronUp } from "react-icons/fa"; // Importing arrows from react-icons const FAQContainer = styled.div` padding: 6rem 2rem 4rem 2rem; @@ -15,7 +16,7 @@ const FAQHeading = styled(motion.h1)` margin-bottom: 2rem; text-align: center; color: #78350f; - font-family: 'Playfair Display', serif; + font-family: "Playfair Display", serif; display: flex; flex-wrap: wrap; flex-direction: column; @@ -54,7 +55,7 @@ const FAQItem = styled(motion.div)` &:hover { transform: translateY(-10px); box-shadow: 0 15px 40px rgba(0, 0, 0, 0.2); - background-color:rgb(241, 224, 198)/* Coffee color */ + background-color: rgb(241, 224, 198); /* Coffee color */ } `; @@ -62,22 +63,44 @@ const Question = styled(motion.h3)` font-size: 1.5rem; margin-bottom: 1rem; color: #78350f; - font-family: 'Playfair Display', serif; + font-family: "Playfair Display", serif; cursor: pointer; font-weight: 550; + display: flex; + align-items: center; /* Aligns text and arrow horizontally */ + justify-content: space-between; /* Distributes space between question text and arrow */ + width: 100%; /* Ensure the question occupies full width */ `; const Answer = styled(motion.p)` font-size: 1.1rem; color: #6b4423; line-height: 1.6; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; max-height: 0; overflow: hidden; transition: max-height 0.4s ease-out; `; +const ArrowIcon = styled.div` + font-size: 2rem; /* Ensures arrow is large enough */ + transition: transform 1s ease; + transform: ${({ isOpen }) => (isOpen ? "rotate(180deg)" : "rotate(180deg)")}; + margin-left: 1rem; + display: inline-block; + vertical-align: middle; +`; + function FAQ() { + const [isOpen, setIsOpen] = useState({}); // state to track which FAQ is open + + const toggleAnswer = (index) => { + setIsOpen((prevState) => ({ + ...prevState, + [index]: !prevState[index], + })); + }; + return ( <FAQContainer> <FAQHeading @@ -88,121 +111,50 @@ function FAQ() { Frequently Asked Questions (FAQs) </FAQHeading> <FAQContent> - <FAQItem - initial={{ opacity: 0, y: 50 }} - animate={{ opacity: 1, y: 0 }} - transition={{ duration: 0.5, delay: 0.4 }} - onClick={() => { - const answer = document.getElementById('answer1'); - if (answer.style.maxHeight) { - answer.style.maxHeight = null; - } else { - answer.style.maxHeight = answer.scrollHeight + 'px'; - } - }} - > - <Question - initial={{ opacity: 0, x: -50 }} - animate={{ opacity: 1, x: 0 }} - transition={{ duration: 0.5, delay: 0.4 }} - > - How do I place an order? - </Question> - <Answer id="answer1" - initial={{ opacity: 0, x: 50 }} - animate={{ opacity: 1, x: 0 }} - transition={{ duration: 0.5, delay: 0.6 }} - > - To place an order, browse our collection and click the 'Add to Cart' button. When you're ready, proceed to checkout. - </Answer> - </FAQItem> - <FAQItem - initial={{ opacity: 0, y: 50 }} - animate={{ opacity: 1, y: 0 }} - transition={{ duration: 0.5, delay: 0.4 }} - onClick={() => { - const answer = document.getElementById('answer2'); - if (answer.style.maxHeight) { - answer.style.maxHeight = null; - } else { - answer.style.maxHeight = answer.scrollHeight + 'px'; - } - }} - > - <Question - initial={{ opacity: 0, x: -50 }} - animate={{ opacity: 1, x: 0 }} - transition={{ duration: 0.5 , delay: 0.4 }} - > - Can I modify my order after placing it? - </Question> - <Answer id="answer2" - initial={{ opacity: 0, x: 50 }} - animate={{ opacity: 1, x: 0 }} - transition={{ duration: 0.5, delay: 0.6 }} - > - Unfortunately, once an order is placed, it cannot be modified. However, you can cancel it and place a new one if needed. - </Answer> - </FAQItem> - <FAQItem - initial={{ opacity: 0, y: 50 }} - animate={{ opacity: 1, y: 0 }} - transition={{ duration: 0.5, delay: 0.6 }} - onClick={() => { - const answer = document.getElementById('answer3'); - if (answer.style.maxHeight) { - answer.style.maxHeight = null; - } else { - answer.style.maxHeight = answer.scrollHeight + 'px'; - } - }} - > - <Question - initial={{ opacity: 0, x: -50 }} - animate={{ opacity: 1, x: 0 }} + {[1, 2, 3, 4].map((index) => ( + <FAQItem + key={index} + initial={{ opacity: 0, y: 50 }} + animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5, delay: 0.4 }} + onClick={() => toggleAnswer(index)} > - What payment methods do you accept? - </Question> - <Answer id="answer3" - initial={{ opacity: 0, x: 50 }} - animate={{ opacity: 1, x: 0 }} - transition={{ duration: 0.5, delay: 0.6 }} - > - We accept various payment methods including credit cards, PayPal, and bank transfers. - </Answer> - </FAQItem> - <FAQItem - initial={{ opacity: 0, y: 50 }} - animate={{ opacity: 1, y: 0 }} - transition={{ duration: 0.5, delay: 0.8 }} - onClick={() => { - const answer = document.getElementById('answer4'); - if (answer.style.maxHeight) { - answer.style.maxHeight = null; - } else { - answer.style.maxHeight = answer.scrollHeight + 'px'; - } - }} - > - <Question - initial={{ opacity: 0, x: -50 }} - animate={{ opacity: 1, x: 0 }} - transition={{ duration: 0.5, delay: 0.4 }} - > - How can I track my order? - </Question> - <Answer id="answer4" - initial={{ opacity: 0, x: 50 }} - animate={{ opacity: 1, x: 0 }} - transition={{ duration: 0.5, delay: 0.6 }} - > - After your order is shipped, you will receive a tracking number via email to monitor your shipment. - </Answer> - </FAQItem> + <Question + initial={{ opacity: 0, x: -50 }} + animate={{ opacity: 1, x: 0 }} + transition={{ duration: 0.5, delay: 0.4 }} + > + {index === 1 && "How do I place an order?"} + {index === 2 && "Can I modify my order after placing it?"} + {index === 3 && "What payment methods do you accept?"} + {index === 4 && "How can I track my order?"} + <ArrowIcon isOpen={isOpen[index]}> + {isOpen[index] ? <FaChevronDown /> : <FaChevronUp />} + </ArrowIcon> + </Question> + <Answer + id={`answer${index}`} + initial={{ opacity: 0, x: 50 }} + animate={{ opacity: 1, x: 0 }} + transition={{ duration: 0.5, delay: 0.6 }} + style={{ + maxHeight: isOpen[index] ? "200px" : "0", // max-height for opening/closing + }} + > + {index === 1 && + 'To place an order, browse our collection and click the "Add to Cart" button. When you\'re ready, proceed to checkout.'} + {index === 2 && + "Unfortunately, once an order is placed, it cannot be modified. However, you can cancel it and place a new one if needed."} + {index === 3 && + "We accept various payment methods including credit cards, PayPal, and bank transfers."} + {index === 4 && + "After your order is shipped, you will receive a tracking number via email to monitor your shipment."} + </Answer> + </FAQItem> + ))} </FAQContent> </FAQContainer> ); } -export default FAQ; \ No newline at end of file +export default FAQ; From 1a7ae74e7e5b0a70014a3e88d5afc6d0220e4ed9 Mon Sep 17 00:00:00 2001 From: SurajSakhare100 <sakharesuraj10@gmail.com> Date: Tue, 14 Jan 2025 21:44:53 +0530 Subject: [PATCH 07/17] Login/Register Page UI updated --- src/Pages/Register.js | 286 ++++++++++++------------------------------ src/Pages/login.js | 248 ++++++++++-------------------------- 2 files changed, 145 insertions(+), 389 deletions(-) diff --git a/src/Pages/Register.js b/src/Pages/Register.js index 278deed..8e1cd81 100644 --- a/src/Pages/Register.js +++ b/src/Pages/Register.js @@ -1,211 +1,85 @@ -import React, { useState } from "react"; -import styled from "styled-components"; -import { motion } from "framer-motion"; -import { Link, useNavigate } from "react-router-dom"; -import { useDispatch } from "react-redux"; -import { login } from "../Store/authSlice"; - -const RegisterBackGround = styled.section` - background-image: url("https://img.freepik.com/free-photo/hot-latte-art-coffee-cup-wood-table-coffee-shop_1150-8937.jpg"); - background-size: cover; - background-position: center; - height: 100vh; -`; - -const RegisterContainer = styled.div` - display: flex; - justify-content: center; - align-items: center; - height: 100vh; - padding: 0 1rem; - backdrop-filter: blur(8px); - background: rgba(0, 0, 0, 0.6); -`; - -const RegisterForm = styled(motion.form)` - background-color: rgba(255, 255, 255, 0.9); - padding: 2.5rem; - border-radius: 12px; - box-shadow: 0 6px 12px rgba(0, 0, 0, 0.2); - width: 350px; - max-width: 90%; - text-align: center; - opacity: 1; - transition: opacity 0.6s ease-in-out; -`; - -const Heading = styled.h2` - margin-bottom: 1.5rem; - color: #7c2214; - font-size: 1.8rem; - font-weight: bold; -`; - -const Input = styled(motion.input)` - width: 100%; - padding: 0.8rem; - margin-bottom: 1.2rem; - border: 1px solid #ddd; - border-radius: 8px; - font-size: 1rem; - transition: all 0.3s ease; - - &:focus { - border-color: #7c2214; - outline: none; - box-shadow: 0 0 5px rgba(124, 34, 20, 0.5); - } - &:hover { - border-color: #aaa; - } -`; - -const Button = styled(motion.button)` - width: 100%; - padding: 0.8rem; - background-color: #7c2214; - color: white; - border: none; - border-radius: 8px; - font-size: 1rem; - font-weight: bold; - cursor: pointer; - transition: background-color 0.3s; - - &:hover { - background-color: #5b190f; - } -`; - -const LoginLink = styled(Link)` - display: block; - margin-top: 1.5rem; - font-size: 0.9rem; - color: #7c2214; - text-decoration: underline; - - &:hover { - text-decoration: none; - color: #5b190f; - } -`; - -const SuccessMessage = styled.div` - margin-top: 1.5rem; - color: green; - text-align: center; - font-weight: bold; -`; - -const ErrorMessage = styled.div` - margin-top: 1.5rem; - color: red; - text-align: center; - font-weight: bold; -`; - -const Register = () => { - const [formData, setFormData] = useState({ - username: "", - email: "", - password: "", - confirmPassword: "", - }); - - const [isSubmitted, setIsSubmitted] = useState(false); - const [error, setError] = useState(""); - const dispatch = useDispatch(); - const navigate = useNavigate(); - - const handleChange = (e) => { - const { name, value } = e.target; - setFormData({ - ...formData, - [name]: value, - }); - }; - - const handleSubmit = (e) => { - e.preventDefault(); - if(formData.password.length < 9){ - setError("Password must have a minimum of 8 characters"); - return; - } - else if (formData.password !== formData.confirmPassword) { - setError("Passwords do not match"); - return; - } - localStorage.setItem("user", JSON.stringify(formData)); - dispatch(login({ username: formData.username, email: formData.email })); - setIsSubmitted(true); - setError(""); - setTimeout(() => { - navigate("/"); - }, 2000); - }; +import React from "react"; +function SignupPage() { return ( - <RegisterBackGround> - <RegisterContainer> - <RegisterForm - initial={{ opacity: 0, y: 50 }} - animate={{ opacity: 1, y: 0 }} - transition={{ duration: 0.6 }} - onSubmit={handleSubmit} - > - <Heading>Register</Heading> - <Input - type="text" - name="username" - placeholder="Username" - value={formData.username} - onChange={handleChange} - required - whileFocus={{ scale: 1.03 }} - /> - <Input - type="email" - name="email" - placeholder="Email" - value={formData.email} - onChange={handleChange} - required - whileFocus={{ scale: 1.03 }} - /> - <Input - type="password" - name="password" - placeholder="Password" - value={formData.password} - onChange={handleChange} - required - whileFocus={{ scale: 1.03 }} - /> - <Input - type="password" - name="confirmPassword" - placeholder="Confirm Password" - value={formData.confirmPassword} - onChange={handleChange} - required - whileFocus={{ scale: 1.03 }} + <div className="flex items-center justify-center h-screen bg-gray-100"> + <div className="bg-[#D2B48C] rounded-lg shadow-lg overflow-hidden w-[900px] h-[500px] flex"> + {/* Left Side: Image */} + <div className="w-1/2"> + <img + src="https://www.shutterstock.com/image-photo/assorted-iced-coffee-on-white-600nw-2480796893.jpg" + alt="Coffee" + className="w-full h-full object-cover" /> - <Button - type="submit" - whileHover={{ scale: 1.05 }} - whileTap={{ scale: 0.95 }} - > - Register - </Button> - {error && <ErrorMessage>{error}</ErrorMessage>} - {isSubmitted && ( - <SuccessMessage>Registration successful!</SuccessMessage> - )} - <LoginLink to="/login">Already have an account? Login</LoginLink> - </RegisterForm> - </RegisterContainer> - </RegisterBackGround> + </div> + {/* Right Side: Signup Form */} + <div className="w-1/2 p-10 flex flex-col justify-center bg-white"> + <h2 className="text-3xl font-bold text-[#4E342E] text-center mb-6"> + Create an Account + </h2> + <form> + <div className="mb-4"> + <label + className="block text-gray-700 font-medium mb-2" + htmlFor="name" + > + Full Name + </label> + <input + type="text" + id="name" + placeholder="Enter your name" + className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[#6D4C41]" + /> + </div> + <div className="mb-4"> + <label + className="block text-gray-700 font-medium mb-2" + htmlFor="email" + > + Email Address + </label> + <input + type="email" + id="email" + placeholder="Enter your email" + className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[#6D4C41]" + /> + </div> + <div className="mb-4"> + <label + className="block text-gray-700 font-medium mb-2" + htmlFor="password" + > + Password + </label> + <input + type="password" + id="password" + placeholder="Enter your password" + className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[#6D4C41]" + /> + </div> + <button + type="submit" + className="w-full bg-[#4E342E] text-white py-2 px-4 rounded-lg hover:bg-[#3E2723] transition duration-300" + > + Sign Up + </button> + </form> + <p className="text-sm text-gray-600 text-center mt-6"> + Already have an account?{" "} + <a + href="/login" + className="text-[#6D4C41] font-medium hover:underline" + > + Log In + </a> + </p> + </div> + </div> + </div> ); -}; +} -export default Register; +export default SignupPage; diff --git a/src/Pages/login.js b/src/Pages/login.js index 4ff9da4..d651251 100644 --- a/src/Pages/login.js +++ b/src/Pages/login.js @@ -1,189 +1,71 @@ -import React, { useState } from "react"; -import { useDispatch } from "react-redux"; -import { login } from "../Store/authSlice"; -import styled from "styled-components"; -import { motion } from "framer-motion"; -import { Link, useNavigate } from "react-router-dom"; -const LoginBackGround = styled.section` - background-image: url('https://img.freepik.com/free-photo/hot-latte-art-coffee-cup-wood-table-coffee-shop_1150-8937.jpg'); - background-size: cover; - background-position: center; - height: 100vh; -`; - -const LoginContainer = styled.div` - display: flex; - justify-content: center; - align-items: center; - height: 100vh; - padding: 0 1rem; - backdrop-filter: blur(8px); - background: rgba(0, 0, 0, 0.6); -`; - -const LoginForm = styled(motion.form)` - background-color: rgba(255, 255, 255, 0.9); - padding: 2.5rem; - border-radius: 12px; - box-shadow: 0 6px 12px rgba(0, 0, 0, 0.2); - width: 350px; - max-width: 90%; - text-align: center; - opacity: 1; - transition: opacity 0.6s ease-in-out; -`; - -const Heading = styled.h2` - margin-bottom: 1.5rem; - color: #7c2214; - font-size: 1.8rem; - font-weight: bold; -`; - -const Input = styled.input` - width: 100%; - padding: 0.75rem; - margin-bottom: 1.2rem; - border: 1px solid #ddd; - border-radius: 8px; - font-size:1rem; - transition: border-color 0.3s ease,box-shadow 0.3s ease; - - &:focus{ - border-color: #7c2214; - box-shadow: rgba(0, 0, 0, 0.16) 0px 10px 36px 0px, rgba(0, 0, 0, 0.06) 0px 0px 0px 1px; - outline:none; - } - - &:hover { - border-color: #aaa; - } - - &::placeholder{ - color:#999; - } -`; - -const Button = styled(motion.button)` - width: 100%; - padding: 0.75rem; - background-color: #7c2214; - color: white; - border: none; - border-radius: 8px; - cursor: pointer; - font-size: 1rem; - font-weight: bold; - transition: background 0.3s ease, transform 0.2s ease; - - &:hover{ - background-color: #6c1a1a; - color: white; - text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.6); - transform: translateY(-2px); - } - - &:active{ - transform: translateY(0); - } - -`; - -const RegisterLink = styled(Link)` - display: block; - margin-top: 1rem; - text-align: center; - color: #7c2214; - text-decoration: none; -`; - -const ForgetPasswordLink = styled(Link)` - display: block; - margin-top: 0.5rem; - text-align: center; - color: #7c2214; - text-decoration: none; -`; - -const ErrorMessage = styled.div` - margin-top: 1rem; - color: red; - text-align: center; -`; - -function Login() { - const [username, setUsername] = useState(""); - const [email, setEmail] = useState(""); - const [password, setPassword] = useState(""); - const [error, setError] = useState(""); - const dispatch = useDispatch(); - const navigate = useNavigate(); - - const handleSubmit = (e) => { - e.preventDefault(); - const storedUser = JSON.parse(localStorage.getItem("user")); - if ( - storedUser && - storedUser.username === username && - storedUser.email === email && - storedUser.password === password - ) { - dispatch(login({ username, email })); - navigate("/"); // Redirect to home page - } else { - setError("Invalid credentials"); - } - }; +import React from "react"; +function LoginPage() { return ( - <LoginBackGround> - <LoginContainer> - <LoginForm - initial={{ opacity: 0, y: 50 }} - animate={{ opacity: 1, y: 0 }} - transition={{ duration: 0.5 }} - onSubmit={handleSubmit} - > - <Heading>Login</Heading> - <Input - type="text" - placeholder="Username" - value={username} - onChange={(e) => setUsername(e.target.value)} - required - /> - <Input - type="email" - placeholder="Email" - value={email} - onChange={(e) => setEmail(e.target.value)} - required - /> - <Input - type="password" - placeholder="Password" - value={password} - onChange={(e) => setPassword(e.target.value)} - required + <div className="flex items-center justify-center min-h-screen bg-gray-100"> + <div className="bg-[#D2B48C] rounded-lg shadow-lg overflow-hidden w-[900px] h-[500px] flex"> + {/* Left Side: Image */} + <div className="w-1/2"> + <img + src="https://www.shutterstock.com/image-photo/assorted-iced-coffee-on-white-600nw-2480796893.jpg" + alt="Coffee" + className="w-full h-full object-cover" /> - <Button - whileHover={{ scale: 1.05 }} - whileTap={{ scale: 0.95 }} - type="submit" - > - Login - </Button> - {error && <ErrorMessage>{error}</ErrorMessage>} - <RegisterLink to="/register"> - Don't have an account? <b>Register</b> - </RegisterLink> - <ForgetPasswordLink to="/forget-password"> - Forgot Password? - </ForgetPasswordLink> - </LoginForm> - </LoginContainer> - </LoginBackGround> + </div> + {/* Right Side: Login Form */} + <div className="w-1/2 p-10 flex flex-col justify-center bg-white"> + <h2 className="text-3xl font-bold text-[#4E342E] text-center mb-6"> + Welcome Back! + </h2> + <form> + <div className="mb-4"> + <label + className="block text-gray-700 font-medium mb-2" + htmlFor="email" + > + Email Address + </label> + <input + type="email" + id="email" + placeholder="Enter your email" + className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[#6D4C41]" + /> + </div> + <div className="mb-4"> + <label + className="block text-gray-700 font-medium mb-2" + htmlFor="password" + > + Password + </label> + <input + type="password" + id="password" + placeholder="Enter your password" + className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[#6D4C41]" + /> + </div> + <button + type="submit" + className="w-full bg-[#4E342E] text-white py-2 px-4 rounded-lg hover:bg-[#3E2723] transition duration-300" + > + Log In + </button> + </form> + <p className="text-sm text-gray-600 text-center mt-6"> + Don’t have an account?{" "} + <a + href="/register" + className="text-[#6D4C41] font-medium hover:underline" + > + Sign Up + </a> + </p> + </div> + </div> + </div> ); } -export default Login; +export default LoginPage; From 32cedb567bd805c58ae7246b84afd3e983c35603 Mon Sep 17 00:00:00 2001 From: tulikaa25 <tulikaa257@gmail.com> Date: Tue, 14 Jan 2025 23:24:42 +0530 Subject: [PATCH 08/17] add footer changes --- src/componets/FooterImg.png | Bin 0 -> 33942 bytes src/componets/footer.js | 33 +++++++++++++++++++++++++-------- 2 files changed, 25 insertions(+), 8 deletions(-) create mode 100644 src/componets/FooterImg.png diff --git a/src/componets/FooterImg.png b/src/componets/FooterImg.png new file mode 100644 index 0000000000000000000000000000000000000000..2f1e8f43e1d97edd3332f6599818be1891f6b54d GIT binary patch literal 33942 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 LNkvXXu0mjfYX>q5 literal 0 HcmV?d00001 diff --git a/src/componets/footer.js b/src/componets/footer.js index e199112..5719c43 100644 --- a/src/componets/footer.js +++ b/src/componets/footer.js @@ -2,11 +2,14 @@ import React from "react"; import styled from "styled-components"; import { motion } from "framer-motion"; import { Link } from "react-router-dom"; +import FooterImg from './FooterImg.png'; // Styled components for the footer const FooterContainer = styled.footer` - background: linear-gradient(135deg, #5b2c1a, #8e5234); - color: #fffbeb; + background: linear-gradient(90deg, rgba(148, 93, 56, 1), rgba(56, 39, 16, 1)); +-webkit-background: linear-gradient(90deg, rgba(148, 93, 56, 1), rgba(56, 39, 16, 1)); +-moz-background: linear-gradient(90deg, rgba(148, 93, 56, 1), rgba(56, 39, 16, 1)); + color: #fffbeb; padding: 1.5rem 2rem; text-align: center; position: relative; @@ -37,10 +40,19 @@ const FooterContent = styled.div` const InfoSection = styled.div` display: flex; - justify-content: space-between; + justify-content:space-between; + align-items:center; margin: 2rem 0; text-align: left; - + .infoimg + { + height:20rem; + padding-right:1rem; + } + .info-wrapper + { + display:flex; + } @media (max-width: 768px) { flex-direction: column; gap: 1.5rem; @@ -67,10 +79,11 @@ const InfoColumn = styled.div` } a:hover { - color: #fbbf24; + color: #fbbf24; + text-decoration: underline; } -`; +` const SocialIcons = styled.div` display: flex; @@ -129,7 +142,7 @@ const Divider = styled.hr` height: 2px; background: #ffd6a5; margin: 2rem auto; - width: 80%; + width: 60%; `; @@ -188,7 +201,9 @@ function Footer() { {/* Informational Sections */} <InfoSection> - <InfoColumn> + <img src={FooterImg} alt="Footer" className="infoimg"/> + <div className="info-wrapper"> + <InfoColumn> <h3>About Us</h3> <p> Founded in 2010, MsCafe is dedicated to serving the finest coffee @@ -222,6 +237,8 @@ function Footer() { </a> </p> </InfoColumn> + </div> + </InfoSection> {/* Footer Text */} From 6acaa02adb6c32a4b031c8dbec6f5bc5c5346ee1 Mon Sep 17 00:00:00 2001 From: Avni Sharma <sudhanshuvandil@gmail.com> Date: Wed, 15 Jan 2025 15:48:27 +0530 Subject: [PATCH 09/17] Create auto-comment.yml --- .github/workflows/auto-comment.yml | 75 ++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 .github/workflows/auto-comment.yml diff --git a/.github/workflows/auto-comment.yml b/.github/workflows/auto-comment.yml new file mode 100644 index 0000000..11d42c5 --- /dev/null +++ b/.github/workflows/auto-comment.yml @@ -0,0 +1,75 @@ +name: Automate Issue and PR Responses + +on: + issues: + types: + - opened + - closed + pull_request: + types: + - opened + - closed + +jobs: + respond-to-events: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + # Respond to new issues + - name: Respond to new issues + if: ${{ github.event_name == 'issues' && github.event.action == 'opened' }} + run: | + echo "Hey @${{ github.actor }}, Welcome to 💖coffeeShop! 🎊" > comment.txt + echo "Thanks for opening an issue! 🙌 Please wait for the issue to be assigned." >> comment.txt + echo "Happy Coding!! ✨" >> comment.txt + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: peter-evans/create-or-update-comment@v3 + with: + issue-number: ${{ github.event.issue.number }} + body-path: comment.txt + + # Respond to closed issues + - name: Respond to closed issues + if: ${{ github.event_name == 'issues' && github.event.action == 'closed' }} + run: | + echo "Hello @${{ github.event.issue.user.login }}! Your issue #${{ github.event.issue.number }} has been closed." > comment.txt + echo "Thank you for your contribution to 💖coffeeShop!!! 🙌" >> comment.txt + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: peter-evans/create-or-update-comment@v3 + with: + issue-number: ${{ github.event.issue.number }} + body-path: comment.txt + + # Respond to new PRs + - name: Respond to new PRs + if: ${{ github.event_name == 'pull_request' && github.event.action == 'opened' }} + run: | + echo "Hey @${{ github.actor }}, Welcome to 💖coffeeShop 🎊" > comment.txt + echo "Thanks for your contribution! Your effort makes this project better. Keep it up! 🙌" >> comment.txt + echo "Please wait for the PR to be reviewed." >> comment.txt + echo "Happy Coding!! ✨" >> comment.txt + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: peter-evans/create-or-update-comment@v3 + with: + issue-number: ${{ github.event.pull_request.number }} + body-path: comment.txt + + # Respond to merged PRs + - name: Respond to merged PRs + if: ${{ github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged }} + run: | + echo "@${{ github.event.pull_request.user.login }} Congrats, Your pull request has been successfully merged 🥳🎉" > comment.txt + echo "Thank you for your contribution to 💖coffeeShop!!" >> comment.txt + echo "Happy coding 🎊, Keep Contributing 🙌 !!!" >> comment.txt + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: peter-evans/create-or-update-comment@v3 + with: + issue-number: ${{ github.event.pull_request.number }} + body-path: comment.txt From 7567e4fbbb51fecb6242eb4eb03a243fb4f81966 Mon Sep 17 00:00:00 2001 From: divyanshii10 <149924007+divyanshii10@users.noreply.github.com> Date: Wed, 15 Jan 2025 18:32:45 +0530 Subject: [PATCH 10/17] proper alignment of navbar options --- package-lock.json | 132 ++++++++++++++++++++++++++++++++++++++++ src/componets/Navbar.js | 4 +- 2 files changed, 135 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index c9d1de9..873ade6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23968,6 +23968,27 @@ "undici-types": "~6.20.0" } }, + "@types/node-fetch": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==", + "requires": { + "@types/node": "*", + "form-data": "^4.0.0" + }, + "dependencies": { + "form-data": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + } + } + }, "@types/node-forge": { "version": "1.3.11", "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", @@ -24415,6 +24436,14 @@ "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==" }, + "abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "requires": { + "event-target-shim": "^5.0.0" + } + }, "accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -24485,6 +24514,14 @@ "debug": "4" } }, + "agentkeepalive": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", + "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==", + "requires": { + "humanize-ms": "^1.2.1" + } + }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -26874,6 +26911,11 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" }, + "event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" + }, "eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", @@ -27317,6 +27359,20 @@ "mime-types": "^2.1.12" } }, + "form-data-encoder": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", + "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==" + }, + "formdata-node": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", + "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", + "requires": { + "node-domexception": "1.0.0", + "web-streams-polyfill": "4.0.0-beta.3" + } + }, "forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -27834,6 +27890,14 @@ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==" }, + "humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "requires": { + "ms": "^2.0.0" + } + }, "iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -30369,6 +30433,40 @@ "tslib": "^2.0.3" } }, + "node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==" + }, + "node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "requires": { + "whatwg-url": "^5.0.0" + }, + "dependencies": { + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } + } + }, "node-forge": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", @@ -30562,6 +30660,35 @@ "is-wsl": "^2.2.0" } }, + "openai": { + "version": "4.78.0", + "resolved": "https://registry.npmjs.org/openai/-/openai-4.78.0.tgz", + "integrity": "sha512-4rRsKkx++5m1zayxkryVH+K/z91cv1sRbaNJAhSQjZiSCQOR7eaM8KpfIssXrS9Hlpta7+VcuO/fi57pW8xGjA==", + "requires": { + "@types/node": "^18.11.18", + "@types/node-fetch": "^2.6.4", + "abort-controller": "^3.0.0", + "agentkeepalive": "^4.2.1", + "form-data-encoder": "1.7.2", + "formdata-node": "^4.3.2", + "node-fetch": "^2.6.7" + }, + "dependencies": { + "@types/node": { + "version": "18.19.70", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.70.tgz", + "integrity": "sha512-RE+K0+KZoEpDUbGGctnGdkrLFwi1eYKTlIHNl2Um98mUkGsm1u2Ff6Ltd0e8DktTtC98uy7rSj+hO8t/QuLoVQ==", + "requires": { + "undici-types": "~5.26.4" + } + }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + } + } + }, "optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -34092,6 +34219,11 @@ "minimalistic-assert": "^1.0.0" } }, + "web-streams-polyfill": { + "version": "4.0.0-beta.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", + "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==" + }, "web-vitals": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-2.1.4.tgz", diff --git a/src/componets/Navbar.js b/src/componets/Navbar.js index 794ea58..e44130e 100644 --- a/src/componets/Navbar.js +++ b/src/componets/Navbar.js @@ -129,7 +129,9 @@ const NavLink = styled(motion.div)` font-size: 1.1rem; transition: all 0.3s ease; font-family: "Poppins", sans-serif; - padding: 25px; + padding: 20px; + + &:hover { color: #ffe4b5; From 4228c241668f02c6dba8776c5c0e35bba557e576 Mon Sep 17 00:00:00 2001 From: Jivan052 <jamadarjivan01@gmail.com> Date: Wed, 15 Jan 2025 22:19:22 +0530 Subject: [PATCH 11/17] Added navigation and chnaged some functionality --- src/Pages/Home.js | 41 +++++++++++++++++++++++++++-------------- src/componets/Navbar.js | 2 +- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/Pages/Home.js b/src/Pages/Home.js index 770792b..244be45 100644 --- a/src/Pages/Home.js +++ b/src/Pages/Home.js @@ -322,7 +322,6 @@ function Home() { src="https://img.freepik.com/free-photo/side-view-fresh-coffee-beans-falling-out-black-basket-red-background_141793-27586.jpg?t=st=1727759694~exp=1727763294~hmac=661c2c2b8c561df98b21f74effb9bb02a0875b0584c062f076bceafa5d6f7eda&w=1380" alt="Quality Beans" /> - <Link to="/premiumbeans"> <FeatureTitle>Premium Beans</FeatureTitle> </Link> @@ -354,22 +353,36 @@ function Home() { </FeatureCard> </FeaturesSection> <SpecialtySection ref={specialtyRef}> - <SpecialtyImage - src="https://img.freepik.com/free-photo/brown-coffee-beans-seed_74190-6651.jpg?ga=GA1.1.1542821208.1727756299&semt=ais_hybrid " - alt="Specialty Coffee 1" - /> - <SpecialtyImage - src="https://img.freepik.com/free-photo/coffee-machine-making-perfect-cup-coffee_23-2151699675.jpg?ga=GA1.1.1542821208.1727756299&semt=ais_hybrid" - alt="Specialty Coffee 2" - /> - <SpecialtyImage - src="https://img.freepik.com/free-photo/coffee-cup-with-beans_23-2148453628.jpg?t=st=1727760337~exp=1727763937~hmac=c326eb236a78a478ea9d9703e1bdbb8b390dcc71cefb24d78ca7a85bcb1c1cc5&w=740" - alt="Specialty Coffee 3" - /> + <div style={{ textAlign: 'center', margin: '1rem' }}> + <a href="/premiumbeans"> + <SpecialtyImage + src="https://img.freepik.com/free-photo/brown-coffee-beans-seed_74190-6651.jpg?ga=GA1.1.1542821208.1727756299&semt=ais_hybrid " + alt="Specialty Coffee 1" + /> + </a> + <Subtitle style={{ fontSize: '1.5rem', fontFamily: 'Playfair Display, serif' }}>Premium Beans</Subtitle> + </div> + <div style={{ textAlign: 'center', margin: '1rem' }}> + <a href="/shop/coffee"> + <SpecialtyImage + src="https://img.freepik.com/free-photo/coffee-machine-making-perfect-cup-coffee_23-2151699675.jpg?ga=GA1.1.1542821208.1727756299&semt=ais_hybrid" + alt="Specialty Coffee 2" + /> + </a> + <Subtitle style={{ fontSize: '1.5rem', fontFamily: 'Playfair Display, serif' }}>Special Flat White</Subtitle> + </div> + <div style={{ textAlign: 'center', margin: '1rem' }}> + <a href="/shop/coffee"> + <SpecialtyImage + src="https://img.freepik.com/free-photo/coffee-cup-with-beans_23-2148453628.jpg?t=st=1727760337~exp=1727763937~hmac=c326eb236a78a478ea9d9703e1bdbb8b390dcc71cefb24d78ca7a85bcb1c1cc5&w=740" + alt="Specialty Coffee 3" + /> + </a> + <Subtitle style={{ fontSize: '1.5rem', fontFamily: 'Playfair Display, serif' }}>Nitro Cold Brew</Subtitle> + </div> </SpecialtySection> <Faq /> </HomeContainer> ); } - export default Home; diff --git a/src/componets/Navbar.js b/src/componets/Navbar.js index 8f3646e..2132843 100644 --- a/src/componets/Navbar.js +++ b/src/componets/Navbar.js @@ -351,7 +351,7 @@ function Navbar() { </NavLinks> ); } - + if (items.title === "User") { return ( <NavLinks> From e6cd0daf874f283f46c0b59571184c72c5eb02d3 Mon Sep 17 00:00:00 2001 From: Jivan052 <jamadarjivan01@gmail.com> Date: Wed, 15 Jan 2025 22:28:31 +0530 Subject: [PATCH 12/17] dropdown chnage --- src/componets/Navitems.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/componets/Navitems.js b/src/componets/Navitems.js index bb0b3aa..1445317 100644 --- a/src/componets/Navitems.js +++ b/src/componets/Navitems.js @@ -89,10 +89,4 @@ export const userLoginDropdown = [ path: "./cart", cName: "submenu-item", }, - { - id: 2, - title: "profile", - path: "./profile", - cName: "submenu-item", - }, ]; From cc53de93d7617ecc1f8785c754c0da4fbd18d3db Mon Sep 17 00:00:00 2001 From: Jivan <137729176+Jivan052@users.noreply.github.com> Date: Wed, 15 Jan 2025 22:49:40 +0530 Subject: [PATCH 13/17] Update Home.js --- src/Pages/Home.js | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/Pages/Home.js b/src/Pages/Home.js index 411fc18..02dac40 100644 --- a/src/Pages/Home.js +++ b/src/Pages/Home.js @@ -377,21 +377,6 @@ function Home() { </a> <Subtitle style={{ fontSize: '1.5rem', fontFamily: 'Playfair Display, serif' }}>Nitro Cold Brew</Subtitle> </div> - - <h1>Our Specialities</h1> - <SpecialtyImage - src="https://img.freepik.com/free-photo/brown-coffee-beans-seed_74190-6651.jpg?ga=GA1.1.1542821208.1727756299&semt=ais_hybrid " - alt="Specialty Coffee 1" - /> - <SpecialtyImage - src="https://img.freepik.com/free-photo/coffee-machine-making-perfect-cup-coffee_23-2151699675.jpg?ga=GA1.1.1542821208.1727756299&semt=ais_hybrid" - alt="Specialty Coffee 2" - /> - <SpecialtyImage - src="https://img.freepik.com/free-photo/coffee-cup-with-beans_23-2148453628.jpg?t=st=1727760337~exp=1727763937~hmac=c326eb236a78a478ea9d9703e1bdbb8b390dcc71cefb24d78ca7a85bcb1c1cc5&w=740" - alt="Specialty Coffee 3" - /> - </SpecialtySection> </HomeContainer> ); From 5d889acb9cc1f415ddc71ba91663a0d1ec715585 Mon Sep 17 00:00:00 2001 From: Jivan <137729176+Jivan052@users.noreply.github.com> Date: Wed, 15 Jan 2025 22:51:28 +0530 Subject: [PATCH 14/17] Update Home.js --- src/Pages/Home.js | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/Pages/Home.js b/src/Pages/Home.js index 02dac40..244be45 100644 --- a/src/Pages/Home.js +++ b/src/Pages/Home.js @@ -7,7 +7,7 @@ import styled from "styled-components"; import Button from "../componets/Button"; import Faq from "../componets/faq"; import "./Home.css"; -import DynamicText from "./dynamicText"; + gsap.registerPlugin(ScrollTrigger); const HomeContainer = styled.div` @@ -19,9 +19,9 @@ const HomeContainer = styled.div` const HeroSection = styled.section` display: flex; - padding: 0; - margin: 0; - top: -2rem; + padding:0; + margin:0; + top:-2rem; flex-direction: column; align-items: center; justify-content: center; @@ -30,7 +30,7 @@ const HeroSection = styled.section` width: 100%; - gap: -0.5rem; + gap:-0.5rem; background-image: linear-gradient( rgba(44, 19, 11, 0.7), @@ -56,7 +56,8 @@ const HeroSection = styled.section` const Title = styled(motion.h1)` font-size: 5rem; - + + font-family: "Playfair Display", serif; color: #ffe4b5; @@ -67,20 +68,22 @@ const Title = styled(motion.h1)` const Subtitle = styled(motion.p)` font-size: 1.8rem; - + font-family: "Poppins", sans-serif; color: #deb887; max-width: 600px; + @media (max-width: 768px) { font-size: 1.4rem; + } `; const StyledButton = styled(Button)` background: #d2691e; color: #ffe4b5; - padding: 0.8rem; + padding:0.8rem; font-size: 1.2rem; border-radius: 30px; border: 2px solid #8b4513; @@ -96,9 +99,8 @@ const StyledButton = styled(Button)` } @media (min-width: 783px) { - font-size: 0.8rem; - padding: 0.5rem; - } + font-size:0.8rem; + padding: 0.5rem} `; const FeaturesSection = styled.section` @@ -110,6 +112,8 @@ const FeaturesSection = styled.section` position: relative; overflow: visible; + + @media (max-width: 768px) { padding: 4rem 2rem; gap: 2rem; @@ -179,9 +183,9 @@ const SpecialtySection = styled.section` background: #2c130b; position: relative; - & h1 { - width: 100%; - text-align: center; + &::before { + content: "Our Specialties"; + position: absolute; top: 2rem; left: 50%; transform: translateX(-50%); @@ -298,7 +302,7 @@ function Home() { animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.8, ease: "easeOut" }} > - <DynamicText text="Welcome to MsCafe" /> + Welcome to MsCafe - + ); } From 5bd01a34febeaccba22a8e7ed23c5fa524725f92 Mon Sep 17 00:00:00 2001 From: Ayush Kumar Date: Thu, 16 Jan 2025 19:24:14 +0530 Subject: [PATCH 15/17] in shop made the search button from rectangle shape to rounder corners add some margin form right to deattch the search icon , also made changes in the search icon also. --- src/Pages/Shop.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Pages/Shop.js b/src/Pages/Shop.js index 7aaf4f3..1d772a2 100644 --- a/src/Pages/Shop.js +++ b/src/Pages/Shop.js @@ -650,23 +650,26 @@ const SearchFilterContainer = styled.div` const SearchInput = styled.input` padding: 0.5rem; font-size: 1rem; - border: 1px solid #ddd; - border-radius: 4px 0 0 4px; + border: 2px solid brown; /* Updated border width and color */ + border-radius: 20px; /* Increased roundness */ outline: none; width: 300px; + margin-right: 1rem; /* Added margin on the right */ &:focus { - border-color: #6b4f4f; + border-color: #6b4f4f; /* Focus state border color */ } `; + const SearchButton = styled.button` padding: 0.5rem 1rem; font-size: 1rem; + font-weight: bold; background: linear-gradient(145deg, #6b4f4f, #7d5858); color: white; border: none; - border-radius: 0 4px 4px 0; + border-radius: 15px 15px 15px 15px; cursor: pointer; transition: background 0.3s ease; @@ -735,7 +738,7 @@ function Shop() { initial={{ opacity: 0, y: -50 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.8, ease: "easeOut" }} - text-weight="extrabold" + text-weight="bold-800" > From 13a0c9f72851a61276a6bcdc46df650889b2c9ec Mon Sep 17 00:00:00 2001 From: Janumala Akhilendra <82641474+JanumalaAkhilendra@users.noreply.github.com> Date: Thu, 16 Jan 2025 20:07:23 +0530 Subject: [PATCH 16/17] Update Navitems.js --- src/componets/Navitems.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/componets/Navitems.js b/src/componets/Navitems.js index e9fefd5..31bab08 100644 --- a/src/componets/Navitems.js +++ b/src/componets/Navitems.js @@ -34,13 +34,7 @@ export const navItems = [ title: "User", path: "./user", cName: "nav-item", - }, - { - id :6, - title:"About", - path:"./about", - cName:"nav-item", - }, + }. ]; From 8c201884ab966150cc707ea10bc31d5641ec01c3 Mon Sep 17 00:00:00 2001 From: Janumala Akhilendra <82641474+JanumalaAkhilendra@users.noreply.github.com> Date: Thu, 16 Jan 2025 20:13:12 +0530 Subject: [PATCH 17/17] Update Navitems.js --- src/componets/Navitems.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/componets/Navitems.js b/src/componets/Navitems.js index 31bab08..8ecb635 100644 --- a/src/componets/Navitems.js +++ b/src/componets/Navitems.js @@ -34,7 +34,7 @@ export const navItems = [ title: "User", path: "./user", cName: "nav-item", - }. + }, ];