[
  {
    "path": ".eslintrc.json",
    "content": "{\n  \"extends\": \"next/core-web-vitals\",\n  \"rules\": {\n    \"no-unused-vars\": \"error\"\n  }\n}\n"
  },
  {
    "path": ".gitignore",
    "content": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pnp\n.pnp.js\n.yarn/install-state.gz\n\n# testing\n/coverage\n\n# next.js\n/.next/\n/out/\n\n# production\n/build\n\n# misc\n.DS_Store\n*.pem\n\n# debug\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# local env files\n.env*.local\n.env\n\n# vercel\n.vercel\n\n# typescript\n*.tsbuildinfo\nnext-env.d.ts\n\n# docker\n.postgres-data"
  },
  {
    "path": ".husky/commit-msg",
    "content": "#!/bin/sh\n. \"$(dirname \"$0\")/_/husky.sh\"\n\n.git/hooks/commit-msg $1"
  },
  {
    "path": ".husky/pre-commit",
    "content": "npx lint-staged\n"
  },
  {
    "path": ".lintstagedrc.json",
    "content": "{\n  \"*.ts?(x)\": [\"eslint --fix\", \"prettier --write\"]\n}\n"
  },
  {
    "path": ".prettierrc",
    "content": "{\n  \"plugins\": [\"prettier-plugin-tailwindcss\"]\n}\n"
  },
  {
    "path": "README.md",
    "content": "This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).\n\n## Getting Started\n\nFirst, run the development server:\n\n```bash\nnpm run dev\n# or\nyarn dev\n# or\npnpm dev\n# or\nbun dev\n```\n\nOpen [http://localhost:3000](http://localhost:3000) with your browser to see the result.\n\nYou can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.\n\nThis project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.\n\n## Learn More\n\nTo learn more about Next.js, take a look at the following resources:\n\n- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.\n- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.\n\nYou can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!\n\n## Deploy on Vercel\n\nThe easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.\n\nCheck out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.\n"
  },
  {
    "path": "app/_actions/order.ts",
    "content": "\"use server\";\n\nimport { Prisma } from \"@prisma/client\";\nimport { db } from \"../_lib/prisma\";\nimport { revalidatePath } from \"next/cache\";\n\nexport const createOrder = async (data: Prisma.OrderCreateInput) => {\n  await db.order.create({ data });\n  revalidatePath(\"/my-orders\");\n};\n"
  },
  {
    "path": "app/_actions/restaurant.ts",
    "content": "\"use server\";\n\nimport { revalidatePath } from \"next/cache\";\nimport { db } from \"../_lib/prisma\";\n\nexport const toggleFavoriteRestaurant = async (\n  userId: string,\n  restaurantId: string,\n) => {\n  const isFavorite = await db.userFavoriteRestaurant.findFirst({\n    where: {\n      userId,\n      restaurantId,\n    },\n  });\n\n  if (isFavorite) {\n    await db.userFavoriteRestaurant.delete({\n      where: {\n        userId_restaurantId: {\n          userId,\n          restaurantId,\n        },\n      },\n    });\n\n    revalidatePath(\"/\");\n    return;\n  }\n\n  await db.userFavoriteRestaurant.create({\n    data: {\n      userId,\n      restaurantId,\n    },\n  });\n\n  revalidatePath(\"/\");\n};\n"
  },
  {
    "path": "app/_components/cart-item.tsx",
    "content": "import Image from \"next/image\";\nimport { CartContext, CartProduct } from \"../_context/cart\";\nimport { calculateProductTotalPrice, formatCurrency } from \"../_helpers/price\";\nimport { Button } from \"./ui/button\";\nimport { ChevronLeftIcon, ChevronRightIcon, TrashIcon } from \"lucide-react\";\nimport { memo, useContext } from \"react\";\n\ninterface CartItemProps {\n  cartProduct: CartProduct;\n}\n\nconst CartItem = ({ cartProduct }: CartItemProps) => {\n  const {\n    decreaseProductQuantity,\n    increaseProductQuantity,\n    removeProductFromCart,\n  } = useContext(CartContext);\n\n  const handleDecreaseQuantityClick = () =>\n    decreaseProductQuantity(cartProduct.id);\n\n  const handleIncreaseQuantityClick = () =>\n    increaseProductQuantity(cartProduct.id);\n\n  const handleRemoveClick = () => removeProductFromCart(cartProduct.id);\n\n  return (\n    <div className=\"flex items-center justify-between\">\n      <div className=\"flex items-center gap-4\">\n        {/* IMAGEM E INFO */}\n        <div className=\"relative h-20 w-20\">\n          <Image\n            src={cartProduct.imageUrl}\n            alt={cartProduct.name}\n            fill\n            sizes=\"100%\"\n            className=\"rounded-lg object-cover\"\n          />\n        </div>\n\n        <div className=\"space-y-1\">\n          <h3 className=\"text-xs\">{cartProduct.name}</h3>\n\n          <div className=\"flex items-center gap-1\">\n            <h4 className=\"text-sm font-semibold\">\n              {formatCurrency(\n                calculateProductTotalPrice(cartProduct) * cartProduct.quantity,\n              )}\n            </h4>\n            {cartProduct.discountPercentage > 0 && (\n              <span className=\"text-xs text-muted-foreground line-through\">\n                {formatCurrency(\n                  Number(cartProduct.price) * cartProduct.quantity,\n                )}\n              </span>\n            )}\n          </div>\n\n          {/* QUANTIDADE */}\n\n          <div className=\"flex items-center text-center\">\n            <Button\n              size=\"icon\"\n              variant=\"ghost\"\n              className=\"h-7 w-7 border border-solid border-muted-foreground\"\n            >\n              <ChevronLeftIcon\n                size={16}\n                onClick={handleDecreaseQuantityClick}\n              />\n            </Button>\n            <p className=\"block w-8 text-xs\">{cartProduct.quantity}</p>\n            <Button\n              size=\"icon\"\n              className=\"h-7 w-7\"\n              onClick={handleIncreaseQuantityClick}\n            >\n              <ChevronRightIcon size={16} />\n            </Button>\n          </div>\n        </div>\n      </div>\n\n      {/* BOTÃO DE DELETAR */}\n      <Button\n        size=\"icon\"\n        variant=\"ghost\"\n        className=\"h-7 w-7 border border-solid border-muted-foreground\"\n        onClick={handleRemoveClick}\n      >\n        <TrashIcon size={16} />\n      </Button>\n    </div>\n  );\n};\n\nexport default memo(CartItem, (prev, next) => {\n  return prev.cartProduct.quantity === next.cartProduct.quantity;\n});\n"
  },
  {
    "path": "app/_components/cart.tsx",
    "content": "import { useContext, useState } from \"react\";\nimport { CartContext } from \"../_context/cart\";\nimport CartItem from \"./cart-item\";\nimport { Card, CardContent } from \"./ui/card\";\nimport { formatCurrency } from \"../_helpers/price\";\nimport { Separator } from \"./ui/separator\";\nimport { Button } from \"./ui/button\";\nimport { createOrder } from \"../_actions/order\";\nimport { OrderStatus } from \"@prisma/client\";\nimport { useSession } from \"next-auth/react\";\nimport { Loader2 } from \"lucide-react\";\nimport {\n  AlertDialog,\n  AlertDialogAction,\n  AlertDialogCancel,\n  AlertDialogContent,\n  AlertDialogDescription,\n  AlertDialogFooter,\n  AlertDialogHeader,\n  AlertDialogTitle,\n} from \"./ui/alert-dialog\";\nimport { toast } from \"sonner\";\nimport { useRouter } from \"next/navigation\";\n\ninterface CartProps {\n  // eslint-disable-next-line no-unused-vars\n  setIsOpen: (isOpen: boolean) => void;\n}\n\nconst Cart = ({ setIsOpen }: CartProps) => {\n  const router = useRouter();\n\n  const [isSubmitLoading, setIsSubmitLoading] = useState(false);\n  const [isConfirmDialogOpen, setIsConfirmDialogOpen] = useState(false);\n\n  const { data } = useSession();\n\n  const { products, subtotalPrice, totalPrice, totalDiscounts, clearCart } =\n    useContext(CartContext);\n\n  const handleFinishOrderClick = async () => {\n    if (!data?.user) return;\n\n    const restaurant = products[0].restaurant;\n\n    try {\n      setIsSubmitLoading(true);\n\n      await createOrder({\n        subtotalPrice,\n        totalDiscounts,\n        totalPrice,\n        deliveryFee: restaurant.deliveryFee,\n        deliveryTimeMinutes: restaurant.deliveryTimeMinutes,\n        restaurant: {\n          connect: { id: restaurant.id },\n        },\n        status: OrderStatus.CONFIRMED,\n        user: {\n          connect: { id: data.user.id },\n        },\n        products: {\n          createMany: {\n            data: products.map((product) => ({\n              productId: product.id,\n              quantity: product.quantity,\n            })),\n          },\n        },\n      });\n\n      clearCart();\n      setIsOpen(false);\n\n      toast(\"Pedido finalizado com sucesso!\", {\n        description: \"Você pode acompanhá-lo na tela dos seus pedidos.\",\n        action: {\n          label: \"Meus Pedidos\",\n          onClick: () => router.push(\"/my-orders\"),\n        },\n      });\n    } catch (error) {\n      console.error(error);\n    } finally {\n      setIsSubmitLoading(false);\n    }\n  };\n\n  return (\n    <>\n      <div className=\"flex h-full flex-col py-5\">\n        {products.length > 0 ? (\n          <>\n            <div className=\"flex-auto space-y-4\">\n              {products.map((product) => (\n                <CartItem key={product.id} cartProduct={product} />\n              ))}\n            </div>\n\n            {/* TOTAIS */}\n            <div className=\"mt-6\">\n              <Card>\n                <CardContent className=\"space-y-2 p-5\">\n                  <div className=\"flex items-center justify-between text-xs\">\n                    <span className=\"text-muted-foreground\">Subtotal</span>\n                    <span>{formatCurrency(subtotalPrice)}</span>\n                  </div>\n\n                  <Separator />\n\n                  <div className=\"flex items-center justify-between text-xs\">\n                    <span className=\"text-muted-foreground\">Descontos</span>\n                    <span>- {formatCurrency(totalDiscounts)}</span>\n                  </div>\n\n                  <Separator className=\"h-[0.5px]\" />\n\n                  <div className=\"flex items-center justify-between text-xs\">\n                    <span className=\"text-muted-foreground\">Entrega</span>\n\n                    {Number(products?.[0].restaurant.deliveryFee) === 0 ? (\n                      <span className=\"uppercase text-primary\">Grátis</span>\n                    ) : (\n                      formatCurrency(\n                        Number(products?.[0].restaurant.deliveryFee),\n                      )\n                    )}\n                  </div>\n\n                  <Separator />\n\n                  <div className=\"flex items-center justify-between text-xs font-semibold\">\n                    <span>Total</span>\n                    <span>{formatCurrency(totalPrice)}</span>\n                  </div>\n                </CardContent>\n              </Card>\n            </div>\n\n            {/* FINALIZAR PEDIDO */}\n            <Button\n              className=\"mt-6 w-full\"\n              onClick={() => setIsConfirmDialogOpen(true)}\n              disabled={isSubmitLoading}\n            >\n              Finalizar pedido\n            </Button>\n          </>\n        ) : (\n          <h2 className=\"text-left font-medium\">Sua sacola está vazia.</h2>\n        )}\n      </div>\n\n      <AlertDialog\n        open={isConfirmDialogOpen}\n        onOpenChange={setIsConfirmDialogOpen}\n      >\n        <AlertDialogContent>\n          <AlertDialogHeader>\n            <AlertDialogTitle>Deseja finalizar seu pedido?</AlertDialogTitle>\n            <AlertDialogDescription>\n              Ao finalizar seu pedido, você concorda com os termos e condições\n              da nossa plataforma.\n            </AlertDialogDescription>\n          </AlertDialogHeader>\n          <AlertDialogFooter>\n            <AlertDialogCancel>Cancelar</AlertDialogCancel>\n            <AlertDialogAction\n              onClick={handleFinishOrderClick}\n              disabled={isSubmitLoading}\n            >\n              {isSubmitLoading && (\n                <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n              )}\n              Finalizar\n            </AlertDialogAction>\n          </AlertDialogFooter>\n        </AlertDialogContent>\n      </AlertDialog>\n    </>\n  );\n};\n\nexport default Cart;\n"
  },
  {
    "path": "app/_components/category-item.tsx",
    "content": "import { Category } from \"@prisma/client\";\nimport Image from \"next/image\";\nimport Link from \"next/link\";\n\ninterface CategoryItemProps {\n  category: Category;\n}\n\nconst CategoryItem = ({ category }: CategoryItemProps) => {\n  return (\n    <Link\n      href={`/categories/${category.id}/products`}\n      className=\"flex items-center justify-center gap-3 rounded-full bg-white px-4 py-3 shadow-md\"\n    >\n      <Image\n        src={category.imageUrl}\n        alt={category.name}\n        height={30}\n        width={30}\n      />\n\n      <span className=\"text-sm font-semibold\">{category.name}</span>\n    </Link>\n  );\n};\n\nexport default CategoryItem;\n"
  },
  {
    "path": "app/_components/category-list.tsx",
    "content": "import { db } from \"../_lib/prisma\";\nimport CategoryItem from \"./category-item\";\n\nconst CategoryList = async () => {\n  const categories = await db.category.findMany({});\n\n  return (\n    <div className=\"grid grid-cols-2 gap-3\">\n      {categories.map((category) => (\n        <CategoryItem key={category.id} category={category} />\n      ))}\n    </div>\n  );\n};\n\nexport default CategoryList;\n"
  },
  {
    "path": "app/_components/delivery-info.tsx",
    "content": "import { BikeIcon, TimerIcon } from \"lucide-react\";\nimport { Card } from \"./ui/card\";\nimport { formatCurrency } from \"../_helpers/price\";\nimport { Restaurant } from \"@prisma/client\";\n\ninterface DeliveryInfoProps {\n  restaurant: Pick<Restaurant, \"deliveryFee\" | \"deliveryTimeMinutes\">;\n}\n\nconst DeliveryInfo = ({ restaurant }: DeliveryInfoProps) => {\n  return (\n    <>\n      <Card className=\"mt-6 flex justify-around py-3\">\n        {/* CUSTO */}\n        <div className=\"flex flex-col items-center\">\n          <div className=\"flex items-center gap-1 text-muted-foreground\">\n            <span className=\"text-xs\">Entrega</span>\n            <BikeIcon size={14} />\n          </div>\n\n          {Number(restaurant.deliveryFee) > 0 ? (\n            <p className=\"text-xs font-semibold\">\n              {formatCurrency(Number(restaurant.deliveryFee))}\n            </p>\n          ) : (\n            <p className=\"text-xs font-semibold\">Grátis</p>\n          )}\n        </div>\n\n        {/* TEMPO */}\n        <div className=\"flex flex-col items-center\">\n          <div className=\"flex items-center gap-1 text-muted-foreground\">\n            <span className=\"text-xs\">Entrega</span>\n            <TimerIcon size={14} />\n          </div>\n\n          <p className=\"text-xs font-semibold\">\n            {restaurant.deliveryTimeMinutes} min\n          </p>\n        </div>\n      </Card>\n    </>\n  );\n};\n\nexport default DeliveryInfo;\n"
  },
  {
    "path": "app/_components/discount-badge.tsx",
    "content": "import { Product } from \"@prisma/client\";\nimport { ArrowDownIcon } from \"lucide-react\";\n\ninterface DiscountBadgeProps {\n  product: Pick<Product, \"discountPercentage\">;\n}\n\nconst DiscountBadge = ({ product }: DiscountBadgeProps) => {\n  return (\n    <div className=\"flex items-center gap-[2px] rounded-full bg-primary px-2 py-[2px] text-white\">\n      <ArrowDownIcon size={12} />\n      <span className=\"text-xs font-semibold\">\n        {product.discountPercentage}%\n      </span>\n    </div>\n  );\n};\n\nexport default DiscountBadge;\n"
  },
  {
    "path": "app/_components/header.tsx",
    "content": "\"use client\";\n\nimport Image from \"next/image\";\nimport { Button } from \"./ui/button\";\nimport {\n  HeartIcon,\n  HomeIcon,\n  LogInIcon,\n  LogOutIcon,\n  MenuIcon,\n  ScrollTextIcon,\n} from \"lucide-react\";\nimport Link from \"next/link\";\nimport { signIn, signOut, useSession } from \"next-auth/react\";\nimport {\n  Sheet,\n  SheetContent,\n  SheetHeader,\n  SheetTitle,\n  SheetTrigger,\n} from \"./ui/sheet\";\nimport { Avatar, AvatarFallback, AvatarImage } from \"./ui/avatar\";\nimport { Separator } from \"./ui/separator\";\n\nconst Header = () => {\n  const { data } = useSession();\n\n  const handleSignOutClick = () => signOut();\n  const handleSignInClick = () => signIn();\n\n  return (\n    <div className=\"flex justify-between px-5 pt-6\">\n      <Link href=\"/\">\n        <div className=\"relative h-[30px] w-[100px]\">\n          <Image\n            src=\"/logo.png\"\n            alt=\"FSW Foods\"\n            sizes=\"100%\"\n            fill\n            className=\"object-cover\"\n          />\n        </div>\n      </Link>\n\n      <Sheet>\n        <SheetTrigger asChild>\n          <Button\n            size=\"icon\"\n            variant=\"outline\"\n            className=\"border-none bg-transparent\"\n          >\n            <MenuIcon />\n          </Button>\n        </SheetTrigger>\n\n        <SheetContent>\n          <SheetHeader>\n            <SheetTitle className=\"text-left\">Menu</SheetTitle>\n          </SheetHeader>\n\n          {data?.user ? (\n            <>\n              <div className=\"flex justify-between pt-6\">\n                <div className=\"flex items-center gap-3\">\n                  <Avatar>\n                    <AvatarImage\n                      src={data?.user?.image as string | undefined}\n                    />\n                    <AvatarFallback>\n                      {data?.user?.name?.split(\" \")[0][0]}\n                      {data?.user?.name?.split(\" \")[1][0]}\n                    </AvatarFallback>\n                  </Avatar>\n\n                  <div>\n                    <h3 className=\"font-semibold\">{data?.user?.name}</h3>\n                    <span className=\"block text-xs text-muted-foreground\">\n                      {data?.user?.email}\n                    </span>\n                  </div>\n                </div>\n              </div>\n            </>\n          ) : (\n            <>\n              <div className=\"flex items-center justify-between pt-10\">\n                <h2 className=\"font-semibold\">Olá. Faça seu login!</h2>\n                <Button size=\"icon\" onClick={handleSignInClick}>\n                  <LogInIcon />\n                </Button>\n              </div>\n            </>\n          )}\n\n          <div className=\"py-6\">\n            <Separator />\n          </div>\n\n          <div className=\"space-y-2\">\n            <Button\n              variant=\"ghost\"\n              className=\"w-full justify-start space-x-3 rounded-full text-sm font-normal\"\n            >\n              <HomeIcon size={16} />\n              <span className=\"block\">Início</span>\n            </Button>\n\n            {data?.user && (\n              <>\n                <Button\n                  variant=\"ghost\"\n                  className=\"w-full justify-start space-x-3 rounded-full text-sm font-normal\"\n                  asChild\n                >\n                  <Link href=\"/my-orders\">\n                    <ScrollTextIcon size={16} />\n                    <span className=\"block\">Meus Pedidos</span>\n                  </Link>\n                </Button>\n\n                <Button\n                  variant=\"ghost\"\n                  className=\"w-full justify-start space-x-3 rounded-full text-sm font-normal\"\n                  asChild\n                >\n                  <Link href=\"/my-favorite-restaurants\">\n                    <HeartIcon size={16} />\n                    <span className=\"block\">Restaurantes Favoritos</span>\n                  </Link>\n                </Button>\n              </>\n            )}\n          </div>\n\n          <div className=\"py-6\">\n            <Separator />\n          </div>\n\n          {data?.user && (\n            <Button\n              variant=\"ghost\"\n              className=\"w-full justify-start space-x-3 rounded-full text-sm font-normal\"\n              onClick={handleSignOutClick}\n            >\n              <LogOutIcon size={16} />\n              <span className=\"block\">Sair da conta</span>\n            </Button>\n          )}\n        </SheetContent>\n      </Sheet>\n    </div>\n  );\n};\n\nexport default Header;\n"
  },
  {
    "path": "app/_components/product-item.tsx",
    "content": "\"use client\";\n\nimport { Prisma } from \"@prisma/client\";\nimport Image from \"next/image\";\nimport { calculateProductTotalPrice, formatCurrency } from \"../_helpers/price\";\nimport { ArrowDownIcon } from \"lucide-react\";\nimport Link from \"next/link\";\nimport { cn } from \"../_lib/utils\";\n\ninterface ProductItemProps {\n  product: Prisma.ProductGetPayload<{\n    include: {\n      restaurant: {\n        select: {\n          name: true;\n        };\n      };\n    };\n  }>;\n  className?: string;\n}\n\nconst ProductItem = ({ product, className }: ProductItemProps) => {\n  return (\n    <Link\n      className={cn(\"w-[150px] min-w-[150px]\", className)}\n      href={`/products/${product.id}`}\n    >\n      <div className=\"w-full space-y-2\">\n        <div className=\"relative aspect-square w-full\">\n          <Image\n            src={product.imageUrl}\n            alt={product.name}\n            fill\n            sizes=\"100%\"\n            className=\"rounded-lg object-cover shadow-md\"\n          />\n\n          {product.discountPercentage && (\n            <div className=\"absolute left-2 top-2 flex items-center gap-[2px] rounded-full bg-primary px-2 py-[2px] text-white\">\n              <ArrowDownIcon size={12} />\n              <span className=\"text-xs font-semibold\">\n                {product.discountPercentage}%\n              </span>\n            </div>\n          )}\n        </div>\n\n        <div>\n          <h2 className=\"truncate text-sm\">{product.name}</h2>\n          <div className=\"flex items-center gap-1\">\n            <h3 className=\"font-semibold\">\n              {formatCurrency(calculateProductTotalPrice(product))}\n            </h3>\n            {product.discountPercentage > 0 && (\n              <span className=\"text-xs text-muted-foreground line-through\">\n                {formatCurrency(Number(product.price))}\n              </span>\n            )}\n          </div>\n\n          <span className=\"block text-xs text-muted-foreground\">\n            {product.restaurant.name}\n          </span>\n        </div>\n      </div>\n    </Link>\n  );\n};\n\nexport default ProductItem;\n"
  },
  {
    "path": "app/_components/product-list.tsx",
    "content": "import { Prisma } from \"@prisma/client\";\nimport ProductItem from \"./product-item\";\n\ninterface ProductListProps {\n  products: Prisma.ProductGetPayload<{\n    include: {\n      restaurant: {\n        select: {\n          name: true;\n        };\n      };\n    };\n  }>[];\n}\n\nconst ProductList = ({ products }: ProductListProps) => {\n  return (\n    <div className=\"flex gap-4 overflow-x-scroll px-5 [&::-webkit-scrollbar]:hidden\">\n      {products.map((product) => (\n        <ProductItem key={product.id} product={product} />\n      ))}\n    </div>\n  );\n};\n\nexport default ProductList;\n"
  },
  {
    "path": "app/_components/promo-banner.tsx",
    "content": "import Image, { ImageProps } from \"next/image\";\n\nconst PromoBanner = (props: ImageProps) => {\n  return (\n    <Image\n      height={0}\n      width={0}\n      className=\"h-auto w-full object-contain\"\n      sizes=\"100%\"\n      quality={100}\n      {...props}\n    />\n  );\n};\n\nexport default PromoBanner;\n"
  },
  {
    "path": "app/_components/restaurant-item.tsx",
    "content": "\"use client\";\n\nimport { Restaurant, UserFavoriteRestaurant } from \"@prisma/client\";\nimport { BikeIcon, HeartIcon, StarIcon, TimerIcon } from \"lucide-react\";\nimport Image from \"next/image\";\nimport { formatCurrency } from \"../_helpers/price\";\nimport { Button } from \"./ui/button\";\nimport Link from \"next/link\";\nimport { cn } from \"../_lib/utils\";\nimport { toggleFavoriteRestaurant } from \"../_actions/restaurant\";\nimport { toast } from \"sonner\";\nimport { useSession } from \"next-auth/react\";\n\ninterface RestaurantItemProps {\n  restaurant: Restaurant;\n  className?: string;\n  userFavoriteRestaurants: UserFavoriteRestaurant[];\n}\n\nconst RestaurantItem = ({\n  restaurant,\n  className,\n  userFavoriteRestaurants,\n}: RestaurantItemProps) => {\n  const { data } = useSession();\n  const isFavorite = userFavoriteRestaurants.some(\n    (fav) => fav.restaurantId === restaurant.id,\n  );\n\n  const handleFavoriteClick = async () => {\n    if (!data?.user.id) return;\n    try {\n      await toggleFavoriteRestaurant(data?.user.id, restaurant.id);\n      toast.success(\n        isFavorite\n          ? \"Restaurante removido dos favoritos.\"\n          : \"Restaurante favoritado.\",\n      );\n    } catch (error) {\n      toast.error(\"Erro ao favoritar restaurante.\");\n    }\n  };\n\n  return (\n    <div className={cn(\"min-w-[266px] max-w-[266px]\", className)}>\n      <div className=\"w-full space-y-3\">\n        {/* IMAGEM */}\n        <div className=\"relative h-[136px] w-full\">\n          <Link href={`/restaurants/${restaurant.id}`}>\n            <Image\n              src={restaurant.imageUrl}\n              fill\n              sizes=\"100%\"\n              className=\"rounded-lg object-cover\"\n              alt={restaurant.name}\n            />\n          </Link>\n\n          <div className=\"absolute left-2 top-2 flex items-center gap-[2px] rounded-full bg-primary bg-white px-2 py-[2px]\">\n            <StarIcon size={12} className=\"fill-yellow-400 text-yellow-400\" />\n            <span className=\"text-xs font-semibold\">5.0</span>\n          </div>\n\n          {data?.user.id && (\n            <Button\n              size=\"icon\"\n              className={`absolute right-2 top-2 h-7 w-7 rounded-full bg-gray-700 ${isFavorite && \"bg-primary hover:bg-gray-700\"}`}\n              onClick={handleFavoriteClick}\n            >\n              <HeartIcon size={16} className=\"fill-white\" />\n            </Button>\n          )}\n        </div>\n        {/* TEXTO */}\n        <div>\n          <h3 className=\"text-sm font-semibold\">{restaurant.name}</h3>\n          {/* INFORMAÇÕES DA ENTREGA */}\n          <div className=\"flex gap-3\">\n            {/* CUSTO DE ENTREGA */}\n            <div className=\"flex items-center gap-1\">\n              <BikeIcon className=\"text-primary\" size={14} />\n              <span className=\"text-xs text-muted-foreground\">\n                {Number(restaurant.deliveryFee) === 0\n                  ? \"Entrega grátis\"\n                  : formatCurrency(Number(restaurant.deliveryFee))}\n              </span>\n            </div>\n            {/* TEMPO DE ENTREGA */}\n            <div className=\"flex items-center gap-1\">\n              <TimerIcon className=\"text-primary\" size={14} />\n              <span className=\"text-xs text-muted-foreground\">\n                {restaurant.deliveryTimeMinutes} min\n              </span>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  );\n};\n\nexport default RestaurantItem;\n"
  },
  {
    "path": "app/_components/restaurant-list.tsx",
    "content": "import { getServerSession } from \"next-auth\";\nimport { db } from \"../_lib/prisma\";\nimport RestaurantItem from \"./restaurant-item\";\nimport { authOptions } from \"../_lib/auth\";\n\nconst RestaurantList = async () => {\n  const session = await getServerSession(authOptions);\n\n  // TODO: pegar restaurantes com maior número de pedidos\n  const restaurants = await db.restaurant.findMany({ take: 10 });\n  const userFavoriteRestaurants = await db.userFavoriteRestaurant.findMany({\n    where: { userId: session?.user?.id },\n  });\n\n  return (\n    <div className=\"flex gap-4 overflow-x-scroll px-5 [&::-webkit-scrollbar]:hidden\">\n      {restaurants.map((restaurant) => (\n        <RestaurantItem\n          key={restaurant.id}\n          restaurant={restaurant}\n          userFavoriteRestaurants={userFavoriteRestaurants}\n        />\n      ))}\n    </div>\n  );\n};\n\nexport default RestaurantList;\n"
  },
  {
    "path": "app/_components/search.tsx",
    "content": "\"use client\";\n\nimport { SearchIcon } from \"lucide-react\";\nimport { Button } from \"./ui/button\";\nimport { Input } from \"./ui/input\";\nimport { FormEventHandler, useState } from \"react\";\nimport { useRouter } from \"next/navigation\";\n\nconst Search = () => {\n  const router = useRouter();\n  const [search, setSearch] = useState(\"\");\n\n  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n    setSearch(e.target.value);\n  };\n\n  const handleSearchSubmit: FormEventHandler<HTMLFormElement> = (e) => {\n    e.preventDefault();\n\n    if (!search) {\n      return;\n    }\n\n    router.push(`/restaurants?search=${search}`);\n  };\n\n  return (\n    <form className=\"flex gap-2\" onSubmit={handleSearchSubmit}>\n      <Input\n        placeholder=\"Buscar restaurantes\"\n        className=\"border-none\"\n        onChange={handleChange}\n        value={search}\n      />\n      <Button size=\"icon\" type=\"submit\">\n        <SearchIcon size={20} />\n      </Button>\n    </form>\n  );\n};\n\nexport default Search;\n"
  },
  {
    "path": "app/_components/ui/alert-dialog.tsx",
    "content": "\"use client\";\n\nimport * as React from \"react\";\nimport * as AlertDialogPrimitive from \"@radix-ui/react-alert-dialog\";\n\nimport { cn } from \"@/app/_lib/utils\";\nimport { buttonVariants } from \"@/app/_components/ui/button\";\n\nconst AlertDialog = AlertDialogPrimitive.Root;\n\nconst AlertDialogTrigger = AlertDialogPrimitive.Trigger;\n\nconst AlertDialogPortal = AlertDialogPrimitive.Portal;\n\nconst AlertDialogOverlay = React.forwardRef<\n  React.ElementRef<typeof AlertDialogPrimitive.Overlay>,\n  React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n  <AlertDialogPrimitive.Overlay\n    className={cn(\n      \"fixed inset-0 z-50 bg-black/80  data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n      className,\n    )}\n    {...props}\n    ref={ref}\n  />\n));\nAlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;\n\nconst AlertDialogContent = React.forwardRef<\n  React.ElementRef<typeof AlertDialogPrimitive.Content>,\n  React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Content>\n>(({ className, ...props }, ref) => (\n  <AlertDialogPortal>\n    <AlertDialogOverlay />\n    <AlertDialogPrimitive.Content\n      ref={ref}\n      className={cn(\n        \"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg\",\n        className,\n      )}\n      {...props}\n    />\n  </AlertDialogPortal>\n));\nAlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName;\n\nconst AlertDialogHeader = ({\n  className,\n  ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n  <div\n    className={cn(\n      \"flex flex-col space-y-2 text-center sm:text-left\",\n      className,\n    )}\n    {...props}\n  />\n);\nAlertDialogHeader.displayName = \"AlertDialogHeader\";\n\nconst AlertDialogFooter = ({\n  className,\n  ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n  <div\n    className={cn(\n      \"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2\",\n      className,\n    )}\n    {...props}\n  />\n);\nAlertDialogFooter.displayName = \"AlertDialogFooter\";\n\nconst AlertDialogTitle = React.forwardRef<\n  React.ElementRef<typeof AlertDialogPrimitive.Title>,\n  React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Title>\n>(({ className, ...props }, ref) => (\n  <AlertDialogPrimitive.Title\n    ref={ref}\n    className={cn(\"text-lg font-semibold\", className)}\n    {...props}\n  />\n));\nAlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;\n\nconst AlertDialogDescription = React.forwardRef<\n  React.ElementRef<typeof AlertDialogPrimitive.Description>,\n  React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Description>\n>(({ className, ...props }, ref) => (\n  <AlertDialogPrimitive.Description\n    ref={ref}\n    className={cn(\"text-sm text-muted-foreground\", className)}\n    {...props}\n  />\n));\nAlertDialogDescription.displayName =\n  AlertDialogPrimitive.Description.displayName;\n\nconst AlertDialogAction = React.forwardRef<\n  React.ElementRef<typeof AlertDialogPrimitive.Action>,\n  React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Action>\n>(({ className, ...props }, ref) => (\n  <AlertDialogPrimitive.Action\n    ref={ref}\n    className={cn(buttonVariants(), className)}\n    {...props}\n  />\n));\nAlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;\n\nconst AlertDialogCancel = React.forwardRef<\n  React.ElementRef<typeof AlertDialogPrimitive.Cancel>,\n  React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Cancel>\n>(({ className, ...props }, ref) => (\n  <AlertDialogPrimitive.Cancel\n    ref={ref}\n    className={cn(\n      buttonVariants({ variant: \"outline\" }),\n      \"mt-2 sm:mt-0\",\n      className,\n    )}\n    {...props}\n  />\n));\nAlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;\n\nexport {\n  AlertDialog,\n  AlertDialogPortal,\n  AlertDialogOverlay,\n  AlertDialogTrigger,\n  AlertDialogContent,\n  AlertDialogHeader,\n  AlertDialogFooter,\n  AlertDialogTitle,\n  AlertDialogDescription,\n  AlertDialogAction,\n  AlertDialogCancel,\n};\n"
  },
  {
    "path": "app/_components/ui/avatar.tsx",
    "content": "\"use client\";\n\nimport * as React from \"react\";\nimport * as AvatarPrimitive from \"@radix-ui/react-avatar\";\n\nimport { cn } from \"@/app/_lib/utils\";\n\nconst Avatar = React.forwardRef<\n  React.ElementRef<typeof AvatarPrimitive.Root>,\n  React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>\n>(({ className, ...props }, ref) => (\n  <AvatarPrimitive.Root\n    ref={ref}\n    className={cn(\n      \"relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full\",\n      className,\n    )}\n    {...props}\n  />\n));\nAvatar.displayName = AvatarPrimitive.Root.displayName;\n\nconst AvatarImage = React.forwardRef<\n  React.ElementRef<typeof AvatarPrimitive.Image>,\n  React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>\n>(({ className, ...props }, ref) => (\n  <AvatarPrimitive.Image\n    ref={ref}\n    className={cn(\"aspect-square h-full w-full\", className)}\n    {...props}\n  />\n));\nAvatarImage.displayName = AvatarPrimitive.Image.displayName;\n\nconst AvatarFallback = React.forwardRef<\n  React.ElementRef<typeof AvatarPrimitive.Fallback>,\n  React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>\n>(({ className, ...props }, ref) => (\n  <AvatarPrimitive.Fallback\n    ref={ref}\n    className={cn(\n      \"flex h-full w-full items-center justify-center rounded-full bg-muted\",\n      className,\n    )}\n    {...props}\n  />\n));\nAvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;\n\nexport { Avatar, AvatarImage, AvatarFallback };\n"
  },
  {
    "path": "app/_components/ui/button.tsx",
    "content": "import * as React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"@/app/_lib/utils\";\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-semibold ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-destructive-foreground hover:bg-destructive/90\",\n        outline:\n          \"border border-input bg-background hover:bg-accent hover:text-accent-foreground\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost: \"hover:bg-accent hover:text-accent-foreground\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-10 px-4 py-2\",\n        sm: \"h-9 rounded-md px-3\",\n        lg: \"h-11 rounded-md px-8\",\n        icon: \"h-10 w-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  },\n);\n\nexport interface ButtonProps\n  extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n    VariantProps<typeof buttonVariants> {\n  asChild?: boolean;\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n  ({ className, variant, size, asChild = false, ...props }, ref) => {\n    const Comp = asChild ? Slot : \"button\";\n    return (\n      <Comp\n        className={cn(buttonVariants({ variant, size, className }))}\n        ref={ref}\n        {...props}\n      />\n    );\n  },\n);\nButton.displayName = \"Button\";\n\nexport { Button, buttonVariants };\n"
  },
  {
    "path": "app/_components/ui/card.tsx",
    "content": "import * as React from \"react\";\n\nimport { cn } from \"@/app/_lib/utils\";\n\nconst Card = React.forwardRef<\n  HTMLDivElement,\n  React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n  <div\n    ref={ref}\n    className={cn(\n      \"rounded-lg border bg-card text-card-foreground shadow-sm\",\n      className\n    )}\n    {...props}\n  />\n));\nCard.displayName = \"Card\";\n\nconst CardHeader = React.forwardRef<\n  HTMLDivElement,\n  React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n  <div\n    ref={ref}\n    className={cn(\"flex flex-col space-y-1.5 p-6\", className)}\n    {...props}\n  />\n));\nCardHeader.displayName = \"CardHeader\";\n\nconst CardTitle = React.forwardRef<\n  HTMLParagraphElement,\n  React.HTMLAttributes<HTMLHeadingElement>\n>(({ className, ...props }, ref) => (\n  <h3\n    ref={ref}\n    className={cn(\n      \"text-2xl font-semibold leading-none tracking-tight\",\n      className\n    )}\n    {...props}\n  />\n));\nCardTitle.displayName = \"CardTitle\";\n\nconst CardDescription = React.forwardRef<\n  HTMLParagraphElement,\n  React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n  <p\n    ref={ref}\n    className={cn(\"text-sm text-muted-foreground\", className)}\n    {...props}\n  />\n));\nCardDescription.displayName = \"CardDescription\";\n\nconst CardContent = React.forwardRef<\n  HTMLDivElement,\n  React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n  <div ref={ref} className={cn(\"p-6 pt-0\", className)} {...props} />\n));\nCardContent.displayName = \"CardContent\";\n\nconst CardFooter = React.forwardRef<\n  HTMLDivElement,\n  React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n  <div\n    ref={ref}\n    className={cn(\"flex items-center p-6 pt-0\", className)}\n    {...props}\n  />\n));\nCardFooter.displayName = \"CardFooter\";\n\nexport {\n  Card,\n  CardHeader,\n  CardFooter,\n  CardTitle,\n  CardDescription,\n  CardContent,\n};\n"
  },
  {
    "path": "app/_components/ui/input.tsx",
    "content": "import * as React from \"react\";\n\nimport { cn } from \"@/app/_lib/utils\";\n\nexport interface InputProps\n  extends React.InputHTMLAttributes<HTMLInputElement> {}\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\n  ({ className, type, ...props }, ref) => {\n    return (\n      <input\n        type={type}\n        className={cn(\n          \"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50\",\n          className,\n        )}\n        ref={ref}\n        {...props}\n      />\n    );\n  },\n);\nInput.displayName = \"Input\";\n\nexport { Input };\n"
  },
  {
    "path": "app/_components/ui/separator.tsx",
    "content": "\"use client\";\n\nimport * as React from \"react\";\nimport * as SeparatorPrimitive from \"@radix-ui/react-separator\";\n\nimport { cn } from \"@/app/_lib/utils\";\n\nconst Separator = React.forwardRef<\n  React.ElementRef<typeof SeparatorPrimitive.Root>,\n  React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root>\n>(\n  (\n    { className, orientation = \"horizontal\", decorative = true, ...props },\n    ref,\n  ) => (\n    <SeparatorPrimitive.Root\n      ref={ref}\n      decorative={decorative}\n      orientation={orientation}\n      className={cn(\n        \"shrink-0 bg-[#EEEEEE]\",\n        orientation === \"horizontal\" ? \"h-[1px] w-full\" : \"h-full w-[1px]\",\n        className,\n      )}\n      {...props}\n    />\n  ),\n);\nSeparator.displayName = SeparatorPrimitive.Root.displayName;\n\nexport { Separator };\n"
  },
  {
    "path": "app/_components/ui/sheet.tsx",
    "content": "\"use client\";\n\nimport * as React from \"react\";\nimport * as SheetPrimitive from \"@radix-ui/react-dialog\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { X } from \"lucide-react\";\n\nimport { cn } from \"@/app/_lib/utils\";\n\nconst Sheet = SheetPrimitive.Root;\n\nconst SheetTrigger = SheetPrimitive.Trigger;\n\nconst SheetClose = SheetPrimitive.Close;\n\nconst SheetPortal = SheetPrimitive.Portal;\n\nconst SheetOverlay = React.forwardRef<\n  React.ElementRef<typeof SheetPrimitive.Overlay>,\n  React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n  <SheetPrimitive.Overlay\n    className={cn(\n      \"fixed inset-0 z-50 bg-black/80  data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n      className,\n    )}\n    {...props}\n    ref={ref}\n  />\n));\nSheetOverlay.displayName = SheetPrimitive.Overlay.displayName;\n\nconst sheetVariants = cva(\n  \"fixed z-50 gap-4 bg-white p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500\",\n  {\n    variants: {\n      side: {\n        top: \"inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top\",\n        bottom:\n          \"inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom\",\n        left: \"inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm\",\n        right:\n          \"inset-y-0 right-0 h-full w-3/4  border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm\",\n      },\n    },\n    defaultVariants: {\n      side: \"right\",\n    },\n  },\n);\n\ninterface SheetContentProps\n  extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,\n    VariantProps<typeof sheetVariants> {}\n\nconst SheetContent = React.forwardRef<\n  React.ElementRef<typeof SheetPrimitive.Content>,\n  SheetContentProps\n>(({ side = \"right\", className, children, ...props }, ref) => (\n  <SheetPortal>\n    <SheetOverlay />\n    <SheetPrimitive.Content\n      ref={ref}\n      className={cn(sheetVariants({ side }), className)}\n      {...props}\n    >\n      {children}\n      <SheetPrimitive.Close className=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary\">\n        <X className=\"h-4 w-4\" />\n        <span className=\"sr-only\">Close</span>\n      </SheetPrimitive.Close>\n    </SheetPrimitive.Content>\n  </SheetPortal>\n));\nSheetContent.displayName = SheetPrimitive.Content.displayName;\n\nconst SheetHeader = ({\n  className,\n  ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n  <div\n    className={cn(\n      \"flex flex-col space-y-2 text-center sm:text-left\",\n      className,\n    )}\n    {...props}\n  />\n);\nSheetHeader.displayName = \"SheetHeader\";\n\nconst SheetFooter = ({\n  className,\n  ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n  <div\n    className={cn(\n      \"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2\",\n      className,\n    )}\n    {...props}\n  />\n);\nSheetFooter.displayName = \"SheetFooter\";\n\nconst SheetTitle = React.forwardRef<\n  React.ElementRef<typeof SheetPrimitive.Title>,\n  React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>\n>(({ className, ...props }, ref) => (\n  <SheetPrimitive.Title\n    ref={ref}\n    className={cn(\"text-lg font-semibold text-foreground\", className)}\n    {...props}\n  />\n));\nSheetTitle.displayName = SheetPrimitive.Title.displayName;\n\nconst SheetDescription = React.forwardRef<\n  React.ElementRef<typeof SheetPrimitive.Description>,\n  React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>\n>(({ className, ...props }, ref) => (\n  <SheetPrimitive.Description\n    ref={ref}\n    className={cn(\"text-sm text-muted-foreground\", className)}\n    {...props}\n  />\n));\nSheetDescription.displayName = SheetPrimitive.Description.displayName;\n\nexport {\n  Sheet,\n  SheetPortal,\n  SheetOverlay,\n  SheetTrigger,\n  SheetClose,\n  SheetContent,\n  SheetHeader,\n  SheetFooter,\n  SheetTitle,\n  SheetDescription,\n};\n"
  },
  {
    "path": "app/_components/ui/sonner.tsx",
    "content": "\"use client\";\n\nimport { useTheme } from \"next-themes\";\nimport { Toaster as Sonner } from \"sonner\";\n\ntype ToasterProps = React.ComponentProps<typeof Sonner>;\n\nconst Toaster = ({ ...props }: ToasterProps) => {\n  const { theme = \"system\" } = useTheme();\n\n  return (\n    <Sonner\n      theme={theme as ToasterProps[\"theme\"]}\n      className=\"toaster group\"\n      toastOptions={{\n        classNames: {\n          toast:\n            \"group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg\",\n          description: \"group-[.toast]:text-muted-foreground\",\n          actionButton:\n            \"group-[.toast]:bg-primary group-[.toast]:text-primary-foreground\",\n          cancelButton:\n            \"group-[.toast]:bg-muted group-[.toast]:text-muted-foreground\",\n        },\n      }}\n      {...props}\n    />\n  );\n};\n\nexport { Toaster };\n"
  },
  {
    "path": "app/_context/cart.tsx",
    "content": "/* eslint-disable no-unused-vars */\n\"use client\";\n\nimport { Prisma } from \"@prisma/client\";\nimport { ReactNode, createContext, useState } from \"react\";\nimport { calculateProductTotalPrice } from \"../_helpers/price\";\n\nexport interface CartProduct\n  extends Prisma.ProductGetPayload<{\n    include: {\n      restaurant: {\n        select: {\n          id: true;\n          deliveryFee: true;\n          deliveryTimeMinutes: true;\n        };\n      };\n    };\n  }> {\n  quantity: number;\n}\n\ninterface ICartContext {\n  products: CartProduct[];\n  subtotalPrice: number;\n  totalPrice: number;\n  totalDiscounts: number;\n  totalQuantity: number;\n  addProductToCart: ({\n    product,\n    emptyCart,\n  }: {\n    product: CartProduct;\n    emptyCart?: boolean;\n  }) => void;\n  decreaseProductQuantity: (productId: string) => void;\n  increaseProductQuantity: (productId: string) => void;\n  removeProductFromCart: (productId: string) => void;\n  clearCart: () => void;\n}\n\nexport const CartContext = createContext<ICartContext>({\n  products: [],\n  subtotalPrice: 0,\n  totalPrice: 0,\n  totalDiscounts: 0,\n  totalQuantity: 0,\n  addProductToCart: () => {},\n  decreaseProductQuantity: () => {},\n  increaseProductQuantity: () => {},\n  removeProductFromCart: () => {},\n  clearCart: () => {},\n});\n\nexport const CartProvider = ({ children }: { children: ReactNode }) => {\n  const [products, setProducts] = useState<CartProduct[]>([]);\n\n  const subtotalPrice = products.reduce((acc, product) => {\n    return acc + Number(product.price) * product.quantity;\n  }, 0);\n\n  const totalPrice =\n    products.reduce((acc, product) => {\n      return acc + calculateProductTotalPrice(product) * product.quantity;\n    }, 0) + Number(products?.[0]?.restaurant?.deliveryFee);\n\n  const totalQuantity = products.reduce((acc, product) => {\n    return acc + product.quantity;\n  }, 0);\n\n  const totalDiscounts =\n    subtotalPrice - totalPrice + Number(products?.[0]?.restaurant?.deliveryFee);\n\n  const clearCart = () => {\n    return setProducts([]);\n  };\n\n  const decreaseProductQuantity: ICartContext[\"decreaseProductQuantity\"] = (\n    productId: string,\n  ) => {\n    return setProducts((prev) =>\n      prev.map((cartProduct) => {\n        if (cartProduct.id === productId) {\n          if (cartProduct.quantity === 1) {\n            return cartProduct;\n          }\n\n          return {\n            ...cartProduct,\n            quantity: cartProduct.quantity - 1,\n          };\n        }\n\n        return cartProduct;\n      }),\n    );\n  };\n\n  const increaseProductQuantity: ICartContext[\"increaseProductQuantity\"] = (\n    productId: string,\n  ) => {\n    return setProducts((prev) =>\n      prev.map((cartProduct) => {\n        if (cartProduct.id === productId) {\n          return {\n            ...cartProduct,\n            quantity: cartProduct.quantity + 1,\n          };\n        }\n\n        return cartProduct;\n      }),\n    );\n  };\n\n  const removeProductFromCart: ICartContext[\"removeProductFromCart\"] = (\n    productId: string,\n  ) => {\n    return setProducts((prev) =>\n      prev.filter((product) => product.id !== productId),\n    );\n  };\n\n  const addProductToCart: ICartContext[\"addProductToCart\"] = ({\n    product,\n    emptyCart,\n  }) => {\n    if (emptyCart) {\n      setProducts([]);\n    }\n\n    // VERIFICAR SE O PRODUTO JÁ ESTÁ NO CARRINHO\n    const isProductAlreadyOnCart = products.some(\n      (cartProduct) => cartProduct.id === product.id,\n    );\n\n    // SE ELE ESTIVER, AUMENTAR A SUA QUANTIDADE\n    if (isProductAlreadyOnCart) {\n      return setProducts((prev) =>\n        prev.map((cartProduct) => {\n          if (cartProduct.id === product.id) {\n            return {\n              ...cartProduct,\n              quantity: cartProduct.quantity + product.quantity,\n            };\n          }\n\n          return cartProduct;\n        }),\n      );\n    }\n\n    // SE NÃO, ADICIONÁ-LO COM A QUANTIDADE RECEBIDA\n    setProducts((prev) => [...prev, product]);\n  };\n\n  return (\n    <CartContext.Provider\n      value={{\n        products,\n        subtotalPrice,\n        totalPrice,\n        totalDiscounts,\n        totalQuantity,\n        clearCart,\n        addProductToCart,\n        decreaseProductQuantity,\n        increaseProductQuantity,\n        removeProductFromCart,\n      }}\n    >\n      {children}\n    </CartContext.Provider>\n  );\n};\n"
  },
  {
    "path": "app/_helpers/price.ts",
    "content": "import { Product } from \"@prisma/client\";\n\nexport const calculateProductTotalPrice = (product: Product): number => {\n  if (product.discountPercentage === 0) {\n    return Number(product.price);\n  }\n\n  const discount = Number(product.price) * (product.discountPercentage / 100);\n\n  return Number(product.price) - discount;\n};\n\nexport const formatCurrency = (value: number): string => {\n  return `R$${Intl.NumberFormat(\"pt-BR\", {\n    currency: \"BRL\",\n    minimumFractionDigits: 2,\n  }).format(value)}`;\n};\n"
  },
  {
    "path": "app/_helpers/restaurant.ts",
    "content": "import { UserFavoriteRestaurant } from \"@prisma/client\";\n\nexport const isRestaurantFavorited = (\n  restaurantId: string,\n  userFavoriteRestaurants: UserFavoriteRestaurant[],\n) => userFavoriteRestaurants?.some((fav) => fav.restaurantId === restaurantId);\n"
  },
  {
    "path": "app/_hooks/use-toggle-favorite-restaurant.ts",
    "content": "import { toast } from \"sonner\";\nimport { toggleFavoriteRestaurant } from \"../_actions/restaurant\";\nimport { UserFavoriteRestaurant } from \"@prisma/client\";\nimport { useRouter } from \"next/navigation\";\n\ninterface UseToggleFavoriteRestaurantProps {\n  userId?: string;\n  userFavoriteRestaurants?: UserFavoriteRestaurant[];\n  restaurantId: string;\n  restaurantIsFavorited?: boolean;\n}\n\nconst useToggleFavoriteRestaurant = ({\n  userId,\n  restaurantId,\n  restaurantIsFavorited,\n}: UseToggleFavoriteRestaurantProps) => {\n  const router = useRouter();\n\n  const handleFavoriteClick = async () => {\n    if (!userId) return;\n\n    try {\n      await toggleFavoriteRestaurant(userId, restaurantId);\n\n      toast(\n        restaurantIsFavorited\n          ? \"Restaurante removido dos favoritos.\"\n          : \"Restaurante favoritado.\",\n        {\n          action: {\n            label: \"Ver Favoritos\",\n            onClick: () => router.push(\"/my-favorite-restaurants\"),\n          },\n        },\n      );\n    } catch (error) {\n      toast.error(\"Erro ao favoritar restaurante.\");\n    }\n  };\n\n  return { handleFavoriteClick };\n};\n\nexport default useToggleFavoriteRestaurant;\n"
  },
  {
    "path": "app/_lib/auth.ts",
    "content": "import { PrismaAdapter } from \"@auth/prisma-adapter\";\nimport { AuthOptions } from \"next-auth\";\nimport { db } from \"./prisma\";\nimport GoogleProvider from \"next-auth/providers/google\";\nimport { Adapter } from \"next-auth/adapters\";\n\nexport const authOptions: AuthOptions = {\n  adapter: PrismaAdapter(db) as Adapter,\n  providers: [\n    GoogleProvider({\n      clientId: process.env.GOOGLE_CLIENT_ID as string,\n      clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,\n    }),\n  ],\n  callbacks: {\n    async session({ session, user }) {\n      session.user = { ...session.user, id: user.id };\n      return session;\n    },\n  },\n  secret: process.env.NEXTAUTH_SECRET,\n};\n"
  },
  {
    "path": "app/_lib/prisma.ts",
    "content": "/* eslint-disable no-unused-vars */\nimport { PrismaClient } from \"@prisma/client\";\n\ndeclare global {\n  var cachedPrisma: PrismaClient;\n}\n\nlet prisma: PrismaClient;\nif (process.env.NODE_ENV === \"production\") {\n  prisma = new PrismaClient();\n} else {\n  if (!global.cachedPrisma) {\n    global.cachedPrisma = new PrismaClient();\n  }\n  prisma = global.cachedPrisma;\n}\n\nexport const db = prisma;\n"
  },
  {
    "path": "app/_lib/utils.ts",
    "content": "import { type ClassValue, clsx } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n"
  },
  {
    "path": "app/_providers/auth.tsx",
    "content": "\"use client\";\n\nimport { SessionProvider } from \"next-auth/react\";\nimport { ReactNode } from \"react\";\n\nconst AuthProvider = ({ children }: { children: ReactNode }) => {\n  return <SessionProvider>{children}</SessionProvider>;\n};\n\nexport default AuthProvider;\n"
  },
  {
    "path": "app/api/auth/[...nextauth]/route.ts",
    "content": "import NextAuth from \"next-auth\";\nimport { authOptions } from \"@/app/_lib/auth\";\n\nconst handler = NextAuth(authOptions);\n\nexport { handler as GET, handler as POST };\n"
  },
  {
    "path": "app/categories/[id]/products/page.tsx",
    "content": "import Header from \"@/app/_components/header\";\nimport ProductItem from \"@/app/_components/product-item\";\nimport { db } from \"@/app/_lib/prisma\";\nimport { notFound } from \"next/navigation\";\n\ninterface CategoriesPageProps {\n  params: {\n    id: string;\n  };\n}\n\nconst CategoriesPage = async ({ params: { id } }: CategoriesPageProps) => {\n  const category = await db.category.findUnique({\n    where: {\n      id,\n    },\n    include: {\n      products: {\n        include: {\n          restaurant: {\n            select: {\n              name: true,\n            },\n          },\n        },\n      },\n    },\n  });\n\n  if (!category) {\n    return notFound();\n  }\n\n  return (\n    <>\n      <Header />\n      <div className=\"px-5 py-6\">\n        <h2 className=\"mb-6 text-lg font-semibold\">{category.name}</h2>\n        <div className=\"grid grid-cols-2 gap-6\">\n          {category.products.map((product) => (\n            <ProductItem\n              key={product.id}\n              product={product}\n              className=\"min-w-full\"\n            />\n          ))}\n        </div>\n      </div>\n    </>\n  );\n};\n\nexport default CategoriesPage;\n"
  },
  {
    "path": "app/globals.css",
    "content": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n:root {\n  --background: 0 0% 96%;\n  --foreground: 0 0% 20%;\n  --card: 356 50% 100%;\n  --card-foreground: 356 5% 15%;\n  --popover: 356 100% 100%;\n  --popover-foreground: 356 100% 10%;\n  --primary: 356 83% 51.6%;\n  --primary-foreground: 0 0% 100%;\n  --secondary: 356 30% 90%;\n  --secondary-foreground: 0 0% 0%;\n  --muted: 318 30% 95%;\n  --muted-foreground: 225 8% 53%;\n  --accent: 318 30% 90%;\n  --accent-foreground: 356 5% 15%;\n  --destructive: 0 100% 50%;\n  --destructive-foreground: 356 5% 100%;\n  --border: 356 30% 82%;\n  --input: 356 30% 50%;\n  --ring: 356 83% 51.6%;\n  --radius: 0.75rem;\n}\n\n.dark {\n  --background: 356 50% 10%;\n  --foreground: 356 5% 100%;\n  --card: 356 50% 10%;\n  --card-foreground: 356 5% 100%;\n  --popover: 356 50% 5%;\n  --popover-foreground: 356 5% 100%;\n  --primary: 356 83% 51.6%;\n  --primary-foreground: 0 0% 100%;\n  --secondary: 356 30% 20%;\n  --secondary-foreground: 0 0% 100%;\n  --muted: 318 30% 25%;\n  --muted-foreground: 225 8% 53%;\n  --accent: 318 30% 25%;\n  --accent-foreground: 356 5% 95%;\n  --destructive: 0 100% 50%;\n  --destructive-foreground: 356 5% 100%;\n  --border: 356 30% 50%;\n  --input: 356 30% 50%;\n  --ring: 356 83% 51.6%;\n  --radius: 0.75rem;\n}\n\n@layer base {\n  * {\n    @apply box-border;\n  }\n\n  body {\n    @apply text-foreground antialiased;\n  }\n}\n"
  },
  {
    "path": "app/layout.tsx",
    "content": "import type { Metadata } from \"next\";\nimport { Poppins } from \"next/font/google\";\nimport \"./globals.css\";\nimport { CartProvider } from \"./_context/cart\";\nimport AuthProvider from \"./_providers/auth\";\nimport { Toaster } from \"@/app/_components/ui/sonner\";\n\nconst poppins = Poppins({\n  subsets: [\"latin\"],\n  weight: [\"400\", \"500\", \"600\", \"700\", \"800\"],\n});\n\nexport const metadata: Metadata = {\n  title: \"Create Next App\",\n  description: \"Generated by create next app\",\n};\n\nexport default function RootLayout({\n  children,\n}: Readonly<{\n  children: React.ReactNode;\n}>) {\n  return (\n    <html lang=\"en\">\n      <body className={poppins.className}>\n        <AuthProvider>\n          <CartProvider>{children}</CartProvider>\n        </AuthProvider>\n\n        <Toaster />\n      </body>\n    </html>\n  );\n}\n"
  },
  {
    "path": "app/my-favorite-restaurants/page.tsx",
    "content": "import { getServerSession } from \"next-auth\";\nimport { db } from \"../_lib/prisma\";\nimport { authOptions } from \"../_lib/auth\";\nimport { notFound } from \"next/navigation\";\nimport Header from \"../_components/header\";\nimport RestaurantItem from \"../_components/restaurant-item\";\n\nconst MyFavoriteRestaurants = async () => {\n  const session = await getServerSession(authOptions);\n\n  if (!session) {\n    return notFound();\n  }\n\n  const userFavoriteRestaurants = await db.userFavoriteRestaurant.findMany({\n    where: {\n      userId: session.user.id,\n    },\n    include: {\n      restaurant: true,\n    },\n  });\n\n  return (\n    <>\n      <Header />\n      <div className=\"px-5 py-6\">\n        <h2 className=\"mb-6 text-lg font-semibold\">Restaurantes Favoritos</h2>\n        <div className=\"flex w-full flex-col gap-6\">\n          {userFavoriteRestaurants.length > 0 ? (\n            userFavoriteRestaurants.map(({ restaurant }) => (\n              <RestaurantItem\n                key={restaurant.id}\n                restaurant={restaurant}\n                className=\"min-w-full max-w-full\"\n                userFavoriteRestaurants={userFavoriteRestaurants}\n              />\n            ))\n          ) : (\n            <h3 className=\"font-medium\">\n              Você ainda não marcou nenhum restaurante como favorito.\n            </h3>\n          )}\n        </div>\n      </div>\n    </>\n  );\n};\n\nexport default MyFavoriteRestaurants;\n"
  },
  {
    "path": "app/my-orders/_components/order-item.tsx",
    "content": "\"use client\";\n\nimport { Avatar, AvatarImage } from \"@/app/_components/ui/avatar\";\nimport { Button } from \"@/app/_components/ui/button\";\nimport { Card, CardContent } from \"@/app/_components/ui/card\";\nimport { Separator } from \"@/app/_components/ui/separator\";\nimport { CartContext } from \"@/app/_context/cart\";\nimport { formatCurrency } from \"@/app/_helpers/price\";\nimport { OrderStatus, Prisma } from \"@prisma/client\";\nimport { ChevronRightIcon } from \"lucide-react\";\nimport Link from \"next/link\";\nimport { useRouter } from \"next/navigation\";\nimport { useContext } from \"react\";\n\ninterface OrderItemProps {\n  order: Prisma.OrderGetPayload<{\n    include: {\n      restaurant: true;\n      products: {\n        include: {\n          product: true;\n        };\n      };\n    };\n  }>;\n}\n\nconst getOrderStatusLabel = (status: OrderStatus) => {\n  switch (status) {\n    case \"CANCELED\":\n      return \"Cancelado\";\n    case \"COMPLETED\":\n      return \"Finalizado\";\n    case \"CONFIRMED\":\n      return \"Confirmado\";\n    case \"DELIVERING\":\n      return \"Em Transporte\";\n    case \"PREPARING\":\n      return \"Preparando\";\n  }\n};\n\nconst OrderItem = ({ order }: OrderItemProps) => {\n  const { addProductToCart } = useContext(CartContext);\n\n  const router = useRouter();\n\n  const handleRedoOrderClick = () => {\n    for (const orderProduct of order.products) {\n      addProductToCart({\n        product: {\n          ...orderProduct.product,\n          restaurant: order.restaurant,\n          quantity: orderProduct.quantity,\n        },\n      });\n    }\n\n    router.push(`/restaurants/${order.restaurantId}`);\n  };\n  return (\n    <Card>\n      <CardContent className=\"p-5\">\n        <div\n          className={`w-fit rounded-full bg-[#EEEEEE] px-2 py-1 text-muted-foreground ${order.status !== \"COMPLETED\" && \"bg-green-500 text-white\"}`}\n        >\n          <span className=\"block text-xs font-semibold\">\n            {getOrderStatusLabel(order.status)}\n          </span>\n        </div>\n\n        <div className=\"flex items-center justify-between pt-3\">\n          <div className=\"flex items-center gap-2\">\n            <Avatar className=\"h-6 w-6\">\n              <AvatarImage src={order.restaurant.imageUrl} />\n            </Avatar>\n\n            <span className=\"text-sm font-semibold\">\n              {order.restaurant.name}\n            </span>\n          </div>\n\n          <Button\n            variant=\"link\"\n            size=\"icon\"\n            className=\"h-5 w-5 text-black\"\n            asChild\n          >\n            <Link href={`/restaurants/${order.restaurantId}`}>\n              <ChevronRightIcon />\n            </Link>\n          </Button>\n        </div>\n\n        <div className=\"py-3\">\n          <Separator />\n        </div>\n\n        <div className=\"space-y-2\">\n          {order.products.map((product) => (\n            <div key={product.id} className=\"flex items-center gap-2\">\n              <div className=\"flex h-5 w-5 items-center justify-center rounded-full bg-muted-foreground\">\n                <span className=\"block text-xs text-white\">\n                  {product.quantity}\n                </span>\n              </div>\n              <span className=\"block text-xs text-muted-foreground\">\n                {product.product.name}\n              </span>\n            </div>\n          ))}\n        </div>\n\n        <div className=\"py-3\">\n          <Separator />\n        </div>\n\n        <div className=\"flex items-center justify-between\">\n          <p className=\"text-sm\">{formatCurrency(Number(order.totalPrice))}</p>\n          <Button\n            variant=\"ghost\"\n            size=\"sm\"\n            className=\"text-xs text-primary\"\n            disabled={order.status !== \"COMPLETED\"}\n            onClick={handleRedoOrderClick}\n          >\n            Refazer pedido\n          </Button>\n        </div>\n      </CardContent>\n    </Card>\n  );\n};\n\nexport default OrderItem;\n"
  },
  {
    "path": "app/my-orders/page.tsx",
    "content": "import { getServerSession } from \"next-auth\";\nimport { db } from \"../_lib/prisma\";\nimport { authOptions } from \"../_lib/auth\";\nimport { redirect } from \"next/navigation\";\nimport Header from \"../_components/header\";\nimport OrderItem from \"./_components/order-item\";\n\nconst MyOrdersPage = async () => {\n  const session = await getServerSession(authOptions);\n\n  if (!session?.user) {\n    return redirect(\"/\");\n  }\n\n  const orders = await db.order.findMany({\n    where: {\n      userId: session.user.id,\n    },\n    include: {\n      restaurant: true,\n      products: {\n        include: {\n          product: true,\n        },\n      },\n    },\n  });\n\n  return (\n    <>\n      <Header />\n\n      <div className=\"px-5 py-6\">\n        <h2 className=\"pb-6 text-lg font-semibold\">Meus Pedidos</h2>\n\n        <div className=\"space-y-4\">\n          {orders.map((order) => (\n            <OrderItem key={order.id} order={order} />\n          ))}\n        </div>\n      </div>\n    </>\n  );\n};\n\nexport default MyOrdersPage;\n"
  },
  {
    "path": "app/page.tsx",
    "content": "import CategoryList from \"./_components/category-list\";\nimport Header from \"./_components/header\";\nimport Search from \"./_components/search\";\nimport ProductList from \"./_components/product-list\";\nimport { Button } from \"./_components/ui/button\";\nimport { ChevronRightIcon } from \"lucide-react\";\nimport { db } from \"./_lib/prisma\";\nimport PromoBanner from \"./_components/promo-banner\";\nimport RestaurantList from \"./_components/restaurant-list\";\nimport Link from \"next/link\";\n\nconst fetch = async () => {\n  const getProducts = db.product.findMany({\n    where: {\n      discountPercentage: {\n        gt: 0,\n      },\n    },\n    take: 10,\n    include: {\n      restaurant: {\n        select: {\n          name: true,\n        },\n      },\n    },\n  });\n\n  const getBurguersCategory = db.category.findFirst({\n    where: {\n      name: \"Hambúrgueres\",\n    },\n  });\n\n  const getPizzasCategory = db.category.findFirst({\n    where: {\n      name: \"Pizzas\",\n    },\n  });\n\n  const [products, burguersCategory, pizzasCategory] = await Promise.all([\n    getProducts,\n    getBurguersCategory,\n    getPizzasCategory,\n  ]);\n\n  return { products, burguersCategory, pizzasCategory };\n};\n\nconst Home = async () => {\n  const { products, burguersCategory, pizzasCategory } = await fetch();\n\n  return (\n    <>\n      <Header />\n      <div className=\"px-5 pt-6\">\n        <Search />\n      </div>\n\n      <div className=\"px-5 pt-6\">\n        <CategoryList />\n      </div>\n\n      <div className=\"px-5 pt-6\">\n        <Link href={`/categories/${pizzasCategory?.id}/products`}>\n          <PromoBanner\n            src=\"/promo-banner-01.png\"\n            alt=\"Até 30% de desconto em pizzas!\"\n          />\n        </Link>\n      </div>\n\n      <div className=\"space-y-4 pt-6\">\n        <div className=\"flex items-center justify-between px-5\">\n          <h2 className=\"font-semibold\">Pedidos Recomendados</h2>\n\n          <Button\n            variant=\"ghost\"\n            className=\"h-fit p-0 text-primary hover:bg-transparent\"\n            asChild\n          >\n            <Link href=\"/products/recommended\">\n              Ver todos\n              <ChevronRightIcon size={16} />\n            </Link>\n          </Button>\n        </div>\n        <ProductList products={products} />\n      </div>\n\n      <div className=\"px-5 pt-6\">\n        <Link href={`/categories/${burguersCategory?.id}/products`}>\n          <PromoBanner\n            src=\"/promo-banner-02.png\"\n            alt=\"A partir de R$17,90 em lanches\"\n          />\n        </Link>\n      </div>\n\n      <div className=\"space-y-4 py-6\">\n        <div className=\"flex items-center justify-between px-5\">\n          <h2 className=\"font-semibold\">Restaurantes Recomendados</h2>\n\n          <Button\n            variant=\"ghost\"\n            className=\"h-fit p-0 text-primary hover:bg-transparent\"\n            asChild\n          >\n            <Link href=\"/restaurants/recommended\">\n              Ver todos\n              <ChevronRightIcon size={16} />\n            </Link>\n          </Button>\n        </div>\n        <RestaurantList />\n      </div>\n    </>\n  );\n};\n\nexport default Home;\n"
  },
  {
    "path": "app/products/[id]/_components/product-details.tsx",
    "content": "\"use client\";\n\nimport Cart from \"@/app/_components/cart\";\nimport DeliveryInfo from \"@/app/_components/delivery-info\";\nimport DiscountBadge from \"@/app/_components/discount-badge\";\nimport ProductList from \"@/app/_components/product-list\";\nimport {\n  AlertDialog,\n  AlertDialogAction,\n  AlertDialogCancel,\n  AlertDialogContent,\n  AlertDialogDescription,\n  AlertDialogFooter,\n  AlertDialogHeader,\n  AlertDialogTitle,\n} from \"@/app/_components/ui/alert-dialog\";\nimport { Button } from \"@/app/_components/ui/button\";\nimport {\n  Sheet,\n  SheetContent,\n  SheetHeader,\n  SheetTitle,\n} from \"@/app/_components/ui/sheet\";\nimport { CartContext } from \"@/app/_context/cart\";\nimport {\n  formatCurrency,\n  calculateProductTotalPrice,\n} from \"@/app/_helpers/price\";\nimport { Prisma } from \"@prisma/client\";\nimport { ChevronLeftIcon, ChevronRightIcon } from \"lucide-react\";\nimport Image from \"next/image\";\nimport { useContext, useState } from \"react\";\n\ninterface ProductDetailsProps {\n  product: Prisma.ProductGetPayload<{\n    include: {\n      restaurant: true;\n    };\n  }>;\n  complementaryProducts: Prisma.ProductGetPayload<{\n    include: {\n      restaurant: true;\n    };\n  }>[];\n}\n\nconst ProductDetails = ({\n  product,\n  complementaryProducts,\n}: ProductDetailsProps) => {\n  const [quantity, setQuantity] = useState(1);\n  const [isCartOpen, setIsCartOpen] = useState(false);\n  const [isConfirmationDialogOpen, setIsConfirmationDialogOpen] =\n    useState(false);\n\n  const { addProductToCart, products } = useContext(CartContext);\n\n  const addToCart = ({ emptyCart }: { emptyCart?: boolean }) => {\n    addProductToCart({ product: { ...product, quantity }, emptyCart });\n    setIsCartOpen(true);\n  };\n\n  const handleAddToCartClick = () => {\n    // VERIFICAR SE HÁ ALGUM PRODUTO DE OUTRO RESTAURANTE NO CARRINHO\n    const hasDifferentRestaurantProduct = products.some(\n      (cartProduct) => cartProduct.restaurantId !== product.restaurantId,\n    );\n\n    // SE HOUVER, ABRIR UM AVISO\n    if (hasDifferentRestaurantProduct) {\n      return setIsConfirmationDialogOpen(true);\n    }\n\n    addToCart({\n      emptyCart: false,\n    });\n  };\n\n  const handleIncreaseQuantityClick = () =>\n    setQuantity((currentState) => currentState + 1);\n  const handleDecreaseQuantityClick = () =>\n    setQuantity((currentState) => {\n      if (currentState === 1) return 1;\n\n      return currentState - 1;\n    });\n\n  return (\n    <>\n      <div className=\"relative z-50 mt-[-1.5rem] rounded-tl-3xl rounded-tr-3xl bg-white py-5\">\n        {/* RESTAURANTE */}\n        <div className=\"flex items-center gap-[0.375rem] px-5\">\n          <div className=\"relative h-6 w-6\">\n            <Image\n              src={product.restaurant.imageUrl}\n              alt={product.restaurant.name}\n              fill\n              sizes=\"100%\"\n              className=\"rounded-full object-cover\"\n            />\n          </div>\n          <span className=\"text-xs text-muted-foreground\">\n            {product.restaurant.name}\n          </span>\n        </div>\n\n        {/* NOME DO PRODUTO */}\n        <h1 className=\"mb-2 mt-1 px-5 text-xl font-semibold\">{product.name}</h1>\n\n        {/* PREÇO DO PRODUTO E QUANTIDADE */}\n        <div className=\"flex justify-between px-5\">\n          {/* PREÇO COM DESCONTO */}\n          <div>\n            <div className=\"flex items-center gap-2\">\n              <h2 className=\"text-xl font-semibold\">\n                {formatCurrency(calculateProductTotalPrice(product))}\n              </h2>\n              {product.discountPercentage > 0 && (\n                <DiscountBadge product={product} />\n              )}\n            </div>\n\n            {/* PREÇO ORIGINAL */}\n            {product.discountPercentage > 0 && (\n              <p className=\"text-sm text-muted-foreground\">\n                De: {formatCurrency(Number(product.price))}\n              </p>\n            )}\n          </div>\n\n          {/* QUANTIDADE */}\n          <div className=\"flex items-center gap-3 text-center\">\n            <Button\n              size=\"icon\"\n              variant=\"ghost\"\n              className=\"border border-solid border-muted-foreground\"\n              onClick={handleDecreaseQuantityClick}\n            >\n              <ChevronLeftIcon />\n            </Button>\n            <span className=\"w-4\">{quantity}</span>\n            <Button size=\"icon\" onClick={handleIncreaseQuantityClick}>\n              <ChevronRightIcon />\n            </Button>\n          </div>\n        </div>\n\n        <div className=\"px-5\">\n          <DeliveryInfo restaurant={product.restaurant} />\n        </div>\n\n        <div className=\"mt-6 space-y-3 px-5\">\n          <h3 className=\"font-semibold\">Sobre</h3>\n          <p className=\"text-sm text-muted-foreground\">{product.description}</p>\n        </div>\n\n        <div className=\"mt-6 space-y-3\">\n          <h3 className=\"px-5 font-semibold\">Sucos</h3>\n          <ProductList products={complementaryProducts} />\n        </div>\n\n        <div className=\"mt-6 px-5\">\n          <Button\n            className=\"w-full font-semibold\"\n            onClick={handleAddToCartClick}\n          >\n            Adicionar à sacola\n          </Button>\n        </div>\n      </div>\n\n      <Sheet open={isCartOpen} onOpenChange={setIsCartOpen}>\n        <SheetContent className=\"w-[90vw]\">\n          <SheetHeader>\n            <SheetTitle className=\"text-left\">Sacola</SheetTitle>\n          </SheetHeader>\n\n          <Cart setIsOpen={setIsCartOpen} />\n        </SheetContent>\n      </Sheet>\n\n      <AlertDialog\n        open={isConfirmationDialogOpen}\n        onOpenChange={setIsConfirmationDialogOpen}\n      >\n        <AlertDialogContent>\n          <AlertDialogHeader>\n            <AlertDialogTitle>\n              Você só pode adicionar itens de um restaurante por vez\n            </AlertDialogTitle>\n            <AlertDialogDescription>\n              Deseja mesmo adicionar esse produto? Isso limpará sua sacola\n              atual.\n            </AlertDialogDescription>\n          </AlertDialogHeader>\n          <AlertDialogFooter>\n            <AlertDialogCancel>Cancelar</AlertDialogCancel>\n            <AlertDialogAction onClick={() => addToCart({ emptyCart: true })}>\n              Esvaziar sacola e adicionar\n            </AlertDialogAction>\n          </AlertDialogFooter>\n        </AlertDialogContent>\n      </AlertDialog>\n    </>\n  );\n};\n\nexport default ProductDetails;\n"
  },
  {
    "path": "app/products/[id]/_components/product-image.tsx",
    "content": "\"use client\";\n\nimport { Button } from \"@/app/_components/ui/button\";\nimport { Product } from \"@prisma/client\";\nimport { ChevronLeftIcon } from \"lucide-react\";\nimport Image from \"next/image\";\nimport { useRouter } from \"next/navigation\";\n\ninterface ProductImageProps {\n  product: Pick<Product, \"name\" | \"imageUrl\">;\n}\n\nconst ProductImage = ({ product }: ProductImageProps) => {\n  const router = useRouter();\n\n  const handleBackClick = () => router.back();\n\n  return (\n    <div className=\"relative h-[360px] w-full\">\n      <Image\n        src={product.imageUrl}\n        alt={product.name}\n        fill\n        sizes=\"100%\"\n        className=\"object-cover\"\n      />\n\n      <Button\n        className=\"absolute left-4 top-4 rounded-full bg-white text-foreground hover:text-white\"\n        size=\"icon\"\n        onClick={handleBackClick}\n      >\n        <ChevronLeftIcon />\n      </Button>\n    </div>\n  );\n};\n\nexport default ProductImage;\n"
  },
  {
    "path": "app/products/[id]/page.tsx",
    "content": "import { db } from \"@/app/_lib/prisma\";\nimport { notFound } from \"next/navigation\";\nimport ProductImage from \"./_components/product-image\";\nimport ProductDetails from \"./_components/product-details\";\n\ninterface ProductPageProps {\n  params: {\n    id: string;\n  };\n}\n\nconst ProductPage = async ({ params: { id } }: ProductPageProps) => {\n  const product = await db.product.findUnique({\n    where: {\n      id,\n    },\n    include: {\n      restaurant: true,\n    },\n  });\n\n  if (!product) {\n    return notFound();\n  }\n\n  const juices = await db.product.findMany({\n    where: {\n      category: {\n        name: \"Sucos\",\n      },\n      restaurant: {\n        id: product?.restaurant.id,\n      },\n    },\n    include: {\n      restaurant: true,\n    },\n  });\n\n  return (\n    <div>\n      {/* IMAGEM */}\n      <ProductImage product={product} />\n\n      {/* TITULO E PREÇO */}\n      <ProductDetails product={product} complementaryProducts={juices} />\n    </div>\n  );\n};\n\nexport default ProductPage;\n"
  },
  {
    "path": "app/products/recommended/page.tsx",
    "content": "import Header from \"@/app/_components/header\";\nimport ProductItem from \"@/app/_components/product-item\";\nimport { db } from \"@/app/_lib/prisma\";\n\nconst RecommendedProductsPage = async () => {\n  const products = await db.product.findMany({\n    where: {\n      discountPercentage: {\n        gt: 0,\n      },\n    },\n    take: 20,\n    include: {\n      restaurant: {\n        select: {\n          name: true,\n        },\n      },\n    },\n  });\n\n  // TODO: pegar produtos com mais pedidos\n  return (\n    <>\n      <Header />\n      <div className=\"px-5 py-6\">\n        <h2 className=\"mb-6 text-lg font-semibold\">Pedidos Recomendados</h2>\n        <div className=\"grid grid-cols-2 gap-6\">\n          {products.map((product) => (\n            <ProductItem\n              key={product.id}\n              product={product}\n              className=\"min-w-full\"\n            />\n          ))}\n        </div>\n      </div>\n    </>\n  );\n};\n\nexport default RecommendedProductsPage;\n"
  },
  {
    "path": "app/restaurants/[id]/_components/cart-banner.tsx",
    "content": "\"use client\";\n\nimport Cart from \"@/app/_components/cart\";\nimport { Button } from \"@/app/_components/ui/button\";\nimport {\n  Sheet,\n  SheetContent,\n  SheetHeader,\n  SheetTitle,\n} from \"@/app/_components/ui/sheet\";\nimport { CartContext } from \"@/app/_context/cart\";\nimport { formatCurrency } from \"@/app/_helpers/price\";\nimport { Restaurant } from \"@prisma/client\";\nimport { useContext, useState } from \"react\";\n\ninterface CartBannerProps {\n  restaurant: Pick<Restaurant, \"id\">;\n}\n\nconst CartBanner = ({ restaurant }: CartBannerProps) => {\n  const [isCartOpen, setIsCartOpen] = useState(false);\n  const { products, totalPrice, totalQuantity } = useContext(CartContext);\n\n  const restaurantHasProductsOnCart = products.some(\n    (product) => product.restaurantId === restaurant.id,\n  );\n\n  if (!restaurantHasProductsOnCart) return null;\n\n  return (\n    <div className=\"fixed bottom-0 left-0 z-50 w-full border-t border-solid border-muted bg-white p-5 pt-3 shadow-md\">\n      <div className=\"flex items-center justify-between\">\n        {/* PREÇO */}\n        <div>\n          <span className=\"text-xs text-muted-foreground\">\n            Total sem entrega\n          </span>\n          <h3 className=\"font-semibold\">\n            {formatCurrency(totalPrice)}{\" \"}\n            <span className=\"text-xs font-normal text-muted-foreground\">\n              {\" \"}\n              / {totalQuantity} {totalQuantity > 1 ? \"itens\" : \"item\"}\n            </span>\n          </h3>\n        </div>\n        {/* BOTÃO */}\n\n        <Button onClick={() => setIsCartOpen(true)}>Ver sacola</Button>\n\n        <Sheet open={isCartOpen} onOpenChange={setIsCartOpen}>\n          <SheetContent className=\"w-[90vw]\">\n            <SheetHeader>\n              <SheetTitle className=\"text-left\">Sacola</SheetTitle>\n            </SheetHeader>\n\n            <Cart setIsOpen={setIsCartOpen} />\n          </SheetContent>\n        </Sheet>\n      </div>\n    </div>\n  );\n};\n\nexport default CartBanner;\n"
  },
  {
    "path": "app/restaurants/[id]/_components/restaurant-image.tsx",
    "content": "\"use client\";\n\nimport { Button } from \"@/app/_components/ui/button\";\nimport { isRestaurantFavorited } from \"@/app/_helpers/restaurant\";\nimport useToggleFavoriteRestaurant from \"@/app/_hooks/use-toggle-favorite-restaurant\";\nimport { Restaurant, UserFavoriteRestaurant } from \"@prisma/client\";\nimport { ChevronLeftIcon, HeartIcon } from \"lucide-react\";\nimport { useSession } from \"next-auth/react\";\nimport Image from \"next/image\";\nimport { useRouter } from \"next/navigation\";\n\ninterface RestaurantImageProps {\n  restaurant: Pick<Restaurant, \"id\" | \"name\" | \"imageUrl\">;\n  userFavoriteRestaurants: UserFavoriteRestaurant[];\n}\n\nconst RestaurantImage = ({\n  restaurant,\n  userFavoriteRestaurants,\n}: RestaurantImageProps) => {\n  const { data } = useSession();\n\n  const router = useRouter();\n\n  const isFavorite = isRestaurantFavorited(\n    restaurant.id,\n    userFavoriteRestaurants,\n  );\n\n  const { handleFavoriteClick } = useToggleFavoriteRestaurant({\n    restaurantId: restaurant.id,\n    userId: data?.user.id,\n    restaurantIsFavorited: isFavorite,\n  });\n\n  const handleBackClick = () => router.back();\n\n  return (\n    <div className=\"relative h-[250px] w-full\">\n      <Image\n        src={restaurant.imageUrl}\n        alt={restaurant.name}\n        fill\n        sizes=\"100%\"\n        className=\"object-cover\"\n      />\n\n      <Button\n        className=\"absolute left-4 top-4 rounded-full bg-white text-foreground hover:text-white\"\n        size=\"icon\"\n        onClick={handleBackClick}\n      >\n        <ChevronLeftIcon />\n      </Button>\n\n      <Button\n        size=\"icon\"\n        className={`absolute right-4 top-4 rounded-full bg-gray-700 ${isFavorite && \"bg-primary hover:bg-gray-700\"}`}\n        onClick={handleFavoriteClick}\n      >\n        <HeartIcon size={20} className=\"fill-white\" />\n      </Button>\n    </div>\n  );\n};\n\nexport default RestaurantImage;\n"
  },
  {
    "path": "app/restaurants/[id]/page.tsx",
    "content": "import { db } from \"@/app/_lib/prisma\";\nimport { notFound } from \"next/navigation\";\nimport RestaurantImage from \"./_components/restaurant-image\";\nimport Image from \"next/image\";\nimport { StarIcon } from \"lucide-react\";\nimport DeliveryInfo from \"@/app/_components/delivery-info\";\nimport ProductList from \"@/app/_components/product-list\";\nimport CartBanner from \"./_components/cart-banner\";\nimport { getServerSession } from \"next-auth\";\nimport { authOptions } from \"@/app/_lib/auth\";\n\ninterface RestaurantPageProps {\n  params: {\n    id: string;\n  };\n}\n\nconst RestaurantPage = async ({ params: { id } }: RestaurantPageProps) => {\n  const restaurant = await db.restaurant.findUnique({\n    where: {\n      id,\n    },\n    include: {\n      categories: {\n        orderBy: {\n          createdAt: \"desc\",\n        },\n        include: {\n          products: {\n            where: {\n              restaurantId: id,\n            },\n            include: {\n              restaurant: {\n                select: {\n                  name: true,\n                },\n              },\n            },\n          },\n        },\n      },\n      products: {\n        take: 10,\n        include: {\n          restaurant: {\n            select: {\n              name: true,\n            },\n          },\n        },\n      },\n    },\n  });\n\n  if (!restaurant) {\n    return notFound();\n  }\n  const session = await getServerSession(authOptions);\n\n  const userFavoriteRestaurants = await db.userFavoriteRestaurant.findMany({\n    where: {\n      userId: session?.user.id,\n    },\n  });\n\n  return (\n    <div>\n      <RestaurantImage\n        restaurant={restaurant}\n        userFavoriteRestaurants={userFavoriteRestaurants}\n      />\n\n      <div className=\"relative z-50 mt-[-1.5rem] flex items-center justify-between rounded-tl-3xl rounded-tr-3xl bg-white px-5 pt-5\">\n        {/* TITULO */}\n        <div className=\"flex items-center gap-[0.375rem]\">\n          <div className=\"relative h-8 w-8\">\n            <Image\n              src={restaurant.imageUrl}\n              alt={restaurant.name}\n              fill\n              sizes=\"100%\"\n              className=\"rounded-full object-cover\"\n            />\n          </div>\n          <h1 className=\"text-xl font-semibold\">{restaurant.name}</h1>\n        </div>\n\n        <div className=\"flex items-center gap-[3px] rounded-full bg-foreground px-2 py-[2px] text-white\">\n          <StarIcon size={12} className=\"fill-yellow-400 text-yellow-400\" />\n          <span className=\"text-xs font-semibold\">5.0</span>\n        </div>\n      </div>\n\n      <div className=\"px-5\">\n        <DeliveryInfo restaurant={restaurant} />\n      </div>\n\n      <div className=\"mt-3 flex gap-4 overflow-x-scroll px-5 [&::-webkit-scrollbar]:hidden\">\n        {restaurant.categories.map((category) => (\n          <div\n            key={category.id}\n            className=\"min-w-[167px] rounded-lg bg-[#F4F4F4] text-center\"\n          >\n            <span className=\"text-xs text-muted-foreground\">\n              {category.name}\n            </span>\n          </div>\n        ))}\n      </div>\n\n      <div className=\"mt-6 space-y-4\">\n        {/* TODO: mostrar produtos mais pedidos quando implementarmos realização de pedido */}\n        <h2 className=\"px-5  font-semibold\">Mais Pedidos</h2>\n        <ProductList products={restaurant.products} />\n      </div>\n\n      {restaurant.categories.map((category) => (\n        <div className=\"mt-6 space-y-4\" key={category.id}>\n          {/* TODO: mostrar produtos mais pedidos quando implementarmos realização de pedido */}\n          <h2 className=\"px-5  font-semibold\">{category.name}</h2>\n          <ProductList products={category.products} />\n        </div>\n      ))}\n\n      <CartBanner restaurant={restaurant} />\n    </div>\n  );\n};\n\nexport default RestaurantPage;\n"
  },
  {
    "path": "app/restaurants/_actions/search.ts",
    "content": "\"use server\";\n\nimport { db } from \"@/app/_lib/prisma\";\n\nexport const searchForRestaurants = async (search: string) => {\n  const restaurants = await db.restaurant.findMany({\n    where: {\n      name: {\n        contains: search,\n        mode: \"insensitive\",\n      },\n    },\n  });\n\n  return restaurants;\n};\n"
  },
  {
    "path": "app/restaurants/_components/restaurants.tsx",
    "content": "\"use client\";\n\nimport { Restaurant, UserFavoriteRestaurant } from \"@prisma/client\";\nimport { notFound, useSearchParams } from \"next/navigation\";\nimport { useEffect, useState } from \"react\";\nimport { searchForRestaurants } from \"../_actions/search\";\nimport Header from \"@/app/_components/header\";\nimport RestaurantItem from \"@/app/_components/restaurant-item\";\n\ninterface RestaurantProps {\n  userFavoriteRestaurants: UserFavoriteRestaurant[];\n}\n\nconst Restaurants = ({ userFavoriteRestaurants }: RestaurantProps) => {\n  const searchParams = useSearchParams();\n  const [restaurants, setRestaurants] = useState<Restaurant[]>([]);\n\n  const searchFor = searchParams.get(\"search\");\n\n  useEffect(() => {\n    const fetchRestaurants = async () => {\n      if (!searchFor) return;\n      const foundRestaurants = await searchForRestaurants(searchFor);\n      setRestaurants(foundRestaurants);\n    };\n\n    fetchRestaurants();\n  }, [searchFor]);\n\n  if (!searchFor) {\n    return notFound();\n  }\n\n  return (\n    <>\n      <Header />\n      <div className=\"px-5 py-6\">\n        <h2 className=\"mb-6 text-lg font-semibold\">Restaurantes Encontrados</h2>\n        <div className=\"flex w-full flex-col gap-6\">\n          {restaurants.map((restaurant) => (\n            <RestaurantItem\n              key={restaurant.id}\n              restaurant={restaurant}\n              className=\"min-w-full max-w-full\"\n              userFavoriteRestaurants={userFavoriteRestaurants}\n            />\n          ))}\n        </div>\n      </div>\n    </>\n  );\n};\n\nexport default Restaurants;\n"
  },
  {
    "path": "app/restaurants/page.tsx",
    "content": "import { Suspense } from \"react\";\nimport Restaurants from \"./_components/restaurants\";\nimport { getServerSession } from \"next-auth\";\nimport { authOptions } from \"../_lib/auth\";\nimport { db } from \"../_lib/prisma\";\n\nconst RestaurantsPage = async () => {\n  const session = await getServerSession(authOptions);\n  const userFavoriteRestaurants = await db.userFavoriteRestaurant.findMany({\n    where: {\n      userId: session?.user.id,\n    },\n    include: {\n      restaurant: true,\n    },\n  });\n\n  return (\n    <Suspense>\n      <Restaurants userFavoriteRestaurants={userFavoriteRestaurants} />\n    </Suspense>\n  );\n};\n\nexport default RestaurantsPage;\n"
  },
  {
    "path": "app/restaurants/recommended/page.tsx",
    "content": "import Header from \"@/app/_components/header\";\nimport RestaurantItem from \"@/app/_components/restaurant-item\";\nimport { authOptions } from \"@/app/_lib/auth\";\nimport { db } from \"@/app/_lib/prisma\";\nimport { getServerSession } from \"next-auth\";\n\nconst RecommendedRestaurants = async () => {\n  const session = await getServerSession(authOptions);\n  const userFavoriteRestaurants = await db.userFavoriteRestaurant.findMany({\n    where: {\n      userId: session?.user.id,\n    },\n    include: {\n      restaurant: true,\n    },\n  });\n  const restaurants = await db.restaurant.findMany({});\n\n  return (\n    <>\n      <Header />\n      <div className=\"px-5 py-6\">\n        <h2 className=\"mb-6 text-lg font-semibold\">\n          Restaurantes Recomendados\n        </h2>\n        <div className=\"flex w-full flex-col gap-6\">\n          {restaurants.map((restaurant) => (\n            <RestaurantItem\n              key={restaurant.id}\n              restaurant={restaurant}\n              className=\"min-w-full max-w-full\"\n              userFavoriteRestaurants={userFavoriteRestaurants}\n            />\n          ))}\n        </div>\n      </div>\n    </>\n  );\n};\n\nexport default RecommendedRestaurants;\n"
  },
  {
    "path": "components.json",
    "content": "{\n  \"$schema\": \"https://ui.shadcn.com/schema.json\",\n  \"style\": \"default\",\n  \"rsc\": true,\n  \"tsx\": true,\n  \"tailwind\": {\n    \"config\": \"tailwind.config.ts\",\n    \"css\": \"app/globals.css\",\n    \"baseColor\": \"slate\",\n    \"cssVariables\": true,\n    \"prefix\": \"\"\n  },\n  \"aliases\": {\n    \"components\": \"@/app/_components\",\n    \"utils\": \"@/app/_lib/utils\"\n  }\n}\n"
  },
  {
    "path": "docker-compose.yml",
    "content": "version: \"3\"\n\nservices:\n  postgres:\n    image: postgres:latest\n    container_name: fsw-foods-postgres\n    environment:\n      POSTGRES_USER: postgres\n      POSTGRES_PASSWORD: password\n    ports:\n      - \"5432:5432\"\n    volumes:\n      - ./.postgres-data:/var/lib/postgresql/data\n\nvolumes:\n  .postgres-data:\n"
  },
  {
    "path": "next-auth.d.ts",
    "content": "/* eslint-disable no-unused-vars */\nimport { DefaultSession } from \"next-auth\";\n\ndeclare module \"next-auth\" {\n  interface Session {\n    user: {\n      id?: string;\n    } & DefaultSession[\"user\"];\n  }\n}\n"
  },
  {
    "path": "next.config.mjs",
    "content": "/** @type {import('next').NextConfig} */\nconst nextConfig = {\n  images: {\n    remotePatterns: [{ hostname: \"utfs.io\" }],\n  },\n};\n\nexport default nextConfig;\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"fsw-foods\",\n  \"version\": \"0.1.0\",\n  \"private\": true,\n  \"scripts\": {\n    \"dev\": \"next dev\",\n    \"build\": \"next build\",\n    \"start\": \"next start\",\n    \"lint\": \"next lint\",\n    \"prepare\": \"husky && prisma generate\"\n  },\n  \"prisma\": {\n    \"seed\": \"ts-node ./prisma/seed.ts\"\n  },\n  \"dependencies\": {\n    \"@auth/prisma-adapter\": \"^2.0.0\",\n    \"@prisma/client\": \"^5.12.1\",\n    \"@radix-ui/react-alert-dialog\": \"^1.0.5\",\n    \"@radix-ui/react-avatar\": \"^1.0.4\",\n    \"@radix-ui/react-dialog\": \"^1.0.5\",\n    \"@radix-ui/react-separator\": \"^1.0.3\",\n    \"@radix-ui/react-slot\": \"^1.0.2\",\n    \"class-variance-authority\": \"^0.7.0\",\n    \"clsx\": \"^2.1.0\",\n    \"git-commit-msg-linter\": \"^5.0.7\",\n    \"lucide-react\": \"^0.368.0\",\n    \"next\": \"14.2.1\",\n    \"next-auth\": \"^4.24.7\",\n    \"next-themes\": \"^0.3.0\",\n    \"react\": \"^18\",\n    \"react-dom\": \"^18\",\n    \"sonner\": \"^1.4.41\",\n    \"tailwind-merge\": \"^2.2.2\",\n    \"tailwindcss-animate\": \"^1.0.7\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^20\",\n    \"@types/react\": \"^18\",\n    \"@types/react-dom\": \"^18\",\n    \"eslint\": \"^8\",\n    \"eslint-config-next\": \"14.2.1\",\n    \"husky\": \"^9.0.11\",\n    \"lint-staged\": \"^15.2.2\",\n    \"postcss\": \"^8\",\n    \"prettier\": \"^3.2.5\",\n    \"prettier-plugin-tailwindcss\": \"^0.5.14\",\n    \"prisma\": \"^5.12.1\",\n    \"tailwindcss\": \"^3.4.1\",\n    \"ts-node\": \"^10.9.2\",\n    \"typescript\": \"^5\"\n  }\n}\n"
  },
  {
    "path": "postcss.config.mjs",
    "content": "/** @type {import('postcss-load-config').Config} */\nconst config = {\n  plugins: {\n    tailwindcss: {},\n  },\n};\n\nexport default config;\n"
  },
  {
    "path": "prisma/migrations/20240415210903_init_database/migration.sql",
    "content": "-- CreateTable\nCREATE TABLE \"Restaurant\" (\n    \"id\" TEXT NOT NULL,\n    \"name\" TEXT NOT NULL,\n    \"imageUrl\" TEXT NOT NULL,\n    \"deliveryFee\" DECIMAL(10,2) NOT NULL,\n    \"deliveryTimeMinutes\" INTEGER NOT NULL,\n\n    CONSTRAINT \"Restaurant_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"Category\" (\n    \"id\" TEXT NOT NULL,\n    \"name\" TEXT NOT NULL,\n    \"imageUrl\" TEXT NOT NULL,\n\n    CONSTRAINT \"Category_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"Product\" (\n    \"id\" TEXT NOT NULL,\n    \"name\" TEXT NOT NULL,\n    \"description\" TEXT NOT NULL,\n    \"imageUrl\" TEXT NOT NULL,\n    \"price\" DECIMAL(10,2) NOT NULL,\n    \"discountPercentage\" INTEGER NOT NULL DEFAULT 0,\n    \"restaurantId\" TEXT NOT NULL,\n    \"categoryId\" TEXT NOT NULL,\n\n    CONSTRAINT \"Product_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"_CategoryToRestaurant\" (\n    \"A\" TEXT NOT NULL,\n    \"B\" TEXT NOT NULL\n);\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"_CategoryToRestaurant_AB_unique\" ON \"_CategoryToRestaurant\"(\"A\", \"B\");\n\n-- CreateIndex\nCREATE INDEX \"_CategoryToRestaurant_B_index\" ON \"_CategoryToRestaurant\"(\"B\");\n\n-- AddForeignKey\nALTER TABLE \"Product\" ADD CONSTRAINT \"Product_restaurantId_fkey\" FOREIGN KEY (\"restaurantId\") REFERENCES \"Restaurant\"(\"id\") ON DELETE RESTRICT ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"Product\" ADD CONSTRAINT \"Product_categoryId_fkey\" FOREIGN KEY (\"categoryId\") REFERENCES \"Category\"(\"id\") ON DELETE RESTRICT ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"_CategoryToRestaurant\" ADD CONSTRAINT \"_CategoryToRestaurant_A_fkey\" FOREIGN KEY (\"A\") REFERENCES \"Category\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"_CategoryToRestaurant\" ADD CONSTRAINT \"_CategoryToRestaurant_B_fkey\" FOREIGN KEY (\"B\") REFERENCES \"Restaurant\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n"
  },
  {
    "path": "prisma/migrations/20240501004806_add_created_at/migration.sql",
    "content": "-- AlterTable\nALTER TABLE \"Category\" ADD COLUMN     \"createdAt\" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;\n\n-- AlterTable\nALTER TABLE \"Product\" ADD COLUMN     \"createdAt\" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;\n"
  },
  {
    "path": "prisma/migrations/20240502232158_add_auth_tables/migration.sql",
    "content": "-- CreateTable\nCREATE TABLE \"accounts\" (\n    \"id\" TEXT NOT NULL,\n    \"user_id\" TEXT NOT NULL,\n    \"type\" TEXT NOT NULL,\n    \"provider\" TEXT NOT NULL,\n    \"provider_account_id\" TEXT NOT NULL,\n    \"refresh_token\" TEXT,\n    \"access_token\" TEXT,\n    \"expires_at\" INTEGER,\n    \"token_type\" TEXT,\n    \"scope\" TEXT,\n    \"id_token\" TEXT,\n    \"session_state\" TEXT,\n\n    CONSTRAINT \"accounts_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"sessions\" (\n    \"id\" TEXT NOT NULL,\n    \"session_token\" TEXT NOT NULL,\n    \"user_id\" TEXT NOT NULL,\n    \"expires\" TIMESTAMP(3) NOT NULL,\n\n    CONSTRAINT \"sessions_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"users\" (\n    \"id\" TEXT NOT NULL,\n    \"name\" TEXT,\n    \"email\" TEXT,\n    \"email_verified\" TIMESTAMP(3),\n    \"image\" TEXT,\n\n    CONSTRAINT \"users_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"verificationtokens\" (\n    \"identifier\" TEXT NOT NULL,\n    \"token\" TEXT NOT NULL,\n    \"expires\" TIMESTAMP(3) NOT NULL\n);\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"accounts_provider_provider_account_id_key\" ON \"accounts\"(\"provider\", \"provider_account_id\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"sessions_session_token_key\" ON \"sessions\"(\"session_token\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"users_email_key\" ON \"users\"(\"email\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"verificationtokens_identifier_token_key\" ON \"verificationtokens\"(\"identifier\", \"token\");\n\n-- AddForeignKey\nALTER TABLE \"accounts\" ADD CONSTRAINT \"accounts_user_id_fkey\" FOREIGN KEY (\"user_id\") REFERENCES \"users\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"sessions\" ADD CONSTRAINT \"sessions_user_id_fkey\" FOREIGN KEY (\"user_id\") REFERENCES \"users\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n"
  },
  {
    "path": "prisma/migrations/20240503000412_add_order_table/migration.sql",
    "content": "-- CreateEnum\nCREATE TYPE \"OrderStatus\" AS ENUM ('CONFIRMED', 'CANCELED', 'PREPARING', 'DELIVERING', 'COMPLETED');\n\n-- CreateTable\nCREATE TABLE \"Order\" (\n    \"id\" TEXT NOT NULL,\n    \"userId\" TEXT NOT NULL,\n    \"restaurantId\" TEXT NOT NULL,\n    \"deliveryFee\" DECIMAL(10,2) NOT NULL,\n    \"deliveryTimeMinutes\" INTEGER NOT NULL,\n    \"subtotalPrice\" DECIMAL(10,2) NOT NULL,\n    \"totalPrice\" DECIMAL(10,2) NOT NULL,\n    \"totalDiscounts\" DECIMAL(10,2) NOT NULL,\n    \"createdAt\" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,\n    \"status\" \"OrderStatus\" NOT NULL,\n\n    CONSTRAINT \"Order_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"_OrderToProduct\" (\n    \"A\" TEXT NOT NULL,\n    \"B\" TEXT NOT NULL\n);\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"_OrderToProduct_AB_unique\" ON \"_OrderToProduct\"(\"A\", \"B\");\n\n-- CreateIndex\nCREATE INDEX \"_OrderToProduct_B_index\" ON \"_OrderToProduct\"(\"B\");\n\n-- AddForeignKey\nALTER TABLE \"Order\" ADD CONSTRAINT \"Order_userId_fkey\" FOREIGN KEY (\"userId\") REFERENCES \"users\"(\"id\") ON DELETE RESTRICT ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"Order\" ADD CONSTRAINT \"Order_restaurantId_fkey\" FOREIGN KEY (\"restaurantId\") REFERENCES \"Restaurant\"(\"id\") ON DELETE RESTRICT ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"_OrderToProduct\" ADD CONSTRAINT \"_OrderToProduct_A_fkey\" FOREIGN KEY (\"A\") REFERENCES \"Order\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"_OrderToProduct\" ADD CONSTRAINT \"_OrderToProduct_B_fkey\" FOREIGN KEY (\"B\") REFERENCES \"Product\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n"
  },
  {
    "path": "prisma/migrations/20240503012547_add_order_product_table/migration.sql",
    "content": "/*\n  Warnings:\n\n  - You are about to drop the `_OrderToProduct` table. If the table is not empty, all the data it contains will be lost.\n\n*/\n-- DropForeignKey\nALTER TABLE \"_OrderToProduct\" DROP CONSTRAINT \"_OrderToProduct_A_fkey\";\n\n-- DropForeignKey\nALTER TABLE \"_OrderToProduct\" DROP CONSTRAINT \"_OrderToProduct_B_fkey\";\n\n-- AlterTable\nALTER TABLE \"Order\" ADD COLUMN     \"productId\" TEXT;\n\n-- DropTable\nDROP TABLE \"_OrderToProduct\";\n\n-- CreateTable\nCREATE TABLE \"OrderProduct\" (\n    \"id\" TEXT NOT NULL,\n    \"orderId\" TEXT NOT NULL,\n    \"productId\" TEXT NOT NULL,\n    \"quantity\" INTEGER NOT NULL,\n\n    CONSTRAINT \"OrderProduct_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- AddForeignKey\nALTER TABLE \"OrderProduct\" ADD CONSTRAINT \"OrderProduct_orderId_fkey\" FOREIGN KEY (\"orderId\") REFERENCES \"Order\"(\"id\") ON DELETE RESTRICT ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"OrderProduct\" ADD CONSTRAINT \"OrderProduct_productId_fkey\" FOREIGN KEY (\"productId\") REFERENCES \"Product\"(\"id\") ON DELETE RESTRICT ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"Order\" ADD CONSTRAINT \"Order_productId_fkey\" FOREIGN KEY (\"productId\") REFERENCES \"Product\"(\"id\") ON DELETE SET NULL ON UPDATE CASCADE;\n"
  },
  {
    "path": "prisma/migrations/20240503012822_add_order_product_table/migration.sql",
    "content": "/*\n  Warnings:\n\n  - You are about to drop the column `productId` on the `Order` table. All the data in the column will be lost.\n\n*/\n-- DropForeignKey\nALTER TABLE \"Order\" DROP CONSTRAINT \"Order_productId_fkey\";\n\n-- AlterTable\nALTER TABLE \"Order\" DROP COLUMN \"productId\";\n"
  },
  {
    "path": "prisma/migrations/20240503233901_add_user_restaurant_favorites_table/migration.sql",
    "content": "-- CreateTable\nCREATE TABLE \"UserFavoriteRestaurant\" (\n    \"id\" TEXT NOT NULL,\n    \"userId\" TEXT NOT NULL,\n    \"restaurantId\" TEXT NOT NULL,\n    \"createdAt\" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,\n\n    CONSTRAINT \"UserFavoriteRestaurant_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- AddForeignKey\nALTER TABLE \"UserFavoriteRestaurant\" ADD CONSTRAINT \"UserFavoriteRestaurant_userId_fkey\" FOREIGN KEY (\"userId\") REFERENCES \"users\"(\"id\") ON DELETE RESTRICT ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"UserFavoriteRestaurant\" ADD CONSTRAINT \"UserFavoriteRestaurant_restaurantId_fkey\" FOREIGN KEY (\"restaurantId\") REFERENCES \"Restaurant\"(\"id\") ON DELETE RESTRICT ON UPDATE CASCADE;\n"
  },
  {
    "path": "prisma/migrations/20240503235713_add_compound_key_to_user_favorite_restaurant/migration.sql",
    "content": "/*\n  Warnings:\n\n  - The primary key for the `UserFavoriteRestaurant` table will be changed. If it partially fails, the table could be left without primary key constraint.\n  - You are about to drop the column `id` on the `UserFavoriteRestaurant` table. All the data in the column will be lost.\n\n*/\n-- AlterTable\nALTER TABLE \"UserFavoriteRestaurant\" DROP CONSTRAINT \"UserFavoriteRestaurant_pkey\",\nDROP COLUMN \"id\",\nADD CONSTRAINT \"UserFavoriteRestaurant_pkey\" PRIMARY KEY (\"userId\", \"restaurantId\");\n"
  },
  {
    "path": "prisma/migrations/migration_lock.toml",
    "content": "# Please do not edit this file manually\n# It should be added in your version-control system (i.e. Git)\nprovider = \"postgresql\""
  },
  {
    "path": "prisma/schema.prisma",
    "content": "generator client {\n  provider = \"prisma-client-js\"\n}\n\ndatasource db {\n  provider = \"postgresql\"\n  url      = env(\"DATABASE_URL\")\n}\n\nmodel Account {\n  id                String  @id @default(cuid())\n  userId            String  @map(\"user_id\")\n  type              String\n  provider          String\n  providerAccountId String  @map(\"provider_account_id\")\n  refresh_token     String? @db.Text\n  access_token      String? @db.Text\n  expires_at        Int?\n  token_type        String?\n  scope             String?\n  id_token          String? @db.Text\n  session_state     String?\n\n  user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n\n  @@unique([provider, providerAccountId])\n  @@map(\"accounts\")\n}\n\nmodel Session {\n  id           String   @id @default(cuid())\n  sessionToken String   @unique @map(\"session_token\")\n  userId       String   @map(\"user_id\")\n  expires      DateTime\n  user         User     @relation(fields: [userId], references: [id], onDelete: Cascade)\n\n  @@map(\"sessions\")\n}\n\nmodel User {\n  id                  String                   @id @default(cuid())\n  name                String?\n  email               String?                  @unique\n  emailVerified       DateTime?                @map(\"email_verified\")\n  image               String?\n  accounts            Account[]\n  sessions            Session[]\n  orders              Order[]\n  favoriteRestaurants UserFavoriteRestaurant[]\n\n  @@map(\"users\")\n}\n\nmodel VerificationToken {\n  identifier String\n  token      String\n  expires    DateTime\n\n  @@unique([identifier, token])\n  @@map(\"verificationtokens\")\n}\n\nmodel Restaurant {\n  id                  String                   @id @default(uuid())\n  name                String\n  imageUrl            String\n  deliveryFee         Decimal                  @db.Decimal(10, 2)\n  deliveryTimeMinutes Int\n  categories          Category[]\n  products            Product[]\n  orders              Order[]\n  usersWhoFavorited   UserFavoriteRestaurant[]\n}\n\nmodel UserFavoriteRestaurant {\n  userId       String\n  user         User       @relation(fields: [userId], references: [id])\n  restaurantId String\n  restaurant   Restaurant @relation(fields: [restaurantId], references: [id])\n  createdAt    DateTime   @default(now())\n\n   @@id([userId, restaurantId])\n}\n\nmodel Category {\n  id          String       @id @default(uuid())\n  name        String\n  imageUrl    String\n  restaurants Restaurant[]\n  products    Product[]\n  createdAt   DateTime     @default(now())\n}\n\nmodel Product {\n  id                 String         @id @default(uuid())\n  name               String\n  description        String\n  imageUrl           String\n  price              Decimal        @db.Decimal(10, 2)\n  discountPercentage Int            @default(0)\n  restaurantId       String\n  restaurant         Restaurant     @relation(fields: [restaurantId], references: [id])\n  categoryId         String\n  category           Category       @relation(fields: [categoryId], references: [id])\n  createdAt          DateTime       @default(now())\n  orderProducts      OrderProduct[]\n}\n\nmodel OrderProduct {\n  id        String  @id @default(uuid())\n  orderId   String\n  order     Order   @relation(fields: [orderId], references: [id])\n  productId String\n  product   Product @relation(fields: [productId], references: [id])\n  quantity  Int\n}\n\nmodel Order {\n  id                  String         @id @default(uuid())\n  userId              String\n  user                User           @relation(fields: [userId], references: [id])\n  products            OrderProduct[]\n  restaurant          Restaurant     @relation(fields: [restaurantId], references: [id])\n  restaurantId        String\n  deliveryFee         Decimal        @db.Decimal(10, 2)\n  deliveryTimeMinutes Int\n  subtotalPrice       Decimal        @db.Decimal(10, 2)\n  totalPrice          Decimal        @db.Decimal(10, 2)\n  totalDiscounts      Decimal        @db.Decimal(10, 2)\n  createdAt           DateTime       @default(now())\n  status              OrderStatus\n}\n\nenum OrderStatus {\n  CONFIRMED\n  CANCELED\n  PREPARING\n  DELIVERING\n  COMPLETED\n}\n"
  },
  {
    "path": "prisma/seed.ts",
    "content": "const { PrismaClient } = require(\"@prisma/client\");\n\nconst prismaClient = new PrismaClient();\n\nconst description =\n  \"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean nec nisl lorem. Praesent pharetra, sapien ut fringilla malesuada, nisi felis ullamcorper ex, eu consectetur elit dolor sed dolor. Praesent orci mi, auctor aliquet semper vitae, volutpat quis augue. Cras porta sapien nec pharetra laoreet. Sed at velit sit amet mauris varius volutpat sit amet id mauris. Maecenas vitae mattis ante. Morbi nulla quam, sagittis at orci eu, scelerisque auctor neque.\";\n\nconst createBurguers = async (\n  desertsCategoryId: string,\n  juicesCategoryId: string,\n) => {\n  const burguersCategory = await prismaClient.category.create({\n    data: {\n      name: \"Hambúrgueres\",\n      imageUrl:\n        \"https://utfs.io/f/92918634-fc03-4425-bc1f-d1fbc8933586-vzk6us.png\",\n    },\n  });\n\n  const burguerRestaurants = [\n    {\n      name: \"The Burguer King\",\n      imageUrl:\n        \"https://utfs.io/f/020e448e-a7d8-433f-9622-cb3b68f34d48-p3apya.png\",\n      deliveryFee: 5,\n      deliveryTimeMinutes: 30,\n      categories: {\n        connect: {\n          id: burguersCategory.id,\n        },\n      },\n    },\n    {\n      name: \"Omni Burguer\",\n      imageUrl:\n        \"https://utfs.io/f/d0c54665-78d0-41af-98a4-8d1f459c622c-p3apy9.png\",\n      deliveryFee: 5,\n      deliveryTimeMinutes: 30,\n      categories: {\n        connect: {\n          id: burguersCategory.id,\n        },\n      },\n    },\n    {\n      name: \"The Burguer Queen\",\n      imageUrl:\n        \"https://utfs.io/f/d9834f2e-bc37-4c64-981b-cabf03018322-p3apy8.png\",\n      deliveryFee: 0,\n      deliveryTimeMinutes: 45,\n      categories: {\n        connect: {\n          id: burguersCategory.id,\n        },\n      },\n    },\n    {\n      name: \"Burguer House\",\n      imageUrl:\n        \"https://utfs.io/f/9c193fc1-9dcb-4394-8be4-d783266134dc-p3apy7.png\",\n      deliveryFee: 10,\n      deliveryTimeMinutes: 20,\n      categories: {\n        connect: {\n          id: burguersCategory.id,\n        },\n      },\n    },\n  ];\n\n  for (const item of burguerRestaurants) {\n    const restaurant = await prismaClient.restaurant.create({\n      data: item,\n    });\n\n    await createDeserts(restaurant.id, desertsCategoryId);\n    await createJuices(restaurant.id, juicesCategoryId);\n\n    console.log(`Created ${restaurant.name}`);\n\n    const burguerProducts = [\n      {\n        name: \"Cheese Burguer\",\n        price: 30,\n        description: description,\n        discountPercentage: 10,\n        imageUrl:\n          \"https://utfs.io/f/ae177fa1-129c-4f43-9928-aa8ac1080a18-yqapzx.png\",\n        restaurant: {\n          connect: {\n            id: restaurant.id,\n          },\n        },\n        category: {\n          connect: {\n            id: burguersCategory.id,\n          },\n        },\n      },\n      {\n        name: \"Double Cheese Burguer\",\n        price: 40,\n        description: description,\n        discountPercentage: 7,\n        imageUrl:\n          \"https://utfs.io/f/dca007fe-0025-422e-9328-16d40f0a1792-yqapzy.png\",\n        restaurant: {\n          connect: {\n            id: restaurant.id,\n          },\n        },\n        category: {\n          connect: {\n            id: burguersCategory.id,\n          },\n        },\n      },\n      {\n        name: \"Bacon Burguer\",\n        price: 35,\n        description: description,\n        discountPercentage: 5,\n        imageUrl:\n          \"https://utfs.io/f/4cb1ca21-0748-4296-a23d-88e52687506a-yqapzz.png\",\n        restaurant: {\n          connect: {\n            id: restaurant.id,\n          },\n        },\n        category: {\n          connect: {\n            id: burguersCategory.id,\n          },\n        },\n      },\n      {\n        name: \"Double Bacon Burguer\",\n        price: 45,\n        description: description,\n        discountPercentage: 10,\n        imageUrl:\n          \"https://utfs.io/f/ed9fde1e-0675-4829-8001-a775e2825dc6-yqaq00.png\",\n        restaurant: {\n          connect: {\n            id: restaurant.id,\n          },\n        },\n        category: {\n          connect: {\n            id: burguersCategory.id,\n          },\n        },\n      },\n      {\n        name: \"Chicken Burguer\",\n        price: 30,\n        description: description,\n        discountPercentage: 7,\n        imageUrl:\n          \"https://utfs.io/f/0aff860a-3e05-42fd-9b2a-53d03c744949-yqaq01.png\",\n        restaurant: {\n          connect: {\n            id: restaurant.id,\n          },\n        },\n        category: {\n          connect: {\n            id: burguersCategory.id,\n          },\n        },\n      },\n      {\n        name: \"Double Chicken Burguer\",\n        price: 40,\n        description: description,\n        discountPercentage: 5,\n        imageUrl:\n          \"https://utfs.io/f/d2157790-fcb7-4d09-b074-80af4bfb9892-yqaq02.png\",\n        restaurant: {\n          connect: {\n            id: restaurant.id,\n          },\n        },\n        category: {\n          connect: {\n            id: burguersCategory.id,\n          },\n        },\n      },\n    ];\n\n    for (const product of burguerProducts) {\n      await prismaClient.product.create({\n        data: product,\n      });\n\n      console.log(`Created ${product.name}`);\n    }\n  }\n};\n\nconst createPizzas = async (\n  desertsCategoryId: string,\n  juicesCategoryId: string,\n) => {\n  const pizzasCategory = await prismaClient.category.create({\n    data: {\n      name: \"Pizzas\",\n      imageUrl:\n        \"https://utfs.io/f/d9ca0163-6bc8-42dc-bbb3-377636849cd8-mtj7yz.png\",\n    },\n  });\n\n  const pizzaRestaurants = [\n    {\n      name: \"Pizza Hut\",\n      imageUrl:\n        \"https://utfs.io/f/f50301c9-7968-4d76-b4a3-b8ed24e2089c-5p2j0.png\",\n      deliveryFee: 5,\n      deliveryTimeMinutes: 30,\n      categories: {\n        connect: {\n          id: pizzasCategory.id,\n        },\n      },\n    },\n    {\n      name: \"Omni Pizza\",\n      imageUrl:\n        \"https://utfs.io/f/8a9eb9dc-6434-4246-91c9-1c0a60a6e5f0-5p2j1.png\",\n      deliveryFee: 5,\n      deliveryTimeMinutes: 30,\n      categories: {\n        connect: {\n          id: pizzasCategory.id,\n        },\n      },\n    },\n    {\n      name: \"The Pizza Queen\",\n      imageUrl:\n        \"https://utfs.io/f/e83dc871-19e3-4d39-8163-fb2f1e24b6b1-5p2j2.png\",\n      deliveryFee: 0,\n      deliveryTimeMinutes: 45,\n      categories: {\n        connect: {\n          id: pizzasCategory.id,\n        },\n      },\n    },\n    {\n      name: \"Pizza House\",\n      imageUrl:\n        \"https://utfs.io/f/a73ec63a-7fc8-4a23-8d03-62debee79e6a-5p2j3.png\",\n      deliveryFee: 10,\n      deliveryTimeMinutes: 20,\n      categories: {\n        connect: {\n          id: pizzasCategory.id,\n        },\n      },\n    },\n  ];\n\n  for (const item of pizzaRestaurants) {\n    const restaurant = await prismaClient.restaurant.create({\n      data: item,\n    });\n\n    await createDeserts(restaurant.id, desertsCategoryId);\n    await createJuices(restaurant.id, juicesCategoryId);\n\n    console.log(`Created ${restaurant.name}`);\n\n    const pizzaProducts = [\n      {\n        name: \"Pepperoni Pizza\",\n        price: 45,\n        description: description,\n        discountPercentage: 0,\n        imageUrl:\n          \"https://utfs.io/f/645ba997-00b1-44ed-9928-b9eb41e93896-berpub.jpg\",\n        restaurant: {\n          connect: {\n            id: restaurant.id,\n          },\n        },\n        category: {\n          connect: {\n            id: pizzasCategory.id,\n          },\n        },\n      },\n      {\n        name: \"Margarita Pizza\",\n        price: 40,\n        description: description,\n        discountPercentage: 5,\n        imageUrl:\n          \"https://utfs.io/f/4ee1f69b-e0a3-4166-bae5-b666996bcd3b-berpua.png\",\n        restaurant: {\n          connect: {\n            id: restaurant.id,\n          },\n        },\n        category: {\n          connect: {\n            id: pizzasCategory.id,\n          },\n        },\n      },\n      {\n        name: \"Hawaiian Pizza\",\n        price: 45,\n        description: \"A delicious hawaiian pizza\",\n        discountPercentage: 5,\n        imageUrl:\n          \"https://utfs.io/f/0bb7a869-f369-4506-94ea-6cc23c8dd92f-berpu9.png\",\n        restaurant: {\n          connect: {\n            id: restaurant.id,\n          },\n        },\n        category: {\n          connect: {\n            id: pizzasCategory.id,\n          },\n        },\n      },\n      {\n        name: \"Vegetarian Pizza\",\n        price: 35,\n        description: description,\n        discountPercentage: 0,\n        imageUrl:\n          \"https://utfs.io/f/1bb04a24-361c-4e3a-ad2f-81255f2d53b9-berpux.png\",\n        restaurant: {\n          connect: {\n            id: restaurant.id,\n          },\n        },\n        category: {\n          connect: {\n            id: pizzasCategory.id,\n          },\n        },\n      },\n      {\n        name: \"Meat Lovers Pizza\",\n        price: 50,\n        description: description,\n        discountPercentage: 10,\n        imageUrl:\n          \"https://utfs.io/f/ead919ee-2e3d-423f-b294-e525f9d6a5b7-berpuy.png\",\n        restaurant: {\n          connect: {\n            id: restaurant.id,\n          },\n        },\n        category: {\n          connect: {\n            id: pizzasCategory.id,\n          },\n        },\n      },\n    ];\n\n    for (const product of pizzaProducts) {\n      await prismaClient.product.create({\n        data: product,\n      });\n\n      console.log(`Created ${product.name}`);\n    }\n  }\n};\n\nconst createJapanese = async (\n  desertsCategoryId: string,\n  juicesCategoryId: string,\n) => {\n  const japaneseCategory = await prismaClient.category.create({\n    data: {\n      name: \"Japonesa\",\n      imageUrl:\n        \"https://utfs.io/f/ccc2351a-49b0-4613-a233-3b3b3bd6a47c-yd9ii3.png\",\n    },\n  });\n\n  const japaneseRestaurants = [\n    {\n      name: \"Sushi House\",\n      imageUrl:\n        \"https://utfs.io/f/7f52b936-9f7a-40cc-b22f-b62727ddb9cc-fu3r05.png\",\n      deliveryFee: 5,\n      deliveryTimeMinutes: 30,\n      categories: {\n        connect: {\n          id: japaneseCategory.id,\n        },\n      },\n    },\n    {\n      name: \"Omni Sushi\",\n      imageUrl:\n        \"https://utfs.io/f/f809b477-7cf1-47f5-8664-0a4566225867-fu3r06.png\",\n      deliveryFee: 5,\n      deliveryTimeMinutes: 30,\n      categories: {\n        connect: {\n          id: japaneseCategory.id,\n        },\n      },\n    },\n    {\n      name: \"The Sushi Queen\",\n      imageUrl:\n        \"https://utfs.io/f/42bb722a-0b76-40e8-8251-cee9093bed38-fu3r07.png\",\n      deliveryFee: 0,\n      deliveryTimeMinutes: 45,\n      categories: {\n        connect: {\n          id: japaneseCategory.id,\n        },\n      },\n    },\n    {\n      name: \"Sushi House\",\n      imageUrl:\n        \"https://utfs.io/f/de37be82-23bf-4901-aeea-b93c281bf401-fu3r08.png\",\n      deliveryFee: 10,\n      deliveryTimeMinutes: 20,\n      categories: {\n        connect: {\n          id: japaneseCategory.id,\n        },\n      },\n    },\n  ];\n\n  for (const item of japaneseRestaurants) {\n    const restaurant = await prismaClient.restaurant.create({\n      data: item,\n    });\n\n    console.log(`Created ${restaurant.name}`);\n\n    await createDeserts(restaurant.id, desertsCategoryId);\n    await createJuices(restaurant.id, juicesCategoryId);\n\n    const japaneseProducts = [\n      {\n        name: \"Sushi Combo\",\n        price: 30,\n        description: description,\n        discountPercentage: 5,\n        imageUrl:\n          \"https://utfs.io/f/5ef70d5c-892b-424d-8655-6bc2716411e1-1lryd0.png\",\n        restaurant: {\n          connect: {\n            id: restaurant.id,\n          },\n        },\n        category: {\n          connect: {\n            id: japaneseCategory.id,\n          },\n        },\n      },\n      {\n        name: \"Sashimi Combo\",\n        price: 40,\n        description: description,\n        discountPercentage: 10,\n        imageUrl:\n          \"https://utfs.io/f/e8b2fb18-d636-477f-8bed-cfe85358246f-1lryd1.png\",\n        restaurant: {\n          connect: {\n            id: restaurant.id,\n          },\n        },\n        category: {\n          connect: {\n            id: japaneseCategory.id,\n          },\n        },\n      },\n      {\n        name: \"Nigiri Combo\",\n        price: 35,\n        description: description,\n        discountPercentage: 7,\n        imageUrl:\n          \"https://utfs.io/f/fd9458a3-153b-4833-aca1-61a882da1ce6-1lryd2.png\",\n        restaurant: {\n          connect: {\n            id: restaurant.id,\n          },\n        },\n        category: {\n          connect: {\n            id: japaneseCategory.id,\n          },\n        },\n      },\n      {\n        name: \"Temaki Combo\",\n        price: 45,\n        description: description,\n        discountPercentage: 0,\n        imageUrl:\n          \"https://utfs.io/f/eec36a13-de2d-48ed-92d2-4f74477dad83-1lryd3.png\",\n        restaurant: {\n          connect: {\n            id: restaurant.id,\n          },\n        },\n        category: {\n          connect: {\n            id: japaneseCategory.id,\n          },\n        },\n      },\n      {\n        name: \"Uramaki Combo\",\n        price: 30,\n        description: description,\n        discountPercentage: 10,\n        imageUrl:\n          \"https://utfs.io/f/c04a5df1-c1ac-4e28-ba48-27d856caa553-1lryd4.png\",\n        restaurant: {\n          connect: {\n            id: restaurant.id,\n          },\n        },\n        category: {\n          connect: {\n            id: japaneseCategory.id,\n          },\n        },\n      },\n      {\n        name: \"Hosomaki Combo\",\n        price: 40,\n        description: description,\n        discountPercentage: 0,\n        imageUrl:\n          \"https://utfs.io/f/fd147569-14c6-428d-9a54-df64c61c6bb6-1lryd5.png\",\n        restaurant: {\n          connect: {\n            id: restaurant.id,\n          },\n        },\n        category: {\n          connect: {\n            id: japaneseCategory.id,\n          },\n        },\n      },\n    ];\n\n    for (const product of japaneseProducts) {\n      await prismaClient.product.create({\n        data: product,\n      });\n\n      console.log(`Created ${product.name}`);\n    }\n  }\n};\n\nconst createBrazilian = async (\n  desertsCategoryId: string,\n  juicesCategoryId: string,\n) => {\n  const brazilianCategory = await prismaClient.category.create({\n    data: {\n      name: \"Brasileira\",\n      imageUrl:\n        \"https://utfs.io/f/d84e3a7a-fcf6-4d3d-86bf-d62c0b1febdc-m1yv44.png\",\n    },\n  });\n\n  const brazilianRestaurants = [\n    {\n      name: \"Churrascaria House\",\n      imageUrl:\n        \"https://utfs.io/f/5a090f6e-520f-418a-a42a-043b512314a2-n9n78u.png\",\n      deliveryFee: 5,\n      deliveryTimeMinutes: 30,\n      categories: {\n        connect: {\n          id: brazilianCategory.id,\n        },\n      },\n    },\n    {\n      name: \"Omni Churrascaria\",\n      imageUrl:\n        \"https://utfs.io/f/87338583-660e-47f1-a80d-6ea804298bd5-n9n78v.png\",\n      deliveryFee: 5,\n      deliveryTimeMinutes: 30,\n      categories: {\n        connect: {\n          id: brazilianCategory.id,\n        },\n      },\n    },\n    {\n      name: \"The Churrascaria Queen\",\n      imageUrl:\n        \"https://utfs.io/f/b26b00ca-5041-46cb-9b68-a1856ed064ad-n9n78w.png\",\n      deliveryFee: 0,\n      deliveryTimeMinutes: 45,\n      categories: {\n        connect: {\n          id: brazilianCategory.id,\n        },\n      },\n    },\n    {\n      name: \"Churrascaria House\",\n      imageUrl:\n        \"https://utfs.io/f/c1f279ea-ac09-4e4f-9757-30018cb4c7bc-n9n78x.png\",\n      deliveryFee: 10,\n      deliveryTimeMinutes: 20,\n      categories: {\n        connect: {\n          id: brazilianCategory.id,\n        },\n      },\n    },\n  ];\n\n  for (const item of brazilianRestaurants) {\n    const restaurant = await prismaClient.restaurant.create({\n      data: item,\n    });\n\n    console.log(`Created ${restaurant.name}`);\n\n    await createDeserts(restaurant.id, desertsCategoryId);\n    await createJuices(restaurant.id, juicesCategoryId);\n\n    const brazilianProducts = [\n      {\n        name: \"Camarão Citrus\",\n        price: 40,\n        description: description,\n        discountPercentage: 5,\n        imageUrl:\n          \"https://utfs.io/f/cecdeeb8-10e6-4be8-8553-0a120717d194-xf34p9.png\",\n        restaurant: {\n          connect: {\n            id: restaurant.id,\n          },\n        },\n        category: {\n          connect: {\n            id: brazilianCategory.id,\n          },\n        },\n      },\n      {\n        name: \"Picanha Especial\",\n        price: 45,\n        description: description,\n        discountPercentage: 5,\n        imageUrl:\n          \"https://utfs.io/f/089299df-fcb9-446a-a8cc-75e4e26b7357-xf34p8.png\",\n        restaurant: {\n          connect: {\n            id: restaurant.id,\n          },\n        },\n        category: {\n          connect: {\n            id: brazilianCategory.id,\n          },\n        },\n      },\n      {\n        name: \"Macarrão com Carne\",\n        price: 35,\n        description: description,\n        discountPercentage: 5,\n        imageUrl:\n          \"https://utfs.io/f/891eb8aa-635e-4cb3-b7fd-eb8d1c9f14e1-xf34p7.png\",\n        restaurant: {\n          connect: {\n            id: restaurant.id,\n          },\n        },\n        category: {\n          connect: {\n            id: brazilianCategory.id,\n          },\n        },\n      },\n      {\n        name: \"Carne com Salada\",\n        price: 35,\n        description: description,\n        discountPercentage: 5,\n        imageUrl:\n          \"https://utfs.io/f/43d9e18a-4ba9-47b6-9a87-6d4fedbd6f41-xf34ol.png\",\n        restaurant: {\n          connect: {\n            id: restaurant.id,\n          },\n        },\n        category: {\n          connect: {\n            id: brazilianCategory.id,\n          },\n        },\n      },\n      {\n        name: \"Filé Mignon com Fritas\",\n        price: 40,\n        description: description,\n        discountPercentage: 0,\n        imageUrl:\n          \"https://utfs.io/f/0cfa51a6-1a88-4114-a6c6-bf607a5a1cb0-xf34ok.png\",\n        restaurant: {\n          connect: {\n            id: restaurant.id,\n          },\n        },\n        category: {\n          connect: {\n            id: brazilianCategory.id,\n          },\n        },\n      },\n      {\n        name: \"Frango ao Molho\",\n        price: 40,\n        description: description,\n        discountPercentage: 5,\n        imageUrl:\n          \"https://utfs.io/f/9158a622-4b87-4ec6-a726-569dee27a093-xf34oj.png\",\n        restaurant: {\n          connect: {\n            id: restaurant.id,\n          },\n        },\n        category: {\n          connect: {\n            id: brazilianCategory.id,\n          },\n        },\n      },\n    ];\n\n    for (const product of brazilianProducts) {\n      await prismaClient.product.create({\n        data: product,\n      });\n\n      console.log(`Created ${product.name}`);\n    }\n  }\n};\n\nconst createDeserts = async (restaurantId: string, categoryId: string) => {\n  await prismaClient.restaurant.update({\n    where: {\n      id: restaurantId,\n    },\n    data: {\n      categories: {\n        connect: {\n          id: categoryId,\n        },\n      },\n    },\n  });\n\n  const desertProducts = [\n    {\n      name: \"Sorvete Especial\",\n      price: 30,\n      description: description,\n      discountPercentage: 10,\n      imageUrl:\n        \"https://utfs.io/f/b703fcaa-eb9c-4257-a08e-fba0f0e12fc1-pr8gxl.png\",\n      restaurant: {\n        connect: {\n          id: restaurantId,\n        },\n      },\n      category: {\n        connect: {\n          id: categoryId,\n        },\n      },\n    },\n    {\n      name: \"Bolo de Chocolate\",\n      price: 40,\n      description: description,\n      discountPercentage: 7,\n      imageUrl:\n        \"https://utfs.io/f/029befff-aba7-49b3-91c4-8da022e699b0-pr8gxm.png\",\n      restaurant: {\n        connect: {\n          id: restaurantId,\n        },\n      },\n      category: {\n        connect: {\n          id: categoryId,\n        },\n      },\n    },\n    {\n      name: \"Petit Gateau\",\n      price: 55,\n      description: description,\n      discountPercentage: 5,\n      imageUrl:\n        \"https://utfs.io/f/98f262f6-dc35-428b-bac9-ac443f9f41bb-pr8gxn.png\",\n      restaurant: {\n        connect: {\n          id: restaurantId,\n        },\n      },\n      category: {\n        connect: {\n          id: categoryId,\n        },\n      },\n    },\n    {\n      name: \"Bolo de Morango\",\n      price: 35,\n      description: description,\n      discountPercentage: 5,\n      imageUrl:\n        \"https://utfs.io/f/6e6ad97a-f1f1-4d4b-bb40-f5ff25ba97d4-pr8gxo.png\",\n      restaurant: {\n        connect: {\n          id: restaurantId,\n        },\n      },\n      category: {\n        connect: {\n          id: categoryId,\n        },\n      },\n    },\n    {\n      name: \"Biscoito de Chocolate\",\n      price: 30,\n      description: description,\n      discountPercentage: 7,\n      imageUrl:\n        \"https://utfs.io/f/4b8d0b7c-daa9-46f6-aebd-385cf5e086f7-pr8gxp.png\",\n      restaurant: {\n        connect: {\n          id: restaurantId,\n        },\n      },\n      category: {\n        connect: {\n          id: categoryId,\n        },\n      },\n    },\n    {\n      name: \"Torta de Morango\",\n      price: 45,\n      description: description,\n      discountPercentage: 5,\n      imageUrl:\n        \"https://utfs.io/f/4caadde1-0a1c-45a6-895b-4bfb6986099d-pr8gxq.png\",\n      restaurant: {\n        connect: {\n          id: restaurantId,\n        },\n      },\n      category: {\n        connect: {\n          id: categoryId,\n        },\n      },\n    },\n  ];\n\n  for (const product of desertProducts) {\n    await prismaClient.product.create({\n      data: product,\n    });\n\n    console.log(`Created ${product.name}`);\n  }\n};\n\nconst createJuices = async (restaurantId: string, categoryId: string) => {\n  await prismaClient.restaurant.update({\n    where: {\n      id: restaurantId,\n    },\n    data: {\n      categories: {\n        connect: {\n          id: categoryId,\n        },\n      },\n    },\n  });\n\n  const juiceProducts = [\n    {\n      name: \"Suco de Cenoura\",\n      price: 15,\n      description: description,\n      discountPercentage: 5,\n      imageUrl:\n        \"https://utfs.io/f/5126e950-40ca-4ef1-a166-16274fec16bc-6b2vea.png\",\n      restaurant: {\n        connect: {\n          id: restaurantId,\n        },\n      },\n      category: {\n        connect: {\n          id: categoryId,\n        },\n      },\n    },\n    {\n      name: \"Suco Cítrico\",\n      price: 20,\n      description: description,\n      discountPercentage: 7,\n      imageUrl:\n        \"https://utfs.io/f/6dbe915d-af87-4f2a-b841-864ba9427da8-6b2ve9.png\",\n      restaurant: {\n        connect: {\n          id: restaurantId,\n        },\n      },\n      category: {\n        connect: {\n          id: categoryId,\n        },\n      },\n    },\n    {\n      name: \"Suco de Limão\",\n      price: 12,\n      description: description,\n      discountPercentage: 5,\n      imageUrl:\n        \"https://utfs.io/f/03aa4137-c949-4d2c-bdf2-bad6dd1f565e-6b2ve7.png\",\n      restaurant: {\n        connect: {\n          id: restaurantId,\n        },\n      },\n      category: {\n        connect: {\n          id: categoryId,\n        },\n      },\n    },\n    {\n      name: \"Suco de Laranja\",\n      price: 12,\n      description: description,\n      discountPercentage: 5,\n      imageUrl:\n        \"https://utfs.io/f/ce2b8e30-b922-4b1e-bdde-656348cd25c3-6b2ve6.png\",\n      restaurant: {\n        connect: {\n          id: restaurantId,\n        },\n      },\n      category: {\n        connect: {\n          id: categoryId,\n        },\n      },\n    },\n    {\n      name: \"Suco de Abacaxi\",\n      price: 12,\n      description: description,\n      discountPercentage: 7,\n      imageUrl:\n        \"https://utfs.io/f/c4202826-7014-4368-8941-fa1af9b9c8b2-6b2ve5.png\",\n      restaurant: {\n        connect: {\n          id: restaurantId,\n        },\n      },\n      category: {\n        connect: {\n          id: categoryId,\n        },\n      },\n    },\n    {\n      name: \"Suco de Melancia\",\n      price: 12,\n      description: description,\n      discountPercentage: 5,\n      imageUrl:\n        \"https://utfs.io/f/a9ba878f-79a8-4c25-883c-5c2e1670b256-6b2ve4.png\",\n      restaurant: {\n        connect: {\n          id: restaurantId,\n        },\n      },\n      category: {\n        connect: {\n          id: categoryId,\n        },\n      },\n    },\n  ];\n\n  for (const product of juiceProducts) {\n    await prismaClient.product.create({\n      data: product,\n    });\n\n    console.log(`Created ${product.name}`);\n  }\n};\n\nconst main = async () => {\n  const desertsCategory = await prismaClient.category.create({\n    data: {\n      name: \"Sobremesas\",\n      imageUrl:\n        \"https://utfs.io/f/0f81c141-4787-4a81-abce-cbd9c6596c7a-xayf5d.png\",\n    },\n  });\n\n  const juicesCategory = await prismaClient.category.create({\n    data: {\n      name: \"Sucos\",\n      imageUrl:\n        \"https://utfs.io/f/9f3013bf-0778-4d80-a330-4da2682deaf9-o41y62.png\",\n    },\n  });\n\n  await createBurguers(desertsCategory.id, juicesCategory.id);\n  await createPizzas(desertsCategory.id, juicesCategory.id);\n  await createJapanese(desertsCategory.id, juicesCategory.id);\n  await createBrazilian(desertsCategory.id, juicesCategory.id);\n};\n\nmain()\n  .then(() => {\n    console.log(\"Seed do banco de dados realizado com sucesso!\");\n  })\n  .catch((error) => {\n    console.error(error);\n    process.exit(1);\n  })\n  .finally(async () => {\n    await prismaClient.$disconnect();\n  });\n"
  },
  {
    "path": "tailwind.config.ts",
    "content": "import type { Config } from \"tailwindcss\"\n\nconst config = {\n  darkMode: [\"class\"],\n  content: [\n    './pages/**/*.{ts,tsx}',\n    './components/**/*.{ts,tsx}',\n    './app/**/*.{ts,tsx}',\n    './src/**/*.{ts,tsx}',\n\t],\n  prefix: \"\",\n  theme: {\n    container: {\n      center: true,\n      padding: \"2rem\",\n      screens: {\n        \"2xl\": \"1400px\",\n      },\n    },\n    extend: {\n      colors: {\n        border: \"hsl(var(--border))\",\n        input: \"hsl(var(--input))\",\n        ring: \"hsl(var(--ring))\",\n        background: \"hsl(var(--background))\",\n        foreground: \"hsl(var(--foreground))\",\n        primary: {\n          DEFAULT: \"hsl(var(--primary))\",\n          foreground: \"hsl(var(--primary-foreground))\",\n        },\n        secondary: {\n          DEFAULT: \"hsl(var(--secondary))\",\n          foreground: \"hsl(var(--secondary-foreground))\",\n        },\n        destructive: {\n          DEFAULT: \"hsl(var(--destructive))\",\n          foreground: \"hsl(var(--destructive-foreground))\",\n        },\n        muted: {\n          DEFAULT: \"hsl(var(--muted))\",\n          foreground: \"hsl(var(--muted-foreground))\",\n        },\n        accent: {\n          DEFAULT: \"hsl(var(--accent))\",\n          foreground: \"hsl(var(--accent-foreground))\",\n        },\n        popover: {\n          DEFAULT: \"hsl(var(--popover))\",\n          foreground: \"hsl(var(--popover-foreground))\",\n        },\n        card: {\n          DEFAULT: \"hsl(var(--card))\",\n          foreground: \"hsl(var(--card-foreground))\",\n        },\n      },\n      borderRadius: {\n        lg: \"var(--radius)\",\n        md: \"calc(var(--radius) - 2px)\",\n        sm: \"calc(var(--radius) - 4px)\",\n      },\n      keyframes: {\n        \"accordion-down\": {\n          from: { height: \"0\" },\n          to: { height: \"var(--radix-accordion-content-height)\" },\n        },\n        \"accordion-up\": {\n          from: { height: \"var(--radix-accordion-content-height)\" },\n          to: { height: \"0\" },\n        },\n      },\n      animation: {\n        \"accordion-down\": \"accordion-down 0.2s ease-out\",\n        \"accordion-up\": \"accordion-up 0.2s ease-out\",\n      },\n    },\n  },\n  plugins: [require(\"tailwindcss-animate\")],\n} satisfies Config\n\nexport default config"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"lib\": [\"dom\", \"dom.iterable\", \"esnext\"],\n    \"allowJs\": true,\n    \"skipLibCheck\": true,\n    \"strict\": true,\n    \"noEmit\": true,\n    \"esModuleInterop\": true,\n    \"module\": \"esnext\",\n    \"moduleResolution\": \"bundler\",\n    \"resolveJsonModule\": true,\n    \"isolatedModules\": true,\n    \"jsx\": \"preserve\",\n    \"incremental\": true,\n    \"plugins\": [\n      {\n        \"name\": \"next\"\n      }\n    ],\n    \"paths\": {\n      \"@/*\": [\"./*\"]\n    }\n  },\n  \"include\": [\n    \"next-env.d.ts\",\n    \"**/*.ts\",\n    \"**/*.tsx\",\n    \".next/types/**/*.ts\",\n    \"next-auth.d.ts\"\n  ],\n  \"exclude\": [\"node_modules\"]\n}\n"
  }
]