From 1c323c5a7fac604d842d9b8dbb37f1ac69954eca Mon Sep 17 00:00:00 2001
From: James Grugett <jahooma@gmail.com>
Date: Wed, 24 Aug 2022 12:59:21 -0500
Subject: [PATCH] Simple recommended contracts based on contract creator

---
 web/lib/firebase/contracts.ts           | 20 ++++++++++++++++++++
 web/pages/[username]/[contractSlug].tsx | 20 ++++++++++++++++++--
 2 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/web/lib/firebase/contracts.ts b/web/lib/firebase/contracts.ts
index fc205b6a..6dc2ee3e 100644
--- a/web/lib/firebase/contracts.ts
+++ b/web/lib/firebase/contracts.ts
@@ -295,6 +295,26 @@ export async function getClosingSoonContracts() {
   return sortBy(chooseRandomSubset(data, 2), (contract) => contract.closeTime)
 }
 
+export const getRandTopCreatorContracts = async (
+  creatorId: string,
+  count: number,
+  excluding: string[] = []
+) => {
+  const creatorContractsQuery = query(
+    contracts,
+    where('isResolved', '==', false),
+    where('creatorId', '==', creatorId),
+    orderBy('popularityScore', 'desc'),
+    limit(Math.max(count * 2, 15))
+  )
+  const data = await getValues<Contract>(creatorContractsQuery)
+  const open = data
+    .filter((c) => c.closeTime && c.closeTime > Date.now())
+    .filter((c) => !excluding.includes(c.id))
+
+  return chooseRandomSubset(open, count)
+}
+
 export async function getRecentBetsAndComments(contract: Contract) {
   const contractDoc = doc(contracts, contract.id)
 
diff --git a/web/pages/[username]/[contractSlug].tsx b/web/pages/[username]/[contractSlug].tsx
index e62c457e..282df488 100644
--- a/web/pages/[username]/[contractSlug].tsx
+++ b/web/pages/[username]/[contractSlug].tsx
@@ -11,6 +11,7 @@ import { Spacer } from 'web/components/layout/spacer'
 import {
   Contract,
   getContractFromSlug,
+  getRandTopCreatorContracts,
   tradingAllowed,
 } from 'web/lib/firebase/contracts'
 import { SEO } from 'web/components/SEO'
@@ -39,6 +40,8 @@ import {
   ContractLeaderboard,
   ContractTopTrades,
 } from 'web/components/contract/contract-leaderboard'
+import { Subtitle } from 'web/components/subtitle'
+import { ContractsGrid } from 'web/components/contract/contracts-grid'
 
 export const getStaticProps = fromPropz(getStaticPropz)
 export async function getStaticPropz(props: {
@@ -48,9 +51,12 @@ export async function getStaticPropz(props: {
   const contract = (await getContractFromSlug(contractSlug)) || null
   const contractId = contract?.id
 
-  const [bets, comments] = await Promise.all([
+  const [bets, comments, recommendedContracts] = await Promise.all([
     contractId ? listAllBets(contractId) : [],
     contractId ? listAllComments(contractId) : [],
+    contract
+      ? getRandTopCreatorContracts(contract.creatorId, 4, [contract?.id])
+      : [],
   ])
 
   return {
@@ -61,6 +67,7 @@ export async function getStaticPropz(props: {
       // Limit the data sent to the client. Client will still load all bets and comments directly.
       bets: bets.slice(0, 5000),
       comments: comments.slice(0, 1000),
+      recommendedContracts,
     },
 
     revalidate: 60, // regenerate after a minute
@@ -77,6 +84,7 @@ export default function ContractPage(props: {
   bets: Bet[]
   comments: ContractComment[]
   slug: string
+  recommendedContracts: Contract[]
   backToHome?: () => void
 }) {
   props = usePropz(props, getStaticPropz) ?? {
@@ -84,6 +92,7 @@ export default function ContractPage(props: {
     username: '',
     comments: [],
     bets: [],
+    recommendedContracts: [],
     slug: '',
   }
 
@@ -145,7 +154,7 @@ export function ContractPageContent(
     user?: User | null
   }
 ) {
-  const { backToHome, comments, user } = props
+  const { backToHome, comments, user, recommendedContracts } = props
 
   const contract = useContractWithPreload(props.contract) ?? props.contract
 
@@ -258,6 +267,13 @@ export function ContractPageContent(
           tips={tips}
           comments={comments}
         />
+
+        {recommendedContracts?.length > 0 && (
+          <Col className="mx-2 gap-2 sm:mx-0">
+            <Subtitle text="Recommended" />
+            <ContractsGrid contracts={recommendedContracts} />
+          </Col>
+        )}
       </Col>
     </Page>
   )