split components into folders, add all home page sections
This commit is contained in:
parent
4faae9d54f
commit
3343ea68d5
1
relume-test/package-lock.json
generated
1
relume-test/package-lock.json
generated
@ -10,6 +10,7 @@
|
||||
"dependencies": {
|
||||
"@relume_io/relume-tailwind": "^1.3.0",
|
||||
"@relume_io/relume-ui": "^1.3.1",
|
||||
"clsx": "^2.1.1",
|
||||
"framer-motion": "^12.38.0",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
"dependencies": {
|
||||
"@relume_io/relume-tailwind": "^1.3.0",
|
||||
"@relume_io/relume-ui": "^1.3.1",
|
||||
"clsx": "^2.1.1",
|
||||
"framer-motion": "^12.38.0",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
|
||||
@ -1,15 +1,7 @@
|
||||
import { Navbar3 } from "./Navbar";
|
||||
import { Header1 } from "./Header";
|
||||
import { Footer3 } from "./Footer";
|
||||
import Home from "./pages/Home";
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div>
|
||||
<Navbar3 />
|
||||
<Header1 />
|
||||
<Footer3 />
|
||||
</div>
|
||||
);
|
||||
return <Home />;
|
||||
}
|
||||
|
||||
export default App;
|
||||
79
relume-test/src/components/Cta30.tsx
Normal file
79
relume-test/src/components/Cta30.tsx
Normal file
@ -0,0 +1,79 @@
|
||||
import * as React from "react";
|
||||
import { useState } from "react";
|
||||
import { Button, Input } from "@relume_io/relume-ui";
|
||||
import type { ButtonProps } from "@relume_io/relume-ui";
|
||||
|
||||
type Props = {
|
||||
heading: string;
|
||||
description: string;
|
||||
inputPlaceholder?: string;
|
||||
button: ButtonProps;
|
||||
termsAndConditions: string;
|
||||
video: string;
|
||||
videoType: string;
|
||||
};
|
||||
|
||||
export type Cta30Props = React.ComponentPropsWithoutRef<"section"> & Partial<Props>;
|
||||
|
||||
export const Cta30 = (props: Cta30Props) => {
|
||||
const { heading, description, inputPlaceholder, button, termsAndConditions, video, videoType } = {
|
||||
...Cta30Defaults,
|
||||
...props,
|
||||
};
|
||||
|
||||
const [emailInput, setEmailInput] = useState<string>("");
|
||||
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
|
||||
event.preventDefault();
|
||||
console.log({ emailInput });
|
||||
};
|
||||
|
||||
return (
|
||||
<section id="relume" className="relative px-[5%] py-16 md:py-24 lg:py-28">
|
||||
<div className="container relative z-10 max-w-lg text-center">
|
||||
<h2 className="rb-5 mb-5 text-5xl font-bold text-text-alternative md:mb-6 md:text-7xl lg:text-8xl">
|
||||
{heading}
|
||||
</h2>
|
||||
<p className="text-text-alternative md:text-md">{description}</p>
|
||||
<div className="mx-auto mt-6 w-full max-w-sm md:mt-8">
|
||||
<form
|
||||
className="rb-4 mb-4 grid max-w-sm grid-cols-1 gap-y-3 sm:grid-cols-[1fr_max-content] sm:gap-4"
|
||||
onSubmit={handleSubmit}
|
||||
>
|
||||
<Input
|
||||
id="email"
|
||||
type="email"
|
||||
placeholder={inputPlaceholder}
|
||||
value={emailInput}
|
||||
onChange={(e) => setEmailInput(e.target.value)}
|
||||
/>
|
||||
<Button {...button} className="items-center justify-center px-6 py-3">
|
||||
{button.title}
|
||||
</Button>
|
||||
</form>
|
||||
<div dangerouslySetInnerHTML={{ __html: termsAndConditions }} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="absolute inset-0 z-0">
|
||||
<video className="absolute inset-0 aspect-video size-full object-cover" autoPlay loop muted>
|
||||
<source src={video} type={videoType} />
|
||||
</video>
|
||||
<div className="absolute inset-0 bg-black/50" />
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export const Cta30Defaults: Props = {
|
||||
heading: "Medium length heading goes here",
|
||||
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique.",
|
||||
inputPlaceholder: "Enter your email",
|
||||
button: { title: "Sign up", variant: "primary", size: "sm" },
|
||||
termsAndConditions: `
|
||||
<p class='text-xs text-text-alternative'>
|
||||
By clicking Sign Up you're confirming that you agree with our
|
||||
<a href='#' class='underline'>Terms and Conditions</a>.
|
||||
</p>
|
||||
`,
|
||||
video: "https://d22po4pjz3o32e.cloudfront.net/placeholder-video.mp4",
|
||||
videoType: "video/mp4",
|
||||
};
|
||||
146
relume-test/src/components/Event17.tsx
Normal file
146
relume-test/src/components/Event17.tsx
Normal file
@ -0,0 +1,146 @@
|
||||
import * as React from "react";
|
||||
import type { ButtonProps } from "@relume_io/relume-ui";
|
||||
import { Button } from "@relume_io/relume-ui";
|
||||
import { RxChevronRight } from "react-icons/rx";
|
||||
import { BiMap, BiCalendarAlt } from "react-icons/bi";
|
||||
|
||||
type ImageProps = {
|
||||
src: string;
|
||||
alt?: string;
|
||||
};
|
||||
|
||||
type Date = {
|
||||
weekday: string;
|
||||
day: string;
|
||||
month: string;
|
||||
year: string;
|
||||
};
|
||||
|
||||
type FeaturedEvent = {
|
||||
url: string;
|
||||
image: ImageProps;
|
||||
date: Date;
|
||||
category: string;
|
||||
title: string;
|
||||
location: string;
|
||||
description: string;
|
||||
button: ButtonProps;
|
||||
};
|
||||
|
||||
type Props = {
|
||||
tagline: string;
|
||||
heading: string;
|
||||
description: string;
|
||||
button: ButtonProps;
|
||||
featuredEvents: FeaturedEvent[];
|
||||
};
|
||||
|
||||
export type Event17Props = React.ComponentPropsWithoutRef<"section"> & Partial<Props>;
|
||||
|
||||
export const Event17 = (props: Event17Props) => {
|
||||
const { tagline, heading, description, button, featuredEvents } = {
|
||||
...Event17Defaults,
|
||||
...props,
|
||||
};
|
||||
return (
|
||||
<section id="relume" className="px-[5%] py-16 md:py-24 lg:py-28">
|
||||
<div className="container">
|
||||
<div className="mx-auto mb-12 max-w-lg text-center md:mb-18 lg:mb-20">
|
||||
<h4 className="font-semibold">{tagline}</h4>
|
||||
<h1 className="mt-3 text-5xl font-bold md:mt-4 md:text-7xl lg:text-8xl">{heading}</h1>
|
||||
<p className="mt-5 text-base md:mt-6 md:text-md">{description}</p>
|
||||
</div>
|
||||
<div className="grid auto-cols-fr grid-cols-1 gap-x-8 gap-y-12 md:grid-cols-2 md:gap-y-16 lg:grid-cols-3">
|
||||
{featuredEvents.map((event, index) => (
|
||||
<FeaturedEvent key={index} {...event} />
|
||||
))}
|
||||
</div>
|
||||
<div className="mt-12 flex justify-center md:mt-18 lg:mt-20">
|
||||
<Button {...button}>{button.title}</Button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
const FeaturedEvent: React.FC<FeaturedEvent> = ({
|
||||
url, image, date, category, title, location, description, button,
|
||||
}) => {
|
||||
return (
|
||||
<div className="flex flex-col items-start">
|
||||
<a href={url} className="relative block aspect-[3/2] w-full">
|
||||
<img src={image.src} alt={image.alt} className="absolute size-full object-cover" />
|
||||
<span className="absolute right-4 top-4 bg-background-secondary px-2 py-1 text-sm font-semibold">
|
||||
{category}
|
||||
</span>
|
||||
</a>
|
||||
<div className="mt-5 flex flex-col items-start md:mt-6">
|
||||
<div className="mb-3 flex flex-wrap gap-4 text-sm md:mb-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<BiCalendarAlt className="size-6 flex-none" />
|
||||
{date.weekday} {date.day} {date.month} {date.year}
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<BiMap className="size-6 flex-none" />
|
||||
<span>{location}</span>
|
||||
</div>
|
||||
</div>
|
||||
<a href={url} className="mb-2">
|
||||
<h2 className="text-xl font-bold md:text-2xl">{title}</h2>
|
||||
</a>
|
||||
<p>{description}</p>
|
||||
<Button {...button} className="mt-5 md:mt-6">
|
||||
{button.title}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const Event17Defaults: Props = {
|
||||
tagline: "Tagline",
|
||||
heading: "Events",
|
||||
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
|
||||
button: { variant: "secondary", size: "primary", title: "View all" },
|
||||
featuredEvents: [
|
||||
{
|
||||
url: "#",
|
||||
image: {
|
||||
src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image-landscape.svg",
|
||||
alt: "Relume placeholder image 1",
|
||||
},
|
||||
date: { weekday: "Fri", day: "09", month: "Feb", year: "2024" },
|
||||
category: "Category",
|
||||
title: "Event title heading",
|
||||
location: "Location",
|
||||
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.",
|
||||
button: { title: "View event", variant: "link", size: "link", iconRight: <RxChevronRight /> },
|
||||
},
|
||||
{
|
||||
url: "#",
|
||||
image: {
|
||||
src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image-landscape.svg",
|
||||
alt: "Relume placeholder image 2",
|
||||
},
|
||||
date: { weekday: "Sat", day: "10", month: "Feb", year: "2024" },
|
||||
category: "Category",
|
||||
title: "Event title heading",
|
||||
location: "Location",
|
||||
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.",
|
||||
button: { title: "View event", variant: "link", size: "link", iconRight: <RxChevronRight /> },
|
||||
},
|
||||
{
|
||||
url: "#",
|
||||
image: {
|
||||
src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image-landscape.svg",
|
||||
alt: "Relume placeholder image 3",
|
||||
},
|
||||
date: { weekday: "Sun", day: "11", month: "Feb", year: "2024" },
|
||||
category: "Category",
|
||||
title: "Event title heading",
|
||||
location: "Location",
|
||||
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.",
|
||||
button: { title: "View event", variant: "link", size: "link", iconRight: <RxChevronRight /> },
|
||||
},
|
||||
],
|
||||
};
|
||||
151
relume-test/src/components/Event20.tsx
Normal file
151
relume-test/src/components/Event20.tsx
Normal file
@ -0,0 +1,151 @@
|
||||
import * as React from "react";
|
||||
import type { ButtonProps } from "@relume_io/relume-ui";
|
||||
import { Button } from "@relume_io/relume-ui";
|
||||
import { RxChevronRight } from "react-icons/rx";
|
||||
import { BiMap, BiCalendarAlt } from "react-icons/bi";
|
||||
|
||||
type ImageProps = {
|
||||
src: string;
|
||||
alt?: string;
|
||||
};
|
||||
|
||||
type Date = {
|
||||
weekday: string;
|
||||
day: string;
|
||||
month: string;
|
||||
year: string;
|
||||
};
|
||||
|
||||
type FeaturedEvent = {
|
||||
url: string;
|
||||
image: ImageProps;
|
||||
date: Date;
|
||||
category: string;
|
||||
title: string;
|
||||
location: string;
|
||||
description: string;
|
||||
button: ButtonProps;
|
||||
};
|
||||
|
||||
type Props = {
|
||||
tagline: string;
|
||||
heading: string;
|
||||
description: string;
|
||||
button: ButtonProps;
|
||||
featuredEvents: FeaturedEvent[];
|
||||
};
|
||||
|
||||
export type Event20Props = React.ComponentPropsWithoutRef<"section"> & Partial<Props>;
|
||||
|
||||
export const Event20 = (props: Event20Props) => {
|
||||
const { tagline, heading, description, button, featuredEvents } = {
|
||||
...Event20Defaults,
|
||||
...props,
|
||||
};
|
||||
return (
|
||||
<section id="relume" className="px-[5%] py-16 md:py-24 lg:py-28">
|
||||
<div className="container">
|
||||
<div className="mb-12 grid auto-cols-fr grid-cols-1 items-end gap-12 md:mb-18 md:grid-cols-[1fr_max-content] lg:mb-20 lg:gap-20">
|
||||
<div className="max-w-lg">
|
||||
<p className="mb-3 font-semibold md:mb-4">{tagline}</p>
|
||||
<h1 className="mb-3 text-5xl font-bold md:mb-4 md:text-7xl lg:text-8xl">{heading}</h1>
|
||||
<p className="md:text-md">{description}</p>
|
||||
</div>
|
||||
<Button {...button} className="hidden md:flex">
|
||||
{button.title}
|
||||
</Button>
|
||||
</div>
|
||||
<div className="grid auto-cols-fr grid-cols-1 gap-x-8 gap-y-12 md:grid-cols-2 md:gap-y-16 lg:grid-cols-3">
|
||||
{featuredEvents.map((event, index) => (
|
||||
<FeaturedEvent key={index} {...event} />
|
||||
))}
|
||||
</div>
|
||||
<div className="mt-12 flex justify-end md:hidden">
|
||||
<Button {...button}>{button.title}</Button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
const FeaturedEvent: React.FC<FeaturedEvent> = ({
|
||||
url, image, date, category, title, location, description, button,
|
||||
}) => {
|
||||
return (
|
||||
<div className="flex flex-col items-start border border-border-primary">
|
||||
<a href={url} className="relative block aspect-[3/2] w-full">
|
||||
<img src={image.src} alt={image.alt} className="absolute size-full object-cover" />
|
||||
<span className="absolute right-4 top-4 bg-background-secondary px-2 py-1 text-sm font-semibold">
|
||||
{category}
|
||||
</span>
|
||||
</a>
|
||||
<div className="flex flex-col items-start p-6">
|
||||
<div className="mb-3 flex flex-wrap gap-2 text-sm sm:gap-4 md:mb-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<BiCalendarAlt className="size-6 flex-none" />
|
||||
{date.weekday} {date.day} {date.month} {date.year}
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<BiMap className="size-6 flex-none" />
|
||||
<span>{location}</span>
|
||||
</div>
|
||||
</div>
|
||||
<a href={url} className="mb-2">
|
||||
<h2 className="text-xl font-bold md:text-2xl">{title}</h2>
|
||||
</a>
|
||||
<p>{description}</p>
|
||||
<Button {...button} className="mt-5 md:mt-6">
|
||||
{button.title}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const Event20Defaults: Props = {
|
||||
tagline: "Tagline",
|
||||
heading: "Events",
|
||||
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
|
||||
button: { variant: "secondary", size: "primary", title: "View all" },
|
||||
featuredEvents: [
|
||||
{
|
||||
url: "#",
|
||||
image: {
|
||||
src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image-landscape.svg",
|
||||
alt: "Relume placeholder image 1",
|
||||
},
|
||||
date: { weekday: "Fri", day: "09", month: "Feb", year: "2024" },
|
||||
category: "Category",
|
||||
title: "Event title heading",
|
||||
location: "Location",
|
||||
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.",
|
||||
button: { title: "View event", variant: "link", size: "link", iconRight: <RxChevronRight /> },
|
||||
},
|
||||
{
|
||||
url: "#",
|
||||
image: {
|
||||
src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image-landscape.svg",
|
||||
alt: "Relume placeholder image 2",
|
||||
},
|
||||
date: { weekday: "Sat", day: "10", month: "Feb", year: "2024" },
|
||||
category: "Category",
|
||||
title: "Event title heading",
|
||||
location: "Location",
|
||||
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.",
|
||||
button: { title: "View event", variant: "link", size: "link", iconRight: <RxChevronRight /> },
|
||||
},
|
||||
{
|
||||
url: "#",
|
||||
image: {
|
||||
src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image-landscape.svg",
|
||||
alt: "Relume placeholder image 3",
|
||||
},
|
||||
date: { weekday: "Sun", day: "11", month: "Feb", year: "2024" },
|
||||
category: "Category",
|
||||
title: "Event title heading",
|
||||
location: "Location",
|
||||
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.",
|
||||
button: { title: "View event", variant: "link", size: "link", iconRight: <RxChevronRight /> },
|
||||
},
|
||||
],
|
||||
};
|
||||
100
relume-test/src/components/Faq10.tsx
Normal file
100
relume-test/src/components/Faq10.tsx
Normal file
@ -0,0 +1,100 @@
|
||||
import * as React from "react";
|
||||
import {
|
||||
Button,
|
||||
Accordion,
|
||||
AccordionTrigger,
|
||||
AccordionContent,
|
||||
AccordionItem,
|
||||
} from "@relume_io/relume-ui";
|
||||
import type { ButtonProps } from "@relume_io/relume-ui";
|
||||
|
||||
type QuestionsProps = {
|
||||
title: string;
|
||||
answer: string;
|
||||
};
|
||||
|
||||
type Props = {
|
||||
heading: string;
|
||||
description: string;
|
||||
footerHeading: string;
|
||||
footerDescription: string;
|
||||
button: ButtonProps;
|
||||
questions: QuestionsProps[];
|
||||
};
|
||||
|
||||
export type Faq10Props = React.ComponentPropsWithoutRef<"section"> & Partial<Props>;
|
||||
|
||||
export const Faq10 = (props: Faq10Props) => {
|
||||
const { heading, description, questions, footerHeading, footerDescription, button } = {
|
||||
...Faq10Defaults,
|
||||
...props,
|
||||
};
|
||||
|
||||
const halfLength = Math.ceil(questions.length / 2);
|
||||
const firstColumnQuestions = questions.slice(0, halfLength);
|
||||
const secondColumnQuestions = questions.slice(halfLength);
|
||||
|
||||
return (
|
||||
<section id="relume" className="px-[5%] py-16 md:py-24 lg:py-28">
|
||||
<div className="container">
|
||||
<div className="mx-auto mb-12 w-full max-w-lg text-center md:mb-18 lg:mb-20">
|
||||
<h2 className="rb-5 mb-5 text-5xl font-bold md:mb-6 md:text-7xl lg:text-8xl">
|
||||
{heading}
|
||||
</h2>
|
||||
<p className="md:text-md">{description}</p>
|
||||
</div>
|
||||
<div className="grid w-full auto-rows-min grid-cols-1 items-start gap-x-12 md:grid-cols-2 lg:gap-x-16">
|
||||
<Accordion type="multiple" className="w-full">
|
||||
{firstColumnQuestions.map((question, index) => (
|
||||
<AccordionItem key={index} value={`item-${index}`} className="overflow-hidden">
|
||||
<AccordionTrigger className="md:py-5 md:text-md">{question.title}</AccordionTrigger>
|
||||
<AccordionContent className="md:pb-6">{question.answer}</AccordionContent>
|
||||
</AccordionItem>
|
||||
))}
|
||||
</Accordion>
|
||||
<Accordion type="multiple" className="w-full">
|
||||
{secondColumnQuestions.map((question, index) => (
|
||||
<AccordionItem
|
||||
key={index + halfLength}
|
||||
value={`item-${index + halfLength}`}
|
||||
className="overflow-hidden first:border-t-0 md:first:border-t"
|
||||
>
|
||||
<AccordionTrigger className="md:py-5 md:text-md">{question.title}</AccordionTrigger>
|
||||
<AccordionContent className="md:pb-6">{question.answer}</AccordionContent>
|
||||
</AccordionItem>
|
||||
))}
|
||||
</Accordion>
|
||||
</div>
|
||||
<div className="mx-auto mt-12 max-w-md text-center md:mt-18 lg:mt-20">
|
||||
<h4 className="mb-3 text-2xl font-bold md:mb-4 md:text-3xl md:leading-[1.3] lg:text-4xl">
|
||||
{footerHeading}
|
||||
</h4>
|
||||
<p className="md:text-md">{footerDescription}</p>
|
||||
<div className="mt-6 md:mt-8">
|
||||
<Button {...button}>{button.title}</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export const Faq10Defaults: Props = {
|
||||
heading: "FAQs",
|
||||
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique.",
|
||||
questions: [
|
||||
{ title: "Question text goes here", answer: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere." },
|
||||
{ title: "Question text goes here", answer: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere." },
|
||||
{ title: "Question text goes here", answer: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere." },
|
||||
{ title: "Question text goes here", answer: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere." },
|
||||
{ title: "Question text goes here", answer: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere." },
|
||||
{ title: "Question text goes here", answer: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere." },
|
||||
{ title: "Question text goes here", answer: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere." },
|
||||
{ title: "Question text goes here", answer: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere." },
|
||||
{ title: "Question text goes here", answer: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere." },
|
||||
{ title: "Question text goes here", answer: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere." },
|
||||
],
|
||||
footerHeading: "Still have questions?",
|
||||
footerDescription: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
|
||||
button: { title: "Contact", variant: "secondary" },
|
||||
};
|
||||
99
relume-test/src/components/Gallery19.tsx
Normal file
99
relume-test/src/components/Gallery19.tsx
Normal file
@ -0,0 +1,99 @@
|
||||
import * as React from "react";
|
||||
import { useState, useEffect } from "react";
|
||||
import {
|
||||
Carousel,
|
||||
CarouselContent,
|
||||
CarouselItem,
|
||||
CarouselNext,
|
||||
CarouselPrevious,
|
||||
} from "@relume_io/relume-ui";
|
||||
import type { CarouselApi } from "@relume_io/relume-ui";
|
||||
import clsx from "clsx";
|
||||
|
||||
type ImageProps = {
|
||||
src: string;
|
||||
alt?: string;
|
||||
};
|
||||
|
||||
type Props = {
|
||||
heading: string;
|
||||
description: string;
|
||||
images: ImageProps[];
|
||||
};
|
||||
|
||||
export type Gallery19Props = React.ComponentPropsWithoutRef<"section"> & Partial<Props>;
|
||||
|
||||
export const Gallery19 = (props: Gallery19Props) => {
|
||||
const { heading, description, images } = {
|
||||
...Gallery19Defaults,
|
||||
...props,
|
||||
};
|
||||
|
||||
const [api, setApi] = useState<CarouselApi>();
|
||||
const [current, setCurrent] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
if (!api) return;
|
||||
setCurrent(api.selectedScrollSnap() + 1);
|
||||
api.on("select", () => {
|
||||
setCurrent(api.selectedScrollSnap() + 1);
|
||||
});
|
||||
}, [api]);
|
||||
|
||||
return (
|
||||
<section id="relume">
|
||||
<div className="px-[5%] py-16 md:py-24 lg:py-28">
|
||||
<div className="container">
|
||||
<div className="rb-12 mb-12 text-center md:mb-18 lg:mb-20">
|
||||
<h2 className="rb-5 mb-5 text-5xl font-bold md:mb-6 md:text-7xl lg:text-8xl">
|
||||
{heading}
|
||||
</h2>
|
||||
<p className="md:text-md">{description}</p>
|
||||
</div>
|
||||
<Carousel setApi={setApi} opts={{ loop: true, align: "start" }}>
|
||||
<div className="relative">
|
||||
<CarouselContent className="ml-0">
|
||||
{images.map((image, index) => (
|
||||
<CarouselItem key={index} className="basis-1/2 px-3 md:basis-1/4 md:px-4">
|
||||
<div className="w-full">
|
||||
<img src={image.src} alt={image.alt} className="aspect-square size-full object-cover" />
|
||||
</div>
|
||||
</CarouselItem>
|
||||
))}
|
||||
</CarouselContent>
|
||||
<CarouselPrevious className="hidden md:flex md:size-12 lg:size-14" />
|
||||
<CarouselNext className="hidden md:flex md:size-12 lg:size-14" />
|
||||
</div>
|
||||
<div className="mt-[30px] flex items-center justify-center md:mt-[46px]">
|
||||
{images.map((_, index) => (
|
||||
<button
|
||||
key={index}
|
||||
onClick={() => api?.scrollTo(index)}
|
||||
className={clsx("relative mx-[3px] inline-block size-2 rounded-full", {
|
||||
"bg-black": current === index + 1,
|
||||
"bg-neutral-darker/40": current !== index + 1,
|
||||
})}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</Carousel>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export const Gallery19Defaults: Props = {
|
||||
heading: "Image Gallery",
|
||||
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
|
||||
images: [
|
||||
{ src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image.svg", alt: "Relume placeholder image 1" },
|
||||
{ src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image.svg", alt: "Relume placeholder image 2" },
|
||||
{ src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image.svg", alt: "Relume placeholder image 3" },
|
||||
{ src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image.svg", alt: "Relume placeholder image 4" },
|
||||
{ src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image.svg", alt: "Relume placeholder image 5" },
|
||||
{ src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image.svg", alt: "Relume placeholder image 6" },
|
||||
{ src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image.svg", alt: "Relume placeholder image 7" },
|
||||
{ src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image.svg", alt: "Relume placeholder image 8" },
|
||||
],
|
||||
};
|
||||
104
relume-test/src/components/Pricing18.tsx
Normal file
104
relume-test/src/components/Pricing18.tsx
Normal file
@ -0,0 +1,104 @@
|
||||
import * as React from "react";
|
||||
import { Button } from "@relume_io/relume-ui";
|
||||
import type { ButtonProps } from "@relume_io/relume-ui";
|
||||
import { BiCheck } from "react-icons/bi";
|
||||
|
||||
type PricingPlan = {
|
||||
planName: string;
|
||||
monthlyPrice: string;
|
||||
yearlyPrice: string;
|
||||
features: string[];
|
||||
button: ButtonProps;
|
||||
};
|
||||
|
||||
type Props = {
|
||||
tagline: string;
|
||||
heading: string;
|
||||
description: string;
|
||||
pricingPlans: PricingPlan[];
|
||||
};
|
||||
|
||||
export type Pricing18Props = React.ComponentPropsWithoutRef<"section"> & Partial<Props>;
|
||||
|
||||
export const Pricing18 = (props: Pricing18Props) => {
|
||||
const { tagline, heading, description, pricingPlans } = {
|
||||
...Pricing18Defaults,
|
||||
...props,
|
||||
};
|
||||
return (
|
||||
<section id="relume" className="px-[5%] py-16 md:py-24 lg:py-28">
|
||||
<div className="container">
|
||||
<div className="mx-auto mb-12 max-w-lg text-center md:mb-18 lg:mb-20">
|
||||
<p className="mb-3 font-semibold md:mb-4">{tagline}</p>
|
||||
<h2 className="rb-5 mb-5 text-5xl font-bold md:mb-6 md:text-7xl lg:text-8xl">
|
||||
{heading}
|
||||
</h2>
|
||||
<p className="md:text-md">{description}</p>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 gap-8 lg:grid-cols-3">
|
||||
{pricingPlans.map((plan, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="flex h-full flex-col justify-between border border-border-primary px-6 py-8 md:p-8"
|
||||
>
|
||||
<div>
|
||||
<div className="rb-6 mb-6 text-center md:mb-8">
|
||||
<h6 className="text-md font-bold md:text-xl">{plan.planName}</h6>
|
||||
<h1 className="my-2 text-6xl font-bold md:text-9xl lg:text-10xl">
|
||||
{plan.monthlyPrice}
|
||||
<span className="text-2xl font-bold md:text-3xl lg:text-4xl">/mo</span>
|
||||
</h1>
|
||||
<p>or {plan.yearlyPrice} yearly</p>
|
||||
</div>
|
||||
<div className="mb-8 grid grid-cols-1 gap-4 py-2">
|
||||
{plan.features.map((feature, index) => (
|
||||
<div key={index} className="flex self-start">
|
||||
<div className="mr-4 flex-none self-start">
|
||||
<BiCheck className="size-6" />
|
||||
</div>
|
||||
<p>{feature}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<Button {...plan.button} className="w-full">
|
||||
{plan.button.title}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export const Pricing18Defaults: Props = {
|
||||
tagline: "Tagline",
|
||||
heading: "Pricing plan",
|
||||
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
|
||||
pricingPlans: [
|
||||
{
|
||||
planName: "Basic plan",
|
||||
monthlyPrice: "$19",
|
||||
yearlyPrice: "$199",
|
||||
features: ["Feature text goes here", "Feature text goes here", "Feature text goes here"],
|
||||
button: { title: "Get started" },
|
||||
},
|
||||
{
|
||||
planName: "Business plan",
|
||||
monthlyPrice: "$29",
|
||||
yearlyPrice: "$299",
|
||||
features: ["Feature text goes here", "Feature text goes here", "Feature text goes here", "Feature text goes here"],
|
||||
button: { title: "Get started" },
|
||||
},
|
||||
{
|
||||
planName: "Enterprise plan",
|
||||
monthlyPrice: "$49",
|
||||
yearlyPrice: "$499",
|
||||
features: ["Feature text goes here", "Feature text goes here", "Feature text goes here", "Feature text goes here", "Feature text goes here"],
|
||||
button: { title: "Get started" },
|
||||
},
|
||||
],
|
||||
};
|
||||
27
relume-test/src/pages/Home.tsx
Normal file
27
relume-test/src/pages/Home.tsx
Normal file
@ -0,0 +1,27 @@
|
||||
import { Navbar3 } from "../components/Navbar";
|
||||
import { Header1 } from "../components/Header";
|
||||
import { Event17 } from "../components/Event17";
|
||||
import { Gallery19 } from "../components/Gallery19";
|
||||
import { Cta30 } from "../components/Cta30";
|
||||
import { Event20 } from "../components/Event20";
|
||||
import { Pricing18 } from "../components/Pricing18";
|
||||
import { Faq10 } from "../components/Faq10";
|
||||
import { Footer3 } from "../components/Footer";
|
||||
|
||||
export const Home = () => {
|
||||
return (
|
||||
<div>
|
||||
<Navbar3 />
|
||||
<Header1 />
|
||||
<Event17 />
|
||||
<Gallery19 />
|
||||
<Cta30 />
|
||||
<Event20 />
|
||||
<Pricing18 />
|
||||
<Faq10 />
|
||||
<Footer3 />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Home;
|
||||
1242
relume-test/src/reactcomponents_home.jsx
Normal file
1242
relume-test/src/reactcomponents_home.jsx
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user