fix merge conflict

This commit is contained in:
MarconLP 2023-04-28 17:25:57 +02:00
commit 9746927126
No known key found for this signature in database
GPG key ID: F4CAFFDFA3451D5E
6 changed files with 298 additions and 129 deletions

63
src/components/CTA.tsx Normal file
View file

@ -0,0 +1,63 @@
import { useAtom } from "jotai/index";
import recordVideoModalOpen from "~/atoms/recordVideoModalOpen";
import { usePostHog } from "posthog-js/react";
export default function CTA() {
const [, setRecordOpen] = useAtom(recordVideoModalOpen);
const posthog = usePostHog();
const openRecordModal = () => {
setRecordOpen(true);
posthog?.capture("open record video modal", {
cta: "cta section",
});
};
return (
<div className="bg-white">
<div className="mx-auto max-w-7xl py-12 sm:px-6 sm:py-16 lg:px-8">
<div className="relative isolate overflow-hidden bg-gray-900 px-6 py-24 text-center shadow-2xl sm:rounded-3xl sm:px-16">
<h2 className="mx-auto max-w-2xl text-4xl font-bold tracking-tight text-white">
Ready to improve how your team communicates?
</h2>
<div className="mt-10 flex items-center justify-center gap-x-6">
<button
onClick={openRecordModal}
className="inline-flex max-h-[40px] items-center rounded-md border border-transparent bg-red-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2"
>
Record a video
</button>
</div>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 1024 1024"
className="absolute left-1/2 top-1/2 -z-10 h-[64rem] w-[64rem] -translate-x-1/2"
aria-hidden="true"
>
<circle
cx={512}
cy={512}
r={512}
fill="url(#827591b1-ce8c-4110-b064-7cb85a0b1217)"
fillOpacity="0.7"
/>
<defs>
<radialGradient
id="827591b1-ce8c-4110-b064-7cb85a0b1217"
cx={0}
cy={0}
r={1}
gradientUnits="userSpaceOnUse"
gradientTransform="translate(512 512) rotate(90) scale(512)"
>
<stop stopColor="#7775D6" />
<stop offset={1} stopColor="#E935C1" stopOpacity={0} />
</radialGradient>
</defs>
</svg>
</div>
</div>
</div>
);
}

View file

@ -1,35 +1,27 @@
import Link from "next/link";
export default function Footer() { export default function Footer() {
return ( return (
<div className="mx-16 flex items-center justify-center"> <div className="mx-16 flex items-center justify-center">
<footer className="mb-4 mt-4 flex h-full w-[1048px] flex-col-reverse items-center justify-between text-sm md:flex-row"> <footer className="mb-4 mt-4 flex h-full w-[1048px] flex-col-reverse items-center justify-between text-sm md:flex-row">
<div className="mx-8 my-[50px] text-sm text-[#666] md:my-0"> <div className="my-[50px] ml-8 text-sm text-[#666] md:my-0">
© 2023 Snapify © 2023 Snapify
</div> </div>
<div className="mx-8 flex w-full flex-col px-[50px] md:w-auto md:flex-row md:px-0"> <div className="mr-8 flex w-full flex-col sm:px-[50px] md:w-auto md:flex-row md:gap-8 md:px-0">
<a {[
className="flex h-[42px] cursor-pointer items-center border-b border-[#eee] text-sm text-[#666] hover:text-black md:ml-8 md:border-none" { name: "Privacy Policy", link: "/legal/privacy-policy" },
href="/legal/privacy-policy" { name: "Terms and Conditions", link: "/legal/terms" },
> { name: "Status", link: "https://status.snapify.it" },
Privacy Policy { name: "Impressum", link: "/legal/impressum" },
</a> ].map(({ name, link }) => (
<a <Link
className="flex h-[42px] cursor-pointer items-center border-b border-[#eee] text-sm text-[#666] hover:text-black md:ml-8 md:border-none" key={name}
href="/legal/terms" className="flex h-[42px] cursor-pointer items-center border-b border-[#eee] text-sm text-[#666] hover:text-black md:border-none"
> href={link}
Terms and Conditions >
</a> {name}
<a </Link>
className="flex h-[42px] cursor-pointer items-center border-b border-[#eee] text-sm text-[#666] hover:text-black md:ml-8 md:border-none" ))}
href="/legal/impressum"
>
Impressum
</a>
<a
className="flex h-[42px] cursor-pointer items-center border-b border-[#eee] text-sm text-[#666] hover:text-black md:ml-8 md:border-none"
href="https://status.snapify.it"
>
Status
</a>
</div> </div>
</footer> </footer>
</div> </div>

View file

@ -49,62 +49,42 @@ export default function Header() {
</Link> </Link>
))} ))}
</div> </div>
<Link
href="/sign-in"
className="text-sm font-semibold leading-6 text-gray-900"
>
Log in <span aria-hidden="true">&rarr;</span>
</Link>
<> <div className="flex flex-row items-center md:hidden">
<div className="flex flex-row items-center md:hidden"> <Link
<Link href={"#"} className="mr-6"> href="/sign-in"
<div className="block h-[32px] rounded-[5px] border border-solid border-black bg-black p-2 text-sm leading-3 text-white transition hover:bg-white hover:text-black"> className="text-sm font-semibold leading-6 text-gray-900"
Open App
</div>
</Link>
<div
className="flex h-[42px] w-[42px] cursor-pointer items-center justify-center"
onClick={() => setNavbarOpen(!navbarOpen)}
>
<Bars3Icon className="h-6 w-6" />
</div>
</div>
<div
style={{
transition: "all 0.2s cubic-bezier(.17,.27,0,.99)",
height: navbarOpen ? "calc(100vh - 64px)" : "calc(100vh - 80px)",
opacity: 0,
}}
className={`absolute left-0 right-0 bg-white px-6 pt-6 opacity-0 ${
navbarOpen
? "visible top-[64px] block !opacity-100"
: "invisible top-[80px]"
}`}
> >
<Link href="/" onClick={closeNav}> Log in <span aria-hidden="true">&rarr;</span>
<div className="flex h-[48px] cursor-pointer items-center border-b border-[#EAEAEA] text-[16px] hover:bg-[#FAFAFA]"> </Link>
Overview <div
</div> className="flex h-[42px] w-[42px] cursor-pointer items-center justify-center"
</Link> onClick={() => setNavbarOpen(!navbarOpen)}
<Link href="/contact" onClick={closeNav}> >
<div className="flex h-[48px] cursor-pointer items-center border-b border-[#EAEAEA] text-[16px] hover:bg-[#FAFAFA]"> <Bars3Icon className="h-6 w-6" />
Contact
</div>
</Link>
<Link href="/changelog" onClick={closeNav}>
<div className="flex h-[48px] cursor-pointer items-center border-b border-[#EAEAEA] text-[16px] hover:bg-[#FAFAFA]">
Changelog
</div>
</Link>
<Link href="https://app.tablane.net/shared/board/63906741c22c232ed88df799">
<div className="flex h-[48px] cursor-pointer items-center border-b border-[#EAEAEA] text-[16px] hover:bg-[#FAFAFA]">
Roadmap
</div>
</Link>
</div> </div>
</> </div>
<div
style={{
transition: "all 0.2s cubic-bezier(.17,.27,0,.99)",
height: navbarOpen ? "calc(100vh - 64px)" : "calc(100vh - 80px)",
opacity: 0,
}}
className={`absolute left-0 right-0 bg-white px-6 pt-6 opacity-0 ${
navbarOpen
? "visible top-[64px] block !opacity-100"
: "invisible top-[80px]"
}`}
>
{navigation.map(({ href, name }) => (
<Link key={name} href={href} onClick={closeNav}>
<div className="flex h-[48px] cursor-pointer items-center border-b border-[#EAEAEA] text-[16px] hover:bg-[#FAFAFA]">
{name}
</div>
</Link>
))}
</div>
</div> </div>
</div> </div>
); );

View file

@ -92,7 +92,7 @@ export default function Paywall() {
<div className="w-full md:max-w-sm"> <div className="w-full md:max-w-sm">
<div className="sm:align-center mb-4 flex flex-none flex-wrap items-center gap-4 px-2 py-1 md:justify-center"> <div className="sm:align-center mb-4 flex flex-none flex-wrap items-center gap-4 px-2 py-1 md:justify-center">
<div className="relative flex items-center gap-2 text-sm font-medium"> <div className="relative flex items-center gap-2 text-sm font-medium">
<span className=" svelte-10wstod">Monthly</span> <span className="">Monthly</span>
<label className="group relative flex cursor-pointer items-center gap-2 text-sm font-medium text-gray-600"> <label className="group relative flex cursor-pointer items-center gap-2 text-sm font-medium text-gray-600">
<input <input
onChange={toggleBillingCycle} onChange={toggleBillingCycle}
@ -105,9 +105,7 @@ export default function Paywall() {
</span> </span>
<span /> <span />
</label> </label>
<span className="svelte-10wstod opacity-50"> <span className="opacity-50">Annually</span>
Annually
</span>
<span className="rounded-md bg-[#cbf4c9] px-2 py-1 text-xs text-[#0e6245]"> <span className="rounded-md bg-[#cbf4c9] px-2 py-1 text-xs text-[#0e6245]">
20% Off 20% Off
</span> </span>
@ -118,7 +116,7 @@ export default function Paywall() {
className="w-full flex-none rounded-3xl border bg-white shadow-sm" className="w-full flex-none rounded-3xl border bg-white shadow-sm"
> >
<div className="hero relative flex flex-col items-start rounded-3xl px-6 py-6 shadow-sm"> <div className="hero relative flex flex-col items-start rounded-3xl px-6 py-6 shadow-sm">
<div className="svelte-10wstod rounded-lg bg-white/20 px-2 font-medium"> <div className="rounded-lg bg-white/20 px-2 font-medium">
Pro Pro
</div> </div>
<div className="mb-2 mt-4 flex items-end text-5xl font-extrabold tracking-tight"> <div className="mb-2 mt-4 flex items-end text-5xl font-extrabold tracking-tight">
@ -167,7 +165,7 @@ export default function Paywall() {
</div> </div>
<Tooltip title={description}> <Tooltip title={description}>
<div className="svelte-10wstod text-base text-gray-500 underline decoration-gray-400 decoration-dashed underline-offset-4"> <div className="text-base text-gray-500 underline decoration-gray-400 decoration-dashed underline-offset-4">
{feature} {feature}
</div> </div>
</Tooltip> </Tooltip>

View file

@ -11,6 +11,7 @@ import { CheckCircleIcon } from "@heroicons/react/24/outline";
import Footer from "~/components/Footer"; import Footer from "~/components/Footer";
import Header from "~/components/Header"; import Header from "~/components/Header";
import Image from "next/image"; import Image from "next/image";
import CTA from "~/components/CTA";
const Home: NextPage = () => { const Home: NextPage = () => {
const [, setRecordOpen] = useAtom(recordVideoModalOpen); const [, setRecordOpen] = useAtom(recordVideoModalOpen);
@ -299,50 +300,7 @@ const Home: NextPage = () => {
</div> </div>
</div> </div>
<div className="bg-white"> <CTA />
<div className="mx-auto max-w-7xl py-12 sm:px-6 sm:py-16 lg:px-8">
<div className="relative isolate overflow-hidden bg-gray-900 px-6 py-24 text-center shadow-2xl sm:rounded-3xl sm:px-16">
<h2 className="mx-auto max-w-2xl text-4xl font-bold tracking-tight text-white">
Ready to improve how your team communicates?
</h2>
<div className="mt-10 flex items-center justify-center gap-x-6">
<button
onClick={openRecordModal}
className="inline-flex max-h-[40px] items-center rounded-md border border-transparent bg-red-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2"
>
Record a video
</button>
</div>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 1024 1024"
className="absolute left-1/2 top-1/2 -z-10 h-[64rem] w-[64rem] -translate-x-1/2"
aria-hidden="true"
>
<circle
cx={512}
cy={512}
r={512}
fill="url(#827591b1-ce8c-4110-b064-7cb85a0b1217)"
fillOpacity="0.7"
/>
<defs>
<radialGradient
id="827591b1-ce8c-4110-b064-7cb85a0b1217"
cx={0}
cy={0}
r={1}
gradientUnits="userSpaceOnUse"
gradientTransform="translate(512 512) rotate(90) scale(512)"
>
<stop stopColor="#7775D6" />
<stop offset={1} stopColor="#E935C1" stopOpacity={0} />
</radialGradient>
</defs>
</svg>
</div>
</div>
</div>
<Footer /> <Footer />
</div> </div>

178
src/pages/pricing.tsx Normal file
View file

@ -0,0 +1,178 @@
import Footer from "~/components/Footer";
import Header from "~/components/Header";
import Head from "next/head";
import { useState } from "react";
import { CheckIcon } from "@heroicons/react/20/solid";
import Tooltip from "~/components/Tooltip";
import { Disclosure, Transition } from "@headlessui/react";
import { ChevronUpIcon } from "@heroicons/react/20/solid";
import CTA from "~/components/CTA";
import VideoRecordModal from "~/components/VideoRecordModal";
export default function Pricing() {
const [billedAnnually, setBilledAnnually] = useState<boolean>(false);
return (
<>
<Head>
<title>{"Snapify | Pricing"}</title>
<meta name="description" content="Generated by create-t3-app" />
<link rel="icon" href="/favicon.ico" />
</Head>
<Header />
<div className="my-20 flex h-40 items-center justify-center sm:mx-10 lg:mx-20">
<span className="text-center text-4xl font-bold lg:text-7xl">
Choose the plan that fits your needs.
</span>
</div>
<div className="relative mx-4 mb-20 flex flex-col items-center justify-center gap-12 md:flex-row md:gap-4 lg:mx-16 lg:gap-16">
<div className="absolute left-[calc(50%_-_calc(min(75vw,500px)_/_2))] h-[min(75vw,500px)] w-[min(75vw,500px)] bg-[radial-gradient(circle_at_center,#666_0,#fff_100%)] opacity-80 blur-[calc(0.5_*_min(75vw,500px))]"></div>
{[
{
name: "Free",
price: { monthly: 0, annual: 0 },
features: [
{
feature: "Unlimited video recording",
description: "Record and share unlimited videos",
},
{
feature: "10 video uploads",
description: "Upload external videos to your Library",
},
{
feature: "Remove branding",
description: "Remove Snapify branding from your videos",
},
],
},
{
name: "Pro",
price: { monthly: 5, annual: 4 },
features: [
{
feature: "Unlimited videos",
description: "Record and share unlimited videos",
},
{
feature: "Video uploads",
description: "Upload external videos to your Library",
},
{
feature: "Remove branding",
description: "Remove Snapify branding from your videos",
},
],
},
].map(({ name, price, features }) => (
<div
key={name}
className="relative w-full max-w-[400px] flex-1 rounded-3xl border bg-white shadow-sm"
>
{name === "Pro" ? (
<div className="absolute -top-6 left-2/4 z-[1] mt-0 -translate-x-2/4 cursor-default select-none rounded-3xl border-0 border-solid border-[#eaeaea] bg-[linear-gradient(180deg,rgba(0,0,0,.8),#000)] px-[22px] py-3.5 text-white shadow-[0_8px_30px_rgb(0_0_0/6%)] backdrop-blur-[2px]">
<span className="text-xs font-bold">Most Popular</span>
</div>
) : null}
<div className="hero relative flex flex-col items-start rounded-3xl px-6 py-6 shadow-sm">
<div className="rounded-lg bg-white/20 px-2 font-medium">
{name}
</div>
<div className="mb-2 mt-4 flex items-end text-5xl font-extrabold tracking-tight">
{billedAnnually ? price.annual : price.monthly}
<span className="mb-1 text-sm opacity-80">/ mo.</span>
</div>
<div className="mt-2 text-sm">
{billedAnnually ? "billed annually" : "billed monthly"}
</div>
<div className="mt-2 flex-grow" />
<button
type="submit"
className="btn mt-4 block w-full appearance-none rounded-lg bg-black px-4 py-2.5 text-center text-sm font-medium text-white shadow-lg shadow-black/50 duration-100 focus:outline-transparent disabled:opacity-80"
>
Get started
</button>
</div>
<div className="mt-4 flex flex-col gap-2 pb-8">
{features.map(({ feature, description }) => (
<div
key={feature}
className="flex items-center gap-2 text-gray-500"
>
<div className="ml-6 h-5 w-5 flex-none">
<CheckIcon />
</div>
<Tooltip title={description}>
<div className="text-base text-gray-500 underline decoration-gray-400 decoration-dashed underline-offset-4">
{feature}
</div>
</Tooltip>
</div>
))}
</div>
</div>
))}
</div>
<div className="flex flex-col items-center justify-center border-y border-[#eaeaea] bg-[#fafafa] pb-8">
<div className="mb-12 mt-8">
<span className="text-5xl font-bold">FAQs</span>
</div>
<div className="flex flex-1 border-collapse flex-col justify-center px-6">
{[
{
question: "What are my payment options?",
answer:
"You can be billed monthly, but save 20% if you pay annually. We currently accept credit card payment. Contact us at hello@snapify.it if you need an alternative payment method.",
},
{
question:
"What happens when I hit my 10 video limit on the Free plan?",
answer:
"Our Free plan has a limit of 10 videos. To record more than 10 videos, you will need to delete videos or upgrade to the Pro plan.",
},
].map(({ answer, question }) => (
<Disclosure
key={question}
as="div"
className="max-w-[600px] max-w-[80vw] sm:w-[600px]"
>
{({ open }) => (
<>
<Disclosure.Button className="flex h-12 w-full items-center justify-between border-t border-[#eaeaea] px-4 py-8 text-left text-sm font-medium">
<span>{question}</span>
<ChevronUpIcon
className={`transition-transform ${
open ? "rotate-180" : ""
} h-5 w-5`}
/>
</Disclosure.Button>
<Transition
enter="transition duration-100 ease-out"
enterFrom="transform scale-95 opacity-0"
enterTo="transform scale-100 opacity-100"
leave="transition duration-75 ease-out"
leaveFrom="transform scale-100 opacity-100"
leaveTo="transform scale-95 opacity-0"
>
<Disclosure.Panel className="px-4 pb-2 pt-0 text-sm text-gray-500">
{answer}
</Disclosure.Panel>
</Transition>
</>
)}
</Disclosure>
))}
</div>
</div>
<CTA />
<Footer />
<VideoRecordModal />
</>
);
}