Skip to content

Commit

Permalink
adding prime landing page
Browse files Browse the repository at this point in the history
  • Loading branch information
julien51 committed Oct 8, 2024
1 parent df71500 commit 81ce959
Show file tree
Hide file tree
Showing 8 changed files with 196 additions and 22 deletions.
14 changes: 14 additions & 0 deletions unlock-app/app/prime/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from 'react'
import { Metadata } from 'next'
import PrimeContent from '~/components/interface/prime/PrimeContent'

export const metadata: Metadata = {
title: 'Unlock Prime',
description: 'TK',
}

const PrimeLandingPage: React.FC = () => {
return <PrimeContent />
}

export default PrimeLandingPage
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ const RemoveKeyGranterModal = ({
<span className="text-base text-brand-dark p-6">
{isCreditCardGranter
? 'If you remove this key granter, credit card purchases for your contracts will be disabled'
: `Please confirm you want to remove this key granter`}
: 'Please confirm you want to remove this key granter'}
</span>
</div>
<div className="flex gap-4">
Expand Down
156 changes: 156 additions & 0 deletions unlock-app/src/components/interface/prime/PrimeContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
'use client'

import Head from 'next/head'
import { pageTitle } from '../../../constants'
import { TwitterTags } from '../../page/TwitterTags'
import { OpenGraphTags } from '../../page/OpenGraphTags'
import { AppLayout } from '../../interface/layouts/AppLayout'
import { Button, Placeholder } from '@unlock-protocol/ui'
import { useQuery } from '@tanstack/react-query'
import { config } from '~/config/app'
import { Web3Service } from '@unlock-protocol/unlock-js'
import networks from '@unlock-protocol/networks'
import { useRouter } from 'next/navigation'
import { useUnlockPrime } from '~/hooks/useUnlockPrime'

export const PrimeContent = () => {
const router = useRouter()
const { joinPrime, isPrime } = useUnlockPrime()

const { data: lock } = useQuery({
queryKey: ['prime'],
queryFn: async () => {
const web3Service = new Web3Service(networks)
const lock = await web3Service.getLock(
config.prime.contract,
config.prime.network
)
return lock
},
})

return (
<AppLayout authRequired={false} showLinks={false}>
<Head>
<title>{pageTitle()}</title>
<TwitterTags />
<OpenGraphTags />
</Head>
<div>
<main className="flex flex-col gap-4 text-center md:w-3/4 mx-auto">
<h1
className="text-5xl font-extrabold text-transparent uppercase md:text-7xl bg-clip-text"
style={{
backgroundImage:
'linear-gradient(85.7deg, #603DEB 3.25%, #F19077 90.24%)',
}}
>
Unlock Prime
</h1>
<p className="text-2xl">
You can use Unlock Labs basic tools for free. Upgrade to Unlock
Prime and get monthly ETH rewards, enhanced features, and a stack of
other benefits.
</p>
<section className="flex mt-8 md:mt-8 gap-8 md:justify-center items-center md:items-stretch flex-col md:flex-row">
<div className="w-96 flex flex-col gap-2 border p-4 rounded-lg">
<h2 className="text-3xl font-semibold">Unlock Basic</h2>
<h3 className="">Free</h3>
<Button
className="m-2"
onClick={() => {
router.push('/')
}}
>
Get Started
</Button>
<ul className="flex flex-col pl-4 text-left gap-2">
<li>
<h4 className="text-lg font-semibold">
Bring your experiences onchain
</h4>
</li>
<li>
<ul className="flex flex-col pl-4 text-left gap-2">
<li>Accept onchain payments</li>
<li>Accept credit card payments</li>
<li>
Available on Base, Arbitrum, Polygon, and other networks
</li>
</ul>
</li>

<li>
<h4 className="text-lg font-semibold">Events</h4>
</li>
<li>
<ul className="flex flex-col pl-4 text-left gap-2">
<li>Event landing page</li>
<li>Free and paid event ticketing</li>
<li>RSVP application approvals</li>
<li>Proof-of-attendance tokens</li>
<li>Customizable ticket designs</li>
<li>Support for up to 5 events</li>
</ul>
</li>
</ul>
</div>
<div className="w-96 flex flex-col gap-2 border p-4 rounded-lg">
<h2 className="text-3xl font-semibold">Unlock Prime</h2>
<h3 className="">
{!lock ? (
<Placeholder.Root>
<Placeholder.Line size="md" />
</Placeholder.Root>
) : (
`${lock?.keyPrice} ${lock?.currencySymbol}/mo (~$6)`
)}
</h3>
<Button
disabled={isPrime}
className="m-2"
onClick={() => {
joinPrime()
}}
>
{isPrime ? '💫 You are a Prime Member!' : 'Get Unlock Prime'}
</Button>
<ul className="flex flex-col pl-4 text-left gap-2">
<li>
<h4 className="text-lg font-semibold">
Everything in Basic, plus...
</h4>
</li>
<li>
<ul className="flex flex-col pl-4 text-left gap-2">
<li>Monthly ETH rewards†</li>
<li>Unlimited airdrops</li>
<li>Exclusive partner discounts</li>
<li>Swag</li>
<li>Cancel anytime</li>
</ul>
</li>
<li>
<h4 className="text-lg font-semibold">Events</h4>
</li>
<li>
<ul className="flex flex-col pl-4 text-left gap-2">
<li>Unlimited events</li>
<li>Multiple event template layouts</li>
<li>Attendee check-in</li>
</ul>
</li>
</ul>
</div>
</section>
<small>
† ETH reward currently 110% of what you paid that month, while
supplies last.
</small>
</main>
</div>
</AppLayout>
)
}

export default PrimeContent
19 changes: 2 additions & 17 deletions unlock-app/src/components/interface/prime/PrimeOnly.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,11 @@
import { Button, Card } from '@unlock-protocol/ui'
import { ReactNode } from 'react'
import { useUnlockPrime } from '~/hooks/useUnlockPrime'
import { Paywall } from '@unlock-protocol/paywall'
import networks from '@unlock-protocol/networks'
import Link from 'next/link'
import { FiExternalLink as ExternalLinkIcon } from 'react-icons/fi'
import { config } from '~/config/app'

export const PrimeOnly = ({ children }: { children: ReactNode }) => {
const { isPrime } = useUnlockPrime()

const join = () => {
const paywall = new Paywall(networks)
paywall.loadCheckoutModal({
locks: {
[config.prime.contract]: {
network: config.prime.network,
},
},
pessimistic: true,
})
}
const { isPrime, joinPrime } = useUnlockPrime()

if (isPrime) {
return <>{children}</>
Expand All @@ -43,7 +28,7 @@ export const PrimeOnly = ({ children }: { children: ReactNode }) => {
</Link>
</p>
<div className="flex justify-center">
<Button onClick={join}>Become a Prime Member</Button>
<Button onClick={joinPrime}>Become a Prime Member</Button>
</div>
</Card>
)
Expand Down
4 changes: 2 additions & 2 deletions unlock-app/src/config/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const staging = {
coinbaseProjectId: '4e90fd0f-bb62-4e1c-91a4-f08c76d1b09e',
prime: {
network: 84532,
contract: '0xcAdc0e0A9E555e6c058915C09E3F23255a399999',
contract: '0xB37D532429940f3C59DA0aed4D0692bFfa9AF316',
},
}

Expand All @@ -33,7 +33,7 @@ const dev = {
process.env.NEXT_PUBLIC_COINBASE_PROJECT_ID || staging.coinbaseProjectId,
prime: {
network: 84532,
contract: '0xcAdc0e0A9E555e6c058915C09E3F23255a399999',
contract: '0xB37D532429940f3C59DA0aed4D0692bFfa9AF316',
},
}

Expand Down
Empty file.
21 changes: 20 additions & 1 deletion unlock-app/src/hooks/useUnlockPrime.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { useQuery } from '@tanstack/react-query'
import networks from '@unlock-protocol/networks'
import Paywall from '@unlock-protocol/paywall'
import { Web3Service } from '@unlock-protocol/unlock-js'
import { useCallback } from 'react'
import { config } from '~/config/app'
import { useAuth } from '~/contexts/AuthenticationContext'

Expand All @@ -21,5 +23,22 @@ export const useUnlockPrime = () => {
enabled: !!account,
})

return { isPrime, ...rest }
const joinPrime = useCallback(async () => {
const paywall = new Paywall(networks)
await paywall.loadCheckoutModal({
title: '🪄 Join Unlock Prime!',
locks: {
[config.prime.contract]: {
network: config.prime.network,
skipRecipient: true,
recurringPayments: 'forever',
},
},
skipRecipient: true,
pessimistic: true,
})
rest.refetch() // Refetch, in case there was a purchase!
}, [])

return { isPrime, ...rest, joinPrime }
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ interface HeroSectionProps {
const HeroSectionDetails: HeroSectionProps = {
subhead: 'Open source and purpose built',
title:
' Smart contracts built specifically for memberships and subscription NFT',
'Smart contracts built specifically for memberships and subscription NFT',
description:
'The only smart contracts that let you add time constraints, update pricing, and handle recurring payments.',
}
Expand Down

0 comments on commit 81ce959

Please sign in to comment.