-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2d42f39
commit 134931a
Showing
28 changed files
with
453 additions
and
139 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
"use client"; | ||
import { motion } from "framer-motion"; | ||
import React from "react"; | ||
import { ImagesSlider } from "./ui/images-slider"; | ||
|
||
export function EnterpriseSlides() { | ||
const images = [ | ||
"/dashboard/Horizon-Dashboard3.png", | ||
"/dashboard/Horizon-Dashboard.png", | ||
"/dashboard/Horizon-Dashboard4.png", | ||
"/dashboard/Horizon-Dashboard5.png", | ||
"/dashboard/Horizon-Dashboard6.png", | ||
"/dashboard/Horizon-Dashboard7.png", | ||
"/dashboard/Horizon-Dashboard8.png", | ||
"/dashboard/Horizon-Dashboard9.png", | ||
"/dashboard/Horizon-Dashboard10.png", | ||
"/dashboard/Horizon-Dashboard11.png", | ||
"/dashboard/Horizon-Dashboard12.png", | ||
"/dashboard/Horizon-Dashboard13.png", | ||
"/dashboard/Horizon-Dashboard14.png", | ||
"/dashboard/Horizon-Dashboard15.png", | ||
"/dashboard/Horizon-Dashboard16.png" | ||
]; | ||
return ( | ||
<ImagesSlider className="h-[27rem]" images={images}> | ||
<motion.div | ||
initial={{ | ||
opacity: 0, | ||
y: -80, | ||
}} | ||
animate={{ | ||
opacity: 1, | ||
y: 0, | ||
}} | ||
transition={{ | ||
duration: 0.6, | ||
}} | ||
className="z-50 flex flex-col justify-center items-center" | ||
> | ||
{/* <motion.p className="font-bold text-xl md:text-6xl text-center bg-clip-text text-transparent bg-gradient-to-b from-neutral-50 to-neutral-400 py-4"> | ||
The hero section slideshow <br /> nobody asked for | ||
</motion.p> | ||
<button className="px-4 py-2 backdrop-blur-sm border bg-emerald-300/10 border-emerald-500/20 text-white mx-auto text-center rounded-full relative mt-4"> | ||
<span>Join now →</span> | ||
<div className="absolute inset-x-0 h-px -bottom-px bg-gradient-to-r w-3/4 mx-auto from-transparent via-emerald-500 to-transparent" /> | ||
</button> */} | ||
</motion.div> | ||
</ImagesSlider> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
"use client"; | ||
import { cn } from "../lib/utils"; | ||
import { motion, AnimatePresence } from "framer-motion"; | ||
import React, { useEffect, useState } from "react"; | ||
|
||
export const ImagesSlider = ({ | ||
images, | ||
children, | ||
overlay = true, | ||
overlayClassName, | ||
className, | ||
autoplay = true, | ||
direction = "up", | ||
}: { | ||
images: string[]; | ||
children: React.ReactNode; | ||
overlay?: React.ReactNode; | ||
overlayClassName?: string; | ||
className?: string; | ||
autoplay?: boolean; | ||
direction?: "up" | "down"; | ||
}) => { | ||
const [currentIndex, setCurrentIndex] = useState(0); | ||
const [loading, setLoading] = useState(false); | ||
const [loadedImages, setLoadedImages] = useState<string[]>([]); | ||
|
||
const handleNext = () => { | ||
setCurrentIndex((prevIndex) => | ||
prevIndex + 1 === images.length ? 0 : prevIndex + 1 | ||
); | ||
}; | ||
|
||
const handlePrevious = () => { | ||
setCurrentIndex((prevIndex) => | ||
prevIndex - 1 < 0 ? images.length - 1 : prevIndex - 1 | ||
); | ||
}; | ||
|
||
useEffect(() => { | ||
loadImages(); | ||
}, []); | ||
|
||
const loadImages = () => { | ||
setLoading(true); | ||
const loadPromises = images.map((image) => { | ||
return new Promise((resolve, reject) => { | ||
const img = new Image(); | ||
img.src = image; | ||
img.onload = () => resolve(image); | ||
img.onerror = reject; | ||
}); | ||
}); | ||
|
||
Promise.all(loadPromises) | ||
.then((loadedImages) => { | ||
setLoadedImages(loadedImages as string[]); | ||
setLoading(false); | ||
}) | ||
.catch((error) => console.error("Failed to load images", error)); | ||
}; | ||
useEffect(() => { | ||
const handleKeyDown = (event: KeyboardEvent) => { | ||
if (event.key === "ArrowRight") { | ||
handleNext(); | ||
} else if (event.key === "ArrowLeft") { | ||
handlePrevious(); | ||
} | ||
}; | ||
|
||
window.addEventListener("keydown", handleKeyDown); | ||
|
||
// autoplay | ||
let interval: any; | ||
if (autoplay) { | ||
interval = setInterval(() => { | ||
handleNext(); | ||
}, 5000); | ||
} | ||
|
||
return () => { | ||
window.removeEventListener("keydown", handleKeyDown); | ||
clearInterval(interval); | ||
}; | ||
}, []); | ||
|
||
const slideVariants = { | ||
initial: { | ||
scale: 0, | ||
opacity: 0, | ||
rotateX: 45, | ||
}, | ||
visible: { | ||
scale: 1, | ||
rotateX: 0, | ||
opacity: 1, | ||
transition: { | ||
duration: 0.5, | ||
ease: [0.645, 0.045, 0.355, 1.0], | ||
}, | ||
}, | ||
upExit: { | ||
opacity: 1, | ||
y: "-150%", | ||
transition: { | ||
duration: 1, | ||
}, | ||
}, | ||
downExit: { | ||
opacity: 1, | ||
y: "150%", | ||
transition: { | ||
duration: 1, | ||
}, | ||
}, | ||
}; | ||
|
||
const areImagesLoaded = loadedImages.length > 0; | ||
|
||
return ( | ||
<div | ||
className={cn( | ||
"overflow-hidden h-full w-full relative flex items-center justify-center", | ||
className | ||
)} | ||
style={{ | ||
perspective: "1000px", | ||
}} | ||
> | ||
{areImagesLoaded && children} | ||
{areImagesLoaded && overlay && ( | ||
<div | ||
className={cn("absolute inset-0 bg-black/0 z-40", overlayClassName)} | ||
/> | ||
)} | ||
|
||
{areImagesLoaded && ( | ||
<AnimatePresence> | ||
<motion.img | ||
key={currentIndex} | ||
src={loadedImages[currentIndex]} | ||
initial="initial" | ||
animate="visible" | ||
exit={direction === "up" ? "upExit" : "downExit"} | ||
variants={slideVariants} | ||
className="image h-full w-full absolute inset-0 object-cover object-center rounded-xl" | ||
/> | ||
</AnimatePresence> | ||
)} | ||
</div> | ||
); | ||
}; |
Oops, something went wrong.