Daily active users & comments

This commit is contained in:
James Grugett 2022-03-03 12:59:12 -08:00
parent ed9b20b5ad
commit cb9fa0ceb2
3 changed files with 83 additions and 14 deletions

View File

@ -6,8 +6,9 @@ import { useWindowSize } from '../../hooks/use-window-size'
export function DailyCountChart(props: { export function DailyCountChart(props: {
startDate: number startDate: number
dailyCounts: number[] dailyCounts: number[]
small?: boolean
}) { }) {
const { dailyCounts, startDate } = props const { dailyCounts, startDate, small } = props
const { width } = useWindowSize() const { width } = useWindowSize()
const dates = dailyCounts.map((_, i) => const dates = dailyCounts.map((_, i) =>
@ -18,16 +19,16 @@ export function DailyCountChart(props: {
x: date, x: date,
y: betCount, y: betCount,
})) }))
const data = [{ id: 'Yes', data: points, color: '#11b981' }] const data = [{ id: 'Count', data: points, color: '#11b981' }]
return ( return (
<div <div
className="w-full" className="w-full"
style={{ height: !width || width >= 800 ? 400 : 250 }} style={{ height: !small && (!width || width >= 800) ? 400 : 250 }}
> >
<ResponsiveLine <ResponsiveLine
data={data} data={data}
yScale={{ type: 'linear' }} yScale={{ type: 'linear', stacked: false }}
xScale={{ xScale={{
type: 'time', type: 'time',
}} }}
@ -35,7 +36,7 @@ export function DailyCountChart(props: {
format: (date) => dayjs(date).format('MMM DD'), format: (date) => dayjs(date).format('MMM DD'),
}} }}
colors={{ datum: 'color' }} colors={{ datum: 'color' }}
pointSize={10} pointSize={width && width >= 800 ? 10 : 0}
pointBorderWidth={1} pointBorderWidth={1}
pointBorderColor="#fff" pointBorderColor="#fff"
enableSlices="x" enableSlices="x"

View File

@ -7,6 +7,7 @@ import {
where, where,
orderBy, orderBy,
} from 'firebase/firestore' } from 'firebase/firestore'
import _ from 'lodash'
import { getValues, listenForValues } from './utils' import { getValues, listenForValues } from './utils'
import { db } from './init' import { db } from './init'
@ -89,3 +90,30 @@ export function listenForRecentComments(
) { ) {
return listenForValues<Comment>(recentCommentsQuery, setComments) return listenForValues<Comment>(recentCommentsQuery, setComments)
} }
const getCommentsQuery = (startTime: number, endTime: number) =>
query(
collectionGroup(db, 'comments'),
where('createdTime', '>=', startTime),
where('createdTime', '<', endTime),
orderBy('createdTime', 'asc')
)
export async function getDailyComments(
startTime: number,
numberOfDays: number
) {
const query = getCommentsQuery(
startTime,
startTime + DAY_IN_MS * numberOfDays
)
const comments = await getValues<Comment>(query)
const commentsByDay = _.range(0, numberOfDays).map(() => [] as Comment[])
for (const comment of comments) {
const dayIndex = Math.floor((comment.createdTime - startTime) / DAY_IN_MS)
commentsByDay[dayIndex].push(comment)
}
return commentsByDay
}

View File

@ -2,9 +2,11 @@ import dayjs from 'dayjs'
import _ from 'lodash' import _ from 'lodash'
import { DailyCountChart } from '../components/analytics/charts' import { DailyCountChart } from '../components/analytics/charts'
import { Col } from '../components/layout/col' import { Col } from '../components/layout/col'
import { Spacer } from '../components/layout/spacer'
import { Page } from '../components/page' import { Page } from '../components/page'
import { Title } from '../components/title' import { Title } from '../components/title'
import { getDailyBets } from '../lib/firebase/bets' import { getDailyBets } from '../lib/firebase/bets'
import { getDailyComments } from '../lib/firebase/comments'
import { getDailyContracts } from '../lib/firebase/contracts' import { getDailyContracts } from '../lib/firebase/contracts'
export async function getStaticProps() { export async function getStaticProps() {
@ -12,22 +14,34 @@ export async function getStaticProps() {
const today = dayjs(dayjs().format('YYYY-MM-DD')) const today = dayjs(dayjs().format('YYYY-MM-DD'))
const startDate = today.subtract(numberOfDays, 'day') const startDate = today.subtract(numberOfDays, 'day')
const dailyBets = await getDailyBets(startDate.valueOf(), numberOfDays) const [dailyBets, dailyContracts, dailyComments] = await Promise.all([
const dailyBetCounts = dailyBets.map((bets) => bets.length) getDailyBets(startDate.valueOf(), numberOfDays),
getDailyContracts(startDate.valueOf(), numberOfDays),
getDailyComments(startDate.valueOf(), numberOfDays),
])
const dailyContracts = await getDailyContracts( const dailyBetCounts = dailyBets.map((bets) => bets.length)
startDate.valueOf(),
numberOfDays
)
const dailyContractCounts = dailyContracts.map( const dailyContractCounts = dailyContracts.map(
(contracts) => contracts.length (contracts) => contracts.length
) )
const dailyCommentCounts = dailyComments.map((comments) => comments.length)
const dailyActiveUsers = _.zip(dailyContracts, dailyBets, dailyComments).map(
([contracts, bets, comments]) => {
const creatorIds = (contracts ?? []).map((c) => c.creatorId)
const betUserIds = (bets ?? []).map((bet) => bet.userId)
const commentUserIds = (comments ?? []).map((comment) => comment.userId)
return _.uniq([...creatorIds, ...betUserIds, commentUserIds]).length
}
)
return { return {
props: { props: {
startDate: startDate.valueOf(), startDate: startDate.valueOf(),
dailyActiveUsers,
dailyBetCounts, dailyBetCounts,
dailyContractCounts, dailyContractCounts,
dailyCommentCounts,
}, },
revalidate: 12 * 60 * 60, // regenerate after half a day revalidate: 12 * 60 * 60, // regenerate after half a day
} }
@ -35,12 +49,15 @@ export async function getStaticProps() {
export default function Analytics(props: { export default function Analytics(props: {
startDate: number startDate: number
dailyActiveUsers: number[]
dailyBetCounts: number[] dailyBetCounts: number[]
dailyContractCounts: number[] dailyContractCounts: number[]
dailyCommentCounts: number[]
}) { }) {
return ( return (
<Page> <Page>
<CustomAnalytics {...props} /> <CustomAnalytics {...props} />
<Spacer h={8} />
<FirebaseAnalytics /> <FirebaseAnalytics />
</Page> </Page>
) )
@ -48,19 +65,42 @@ export default function Analytics(props: {
function CustomAnalytics(props: { function CustomAnalytics(props: {
startDate: number startDate: number
dailyActiveUsers: number[]
dailyBetCounts: number[] dailyBetCounts: number[]
dailyContractCounts: number[] dailyContractCounts: number[]
dailyCommentCounts: number[]
}) { }) {
const { startDate, dailyBetCounts, dailyContractCounts } = props const {
startDate,
dailyActiveUsers,
dailyBetCounts,
dailyContractCounts,
dailyCommentCounts,
} = props
return ( return (
<Col className="mb-8"> <Col>
<Title text="Active users" />
<DailyCountChart dailyCounts={dailyActiveUsers} startDate={startDate} />
<Title text="Bets count" /> <Title text="Bets count" />
<DailyCountChart dailyCounts={dailyBetCounts} startDate={startDate} /> <DailyCountChart
dailyCounts={dailyBetCounts}
startDate={startDate}
small
/>
<Title text="Markets count" /> <Title text="Markets count" />
<DailyCountChart <DailyCountChart
dailyCounts={dailyContractCounts} dailyCounts={dailyContractCounts}
startDate={startDate} startDate={startDate}
small
/>
<Title text="Comments count" />
<DailyCountChart
dailyCounts={dailyCommentCounts}
startDate={startDate}
small
/> />
</Col> </Col>
) )