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:
parent
96e9f749d2
commit
91bec9c996
30
web/components/info-box.tsx
Normal file
30
web/components/info-box.tsx
Normal 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>
|
||||||
|
)
|
||||||
|
}
|
|
@ -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' },
|
||||||
|
|
27
web/hooks/use-save-referral.ts
Normal file
27
web/hooks/use-save-referral.ts
Normal 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])
|
||||||
|
}
|
|
@ -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">
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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}>
|
||||||
|
|
|
@ -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
57
web/pages/referrals.tsx
Normal 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>
|
||||||
|
)
|
||||||
|
}
|
BIN
web/public/logo-flapping-with-money.gif
Normal file
BIN
web/public/logo-flapping-with-money.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 287 KiB |
Loading…
Reference in New Issue
Block a user