From 8de5a39672cb2f9cf35ac4f22e84979c71280bcb Mon Sep 17 00:00:00 2001 From: Shivansh Date: Fri, 8 Nov 2024 06:04:34 +0530 Subject: [PATCH] vendor dashboard page --- .../[vendorId]/components/dishesPage.tsx | 52 ++++ .../app/vendor/[vendorId]/page.tsx | 14 +- alimento-nextjs/components/ui/carousel.tsx | 261 ++++++++++++++++++ .../components/vendor/dishCard.tsx | 83 ++++++ alimento-nextjs/package.json | 2 + alimento-nextjs/prisma/schema.prisma | 2 +- 6 files changed, 410 insertions(+), 4 deletions(-) create mode 100644 alimento-nextjs/app/vendor/[vendorId]/components/dishesPage.tsx create mode 100644 alimento-nextjs/components/ui/carousel.tsx create mode 100644 alimento-nextjs/components/vendor/dishCard.tsx diff --git a/alimento-nextjs/app/vendor/[vendorId]/components/dishesPage.tsx b/alimento-nextjs/app/vendor/[vendorId]/components/dishesPage.tsx new file mode 100644 index 0000000..ae47169 --- /dev/null +++ b/alimento-nextjs/app/vendor/[vendorId]/components/dishesPage.tsx @@ -0,0 +1,52 @@ +import React, { useState } from 'react'; +import { Button } from '@/components/ui/button'; // Import the Shadcn Button component +import Link from 'next/link'; +import { DishWithImages } from '../page'; +import DishCard from '@/components/vendor/dishCard'; + +const DishesPage = async ({ + vendorId, + Dishes, +}: { + vendorId: string + Dishes: DishWithImages[]; +}) => { + + return ( +
+
+

Your Dishes

+ + +
+ +
+ setSearchTerm(e.target.value)} + className="p-3 border rounded-full border-gray-300 w-full md:w-1/2" // Adjusted width to make it centered + /> +
+ +
+ {Dishes.map((Dish, index) => ( + + ))} +
+
+ ); +}; + +export default DishesPage; diff --git a/alimento-nextjs/app/vendor/[vendorId]/page.tsx b/alimento-nextjs/app/vendor/[vendorId]/page.tsx index 380f943..e60f994 100644 --- a/alimento-nextjs/app/vendor/[vendorId]/page.tsx +++ b/alimento-nextjs/app/vendor/[vendorId]/page.tsx @@ -1,6 +1,7 @@ import SetUpDishes from '@/components/multistepForm/setupDishes'; import prismadb from '@/lib/prismadb'; -import { Dish } from '@prisma/client'; +import { Dish, Image } from '@prisma/client'; +import DishesPage from './components/dishesPage'; interface VendorPageProps { params: { @@ -8,8 +9,12 @@ interface VendorPageProps { }; } +export interface DishWithImages extends Dish{ + images:Image[] +} + const VendorPage: React.FC = async ({ params }) => { - let Dishes: Dish[] | null = []; + let Dishes: DishWithImages[] | null = []; const { vendorId } = await params; try { @@ -17,6 +22,9 @@ const VendorPage: React.FC = async ({ params }) => { where: { vendorId: vendorId, }, + include:{ + images:true + } }); } catch (err) { console.error( @@ -26,7 +34,7 @@ const VendorPage: React.FC = async ({ params }) => { } if (Dishes.length){ - return
this will be the dishes page
+ return } else{ diff --git a/alimento-nextjs/components/ui/carousel.tsx b/alimento-nextjs/components/ui/carousel.tsx new file mode 100644 index 0000000..5a36366 --- /dev/null +++ b/alimento-nextjs/components/ui/carousel.tsx @@ -0,0 +1,261 @@ +"use client" + +import * as React from "react" +import useEmblaCarousel, { + type UseEmblaCarouselType, +} from "embla-carousel-react" +import { cn } from "@/lib/utils" +import { Button } from "@/components/ui/button" +import { ArrowLeftIcon, ArrowRightIcon } from "@radix-ui/react-icons" + +type CarouselApi = UseEmblaCarouselType[1] +type UseCarouselParameters = Parameters +type CarouselOptions = UseCarouselParameters[0] +type CarouselPlugin = UseCarouselParameters[1] + +type CarouselProps = { + opts?: CarouselOptions + plugins?: CarouselPlugin + orientation?: "horizontal" | "vertical" + setApi?: (api: CarouselApi) => void +} + +type CarouselContextProps = { + carouselRef: ReturnType[0] + api: ReturnType[1] + scrollPrev: () => void + scrollNext: () => void + canScrollPrev: boolean + canScrollNext: boolean +} & CarouselProps + +const CarouselContext = React.createContext(null) + +function useCarousel() { + const context = React.useContext(CarouselContext) + + if (!context) { + throw new Error("useCarousel must be used within a ") + } + + return context +} + +const Carousel = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes & CarouselProps +>( + ( + { + orientation = "horizontal", + opts, + setApi, + plugins, + className, + children, + ...props + }, + ref + ) => { + const [carouselRef, api] = useEmblaCarousel( + { + ...opts, + axis: orientation === "horizontal" ? "x" : "y", + }, + plugins + ) + const [canScrollPrev, setCanScrollPrev] = React.useState(false) + const [canScrollNext, setCanScrollNext] = React.useState(false) + + const onSelect = React.useCallback((api: CarouselApi) => { + if (!api) { + return + } + + setCanScrollPrev(api.canScrollPrev()) + setCanScrollNext(api.canScrollNext()) + }, []) + + const scrollPrev = React.useCallback(() => { + api?.scrollPrev() + }, [api]) + + const scrollNext = React.useCallback(() => { + api?.scrollNext() + }, [api]) + + const handleKeyDown = React.useCallback( + (event: React.KeyboardEvent) => { + if (event.key === "ArrowLeft") { + event.preventDefault() + scrollPrev() + } else if (event.key === "ArrowRight") { + event.preventDefault() + scrollNext() + } + }, + [scrollPrev, scrollNext] + ) + + React.useEffect(() => { + if (!api || !setApi) { + return + } + + setApi(api) + }, [api, setApi]) + + React.useEffect(() => { + if (!api) { + return + } + + onSelect(api) + api.on("reInit", onSelect) + api.on("select", onSelect) + + return () => { + api?.off("select", onSelect) + } + }, [api, onSelect]) + + return ( + +
+ {children} +
+
+ ) + } +) +Carousel.displayName = "Carousel" + +const CarouselContent = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => { + const { carouselRef, orientation } = useCarousel() + + return ( +
+
+
+ ) +}) +CarouselContent.displayName = "CarouselContent" + +const CarouselItem = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => { + const { orientation } = useCarousel() + + return ( +
+ ) +}) +CarouselItem.displayName = "CarouselItem" + +const CarouselPrevious = React.forwardRef< + HTMLButtonElement, + React.ComponentProps +>(({ className, variant = "outline", size = "icon", ...props }, ref) => { + const { orientation, scrollPrev, canScrollPrev } = useCarousel() + + return ( + + ) +}) +CarouselPrevious.displayName = "CarouselPrevious" + +const CarouselNext = React.forwardRef< + HTMLButtonElement, + React.ComponentProps +>(({ className, variant = "outline", size = "icon", ...props }, ref) => { + const { orientation, scrollNext, canScrollNext } = useCarousel() + + return ( + + ) +}) +CarouselNext.displayName = "CarouselNext" + +export { + type CarouselApi, + Carousel, + CarouselContent, + CarouselItem, + CarouselPrevious, + CarouselNext, +} diff --git a/alimento-nextjs/components/vendor/dishCard.tsx b/alimento-nextjs/components/vendor/dishCard.tsx new file mode 100644 index 0000000..424418b --- /dev/null +++ b/alimento-nextjs/components/vendor/dishCard.tsx @@ -0,0 +1,83 @@ +'use client'; +import React from 'react'; +import { Category, Image as ImageInterface, Tag } from '@prisma/client'; +import { + Carousel, + CarouselContent, + CarouselItem, +} from '@/components/ui/carousel'; +import Image from 'next/image'; +import Autoplay from 'embla-carousel-autoplay'; +import { Button } from '@/components/ui/button'; // Importing the Button component from Shadcn +import Link from 'next/link'; + +interface DishCardProps { + name: string; + price: number; + description: string; + vendorId:string + category: Category + images: ImageInterface[]; + tags: Tag[] + DishId: string +} + +const DishCard: React.FC = ({ + name, + vendorId, + price, + description, + category, + images, + DishId +}) => { + return ( +
+ + + {images.map((image, index) => ( + + {name} + + ))} + + +
+

{name}

+

{description}

+

Price: ₹{price}

+

Category: {category}

+
+ + + + +
+
+
+ ); +}; + +export default DishCard; diff --git a/alimento-nextjs/package.json b/alimento-nextjs/package.json index fadfb6b..23068f8 100644 --- a/alimento-nextjs/package.json +++ b/alimento-nextjs/package.json @@ -20,6 +20,8 @@ "axios": "^1.7.7", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", + "embla-carousel-autoplay": "^8.3.1", + "embla-carousel-react": "^8.3.1", "input-otp": "^1.4.1", "lucide-react": "^0.454.0", "next": "15.0.2", diff --git a/alimento-nextjs/prisma/schema.prisma b/alimento-nextjs/prisma/schema.prisma index f13fe88..c5ef52b 100644 --- a/alimento-nextjs/prisma/schema.prisma +++ b/alimento-nextjs/prisma/schema.prisma @@ -57,7 +57,7 @@ enum Tag { model Dish { id String @id @default(uuid()) @map("_id") name String - description String? + description String price Float category Category tags Tag[]