From 9b0d96cfa1f3f3c614210821fca8927d524bf0d0 Mon Sep 17 00:00:00 2001 From: Ian Philips Date: Thu, 28 Apr 2022 09:49:42 -0600 Subject: [PATCH] Allow users a free daily market --- functions/src/create-contract.ts | 13 +++++++++++-- web/components/nav/sidebar.tsx | 32 +++++++++++++++++++++++++++++--- web/lib/firebase/contracts.ts | 13 +++++++++++++ web/pages/create.tsx | 25 ++++++++++++++++++++----- 4 files changed, 73 insertions(+), 10 deletions(-) diff --git a/functions/src/create-contract.ts b/functions/src/create-contract.ts index 16a416b1..267e9031 100644 --- a/functions/src/create-contract.ts +++ b/functions/src/create-contract.ts @@ -1,7 +1,7 @@ import * as functions from 'firebase-functions' import * as admin from 'firebase-admin' import * as _ from 'lodash' - +import { query, where } from 'firebase/firestore' import { chargeUser, getUser } from './utils' import { Binary, @@ -109,7 +109,16 @@ export const createContract = functions tags ?? [] ) - if (ante) await chargeUser(creator.id, ante) + // uses utc time on server: + const today = new Date().setHours(0, 0, 0, 0) + const userContractsCreatedTodaySnapshot = await firestore + .collection(`contracts`) + .where('creatorId', '==', userId) + .where('createdTime', '>=', today) + .get() + const isFree = userContractsCreatedTodaySnapshot.size === 0 + + if (!isFree && ante) await chargeUser(creator.id, ante) await contractRef.create(contract) diff --git a/web/components/nav/sidebar.tsx b/web/components/nav/sidebar.tsx index 67e8ae29..f8e2158b 100644 --- a/web/components/nav/sidebar.tsx +++ b/web/components/nav/sidebar.tsx @@ -19,6 +19,13 @@ import { firebaseLogin, firebaseLogout } from '../../lib/firebase/users' import { ManifoldLogo } from './manifold-logo' import { MenuButton } from './menu' import { getNavigationOptions, ProfileSummary } from './profile-menu' +import { CreatorContractsList } from '../contract/contracts-list' +import { + Contract, + listContracts, + userHasCreatedContractToday, +} from '../../lib/firebase/contracts' +import { useState } from 'react' const navigation = [ { name: 'Home', href: '/home', icon: HomeIcon }, @@ -96,6 +103,11 @@ export default function Sidebar() { const user = useUser() let folds = useFollowedFolds(user) || [] folds = _.sortBy(folds, 'followCount').reverse() + const [deservesDailyFreeMarket, setDeservesDailyFreeMarket] = useState(false) + user && + userHasCreatedContractToday(user.id).then((result) => { + setDeservesDailyFreeMarket(result) + }) const navigationOptions = user === null ? signedOutNavigation : navigation const mobileNavigationOptions = @@ -159,10 +171,24 @@ export default function Sidebar() { /> + {/*// check their markets for if any have a created time of today, if they haven't made a market today, let them know they get a free market*/} + {deservesDailyFreeMarket ? ( +
+ Use your daily free market! +
+ ) : ( +
+ )} + + {/*// check their markets for if any have a created time of today, if they haven't made a market today, give let them know they get a free market*/} {user && ( - - - +
+ + + +
)} ) diff --git a/web/lib/firebase/contracts.ts b/web/lib/firebase/contracts.ts index 1646bd09..92bcfae1 100644 --- a/web/lib/firebase/contracts.ts +++ b/web/lib/firebase/contracts.ts @@ -121,6 +121,19 @@ export async function listAllContracts(): Promise { return snapshot.docs.map((doc) => doc.data() as Contract) } +export async function userHasCreatedContractToday( + userId: string +): Promise { + // uses utc time like the server + const todayAtMidnight = dayjs.utc().startOf('day').valueOf() + return listContracts(userId).then((contracts) => { + const todayContracts = contracts.filter((contract) => { + return contract.createdTime > todayAtMidnight + }) + return todayContracts.length === 0 + }) +} + export function listenForContracts( setContracts: (contracts: Contract[]) => void ) { diff --git a/web/pages/create.tsx b/web/pages/create.tsx index b668fffb..cdefc975 100644 --- a/web/pages/create.tsx +++ b/web/pages/create.tsx @@ -6,7 +6,11 @@ import Textarea from 'react-expanding-textarea' import { Spacer } from '../components/layout/spacer' import { useUser } from '../hooks/use-user' -import { Contract, contractPath } from '../lib/firebase/contracts' +import { + Contract, + contractPath, + userHasCreatedContractToday, +} from '../lib/firebase/contracts' import { createContract } from '../lib/firebase/api-call' import { FIXED_ANTE, MINIMUM_ANTE } from '../../common/antes' import { InfoTooltip } from '../components/info-tooltip' @@ -70,6 +74,13 @@ export function NewContract(props: { question: string; tag?: string }) { const tags = parseWordsAsTags(tagText) const [ante, setAnte] = useState(FIXED_ANTE) + + const [deservesDailyFreeMarket, setDeservesDailyFreeMarket] = useState(false) + creator && + userHasCreatedContractToday(creator.id).then((result) => { + setDeservesDailyFreeMarket(result) + }) + // useEffect(() => { // if (ante === null && creator) { // const initialAnte = creator.balance < 100 ? MINIMUM_ANTE : 100 @@ -241,10 +252,14 @@ export function NewContract(props: { question: string; tag?: string }) { text={`Cost to create your market. This amount is used to subsidize trading.`} /> - -
{formatMoney(ante)}
- - {ante > balance && ( + {deservesDailyFreeMarket ? ( +
FREE
+ ) : ( +
+ {formatMoney(ante)} +
+ )} + {!deservesDailyFreeMarket && ante > balance && (
Insufficient balance