From b16c6f73ea877838e6239c182c8c9843dff1b72b Mon Sep 17 00:00:00 2001 From: Shivansh Date: Thu, 17 Oct 2024 19:33:32 +0530 Subject: [PATCH] Implemented load more functionality and global modal provider for under construction alert --- app/Categories/page.tsx | 7 +- app/Teams/page.tsx | 5 +- components/main-nav.tsx | 26 ++- components/navbar.tsx | 3 +- components/stores.tsx | 307 +++++++++++++++++++++++----- components/ui/underConstruction.tsx | 46 +++-- context/modalContext.tsx | 32 +++ providers/sessionProvider.tsx | 5 +- 8 files changed, 356 insertions(+), 75 deletions(-) create mode 100644 context/modalContext.tsx diff --git a/app/Categories/page.tsx b/app/Categories/page.tsx index bfe9942..12c5cc8 100644 --- a/app/Categories/page.tsx +++ b/app/Categories/page.tsx @@ -1,5 +1,4 @@ import Stores from "@/components/stores"; -import { Button } from "@/components/ui/button"; const Category = () => { return ( @@ -11,11 +10,7 @@ const Category = () => { {/* */} -
- -
+ ); }; diff --git a/app/Teams/page.tsx b/app/Teams/page.tsx index 4951df6..6fbf94a 100644 --- a/app/Teams/page.tsx +++ b/app/Teams/page.tsx @@ -1,10 +1,7 @@ -import UnderConstruction from "@/components/ui/underConstruction"; - const Teams = () => { return ( - - + <> //
//
//
diff --git a/components/main-nav.tsx b/components/main-nav.tsx index dac73d1..e878c1f 100644 --- a/components/main-nav.tsx +++ b/components/main-nav.tsx @@ -1,6 +1,6 @@ "use client"; -import React, { useState } from "react"; +import React, { useEffect, useState } from "react"; import { cn } from "@/lib/utils"; import Link from "next/link"; import { usePathname } from "next/navigation"; @@ -9,16 +9,27 @@ import { Heart, ShoppingCart } from "lucide-react"; // Import any required icons import { Menu, X } from "lucide-react"; // Icons for hamburger menu import { ModeToggle } from "./ui/themeButton"; import AuthButtons from "./authButtons"; +import { useConstruction } from "@/context/modalContext"; interface MainNavProps{ className?:React.HTMLAttributes theme:string } + export function MainNav({ className,theme }:MainNavProps) { + + const [loading,setLoading]=useState(true); + const {openDialog}=useConstruction(); const pathname = usePathname(); const [isOpen, setIsOpen] = useState(false); // State to toggle mobile menu visibility + useEffect(()=>{ + setLoading(false); + },[]) + + if(loading) return null; + const toggleMenu = () => setIsOpen(!isOpen); // Toggle function for menu const routes = [ @@ -29,7 +40,12 @@ export function MainNav({ className,theme }:MainNavProps) { label: "Categories", active: pathname.startsWith(`/Categories`), }, - { href: `/Teams`, label: "Teams", active: pathname.startsWith(`/Teams`) }, + { href: `#`, label: "Teams", active: pathname.startsWith(`/Teams`), + onClick: (e: React.MouseEvent) => { + e.preventDefault(); + openDialog(); + }, + }, { href: `/Blog`, label: "Blog", active: pathname.startsWith(`/Blog`) }, { href: `/MyOrders`, @@ -79,6 +95,7 @@ export function MainNav({ className,theme }:MainNavProps) { route.active ?`${theme==='dark'?'text-gray-500':'text-customTeal'}`:`${theme==='dark'?'text-gray-200':'text-customBlue'}`, theme=='dark'? `${'hover:text-gray-500'}`:`${'hover:text-customTeal'}` )} + onClick={route.onClick} > {route.logo && {route.logo}} {route.label} @@ -108,7 +125,10 @@ export function MainNav({ className,theme }:MainNavProps) { route.active ?`${theme==='dark'?'text-gray-200':'text-customTeal'}`:`${theme==='dark'?'text-gray-200':'text-customBlue'}`, theme=='dark'? `${'hover:text-gray-500'}`:`${'hover:text-customTeal'}` )} - onClick={toggleMenu} // Close menu on link click + onClick={(e) => { + toggleMenu(); // Close menu on link click + if (route.onClick) route.onClick(e); // Call route's onClick if it exists + }}// Close menu on link click > {route.logo && {route.logo}} {route.label} diff --git a/components/navbar.tsx b/components/navbar.tsx index c5397ad..da3e3b8 100644 --- a/components/navbar.tsx +++ b/components/navbar.tsx @@ -3,6 +3,7 @@ import Image from "next/image"; import Link from "next/link"; import { MainNav } from "./main-nav"; import { useTheme } from "@/context/themeProvider"; +import UnderConstructionAlert from "./ui/underConstruction"; // import { useTheme } from "@/context/ThemeContext"; // Import your theme context const Navbar = () => { @@ -29,7 +30,7 @@ const Navbar = () => { {/* all the navigation links */} - +
); diff --git a/components/stores.tsx b/components/stores.tsx index 02f7f22..6b8435e 100644 --- a/components/stores.tsx +++ b/components/stores.tsx @@ -1,3 +1,5 @@ +"use client" + import Image from "next/image"; import { Button } from "./ui/button"; import { @@ -9,98 +11,309 @@ import { CardTitle, } from "./ui/card"; import SeperatorHeading from "./ui/seperatorHeading"; +import { useState } from "react"; const cardData = [ { - id:1, - title: "Fashion & Accessories", - logo: "/fasion.png", - description: - "Explore the latest trends with exclusive offers on clothing, shoes and accessories", + id: 1, + title: "Fashion Hub", + logo: "/shops/fashion_image1.jpg", + description: "Explore trendy clothes for all ages.", category: "Fashion", - Offers: "50+ Brands", - deliveryTime: "Same day delivery", - StartingFrom: "$10", - ButtonLink: "/", + Offers: "30+ Brands", + deliveryTime: "1-2 day delivery", + StartingFrom: "$15", + ButtonLink: "/fashion-hub", }, { - id:2, - title: "Electronics & Gadgets", - logo: "/electronics.png", - description: - "Shop for the latest electronics and gadgets from top brands at the best prices.", - category: "Fashion", - Offers: "50+ Brands", - deliveryTime: "Same day delivery", + id: 2, + title: "Tech World", + logo: "/shops/tech_image1.jpg", + description: "Find the latest gadgets and electronics.", + category: "Electronics", + Offers: "40+ Brands", + deliveryTime: "Same-day delivery", + StartingFrom: "$100", + ButtonLink: "/tech-world", + }, + { + id: 3, + title: "Fresh Mart", + logo: "/shops/grocery_image1.jpg", + description: "Fresh produce and groceries at your doorstep.", + category: "Groceries", + Offers: "20+ Stores", + deliveryTime: "30 min delivery", StartingFrom: "$10", - ButtonLink: "/", + ButtonLink: "/fresh-mart", }, { - id:3, - title: "Groceries & Essentials", - logo: "/groceries.png", - description: - "Order fresh groceries and daily essentials from trusted local stores, delivered to your doorstep.", + id: 4, + title: "Style Studio", + logo: "/shops/fashion_image2.jpg", + description: "Discover designer clothes and accessories.", category: "Fashion", Offers: "50+ Brands", - deliveryTime: "30 min delivery", + deliveryTime: "2-3 day delivery", + StartingFrom: "$50", + ButtonLink: "/style-studio", + }, + { + id: 5, + title: "Gadget Zone", + logo: "/shops/tech_image2.jpg", + description: "Shop for cutting-edge technology products.", + category: "Electronics", + Offers: "30+ Brands", + deliveryTime: "Next-day delivery", + StartingFrom: "$150", + ButtonLink: "/gadget-zone", + }, + { + id: 6, + title: "Green Grocer", + logo: "/shops/grocery_image2.jpg", + description: "Organic and locally sourced produce.", + category: "Groceries", + Offers: "10+ Organic Stores", + deliveryTime: "45 min delivery", + StartingFrom: "$12", + ButtonLink: "/green-grocer", + }, + { + id: 7, + title: "Wellness Center", + logo: "/shops/wellness_image1.jpg", + description: "Health and wellness products for your well-being.", + category: "Health", + Offers: "30+ Brands", + deliveryTime: "2 day delivery", + StartingFrom: "$20", + ButtonLink: "/wellness-center", + }, + { + id: 8, + title: "Book Nook", + logo: "/shops/bookstore_image1.jpg", + description: "Browse a wide range of books and media.", + category: "Books", + Offers: "50+ Publishers", + deliveryTime: "2-3 day delivery", + StartingFrom: "$5", + ButtonLink: "/book-nook", + }, + { + id: 9, + title: "Toy Box", + logo: "/shops/toystore_image1.jpeg", + description: "Fun toys and games for all ages.", + category: "Toys", + Offers: "20+ Brands", + deliveryTime: "1-2 day delivery", StartingFrom: "$10", - ButtonLink: "/", + ButtonLink: "/toy-box", + }, + { + id: 10, + title: "Baby Bliss", + logo: "/shops/babystore_image1.jpg", + description: "Everything for babies and new mothers.", + category: "Baby Products", + Offers: "15+ Stores", + deliveryTime: "1 day delivery", + StartingFrom: "$8", + ButtonLink: "/baby-bliss", + }, + { + id: 11, + title: "Auto Zone", + logo: "/shops/automative_image1.jpg", + description: "Automotive parts and tools for your vehicle.", + category: "Automotive", + Offers: "10+ Brands", + deliveryTime: "3-4 day delivery", + StartingFrom: "$50", + ButtonLink: "/auto-zone", + }, + { + id: 12, + title: "Pet Paradise", + logo: "/shops/pet_image1.jpg", + description: "Supplies and accessories for your pets.", + category: "Pet Supplies", + Offers: "20+ Brands", + deliveryTime: "1-2 day delivery", + StartingFrom: "$5", + ButtonLink: "/pet-paradise", }, ]; + const Stores = () => { + const [showMore, setShowMore] = useState(false); + + // Slice stores: Display only 3 in the first row initially + const initialStores = cardData.slice(0, 3); + const remainingStores = cardData.slice(3); + return (
Shop for your favourite products
- -
- {cardData.map((card) => ( - + {initialStores.map((card) => ( +
-
- card image -
- - {card.description} - -
-
+
+ card image +
+ + {card.description} + +
+
{card.title}
-
-
Category
-
Offers Available
-
Delivery Time
-
Starting from
+
+ Category +
+
+ Offers Available +
+
+ Delivery Time +
+
+ Starting from +
-
{card.category}
-
{card.Offers}
-
{card.deliveryTime}
-
{card.StartingFrom}
+
+ {card.category} +
+
+ {card.Offers} +
+
+ {card.deliveryTime} +
+
+ {card.StartingFrom} +
-
))}
+ + {showMore && ( +
+ {remainingStores.map((card) => ( + + +
+
+ card image +
+ + {card.description} + +
+
+ + {card.title} + +
+
+ +
+
+
+ Category +
+
+ Offers Available +
+
+ Delivery Time +
+
+ Starting from +
+
+
+
+ {card.category} +
+
+ {card.Offers} +
+
+ {card.deliveryTime} +
+
+ {card.StartingFrom} +
+
+
+
+ + + +
+ ))} +
+ )} + + + +
); }; diff --git a/components/ui/underConstruction.tsx b/components/ui/underConstruction.tsx index e468e79..ba5d777 100644 --- a/components/ui/underConstruction.tsx +++ b/components/ui/underConstruction.tsx @@ -1,19 +1,39 @@ +"use client"; import { Construction } from "lucide-react"; +import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog"; +import { useConstruction } from "@/context/modalContext"; + +const UnderConstructionAlert = ({theme}:{theme:string}) => { + const { isOpen, closeDialog } = useConstruction(); -const UnderConstruction = () => { return ( -
-
- -
-
- This page is under development. We apologise for the inconvinience{" "} -
-
Please check back soon.
-
-
-
+ <> + {/* { + e.preventDefault(); // Prevent default link behavior + openDialog(); // Open the dialog globally + }} + > + This page is under construction + */} + + + + + + + This page is under development + +

+ We apologize for the inconvenience. Please check back soon. +

+
+
+
+ ); }; -export default UnderConstruction; +export default UnderConstructionAlert; diff --git a/context/modalContext.tsx b/context/modalContext.tsx new file mode 100644 index 0000000..0724aeb --- /dev/null +++ b/context/modalContext.tsx @@ -0,0 +1,32 @@ +"use client"; // Ensure it runs only in the browser + +import React, { createContext, useContext, useState, ReactNode } from "react"; + +interface ConstructionContextType { + isOpen: boolean; + openDialog: () => void; + closeDialog: () => void; +} + +const ConstructionContext = createContext(undefined); + +export const ConstructionProvider = ({ children }: { children: ReactNode }) => { + const [isOpen, setIsOpen] = useState(false); + + const openDialog = () => setIsOpen(true); + const closeDialog = () => setIsOpen(false); + + return ( + + {children} + + ); +}; + +export const useConstruction = () => { + const context = useContext(ConstructionContext); + if (!context) { + throw new Error("useConstruction must be used within a ConstructionProvider"); + } + return context; +}; diff --git a/providers/sessionProvider.tsx b/providers/sessionProvider.tsx index 83f7eec..04ffd7a 100644 --- a/providers/sessionProvider.tsx +++ b/providers/sessionProvider.tsx @@ -2,11 +2,14 @@ import React from "react"; import { SessionProvider } from "next-auth/react"; import { ThemeProvider } from "@/context/themeProvider"; +import { ConstructionProvider } from "@/context/modalContext"; export const Providers = ({ children }: { children: React.ReactNode }) => { return ( - {children} + + {children} + ); };