mirror of
https://github.com/supermemoryai/supermemory.git
synced 2026-05-07 00:41:13 +00:00
Merge pull request #50 from CodeTorso/improved-landing-page
landing page improved for readability and smooth scroll
This commit is contained in:
commit
d34450f54e
12 changed files with 240 additions and 105 deletions
|
|
@ -6,13 +6,13 @@ function Cta() {
|
|||
return (
|
||||
<section
|
||||
id="try"
|
||||
className="relative mb-32 mt-40 flex w-full flex-col items-center justify-center gap-8"
|
||||
className="relative mb-44 mt-60 flex w-full flex-col items-center justify-center gap-8"
|
||||
>
|
||||
<div className="absolute left-0 z-[-1] h-full w-full">
|
||||
{/* a blue gradient line that's slightly tilted with blur (a lotof blur)*/}
|
||||
<div className="overflow-hidden">
|
||||
<div
|
||||
className="absolute left-0 h-32 w-full overflow-hidden bg-[#369DFD] bg-opacity-70 blur-[337.4px]"
|
||||
className="absolute left-[20%] top-[-165%] h-32 w-full overflow-hidden bg-[#369DFD] bg-opacity-70 blur-[337.4px]"
|
||||
style={{ transform: "rotate(-30deg)" }}
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -26,7 +26,7 @@ function Cta() {
|
|||
draggable="false"
|
||||
className="absolute z-[-2] hidden select-none rounded-3xl bg-black md:block lg:w-[80%]"
|
||||
/>
|
||||
<h1 className="z-20 mt-4 text-center text-5xl font-light text-white">
|
||||
<h1 className="z-20 mt-4 text-center text-5xl font-medium tracking-tight text-white">
|
||||
Your bookmarks are collecting dust.
|
||||
</h1>
|
||||
<div className="text-center text-sm text-zinc-500">
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ function EmailInput() {
|
|||
<input
|
||||
type="email"
|
||||
name="email"
|
||||
className={`transition-width flex w-full items-center rounded-2xl bg-[#37485E] px-4 py-2 duration-300 focus:outline-none`}
|
||||
className={`transition-width flex w-full items-center rounded-2xl bg-[#37485E] px-4 py-2 duration-300 focus:outline-none outline-none`}
|
||||
placeholder="Enter your email"
|
||||
value={email}
|
||||
required
|
||||
|
|
|
|||
59
apps/web-v2/src/app/(landing)/FeatureContent.tsx
Normal file
59
apps/web-v2/src/app/(landing)/FeatureContent.tsx
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
export const features = [
|
||||
{
|
||||
title: "For Researchers",
|
||||
description:
|
||||
"Add content to collections and use it as a knowledge base for your research, link multiple sources together to get a better understanding of the topic.",
|
||||
svg: <ResearchSvg />
|
||||
},
|
||||
{
|
||||
title: "For Content writers",
|
||||
description:
|
||||
"Save time and use the writing assistant to generate content based on your own saved collections and sources.",
|
||||
svg: <ContentSvg />
|
||||
},
|
||||
{
|
||||
title: "For Developers",
|
||||
description:
|
||||
"Talk to documentation websites, code snippets, etc. so you never have to google the same thing a hundred times.",
|
||||
svg: <DeveloperSvg />
|
||||
},
|
||||
];
|
||||
|
||||
function ResearchSvg() {
|
||||
return (
|
||||
<svg
|
||||
className="mr-3 shrink-0 fill-zinc-400"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
>
|
||||
<path d="m7.951 14.537 6.296-7.196 1.506 1.318-7.704 8.804-3.756-3.756 1.414-1.414 2.244 2.244Zm11.296-7.196 1.506 1.318-7.704 8.804-1.756-1.756 1.414-1.414.244.244 6.296-7.196Z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
function ContentSvg() {
|
||||
return (
|
||||
<svg
|
||||
className="mr-3 shrink-0 fill-zinc-400"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
>
|
||||
<path d="m16.997 19.056-1.78-.912A13.91 13.91 0 0 0 16.75 11.8c0-2.206-.526-4.38-1.533-6.344l1.78-.912A15.91 15.91 0 0 1 18.75 11.8c0 2.524-.602 5.01-1.753 7.256Zm-3.616-1.701-1.77-.93A9.944 9.944 0 0 0 12.75 11.8c0-1.611-.39-3.199-1.14-4.625l1.771-.93c.9 1.714 1.37 3.62 1.369 5.555 0 1.935-.47 3.841-1.369 5.555Zm-3.626-1.693-1.75-.968c.49-.885.746-1.881.745-2.895a5.97 5.97 0 0 0-.745-2.893l1.75-.968a7.968 7.968 0 0 1 .995 3.861 7.97 7.97 0 0 1-.995 3.863Zm-3.673-1.65-1.664-1.11c.217-.325.333-.709.332-1.103 0-.392-.115-.776-.332-1.102L6.082 9.59c.437.655.67 1.425.668 2.21a3.981 3.981 0 0 1-.668 2.212Z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
function DeveloperSvg() {
|
||||
return (
|
||||
<svg
|
||||
className="mr-3 shrink-0 fill-zinc-400"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
>
|
||||
<path d="m11.293 5.293 1.414 1.414-8 8-1.414-1.414 8-8Zm7-1 1.414 1.414-8 8-1.414-1.414 8-8Zm0 6 1.414 1.414-8 8-1.414-1.414 8-8Z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
|
@ -6,8 +6,11 @@ import Image from "next/image";
|
|||
import CarouselIllustration from "@/../public/images/carousel-illustration-01.png";
|
||||
import { X } from "@/utils/icons";
|
||||
|
||||
import { features } from "./FeatureContent";
|
||||
import { CardClick } from "@/components/ui/cardClick";
|
||||
|
||||
export default function Features() {
|
||||
const [tab, setTab] = useState<number>(1);
|
||||
const [tab, setTab] = useState<number>(0);
|
||||
|
||||
const tabs = useRef<HTMLDivElement>(null);
|
||||
|
||||
|
|
@ -16,17 +19,21 @@ export default function Features() {
|
|||
tabs.current.parentElement.style.height = `${tabs.current.clientHeight}px`;
|
||||
};
|
||||
|
||||
function handleClickIndex(tab:number){
|
||||
setTab(tab);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
heightFix();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<section className="relative w-full overflow-hidden after:pointer-events-none after:absolute after:right-0 after:top-0 after:h-full after:w-96 after:bg-gradient-to-l after:from-[#369DFD30] max-lg:after:hidden">
|
||||
<div className="py-12 md:py-20">
|
||||
<section className="relative w-full overflow-hidden max-lg:after:hidden">
|
||||
<div className="py-12 md:pb-32">
|
||||
{/* Carousel */}
|
||||
<div
|
||||
id="use-cases"
|
||||
className="mx-auto max-w-xl px-4 sm:px-6 lg:max-w-6xl"
|
||||
className="mx-auto max-w-xl px-4 sm:px-6 lg:max-w-6xl md:pt-40"
|
||||
>
|
||||
<div className="space-y-12 lg:flex lg:space-x-12 lg:space-y-0 xl:space-x-24">
|
||||
{/* Content */}
|
||||
|
|
@ -46,82 +53,7 @@ export default function Features() {
|
|||
</div>
|
||||
{/* Tabs buttons */}
|
||||
<div className="mb-8 space-y-2 md:mb-0">
|
||||
<button
|
||||
className={`flex items-center rounded-2xl border border-transparent px-6 py-4 text-left ${tab !== 1 ? "" : "[background:linear-gradient(#2E2E32,#2E2E32)_padding-box,linear-gradient(120deg,theme(colors.zinc.700),theme(colors.zinc.700/0),theme(colors.zinc.700))_border-box]"}`}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
setTab(1);
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
className="mr-3 shrink-0 fill-zinc-400"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
>
|
||||
<path d="m7.951 14.537 6.296-7.196 1.506 1.318-7.704 8.804-3.756-3.756 1.414-1.414 2.244 2.244Zm11.296-7.196 1.506 1.318-7.704 8.804-1.756-1.756 1.414-1.414.244.244 6.296-7.196Z" />
|
||||
</svg>
|
||||
<div>
|
||||
<div className="font-inter-tight mb-1 text-lg font-semibold text-zinc-200">
|
||||
For Researchers
|
||||
</div>
|
||||
<div className="text-zinc-500">
|
||||
Add content to collections and use it as a knowledge base
|
||||
for your research, link multiple sources together to get a
|
||||
better understanding of the topic.
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
<button
|
||||
className={`flex items-center rounded-2xl border border-transparent px-6 py-4 text-left ${tab !== 2 ? "" : "[background:linear-gradient(#2E2E32,#2E2E32)_padding-box,linear-gradient(120deg,theme(colors.zinc.700),theme(colors.zinc.700/0),theme(colors.zinc.700))_border-box]"}`}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
setTab(2);
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
className="mr-3 shrink-0 fill-zinc-400"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
>
|
||||
<path d="m16.997 19.056-1.78-.912A13.91 13.91 0 0 0 16.75 11.8c0-2.206-.526-4.38-1.533-6.344l1.78-.912A15.91 15.91 0 0 1 18.75 11.8c0 2.524-.602 5.01-1.753 7.256Zm-3.616-1.701-1.77-.93A9.944 9.944 0 0 0 12.75 11.8c0-1.611-.39-3.199-1.14-4.625l1.771-.93c.9 1.714 1.37 3.62 1.369 5.555 0 1.935-.47 3.841-1.369 5.555Zm-3.626-1.693-1.75-.968c.49-.885.746-1.881.745-2.895a5.97 5.97 0 0 0-.745-2.893l1.75-.968a7.968 7.968 0 0 1 .995 3.861 7.97 7.97 0 0 1-.995 3.863Zm-3.673-1.65-1.664-1.11c.217-.325.333-.709.332-1.103 0-.392-.115-.776-.332-1.102L6.082 9.59c.437.655.67 1.425.668 2.21a3.981 3.981 0 0 1-.668 2.212Z" />
|
||||
</svg>
|
||||
<div>
|
||||
<div className="font-inter-tight mb-1 text-lg font-semibold text-zinc-200">
|
||||
For Content writers
|
||||
</div>
|
||||
<div className="text-zinc-500">
|
||||
Save time and use the writing assistant to generate
|
||||
content based on your own saved collections and sources.
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
<button
|
||||
className={`flex items-center rounded-2xl border border-transparent px-6 py-4 text-left ${tab !== 3 ? "" : "[background:linear-gradient(#2E2E32,#2E2E32)_padding-box,linear-gradient(120deg,theme(colors.zinc.700),theme(colors.zinc.700/0),theme(colors.zinc.700))_border-box]"}`}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
setTab(3);
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
className="mr-3 shrink-0 fill-zinc-400"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
>
|
||||
<path d="m11.293 5.293 1.414 1.414-8 8-1.414-1.414 8-8Zm7-1 1.414 1.414-8 8-1.414-1.414 8-8Zm0 6 1.414 1.414-8 8-1.414-1.414 8-8Z" />
|
||||
</svg>
|
||||
<div>
|
||||
<div className="font-inter-tight mb-1 text-lg font-semibold text-zinc-200">
|
||||
For Developers
|
||||
</div>
|
||||
<div className="text-zinc-500">
|
||||
Talk to documentation websites, code snippets, etc. so you
|
||||
never have to google the same thing a hundred times.
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
<CardClick tab={tab} items={features} handleClickIndex={handleClickIndex} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -130,7 +62,7 @@ export default function Features() {
|
|||
<div className="relative flex flex-col" ref={tabs}>
|
||||
{/* Item 1 */}
|
||||
<Transition
|
||||
show={tab === 1}
|
||||
show={tab === 0}
|
||||
enter="transition ease-in-out duration-700 transform order-first"
|
||||
enterFrom="opacity-0 -translate-y-4"
|
||||
enterTo="opacity-100 translate-y-0"
|
||||
|
|
@ -152,7 +84,7 @@ export default function Features() {
|
|||
</Transition>
|
||||
{/* Item 2 */}
|
||||
<Transition
|
||||
show={tab === 2}
|
||||
show={tab === 1}
|
||||
enter="transition ease-in-out duration-700 transform order-first"
|
||||
enterFrom="opacity-0 -translate-y-4"
|
||||
enterTo="opacity-100 translate-y-0"
|
||||
|
|
@ -174,7 +106,7 @@ export default function Features() {
|
|||
</Transition>
|
||||
{/* Item 3 */}
|
||||
<Transition
|
||||
show={tab === 3}
|
||||
show={tab === 2}
|
||||
enter="transition ease-in-out duration-700 transform order-first"
|
||||
enterFrom="opacity-0 -translate-y-4"
|
||||
enterTo="opacity-100 translate-y-0"
|
||||
|
|
@ -202,7 +134,7 @@ export default function Features() {
|
|||
{/* Features blocks */}
|
||||
<div
|
||||
id="features"
|
||||
className="mx-auto mt-24 max-w-6xl px-4 sm:px-6 lg:mt-32"
|
||||
className="mx-auto mt-24 max-w-6xl px-4 sm:px-6 md:pt-40"
|
||||
>
|
||||
<div className="grid gap-8 sm:grid-cols-2 lg:grid-cols-3 lg:gap-16">
|
||||
{/* Block #1 */}
|
||||
|
|
@ -320,6 +252,7 @@ export default function Features() {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import React from "react";
|
|||
import { motion } from "framer-motion";
|
||||
import { Twitter } from "@/utils/icons";
|
||||
import EmailInput from "./EmailInput";
|
||||
import LinkArrow from "./linkArrow";
|
||||
|
||||
const slap = {
|
||||
initial: {
|
||||
|
|
@ -20,19 +21,20 @@ const slap = {
|
|||
function Hero() {
|
||||
return (
|
||||
<>
|
||||
<section className="mt-24 flex max-w-xl flex-col items-center justify-center gap-8 md:mt-40">
|
||||
<section className="mt-24 flex max-w-xl flex-col items-center justify-center gap-10 md:mt-56">
|
||||
<a
|
||||
className="flex items-center justify-center gap-4 rounded-full bg-white/10 px-4 py-2 text-sm"
|
||||
className="group/anchor pl-10 pr-6 flex items-center justify-center gap-4 rounded-full text-white/80 bg-white/10 py-2 text-sm"
|
||||
href="https://twitter.com/supermemoryai"
|
||||
target="_blank"
|
||||
>
|
||||
<Twitter className="h-4 w-4 text-white" /> Follow us on Twitter
|
||||
<Twitter className="h-4 w-4" /><div className="flex"> Follow us on Twitter <LinkArrow classname="group-hover/anchor:opacity-100 opacity-0 transition" stroke="#ffffff" /></div>
|
||||
</a>
|
||||
<motion.h1
|
||||
{...{
|
||||
...slap,
|
||||
transition: { ...slap.transition, delay: 0.2 },
|
||||
}}
|
||||
className="text-center text-4xl font-light text-white md:text-5xl"
|
||||
className="text-center text-4xl text-white/95 md:text-5xl tracking-normal font-semibold"
|
||||
>
|
||||
Build your own second brain with Supermemory
|
||||
</motion.h1>
|
||||
|
|
@ -58,7 +60,7 @@ function Hero() {
|
|||
width={1512}
|
||||
height={1405}
|
||||
draggable="false"
|
||||
className="z-[-2] mt-16 h-full w-[80%] select-none"
|
||||
className="z-[-2] mt-28 h-full w-[80%] select-none"
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ function Navbar() {
|
|||
return (
|
||||
<nav className="fixed top-0 z-[99999] mt-12 hidden w-full px-24 text-sm md:flex">
|
||||
<div className="flex w-full flex-row justify-between rounded-2xl bg-white/10 shadow-[0px_2px_3px_-1px_rgba(0,0,0,0.1),0px_1px_0px_0px_rgba(25,28,33,0.02),0px_0px_0px_1px_rgba(25,28,33,0.08)] backdrop-blur-lg backdrop-filter">
|
||||
<Link href={"/"} className="flex flex-row items-center p-3 opacity-50">
|
||||
<Link href={"/"} className="flex items-center p-3 opacity-50">
|
||||
<Image src={Logo} alt="Supermemory logo" width={40} height={40} />
|
||||
</Link>
|
||||
<div className="flex flex-row items-center gap-8 p-3">
|
||||
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 flex items-center gap-8 p-3">
|
||||
<Link href={"#use-cases"} className="text-soft-foreground-text">
|
||||
Use cases
|
||||
</Link>
|
||||
|
|
|
|||
17
apps/web-v2/src/app/(landing)/footer.tsx
Normal file
17
apps/web-v2/src/app/(landing)/footer.tsx
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import React from 'react'
|
||||
import LinkArrow from './linkArrow'
|
||||
|
||||
function Footer() {
|
||||
return (
|
||||
<footer className="mt-20 flex w-full items-center justify-between gap-4 px-8 py-8 text-sm text-zinc-500">
|
||||
<p>© 2024 Supermemory.ai</p>
|
||||
<div className="flex gap-5">
|
||||
<a className='flex group/mail' target='_blank' href="mailto:hi@dhravya.dev">Contact<LinkArrow classname='group-hover/mail:opacity-100 opacity-0 transition' stroke='#ffffff' /></a>
|
||||
<a className='flex group/twit' target='_blank' href="https://twitter.com/supermemoryai">Twitter <LinkArrow classname='group-hover/twit:opacity-100 opacity-0 transition' stroke='#ffffff' /></a>
|
||||
<a className='flex group/git' target='_blank' href="https://github.com/dhravya/supermemory">Github <LinkArrow stroke='#ffffff' classname='group-hover/git:opacity-100 opacity-0 transition' /></a>
|
||||
</div>
|
||||
</footer>
|
||||
)
|
||||
}
|
||||
|
||||
export default Footer
|
||||
9
apps/web-v2/src/app/(landing)/linkArrow.tsx
Normal file
9
apps/web-v2/src/app/(landing)/linkArrow.tsx
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import React from 'react'
|
||||
|
||||
function LinkArrow({stroke, classname}: {stroke: string, classname?: string}) {
|
||||
return (
|
||||
<svg className={classname} width="24px" height="24px" viewBox="-2.4 -2.4 28.80 28.80" fill="none" xmlns="http://www.w3.org/2000/svg" transform="matrix(1, 0, 0, 1, 0, 0)rotate(0)"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <path d="M7 17L17 7M17 7H8M17 7V16" stroke={stroke} stroke-width="0.792" stroke-linecap="round" stroke-linejoin="round"></path> </g></svg>
|
||||
)
|
||||
}
|
||||
|
||||
export default LinkArrow
|
||||
|
|
@ -1,16 +1,18 @@
|
|||
import Features from "./Features";
|
||||
import RotatingIcons from "./RotatingIcons";
|
||||
import Hero from "./Hero";
|
||||
import Navbar from "./Navbar";
|
||||
import Cta from "./Cta";
|
||||
import { Toaster } from "@/components/ui/toaster";
|
||||
import Features from "./Features";
|
||||
import Footer from "./footer";
|
||||
|
||||
export const runtime = "edge";
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<main className="dark flex min-h-screen flex-col items-center overflow-x-hidden px-2 md:px-0">
|
||||
<Navbar />
|
||||
|
||||
<Navbar />
|
||||
|
||||
{/* Background gradients */}
|
||||
<div className="absolute left-0 top-0 z-[-1] h-full w-full">
|
||||
|
|
@ -28,6 +30,12 @@ export default function Home() {
|
|||
style={{ transform: "rotate(-30deg)" }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="overflow-x-hidden">
|
||||
<div
|
||||
className="absolute right-0 top-[145%] h-40 w-[17%] overflow-x-hidden bg-[#369DFD] bg-opacity-20 blur-[110px]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Hero section */}
|
||||
|
|
@ -36,20 +44,16 @@ export default function Home() {
|
|||
{/* Features section */}
|
||||
<Features />
|
||||
|
||||
|
||||
<RotatingIcons />
|
||||
|
||||
<Cta />
|
||||
|
||||
<Toaster />
|
||||
|
||||
<footer className="mt-16 flex w-full items-center justify-between gap-4 border-t border-zinc-200/50 px-8 py-8 text-sm text-zinc-500">
|
||||
<p>© 2024 Supermemory.ai</p>
|
||||
<div className="flex gap-4">
|
||||
<a href="mailto:hi@dhravya.dev">Contact</a>
|
||||
<a href="https://twitter.com/supermemoryai">Twitter</a>
|
||||
<a href="https://github.com/dhravya/supermemory">Github</a>
|
||||
</div>
|
||||
</footer>
|
||||
<Footer />
|
||||
|
||||
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,6 +82,30 @@
|
|||
}
|
||||
}
|
||||
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
/* width */
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
}
|
||||
|
||||
/* Track */
|
||||
::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/* Handle */
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #131F2C;
|
||||
}
|
||||
|
||||
/* Handle on hover */
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: #22303d;
|
||||
}
|
||||
|
||||
body {
|
||||
color: rgb(var(--foreground-rgb));
|
||||
background: linear-gradient(to bottom, transparent, var(--black-bg))
|
||||
|
|
|
|||
81
apps/web-v2/src/components/ui/cardClick.tsx
Normal file
81
apps/web-v2/src/components/ui/cardClick.tsx
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
"use client";
|
||||
|
||||
import { cn } from "@/utils/cn";
|
||||
import { AnimatePresence, motion } from "framer-motion";
|
||||
import React from "react";
|
||||
|
||||
export const CardClick = ({
|
||||
tab,
|
||||
handleClickIndex,
|
||||
items,
|
||||
}: {
|
||||
tab: number,
|
||||
handleClickIndex: (tab: number)=>void,
|
||||
items: {
|
||||
title: string;
|
||||
description: string;
|
||||
svg: React.ReactNode
|
||||
}[];
|
||||
}) => {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"flex flex-col",
|
||||
)}
|
||||
>
|
||||
{items.map((item, idx) => (
|
||||
<div
|
||||
key={idx}
|
||||
className="group relative block h-full w-full p-2"
|
||||
onMouseDown={() => handleClickIndex(idx)}
|
||||
>
|
||||
<AnimatePresence>
|
||||
{tab === idx && (
|
||||
<motion.span
|
||||
className="absolute -z-[1] inset-0 block h-full w-full rounded-3xl [background:linear-gradient(#2E2E32,#2E2E32),linear-gradient(120deg,theme(colors.zinc.700),theme(colors.zinc.700/0),theme(colors.zinc.700))]"
|
||||
layoutId="hoverBackground"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{
|
||||
opacity: 1,
|
||||
transition: { duration: 0.15 },
|
||||
}}
|
||||
exit={{
|
||||
opacity: 0,
|
||||
transition: { duration: 0.15, delay: 0.2 },
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
<Card title={item.title} description={item.description} svg={item.svg} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const Card = ({
|
||||
title,
|
||||
description,
|
||||
svg
|
||||
}: {
|
||||
title: string;
|
||||
description: string;
|
||||
svg: React.ReactNode;
|
||||
}) => {
|
||||
return (
|
||||
<div
|
||||
className={`flex items-center rounded-2xl border border-transparent px-6 py-4 text-left`}
|
||||
>
|
||||
{svg}
|
||||
<div>
|
||||
<div className="font-inter-tight mb-1 text-lg font-semibold text-zinc-200">
|
||||
{title}
|
||||
</div>
|
||||
<div className="text-zinc-500">
|
||||
{description}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
6
apps/web-v2/src/utils/cn.ts
Normal file
6
apps/web-v2/src/utils/cn.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import { ClassValue, clsx } from "clsx";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs));
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue