update pay function

This commit is contained in:
2025-11-22 16:14:49 +08:00
parent 75696b9e52
commit f56df0e956
58 changed files with 0 additions and 4800 deletions

View File

@@ -1,138 +0,0 @@
import { useRef, useState } from "react";
import { Splide, SplideTrack, SplideSlide } from "@splidejs/react-splide";
import Button from "@/components/Button";
import Image from "@/components/Image";
import { pricing } from "@/mocks/pricing";
type PricingListProps = {
monthly?: boolean;
};
const PricingList = ({ monthly = true }: PricingListProps) => {
const [activeIndex, setActiveIndex] = useState<number>(0);
const ref = useRef<any>(null);
const handleClick = (index: number) => {
setActiveIndex(index);
ref.current?.go(index);
};
return (
<Splide
className="splide-pricing splide-visible"
options={{
mediaQuery: "min",
autoWidth: true,
pagination: false,
arrows: false,
gap: "1rem",
breakpoints: {
1024: {
destroy: true,
},
},
}}
onMoved={(e, newIndex) => setActiveIndex(newIndex)}
hasTrack={false}
ref={ref}
>
<SplideTrack>
{pricing.map((item, index) => (
<SplideSlide
className={`${index === 1 ? "" : "py-3"}`}
key={item.id}
>
<div
className={`w-[19rem] h-full px-6 ${
index === 1 ? "py-12" : "py-8"
} bg-n-8 border border-n-6 rounded-[2rem] lg:w-auto`}
key={item.id}
>
<h4
className={`h4 mb-4 ${
index === 0 ? "text-color-2" : ""
} ${index === 1 ? "text-color-1" : ""} ${
index === 2 ? "text-color-3" : ""
}`}
>
{item.title}
</h4>
<p className="body-2 min-h-[4rem] mb-3 text-n-1/50">
{item.description}
</p>
<div className="flex items-center h-[5.5rem] mb-6">
{item.price && (
<>
<div className="h3">$</div>
<div className="text-[5.5rem] leading-none font-bold">
{monthly
? item.price
: item.price !== "0"
? (
+item.price *
12 *
0.9
).toFixed(1)
: item.price}
</div>
</>
)}
</div>
<Button
className="w-full mb-6"
href={
item.price
? "/pricing"
: "mailto:info@ui8.net"
}
white={!!item.price}
>
{item.price ? "Get started" : "Contact us"}
</Button>
<ul>
{item.features.map((feature, index) => (
<li
className="flex items-start py-5 border-t border-n-6"
key={index}
>
<Image
src="/images/check.svg"
width={24}
height={24}
alt="Check"
/>
<p className="body-2 ml-4">{feature}</p>
</li>
))}
</ul>
</div>
</SplideSlide>
))}
</SplideTrack>
<div className="flex justify-center mt-8 -mx-2 md:mt-15 lg:hidden">
{pricing.map((item, index) => (
<button
className="relative w-6 h-6 mx-2"
onClick={() => handleClick(index)}
key={item.id}
>
<span
className={`absolute inset-0 bg-conic-gradient rounded-full transition-opacity ${
index === activeIndex
? "opacity-100"
: "opacity-0"
}`}
></span>
<span className="absolute inset-0.25 bg-n-8 rounded-full">
<span className="absolute inset-2 bg-n-1 rounded-full"></span>
</span>
</button>
))}
</div>
</Splide>
);
};
export default PricingList;

View File

@@ -1,138 +0,0 @@
import { useRef, useState } from "react";
import { Splide, SplideTrack, SplideSlide } from "@splidejs/react-splide";
import Button from "@/components/Button";
import Image from "@/components/Image";
import { pricing } from "@/mocks/pricing";
type PricingListProps = {
monthly?: boolean;
};
const PricingList = ({ monthly = true }: PricingListProps) => {
const [activeIndex, setActiveIndex] = useState<number>(0);
const ref = useRef<any>(null);
const handleClick = (index: number) => {
setActiveIndex(index);
ref.current?.go(index);
};
return (
<Splide
className="splide-pricing splide-visible"
options={{
mediaQuery: "min",
autoWidth: true,
pagination: false,
arrows: false,
gap: "1rem",
breakpoints: {
1024: {
destroy: true,
},
},
}}
onMoved={(e, newIndex) => setActiveIndex(newIndex)}
hasTrack={false}
ref={ref}
>
<SplideTrack>
{pricing.map((item, index) => (
<SplideSlide
className={`${index === 1 ? "" : "py-3"}`}
key={item.id}
>
<div
className={`w-[19rem] h-full px-6 ${
index === 1 ? "py-12" : "py-8"
} bg-n-8 border border-n-6 rounded-[2rem] lg:w-auto`}
key={item.id}
>
<h4
className={`h4 mb-4 ${
index === 0 ? "text-color-2" : ""
} ${index === 1 ? "text-color-1" : ""} ${
index === 2 ? "text-color-3" : ""
}`}
>
{item.title}
</h4>
<p className="body-2 min-h-[4rem] mb-3 text-n-1/50">
{item.description}
</p>
<div className="flex items-center h-[5.5rem] mb-6">
{item.price && (
<>
<div className="h3">$</div>
<div className="text-[5.5rem] leading-none font-bold">
{monthly
? item.price
: item.price !== "0"
? (
+item.price *
12 *
0.9
).toFixed(1)
: item.price}
</div>
</>
)}
</div>
<Button
className="w-full mb-6"
href={
item.price
? "/pricing"
: "mailto:info@ui8.net"
}
white={!!item.price}
>
{item.price ? "Get started" : "Contact us"}
</Button>
<ul>
{item.features.map((feature, index) => (
<li
className="flex items-start py-5 border-t border-n-6"
key={index}
>
<Image
src="/images/check.svg"
width={24}
height={24}
alt="Check"
/>
<p className="body-2 ml-4">{feature}</p>
</li>
))}
</ul>
</div>
</SplideSlide>
))}
</SplideTrack>
<div className="flex justify-center mt-8 -mx-2 md:mt-15 lg:hidden">
{pricing.map((item, index) => (
<button
className="relative w-6 h-6 mx-2"
onClick={() => handleClick(index)}
key={item.id}
>
<span
className={`absolute inset-0 bg-conic-gradient rounded-full transition-opacity ${
index === activeIndex
? "opacity-100"
: "opacity-0"
}`}
></span>
<span className="absolute inset-0.25 bg-n-8 rounded-full">
<span className="absolute inset-2 bg-n-1 rounded-full"></span>
</span>
</button>
))}
</div>
</Splide>
);
};
export default PricingList;

View File

@@ -1,83 +0,0 @@
import { useRef, useState } from "react";
import Link from "next/link";
import { Splide, SplideTrack, SplideSlide } from "@splidejs/react-splide";
import Section from "@/components/Section";
import Image from "@/components/Image";
import { benefits } from "@/mocks/benefits";
type BenefitsProps = {};
const Benefits = ({}: BenefitsProps) => {
const [activeIndex, setActiveIndex] = useState<number>(0);
const ref = useRef<any>(null);
const handleClick = (index: number) => {
setActiveIndex(index);
ref.current?.go(index);
};
return (
<Section className="overflow-hidden">
<div className="container relative z-2">
<Splide
className="splide-benefits splide-visible max-w-[16rem] md:max-w-none"
options={{
mediaQuery: "min",
pagination: false,
arrows: false,
gap: "1.5rem",
breakpoints: {
768: {
destroy: true,
},
},
}}
onMoved={(e, newIndex) => setActiveIndex(newIndex)}
hasTrack={false}
ref={ref}
>
<SplideTrack>
{benefits.map((item) => (
<SplideSlide key={item.id}>
<div className="flex items-center mb-6">
<Image
src={item.iconUrl}
width={48}
height={48}
alt={item.title}
/>
</div>
<h5 className="h6 mb-4">{item.title}</h5>
<p className="body-2 text-n-3">{item.text}</p>
</SplideSlide>
))}
</SplideTrack>
</Splide>
<div className="flex mt-12 -mx-2 md:hidden">
{benefits.map((item, index) => (
<button
className="relative w-6 h-6 mx-2"
onClick={() => handleClick(index)}
key={item.id}
>
<span
className={`absolute inset-0 bg-conic-gradient rounded-full transition-opacity ${
index === activeIndex
? "opacity-100"
: "opacity-0"
}`}
></span>
<span className="absolute inset-0.25 bg-n-8 rounded-full">
<span className="absolute inset-2 bg-n-1 rounded-full"></span>
</span>
</button>
))}
</div>
</div>
</Section>
);
};
export default Benefits;

View File

@@ -1,83 +0,0 @@
import { useRef, useState } from "react";
import Link from "next/link";
import { Splide, SplideTrack, SplideSlide } from "@splidejs/react-splide";
import Section from "@/components/Section";
import Image from "@/components/Image";
import { benefits } from "@/mocks/benefits";
type BenefitsProps = {};
const Benefits = ({}: BenefitsProps) => {
const [activeIndex, setActiveIndex] = useState<number>(0);
const ref = useRef<any>(null);
const handleClick = (index: number) => {
setActiveIndex(index);
ref.current?.go(index);
};
return (
<Section className="overflow-hidden">
<div className="container relative z-2">
<Splide
className="splide-benefits splide-visible max-w-[16rem] md:max-w-none"
options={{
mediaQuery: "min",
pagination: false,
arrows: false,
gap: "1.5rem",
breakpoints: {
768: {
destroy: true,
},
},
}}
onMoved={(e, newIndex) => setActiveIndex(newIndex)}
hasTrack={false}
ref={ref}
>
<SplideTrack>
{benefits.map((item) => (
<SplideSlide key={item.id}>
<div className="flex items-center mb-6">
<Image
src={item.iconUrl}
width={48}
height={48}
alt={item.title}
/>
</div>
<h5 className="h6 mb-4">{item.title}</h5>
<p className="body-2 text-n-3">{item.text}</p>
</SplideSlide>
))}
</SplideTrack>
</Splide>
<div className="flex mt-12 -mx-2 md:hidden">
{benefits.map((item, index) => (
<button
className="relative w-6 h-6 mx-2"
onClick={() => handleClick(index)}
key={item.id}
>
<span
className={`absolute inset-0 bg-conic-gradient rounded-full transition-opacity ${
index === activeIndex
? "opacity-100"
: "opacity-0"
}`}
></span>
<span className="absolute inset-0.25 bg-n-8 rounded-full">
<span className="absolute inset-2 bg-n-1 rounded-full"></span>
</span>
</button>
))}
</div>
</div>
</Section>
);
};
export default Benefits;

View File

@@ -1,107 +0,0 @@
import { useRef, useState } from "react";
import { Splide, SplideSlide } from "@splidejs/react-splide";
import Section from "@/components/Section";
import Image from "@/components/Image";
import { community } from "@/mocks/community";
type CommunityProps = {};
const Community = ({}: CommunityProps) => {
const [activeIndex, setActiveIndex] = useState<number>(0);
const ref = useRef<any>(null);
const handleClick = (index: number) => {
setActiveIndex(index);
ref.current?.go(index);
};
return (
<Section className="">
<div className="container">
<div className="relative p-0.5 bg-gradient-to-b from-color-2/80 from-[4.5rem] via-color-1/40 via-[9rem] to-n-1/15 rounded-3xl">
<div className="pt-20 px-5 py-10 bg-n-8 rounded-[1.375rem] md:pt-20 md:px-20 mb:pb-16 lg:py-28 lg:pr-48">
<Splide
options={{
type: "fade",
pagination: false,
arrows: false,
}}
onMoved={(e, newIndex) => setActiveIndex(newIndex)}
ref={ref}
>
{community.map((comment) => (
<SplideSlide className="flex" key={comment.id}>
<div className="flex flex-col lg:flex-row lg:items-start">
<div className="quote mb-6 md:mb-12 lg:mb-0 lg:text-[1.75rem] lg:leading-[2.25rem]">
{comment.text}
</div>
<div className="flex items-center mt-auto lg:block lg:mt-0 lg:ml-20">
<div className="w-20 mr-6 lg:w-40 lg:mr-0 lg:mb-11">
<Image
className="w-full rounded-2xl"
src={comment.avatarUrl}
width={160}
height={160}
alt={comment.name}
/>
</div>
<div>
<h6 className="h6">
{comment.name}
</h6>
<div className="caption text-n-1/25">
{comment.role}
</div>
</div>
</div>
</div>
</SplideSlide>
))}
</Splide>
<div
className="flex justify-center mt-10 -mx-2 md:mt-12 md:justify-start lg:absolute lg:top-0
lg:right-20 lg:h-full lg:flex-col lg:justify-center lg:m-0"
>
{community.map((item: any, index: number) => (
<button
className="relative w-6 h-6 mx-2 lg:my-2 lg:mx-0"
onClick={() => handleClick(index)}
key={item.id}
>
<span
className={`absolute inset-0 bg-conic-gradient rounded-full transition-opacity ${
index === activeIndex
? "opacity-100"
: "opacity-0"
}`}
></span>
<span className="absolute inset-0.25 bg-n-8 rounded-full">
<span className="absolute inset-2 bg-n-1 rounded-full"></span>
</span>
</button>
))}
</div>
</div>
<div className="absolute -top-14 left-0 z-2 font-code text-[11.25rem] text-color-1 leading-none md:left-12">
</div>
<div className="absolute top-0 right-0 bg-n-8">
<svg width="72" height="72" viewBox="0 0 72 72">
<path
fill="#0E0C15"
stroke="#FFC876"
strokeWidth="2"
strokeOpacity=".8"
d="M-1176,1 L6.15,1 C13.89,1 21.35,3.89547 27.06,9.11714 L60.91,40.0541 C67.34,45.9271 71,54.2315 71,62.937 L71,444 C71,461.121 57.12,475 40,475 L-1176,475 C-1193.1209,475 -1207,461.121 -1207,444 L-1207,32 C-1207,14.8792 -1193.1208,1 -1176,1 Z"
/>
</svg>
</div>
</div>
</div>
</Section>
);
};
export default Community;

View File

@@ -1,107 +0,0 @@
import { useRef, useState } from "react";
import { Splide, SplideSlide } from "@splidejs/react-splide";
import Section from "@/components/Section";
import Image from "@/components/Image";
import { community } from "@/mocks/community";
type CommunityProps = {};
const Community = ({}: CommunityProps) => {
const [activeIndex, setActiveIndex] = useState<number>(0);
const ref = useRef<any>(null);
const handleClick = (index: number) => {
setActiveIndex(index);
ref.current?.go(index);
};
return (
<Section className="">
<div className="container">
<div className="relative p-0.5 bg-gradient-to-b from-color-2/80 from-[4.5rem] via-color-1/40 via-[9rem] to-n-1/15 rounded-3xl">
<div className="pt-20 px-5 py-10 bg-n-8 rounded-[1.375rem] md:pt-20 md:px-20 mb:pb-16 lg:py-28 lg:pr-48">
<Splide
options={{
type: "fade",
pagination: false,
arrows: false,
}}
onMoved={(e, newIndex) => setActiveIndex(newIndex)}
ref={ref}
>
{community.map((comment) => (
<SplideSlide className="flex" key={comment.id}>
<div className="flex flex-col lg:flex-row lg:items-start">
<div className="quote mb-6 md:mb-12 lg:mb-0 lg:text-[1.75rem] lg:leading-[2.25rem]">
{comment.text}
</div>
<div className="flex items-center mt-auto lg:block lg:mt-0 lg:ml-20">
<div className="w-20 mr-6 lg:w-40 lg:mr-0 lg:mb-11">
<Image
className="w-full rounded-2xl"
src={comment.avatarUrl}
width={160}
height={160}
alt={comment.name}
/>
</div>
<div>
<h6 className="h6">
{comment.name}
</h6>
<div className="caption text-n-1/25">
{comment.role}
</div>
</div>
</div>
</div>
</SplideSlide>
))}
</Splide>
<div
className="flex justify-center mt-10 -mx-2 md:mt-12 md:justify-start lg:absolute lg:top-0
lg:right-20 lg:h-full lg:flex-col lg:justify-center lg:m-0"
>
{community.map((item: any, index: number) => (
<button
className="relative w-6 h-6 mx-2 lg:my-2 lg:mx-0"
onClick={() => handleClick(index)}
key={item.id}
>
<span
className={`absolute inset-0 bg-conic-gradient rounded-full transition-opacity ${
index === activeIndex
? "opacity-100"
: "opacity-0"
}`}
></span>
<span className="absolute inset-0.25 bg-n-8 rounded-full">
<span className="absolute inset-2 bg-n-1 rounded-full"></span>
</span>
</button>
))}
</div>
</div>
<div className="absolute -top-14 left-0 z-2 font-code text-[11.25rem] text-color-1 leading-none md:left-12">
</div>
<div className="absolute top-0 right-0 bg-n-8">
<svg width="72" height="72" viewBox="0 0 72 72">
<path
fill="#0E0C15"
stroke="#FFC876"
strokeWidth="2"
strokeOpacity=".8"
d="M-1176,1 L6.15,1 C13.89,1 21.35,3.89547 27.06,9.11714 L60.91,40.0541 C67.34,45.9271 71,54.2315 71,62.937 L71,444 C71,461.121 57.12,475 40,475 L-1176,475 C-1193.1209,475 -1207,461.121 -1207,444 L-1207,32 C-1207,14.8792 -1193.1208,1 -1176,1 Z"
/>
</svg>
</div>
</div>
</div>
</Section>
);
};
export default Community;

View File

@@ -1,101 +0,0 @@
import Section from "@/components/Section";
import Image from "@/components/Image";
type FeaturesProps = {};
const Features = ({}: FeaturesProps) => {
const content = [
{
id: "0",
title: "Seamless Integration",
text: "With smart automation and top-notch security, it's the perfect solution for teams looking to work smarter.",
},
{
id: "1",
title: "Smart Automation",
},
{
id: "2",
title: "Top-notch Security",
},
];
return (
<Section>
<div className="container">
<div className="-mb-16">
{[
{ id: "0", imageUrl: "/images/features/image-1.jpg" },
{ id: "1", imageUrl: "/images/features/image-1.jpg" },
{ id: "2", imageUrl: "/images/features/image-1.jpg" },
].map((item, index) => (
<div
className="mb-16 md:grid md:grid-cols-2 md:items-center lg:gap-20 xl:gap-40"
key={item.id}
>
<div
className={`mb-8 bg-n-6 rounded-3xl md:relative md:mb-0 ${
index % 2 === 0 ? "" : "md:order-1"
}`}
>
<Image
className="w-full rounded-3xl"
src={item.imageUrl}
width={550}
height={600}
alt="Image"
/>
<div
className={`hidden absolute top-5 -right-8 bottom-5 grid-cols-2 w-8 md:grid ${
index % 2 === 0
? "-right-8"
: "-left-8 rotate-180"
}`}
>
<div className="rounded-r-[1.25rem] bg-[#1B1B2E]"></div>
<div className="my-5 rounded-r-[1.25rem] bg-[#1B1B2E]/50"></div>
</div>
</div>
<div
className={
index % 2 === 0 ? "md:pl-16" : "md:pr-16"
}
>
<h2 className="h2 mb-4 md:mb-8">
Customization Options
</h2>
<ul className="">
{content.map((item) => (
<li
className="py-4 border-b border-n-1/5 md:py-6"
key={item.id}
>
<div className="flex items-center">
<Image
src="/images/check.svg"
width={24}
height={24}
alt="Check"
/>
<h6 className="body-2 ml-5">
{item.title}
</h6>
</div>
{item.text && (
<p className="body-2 mt-3 text-n-4">
{item.text}
</p>
)}
</li>
))}
</ul>
</div>
</div>
))}
</div>
</div>
</Section>
);
};
export default Features;

View File

@@ -1,101 +0,0 @@
import Section from "@/components/Section";
import Image from "@/components/Image";
type FeaturesProps = {};
const Features = ({}: FeaturesProps) => {
const content = [
{
id: "0",
title: "Seamless Integration",
text: "With smart automation and top-notch security, it's the perfect solution for teams looking to work smarter.",
},
{
id: "1",
title: "Smart Automation",
},
{
id: "2",
title: "Top-notch Security",
},
];
return (
<Section>
<div className="container">
<div className="-mb-16">
{[
{ id: "0", imageUrl: "/images/features/image-1.jpg" },
{ id: "1", imageUrl: "/images/features/image-1.jpg" },
{ id: "2", imageUrl: "/images/features/image-1.jpg" },
].map((item, index) => (
<div
className="mb-16 md:grid md:grid-cols-2 md:items-center lg:gap-20 xl:gap-40"
key={item.id}
>
<div
className={`mb-8 bg-n-6 rounded-3xl md:relative md:mb-0 ${
index % 2 === 0 ? "" : "md:order-1"
}`}
>
<Image
className="w-full rounded-3xl"
src={item.imageUrl}
width={550}
height={600}
alt="Image"
/>
<div
className={`hidden absolute top-5 -right-8 bottom-5 grid-cols-2 w-8 md:grid ${
index % 2 === 0
? "-right-8"
: "-left-8 rotate-180"
}`}
>
<div className="rounded-r-[1.25rem] bg-[#1B1B2E]"></div>
<div className="my-5 rounded-r-[1.25rem] bg-[#1B1B2E]/50"></div>
</div>
</div>
<div
className={
index % 2 === 0 ? "md:pl-16" : "md:pr-16"
}
>
<h2 className="h2 mb-4 md:mb-8">
Customization Options
</h2>
<ul className="">
{content.map((item) => (
<li
className="py-4 border-b border-n-1/5 md:py-6"
key={item.id}
>
<div className="flex items-center">
<Image
src="/images/check.svg"
width={24}
height={24}
alt="Check"
/>
<h6 className="body-2 ml-5">
{item.title}
</h6>
</div>
{item.text && (
<p className="body-2 mt-3 text-n-4">
{item.text}
</p>
)}
</li>
))}
</ul>
</div>
</div>
))}
</div>
</div>
</Section>
);
};
export default Features;

View File

@@ -1,38 +0,0 @@
import Heading from "@/components/Heading";
import Image from "@/components/Image";
import Section from "@/components/Section";
type HeroProps = {};
const Hero = ({}: HeroProps) => (
<Section className="overflow-hidden md:-mb-10 xl:-mb-20">
<div className="container relative z-2 md:grid md:grid-cols-2 md:items-center md:gap-10 lg:gap-48">
<Heading
className="md:mt-12 lg:max-w-[30rem] lg:mt-20"
textAlignClassName="md:text-left"
titleLarge="Main features of Brainwave"
textLarge="Here are some of the core features of Brainwavethat make it stand out from other chat applications"
/>
<div className="relative">
<Image
className="w-full md:min-w-[125%] xl:min-w-full"
src="/images/features/features.png"
width={547}
height={588}
alt="Features"
/>
<div className="absolute top-0 left-1/2 w-full">
<Image
className="w-full"
src="/images/grid.png"
width={550}
height={550}
alt="Grid"
/>
</div>
</div>
</div>
</Section>
);
export default Hero;

View File

@@ -1,38 +0,0 @@
import Heading from "@/components/Heading";
import Image from "@/components/Image";
import Section from "@/components/Section";
type HeroProps = {};
const Hero = ({}: HeroProps) => (
<Section className="overflow-hidden md:-mb-10 xl:-mb-20">
<div className="container relative z-2 md:grid md:grid-cols-2 md:items-center md:gap-10 lg:gap-48">
<Heading
className="md:mt-12 lg:max-w-[30rem] lg:mt-20"
textAlignClassName="md:text-left"
titleLarge="Main features of Brainwave"
textLarge="Here are some of the core features of Brainwavethat make it stand out from other chat applications"
/>
<div className="relative">
<Image
className="w-full md:min-w-[125%] xl:min-w-full"
src="/images/features/features.png"
width={547}
height={588}
alt="Features"
/>
<div className="absolute top-0 left-1/2 w-full">
<Image
className="w-full"
src="/images/grid.png"
width={550}
height={550}
alt="Grid"
/>
</div>
</div>
</div>
</Section>
);
export default Hero;

View File

@@ -1,24 +0,0 @@
"use client";
import Layout from "@/components/Layout";
import Services from "@/components/Services";
import Join from "@/components/Join";
import Hero from "./Hero";
import Benefits from "./Benefits";
import Features from "./Features";
import Community from "./Community";
const FeaturesPage = () => {
return (
<Layout>
<Hero />
<Benefits />
<Features />
<Community />
<Services containerClassName="md:pb-10" />
<Join />
</Layout>
);
};
export default FeaturesPage;

View File

@@ -1,24 +0,0 @@
"use client";
import Layout from "@/components/Layout";
import Services from "@/components/Services";
import Join from "@/components/Join";
import Hero from "./Hero";
import Benefits from "./Benefits";
import Features from "./Features";
import Community from "./Community";
const FeaturesPage = () => {
return (
<Layout>
<Hero />
<Benefits />
<Features />
<Community />
<Services containerClassName="md:pb-10" />
<Join />
</Layout>
);
};
export default FeaturesPage;

View File

@@ -1,165 +0,0 @@
import { useRef, useState } from "react";
import { Link } from "react-router-dom";
// import { Splide, SplideTrack, SplideSlide } from "@splidejs/react-splide";
import Section from "../../../components/Section";
import Heading from "../../../components/Heading/index.js";
import Image from "../../../components/Image";
// 简化版数据避免依赖外部mock文件
const benefits = [
{
id: "0",
title: "智能问答",
text: "让用户能够快速找到问题答案,无需在多个信息源中搜索,提升投研效率。",
backgroundUrl: "/images/benefits/card-1.svg",
iconUrl: "/images/benefits/icon-1.svg",
imageUrl: "/images/benefits/image-2.png",
light: true,
},
{
id: "1",
title: "持续学习",
text: "系统采用自然语言处理技术理解用户查询,提供准确相关的投研分析结果。",
backgroundUrl: "/images/benefits/card-2.svg",
iconUrl: "/images/benefits/icon-2.svg",
imageUrl: "/images/benefits/image-2.png",
},
{
id: "2",
title: "全域连接",
text: "随时随地连接AI投研助手支持多设备访问让专业分析更便捷。",
backgroundUrl: "/images/benefits/card-3.svg",
iconUrl: "/images/benefits/icon-3.svg",
imageUrl: "/images/benefits/image-2.png",
},
{
id: "3",
title: "快速响应",
text: "毫秒级响应速度,让用户快速获得投研洞察,把握市场先机。",
backgroundUrl: "/images/benefits/card-4.svg",
iconUrl: "/images/benefits/icon-4.svg",
imageUrl: "/images/benefits/image-2.png",
light: true,
},
{
id: "4",
title: "深度分析",
text: "基于海量数据训练的专业投研模型,提供超越传统分析工具的深度洞察。",
backgroundUrl: "/images/benefits/card-5.svg",
iconUrl: "/images/benefits/icon-1.svg",
imageUrl: "/images/benefits/image-2.png",
},
{
id: "5",
title: "智能预测",
text: "结合机器学习算法,为投资决策提供智能预测和风险评估建议。",
backgroundUrl: "/images/benefits/card-6.svg",
iconUrl: "/images/benefits/icon-2.svg",
imageUrl: "/images/benefits/image-2.png",
},
];
const Benefits = () => {
const [activeIndex, setActiveIndex] = useState(0);
const handleClick = (index) => {
setActiveIndex(index);
};
return (
<Section className="overflow-hidden bg-n-8">
<div className="container relative z-2">
<Heading
className="md:max-w-md lg:max-w-2xl"
title="智能投研,让分析更简单"
text="利用先进的人工智能技术,为您提供专业的投资研究分析服务"
/>
{/* 简化版网格布局暂时不使用Splide */}
<div className="max-w-[24rem] md:max-w-none grid grid-cols-1 md:grid-cols-3 gap-6">
{benefits.map((item, index) => (
<div key={item.id}>
<Link
className="block relative p-0.5 bg-no-repeat bg-[length:100%_100%] md:max-w-[24rem] rounded-xl"
to="/features"
style={{
backgroundImage: `url(${item.backgroundUrl})`,
}}
>
<div className="relative z-2 flex flex-col h-[22.625rem] p-[2.375rem] pointer-events-none">
<h5 className="h5 mb-5">
{item.title}
</h5>
<p className="body-2 mb-6 text-n-3">
{item.text}
</p>
<div className="flex items-center mt-auto">
<Image
className=""
src={item.iconUrl}
width={48}
height={48}
alt={item.title}
/>
<div className="ml-auto font-code text-xs font-bold text-n-1 uppercase tracking-wider">
了解更多
</div>
<svg
className="ml-5 fill-n-1"
width="24"
height="24"
>
<path d="M8.293 5.293a1 1 0 0 1 1.414 0l6 6a1 1 0 0 1 0 1.414l-6 6a1 1 0 0 1-1.414-1.414L13.586 12 8.293 6.707a1 1 0 0 1 0-1.414z" />
</svg>
</div>
</div>
{item.light && (
<div className="absolute top-0 left-1/4 w-full aspect-square bg-radial-gradient from-[#28206C] to-[#28206C]/0 to-70% pointer-events-none"></div>
)}
<div
className="absolute inset-0.5 bg-n-8 rounded-xl"
>
<div className="absolute inset-0 opacity-0 transition-opacity hover:opacity-10">
{item.imageUrl && (
<Image
className="w-full h-full object-cover rounded-xl"
src={item.imageUrl}
width={380}
height={362}
alt={item.title}
/>
)}
</div>
</div>
</Link>
</div>
))}
</div>
{/* 指示器 */}
<div className="flex mt-12 -mx-2 md:mt-15 lg:justify-center xl:mt-20">
{benefits.map((item, index) => (
<button
className="relative w-6 h-6 mx-2"
onClick={() => handleClick(index)}
key={item.id}
>
<span
className={`absolute inset-0 bg-conic-gradient rounded-full transition-opacity ${
index === activeIndex
? "opacity-100"
: "opacity-0"
}`}
></span>
<span className="absolute inset-0.25 bg-n-8 rounded-full">
<span className="absolute inset-2 bg-n-1 rounded-full"></span>
</span>
</button>
))}
</div>
</div>
</Section>
);
};
export default Benefits;

View File

@@ -1,130 +0,0 @@
import Section from "@/components/Section";
import Button from "@/components/Button";
import Image from "@/components/Image";
import { text, content, apps } from "@/mocks/collaboration";
type CollaborationProps = {};
const Collaboration = ({}: CollaborationProps) => {
return (
<Section crosses>
<div className="container lg:flex">
<div className="max-w-[25rem]">
<h2 className="h2 mb-4 md:mb-8">
AI chat app for seamless collaboration
</h2>
<ul className="max-w-[22.5rem] mb-10 md:mb-14">
{content.map((item) => (
<li className="mb-3 py-3" key={item.id}>
<div className="flex items-center">
<Image
src="/images/check.svg"
width={24}
height={24}
alt="Check"
/>
<h6 className="body-2 ml-5">
{item.title}
</h6>
</div>
{item.text && (
<p className="body-2 mt-3 text-n-4">
{item.text}
</p>
)}
</li>
))}
</ul>
<Button>Try it now</Button>
</div>
<div className="mt-15 lg:mt-0 lg:ml-auto xl:w-[37.5rem]">
<div className="relative lg:w-[22.5rem] lg:mx-auto">
<p className="body-2 mb-4 text-n-4 md:mb-16 lg:mb-32">
{text}
</p>
<div className="relative left-1/2 flex w-[22.5rem] aspect-square border border-n-6 rounded-full -translate-x-1/2 scale-75 md:scale-100">
<div className="flex w-60 aspect-square m-auto border border-n-6 rounded-full">
<div className="w-[5.75rem] aspect-square m-auto p-[0.1875rem] bg-conic-gradient rounded-full">
<div className="flex items-center justify-center w-full h-full bg-n-8 rounded-full">
<Image
src="/images/brainwave-symbol.svg"
width={48}
height={48}
alt="Brainwave"
/>
</div>
</div>
</div>
<ul>
{apps.map((app, index) => (
<li
className={`absolute top-0 left-1/2 h-1/2 -ml-[1.625rem] ${
index === 1 && "rotate-[45deg]"
} ${index === 2 && "rotate-[90deg]"} ${
index === 3 && "rotate-[135deg]"
} ${index === 4 && "rotate-[180deg]"} ${
index === 5 && "rotate-[225deg]"
} ${index === 6 && "rotate-[270deg]"} ${
index === 7 && "rotate-[315deg]"
} origin-bottom`}
key={app.id}
>
<div
className={`relative -top-[1.625rem] flex w-[3.25rem] h-[3.25rem] bg-n-7 border border-n-1/15 rounded-xl ${
index === 1 && "-rotate-[45deg]"
} ${
index === 2 && "-rotate-[90deg]"
} ${
index === 3 &&
"-rotate-[135deg]"
} ${
index === 4 &&
"-rotate-[180deg]"
} ${
index === 5 &&
"-rotate-[225deg]"
} ${
index === 6 &&
"-rotate-[270deg]"
} ${
index === 7 &&
"-rotate-[315deg]"
}`}
>
<Image
className="m-auto"
src={app.icon}
width={app.width}
height={app.height}
alt={app.title}
/>
</div>
</li>
))}
</ul>
<div className="hidden absolute top-1/2 right-full w-[32.625rem] -mt-1 mr-10 pointer-events-none xl:block">
<Image
src="/images/collaboration/curve-1.svg"
width={522}
height={182}
alt="Curve 1"
/>
</div>
<div className="hidden absolute top-1/2 left-full w-[10.125rem] -mt-1 ml-10 pointer-events-none xl:block">
<Image
src="/images/collaboration/curve-2.svg"
width={162}
height={76}
alt="Curve 2"
/>
</div>
</div>
</div>
</div>
</div>
</Section>
);
};
export default Collaboration;

View File

@@ -1,130 +0,0 @@
import Section from "@/components/Section";
import Button from "@/components/Button";
import Image from "@/components/Image";
import { text, content, apps } from "@/mocks/collaboration";
type CollaborationProps = {};
const Collaboration = ({}: CollaborationProps) => {
return (
<Section crosses>
<div className="container lg:flex">
<div className="max-w-[25rem]">
<h2 className="h2 mb-4 md:mb-8">
AI chat app for seamless collaboration
</h2>
<ul className="max-w-[22.5rem] mb-10 md:mb-14">
{content.map((item) => (
<li className="mb-3 py-3" key={item.id}>
<div className="flex items-center">
<Image
src="/images/check.svg"
width={24}
height={24}
alt="Check"
/>
<h6 className="body-2 ml-5">
{item.title}
</h6>
</div>
{item.text && (
<p className="body-2 mt-3 text-n-4">
{item.text}
</p>
)}
</li>
))}
</ul>
<Button>Try it now</Button>
</div>
<div className="mt-15 lg:mt-0 lg:ml-auto xl:w-[37.5rem]">
<div className="relative lg:w-[22.5rem] lg:mx-auto">
<p className="body-2 mb-4 text-n-4 md:mb-16 lg:mb-32">
{text}
</p>
<div className="relative left-1/2 flex w-[22.5rem] aspect-square border border-n-6 rounded-full -translate-x-1/2 scale-75 md:scale-100">
<div className="flex w-60 aspect-square m-auto border border-n-6 rounded-full">
<div className="w-[5.75rem] aspect-square m-auto p-[0.1875rem] bg-conic-gradient rounded-full">
<div className="flex items-center justify-center w-full h-full bg-n-8 rounded-full">
<Image
src="/images/brainwave-symbol.svg"
width={48}
height={48}
alt="Brainwave"
/>
</div>
</div>
</div>
<ul>
{apps.map((app, index) => (
<li
className={`absolute top-0 left-1/2 h-1/2 -ml-[1.625rem] ${
index === 1 && "rotate-[45deg]"
} ${index === 2 && "rotate-[90deg]"} ${
index === 3 && "rotate-[135deg]"
} ${index === 4 && "rotate-[180deg]"} ${
index === 5 && "rotate-[225deg]"
} ${index === 6 && "rotate-[270deg]"} ${
index === 7 && "rotate-[315deg]"
} origin-bottom`}
key={app.id}
>
<div
className={`relative -top-[1.625rem] flex w-[3.25rem] h-[3.25rem] bg-n-7 border border-n-1/15 rounded-xl ${
index === 1 && "-rotate-[45deg]"
} ${
index === 2 && "-rotate-[90deg]"
} ${
index === 3 &&
"-rotate-[135deg]"
} ${
index === 4 &&
"-rotate-[180deg]"
} ${
index === 5 &&
"-rotate-[225deg]"
} ${
index === 6 &&
"-rotate-[270deg]"
} ${
index === 7 &&
"-rotate-[315deg]"
}`}
>
<Image
className="m-auto"
src={app.icon}
width={app.width}
height={app.height}
alt={app.title}
/>
</div>
</li>
))}
</ul>
<div className="hidden absolute top-1/2 right-full w-[32.625rem] -mt-1 mr-10 pointer-events-none xl:block">
<Image
src="/images/collaboration/curve-1.svg"
width={522}
height={182}
alt="Curve 1"
/>
</div>
<div className="hidden absolute top-1/2 left-full w-[10.125rem] -mt-1 ml-10 pointer-events-none xl:block">
<Image
src="/images/collaboration/curve-2.svg"
width={162}
height={76}
alt="Curve 2"
/>
</div>
</div>
</div>
</div>
</div>
</Section>
);
};
export default Collaboration;

View File

@@ -1,99 +0,0 @@
import { useRef, useState } from "react";
import Section from "../../../components/Section";
import Button from "../../../components/Button";
import Image from "../../../components/Image";
import Notification from "../../../components/Notification";
// 简化版特性数据
const features = [
{
id: "0",
title: "智能投研分析",
text: "利用先进的AI技术为您提供全面的投资研究分析包括市场趋势、公司基本面、技术指标等多维度分析帮助您做出更明智的投资决策。",
imageUrl: "/images/features/features.png",
iconUrl: "/images/icons/recording-01.svg",
notification: "AI分析完成 - 发现3个潜在投资机会",
},
{
id: "1",
title: "实时市场监控",
text: "24/7全天候监控全球金融市场动态实时捕捉市场变化和投资机会。智能预警系统会在关键时刻及时提醒您确保不错过任何重要的投资时机。",
imageUrl: "/images/features/image-1.jpg",
iconUrl: "/images/icons/chrome-cast.svg",
notification: "市场异动提醒 - 科技股出现上涨信号",
},
];
const Features = () => {
const [currentFeature, setCurrentFeature] = useState(0);
return (
<Section
className="py-10 md:pb-20 lg:pt-16 lg:pb-32 xl:pb-40 overflow-hidden bg-n-7"
customPaddings
>
<div className="container relative z-2">
{features.map((item, index) => (
<div key={item.id} className={index === currentFeature ? "block" : "hidden"}>
<div className="lg:flex">
<div className="lg:flex lg:flex-col lg:items-start lg:max-w-[18.75rem] lg:mr-auto">
<h2 className="h2 mb-6">
{item.title}
</h2>
<p className="body-2 mb-10 text-n-3">
{item.text}
</p>
<Button className="" onClick={null} px="px-7">
了解工作原理
</Button>
</div>
<div className="relative h-[27.5rem] border border-n-1/20 rounded-3xl md:rounded-[2.5rem] lg:flex-1 lg:max-w-[34.625rem] lg:h-[34.5rem] lg:ml-24 xl:h-[36rem] mt-10 lg:mt-0">
<div className="absolute top-[8.5rem] -left-[2rem] w-[21rem] md:w-[25.25rem] md:top-[6.4rem] md:-left-[4.5rem] lg:top-[12rem] lg:-left-[3rem] xl:top-[7.625rem] xl:-left-[4.5rem] xl:w-[32.75rem]">
<Image
className="w-full rounded-xl"
src={item.imageUrl}
width={512}
height={512}
alt="Feature"
/>
</div>
<div className="absolute left-4 right-4 bottom-4 bg-n-8/95 md:left-8 md:right-8 md:bottom-8 rounded-xl">
<Notification
className=""
title={item.notification}
/>
</div>
<div className="absolute top-6 right-6 flex items-center justify-center w-15 h-15 bg-n-1 rounded-full xl:top-8 xl:right-8">
<Image
className=""
src={item.iconUrl}
width={24}
height={24}
alt="Icon"
/>
</div>
<div className="hidden absolute top-0 left-full ml-5 w-full h-full bg-n-8/50 border border-n-1/10 rounded-[2.5rem] md:block"></div>
</div>
</div>
</div>
))}
{/* 简化版导航 */}
<div className="flex justify-center mt-12 gap-4">
{features.map((_, index) => (
<button
key={index}
className={`w-3 h-3 rounded-full transition-colors ${
index === currentFeature ? 'bg-color-1' : 'bg-n-4'
}`}
onClick={() => setCurrentFeature(index)}
/>
))}
</div>
</div>
</Section>
);
};
export default Features;

View File

@@ -1,91 +0,0 @@
import { useRef } from "react";
import { Splide, SplideTrack, SplideSlide } from "@splidejs/react-splide";
import Section from "@/components/Section";
import Button from "@/components/Button";
import Image from "@/components/Image";
import Notification from "@/components/Notification";
import { features } from "@/mocks/features";
import Arrows from "@/components/Arrows";
type FeaturesProps = {};
const Features = ({}: FeaturesProps) => {
const ref = useRef<any>(null);
return (
<Section
className="py-10 md:pb-20 lg:pt-16 lg:pb-32 xl:pb-40 overflow-hidden"
customPaddings
>
<div className="container relative z-2">
<Splide
className="splide-custom splide-visible"
options={{
type: "fade",
rewind: true,
pagination: false,
}}
hasTrack={false}
ref={ref}
>
<SplideTrack>
{features.map((item) => (
<SplideSlide key={item.id}>
<div className="lg:flex" key={item.id}>
<div className="lg:flex lg:flex-col lg:items-start lg:max-w-[18.75rem] lg:mr-auto">
<h2 className="h2 mb-6">
{item.title}
</h2>
<p className="body-2 mb-10 text-n-3">
{item.text}
</p>
<Button>See how it work</Button>
</div>
<Arrows
className="my-10 lg:hidden"
prevClassName="mr-3"
onPrev={() => ref.current?.go("<")}
onNext={() => ref.current?.go(">")}
/>
<div className="relative h-[27.5rem] border border-n-1/20 rounded-3xl md:rounded-[2.5rem] lg:flex-1 lg:max-w-[34.625rem] lg:h-[34.5rem] lg:ml-24 xl:h-[36rem]">
<div className="absolute top-[8.5rem] -left-[2rem] w-[21rem] md:w-[25.25rem] md:top-[6.4rem] md:-left-[4.5rem] lg:top-[12rem] lg:-left-[3rem] xl:top-[7.625rem] xl:-left-[4.5rem] xl:w-[32.75rem]">
<Image
className="w-full"
src={item.imageUrl}
width={512}
height={512}
alt="Figure"
/>
</div>
<Notification
className="absolute left-4 right-4 bottom-4 bg-n-8/95 md:left-8 md:right-8 md:bottom-8"
title={item.notification}
/>
<div className="absolute top-6 right-6 flex items-center justify-center w-15 h-15 bg-n-1 rounded-full xl:top-8 xl:right-8">
<Image
src={item.iconUrl}
width={24}
height={24}
alt="Icon"
/>
</div>
<div className="hidden absolute top-0 left-full ml-5 w-full h-full bg-n-8/50 border border-n-1/10 rounded-[2.5rem] md:block"></div>
</div>
</div>
</SplideSlide>
))}
</SplideTrack>
<Arrows
className="hidden -mt-12 lg:flex"
prevClassName="mr-3"
onPrev={() => ref.current?.go("<")}
onNext={() => ref.current?.go(">")}
/>
</Splide>
</div>
</Section>
);
};
export default Features;

View File

@@ -1,236 +0,0 @@
import { useEffect, useRef, useState } from "react";
// import { MouseParallax, ScrollParallax } from "react-just-parallax";
import Section from "../../../components/Section";
import Button from "../../../components/Button";
import Image from "../../../components/Image";
import Generating from "../../../components/Generating";
import Notification from "../../../components/Notification";
import Logos from "../../../components/Logos";
const Hero = () => {
const [mounted, setMounted] = useState(false);
useEffect(() => {
setMounted(true);
}, []);
const parallaxRef = useRef(null);
return (
<Section
className="-mt-[4.75rem] pt-[8.25rem] pb-4 overflow-hidden md:pt-[9.75rem] md:pb-[4.8rem] lg:-mt-[5.25rem] lg:-mb-40 lg:pt-[12.25rem] lg:pb-[13.8rem]"
crosses
crossesOffset="lg:translate-y-[5.25rem]"
customPaddings
>
{/* 添加深色渐变背景 */}
<div className="absolute inset-0 bg-gradient-to-br from-n-8 via-n-7 to-n-6"></div>
<div className="absolute inset-0 bg-[radial-gradient(ellipse_at_center,rgba(172,106,255,0.1)_0%,transparent_70%)]"></div>
<div className="container relative" ref={parallaxRef}>
<div
className="relative z-1 max-w-[62rem] mx-auto mb-[3.875rem] text-center md:mb-20 lg:mb-[6.25rem]"
style={{ position: 'relative', zIndex: 10 }}
>
<h1
className="h1 mb-6"
style={{
color: '#FFFFFF',
fontSize: '3.75rem',
lineHeight: '4.5rem',
fontWeight: '600',
marginBottom: '24px'
}}
>
探索&nbsp;
<span style={{
background: 'linear-gradient(to right, #AC6AFF, #FFC876)',
WebkitBackgroundClip: 'text',
WebkitTextFillColor: 'transparent',
backgroundClip: 'text'
}}>
AI投研
</span>
&nbsp;的无限可能性 {" "}
<span className="inline-block relative">
<span style={{
background: 'linear-gradient(to right, #FFC876, #AC6AFF)',
WebkitBackgroundClip: 'text',
WebkitTextFillColor: 'transparent',
backgroundClip: 'text'
}}>
价值前沿
</span>
<Image
className="absolute top-full left-0 w-full xl:-mt-2"
src="/images/curve.png"
width={624}
height={28}
alt="Curve"
/>
</span>
</h1>
<p
className="body-1 max-w-3xl mx-auto mb-6 lg:mb-8"
style={{
color: '#CAC6DD',
fontSize: '1.25rem',
lineHeight: '2rem',
marginBottom: '32px',
maxWidth: '48rem',
margin: '0 auto 32px'
}}
>
释放AI的力量升级您的投研效率
体验专业的开放式AI投研平台超越传统分析工具
</p>
<Button href="/community" white className="" onClick={null} px="px-7">
开始使用
</Button>
</div>
<div className="relative max-w-[23.25rem] mx-auto md:max-w-5xl xl:mb-24">
<div className="relative z-1 p-0.5 rounded-2xl bg-conic-gradient">
<div className="relative bg-n-8 rounded-[0.875rem]">
<div className="h-[1.375rem] bg-[#43435C] rounded-t-[0.875rem]"></div>
<div className="aspect-[33/40] rounded-b-[0.875rem] overflow-hidden md:aspect-[688/490] lg:aspect-[1024/490]">
<Image
className="w-full scale-[1.7] translate-y-[8%] md:scale-[1] md:-translate-y-[10.5%] lg:-translate-y-[23.5%]"
src="/images/hero/robot.jpg"
width={1024}
height={490}
alt="AI"
/>
</div>
<Generating className="absolute left-4 right-4 bottom-5 md:left-1/2 md:right-auto md:bottom-8 md:w-[30.5rem] md:-translate-x-1/2" />
{/* 简化版本暂时不使用ScrollParallax */}
<div className="hidden absolute -left-[5.5rem] bottom-[7.625rem] px-1 py-1 bg-[#474060]/40 backdrop-blur border border-n-1/10 rounded-2xl xl:flex">
{[
"/images/icons/home-smile.svg",
"/images/icons/file-02.svg",
"/images/icons/search-md.svg",
"/images/icons/plus-square.svg",
].map((icon, index) => (
<div className="p-5" key={index}>
<Image
className=""
src={icon}
width={24}
height={25}
alt={`Icon ${index}`}
/>
</div>
))}
</div>
<div className="hidden absolute -right-[5.5rem] bottom-[11.25rem] w-[18.375rem] xl:flex">
<Notification
className=""
title="AI投研分析完成"
/>
</div>
</div>
</div>
<div className="relative z-1 h-6 mx-2.5 bg-[#1B1B2E] shadow-xl rounded-b-[1.25rem] lg:h-6 lg:mx-8"></div>
<div className="relative z-1 h-6 mx-6 bg-[#1B1B2E]/70 shadow-xl rounded-b-[1.25rem] lg:h-6 lg:mx-20"></div>
<div className="absolute -top-[54%] left-1/2 w-[234%] -translate-x-1/2 md:-top-[46%] md:w-[138%] lg:-top-[104%]">
<Image
className="w-full"
src="/images/hero/background.jpg"
width={1440}
height={1800}
alt="Hero"
/>
</div>
<div className="absolute -top-[42.375rem] left-1/2 w-[78rem] aspect-square border border-n-2/5 rounded-full -translate-x-1/2 md:-top-[38.5rem] xl:-top-[32rem]">
<div className="absolute top-1/2 left-1/2 w-[65.875rem] aspect-square border border-n-2/10 rounded-full -translate-x-1/2 -translate-y-1/2"></div>
<div className="absolute top-1/2 left-1/2 w-[51.375rem] aspect-square border border-n-2/10 rounded-full -translate-x-1/2 -translate-y-1/2"></div>
<div className="absolute top-1/2 left-1/2 w-[36.125rem] aspect-square border border-n-2/10 rounded-full -translate-x-1/2 -translate-y-1/2"></div>
<div className="absolute top-1/2 left-1/2 w-[23.125rem] aspect-square border border-n-2/10 rounded-full -translate-x-1/2 -translate-y-1/2"></div>
{/* 浮动装饰点 */}
<div className="absolute bottom-1/2 left-1/2 w-0.25 h-1/2 origin-bottom rotate-[46deg]">
<div
className={`w-2 h-2 -ml-1 -mt-36 bg-gradient-to-b from-[#DD734F] to-[#1A1A32] rounded-full transition-transform duration-500 ease-out ${
mounted
? "translate-y-0 opacity-100"
: "translate-y-10 opacity-0"
}`}
></div>
</div>
<div className="absolute bottom-1/2 left-1/2 w-0.25 h-1/2 origin-bottom -rotate-[56deg]">
<div
className={`w-4 h-4 -ml-1 -mt-32 bg-gradient-to-b from-[#DD734F] to-[#1A1A32] rounded-full transition-transform duration-500 ease-out ${
mounted
? "translate-y-0 opacity-100"
: "translate-y-10 opacity-0"
}`}
></div>
</div>
<div className="absolute bottom-1/2 left-1/2 w-0.25 h-1/2 origin-bottom rotate-[54deg]">
<div
className={`hidden w-4 h-4 -ml-1 mt-[12.9rem] bg-gradient-to-b from-[#B9AEDF] to-[#1A1A32] rounded-full xl:block transition-transform duration-500 ease-out ${
mounted
? "translate-y-0 opacity-100"
: "translate-y-10 opacity-0"
}`}
></div>
</div>
<div className="absolute bottom-1/2 left-1/2 w-0.25 h-1/2 origin-bottom -rotate-[65deg]">
<div
className={`w-3 h-3 -ml-1.5 mt-52 bg-gradient-to-b from-[#B9AEDF] to-[#1A1A32] rounded-full transition-transform duration-500 ease-out ${
mounted
? "translate-y-0 opacity-100"
: "translate-y-10 opacity-0"
}`}
></div>
</div>
<div className="absolute bottom-1/2 left-1/2 w-0.25 h-1/2 origin-bottom -rotate-[85deg]">
<div
className={`w-6 h-6 -ml-3 -mt-3 bg-gradient-to-b from-[#88E5BE] to-[#1A1A32] rounded-full transition-transform duration-500 ease-out ${
mounted
? "translate-y-0 opacity-100"
: "translate-y-10 opacity-0"
}`}
></div>
</div>
<div className="absolute bottom-1/2 left-1/2 w-0.25 h-1/2 origin-bottom rotate-[70deg]">
<div
className={`w-6 h-6 -ml-3 -mt-3 bg-gradient-to-b from-[#88E5BE] to-[#1A1A32] rounded-full transition-transform duration-500 ease-out ${
mounted
? "translate-y-0 opacity-100"
: "translate-y-10 opacity-0"
}`}
></div>
</div>
</div>
</div>
<Logos className="hidden relative z-10 mt-20 lg:block" />
</div>
<div className="hidden absolute top-[55.25rem] left-10 right-10 h-0.25 bg-n-6 pointer-events-none xl:block"></div>
<svg
className="hidden absolute top-[54.9375rem] left-[2.1875rem] z-2 pointer-events-none xl:block"
width="11"
height="11"
fill="none"
>
<path
d="M7 1a1 1 0 0 0-1-1H5a1 1 0 0 0-1 1v2a1 1 0 0 1-1 1H1a1 1 0 0 0-1 1v1a1 1 0 0 0 1 1h2a1 1 0 0 1 1 1v2a1 1 0 0 0 1 1h1a1 1 0 0 0 1-1V8a1 1 0 0 1 1-1h2a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1H8a1 1 0 0 1-1-1V1z"
fill="#ada8c4"
/>
</svg>
<svg
className="hidden absolute top-[54.9375rem] right-[2.1875rem] z-2 pointer-events-none xl:block"
width="11"
height="11"
fill="none"
>
<path
d="M7 1a1 1 0 0 0-1-1H5a1 1 0 0 0-1 1v2a1 1 0 0 1-1 1H1a1 1 0 0 0-1 1v1a1 1 0 0 0 1 1h2a1 1 0 0 1 1 1v2a1 1 0 0 0 1 1h1a1 1 0 0 0 1-1V8a1 1 0 0 1 1-1h2a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1H8a1 1 0 0 1-1-1V1z"
fill="#ada8c4"
/>
</svg>
</Section>
);
};
export default Hero;

View File

@@ -1,152 +0,0 @@
import { useRef, useState } from "react";
import { Splide, SplideTrack, SplideSlide } from "@splidejs/react-splide";
import Section from "@/components/Section";
import Image from "@/components/Image";
import Button from "@/components/Button";
import Tagline from "@/components/Tagline";
import Arrows from "@/components/Arrows";
import { howItWorks } from "@/mocks/how-it-works";
type HowItWorksProps = {};
const HowItWorks = ({}: HowItWorksProps) => {
const [activeIndex, setActiveIndex] = useState<number>(0);
const ref = useRef<any>(null);
const handleClick = (index: number) => {
setActiveIndex(index);
ref.current?.go(index);
};
return (
<Section className="lg:-mb-16" crosses>
<div className="container">
<Splide
className="splide-custom"
options={{
type: "fade",
rewind: true,
pagination: false,
}}
hasTrack={false}
ref={ref}
>
<SplideTrack>
{howItWorks.map((item, index) => (
<SplideSlide key={item.id}>
<div className="lg:flex lg:flex-row-reverse lg:items-center">
<div className="">
<Tagline className="mb-4 lg:mb-6">
How it work: 0{index + 1}.
</Tagline>
<h2 className="h2 mb-4 lg:mb-6">
{item.title}
</h2>
<p className="body-2 mb-10 text-n-3">
{item.text}
</p>
<Button href="/login">
Connect now
</Button>
<Arrows
className="my-10 lg:hidden"
prevClassName="mr-3"
onPrev={() => ref.current?.go("<")}
onNext={() => ref.current?.go(">")}
/>
</div>
<div className="relative lg:w-[29.375rem] lg:flex-shrink-0 lg:mr-[7.125rem] xl:w-[34.375rem] xl:mr-40">
<div className="pt-0.25 pl-0.25 overflow-hidden bg-gradient-to-tl from-n-1/0 via-n-1/0 to-n-1/15 rounded-3xl">
<div className="h-[30.5rem] bg-n-7 rounded-[1.4375rem] xl:h-[35.625rem]">
<Image
className="w-full h-full object-contain"
src={item.image}
width={550}
height={570}
alt={item.title}
/>
<div className="absolute left-4 right-4 bottom-4 flex items-center h-16 px-5 bg-n-8 border border-n-1/10 rounded-xl lg:left-6 lg:right-6 lg:bottom-6">
<div className="flex items-center justify-center w-6 h-6 mr-5 bg-color-1 rounded-full">
<svg
className="w-2.5 h-2.5 fill-n-1"
viewBox="0 0 10 10"
>
<path d="M5 0a1 1 0 0 1 .993.883L6 1v3h3a1 1 0 0 1 .117 1.993L9 6H6v3a1 1 0 0 1-1.993.117L4 9V6H1a1 1 0 0 1-.117-1.993L1 4h3V1a1 1 0 0 1 1-1z" />
</svg>
</div>
<div className="text-base text-n-3/75">
Ask anything
</div>
<div className="w-6 h-6 ml-auto opacity-50">
<Image
className="w-full"
src="/images/icons/recording-01.svg"
width={24}
height={24}
alt="Recording"
/>
</div>
</div>
</div>
</div>
<div className="absolute -right-6 top-8 bottom-8 w-6 bg-[#1B1B2E] rounded-r-3xl"></div>
<div className="absolute -right-12 top-16 bottom-16 w-6 bg-[#1B1B2E]/50 rounded-r-3xl"></div>
</div>
</div>
</SplideSlide>
))}
</SplideTrack>
<Arrows
className="hidden justify-center mt-12 lg:flex lg:mt-15 xl:hidden"
prevClassName="mr-3"
onPrev={() => ref.current?.go("<")}
onNext={() => ref.current?.go(">")}
/>
<div className="absolute top-0 -left-[10rem] w-[29.5rem] h-[29.5rem] mix-blend-color-dodge opacity-20 pointer-events-none">
<Image
className="absolute top-1/2 left-1/2 w-[55.5rem] max-w-[55.5rem] h-[61.5rem] -translate-x-1/2 -translate-y-1/2"
src="/images/how-it-works/gradient.png"
width={984}
height={984}
alt="Gradient"
/>
</div>
<div className="hidden grid-cols-4 gap-6 mt-20 xl:grid">
{howItWorks.map((item, index) => (
<div
className="group cursor-pointer"
onClick={() => handleClick(index)}
key={item.id}
>
<div
className={`h-[0.125rem] mb-10 transition-colors ${
index === activeIndex
? "bg-color-1"
: "bg-[#D9D9D9]/10 group-hover:bg-[#D9D9D9]/50"
}`}
></div>
<div className="tagline mb-1 text-n-3">
0{index + 1}.
</div>
<h2 className="mb-[0.625rem] text-2xl leading-8">
{item.title}
</h2>
<p
className={`body-2 text-n-3 line-clamp-3 transition-opacity ${
index !== activeIndex && "opacity-0"
}`}
>
{item.text}
</p>
</div>
))}
</div>
</Splide>
</div>
</Section>
);
};
export default HowItWorks;

View File

@@ -1,152 +0,0 @@
import { useRef, useState } from "react";
import { Splide, SplideTrack, SplideSlide } from "@splidejs/react-splide";
import Section from "@/components/Section";
import Image from "@/components/Image";
import Button from "@/components/Button";
import Tagline from "@/components/Tagline";
import Arrows from "@/components/Arrows";
import { howItWorks } from "@/mocks/how-it-works";
type HowItWorksProps = {};
const HowItWorks = ({}: HowItWorksProps) => {
const [activeIndex, setActiveIndex] = useState<number>(0);
const ref = useRef<any>(null);
const handleClick = (index: number) => {
setActiveIndex(index);
ref.current?.go(index);
};
return (
<Section className="lg:-mb-16" crosses>
<div className="container">
<Splide
className="splide-custom"
options={{
type: "fade",
rewind: true,
pagination: false,
}}
hasTrack={false}
ref={ref}
>
<SplideTrack>
{howItWorks.map((item, index) => (
<SplideSlide key={item.id}>
<div className="lg:flex lg:flex-row-reverse lg:items-center">
<div className="">
<Tagline className="mb-4 lg:mb-6">
How it work: 0{index + 1}.
</Tagline>
<h2 className="h2 mb-4 lg:mb-6">
{item.title}
</h2>
<p className="body-2 mb-10 text-n-3">
{item.text}
</p>
<Button href="/login">
Connect now
</Button>
<Arrows
className="my-10 lg:hidden"
prevClassName="mr-3"
onPrev={() => ref.current?.go("<")}
onNext={() => ref.current?.go(">")}
/>
</div>
<div className="relative lg:w-[29.375rem] lg:flex-shrink-0 lg:mr-[7.125rem] xl:w-[34.375rem] xl:mr-40">
<div className="pt-0.25 pl-0.25 overflow-hidden bg-gradient-to-tl from-n-1/0 via-n-1/0 to-n-1/15 rounded-3xl">
<div className="h-[30.5rem] bg-n-7 rounded-[1.4375rem] xl:h-[35.625rem]">
<Image
className="w-full h-full object-contain"
src={item.image}
width={550}
height={570}
alt={item.title}
/>
<div className="absolute left-4 right-4 bottom-4 flex items-center h-16 px-5 bg-n-8 border border-n-1/10 rounded-xl lg:left-6 lg:right-6 lg:bottom-6">
<div className="flex items-center justify-center w-6 h-6 mr-5 bg-color-1 rounded-full">
<svg
className="w-2.5 h-2.5 fill-n-1"
viewBox="0 0 10 10"
>
<path d="M5 0a1 1 0 0 1 .993.883L6 1v3h3a1 1 0 0 1 .117 1.993L9 6H6v3a1 1 0 0 1-1.993.117L4 9V6H1a1 1 0 0 1-.117-1.993L1 4h3V1a1 1 0 0 1 1-1z" />
</svg>
</div>
<div className="text-base text-n-3/75">
Ask anything
</div>
<div className="w-6 h-6 ml-auto opacity-50">
<Image
className="w-full"
src="/images/icons/recording-01.svg"
width={24}
height={24}
alt="Recording"
/>
</div>
</div>
</div>
</div>
<div className="absolute -right-6 top-8 bottom-8 w-6 bg-[#1B1B2E] rounded-r-3xl"></div>
<div className="absolute -right-12 top-16 bottom-16 w-6 bg-[#1B1B2E]/50 rounded-r-3xl"></div>
</div>
</div>
</SplideSlide>
))}
</SplideTrack>
<Arrows
className="hidden justify-center mt-12 lg:flex lg:mt-15 xl:hidden"
prevClassName="mr-3"
onPrev={() => ref.current?.go("<")}
onNext={() => ref.current?.go(">")}
/>
<div className="absolute top-0 -left-[10rem] w-[29.5rem] h-[29.5rem] mix-blend-color-dodge opacity-20 pointer-events-none">
<Image
className="absolute top-1/2 left-1/2 w-[55.5rem] max-w-[55.5rem] h-[61.5rem] -translate-x-1/2 -translate-y-1/2"
src="/images/how-it-works/gradient.png"
width={984}
height={984}
alt="Gradient"
/>
</div>
<div className="hidden grid-cols-4 gap-6 mt-20 xl:grid">
{howItWorks.map((item, index) => (
<div
className="group cursor-pointer"
onClick={() => handleClick(index)}
key={item.id}
>
<div
className={`h-[0.125rem] mb-10 transition-colors ${
index === activeIndex
? "bg-color-1"
: "bg-[#D9D9D9]/10 group-hover:bg-[#D9D9D9]/50"
}`}
></div>
<div className="tagline mb-1 text-n-3">
0{index + 1}.
</div>
<h2 className="mb-[0.625rem] text-2xl leading-8">
{item.title}
</h2>
<p
className={`body-2 text-n-3 line-clamp-3 transition-opacity ${
index !== activeIndex && "opacity-0"
}`}
>
{item.text}
</p>
</div>
))}
</div>
</Splide>
</div>
</Section>
);
};
export default HowItWorks;

View File

@@ -1,69 +0,0 @@
import Link from "next/link";
import Section from "@/components/Section";
import Image from "@/components/Image";
import Heading from "@/components/Heading";
import PricingList from "@/components/PricingList";
type PricingProps = {};
const Pricing = ({}: PricingProps) => {
return (
<Section className="overflow-hidden">
<div className="container relative z-2">
<div className="hidden relative justify-center mb-[6.5rem] lg:flex">
<Image
className="relative z-1"
src="/images/figures/4-small.png"
width={255}
height={255}
alt="Sphere"
/>
<div className="absolute top-1/2 left-1/2 w-[59.5rem] -translate-x-1/2 -translate-y-1/2 pointer-events-none">
<Image
className="w-full"
src="/images/pricing/stars.svg"
width={952}
height={396}
alt="Stars"
/>
</div>
</div>
<Heading
tag="Get started with Brainwave"
title="Pay once, use forever"
/>
<div className="relative">
<PricingList />
<div className="hidden lg:block absolute top-1/2 right-full w-[92.5rem] h-[11.0625rem] -translate-y-1/2 pointer-events-none">
<Image
className="w-full"
src="/images/pricing/lines.svg"
width={1480}
height={177}
alt="Lines"
/>
</div>
<div className="hidden lg:block absolute top-1/2 left-full w-[92.5rem] h-[11.0625rem] -translate-y-1/2 -scale-x-100 pointer-events-none">
<Image
className="w-full"
src="/images/pricing/lines.svg"
width={1480}
height={177}
alt="Lines"
/>
</div>
</div>
<div className="flex justify-center mt-8 md:mt-15 xl:mt-20">
<Link
className="text-xs font-code font-bold tracking-wider uppercase border-b border-n-1 transition-colors hover:border-n-1/0"
href="/pricing"
>
See the full details
</Link>
</div>
</div>
</Section>
);
};
export default Pricing;

View File

@@ -1,69 +0,0 @@
import Link from "next/link";
import Section from "@/components/Section";
import Image from "@/components/Image";
import Heading from "@/components/Heading";
import PricingList from "@/components/PricingList";
type PricingProps = {};
const Pricing = ({}: PricingProps) => {
return (
<Section className="overflow-hidden">
<div className="container relative z-2">
<div className="hidden relative justify-center mb-[6.5rem] lg:flex">
<Image
className="relative z-1"
src="/images/figures/4-small.png"
width={255}
height={255}
alt="Sphere"
/>
<div className="absolute top-1/2 left-1/2 w-[59.5rem] -translate-x-1/2 -translate-y-1/2 pointer-events-none">
<Image
className="w-full"
src="/images/pricing/stars.svg"
width={952}
height={396}
alt="Stars"
/>
</div>
</div>
<Heading
tag="Get started with Brainwave"
title="Pay once, use forever"
/>
<div className="relative">
<PricingList />
<div className="hidden lg:block absolute top-1/2 right-full w-[92.5rem] h-[11.0625rem] -translate-y-1/2 pointer-events-none">
<Image
className="w-full"
src="/images/pricing/lines.svg"
width={1480}
height={177}
alt="Lines"
/>
</div>
<div className="hidden lg:block absolute top-1/2 left-full w-[92.5rem] h-[11.0625rem] -translate-y-1/2 -scale-x-100 pointer-events-none">
<Image
className="w-full"
src="/images/pricing/lines.svg"
width={1480}
height={177}
alt="Lines"
/>
</div>
</div>
<div className="flex justify-center mt-8 md:mt-15 xl:mt-20">
<Link
className="text-xs font-code font-bold tracking-wider uppercase border-b border-n-1 transition-colors hover:border-n-1/0"
href="/pricing"
>
See the full details
</Link>
</div>
</div>
</Section>
);
};
export default Pricing;

View File

@@ -1,97 +0,0 @@
import Section from "@/components/Section";
import Tagline from "@/components/Tagline";
import Image from "@/components/Image";
import { roadmap } from "@/mocks/roadmap";
import Button from "@/components/Button";
import Heading from "@/components/Heading";
type RoadmapProps = {};
const Roadmap = ({}: RoadmapProps) => (
<Section className="overflow-hidden">
<div className="container md:pb-10">
<Heading tag="Ready to get started" title="What were working on" />
<div className="relative grid gap-6 md:grid-cols-2 md:gap-4 md:pb-[7rem]">
{roadmap.map((item, index) => (
<div
className={`md:flex ${
index % 2 !== 0 ? "md:translate-y-[7rem]" : ""
} p-0.25 rounded-[2.5rem] ${
item.colorful ? "bg-conic-gradient" : "bg-n-6"
}`}
key={item.id}
>
<div className="relative p-8 bg-n-8 rounded-[2.4375rem] overflow-hidden xl:p-15">
<div className="absolute top-0 left-0 max-w-full">
<Image
className="w-full"
src="/images/grid.png"
width={550}
height={550}
alt="Grid"
/>
</div>
<div className="relative z-1">
<div className="flex items-center justify-between max-w-[27rem] mb-8 md:mb-20">
<Tagline>{item.date}</Tagline>
<div className="flex items-center px-4 py-1 bg-n-1 rounded text-n-8">
<Image
className="mr-2.5"
src={
item.status === "done"
? "/images/icons/check.svg"
: "/images/icons/loading-01.svg"
}
width={16}
height={16}
alt={
item.status === "done"
? "Done"
: "In progress"
}
/>
<div className="tagline">
{item.status === "done"
? "Done"
: "In progress"}
</div>
</div>
</div>
<div className="mb-8 md:mb-20">
<div className="-my-10 -mx-15">
<Image
className="w-full"
src={item.imageUrl}
width={628}
height={426}
alt={item.title}
/>
</div>
</div>
<h4 className="h4 mb-4">{item.title}</h4>
<p className="body-2 text-n-4">{item.text}</p>
</div>
</div>
</div>
))}
<div className="absolute top-[18.25rem] -left-[30.375rem] w-[56.625rem] opacity-60 mix-blend-color-dodge pointer-events-none">
<div className="absolute top-1/2 left-1/2 w-[58.85rem] h-[58.85rem] -translate-x-3/4 -translate-y-1/2">
<Image
className="w-full"
src="/images/gradient.png"
width={942}
height={942}
alt="Gradient"
/>
</div>
</div>
</div>
<div className="flex justify-center mt-12 md:mt-15 xl:mt-20">
<Button href="/roadmap">Our roadmap</Button>
</div>
</div>
</Section>
);
export default Roadmap;

View File

@@ -1,97 +0,0 @@
import Section from "@/components/Section";
import Tagline from "@/components/Tagline";
import Image from "@/components/Image";
import { roadmap } from "@/mocks/roadmap";
import Button from "@/components/Button";
import Heading from "@/components/Heading";
type RoadmapProps = {};
const Roadmap = ({}: RoadmapProps) => (
<Section className="overflow-hidden">
<div className="container md:pb-10">
<Heading tag="Ready to get started" title="What were working on" />
<div className="relative grid gap-6 md:grid-cols-2 md:gap-4 md:pb-[7rem]">
{roadmap.map((item, index) => (
<div
className={`md:flex ${
index % 2 !== 0 ? "md:translate-y-[7rem]" : ""
} p-0.25 rounded-[2.5rem] ${
item.colorful ? "bg-conic-gradient" : "bg-n-6"
}`}
key={item.id}
>
<div className="relative p-8 bg-n-8 rounded-[2.4375rem] overflow-hidden xl:p-15">
<div className="absolute top-0 left-0 max-w-full">
<Image
className="w-full"
src="/images/grid.png"
width={550}
height={550}
alt="Grid"
/>
</div>
<div className="relative z-1">
<div className="flex items-center justify-between max-w-[27rem] mb-8 md:mb-20">
<Tagline>{item.date}</Tagline>
<div className="flex items-center px-4 py-1 bg-n-1 rounded text-n-8">
<Image
className="mr-2.5"
src={
item.status === "done"
? "/images/icons/check.svg"
: "/images/icons/loading-01.svg"
}
width={16}
height={16}
alt={
item.status === "done"
? "Done"
: "In progress"
}
/>
<div className="tagline">
{item.status === "done"
? "Done"
: "In progress"}
</div>
</div>
</div>
<div className="mb-8 md:mb-20">
<div className="-my-10 -mx-15">
<Image
className="w-full"
src={item.imageUrl}
width={628}
height={426}
alt={item.title}
/>
</div>
</div>
<h4 className="h4 mb-4">{item.title}</h4>
<p className="body-2 text-n-4">{item.text}</p>
</div>
</div>
</div>
))}
<div className="absolute top-[18.25rem] -left-[30.375rem] w-[56.625rem] opacity-60 mix-blend-color-dodge pointer-events-none">
<div className="absolute top-1/2 left-1/2 w-[58.85rem] h-[58.85rem] -translate-x-3/4 -translate-y-1/2">
<Image
className="w-full"
src="/images/gradient.png"
width={942}
height={942}
alt="Gradient"
/>
</div>
</div>
</div>
<div className="flex justify-center mt-12 md:mt-15 xl:mt-20">
<Button href="/roadmap">Our roadmap</Button>
</div>
</div>
</Section>
);
export default Roadmap;

View File

@@ -1,90 +0,0 @@
import { Splide, SplideTrack, SplideSlide } from "@splidejs/react-splide";
import Section from "@/components/Section";
import Tagline from "@/components/Tagline";
import Button from "@/components/Button";
import Image from "@/components/Image";
import { testimonials } from "@/mocks/testimonials";
import Arrows from "@/components/Arrows";
import Heading from "@/components/Heading";
type TestimonialsProps = {};
const Testimonials = ({}: TestimonialsProps) => (
<Section className="overflow-hidden">
<div className="container relative z-2">
<Heading
tag="Ready to get started"
title="What the community is saying"
/>
<Splide
className="splide-custom splide-visible"
options={{
mediaQuery: "min",
gap: "1.5rem",
breakpoints: {
1024: {
autoWidth: true,
},
},
rewind: true,
pagination: false,
}}
hasTrack={false}
>
<SplideTrack>
{testimonials.map((item) => (
<SplideSlide key={item.id}>
<div className="relative flex h-full p-4 rounded-t-xl overflow-hidden lg:w-[46.125rem]">
<div className="absolute top-0 left-0 right-0 bottom-[3.25rem] border border-n-4/50 rounded-3xl"></div>
<div className="absolute inset-px rounded-t-[1.4375rem] overflow-hidden">
<div className="absolute -inset-0.25">
<Image
className="w-full h-full object-cover"
src={item.imageUrl}
width={739}
height={472}
alt={item.name}
/>
</div>
</div>
<div className="absolute inset-0 bg-gradient-to-r from-n-8/50 to-n-8/0"></div>
<div className="hidden relative z-1 md:flex flex-col flex-1 pt-12 px-4 pb-16">
<div className="w-[12.75rem] h-10 mb-auto">
<Image
className="w-full h-full object-contain"
src={item.logoUrl}
width={204}
height={40}
alt={item.name}
/>
</div>
<div className="h5">{item.name}</div>
<div className="h5 text-n-4">
{item.role}
</div>
</div>
<div className="relative flex z-1 bg-conic-gradient p-0.25 rounded-2xl md:ml-auto">
<div className="flex flex-col items-start p-8 bg-n-8 rounded-[0.9375rem] md:w-[21.75rem]">
<p className="quote mb-8">
{item.text}
</p>
<Button className="mt-auto">
Visit link
</Button>
</div>
</div>
</div>
</SplideSlide>
))}
</SplideTrack>
<Arrows
className="justify-center mt-12 md:mt-15 xl:mt-20"
prevClassName="mr-8"
/>
</Splide>
</div>
</Section>
);
export default Testimonials;

View File

@@ -1,90 +0,0 @@
import { Splide, SplideTrack, SplideSlide } from "@splidejs/react-splide";
import Section from "@/components/Section";
import Tagline from "@/components/Tagline";
import Button from "@/components/Button";
import Image from "@/components/Image";
import { testimonials } from "@/mocks/testimonials";
import Arrows from "@/components/Arrows";
import Heading from "@/components/Heading";
type TestimonialsProps = {};
const Testimonials = ({}: TestimonialsProps) => (
<Section className="overflow-hidden">
<div className="container relative z-2">
<Heading
tag="Ready to get started"
title="What the community is saying"
/>
<Splide
className="splide-custom splide-visible"
options={{
mediaQuery: "min",
gap: "1.5rem",
breakpoints: {
1024: {
autoWidth: true,
},
},
rewind: true,
pagination: false,
}}
hasTrack={false}
>
<SplideTrack>
{testimonials.map((item) => (
<SplideSlide key={item.id}>
<div className="relative flex h-full p-4 rounded-t-xl overflow-hidden lg:w-[46.125rem]">
<div className="absolute top-0 left-0 right-0 bottom-[3.25rem] border border-n-4/50 rounded-3xl"></div>
<div className="absolute inset-px rounded-t-[1.4375rem] overflow-hidden">
<div className="absolute -inset-0.25">
<Image
className="w-full h-full object-cover"
src={item.imageUrl}
width={739}
height={472}
alt={item.name}
/>
</div>
</div>
<div className="absolute inset-0 bg-gradient-to-r from-n-8/50 to-n-8/0"></div>
<div className="hidden relative z-1 md:flex flex-col flex-1 pt-12 px-4 pb-16">
<div className="w-[12.75rem] h-10 mb-auto">
<Image
className="w-full h-full object-contain"
src={item.logoUrl}
width={204}
height={40}
alt={item.name}
/>
</div>
<div className="h5">{item.name}</div>
<div className="h5 text-n-4">
{item.role}
</div>
</div>
<div className="relative flex z-1 bg-conic-gradient p-0.25 rounded-2xl md:ml-auto">
<div className="flex flex-col items-start p-8 bg-n-8 rounded-[0.9375rem] md:w-[21.75rem]">
<p className="quote mb-8">
{item.text}
</p>
<Button className="mt-auto">
Visit link
</Button>
</div>
</div>
</div>
</SplideSlide>
))}
</SplideTrack>
<Arrows
className="justify-center mt-12 md:mt-15 xl:mt-20"
prevClassName="mr-8"
/>
</Splide>
</div>
</Section>
);
export default Testimonials;

View File

@@ -1,30 +0,0 @@
import Layout from "../../components/Layout";
import Hero from "./Hero/index.js";
import Benefits from "./Benefits/index.js";
import Features from "./Features/index.js";
import Collaboration from "./Collaboration";
import HowItWorks from "./HowItWorks";
import Pricing from "./Pricing";
import Testimonials from "./Testimonials";
import Roadmap from "./Roadmap";
import Services from "../../components/Services";
import Join from "../../components/Join";
const HomePage = () => {
return (
<Layout>
<Hero />
<Benefits />
<Features />
<Collaboration />
<HowItWorks />
<Services />
<Pricing />
<Testimonials />
<Roadmap />
<Join />
</Layout>
);
};
export default HomePage;

View File

@@ -1,31 +0,0 @@
import Layout from "../../components/Layout/index.js";
import Hero from "./Hero/index.js";
import Benefits from "./Benefits/index.js";
import Features from "./Features/index.js";
// import Collaboration from "./Collaboration";
// import HowItWorks from "./HowItWorks";
// import Pricing from "./Pricing";
// import Testimonials from "./Testimonials";
// import Roadmap from "./Roadmap";
// import Services from "../../components/Services";
// import Join from "../../components/Join";
const HomePage = () => {
return (
<Layout>
<Hero />
<Benefits />
<Features />
{/* 其他组件将在后续逐步修复 */}
{/* <Collaboration />
<HowItWorks />
<Services />
<Pricing />
<Testimonials />
<Roadmap />
<Join /> */}
</Layout>
);
};
export default HomePage;

View File

@@ -1,62 +0,0 @@
import Section from "@/components/Section";
import Image from "@/components/Image";
import Button from "@/components/Button";
type HelpProps = {};
const Help = ({}: HelpProps) => (
<Section crosses>
<div className="container pt-10 pb-10 lg:grid lg:grid-cols-2 lg:gap-20 lg:items-center lg:p-0">
<div className="hidden lg:block">
<div>
<Image
src="/images/help/help.png"
width={756}
height={756}
alt="Help"
/>
</div>
</div>
<div>
<h2 className="h2 mb-4 md:mb-6">Need help?</h2>
<p className="body-2 mb-5 text-n-3">
Cant find your answer, contact us
</p>
<ul>
{[
{
id: "0",
title: "Join our community",
text: "Discuss anything with other users",
},
{
id: "1",
title: "Email us",
text: "hello@brainwave.com",
},
].map((item) => (
<li
className="flex items-center py-10 border-b border-n-1/15"
key={item.id}
>
<div className="flex items-center justify-center w-15 h-15 mr-10 bg-n-7 border border-n-1/15 rounded-xl">
<Image
src="/images/icons/building-01.svg"
width={24}
height={24}
alt="Contact"
/>
</div>
<div>
<h6 className="h6 text-n-3">{item.title}</h6>
<p className="body-2 text-n-2">{item.text}</p>
</div>
</li>
))}
</ul>
</div>
</div>
</Section>
);
export default Help;

View File

@@ -1,62 +0,0 @@
import Section from "@/components/Section";
import Image from "@/components/Image";
import Button from "@/components/Button";
type HelpProps = {};
const Help = ({}: HelpProps) => (
<Section crosses>
<div className="container pt-10 pb-10 lg:grid lg:grid-cols-2 lg:gap-20 lg:items-center lg:p-0">
<div className="hidden lg:block">
<div>
<Image
src="/images/help/help.png"
width={756}
height={756}
alt="Help"
/>
</div>
</div>
<div>
<h2 className="h2 mb-4 md:mb-6">Need help?</h2>
<p className="body-2 mb-5 text-n-3">
Cant find your answer, contact us
</p>
<ul>
{[
{
id: "0",
title: "Join our community",
text: "Discuss anything with other users",
},
{
id: "1",
title: "Email us",
text: "hello@brainwave.com",
},
].map((item) => (
<li
className="flex items-center py-10 border-b border-n-1/15"
key={item.id}
>
<div className="flex items-center justify-center w-15 h-15 mr-10 bg-n-7 border border-n-1/15 rounded-xl">
<Image
src="/images/icons/building-01.svg"
width={24}
height={24}
alt="Contact"
/>
</div>
<div>
<h6 className="h6 text-n-3">{item.title}</h6>
<p className="body-2 text-n-2">{item.text}</p>
</div>
</li>
))}
</ul>
</div>
</div>
</Section>
);
export default Help;

View File

@@ -1,261 +0,0 @@
import { useState } from "react";
import ScrollIntoView from "react-scroll-into-view";
import Section from "@/components/Section";
import Heading from "@/components/Heading";
import Image from "@/components/Image";
import Tagline from "@/components/Tagline";
import Button from "@/components/Button";
import { navigation } from "@/mocks/how-to-use";
type HowToUseProps = {};
const HowToUse = ({}: HowToUseProps) => {
const [openNavigation, setOpenNavigation] = useState<boolean>(false);
const [openGroupId, setOpenGroudId] = useState<string | null>("g0");
return (
<Section>
<div className="container md:py-10 lg:pt-16 xl:pt-20">
<Heading
textAlignClassName="text-center"
titleLarge="How to use"
textLarge="Get started with Brainwave - AI chat app today and experience the power of AI in your conversations!"
/>
<div className="relative max-w-[75rem] mb-15 mx-auto">
<Image
className="absolute top-6 left-6 w-6 opacity-30 pointer-events-none"
src="/images/icons/search-md.svg"
width={24}
height={24}
alt="Search"
/>
<input
className="w-full h-[4.5rem] pl-[3.5rem] pr-10 bg-transparent border border-n-6 rounded-[2.25rem] outline-none transition-colors focus:border-n-5"
type="text"
placeholder="Search topic"
/>
</div>
<div className="lg:flex">
<div className="mb-16 lg:flex-shrink-0 lg:w-[19rem] lg:mr-10 xl:mr-20">
<div
className="flex items-center justify-between w-full h-16 px-6 bg-n-7 rounded-xl cursor-pointer lg:hidden"
onClick={() => setOpenNavigation(!openNavigation)}
>
<div className="h6 text-n-1/50">
Getting started
</div>
<Image
src="/images/icons/chevron-down.svg"
width={24}
height={24}
alt="Arrow"
/>
</div>
<div
className={`pt-4 ${
openNavigation ? "block" : "hidden"
} lg:block lg:pt-0`}
>
{navigation.map((group) => (
<div className="mb-5" key={group.id}>
<button
className="flex items-start py-3.5"
onClick={() => setOpenGroudId(group.id)}
>
<div
className={`relative w-6 h-6 my-0.5 mr-5 p-0.5 ${
group.id === openGroupId
? "bg-n-7 border-[0.125rem] border-n-1/15 rounded-md"
: ""
}`}
>
<Image
className={`relative z-1 w-full transition-transform ${
group.id === openGroupId
? "rotate-90"
: ""
}`}
src="/images/icons/chevron-right.svg"
width={16}
height={16}
alt="Arrow"
/>
</div>
<div className="text-xl">
{group.title}
</div>
</button>
<div
className={`grid grid-rows-[0fr] transition-all ${
group.id === openGroupId
? "grid-rows-[1fr]"
: ""
}`}
>
<ul className="overflow-hidden">
{group.items.map((item) => (
<li key={item.id}>
<ScrollIntoView
className="body-2 block py-3 pl-11 text-n-3 transition-colors hover:text-color-1 cursor-pointer"
selector={`#anchor-${group.id}-${item.id}`}
>
<span>
{item.title}
</span>
</ScrollIntoView>
</li>
))}
</ul>
</div>
</div>
))}
</div>
</div>
<div className="flex-1">
<h3 className="h3 mb-16 pb-8 border-b border-n-1/15">
Getting started
</h3>
<div className="relative mb-16">
<div className="flex items-start mb-10">
<h4 className="h4 mr-auto">Sign up</h4>
<Tagline className="ml-4 mt-4">01</Tagline>
</div>
<div className="mb-10">
<Image
className="w-full h-full object-cover rounded-3xl"
src="/images/how-to-use/image-1.jpg"
width={896}
height={600}
alt="Image 1"
/>
</div>
<div className="body-2 text-n-2">
<p className="mb-6">
{`To create an account with Brainwave - AI
chat app, all you need to do is provide
your name, email address, and password.
Once you have signed up, you will be
able to start exploring the app's
various features. Brainwave's AI chat
system is designed to provide you with
an intuitive, easy-to-use interface that
makes it simple to chat with friends and
family, or even with new acquaintances.`}
</p>
<p className="mb-6">
In addition, the app is constantly being
updated with new features and improvements,
so you can expect it to continue to evolve
and improve over time. Whether you are
looking for a simple chat app, or a more
advanced platform that can help you stay
connected with people from all over the
world, Brainwave is the perfect choice.
</p>
</div>
<div
id={`anchor-${openGroupId}-0`}
className="absolute -top-32 left-0 w-full h-0.25"
></div>
</div>
<div className="relative mb-16">
<div className="flex items-start mb-10">
<h4 className="h4 mr-auto">
Connect with AI Chatbot
</h4>
<Tagline className="ml-4 mt-4">02</Tagline>
</div>
<div className="mb-10">
<Image
className="w-full h-full object-cover rounded-3xl"
src="/images/how-to-use/image-2.jpg"
width={896}
height={600}
alt="Image 2"
/>
</div>
<div className="body-2 text-n-2">
<p className="mb-6">
Connect with the AI chatbot to start the
conversation. The chatbot uses natural
language processing to understand your
queries and provide relevant responses.
</p>
</div>
<div
id={`anchor-${openGroupId}-1`}
className="absolute -top-32 left-0 w-full h-0.25"
></div>
</div>
<div className="relative mb-16">
<div className="flex items-start mb-10">
<h4 className="h4 mr-auto">
Get Personalized Advices
</h4>
<Tagline className="ml-4 mt-4">03</Tagline>
</div>
<div className="mb-10">
<Image
className="w-full h-full object-cover rounded-3xl"
src="/images/how-to-use/image-3.jpg"
width={896}
height={600}
alt="Image 3"
/>
</div>
<div className="body-2 text-n-2">
<p className="mb-6">
Based on the conversation with the AI
chatbot, you will receive personalized
recommendations related to your queries. The
chatbot is trained to understand your
preferences and provide customized
suggestions.
</p>
</div>
<div
id={`anchor-${openGroupId}-2`}
className="absolute -top-32 left-0 w-full h-0.25"
></div>
</div>
<div className="relative mb-16">
<div className="flex items-start mb-10">
<h4 className="h4 mr-auto">
Explore and Engage
</h4>
<Tagline className="ml-4 mt-4">04</Tagline>
</div>
<div className="mb-10">
<Image
className="w-full h-full object-cover rounded-3xl"
src="/images/how-to-use/image-4.jpg"
width={896}
height={600}
alt="Image 4"
/>
</div>
<div className="body-2 text-n-2">
<p className="mb-6">
Explore the recommendations provided by the
AI chatbot and engage with the app. You can
ask questions, provide feedback, and share
your experience with the chatbot.
</p>
</div>
<div
id={`anchor-${openGroupId}-3`}
className="absolute -top-32 left-0 w-full h-0.25"
></div>
</div>
<div className="flex justify-center">
<Button>Read more</Button>
</div>
</div>
</div>
</div>
</Section>
);
};
export default HowToUse;

View File

@@ -1,261 +0,0 @@
import { useState } from "react";
import ScrollIntoView from "react-scroll-into-view";
import Section from "@/components/Section";
import Heading from "@/components/Heading";
import Image from "@/components/Image";
import Tagline from "@/components/Tagline";
import Button from "@/components/Button";
import { navigation } from "@/mocks/how-to-use";
type HowToUseProps = {};
const HowToUse = ({}: HowToUseProps) => {
const [openNavigation, setOpenNavigation] = useState<boolean>(false);
const [openGroupId, setOpenGroudId] = useState<string | null>("g0");
return (
<Section>
<div className="container md:py-10 lg:pt-16 xl:pt-20">
<Heading
textAlignClassName="text-center"
titleLarge="How to use"
textLarge="Get started with Brainwave - AI chat app today and experience the power of AI in your conversations!"
/>
<div className="relative max-w-[75rem] mb-15 mx-auto">
<Image
className="absolute top-6 left-6 w-6 opacity-30 pointer-events-none"
src="/images/icons/search-md.svg"
width={24}
height={24}
alt="Search"
/>
<input
className="w-full h-[4.5rem] pl-[3.5rem] pr-10 bg-transparent border border-n-6 rounded-[2.25rem] outline-none transition-colors focus:border-n-5"
type="text"
placeholder="Search topic"
/>
</div>
<div className="lg:flex">
<div className="mb-16 lg:flex-shrink-0 lg:w-[19rem] lg:mr-10 xl:mr-20">
<div
className="flex items-center justify-between w-full h-16 px-6 bg-n-7 rounded-xl cursor-pointer lg:hidden"
onClick={() => setOpenNavigation(!openNavigation)}
>
<div className="h6 text-n-1/50">
Getting started
</div>
<Image
src="/images/icons/chevron-down.svg"
width={24}
height={24}
alt="Arrow"
/>
</div>
<div
className={`pt-4 ${
openNavigation ? "block" : "hidden"
} lg:block lg:pt-0`}
>
{navigation.map((group) => (
<div className="mb-5" key={group.id}>
<button
className="flex items-start py-3.5"
onClick={() => setOpenGroudId(group.id)}
>
<div
className={`relative w-6 h-6 my-0.5 mr-5 p-0.5 ${
group.id === openGroupId
? "bg-n-7 border-[0.125rem] border-n-1/15 rounded-md"
: ""
}`}
>
<Image
className={`relative z-1 w-full transition-transform ${
group.id === openGroupId
? "rotate-90"
: ""
}`}
src="/images/icons/chevron-right.svg"
width={16}
height={16}
alt="Arrow"
/>
</div>
<div className="text-xl">
{group.title}
</div>
</button>
<div
className={`grid grid-rows-[0fr] transition-all ${
group.id === openGroupId
? "grid-rows-[1fr]"
: ""
}`}
>
<ul className="overflow-hidden">
{group.items.map((item) => (
<li key={item.id}>
<ScrollIntoView
className="body-2 block py-3 pl-11 text-n-3 transition-colors hover:text-color-1 cursor-pointer"
selector={`#anchor-${group.id}-${item.id}`}
>
<span>
{item.title}
</span>
</ScrollIntoView>
</li>
))}
</ul>
</div>
</div>
))}
</div>
</div>
<div className="flex-1">
<h3 className="h3 mb-16 pb-8 border-b border-n-1/15">
Getting started
</h3>
<div className="relative mb-16">
<div className="flex items-start mb-10">
<h4 className="h4 mr-auto">Sign up</h4>
<Tagline className="ml-4 mt-4">01</Tagline>
</div>
<div className="mb-10">
<Image
className="w-full h-full object-cover rounded-3xl"
src="/images/how-to-use/image-1.jpg"
width={896}
height={600}
alt="Image 1"
/>
</div>
<div className="body-2 text-n-2">
<p className="mb-6">
{`To create an account with Brainwave - AI
chat app, all you need to do is provide
your name, email address, and password.
Once you have signed up, you will be
able to start exploring the app's
various features. Brainwave's AI chat
system is designed to provide you with
an intuitive, easy-to-use interface that
makes it simple to chat with friends and
family, or even with new acquaintances.`}
</p>
<p className="mb-6">
In addition, the app is constantly being
updated with new features and improvements,
so you can expect it to continue to evolve
and improve over time. Whether you are
looking for a simple chat app, or a more
advanced platform that can help you stay
connected with people from all over the
world, Brainwave is the perfect choice.
</p>
</div>
<div
id={`anchor-${openGroupId}-0`}
className="absolute -top-32 left-0 w-full h-0.25"
></div>
</div>
<div className="relative mb-16">
<div className="flex items-start mb-10">
<h4 className="h4 mr-auto">
Connect with AI Chatbot
</h4>
<Tagline className="ml-4 mt-4">02</Tagline>
</div>
<div className="mb-10">
<Image
className="w-full h-full object-cover rounded-3xl"
src="/images/how-to-use/image-2.jpg"
width={896}
height={600}
alt="Image 2"
/>
</div>
<div className="body-2 text-n-2">
<p className="mb-6">
Connect with the AI chatbot to start the
conversation. The chatbot uses natural
language processing to understand your
queries and provide relevant responses.
</p>
</div>
<div
id={`anchor-${openGroupId}-1`}
className="absolute -top-32 left-0 w-full h-0.25"
></div>
</div>
<div className="relative mb-16">
<div className="flex items-start mb-10">
<h4 className="h4 mr-auto">
Get Personalized Advices
</h4>
<Tagline className="ml-4 mt-4">03</Tagline>
</div>
<div className="mb-10">
<Image
className="w-full h-full object-cover rounded-3xl"
src="/images/how-to-use/image-3.jpg"
width={896}
height={600}
alt="Image 3"
/>
</div>
<div className="body-2 text-n-2">
<p className="mb-6">
Based on the conversation with the AI
chatbot, you will receive personalized
recommendations related to your queries. The
chatbot is trained to understand your
preferences and provide customized
suggestions.
</p>
</div>
<div
id={`anchor-${openGroupId}-2`}
className="absolute -top-32 left-0 w-full h-0.25"
></div>
</div>
<div className="relative mb-16">
<div className="flex items-start mb-10">
<h4 className="h4 mr-auto">
Explore and Engage
</h4>
<Tagline className="ml-4 mt-4">04</Tagline>
</div>
<div className="mb-10">
<Image
className="w-full h-full object-cover rounded-3xl"
src="/images/how-to-use/image-4.jpg"
width={896}
height={600}
alt="Image 4"
/>
</div>
<div className="body-2 text-n-2">
<p className="mb-6">
Explore the recommendations provided by the
AI chatbot and engage with the app. You can
ask questions, provide feedback, and share
your experience with the chatbot.
</p>
</div>
<div
id={`anchor-${openGroupId}-3`}
className="absolute -top-32 left-0 w-full h-0.25"
></div>
</div>
<div className="flex justify-center">
<Button>Read more</Button>
</div>
</div>
</div>
</div>
</Section>
);
};
export default HowToUse;

View File

@@ -1,16 +0,0 @@
"use client";
import Layout from "@/components/Layout";
import HowToUse from "./HowToUse";
import Help from "./Help";
const HowToUsePage = () => {
return (
<Layout>
<HowToUse />
<Help />
</Layout>
);
};
export default HowToUsePage;

View File

@@ -1,16 +0,0 @@
"use client";
import Layout from "@/components/Layout";
import HowToUse from "./HowToUse";
import Help from "./Help";
const HowToUsePage = () => {
return (
<Layout>
<HowToUse />
<Help />
</Layout>
);
};
export default HowToUsePage;

View File

@@ -1,152 +0,0 @@
"use client";
import { useSearchParams } from "next/navigation";
import Button from "@/components/Button";
import Image from "@/components/Image";
import Layout from "@/components/Layout";
import Section from "@/components/Section";
const LoginPage = ({}) => {
const searchParams = useSearchParams();
const signUp = searchParams.has("new");
return (
<Layout hideFooter>
<Section className="flex min-h-[calc(100vh-4.8125rem)] overflow-hidden lg:min-h-[calc(100vh-5.3125rem)]">
<div className="container relative z-2 max-w-[68rem] m-auto lg:flex lg:justify-between">
<div className="max-w-[32.875rem] mx-auto mb-12 text-center md:mb-16 lg:flex lg:flex-col lg:justify-around lg:max-w-[23.75rem] lg:m-0 lg:text-left">
<h2 className="h2">
Join the AI revolution with Brainwave
</h2>
<p className="hidden body-2 mt-4 text-n-4 md:block">
Get started with Brainwave - AI chat app today and
experience the power of AI in your conversations!
</p>
</div>
<form
className="relative max-w-[23.5rem] mx-auto p-0.25 bg-conic-gradient rounded-3xl lg:flex-1 lg:max-w-[27.5rem] lg:m-0 xl:mr-12"
action=""
>
<div className="px-9 py-10 bg-n-8 rounded-[1.4375rem] lg:px-16 lg:py-[3.25rem]">
{signUp && (
<div className="relative mb-4 lg:mb-5">
<Image
className="absolute top-4 left-0 w-6 pointer-events-none"
src="/images/icons/mail-01.svg"
width={24}
height={24}
alt="Mail"
/>
<input
className="w-full h-14 pl-12 bg-transparent border-b border-n-1/15 font-light placeholder:text-n-4 outline-none transition-colors focus:border-n-1/30"
type="text"
placeholder="Name"
/>
</div>
)}
<div className="relative mb-4 lg:mb-5">
<Image
className="absolute top-4 left-0 w-6 pointer-events-none"
src="/images/icons/mail-01.svg"
width={24}
height={24}
alt="Mail"
/>
<input
className="w-full h-14 pl-12 bg-transparent border-b border-n-1/15 font-light placeholder:text-n-4 outline-none transition-colors focus:border-n-1/30"
type="text"
placeholder="Email"
/>
</div>
<div className="relative mb-4 lg:mb-5">
<Image
className="absolute top-4 left-0 w-6 pointer-events-none"
src="/images/icons/lock-03.svg"
width={24}
height={24}
alt="Lock"
/>
<input
className="w-full h-14 pl-12 bg-transparent border-b border-n-1/15 font-light placeholder:text-n-4 outline-none transition-colors focus:border-n-1/30"
type="text"
placeholder="Password"
/>
</div>
<Button className="w-full" white>
{signUp ? "Sign up now" : "Sign in"}
</Button>
<div className="mt-10">
<div className="caption mb-6 text-n-4 text-center">
Or start your Brainwave with
</div>
<div className="flex justify-center">
<a
className="flex items-center justify-center w-12 h-12 mx-3 border border-n-1/5 rounded-full transition-colors hover:border-n-1/15"
href="#"
>
<svg width="24" height="24">
<path
fill="#757185"
d="M23.049 10h-10.5v4.5h5.951c-.951 3-3.3 4-5.999 4a6.5 6.5 0 0 1-5.33-2.768 6.5 6.5 0 0 1-.787-5.954 6.5 6.5 0 0 1 4.428-4.057 6.5 6.5 0 0 1 5.863 1.302l3.27-3.117a11 11 0 0 0-9.931-2.623 11 11 0 0 0-7.768 6.721A11 11 0 0 0 3.414 18.21 11 11 0 0 0 12.501 23c6.066 0 11.55-4 10.548-13z"
/>
</svg>
</a>
<a
className="flex items-center justify-center w-12 h-12 mx-3 border border-n-1/5 rounded-full transition-colors hover:border-n-1/15"
href="#"
>
<svg width="24" height="24">
<path
fill="#757185"
d="M21.356 16.252c-1.338-.506-2.233-1.721-2.334-3.17-.099-1.412.593-2.666 1.851-3.355l1.046-.573-.747-.93c-1.255-1.563-3.051-2.497-4.804-2.497-1.215 0-2.058.318-2.735.574-.478.181-.855.323-1.269.323-.472 0-.938-.166-1.478-.358-.708-.252-1.51-.538-2.54-.538-1.99 0-3.997 1.188-5.237 3.098-1.851 2.849-1.343 7.734 1.208 11.616 1.011 1.538 2.428 3.305 4.435 3.323h.039c1.643 0 2.003-.876 3.598-.886 1.742.082 1.962.893 3.589.882 1.961-.018 3.375-1.771 4.499-3.484.664-1.007.921-1.534 1.438-2.678l.438-.97-.997-.377zM15.103 3.214c.65-.834 1.143-2.011.964-3.214-1.062.073-2.302.748-3.027 1.628-.658.799-1.201 1.983-.99 3.135 1.158.036 2.357-.656 3.053-1.549z"
/>
</svg>
</a>
</div>
</div>
</div>
<div className="hidden absolute top-6 -right-12 bottom-6 xl:flex">
<div className="w-6 bg-[#1B1B2E] rounded-r-3xl"></div>
<div className="w-6 my-12 bg-[#1B1B2E]/50 rounded-r-3xl"></div>
</div>
</form>
</div>
<div className="hidden absolute left-5 right-5 bottom-5 z-4 h-0.25 bg-n-6 pointer-events-none md:block lg:left-7.5 lg:right-7.5 lg:bottom-7.5 xl:left-10 xl:right-10 xl:bottom-10"></div>
<svg
className="hidden absolute left-[0.9375rem] bottom-[0.9375rem] z-4 pointer-events-none md:block lg:left-[1.5625rem] lg:bottom-[1.5625rem] xl:left-[2.1875rem] xl:bottom-[2.1875rem]"
width="11"
height="11"
fill="none"
>
<path
d="M7 1a1 1 0 0 0-1-1H5a1 1 0 0 0-1 1v2a1 1 0 0 1-1 1H1a1 1 0 0 0-1 1v1a1 1 0 0 0 1 1h2a1 1 0 0 1 1 1v2a1 1 0 0 0 1 1h1a1 1 0 0 0 1-1V8a1 1 0 0 1 1-1h2a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1H8a1 1 0 0 1-1-1V1z"
fill="#ada8c4"
/>
</svg>
<svg
className="hidden absolute right-[0.9375rem] bottom-[0.9375rem] z-4 pointer-events-none md:block lg:right-[1.5625rem] lg:bottom-[1.5625rem] xl:right-[2.1875rem] xl:bottom-[2.1875rem]"
width="11"
height="11"
fill="none"
>
<path
d="M7 1a1 1 0 0 0-1-1H5a1 1 0 0 0-1 1v2a1 1 0 0 1-1 1H1a1 1 0 0 0-1 1v1a1 1 0 0 0 1 1h2a1 1 0 0 1 1 1v2a1 1 0 0 0 1 1h1a1 1 0 0 0 1-1V8a1 1 0 0 1 1-1h2a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1H8a1 1 0 0 1-1-1V1z"
fill="#ada8c4"
/>
</svg>
<div className="absolute inset-0">
<Image
className="w-full h-full object-cover"
src="/images/login/background.jpg"
width={1920}
height={1080}
quality={100}
alt="Background"
/>
</div>
</Section>
</Layout>
);
};
export default LoginPage;

View File

@@ -1,152 +0,0 @@
"use client";
import { useSearchParams } from "next/navigation";
import Button from "@/components/Button";
import Image from "@/components/Image";
import Layout from "@/components/Layout";
import Section from "@/components/Section";
const LoginPage = ({}) => {
const searchParams = useSearchParams();
const signUp = searchParams.has("new");
return (
<Layout hideFooter>
<Section className="flex min-h-[calc(100vh-4.8125rem)] overflow-hidden lg:min-h-[calc(100vh-5.3125rem)]">
<div className="container relative z-2 max-w-[68rem] m-auto lg:flex lg:justify-between">
<div className="max-w-[32.875rem] mx-auto mb-12 text-center md:mb-16 lg:flex lg:flex-col lg:justify-around lg:max-w-[23.75rem] lg:m-0 lg:text-left">
<h2 className="h2">
Join the AI revolution with Brainwave
</h2>
<p className="hidden body-2 mt-4 text-n-4 md:block">
Get started with Brainwave - AI chat app today and
experience the power of AI in your conversations!
</p>
</div>
<form
className="relative max-w-[23.5rem] mx-auto p-0.25 bg-conic-gradient rounded-3xl lg:flex-1 lg:max-w-[27.5rem] lg:m-0 xl:mr-12"
action=""
>
<div className="px-9 py-10 bg-n-8 rounded-[1.4375rem] lg:px-16 lg:py-[3.25rem]">
{signUp && (
<div className="relative mb-4 lg:mb-5">
<Image
className="absolute top-4 left-0 w-6 pointer-events-none"
src="/images/icons/mail-01.svg"
width={24}
height={24}
alt="Mail"
/>
<input
className="w-full h-14 pl-12 bg-transparent border-b border-n-1/15 font-light placeholder:text-n-4 outline-none transition-colors focus:border-n-1/30"
type="text"
placeholder="Name"
/>
</div>
)}
<div className="relative mb-4 lg:mb-5">
<Image
className="absolute top-4 left-0 w-6 pointer-events-none"
src="/images/icons/mail-01.svg"
width={24}
height={24}
alt="Mail"
/>
<input
className="w-full h-14 pl-12 bg-transparent border-b border-n-1/15 font-light placeholder:text-n-4 outline-none transition-colors focus:border-n-1/30"
type="text"
placeholder="Email"
/>
</div>
<div className="relative mb-4 lg:mb-5">
<Image
className="absolute top-4 left-0 w-6 pointer-events-none"
src="/images/icons/lock-03.svg"
width={24}
height={24}
alt="Lock"
/>
<input
className="w-full h-14 pl-12 bg-transparent border-b border-n-1/15 font-light placeholder:text-n-4 outline-none transition-colors focus:border-n-1/30"
type="text"
placeholder="Password"
/>
</div>
<Button className="w-full" white>
{signUp ? "Sign up now" : "Sign in"}
</Button>
<div className="mt-10">
<div className="caption mb-6 text-n-4 text-center">
Or start your Brainwave with
</div>
<div className="flex justify-center">
<a
className="flex items-center justify-center w-12 h-12 mx-3 border border-n-1/5 rounded-full transition-colors hover:border-n-1/15"
href="#"
>
<svg width="24" height="24">
<path
fill="#757185"
d="M23.049 10h-10.5v4.5h5.951c-.951 3-3.3 4-5.999 4a6.5 6.5 0 0 1-5.33-2.768 6.5 6.5 0 0 1-.787-5.954 6.5 6.5 0 0 1 4.428-4.057 6.5 6.5 0 0 1 5.863 1.302l3.27-3.117a11 11 0 0 0-9.931-2.623 11 11 0 0 0-7.768 6.721A11 11 0 0 0 3.414 18.21 11 11 0 0 0 12.501 23c6.066 0 11.55-4 10.548-13z"
/>
</svg>
</a>
<a
className="flex items-center justify-center w-12 h-12 mx-3 border border-n-1/5 rounded-full transition-colors hover:border-n-1/15"
href="#"
>
<svg width="24" height="24">
<path
fill="#757185"
d="M21.356 16.252c-1.338-.506-2.233-1.721-2.334-3.17-.099-1.412.593-2.666 1.851-3.355l1.046-.573-.747-.93c-1.255-1.563-3.051-2.497-4.804-2.497-1.215 0-2.058.318-2.735.574-.478.181-.855.323-1.269.323-.472 0-.938-.166-1.478-.358-.708-.252-1.51-.538-2.54-.538-1.99 0-3.997 1.188-5.237 3.098-1.851 2.849-1.343 7.734 1.208 11.616 1.011 1.538 2.428 3.305 4.435 3.323h.039c1.643 0 2.003-.876 3.598-.886 1.742.082 1.962.893 3.589.882 1.961-.018 3.375-1.771 4.499-3.484.664-1.007.921-1.534 1.438-2.678l.438-.97-.997-.377zM15.103 3.214c.65-.834 1.143-2.011.964-3.214-1.062.073-2.302.748-3.027 1.628-.658.799-1.201 1.983-.99 3.135 1.158.036 2.357-.656 3.053-1.549z"
/>
</svg>
</a>
</div>
</div>
</div>
<div className="hidden absolute top-6 -right-12 bottom-6 xl:flex">
<div className="w-6 bg-[#1B1B2E] rounded-r-3xl"></div>
<div className="w-6 my-12 bg-[#1B1B2E]/50 rounded-r-3xl"></div>
</div>
</form>
</div>
<div className="hidden absolute left-5 right-5 bottom-5 z-4 h-0.25 bg-n-6 pointer-events-none md:block lg:left-7.5 lg:right-7.5 lg:bottom-7.5 xl:left-10 xl:right-10 xl:bottom-10"></div>
<svg
className="hidden absolute left-[0.9375rem] bottom-[0.9375rem] z-4 pointer-events-none md:block lg:left-[1.5625rem] lg:bottom-[1.5625rem] xl:left-[2.1875rem] xl:bottom-[2.1875rem]"
width="11"
height="11"
fill="none"
>
<path
d="M7 1a1 1 0 0 0-1-1H5a1 1 0 0 0-1 1v2a1 1 0 0 1-1 1H1a1 1 0 0 0-1 1v1a1 1 0 0 0 1 1h2a1 1 0 0 1 1 1v2a1 1 0 0 0 1 1h1a1 1 0 0 0 1-1V8a1 1 0 0 1 1-1h2a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1H8a1 1 0 0 1-1-1V1z"
fill="#ada8c4"
/>
</svg>
<svg
className="hidden absolute right-[0.9375rem] bottom-[0.9375rem] z-4 pointer-events-none md:block lg:right-[1.5625rem] lg:bottom-[1.5625rem] xl:right-[2.1875rem] xl:bottom-[2.1875rem]"
width="11"
height="11"
fill="none"
>
<path
d="M7 1a1 1 0 0 0-1-1H5a1 1 0 0 0-1 1v2a1 1 0 0 1-1 1H1a1 1 0 0 0-1 1v1a1 1 0 0 0 1 1h2a1 1 0 0 1 1 1v2a1 1 0 0 0 1 1h1a1 1 0 0 0 1-1V8a1 1 0 0 1 1-1h2a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1H8a1 1 0 0 1-1-1V1z"
fill="#ada8c4"
/>
</svg>
<div className="absolute inset-0">
<Image
className="w-full h-full object-cover"
src="/images/login/background.jpg"
width={1920}
height={1080}
quality={100}
alt="Background"
/>
</div>
</Section>
</Layout>
);
};
export default LoginPage;

View File

@@ -1,64 +0,0 @@
import { useRef, useState } from "react";
import { Splide, SplideTrack, SplideSlide } from "@splidejs/react-splide";
import Comment from "./Comment";
type CarouselProps = {
items: any;
};
const Carousel = ({ items }: CarouselProps) => {
const [activeIndex, setActiveIndex] = useState<number>(0);
const ref = useRef<any>(null);
const handleClick = (index: number) => {
setActiveIndex(index);
ref.current?.go(index);
};
return (
<Splide
className="splide-visible relative z-2"
options={{
pagination: false,
arrows: false,
gap: "1.5rem",
}}
onMoved={(e, newIndex) => setActiveIndex(newIndex)}
hasTrack={false}
ref={ref}
>
<SplideTrack>
{items.map((item: any) => (
<SplideSlide key={item.id}>
<div className="flex h-full">
<Comment comment={item} />
</div>
</SplideSlide>
))}
</SplideTrack>
<div className="flex justify-center mt-8 -mx-2 md:mt-15 lg:hidden">
{items.map((item: any, index: number) => (
<button
className="relative w-6 h-6 mx-2"
onClick={() => handleClick(index)}
key={item.id}
>
<span
className={`absolute inset-0 bg-conic-gradient rounded-full transition-opacity ${
index === activeIndex
? "opacity-100"
: "opacity-0"
}`}
></span>
<span className="absolute inset-0.25 bg-n-8 rounded-full">
<span className="absolute inset-2 bg-n-1 rounded-full"></span>
</span>
</button>
))}
</div>
</Splide>
);
};
export default Carousel;

View File

@@ -1,64 +0,0 @@
import { useRef, useState } from "react";
import { Splide, SplideTrack, SplideSlide } from "@splidejs/react-splide";
import Comment from "./Comment";
type CarouselProps = {
items: any;
};
const Carousel = ({ items }: CarouselProps) => {
const [activeIndex, setActiveIndex] = useState<number>(0);
const ref = useRef<any>(null);
const handleClick = (index: number) => {
setActiveIndex(index);
ref.current?.go(index);
};
return (
<Splide
className="splide-visible relative z-2"
options={{
pagination: false,
arrows: false,
gap: "1.5rem",
}}
onMoved={(e, newIndex) => setActiveIndex(newIndex)}
hasTrack={false}
ref={ref}
>
<SplideTrack>
{items.map((item: any) => (
<SplideSlide key={item.id}>
<div className="flex h-full">
<Comment comment={item} />
</div>
</SplideSlide>
))}
</SplideTrack>
<div className="flex justify-center mt-8 -mx-2 md:mt-15 lg:hidden">
{items.map((item: any, index: number) => (
<button
className="relative w-6 h-6 mx-2"
onClick={() => handleClick(index)}
key={item.id}
>
<span
className={`absolute inset-0 bg-conic-gradient rounded-full transition-opacity ${
index === activeIndex
? "opacity-100"
: "opacity-0"
}`}
></span>
<span className="absolute inset-0.25 bg-n-8 rounded-full">
<span className="absolute inset-2 bg-n-1 rounded-full"></span>
</span>
</button>
))}
</div>
</Splide>
);
};
export default Carousel;

View File

@@ -1,28 +0,0 @@
import Image from "@/components/Image";
type CommentProps = {
comment: any;
};
const Comment = ({ comment }: CommentProps) => (
<div className="flex flex-col bg-n-8 border border-n-1/5 rounded-2xl">
<div className="quote flex-1 px-5 py-10 md:px-10">{comment.text}</div>
<div className="flex items-center px-5 py-6 bg-n-7 rounded-b-[0.9375rem] md:px-10">
<div className="mr-5">
<h6 className="h6">{comment.name}</h6>
<div className="caption text-n-1/25">{comment.role}</div>
</div>
<div className="ml-auto">
<Image
className="w-full rounded-full"
src={comment.avatarUrl}
width={60}
height={60}
alt={comment.name}
/>
</div>
</div>
</div>
);
export default Comment;

View File

@@ -1,28 +0,0 @@
import Image from "@/components/Image";
type CommentProps = {
comment: any;
};
const Comment = ({ comment }: CommentProps) => (
<div className="flex flex-col bg-n-8 border border-n-1/5 rounded-2xl">
<div className="quote flex-1 px-5 py-10 md:px-10">{comment.text}</div>
<div className="flex items-center px-5 py-6 bg-n-7 rounded-b-[0.9375rem] md:px-10">
<div className="mr-5">
<h6 className="h6">{comment.name}</h6>
<div className="caption text-n-1/25">{comment.role}</div>
</div>
<div className="ml-auto">
<Image
className="w-full rounded-full"
src={comment.avatarUrl}
width={60}
height={60}
alt={comment.name}
/>
</div>
</div>
</div>
);
export default Comment;

View File

@@ -1,25 +0,0 @@
import Masonry, { ResponsiveMasonry } from "react-responsive-masonry";
import Comment from "./Comment";
type GridProps = {
items: any;
};
const Grid = ({ items }: GridProps) => {
return (
<ResponsiveMasonry
className="relative z-2"
columnsCountBreakPoints={{ 768: 2, 1280: 3 }}
>
<Masonry gutter="1.5rem">
{items.map((item: any) => (
<div key={item.id}>
<Comment comment={item} />
</div>
))}
</Masonry>
</ResponsiveMasonry>
);
};
export default Grid;

View File

@@ -1,25 +0,0 @@
import Masonry, { ResponsiveMasonry } from "react-responsive-masonry";
import Comment from "./Comment";
type GridProps = {
items: any;
};
const Grid = ({ items }: GridProps) => {
return (
<ResponsiveMasonry
className="relative z-2"
columnsCountBreakPoints={{ 768: 2, 1280: 3 }}
>
<Masonry gutter="1.5rem">
{items.map((item: any) => (
<div key={item.id}>
<Comment comment={item} />
</div>
))}
</Masonry>
</ResponsiveMasonry>
);
};
export default Grid;

View File

@@ -1,50 +0,0 @@
import dynamic from "next/dynamic";
import { useMediaQuery } from "react-responsive";
import Section from "@/components/Section";
import Heading from "@/components/Heading";
import Image from "@/components/Image";
const Grid = dynamic(() => import("./Grid"), { ssr: false });
const Carousel = dynamic(() => import("./Carousel"), { ssr: false });
import { community } from "@/mocks/community";
type CommunityProps = {};
const Community = ({}: CommunityProps) => {
const isTablet = useMediaQuery({
query: "(min-width: 768px)",
});
return (
<Section>
<div className="container">
<Heading
className="md:text-center"
tagClassName="md:justify-center"
tag="ready to get started"
title="What the community is saying"
/>
<div className="relative">
{isTablet ? (
<Grid items={community} />
) : (
<Carousel items={community} />
)}
<div className="absolute top-[18.25rem] -left-[30.375rem] w-[56.625rem] opacity-60 mix-blend-color-dodge pointer-events-none">
<div className="absolute top-1/2 left-1/2 w-[58.85rem] h-[58.85rem] -translate-x-3/4 -translate-y-1/2">
<Image
className="w-full"
src="/images/gradient.png"
width={942}
height={942}
alt="Gradient"
/>
</div>
</div>
</div>
</div>
</Section>
);
};
export default Community;

View File

@@ -1,50 +0,0 @@
import dynamic from "next/dynamic";
import { useMediaQuery } from "react-responsive";
import Section from "@/components/Section";
import Heading from "@/components/Heading";
import Image from "@/components/Image";
const Grid = dynamic(() => import("./Grid"), { ssr: false });
const Carousel = dynamic(() => import("./Carousel"), { ssr: false });
import { community } from "@/mocks/community";
type CommunityProps = {};
const Community = ({}: CommunityProps) => {
const isTablet = useMediaQuery({
query: "(min-width: 768px)",
});
return (
<Section>
<div className="container">
<Heading
className="md:text-center"
tagClassName="md:justify-center"
tag="ready to get started"
title="What the community is saying"
/>
<div className="relative">
{isTablet ? (
<Grid items={community} />
) : (
<Carousel items={community} />
)}
<div className="absolute top-[18.25rem] -left-[30.375rem] w-[56.625rem] opacity-60 mix-blend-color-dodge pointer-events-none">
<div className="absolute top-1/2 left-1/2 w-[58.85rem] h-[58.85rem] -translate-x-3/4 -translate-y-1/2">
<Image
className="w-full"
src="/images/gradient.png"
width={942}
height={942}
alt="Gradient"
/>
</div>
</div>
</div>
</div>
</Section>
);
};
export default Community;

View File

@@ -1,101 +0,0 @@
import Tippy from "@tippyjs/react";
import Heading from "@/components/Heading";
import Image from "@/components/Image";
import Section from "@/components/Section";
import { comparison } from "@/mocks/comparison";
type ComparisonProps = {};
const Comparison = ({}: ComparisonProps) => {
const check = (value: any, enterprise?: boolean) =>
typeof value === "boolean" ? (
value === true ? (
<Image
src={
enterprise
? "/images/check-yellow.svg"
: "/images/check.svg"
}
width={24}
height={24}
alt="Check"
/>
) : null
) : (
value
);
return (
<Section>
<div className="container">
<Heading
className="md:text-center"
title="Compare plans & features"
/>
<div className="-mx-5 px-5 overflow-auto">
<table className="table-fixed w-full min-w-[32rem]">
<tbody>
<tr className="h6">
<td className="w-[35%] py-4 pr-10">Features</td>
<td className="p-4 text-center text-color-2">
Basic
</td>
<td className="p-4 text-center text-color-1">
Premium
</td>
<td className="p-4 text-center text-color-3">
Enterprise
</td>
</tr>
{comparison.map((item) => (
<tr className="body-2" key={item.id}>
<td className="w-[35%] h-[4.75rem] py-2.5 pr-2.5 border-t border-n-1/5">
<div className="flex items-center">
{item.title}
<Tippy
className="p-2.5 bg-n-1 text-n-8 rounded-xl"
content="Provide dedicated servers for enterprises to ensure maximum security, performance, and uptime."
placement="right"
animation="shift-toward"
>
<div className="flex-shrink-0 ml-3 opacity-30 transition-opacity hover:opacity-100">
<Image
src="/images/icons/help-circle.svg"
width={24}
height={24}
alt="Help"
/>
</div>
</Tippy>
</div>
</td>
<td className="h-[4.75rem] p-2.5 border-t border-n-1/5 text-center">
{check(
item.pricing[0],
item.enterprise
)}
</td>
<td className="h-[4.75rem] p-2.5 border-t border-n-1/5 text-center">
{check(
item.pricing[1],
item.enterprise
)}
</td>
<td className="h-[4.75rem] p-2.5 border-t border-n-1/5 text-center">
{check(
item.pricing[2],
item.enterprise
)}
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</Section>
);
};
export default Comparison;

View File

@@ -1,101 +0,0 @@
import Tippy from "@tippyjs/react";
import Heading from "@/components/Heading";
import Image from "@/components/Image";
import Section from "@/components/Section";
import { comparison } from "@/mocks/comparison";
type ComparisonProps = {};
const Comparison = ({}: ComparisonProps) => {
const check = (value: any, enterprise?: boolean) =>
typeof value === "boolean" ? (
value === true ? (
<Image
src={
enterprise
? "/images/check-yellow.svg"
: "/images/check.svg"
}
width={24}
height={24}
alt="Check"
/>
) : null
) : (
value
);
return (
<Section>
<div className="container">
<Heading
className="md:text-center"
title="Compare plans & features"
/>
<div className="-mx-5 px-5 overflow-auto">
<table className="table-fixed w-full min-w-[32rem]">
<tbody>
<tr className="h6">
<td className="w-[35%] py-4 pr-10">Features</td>
<td className="p-4 text-center text-color-2">
Basic
</td>
<td className="p-4 text-center text-color-1">
Premium
</td>
<td className="p-4 text-center text-color-3">
Enterprise
</td>
</tr>
{comparison.map((item) => (
<tr className="body-2" key={item.id}>
<td className="w-[35%] h-[4.75rem] py-2.5 pr-2.5 border-t border-n-1/5">
<div className="flex items-center">
{item.title}
<Tippy
className="p-2.5 bg-n-1 text-n-8 rounded-xl"
content="Provide dedicated servers for enterprises to ensure maximum security, performance, and uptime."
placement="right"
animation="shift-toward"
>
<div className="flex-shrink-0 ml-3 opacity-30 transition-opacity hover:opacity-100">
<Image
src="/images/icons/help-circle.svg"
width={24}
height={24}
alt="Help"
/>
</div>
</Tippy>
</div>
</td>
<td className="h-[4.75rem] p-2.5 border-t border-n-1/5 text-center">
{check(
item.pricing[0],
item.enterprise
)}
</td>
<td className="h-[4.75rem] p-2.5 border-t border-n-1/5 text-center">
{check(
item.pricing[1],
item.enterprise
)}
</td>
<td className="h-[4.75rem] p-2.5 border-t border-n-1/5 text-center">
{check(
item.pricing[2],
item.enterprise
)}
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</Section>
);
};
export default Comparison;

View File

@@ -1,78 +0,0 @@
import { useState } from "react";
import Section from "@/components/Section";
import Heading from "@/components/Heading";
import { faq } from "@/mocks/faq";
type FaqProps = {};
const Faq = ({}: FaqProps) => {
const [activeId, setActiveId] = useState<string | null>(faq[0].id);
return (
<Section>
<div className="container lg:flex">
<Heading
className="lg:min-w-[22.75rem] lg:mr-12 lg:pt-8 xl:min-w-[32.75rem]"
textAlignClassName="md:text-center lg:text-left"
title="Frequently asked questions"
text={
<>
Havent found what youre looking for?{" "}
<a
className="text-n-1 hover:text-color-2"
href="mailto:info@ui8.net"
>
Contact us
</a>
</>
}
/>
<div className="-mt-8 lg:mt-0">
{faq.map((item) => (
<div
className="py-8 border-b border-n-1/5"
key={item.id}
>
<div
className="flex items-start justify-between cursor-pointer"
onClick={() =>
setActiveId(
activeId === item.id ? null : item.id
)
}
>
<div className="text-[1.25rem] leading-8">
{item.title}
</div>
<div className="relative w-6 h-6 mt-1 ml-10">
<div className="absolute top-[0.6875rem] left-1 w-4 h-0.5 bg-n-1 rounded-sm"></div>
<div
className={`absolute top-[0.6875rem] left-1 w-4 h-0.5 bg-n-1 rounded-sm transition-transform ${
item.id === activeId
? ""
: "rotate-90"
}`}
></div>
</div>
</div>
<div
className={`grid grid-rows-[0fr] transition-all ${
item.id === activeId
? "grid-rows-[1fr]"
: ""
}`}
>
<div className="body-2 text-n-3 overflow-hidden">
<div className="pt-6">{item.text}</div>
</div>
</div>
</div>
))}
</div>
</div>
</Section>
);
};
export default Faq;

View File

@@ -1,78 +0,0 @@
import { useState } from "react";
import Section from "@/components/Section";
import Heading from "@/components/Heading";
import { faq } from "@/mocks/faq";
type FaqProps = {};
const Faq = ({}: FaqProps) => {
const [activeId, setActiveId] = useState<string | null>(faq[0].id);
return (
<Section>
<div className="container lg:flex">
<Heading
className="lg:min-w-[22.75rem] lg:mr-12 lg:pt-8 xl:min-w-[32.75rem]"
textAlignClassName="md:text-center lg:text-left"
title="Frequently asked questions"
text={
<>
Havent found what youre looking for?{" "}
<a
className="text-n-1 hover:text-color-2"
href="mailto:info@ui8.net"
>
Contact us
</a>
</>
}
/>
<div className="-mt-8 lg:mt-0">
{faq.map((item) => (
<div
className="py-8 border-b border-n-1/5"
key={item.id}
>
<div
className="flex items-start justify-between cursor-pointer"
onClick={() =>
setActiveId(
activeId === item.id ? null : item.id
)
}
>
<div className="text-[1.25rem] leading-8">
{item.title}
</div>
<div className="relative w-6 h-6 mt-1 ml-10">
<div className="absolute top-[0.6875rem] left-1 w-4 h-0.5 bg-n-1 rounded-sm"></div>
<div
className={`absolute top-[0.6875rem] left-1 w-4 h-0.5 bg-n-1 rounded-sm transition-transform ${
item.id === activeId
? ""
: "rotate-90"
}`}
></div>
</div>
</div>
<div
className={`grid grid-rows-[0fr] transition-all ${
item.id === activeId
? "grid-rows-[1fr]"
: ""
}`}
>
<div className="body-2 text-n-3 overflow-hidden">
<div className="pt-6">{item.text}</div>
</div>
</div>
</div>
))}
</div>
</div>
</Section>
);
};
export default Faq;

View File

@@ -1,50 +0,0 @@
import Section from "@/components/Section";
import Heading from "@/components/Heading";
import PricingList from "@/components/PricingList";
import { useState } from "react";
import Logos from "@/components/Logos";
type PricingProps = {};
const Pricing = ({}: PricingProps) => {
const [monthly, setMonthly] = useState<boolean>(false);
return (
<Section className="overflow-hidden">
<div className="container relative z-2 md:pt-10 lg:pt-16 xl:pt-20">
<Heading
textAlignClassName="text-center"
titleLarge="Pay once, use forever"
textLarge="Get started with Brainwave - AI chat app today and experience the power of AI in your conversations!"
/>
<div className="w-[19rem] mx-auto mb-10 p-0.25 bg-gradient-to-b from-[#D77DEE]/90 to-n-1/15 rounded-xl">
<div className="flex p-[0.1875rem] bg-n-8 rounded-[0.6875rem]">
<button
className={`button flex-1 h-10 rounded-lg transition-colors ${
monthly ? "bg-n-6" : ""
}`}
onClick={() => setMonthly(true)}
>
monthly
</button>
<button
className={`button flex-1 h-10 rounded-lg transition-colors ${
monthly ? "" : "bg-n-6"
}`}
onClick={() => setMonthly(false)}
>
annually
<span className="ml-2.5 p-1 bg-color-1 rounded">
-10%
</span>
</button>
</div>
</div>
<PricingList monthly={monthly} />
<Logos className="hidden mt-20 lg:block" />
</div>
</Section>
);
};
export default Pricing;

View File

@@ -1,50 +0,0 @@
import Section from "@/components/Section";
import Heading from "@/components/Heading";
import PricingList from "@/components/PricingList";
import { useState } from "react";
import Logos from "@/components/Logos";
type PricingProps = {};
const Pricing = ({}: PricingProps) => {
const [monthly, setMonthly] = useState<boolean>(false);
return (
<Section className="overflow-hidden">
<div className="container relative z-2 md:pt-10 lg:pt-16 xl:pt-20">
<Heading
textAlignClassName="text-center"
titleLarge="Pay once, use forever"
textLarge="Get started with Brainwave - AI chat app today and experience the power of AI in your conversations!"
/>
<div className="w-[19rem] mx-auto mb-10 p-0.25 bg-gradient-to-b from-[#D77DEE]/90 to-n-1/15 rounded-xl">
<div className="flex p-[0.1875rem] bg-n-8 rounded-[0.6875rem]">
<button
className={`button flex-1 h-10 rounded-lg transition-colors ${
monthly ? "bg-n-6" : ""
}`}
onClick={() => setMonthly(true)}
>
monthly
</button>
<button
className={`button flex-1 h-10 rounded-lg transition-colors ${
monthly ? "" : "bg-n-6"
}`}
onClick={() => setMonthly(false)}
>
annually
<span className="ml-2.5 p-1 bg-color-1 rounded">
-10%
</span>
</button>
</div>
</div>
<PricingList monthly={monthly} />
<Logos className="hidden mt-20 lg:block" />
</div>
</Section>
);
};
export default Pricing;

View File

@@ -1,22 +0,0 @@
"use client";
import Layout from "@/components/Layout";
import Pricing from "./Pricing";
import Comparison from "./Comparison";
import Community from "./Community";
import Join from "@/components/Join";
import Faq from "./Faq";
const PricingPage = () => {
return (
<Layout>
<Pricing />
<Comparison />
<Community />
<Faq />
<Join />
</Layout>
);
};
export default PricingPage;

View File

@@ -1,22 +0,0 @@
"use client";
import Layout from "@/components/Layout";
import Pricing from "./Pricing";
import Comparison from "./Comparison";
import Community from "./Community";
import Join from "@/components/Join";
import Faq from "./Faq";
const PricingPage = () => {
return (
<Layout>
<Pricing />
<Comparison />
<Community />
<Faq />
<Join />
</Layout>
);
};
export default PricingPage;

View File

@@ -1,58 +0,0 @@
import Section from "@/components/Section";
import Heading from "@/components/Heading";
import Button from "@/components/Button";
import Generating from "@/components/Generating";
import Image from "@/components/Image";
type HeroProps = {};
const Hero = ({}: HeroProps) => (
<Section>
<div className="container md:pt-10 lg:pt-16 xl:pt-20">
<Heading
className="md:mb-15"
textAlignClassName="text-center"
titleLarge="Roadmap"
textLarge="This document provides a comprehensive guide to developing a chat AI app, including its key features and development steps."
>
<Button
className="mt-8 md:mt-12"
href="mailto:info@ui8.net"
white
>
Suggest features
</Button>
</Heading>
<div className="relative max-w-5xl mx-auto">
<div className="relative z-1 p-0.5 rounded-2xl bg-conic-gradient">
<div className="relative bg-n-8 rounded-[0.875rem]">
<div className="h-[1.375rem] bg-[#43435C] rounded-t-[0.875rem]"></div>
<div className="relative h-[30.625rem] rounded-b-[0.875rem] overflow-hidden">
<Image
className="absolute top-1/2 left-1/2 max-w-none -translate-x-[51%] -translate-y-[58%]"
src="/images/roadmap/hero.png"
width={654}
height={932}
alt="Hero"
/>
</div>
<div className="hidden absolute -top-20 left-[14%] md:block pointer-events-none">
<Image
className="w-full"
src="/images/roadmap/coins.png"
width={76}
height={190}
alt="Coins"
/>
</div>
<Generating className="absolute left-4 right-4 bottom-5 border border-n-1/10 md:left-1/2 md:right-auto md:bottom-8 md:w-[30.5rem] md:-translate-x-1/2" />
</div>
</div>
<div className="relative z-1 h-6 mx-2.5 bg-[#1B1B2E] shadow-xl rounded-b-[1.25rem] lg:h-6 lg:mx-8"></div>
<div className="relative z-1 h-6 mx-6 bg-[#1B1B2E]/70 shadow-xl rounded-b-[1.25rem] lg:h-6 lg:mx-20"></div>
</div>
</div>
</Section>
);
export default Hero;

View File

@@ -1,58 +0,0 @@
import Section from "@/components/Section";
import Heading from "@/components/Heading";
import Button from "@/components/Button";
import Generating from "@/components/Generating";
import Image from "@/components/Image";
type HeroProps = {};
const Hero = ({}: HeroProps) => (
<Section>
<div className="container md:pt-10 lg:pt-16 xl:pt-20">
<Heading
className="md:mb-15"
textAlignClassName="text-center"
titleLarge="Roadmap"
textLarge="This document provides a comprehensive guide to developing a chat AI app, including its key features and development steps."
>
<Button
className="mt-8 md:mt-12"
href="mailto:info@ui8.net"
white
>
Suggest features
</Button>
</Heading>
<div className="relative max-w-5xl mx-auto">
<div className="relative z-1 p-0.5 rounded-2xl bg-conic-gradient">
<div className="relative bg-n-8 rounded-[0.875rem]">
<div className="h-[1.375rem] bg-[#43435C] rounded-t-[0.875rem]"></div>
<div className="relative h-[30.625rem] rounded-b-[0.875rem] overflow-hidden">
<Image
className="absolute top-1/2 left-1/2 max-w-none -translate-x-[51%] -translate-y-[58%]"
src="/images/roadmap/hero.png"
width={654}
height={932}
alt="Hero"
/>
</div>
<div className="hidden absolute -top-20 left-[14%] md:block pointer-events-none">
<Image
className="w-full"
src="/images/roadmap/coins.png"
width={76}
height={190}
alt="Coins"
/>
</div>
<Generating className="absolute left-4 right-4 bottom-5 border border-n-1/10 md:left-1/2 md:right-auto md:bottom-8 md:w-[30.5rem] md:-translate-x-1/2" />
</div>
</div>
<div className="relative z-1 h-6 mx-2.5 bg-[#1B1B2E] shadow-xl rounded-b-[1.25rem] lg:h-6 lg:mx-8"></div>
<div className="relative z-1 h-6 mx-6 bg-[#1B1B2E]/70 shadow-xl rounded-b-[1.25rem] lg:h-6 lg:mx-20"></div>
</div>
</div>
</Section>
);
export default Hero;

View File

@@ -1,60 +0,0 @@
import Image from "@/components/Image";
import Section from "@/components/Section";
import Tagline from "@/components/Tagline";
import { roadmapFull } from "@/mocks/roadmap";
type RoadmapProps = {};
const Roadmap = ({}: RoadmapProps) => (
<Section>
<div className="container max-w-[70rem]">
<ul className="-mb-15 md:mb-0">
{roadmapFull.map((item) => (
<li
className="relative mb-15 md:flex md:mb-0"
key={item.id}
>
<div className="flex items-center h-14 mb-3 md:w-[16rem] md:h-[6.5rem] md:mb-0 lg:h-[9.5rem]">
<Tagline className="mr-8">{item.date}</Tagline>
<div className="w-32 h-0.25 bg-n-6 md:flex-1"></div>
</div>
<div className="md:flex md:flex-1 md:p-6 md:border-l md:border-n-6 lg:py-12 lg:px-20">
<div className="mb-6 md:flex-shrink-0 md:w-14 md:mr-6 md:mb-0">
<Image
src={
item.status === "done"
? "/images/roadmap/done.svg"
: "/images/roadmap/undone.svg"
}
width={56}
height={56}
alt="Done"
/>
</div>
<div className="md:flex-1">
<div className="mb-5 md:flex md:items-center md:justify-between md:min-h-[3.5rem] md:mb-6">
<h5 className="h5">{item.title}</h5>
{item.status === "progress" && (
<div className="absolute top-4 right-0 flex items-center px-4 py-1 bg-n-1 rounded text-n-8 md:static md:flex-shrink-0 md:self-start md:mt-4 md:ml-6">
<Image
className="mr-2.5"
src="/images/icons/loading-01.svg"
width={16}
height={16}
alt="In progress"
/>
<div className="tagline">WIP</div>
</div>
)}
</div>
<p className="body-2 text-n-4">{item.text}</p>
</div>
</div>
</li>
))}
</ul>
</div>
</Section>
);
export default Roadmap;

View File

@@ -1,60 +0,0 @@
import Image from "@/components/Image";
import Section from "@/components/Section";
import Tagline from "@/components/Tagline";
import { roadmapFull } from "@/mocks/roadmap";
type RoadmapProps = {};
const Roadmap = ({}: RoadmapProps) => (
<Section>
<div className="container max-w-[70rem]">
<ul className="-mb-15 md:mb-0">
{roadmapFull.map((item) => (
<li
className="relative mb-15 md:flex md:mb-0"
key={item.id}
>
<div className="flex items-center h-14 mb-3 md:w-[16rem] md:h-[6.5rem] md:mb-0 lg:h-[9.5rem]">
<Tagline className="mr-8">{item.date}</Tagline>
<div className="w-32 h-0.25 bg-n-6 md:flex-1"></div>
</div>
<div className="md:flex md:flex-1 md:p-6 md:border-l md:border-n-6 lg:py-12 lg:px-20">
<div className="mb-6 md:flex-shrink-0 md:w-14 md:mr-6 md:mb-0">
<Image
src={
item.status === "done"
? "/images/roadmap/done.svg"
: "/images/roadmap/undone.svg"
}
width={56}
height={56}
alt="Done"
/>
</div>
<div className="md:flex-1">
<div className="mb-5 md:flex md:items-center md:justify-between md:min-h-[3.5rem] md:mb-6">
<h5 className="h5">{item.title}</h5>
{item.status === "progress" && (
<div className="absolute top-4 right-0 flex items-center px-4 py-1 bg-n-1 rounded text-n-8 md:static md:flex-shrink-0 md:self-start md:mt-4 md:ml-6">
<Image
className="mr-2.5"
src="/images/icons/loading-01.svg"
width={16}
height={16}
alt="In progress"
/>
<div className="tagline">WIP</div>
</div>
)}
</div>
<p className="body-2 text-n-4">{item.text}</p>
</div>
</div>
</li>
))}
</ul>
</div>
</Section>
);
export default Roadmap;

View File

@@ -1,18 +0,0 @@
"use client";
import Layout from "@/components/Layout";
import Join from "@/components/Join";
import Hero from "./Hero";
import Roadmap from "./Roadmap";
const RoadmapPage = () => {
return (
<Layout>
<Hero />
<Roadmap />
<Join />
</Layout>
);
};
export default RoadmapPage;

View File

@@ -1,18 +0,0 @@
"use client";
import Layout from "@/components/Layout";
import Join from "@/components/Join";
import Hero from "./Hero";
import Roadmap from "./Roadmap";
const RoadmapPage = () => {
return (
<Layout>
<Hero />
<Roadmap />
<Join />
</Layout>
);
};
export default RoadmapPage;