feat: 10.10线上最新代码提交
This commit is contained in:
130
src/templates/HomePage/Collaboration/index.js
Normal file
130
src/templates/HomePage/Collaboration/index.js
Normal file
@@ -0,0 +1,130 @@
|
||||
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;
|
||||
152
src/templates/HomePage/HowItWorks/index.js
Normal file
152
src/templates/HomePage/HowItWorks/index.js
Normal file
@@ -0,0 +1,152 @@
|
||||
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;
|
||||
69
src/templates/HomePage/Pricing/index.js
Normal file
69
src/templates/HomePage/Pricing/index.js
Normal file
@@ -0,0 +1,69 @@
|
||||
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;
|
||||
97
src/templates/HomePage/Roadmap/index.js
Normal file
97
src/templates/HomePage/Roadmap/index.js
Normal file
@@ -0,0 +1,97 @@
|
||||
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 we’re 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;
|
||||
90
src/templates/HomePage/Testimonials/index.js
Normal file
90
src/templates/HomePage/Testimonials/index.js
Normal file
@@ -0,0 +1,90 @@
|
||||
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;
|
||||
30
src/templates/HomePage/index.js
Normal file
30
src/templates/HomePage/index.js
Normal file
@@ -0,0 +1,30 @@
|
||||
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;
|
||||
Reference in New Issue
Block a user