-
+
+
-
-
Darurat? Hubungi Kami Sekarang
-
- Jika Anda atau orang lain berada dalam situasi darurat, segera hubungi WhatsApp kami untuk respons cepat 24/7.
-
-
-
-
- Hubungi Darurat
-
+
+
Butuh Bantuan Darurat?
+
Jangan ragu untuk menghubungi kami jika situasi mendesak.
+
+
);
diff --git a/frontend/src/components/gallery4.jsx b/frontend/src/components/gallery4.jsx
new file mode 100644
index 0000000..e39ecc3
--- /dev/null
+++ b/frontend/src/components/gallery4.jsx
@@ -0,0 +1,203 @@
+"use client";;
+import { ArrowLeft, ArrowRight } from "lucide-react";
+import { Link } from "react-router-dom";
+import { useEffect, useState } from "react";
+
+import { Button } from "@/components/ui/button";
+import { Carousel, CarouselContent, CarouselItem } from "@/components/ui/carousel";
+
+const data = [
+ {
+ id: "shadcn-ui",
+ title: "shadcn/ui: Building a Modern Component Library",
+ description:
+ "Explore how shadcn/ui revolutionized React component libraries by providing a unique approach to component distribution and customization, making it easier for developers to build beautiful, accessible applications.",
+ href: "https://ui.shadcn.com",
+ image:
+ "https://images.unsplash.com/photo-1551250928-243dc937c49d?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w2NDI3NzN8MHwxfGFsbHwxMjN8fHx8fHwyfHwxNzIzODA2OTM5fA&ixlib=rb-4.0.3&q=80&w=1080",
+ },
+ {
+ id: "tailwind",
+ title: "Tailwind CSS: The Utility-First Revolution",
+ description:
+ "Discover how Tailwind CSS transformed the way developers style their applications, offering a utility-first approach that speeds up development while maintaining complete design flexibility.",
+ href: "https://tailwindcss.com",
+ image:
+ "https://images.unsplash.com/photo-1551250928-e4a05afaed1e?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w2NDI3NzN8MHwxfGFsbHwxMjR8fHx8fHwyfHwxNzIzODA2OTM5fA&ixlib=rb-4.0.3&q=80&w=1080",
+ },
+ {
+ id: "astro",
+ title: "Astro: The All-in-One Web Framework",
+ description:
+ "Learn how Astro's innovative 'Islands Architecture' and zero-JS-by-default approach is helping developers build faster websites while maintaining rich interactivity where needed.",
+ href: "https://astro.build",
+ image:
+ "https://images.unsplash.com/photo-1536735561749-fc87494598cb?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w2NDI3NzN8MHwxfGFsbHwxNzd8fHx8fHwyfHwxNzIzNjM0NDc0fA&ixlib=rb-4.0.3&q=80&w=1080",
+ },
+ {
+ id: "react",
+ title: "React: Pioneering Component-Based UI",
+ description:
+ "See how React continues to shape modern web development with its component-based architecture, enabling developers to build complex user interfaces with reusable, maintainable code.",
+ href: "https://react.dev",
+ image:
+ "https://images.unsplash.com/photo-1548324215-9133768e4094?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w2NDI3NzN8MHwxfGFsbHwxMzF8fHx8fHwyfHwxNzIzNDM1MzA1fA&ixlib=rb-4.0.3&q=80&w=1080",
+ },
+ {
+ id: "nextjs",
+ title: "Next.js: The React Framework for Production",
+ description:
+ "Explore how Next.js has become the go-to framework for building full-stack React applications, offering features like server components, file-based routing, and automatic optimization.",
+ href: "https://nextjs.org",
+ image:
+ "https://images.unsplash.com/photo-1550070881-a5d71eda5800?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w2NDI3NzN8MHwxfGFsbHwxMjV8fHx8fHwyfHwxNzIzNDM1Mjk4fA&ixlib=rb-4.0.3&q=80&w=1080",
+ },
+];
+
+const Gallery4 = ({
+ title = "Case Studies",
+ description = "Discover how leading companies and developers are leveraging modern web technologies to build exceptional digital experiences. These case studies showcase real-world applications and success stories.",
+ items = data
+}) => {
+ const [carouselApi, setCarouselApi] = useState();
+ const [canScrollPrev, setCanScrollPrev] = useState(false);
+ const [canScrollNext, setCanScrollNext] = useState(false);
+ const [currentSlide, setCurrentSlide] = useState(0);
+
+ useEffect(() => {
+ if (!carouselApi) {
+ return;
+ }
+ const updateSelection = () => {
+ setCanScrollPrev(carouselApi.canScrollPrev());
+ setCanScrollNext(carouselApi.canScrollNext());
+ setCurrentSlide(carouselApi.selectedScrollSnap());
+ };
+ updateSelection();
+ carouselApi.on("select", updateSelection);
+ return () => {
+ carouselApi.off("select", updateSelection);
+ };
+ }, [carouselApi]);
+
+ return (
+
+
+
+
+
+ {title}
+
+
{description}
+
+
+
{
+ carouselApi?.scrollPrev();
+ }}
+ disabled={!canScrollPrev}
+ className="disabled:pointer-events-auto">
+
+
+
{
+ carouselApi?.scrollNext();
+ }}
+ disabled={!canScrollNext}
+ className="disabled:pointer-events-auto">
+
+
+
+
+
+
+
+
+ {items.map((item) => (
+
+ {item.href.startsWith('/') ? (
+
+
+
+
+
+
+ {item.title}
+
+
+ {item.description}
+
+
+
+
+
+ ) : (
+
+
+
+
+
+
+ {item.title}
+
+
+ {item.description}
+
+
+
+
+
+ )}
+
+ ))}
+
+
+
+ {items.map((_, index) => (
+ carouselApi?.scrollTo(index)}
+ aria-label={`Go to slide ${index + 1}`} />
+ ))}
+
+
+
+ );
+};
+
+export { Gallery4 };
diff --git a/frontend/src/components/ui/button.jsx b/frontend/src/components/ui/button.jsx
new file mode 100644
index 0000000..294af54
--- /dev/null
+++ b/frontend/src/components/ui/button.jsx
@@ -0,0 +1,47 @@
+import * as React from "react"
+import { Slot } from "@radix-ui/react-slot"
+import { cva } from "class-variance-authority";
+
+import { cn } from "@/lib/utils"
+
+const buttonVariants = cva(
+ "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium 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",
+ {
+ variants: {
+ variant: {
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
+ destructive:
+ "bg-destructive text-destructive-foreground hover:bg-destructive/90",
+ outline:
+ "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
+ secondary:
+ "bg-secondary text-secondary-foreground hover:bg-secondary/80",
+ ghost: "hover:bg-accent hover:text-accent-foreground",
+ link: "text-primary underline-offset-4 hover:underline",
+ },
+ size: {
+ default: "h-10 px-4 py-2",
+ sm: "h-9 rounded-md px-3",
+ lg: "h-11 rounded-md px-8",
+ icon: "h-10 w-10",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ size: "default",
+ },
+ }
+)
+
+const Button = React.forwardRef(({ className, variant, size, asChild = false, ...props }, ref) => {
+ const Comp = asChild ? Slot : "button"
+ return (
+
+ );
+})
+Button.displayName = "Button"
+
+export { Button, buttonVariants }
diff --git a/frontend/src/components/ui/card.jsx b/frontend/src/components/ui/card.jsx
new file mode 100644
index 0000000..dd79b51
--- /dev/null
+++ b/frontend/src/components/ui/card.jsx
@@ -0,0 +1,50 @@
+import * as React from "react"
+
+import { cn } from "@/lib/utils"
+
+const Card = React.forwardRef(({ className, ...props }, ref) => (
+
+))
+Card.displayName = "Card"
+
+const CardHeader = React.forwardRef(({ className, ...props }, ref) => (
+
+))
+CardHeader.displayName = "CardHeader"
+
+const CardTitle = React.forwardRef(({ className, ...props }, ref) => (
+
+))
+CardTitle.displayName = "CardTitle"
+
+const CardDescription = React.forwardRef(({ className, ...props }, ref) => (
+
+))
+CardDescription.displayName = "CardDescription"
+
+const CardContent = React.forwardRef(({ className, ...props }, ref) => (
+
+))
+CardContent.displayName = "CardContent"
+
+const CardFooter = React.forwardRef(({ className, ...props }, ref) => (
+
+))
+CardFooter.displayName = "CardFooter"
+
+export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
diff --git a/frontend/src/components/ui/carousel.jsx b/frontend/src/components/ui/carousel.jsx
new file mode 100644
index 0000000..55eae80
--- /dev/null
+++ b/frontend/src/components/ui/carousel.jsx
@@ -0,0 +1,193 @@
+import * as React from "react"
+import useEmblaCarousel from "embla-carousel-react";
+import { ArrowLeft, ArrowRight } from "lucide-react"
+
+import { cn } from "@/lib/utils"
+import { Button } from "@/components/ui/button"
+
+const CarouselContext = React.createContext(null)
+
+function useCarousel() {
+ const context = React.useContext(CarouselContext)
+
+ if (!context) {
+ throw new Error("useCarousel must be used within a
")
+ }
+
+ return context
+}
+
+const Carousel = React.forwardRef((
+ {
+ orientation = "horizontal",
+ opts,
+ setApi,
+ plugins,
+ className,
+ children,
+ ...props
+ },
+ ref,
+) => {
+ const [carouselRef, api] = useEmblaCarousel({
+ ...opts,
+ axis: orientation === "horizontal" ? "x" : "y",
+ }, plugins)
+ const [canScrollPrev, setCanScrollPrev] = React.useState(false)
+ const [canScrollNext, setCanScrollNext] = React.useState(false)
+
+ const onSelect = React.useCallback((api) => {
+ if (!api) {
+ return
+ }
+
+ setCanScrollPrev(api.canScrollPrev())
+ setCanScrollNext(api.canScrollNext())
+ }, [])
+
+ const scrollPrev = React.useCallback(() => {
+ api?.scrollPrev()
+ }, [api])
+
+ const scrollNext = React.useCallback(() => {
+ api?.scrollNext()
+ }, [api])
+
+ const handleKeyDown = React.useCallback((event) => {
+ if (event.key === "ArrowLeft") {
+ event.preventDefault()
+ scrollPrev()
+ } else if (event.key === "ArrowRight") {
+ event.preventDefault()
+ scrollNext()
+ }
+ }, [scrollPrev, scrollNext])
+
+ React.useEffect(() => {
+ if (!api || !setApi) {
+ return
+ }
+
+ setApi(api)
+ }, [api, setApi])
+
+ React.useEffect(() => {
+ if (!api) {
+ return
+ }
+
+ onSelect(api)
+ api.on("reInit", onSelect)
+ api.on("select", onSelect)
+
+ return () => {
+ api?.off("select", onSelect)
+ };
+ }, [api, onSelect])
+
+ return (
+
+
+ {children}
+
+
+ );
+})
+Carousel.displayName = "Carousel"
+
+const CarouselContent = React.forwardRef(({ className, ...props }, ref) => {
+ const { carouselRef, orientation } = useCarousel()
+
+ return (
+
+ );
+})
+CarouselContent.displayName = "CarouselContent"
+
+const CarouselItem = React.forwardRef(({ className, ...props }, ref) => {
+ const { orientation } = useCarousel()
+
+ return (
+
+ );
+})
+CarouselItem.displayName = "CarouselItem"
+
+const CarouselPrevious = React.forwardRef(({ className, variant = "outline", size = "icon", ...props }, ref) => {
+ const { orientation, scrollPrev, canScrollPrev } = useCarousel()
+
+ return (
+
+
+ Previous slide
+
+ );
+})
+CarouselPrevious.displayName = "CarouselPrevious"
+
+const CarouselNext = React.forwardRef(({ className, variant = "outline", size = "icon", ...props }, ref) => {
+ const { orientation, scrollNext, canScrollNext } = useCarousel()
+
+ return (
+
+
+ Next slide
+
+ );
+})
+CarouselNext.displayName = "CarouselNext"
+
+export { Carousel, CarouselContent, CarouselItem, CarouselPrevious, CarouselNext };
diff --git a/frontend/src/components/ui/checkbox.jsx b/frontend/src/components/ui/checkbox.jsx
new file mode 100644
index 0000000..dc639bc
--- /dev/null
+++ b/frontend/src/components/ui/checkbox.jsx
@@ -0,0 +1,24 @@
+"use client"
+
+import * as React from "react"
+import * as CheckboxPrimitive from "@radix-ui/react-checkbox"
+import { Check } from "lucide-react"
+
+import { cn } from "@/lib/utils"
+
+const Checkbox = React.forwardRef(({ className, ...props }, ref) => (
+
+
+
+
+
+))
+Checkbox.displayName = CheckboxPrimitive.Root.displayName
+
+export { Checkbox }
diff --git a/frontend/src/components/ui/flow-button.jsx b/frontend/src/components/ui/flow-button.jsx
new file mode 100644
index 0000000..cbd5540
--- /dev/null
+++ b/frontend/src/components/ui/flow-button.jsx
@@ -0,0 +1,53 @@
+// This is file of your component
+
+// You can use any dependencies from npm; we import them automatically in package.json
+'use client';
+import { ArrowRight } from 'lucide-react';
+
+export function FlowButton({
+ text = "Button",
+ href,
+ target,
+ rel,
+ className = "",
+ colorStr = "#111111", // Default text/border color
+ hoverColorStr = "#111111", // Circle bg color on hover
+}) {
+ const Component = href ? 'a' : 'button';
+
+ return (
+
+ {/* Left arrow */}
+
+
+ {/* Text */}
+
+ {text}
+
+
+ {/* Circle Hover Effect */}
+
+
+ {/* Right arrow */}
+
+
+ );
+}
diff --git a/frontend/src/components/ui/input.jsx b/frontend/src/components/ui/input.jsx
new file mode 100644
index 0000000..e69f1c7
--- /dev/null
+++ b/frontend/src/components/ui/input.jsx
@@ -0,0 +1,19 @@
+import * as React from "react"
+
+import { cn } from "@/lib/utils"
+
+const Input = React.forwardRef(({ className, type, ...props }, ref) => {
+ return (
+
+ );
+})
+Input.displayName = "Input"
+
+export { Input }
diff --git a/frontend/src/components/ui/label.jsx b/frontend/src/components/ui/label.jsx
new file mode 100644
index 0000000..a1f4099
--- /dev/null
+++ b/frontend/src/components/ui/label.jsx
@@ -0,0 +1,16 @@
+import * as React from "react"
+import * as LabelPrimitive from "@radix-ui/react-label"
+import { cva } from "class-variance-authority";
+
+import { cn } from "@/lib/utils"
+
+const labelVariants = cva(
+ "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
+)
+
+const Label = React.forwardRef(({ className, ...props }, ref) => (
+
+))
+Label.displayName = LabelPrimitive.Root.displayName
+
+export { Label }
diff --git a/frontend/src/components/ui/select.jsx b/frontend/src/components/ui/select.jsx
new file mode 100644
index 0000000..4a1665c
--- /dev/null
+++ b/frontend/src/components/ui/select.jsx
@@ -0,0 +1,120 @@
+import * as React from "react"
+import * as SelectPrimitive from "@radix-ui/react-select"
+import { Check, ChevronDown, ChevronUp } from "lucide-react"
+
+import { cn } from "@/lib/utils"
+
+const Select = SelectPrimitive.Root
+
+const SelectGroup = SelectPrimitive.Group
+
+const SelectValue = SelectPrimitive.Value
+
+const SelectTrigger = React.forwardRef(({ className, children, ...props }, ref) => (
+
span]:line-clamp-1",
+ className
+ )}
+ {...props}>
+ {children}
+
+
+
+
+))
+SelectTrigger.displayName = SelectPrimitive.Trigger.displayName
+
+const SelectScrollUpButton = React.forwardRef(({ className, ...props }, ref) => (
+
+
+
+))
+SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName
+
+const SelectScrollDownButton = React.forwardRef(({ className, ...props }, ref) => (
+
+
+
+))
+SelectScrollDownButton.displayName =
+ SelectPrimitive.ScrollDownButton.displayName
+
+const SelectContent = React.forwardRef(({ className, children, position = "popper", ...props }, ref) => (
+
+
+
+
+ {children}
+
+
+
+
+))
+SelectContent.displayName = SelectPrimitive.Content.displayName
+
+const SelectLabel = React.forwardRef(({ className, ...props }, ref) => (
+
+))
+SelectLabel.displayName = SelectPrimitive.Label.displayName
+
+const SelectItem = React.forwardRef(({ className, children, ...props }, ref) => (
+
+
+
+
+
+
+
+ {children}
+
+))
+SelectItem.displayName = SelectPrimitive.Item.displayName
+
+const SelectSeparator = React.forwardRef(({ className, ...props }, ref) => (
+
+))
+SelectSeparator.displayName = SelectPrimitive.Separator.displayName
+
+export {
+ Select,
+ SelectGroup,
+ SelectValue,
+ SelectTrigger,
+ SelectContent,
+ SelectLabel,
+ SelectItem,
+ SelectSeparator,
+ SelectScrollUpButton,
+ SelectScrollDownButton,
+}
diff --git a/frontend/src/components/ui/spotlight-card.jsx b/frontend/src/components/ui/spotlight-card.jsx
new file mode 100644
index 0000000..2333b7f
--- /dev/null
+++ b/frontend/src/components/ui/spotlight-card.jsx
@@ -0,0 +1,43 @@
+import React, { useRef, useState } from "react";
+
+export const SpotlightCard = ({ children, className = "", spotlightColor = "rgba(255, 255, 255, 0.25)" }) => {
+ const divRef = useRef(null);
+ const [position, setPosition] = useState({ x: 0, y: 0 });
+ const [opacity, setOpacity] = useState(0);
+
+ const handleMouseMove = (e) => {
+ if (!divRef.current) return;
+
+ const rect = divRef.current.getBoundingClientRect();
+ setPosition({ x: e.clientX - rect.left, y: e.clientY - rect.top });
+ };
+
+ const handleMouseEnter = () => {
+ setOpacity(1);
+ };
+
+ const handleMouseLeave = () => {
+ setOpacity(0);
+ };
+
+ return (
+
+ );
+};
diff --git a/frontend/src/components/ui/switch.jsx b/frontend/src/components/ui/switch.jsx
new file mode 100644
index 0000000..e0b4e8e
--- /dev/null
+++ b/frontend/src/components/ui/switch.jsx
@@ -0,0 +1,24 @@
+"use client"
+
+import * as React from "react"
+import * as SwitchPrimitives from "@radix-ui/react-switch"
+
+import { cn } from "@/lib/utils"
+
+const Switch = React.forwardRef(({ className, ...props }, ref) => (
+
+
+
+))
+Switch.displayName = SwitchPrimitives.Root.displayName
+
+export { Switch }