Referrals page (#676)

* Referrals page added to sidebar; useSaveReferral; InfoBox

* text color

* eslint

* migrate useUsers hook to react-query (#674)

* Remove bet button from free response comments

* Make answer replies more closely spaced together

* Host Ida and Alex's MTG Guesser game (#656)

* Copy over code from Mtg Guesser

* Run Prettier

* CSS Tweaks: Hover feedback, button positioning

* Hide all but counterspell & burn, for now

* Move to /mtg directory

* Fix prettierignore

* smaller jsons (#673)

limited burn to only red cards and also added limited json files to only have fields needed to play

* Add Ida's tweak to card position

Co-authored-by: marsteralex <bob.masteralex@gmail.com>

* Adjust card positioning

* Make the select screen index.html

* Remove other guessing games

* Remove alternate versions; add Alex's email

* Remove unused jsons

* Small FR comments tweaks

* Spacing tweak

* Changing manalinks table UI (#665)

From table to card view

* Fix comment spacing on non-FR

* Move "Send M$" lower in sidebar More list.

* Move leaderboards up in mobile nav

* eslint

* prettier

Co-authored-by: Sinclair Chen <abc.sinclair@gmail.com>
Co-authored-by: James Grugett <jahooma@gmail.com>
Co-authored-by: Austin Chen <akrolsmir@gmail.com>
Co-authored-by: marsteralex <bob.masteralex@gmail.com>
Co-authored-by: ingawei <46611122+ingawei@users.noreply.github.com>
This commit is contained in:
mantikoros 2022-07-21 14:43:10 -05:00 committed by GitHub
parent 96e9f749d2
commit 91bec9c996
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 137 additions and 25 deletions

View File

@ -0,0 +1,30 @@
import clsx from 'clsx'
import { InformationCircleIcon } from '@heroicons/react/solid'
import { Linkify } from './linkify'
export function InfoBox(props: {
title: string
text: string
className?: string
}) {
const { title, text, className } = props
return (
<div className={clsx('rounded-md bg-gray-50 p-4', className)}>
<div className="flex">
<div className="flex-shrink-0">
<InformationCircleIcon
className="h-5 w-5 text-gray-400"
aria-hidden="true"
/>
</div>
<div className="ml-3">
<h3 className="text-sm font-medium text-black">{title}</h3>
<div className="mt-2 text-sm text-black">
<Linkify text={text} />
</div>
</div>
</div>
</div>
)
}

View File

@ -63,6 +63,7 @@ function getMoreNavigation(user?: User | null) {
return [ return [
{ name: 'Leaderboards', href: '/leaderboards' }, { name: 'Leaderboards', href: '/leaderboards' },
{ name: 'Referrals', href: '/referrals' },
{ name: 'Charity', href: '/charity' }, { name: 'Charity', href: '/charity' },
{ name: 'Send M$', href: '/links' }, { name: 'Send M$', href: '/links' },
{ name: 'Discord', href: 'https://discord.gg/eHQBNBqXuh' }, { name: 'Discord', href: 'https://discord.gg/eHQBNBqXuh' },
@ -114,6 +115,7 @@ function getMoreMobileNav() {
...(IS_PRIVATE_MANIFOLD ...(IS_PRIVATE_MANIFOLD
? [] ? []
: [ : [
{ name: 'Referrals', href: '/referrals' },
{ name: 'Charity', href: '/charity' }, { name: 'Charity', href: '/charity' },
{ name: 'Send M$', href: '/links' }, { name: 'Send M$', href: '/links' },
{ name: 'Discord', href: 'https://discord.gg/eHQBNBqXuh' }, { name: 'Discord', href: 'https://discord.gg/eHQBNBqXuh' },

View File

@ -0,0 +1,27 @@
import { useRouter } from 'next/router'
import { useEffect } from 'react'
import { User, writeReferralInfo } from 'web/lib/firebase/users'
export const useSaveReferral = (
user?: User | null,
options?: {
defaultReferrer?: string
contractId?: string
groupId?: string
}
) => {
const router = useRouter()
useEffect(() => {
const { referrer } = router.query as {
referrer?: string
}
const actualReferrer = referrer || options?.defaultReferrer
if (!user && router.isReady && actualReferrer) {
writeReferralInfo(actualReferrer, options?.contractId, options?.groupId)
}
}, [user, router, options])
}

View File

@ -10,7 +10,7 @@ import { useUser } from 'web/hooks/use-user'
import { ResolutionPanel } from 'web/components/resolution-panel' import { ResolutionPanel } from 'web/components/resolution-panel'
import { Title } from 'web/components/title' import { Title } from 'web/components/title'
import { Spacer } from 'web/components/layout/spacer' import { Spacer } from 'web/components/layout/spacer'
import { listUsers, User, writeReferralInfo } from 'web/lib/firebase/users' import { listUsers, User } from 'web/lib/firebase/users'
import { import {
Contract, Contract,
getContractFromSlug, getContractFromSlug,
@ -43,9 +43,9 @@ import { CPMMBinaryContract } from 'common/contract'
import { AlertBox } from 'web/components/alert-box' import { AlertBox } from 'web/components/alert-box'
import { useTracking } from 'web/hooks/use-tracking' import { useTracking } from 'web/hooks/use-tracking'
import { CommentTipMap, useTipTxns } from 'web/hooks/use-tip-txns' import { CommentTipMap, useTipTxns } from 'web/hooks/use-tip-txns'
import { useRouter } from 'next/router'
import { useLiquidity } from 'web/hooks/use-liquidity' import { useLiquidity } from 'web/hooks/use-liquidity'
import { richTextToString } from 'common/util/parse' import { richTextToString } from 'common/util/parse'
import { useSaveReferral } from 'web/hooks/use-save-referral'
export const getStaticProps = fromPropz(getStaticPropz) export const getStaticProps = fromPropz(getStaticPropz)
export async function getStaticPropz(props: { export async function getStaticPropz(props: {
@ -157,15 +157,10 @@ export function ContractPageContent(
const ogCardProps = getOpenGraphProps(contract) const ogCardProps = getOpenGraphProps(contract)
const router = useRouter() useSaveReferral(user, {
defaultReferrer: contract.creatorUsername,
useEffect(() => { contractId: contract.id,
const { referrer } = router.query as { })
referrer?: string
}
if (!user && router.isReady)
writeReferralInfo(contract.creatorUsername, contract.id, referrer)
}, [user, contract, router])
const rightSidebar = hasSidePanel ? ( const rightSidebar = hasSidePanel ? (
<Col className="gap-4"> <Col className="gap-4">

View File

@ -14,12 +14,7 @@ import {
} from 'web/lib/firebase/groups' } from 'web/lib/firebase/groups'
import { Row } from 'web/components/layout/row' import { Row } from 'web/components/layout/row'
import { UserLink } from 'web/components/user-page' import { UserLink } from 'web/components/user-page'
import { import { firebaseLogin, getUser, User } from 'web/lib/firebase/users'
firebaseLogin,
getUser,
User,
writeReferralInfo,
} from 'web/lib/firebase/users'
import { Col } from 'web/components/layout/col' import { Col } from 'web/components/layout/col'
import { useUser } from 'web/hooks/use-user' import { useUser } from 'web/hooks/use-user'
import { listMembers, useGroup, useMembers } from 'web/hooks/use-group' import { listMembers, useGroup, useMembers } from 'web/hooks/use-group'
@ -34,7 +29,7 @@ import { Linkify } from 'web/components/linkify'
import { fromPropz, usePropz } from 'web/hooks/use-propz' import { fromPropz, usePropz } from 'web/hooks/use-propz'
import { Tabs } from 'web/components/layout/tabs' import { Tabs } from 'web/components/layout/tabs'
import { CreateQuestionButton } from 'web/components/create-question-button' import { CreateQuestionButton } from 'web/components/create-question-button'
import React, { useEffect, useState } from 'react' import React, { useState } from 'react'
import { GroupChat } from 'web/components/groups/group-chat' import { GroupChat } from 'web/components/groups/group-chat'
import { LoadingIndicator } from 'web/components/loading-indicator' import { LoadingIndicator } from 'web/components/loading-indicator'
import { Modal } from 'web/components/layout/modal' import { Modal } from 'web/components/layout/modal'
@ -53,6 +48,7 @@ import { searchInAny } from 'common/util/parse'
import { useWindowSize } from 'web/hooks/use-window-size' import { useWindowSize } from 'web/hooks/use-window-size'
import { CopyLinkButton } from 'web/components/copy-link-button' import { CopyLinkButton } from 'web/components/copy-link-button'
import { ENV_CONFIG } from 'common/envs/constants' import { ENV_CONFIG } from 'common/envs/constants'
import { useSaveReferral } from 'web/hooks/use-save-referral'
export const getStaticProps = fromPropz(getStaticPropz) export const getStaticProps = fromPropz(getStaticPropz)
export async function getStaticPropz(props: { params: { slugs: string[] } }) { export async function getStaticPropz(props: { params: { slugs: string[] } }) {
@ -155,13 +151,11 @@ export default function GroupPage(props: {
const messages = useCommentsOnGroup(group?.id) const messages = useCommentsOnGroup(group?.id)
const user = useUser() const user = useUser()
useEffect(() => {
const { referrer } = router.query as { useSaveReferral(user, {
referrer?: string defaultReferrer: creator.username,
} groupId: group?.id,
if (!user && router.isReady) })
writeReferralInfo(creator.username, undefined, referrer, group?.id)
}, [user, creator, group, router])
const { width } = useWindowSize() const { width } = useWindowSize()
const chatDisabled = !group || group.chatDisabled const chatDisabled = !group || group.chatDisabled

View File

@ -12,6 +12,7 @@ import { getContractFromSlug } from 'web/lib/firebase/contracts'
import { useTracking } from 'web/hooks/use-tracking' import { useTracking } from 'web/hooks/use-tracking'
import { track } from 'web/lib/service/analytics' import { track } from 'web/lib/service/analytics'
import { redirectIfLoggedOut } from 'web/lib/firebase/server-auth' import { redirectIfLoggedOut } from 'web/lib/firebase/server-auth'
import { useSaveReferral } from 'web/hooks/use-save-referral'
export const getServerSideProps = redirectIfLoggedOut('/') export const getServerSideProps = redirectIfLoggedOut('/')
@ -21,6 +22,8 @@ const Home = () => {
const router = useRouter() const router = useRouter()
useTracking('view home') useTracking('view home')
useSaveReferral()
return ( return (
<> <>
<Page suspend={!!contract}> <Page suspend={!!contract}>

View File

@ -7,6 +7,7 @@ import { LandingPagePanel } from 'web/components/landing-page-panel'
import { Col } from 'web/components/layout/col' import { Col } from 'web/components/layout/col'
import { ManifoldLogo } from 'web/components/nav/manifold-logo' import { ManifoldLogo } from 'web/components/nav/manifold-logo'
import { redirectIfLoggedIn } from 'web/lib/firebase/server-auth' import { redirectIfLoggedIn } from 'web/lib/firebase/server-auth'
import { useSaveReferral } from 'web/hooks/use-save-referral'
export const getServerSideProps = redirectIfLoggedIn('/home', async (_) => { export const getServerSideProps = redirectIfLoggedIn('/home', async (_) => {
// These hardcoded markets will be shown in the frontpage for signed-out users: // These hardcoded markets will be shown in the frontpage for signed-out users:
@ -32,6 +33,9 @@ export default function Home(props: { hotContracts: Contract[] }) {
// on this page and they log in -- in the future we will make some cleaner way // on this page and they log in -- in the future we will make some cleaner way
const user = useUser() const user = useUser()
const router = useRouter() const router = useRouter()
useSaveReferral()
useEffect(() => { useEffect(() => {
if (user != null) { if (user != null) {
router.replace('/home') router.replace('/home')

57
web/pages/referrals.tsx Normal file
View File

@ -0,0 +1,57 @@
import { Col } from 'web/components/layout/col'
import { SEO } from 'web/components/SEO'
import { Title } from 'web/components/title'
import { useUser } from 'web/hooks/use-user'
import { Page } from 'web/components/page'
import { useTracking } from 'web/hooks/use-tracking'
import { redirectIfLoggedOut } from 'web/lib/firebase/server-auth'
import { REFERRAL_AMOUNT } from 'common/user'
import { CopyLinkButton } from 'web/components/copy-link-button'
import { ENV_CONFIG } from 'common/envs/constants'
import { InfoBox } from 'web/components/info-box'
export const getServerSideProps = redirectIfLoggedOut('/')
export default function ReferralsPage() {
const user = useUser()
useTracking('view referrals')
const url = `https://${ENV_CONFIG.domain}?referrer=${user?.username}`
return (
<Page>
<SEO title="Referrals" description="" url="/add-funds" />
<Col className="items-center">
<Col className="h-full rounded bg-white p-4 py-8 sm:p-8 sm:shadow-md">
<Title className="!mt-0" text="Referrals" />
<img
className="mb-6 block -scale-x-100 self-center"
src="/logo-flapping-with-money.gif"
width={200}
height={200}
/>
<div className={'mb-4'}>
Invite new users to Manifold and get M${REFERRAL_AMOUNT} if they
sign up!
</div>
<CopyLinkButton
url={url}
tracking="copy referral link"
buttonClassName="btn-md rounded-l-none"
toastClassName={'-left-28 mt-1'}
/>
<InfoBox
title="FYI"
className="mt-4 max-w-md"
text="You can also earn the referral bonus from sharing the link to any market or group you've created!"
/>
</Col>
</Col>
</Page>
)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 KiB