{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "testimonal-01",
  "description": "A testimonial slider.",
  "dependencies": [
    "react-icons/md"
  ],
  "files": [
    {
      "path": "registry/blocks/testimonal-01/page.tsx",
      "content": "import Image from \"next/image\"\nimport { MdOutlineFormatQuote } from \"react-icons/md\"\n\nimport {\n  Carousel,\n  CarouselContent,\n  CarouselItem,\n  CarouselNext,\n  CarouselPrevious,\n} from \"@/registry/blocks/testimonal-01/components/carousel\"\nimport Section from \"@/registry/blocks/testimonal-01/components/section\"\n\nconst companies = [\n  {\n    name: \"Google\",\n    url: \"https://pub-b3533f2e1c954842824758490b95c9d5.r2.dev/Google.svg\",\n  },\n  {\n    name: \"GitHub\",\n    url: \"https://pub-b3533f2e1c954842824758490b95c9d5.r2.dev/GitHub.svg\",\n  },\n  {\n    name: \"Amazon\",\n    url: \"https://pub-b3533f2e1c954842824758490b95c9d5.r2.dev/Amazon.svg\",\n  },\n  {\n    name: \"Netflix\",\n    url: \"https://pub-b3533f2e1c954842824758490b95c9d5.r2.dev/Netflix.svg\",\n  },\n  {\n    name: \"YouTube\",\n    url: \"https://pub-b3533f2e1c954842824758490b95c9d5.r2.dev/YouTube.svg\",\n  },\n  {\n    name: \"Instagram\",\n    url: \"https://pub-b3533f2e1c954842824758490b95c9d5.r2.dev/Instagram.svg\",\n  },\n  {\n    name: \"Spotify\",\n    url: \"https://pub-b3533f2e1c954842824758490b95c9d5.r2.dev/Spotify.svg\",\n  },\n]\n\nexport default function Testimonal01Page() {\n  return (\n    <div className=\"flex min-h-svh w-full items-center justify-center p-6 md:p-10\">\n      <div className=\"w-full max-w-sm md:max-w-3xl\">\n        <Section\n          title=\"Testimonial Highlight\"\n          subtitle=\"What our customers are saying\"\n        >\n          <Carousel>\n            <div className=\"relative mx-auto max-w-2xl\">\n              <CarouselContent>\n                {Array.from({ length: 7 }).map((_, index) => (\n                  <CarouselItem key={index}>\n                    <div className=\"p-2 pb-5\">\n                      <div className=\"text-center\">\n                        <MdOutlineFormatQuote className=\"text-themeDarkGray mx-auto my-4 text-4xl\" />\n                        <h4 className=\"text-1xl mx-auto max-w-lg px-10 font-semibold\">\n                          {getTestimonialQuote(index)}\n                        </h4>\n                        <div className=\"mt-8\">\n                          <Image\n                            width={0}\n                            height={40}\n                            src={companies[index % companies.length].url}\n                            alt={`${companies[index % companies.length].name} Logo`}\n                            className=\"mx-auto h-[40px] w-auto\"\n                          />\n                        </div>\n                        <div>\n                          <h4 className=\"text-1xl my-2 font-semibold\">\n                            {getTestimonialName(index)}\n                          </h4>\n                        </div>\n                        <div className=\"mb-3\">\n                          <span className=\"text-themeDarkGray text-sm\">\n                            {getTestimonialRole(index)}\n                          </span>\n                        </div>\n                      </div>\n                    </div>\n                  </CarouselItem>\n                ))}\n              </CarouselContent>\n              <div className=\"from-background pointer-events-none absolute inset-y-0 left-0 h-full w-2/12 bg-gradient-to-r\"></div>\n              <div className=\"from-background pointer-events-none absolute inset-y-0 right-0 h-full w-2/12 bg-gradient-to-l\"></div>\n            </div>\n            <div className=\"hidden md:block\">\n              <CarouselPrevious />\n              <CarouselNext />\n            </div>\n          </Carousel>\n        </Section>\n      </div>\n    </div>\n  )\n}\n\nfunction getTestimonialQuote(index: number): string {\n  const quotes = [\n    \"eldora ui has revolutionized our security testing process. We're now able to identify and address vulnerabilities faster than ever before.\",\n    \"With eldora ui, we've significantly improved our security posture. It's like having an AI-powered ethical hacker working around the clock.\",\n    \"The AI-driven insights from eldora ui have transformed how we approach cybersecurity. It's a game-changer for our platform's security.\",\n    \"eldora ui's automated penetration testing has saved us countless hours and dramatically enhanced our security measures.\",\n    \"Implementing eldora ui was seamless, and the results were immediate. We're now proactively addressing potential security issues before they become threats.\",\n    \"The continuous monitoring capabilities of eldora ui give us peace of mind. We're always one step ahead in protecting our users' data.\",\n    \"eldora ui's compliance mapping feature has streamlined our security audit processes. It's an essential tool for maintaining trust with our users.\",\n  ]\n  return quotes[index % quotes.length]\n}\n\nfunction getTestimonialName(index: number): string {\n  const names = [\n    \"Alex Rivera\",\n    \"Samantha Lee\",\n    \"Raj Patel\",\n    \"Emily Chen\",\n    \"Michael Brown\",\n    \"Linda Wu\",\n    \"Carlos Gomez\",\n  ]\n  return names[index % names.length]\n}\n\nfunction getTestimonialRole(index: number): string {\n  const roles = [\n    \"Head of Cybersecurity\",\n    \"Chief Information Security Officer\",\n    \"VP of Engineering\",\n    \"Security Operations Manager\",\n    \"Director of IT Security\",\n    \"Lead Security Architect\",\n    \"Chief Technology Officer\",\n  ]\n  return roles[index % roles.length]\n}\n",
      "type": "registry:page",
      "target": "app/testimonial/page.tsx"
    },
    {
      "path": "registry/blocks/testimonal-01/components/carousel.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport useEmblaCarousel, {\n  type UseEmblaCarouselType,\n} from \"embla-carousel-react\"\nimport { ArrowLeft, ArrowRight } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/components/ui/button\"\n\ntype CarouselApi = UseEmblaCarouselType[1]\ntype UseCarouselParameters = Parameters<typeof useEmblaCarousel>\ntype CarouselOptions = UseCarouselParameters[0]\ntype CarouselPlugin = UseCarouselParameters[1]\n\ninterface CarouselProps {\n  opts?: CarouselOptions\n  plugins?: CarouselPlugin\n  orientation?: \"horizontal\" | \"vertical\"\n  setApi?: (api: CarouselApi) => void\n}\n\ntype CarouselContextProps = {\n  carouselRef: ReturnType<typeof useEmblaCarousel>[0]\n  api: ReturnType<typeof useEmblaCarousel>[1]\n  scrollPrev: () => void\n  scrollNext: () => void\n  canScrollPrev: boolean\n  canScrollNext: boolean\n} & CarouselProps\n\nconst CarouselContext = React.createContext<CarouselContextProps | null>(null)\n\nfunction useCarousel() {\n  const context = React.useContext(CarouselContext)\n\n  if (!context) {\n    throw new Error(\"useCarousel must be used within a <Carousel />\")\n  }\n\n  return context\n}\n\nconst Carousel = React.forwardRef<\n  HTMLDivElement,\n  React.HTMLAttributes<HTMLDivElement> & CarouselProps\n>(\n  (\n    {\n      orientation = \"horizontal\",\n      opts,\n      setApi,\n      plugins,\n      className,\n      children,\n      ...props\n    },\n    ref\n  ) => {\n    const [carouselRef, api] = useEmblaCarousel(\n      {\n        ...opts,\n        axis: orientation === \"horizontal\" ? \"x\" : \"y\",\n      },\n      plugins\n    )\n    const [canScrollPrev, setCanScrollPrev] = React.useState(false)\n    const [canScrollNext, setCanScrollNext] = React.useState(false)\n\n    const onSelect = React.useCallback((api: CarouselApi) => {\n      if (!api) {\n        return\n      }\n\n      setCanScrollPrev(api.canScrollPrev())\n      setCanScrollNext(api.canScrollNext())\n    }, [])\n\n    const scrollPrev = React.useCallback(() => {\n      api?.scrollPrev()\n    }, [api])\n\n    const scrollNext = React.useCallback(() => {\n      api?.scrollNext()\n    }, [api])\n\n    const handleKeyDown = React.useCallback(\n      (event: React.KeyboardEvent<HTMLDivElement>) => {\n        if (event.key === \"ArrowLeft\") {\n          event.preventDefault()\n          scrollPrev()\n        } else if (event.key === \"ArrowRight\") {\n          event.preventDefault()\n          scrollNext()\n        }\n      },\n      [scrollPrev, scrollNext]\n    )\n\n    React.useEffect(() => {\n      if (!api || !setApi) {\n        return\n      }\n\n      setApi(api)\n    }, [api, setApi])\n\n    React.useEffect(() => {\n      if (!api) {\n        return\n      }\n\n      onSelect(api)\n      api.on(\"reInit\", onSelect)\n      api.on(\"select\", onSelect)\n\n      return () => {\n        api?.off(\"select\", onSelect)\n      }\n    }, [api, onSelect])\n\n    return (\n      <CarouselContext.Provider\n        value={{\n          carouselRef,\n          api,\n          opts,\n          orientation:\n            orientation || (opts?.axis === \"y\" ? \"vertical\" : \"horizontal\"),\n          scrollPrev,\n          scrollNext,\n          canScrollPrev,\n          canScrollNext,\n        }}\n      >\n        <div\n          ref={ref}\n          onKeyDownCapture={handleKeyDown}\n          className={cn(\"relative\", className)}\n          role=\"region\"\n          aria-roledescription=\"carousel\"\n          {...props}\n        >\n          {children}\n        </div>\n      </CarouselContext.Provider>\n    )\n  }\n)\nCarousel.displayName = \"Carousel\"\n\nconst CarouselContent = React.forwardRef<\n  HTMLDivElement,\n  React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => {\n  const { carouselRef, orientation } = useCarousel()\n\n  return (\n    <div ref={carouselRef} className=\"overflow-hidden\">\n      <div\n        ref={ref}\n        className={cn(\n          \"flex\",\n          orientation === \"horizontal\" ? \"-ml-4\" : \"-mt-4 flex-col\",\n          className\n        )}\n        {...props}\n      />\n    </div>\n  )\n})\nCarouselContent.displayName = \"CarouselContent\"\n\nconst CarouselItem = React.forwardRef<\n  HTMLDivElement,\n  React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => {\n  const { orientation } = useCarousel()\n\n  return (\n    <div\n      ref={ref}\n      role=\"group\"\n      aria-roledescription=\"slide\"\n      className={cn(\n        \"min-w-0 shrink-0 grow-0 basis-full\",\n        orientation === \"horizontal\" ? \"pl-4\" : \"pt-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n})\nCarouselItem.displayName = \"CarouselItem\"\n\nconst CarouselPrevious = React.forwardRef<\n  HTMLButtonElement,\n  React.ComponentProps<typeof Button>\n>(({ className, variant = \"outline\", size = \"icon\", ...props }, ref) => {\n  const { orientation, scrollPrev, canScrollPrev } = useCarousel()\n\n  return (\n    <Button\n      ref={ref}\n      variant={variant}\n      size={size}\n      className={cn(\n        \"absolute size-8 rounded-full\",\n        orientation === \"horizontal\"\n          ? \"bottom-0 left-1/2 -translate-x-16 translate-y-4\"\n          : \"-top-12 right-1/2 -translate-x-1/2 rotate-90\",\n        className\n      )}\n      disabled={!canScrollPrev}\n      onClick={scrollPrev}\n      {...props}\n    >\n      <ArrowLeft className=\"size-4\" />\n      <span className=\"sr-only\">Previous slide</span>\n    </Button>\n  )\n})\nCarouselPrevious.displayName = \"CarouselPrevious\"\n\nconst CarouselNext = React.forwardRef<\n  HTMLButtonElement,\n  React.ComponentProps<typeof Button>\n>(({ className, variant = \"outline\", size = \"icon\", ...props }, ref) => {\n  const { orientation, scrollNext, canScrollNext } = useCarousel()\n\n  return (\n    <Button\n      ref={ref}\n      variant={variant}\n      size={size}\n      className={cn(\n        \"absolute size-8 rounded-full\",\n        orientation === \"horizontal\"\n          ? \"right-1/2 bottom-0 translate-x-16 translate-y-4\"\n          : \"-bottom-12 left-1/2 -translate-x-1/2 rotate-90\",\n        className\n      )}\n      disabled={!canScrollNext}\n      onClick={scrollNext}\n      {...props}\n    >\n      <ArrowRight className=\"size-4\" />\n      <span className=\"sr-only\">Next slide</span>\n    </Button>\n  )\n})\nCarouselNext.displayName = \"CarouselNext\"\n\nexport {\n  Carousel,\n  CarouselContent,\n  CarouselItem,\n  CarouselNext,\n  CarouselPrevious,\n  type CarouselApi,\n}\n",
      "type": "registry:component"
    },
    {
      "path": "registry/blocks/testimonal-01/components/section.tsx",
      "content": "interface SectionProps {\n  id?: string\n  title?: string\n  subtitle?: string\n  description?: string\n  children?: React.ReactNode\n  className?: string\n}\n\nexport default function Section({\n  id,\n  title,\n  subtitle,\n  description,\n  children,\n  className,\n}: SectionProps) {\n  const sectionId = title ? title.toLowerCase().replace(/\\s+/g, \"-\") : id\n  return (\n    <section id={id || sectionId}>\n      <div className={className}>\n        <div className=\"relative container mx-auto max-w-7xl px-4 py-16\">\n          <div className=\"mx-auto space-y-4 pb-6 text-center\">\n            {title && (\n              <h2 className=\"text-primary font-mono text-sm font-medium tracking-wider uppercase\">\n                {title}\n              </h2>\n            )}\n            {subtitle && (\n              <h3 className=\"mx-auto mt-4 max-w-xs text-3xl font-semibold sm:max-w-none sm:text-4xl md:text-5xl\">\n                {subtitle}\n              </h3>\n            )}\n            {description && (\n              <p className=\"mx-auto mt-6 max-w-2xl text-lg leading-8 text-slate-600\">\n                {description}\n              </p>\n            )}\n          </div>\n          {children}\n        </div>\n      </div>\n    </section>\n  )\n}\n",
      "type": "registry:component"
    }
  ],
  "categories": [
    "testimonials"
  ],
  "type": "registry:block"
}