damus.io

damus.io website
git clone git://jb55.com/damus.io
Log | Files | Refs | README | LICENSE

NotedeckHero.tsx (6470B)


      1 import { TopMenu } from "../TopMenu";
      2 import { Onest } from 'next/font/google'
      3 import { Button } from "../../ui/Button";
      4 import { FormattedMessage, useIntl } from "react-intl";
      5 import Link from "next/link";
      6 import { motion, useScroll, useTransform } from "framer-motion";
      7 import Image from "next/image";
      8 import { NOTEDECK_WAITLIST_URL } from "@/lib/constants";
      9 import { cn } from "@/lib/utils";
     10 import { ArrowUpRight, ChevronRight, Sparkles } from "lucide-react";
     11 import { useRef } from "react";
     12 
     13 const onest = Onest({ subsets: ['latin'] })
     14 
     15 export function NotedeckHero({ className, introducing }: { className?: string, introducing?: boolean }) {
     16   const intl = useIntl()
     17   const ref = useRef(null)
     18   const { scrollYProgress } = useScroll({
     19     target: ref,
     20     offset: ["start start", "end start"]
     21   })
     22   const mobileScreenshotOffsetX = useTransform(scrollYProgress, [0, 1], [0, -1200]);
     23   const bgOpacity = useTransform(scrollYProgress, [0.3, 1], [1.0, 0.0]);
     24 
     25   return (<>
     26     <div
     27       ref={ref}
     28       className={cn("bg-black overflow-hidden flex-col relative min-h-screen", className)}
     29     >
     30       <motion.div className="container mt-28 z-10 mx-auto px-6 pt-6 flex flex-col justify-center">
     31         <motion.div
     32           className="flex flex-col items-start justify-start h-full grow mt-8 z-10"
     33           style={{ opacity: 0 }}
     34           animate={{ opacity: 1, transition: { delay: 0.5, duration: 1 } }}
     35         >
     36           {introducing && (
     37             <motion.h1
     38                 className={cn("text-2xl uppercase text-white/80 mb-12", onest.className)}
     39             >
     40                 Introducing
     41             </motion.h1>
     42           )}
     43           <div className="flex gap-x-4 items-center mb-2 md:mb-6">
     44             <Image
     45               src="/logo_icon.png"
     46               alt="damus logo"
     47               width={80}
     48               height={80}
     49               className="rounded-lg md:rounded-xl lg:rounded-2xl w-12 md:w-16 lg:w-20 aspect-square"
     50             />
     51             <motion.h1
     52                 className={cn("text-4xl sm:text-4xl md:text-7xl text-transparent bg-clip-text font-semibold whitespace-pre-line max-w-4xl tracking-wide leading-loose", onest.className)}
     53                 style={{
     54                     backgroundImage: "linear-gradient(to right, #ffffff -100%, #ffffff -80%, #2D175B 100%)",
     55                     opacity: 0,
     56                 }}
     57                 animate={{
     58                     backgroundImage: "linear-gradient(to right, #ffffff 0%, #ffffff 100%, #2D175B 180%)",
     59                     transition: { duration: 3 },
     60                     opacity: 1
     61                 }}
     62             >
     63                 Notedeck
     64             </motion.h1>
     65           </div>
     66           <motion.h2
     67               className={cn("mt-2 text-2xl sm:text-3xl md:text-5xl text-transparent bg-clip-text pb-6 font-semibold whitespace-pre-line max-w-4xl tracking-wide leading-8 md:leading-snug lg:leading-normal", onest.className)}
     68               style={{
     69                   backgroundImage: "linear-gradient(to right, #ffffff -100%, #ffffff -40%, #2D175B 100%)",
     70                   opacity: 0,
     71               }}
     72               animate={{
     73                   backgroundImage: "linear-gradient(to right, #ffffff 0%, #ffffff 40%, #2D175B 100%)",
     74                   transition: { duration: 3 },
     75                   opacity: 1
     76               }}
     77           >
     78               <FormattedMessage defaultMessage="Damus. Everywhere. The fastest native, customizable nostr experience, for all platforms." id="notedeck.hero.headline"/>
     79           </motion.h2>
     80           <motion.div
     81             className="inline-flex gap-2 items-center text-xs md:text-md rounded-full bg-purple-100/10 backdrop-blur-sm shadow-lg p-1 px-3 text-purple-100/80 border border-purple-100/30 active:scale-95 transition mt-2 mb-8 md:mb-10"
     82             style={{ opacity: 0 }}
     83             animate={{ opacity: 1, transition: { delay: 1.5, duration: 1 } }}
     84           >
     85             <Sparkles className="h-4 mr-1 text-purple-50" aria-hidden="true" />
     86             {intl.formatMessage({ id: "notedeck.hero.announcement", defaultMessage: "Notedeck Alpha now available on Purple" })}
     87           </motion.div>
     88           <motion.div
     89             className="mt-6 md:mt-4 mb-8 flex flex-col md:flex-row items-center md:items-center gap-y-4 gap-x-6 w-full md:w-auto"
     90             style={{ opacity: 0 }}
     91             animate={{ opacity: 1, transition: { delay: 1.5, duration: 1 } }}
     92           >
     93             <InstallNowButton/>
     94             <a href={"/notedeck#introducing"}>
     95                 <Button variant="link" className="w-full md:w-auto">
     96                     { intl.formatMessage({ id: "notedeck.hero.learn-more", defaultMessage: "Learn more" }) }
     97 
     98                 </Button>
     99             </a>
    100           </motion.div>
    101         </motion.div>
    102       </motion.div>
    103       <motion.div className="flex justify-end w-full relative">
    104         {/* Gradient fade to black on the bottom */}
    105         <div className="w-full h-96 bottom-0 absolute bg-gradient-to-b from-transparent to-black z-10" />
    106         <motion.div
    107           className="z-0 w-auto pointer-events-none mt-[-553px] overflow-x-hidden overflow-y-visible flex"
    108         >
    109           <motion.img
    110             src="/notedeck/notedeck-hero-2.png"
    111             className="block md:hidden"
    112             style={{
    113               width: "1728px",
    114               height: "1106px",
    115               maxWidth: "1728px",
    116               marginLeft: mobileScreenshotOffsetX,
    117               opacity: bgOpacity
    118             }}
    119             alt="Notedeck screenshot"
    120             sizes="1728px"
    121             width={1728}
    122             height={1106}
    123           />
    124           <motion.img
    125             src="/notedeck/notedeck-hero-2.png"
    126             className="hidden md:block"
    127             style={{
    128               width: "1728px",
    129               height: "1106px",
    130               maxWidth: "1728px",
    131             }}
    132             alt="Notedeck screenshot"
    133             sizes="1728px"
    134             width={1728}
    135             height={1106}
    136           />
    137         </motion.div>
    138       </motion.div>
    139     </div>
    140   </>)
    141 }
    142 
    143 export function InstallNowButton({ className }: { className?: string }) {
    144   const intl = useIntl()
    145 
    146   return (
    147     <Link href={"/notedeck/install"} className={cn("w-full md:w-auto", className)}>
    148       <Button variant="accent" className="w-full flex gap-x-2 text-lg font-semibold">
    149         <Sparkles className="w-4 h-4"/>
    150         {intl.formatMessage({ id: "notedeck.hero.install", defaultMessage: "Install now" })}
    151       </Button>
    152     </Link>
    153   )
    154 }