Skip to content

Commit

Permalink
feat: add carousal for grants
Browse files Browse the repository at this point in the history
  • Loading branch information
swarna1101 committed Oct 31, 2024
1 parent 0523cca commit 495bd0e
Show file tree
Hide file tree
Showing 13 changed files with 428 additions and 35 deletions.
Binary file added public/img/grants-banner/grants-lg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/img/grants-banner/grants-md.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/img/grants-banner/grants-sm.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/img/grants-banner/grants-xl.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions public/img/grants-banner/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions public/locales/en/home.json
Original file line number Diff line number Diff line change
Expand Up @@ -118,5 +118,9 @@
"trailblazerBanner": {
"button": "Start your journey",
"text": "Embark on the Trailblazers Journey: Unleash your potential in the Taiko universe!"
},
"grantFactoryBanner": {
"button": "Join now",
"text": "Total Prize Pool"
}
}
168 changes: 168 additions & 0 deletions src/shared/components/grants/grants.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
.wrapper {
padding: 33px 10px;
border-radius: 32px;
border-width: 3px;
display: flex;
align-items: center;
justify-content: center;
gap: 35px;
background-size: cover;
background-position: center;
width: 100%;
height: 650px;
position: relative;
background-color: #1f1d2f;

.cover {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
border-radius: 32px;

.content {
width: 90%;
height: fit-content;
display: flex;
justify-content: space-between;

.leftgroup {
p {
color: white;
font-size: 75px;
font-weight: 500;
line-height: 58px;
font-family: $kFontClashGrotesk;
}
}

.rightgroup {
display: flex;
flex-direction: column;
gap: 15px;
align-items: flex-start;

.rightSubgroup {
display: flex;
align-items: center;
gap: 10px;

.text {
max-width: 350px;
font: 500 16px/24px $kFontClashGrotesk;
letter-spacing: -0.01em;
color: #ff6fc8;
}

.icon {
width: 148.56px;
height: 40px;
}
}
}
}
}

// Small screens
@media screen and (max-width: 579px) {
padding: 10px 10px 15px;
background-image: url("/img/grants-banner/grants-sm.png");
height: 650px;

.cover {
background: linear-gradient(
190.87deg,
rgba(31, 29, 47, 0) 27.28%,
#1f1d2f 47.61%
);

.content {
flex-direction: column;
gap: 15px;
justify-content: center;
align-items: center;
margin-top: 50%;

.leftgroup p {
font-size: 65px;
}
}
}
}

// Medium screens
@media screen and (min-width: 580px) and (max-width: 873px) {
padding: 15px;
background-image: url("/img/grants-banner/grants-md.png");
height: 427px;

.cover {
background: linear-gradient(
278.04deg,
rgba(31, 29, 47, 0) 12.15%,
rgba(31, 29, 47, 0.1) 29.94%,
rgba(31, 29, 47, 0.8) 64.5%
);

.content {
flex-direction: column;
gap: 15px;

.rightgroup {
align-self: flex-start;
}
}
}
}

// Large screens
@media screen and (min-width: 874px) {
background-image: url("/img/grants-banner/grants-lg.png");
height: 295px;

.cover {
background: linear-gradient(
278.04deg,
rgba(31, 29, 47, 0.7) 23.14%,
rgba(31, 29, 47, 0) 41.66%,
rgba(31, 29, 47, 0) 62.73%,
rgba(31, 29, 47, 0.7) 78.07%
);

.content {
flex-direction: row;
gap: 15px;

.rightgroup {
align-self: flex-start;
}
}
}
}

// Extra large screens
@media screen and (min-width: $kLaptopM) {
background-image: url("/img/grants-banner/grants-xl.png");
height: 250px;

.cover {
background: linear-gradient(
278.04deg,
rgba(31, 29, 47, 0.7) 23.14%,
rgba(31, 29, 47, 0) 41.66%,
rgba(31, 29, 47, 0) 62.73%,
rgba(31, 29, 47, 0.7) 78.07%
);

.content {
flex-direction: row;
justify-content: space-between;
gap: 15px;
}
}
}
}
49 changes: 49 additions & 0 deletions src/shared/components/grants/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React from "react";
import css from "./grants.module.scss";

interface Props {
text: string;
icon: string;
logo: string;
button: React.ReactNode;
fullwidth?: boolean;
}

export const GrantsBanner: React.FC<Props> = ({
button,
text,
icon,
logo,
fullwidth,
}) => {
return (
<div className={css.banner}>
<div className={fullwidth ? "" : "container"}>
<div className={css.wrapper} data-class="banner">
<div className={css.cover}>
<div className={css.content}>
<div className={css.leftgroup}>
<p>
the grant <br /> factory
</p>
</div>

<div className={css.rightgroup}>
<div className={css.rightSubgroup}>
<p className={css.text}>{text}</p>
<img
className={css.icon}
src={icon}
alt="Grants"
loading="lazy"
/>
</div>
<div className={css.button}>{button}</div>
</div>
</div>
</div>
</div>
</div>
</div>
);
};
131 changes: 131 additions & 0 deletions src/widgets/01-home-screens/ui/08-banner/BannerCarousel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import React, { useEffect, useState } from "react";

export interface Slide {
component: React.ComponentType<any>;
icon?: string;
logo?: string;
text?: string;
button?: React.ReactNode;
}

interface CarouselProps {
slides: Array<Slide>;
interval?: number;
transitionDuration?: number;
withDots?: boolean;
}

const Carousel: React.FC<CarouselProps> = ({
slides,
interval = 4000,
transitionDuration = 400,
withDots = false,
}) => {
const [currentIndex, setCurrentIndex] = useState(0);
const [isAnimating, setIsAnimating] = useState(false);

useEffect(() => {
const slideInterval = setInterval(() => {
nextSlide();
}, interval);

return () => clearInterval(slideInterval);
}, [interval]);

const nextSlide = () => {
if (isAnimating) return;
setIsAnimating(true);
setCurrentIndex((prevIndex) => (prevIndex + 1) % slides.length);

setTimeout(() => {
setIsAnimating(false);
}, transitionDuration);
};

const goToSlide = (index: number) => {
if (isAnimating || index === currentIndex) return;
setIsAnimating(true);
setCurrentIndex(index);

setTimeout(() => {
setIsAnimating(false);
}, transitionDuration);
};

return (
<div
style={styles.carouselContainer}
aria-label="Image Carousel"
role="region"
aria-roledescription="carousel"
>
<div
style={{
...styles.carouselSlide,
transform: `translateX(-${currentIndex * 100}%)`,
transition: `transform ${transitionDuration}ms ease`,
}}
>
{slides.map((slide, index) => (
<div key={index} style={styles.slide}>
{React.createElement(slide.component)}
</div>
))}
</div>

{slides.length > 1 && withDots && (
<div
style={styles.dotContainer}
role="tablist"
aria-label="Slide navigation"
>
{slides.map((_, index) => (
<button
key={index}
style={{
...styles.dot,
backgroundColor: index === currentIndex ? "#C8047D" : "#D0D0D0",
}}
onClick={() => goToSlide(index)}
aria-label={`Go to slide ${index + 1}`}
/>
))}
</div>
)}
</div>
);
};

export default Carousel;

// Define style object
const styles = {
carouselContainer: {
position: "relative" as const,
width: "100%",
overflow: "hidden" as const,
},
carouselSlide: {
display: "flex" as const,
height: "100%",
transition: "transform 0.5s ease-in-out",
},
slide: {
minWidth: "100%",
height: "100%",
},
dotContainer: {
display: "flex",
justifyContent: "center",
gap: "8px",
marginTop: "16px",
},
dot: {
width: "12px",
height: "12px",
borderRadius: "50%",
transition: "background-color 0.3s",
border: "none",
cursor: "pointer",
},
};
Loading

0 comments on commit 495bd0e

Please sign in to comment.