Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: increment page views server-side #3981

Merged
merged 3 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions src/pages/Howto/Content/Howto/Howto.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ const mockHowtoStore = () => ({
setActiveHowtoBySlug: vi.fn(),
activeHowto: howto,
needsModeration: vi.fn().mockReturnValue(false),
incrementViewCount: vi.fn(),
removeActiveHowto: vi.fn(),
})

Expand Down Expand Up @@ -151,7 +150,7 @@ describe('Howto', () => {
act(() => {
wrapper = factory(
{
...mockHowtoStore(),
...(mockHowtoStore() as any),
},
FactoryHowto({
_createdBy: 'HowtoAuthor',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Fragment, useEffect, useState } from 'react'
import { Fragment, useState } from 'react'
import { Link, useNavigate } from '@remix-run/react'
import {
Button,
Expand All @@ -25,7 +25,6 @@ import {
isAllowedToDeleteContent,
isAllowedToEditContent,
} from 'src/utils/helpers'
import { incrementViewCount } from 'src/utils/incrementViewCount'
import { Alert, Box, Card, Divider, Flex, Heading, Image, Text } from 'theme-ui'

import { ContentAuthorTimestamp } from '../../../../common/ContentAuthorTimestamp/ContentAuthorTimestamp'
Expand Down Expand Up @@ -73,14 +72,6 @@ const HowtoDescription = ({ howto, loggedInUser, ...props }: IProps) => {
}
}

useEffect(() => {
incrementViewCount({
document: howto,
documentType: 'howto',
store: stores.howtoStore,
})
}, [howto._id])

return (
<Card>
<Flex
Expand Down
1 change: 0 additions & 1 deletion src/pages/Research/Content/ResearchArticle.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ describe('Research Article', () => {
const mockResearchStore = {
addSubscriberToResearchArticle: vi.fn(),
formatResearchCommentList: vi.fn(),
incrementViewCount: vi.fn(),
}

it('displays content statistics', async () => {
Expand Down
11 changes: 1 addition & 10 deletions src/pages/Research/Content/ResearchDescription.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Fragment, useEffect, useState } from 'react'
import { Fragment, useState } from 'react'
import { Link, useNavigate } from '@remix-run/react'
import {
Button,
Expand All @@ -19,7 +19,6 @@ import { TagList } from 'src/common/Tags/TagsList'
import { logger } from 'src/logger'
import { useResearchStore } from 'src/stores/Research/research.store'
import { buildStatisticsLabel } from 'src/utils/helpers'
import { incrementViewCount } from 'src/utils/incrementViewCount'
import { Box, Card, Divider, Flex, Heading, Text } from 'theme-ui'

import { ContentAuthorTimestamp } from '../../common/ContentAuthorTimestamp/ContentAuthorTimestamp'
Expand Down Expand Up @@ -82,14 +81,6 @@ const ResearchDescription = ({
}
}

useEffect(() => {
incrementViewCount({
store,
document: research,
documentType: 'research',
})
}, [research._id])

return (
<Card
sx={{
Expand Down
1 change: 0 additions & 1 deletion src/pages/User/user.routes.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ vi.mock('src/common/hooks/useCommonStores', () => ({
stores: {
userStore: {
updateUserBadge: mockUpdateUserBadge,
incrementViewCount: vi.fn(),
},
aggregationsStore: {
updateVerifiedUsers: vi.fn(),
Expand Down
6 changes: 6 additions & 0 deletions src/routes/_.how-to.$slug._index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useLoaderData } from '@remix-run/react'
import { Howto } from 'src/pages/Howto/Content/Howto/Howto'
import { howtoService } from 'src/pages/Howto/howto.service'
import { NotFoundPage } from 'src/pages/NotFound/NotFound'
import { pageViewService } from 'src/services/pageView.service'
import { generateTags, mergeMeta } from 'src/utils/seo.utils'

import type { LoaderFunctionArgs } from '@remix-run/node'
Expand All @@ -11,6 +12,11 @@ import type { IHowtoDB } from 'oa-shared'
export async function loader({ params }: LoaderFunctionArgs) {
const howto = await howtoService.getBySlug(params.slug as string)

if (howto?._id) {
// not awaited to not block the render
pageViewService.incrementViewCount('howtos', howto._id)
}

return json({ howto })
}

Expand Down
6 changes: 6 additions & 0 deletions src/routes/_.questions.$slug._index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useLoaderData } from '@remix-run/react'
import { NotFoundPage } from 'src/pages/NotFound/NotFound'
import { questionService } from 'src/pages/Question/question.service'
import { QuestionPage } from 'src/pages/Question/QuestionPage'
import { pageViewService } from 'src/services/pageView.service'
import { generateTags, mergeMeta } from 'src/utils/seo.utils'

import type { LoaderFunctionArgs } from '@remix-run/node'
Expand All @@ -11,6 +12,11 @@ import type { IQuestionDB, IUploadedFileMeta } from 'oa-shared'
export async function loader({ params }: LoaderFunctionArgs) {
const question = await questionService.getBySlug(params.slug as string)

if (question?._id) {
// not awaited to not block the render
pageViewService.incrementViewCount('questions', question._id)
}

return json({ question })
}

Expand Down
6 changes: 6 additions & 0 deletions src/routes/_.research.$slug._index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ResearchUpdateStatus } from 'oa-shared'
import { NotFoundPage } from 'src/pages/NotFound/NotFound'
import ResearchArticle from 'src/pages/Research/Content/ResearchArticle'
import { researchService } from 'src/pages/Research/research.service'
import { pageViewService } from 'src/services/pageView.service'
import { generateTags, mergeMeta } from 'src/utils/seo.utils'

import type { LoaderFunctionArgs } from '@remix-run/node'
Expand All @@ -16,6 +17,11 @@ export async function loader({ params }: LoaderFunctionArgs) {
(x) => x.status !== ResearchUpdateStatus.DRAFT && x._deleted !== true,
) || []

if (research?._id) {
// not awaited to not block the render
pageViewService.incrementViewCount('research', research._id)
}

return json({ research, publicUpdates })
}

Expand Down
6 changes: 6 additions & 0 deletions src/routes/_.u.$id._index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { json } from '@remix-run/node'
import { useLoaderData } from '@remix-run/react'
import { UserProfile } from 'src/pages/User/content/UserProfile'
import { pageViewService } from 'src/services/pageView.service'
import { userService } from 'src/services/user.service'
import { generateTags, mergeMeta } from 'src/utils/seo.utils'
import { Text } from 'theme-ui'
Expand All @@ -16,6 +17,11 @@ export async function loader({ params }: LoaderFunctionArgs) {
userService.getUserCreatedDocs(userId),
])

if (profile?._id) {
// not awaited to not block the render
pageViewService.incrementViewCount('users', profile._id)
}

return json({ profile, userCreatedDocs: userCreatedDocs || [] })
}

Expand Down
23 changes: 23 additions & 0 deletions src/services/pageView.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { doc, increment, updateDoc } from 'firebase/firestore'
import { DB_ENDPOINTS } from 'oa-shared'
import { firestore } from 'src/utils/firebase'

type PageViewCollections = Pick<
typeof DB_ENDPOINTS,
'users' | 'questions' | 'research' | 'howtos'
>

const incrementViewCount = async (
collectionName: keyof PageViewCollections,
id: string,
) => {
const docRef = doc(firestore, DB_ENDPOINTS[collectionName], id)

return await updateDoc(docRef, {
total_views: increment(1),
})
}

export const pageViewService = {
incrementViewCount,
}
16 changes: 0 additions & 16 deletions src/stores/Howto/howto.store.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,20 +227,4 @@ describe('howto.store', () => {
expect(updatedDownloads).toBe(downloads + 1)
})
})

describe('incrementViews', () => {
it('increments views by one', async () => {
const howtoDoc = FactoryHowto({ total_views: 18 })
const { store, howToItem, updateFn } = await factory([howtoDoc])

// Act
await store.incrementViewCount(howToItem)
const updatedTotalViews = 19

expect(updateFn).toHaveBeenCalledWith(
expect.objectContaining({ total_views: updatedTotalViews }),
expect.anything(),
)
})
})
})
9 changes: 0 additions & 9 deletions src/stores/Howto/howto.store.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { logger } from 'src/logger'
import { getUserCountry } from 'src/utils/getUserCountry'
import { getKeywords } from 'src/utils/searchHelper'

import { incrementDocViewCount } from '../common/incrementDocViewCount'
import { changeMentionToUserReference } from '../common/mentions'
import { ModuleStore } from '../common/module.store'
import { toggleDocUsefulByUser } from '../common/toggleDocUsefulByUser'
Expand Down Expand Up @@ -91,14 +90,6 @@ export class HowtoStore extends ModuleStore {
}
}

public async incrementViewCount(howTo: Partial<IHowtoDB>) {
return await incrementDocViewCount({
collection: COLLECTION_NAME,
db: this.db,
doc: howTo,
})
}

private async addUserReference(msg: string): Promise<{
text: string
users: string[]
Expand Down
24 changes: 0 additions & 24 deletions src/stores/Question/question.store.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,30 +81,6 @@ describe('question.store', () => {
})
})

describe('incrementViews', () => {
it('increments views by one', async () => {
const { store, updateFn } = factory()

const question = FactoryQuestionItem({
title: 'which trees to cut down',
_createdBy: undefined,
total_views: 56,
})

// Act
await store.upsertQuestion(question)

// Act
await store.incrementViewCount(question)
const updatedTotalViews = 57

expect(updateFn).toHaveBeenCalledWith(
expect.objectContaining({ total_views: updatedTotalViews }),
expect.anything(),
)
})
})

describe('toggleSubscriberStatusByUserName', () => {
it('calls the toggle subscriber function', async () => {
const { store } = factory()
Expand Down
10 changes: 0 additions & 10 deletions src/stores/Question/question.store.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { logger } from 'src/logger'
import { getUserCountry } from 'src/utils/getUserCountry'
import { getKeywords } from 'src/utils/searchHelper'

import { incrementDocViewCount } from '../common/incrementDocViewCount'
import { ModuleStore } from '../common/module.store'
import { toggleDocSubscriberStatusByUserName } from '../common/toggleDocSubscriberStatusByUserName'
import { toggleDocUsefulByUser } from '../common/toggleDocUsefulByUser'
Expand All @@ -12,7 +11,6 @@ import type {
IConvertedFileMeta,
IModerationStatus,
IQuestion,
IQuestionDB,
IUploadedFileMeta,
} from 'oa-shared'
import type { DBEndpoint } from '../databaseV2/endpoints'
Expand All @@ -25,14 +23,6 @@ export class QuestionStore extends ModuleStore {
super(rootStore, COLLECTION_NAME)
}

public async incrementViewCount(question: Partial<IQuestionDB>) {
await incrementDocViewCount({
collection: COLLECTION_NAME,
db: this.db,
doc: question,
})
}

public async upsertQuestion(values: IQuestion.FormInput) {
logger.info(`upsertQuestion:`, { values, activeUser: this.activeUser })

Expand Down
15 changes: 0 additions & 15 deletions src/stores/Research/research.store.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -412,21 +412,6 @@ describe('research.store', () => {
})
})

describe('incrementViews', () => {
it('increments views by one', async () => {
const { store, researchItem, updateFn } = await factoryResearchItem()

// Act
await store.incrementViewCount(researchItem)
const updatedTotalViews = researchItem.total_views + 1

expect(updateFn).toHaveBeenCalledWith(
expect.objectContaining({ total_views: updatedTotalViews }),
expect.anything(),
)
})
})

describe('Subscribe', () => {
it('adds subscriber to the research article', async () => {
const { store, researchItem, updateFn } =
Expand Down
9 changes: 0 additions & 9 deletions src/stores/Research/research.store.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { getUserCountry } from 'src/utils/getUserCountry'
import { hasAdminRights, randomID } from 'src/utils/helpers'
import { getKeywords } from 'src/utils/searchHelper'

import { incrementDocViewCount } from '../common/incrementDocViewCount'
import { changeMentionToUserReference } from '../common/mentions'
import { ModuleStore } from '../common/module.store'
import { toggleDocSubscriberStatusByUserName } from '../common/toggleDocSubscriberStatusByUserName'
Expand Down Expand Up @@ -98,14 +97,6 @@ export class ResearchStore extends ModuleStore {
return
}

public async incrementViewCount(researchItem: Partial<IResearch.ItemDB>) {
return await incrementDocViewCount({
collection: COLLECTION_NAME,
db: this.db,
doc: researchItem,
})
}

public async deleteResearch(id: string) {
try {
const dbRef = this.db.collection<IResearchDB>(COLLECTION_NAME).doc(id)
Expand Down
9 changes: 0 additions & 9 deletions src/stores/User/user.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import { logger } from '../../logger'
import { auth, EmailAuthProvider } from '../../utils/firebase'
import { getLocationData } from '../../utils/getLocationData'
import { formatLowerNoSpecial } from '../../utils/helpers'
import { incrementDocViewCount } from '../common/incrementDocViewCount'
import { ModuleStore } from '../common/module.store'
import { Storage } from '../storage'

Expand Down Expand Up @@ -274,14 +273,6 @@ export class UserStore extends ModuleStore {
return this.activeUser
}

public async incrementViewCount(user: Partial<IUserDB>) {
return await incrementDocViewCount({
collection: COLLECTION_NAME,
db: this.db,
doc: user,
})
}

public async updateUserImpact(
fields: IImpactYearFieldList,
year: IImpactYear,
Expand Down
27 changes: 0 additions & 27 deletions src/stores/common/incrementDocViewCount.tsx

This file was deleted.

Loading
Loading