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(page views): track pageviews #51

Merged
merged 6 commits into from
Dec 26, 2022
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
1 change: 1 addition & 0 deletions app/models/page-view/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './page-view.server'
11 changes: 11 additions & 0 deletions app/models/page-view/page-view.server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as AudiophileClient from '~/utils/audiophile-client'

export const createPageView = async (sessionId: string, url: string) => {
const urlObj = new URL(url)
const body = {
page_path: urlObj.pathname,
query_params: urlObj.search
}

await AudiophileClient.sendRequest('post', 'page_views', { sessionToken: sessionId, body })
}
4 changes: 2 additions & 2 deletions app/routes/api/purchase-carts/$cartUuid.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import invariant from 'tiny-invariant'
import { removeCart } from '~/models/purchase-cart'
import * as SessionStorage from '~/utils/session-storage'
import { getSessionId } from '~/utils/session-storage'

import type { ActionArgs } from '@remix-run/node'

export const action = async ({ params, request }: ActionArgs) => {
if (request.method !== 'DELETE') return

const { sessionId } = await SessionStorage.getOrCreateSessionId(request)
const sessionId = await getSessionId(request)
invariant(sessionId, 'there must be an active user session')

const { cartUuid } = params
Expand Down
7 changes: 5 additions & 2 deletions app/routes/api/purchase-carts/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { json } from '@remix-run/node'
import invariant from 'tiny-invariant'
import { createOrUpdateCart } from '~/models/purchase-cart'
import * as SessionStorage from '~/utils/session-storage'
import { getSessionId } from '~/utils/session-storage'

import type { ActionArgs } from '@remix-run/node'

export const action = async ({ request }: ActionArgs) => {
const { sessionId } = await SessionStorage.getOrCreateSessionId(request)
const sessionId = await getSessionId(request)
invariant(sessionId, 'sessionId not found')

const { item, cartUuid } = await request.json()

const cart = await createOrUpdateCart(sessionId, item, cartUuid)
Expand Down
5 changes: 4 additions & 1 deletion app/routes/categories/$categorySlug.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ import invariant from "tiny-invariant"
import { allProductCategories, getProductCategory } from "~/models/product-category"
import { Heading, ProductBanner, CategoriesList, BestAudioBanner } from '~/components'
import type { LoaderArgs } from "@remix-run/server-runtime"
import trackPageView from "~/utils/track-page-view"

export const loader = async ({ params, request }: LoaderArgs) => {
trackPageView(request)

export const loader = async ({ params }: LoaderArgs) => {
const { categorySlug } = params
invariant(categorySlug, "Category slug is required")

Expand Down
9 changes: 7 additions & 2 deletions app/routes/checkout.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import { Outlet, useLoaderData } from '@remix-run/react'
import { json, redirect } from '@remix-run/node'
import invariant from 'tiny-invariant'
import { Text, PurchaseCartSummary } from '~/components'
import { getLastStartedCart } from '~/models/purchase-cart'
import { getOrCreateSessionId } from '~/utils/session-storage'
import { getSessionId } from '~/utils/session-storage'
import trackPageView from '~/utils/track-page-view'
import { getAccessToken } from '~/utils/auth-storage'
import goBack from '~/utils/go-back'

import type { LoaderArgs } from '@remix-run/node'

export const loader = async ({ request }: LoaderArgs) => {
const { sessionId } = await getOrCreateSessionId(request)
trackPageView(request)

const sessionId = await getSessionId(request)
invariant(sessionId, 'sessionId must exist')

const activeCart = await getLastStartedCart(sessionId)
if(!activeCart) return redirect('/')
Expand Down
8 changes: 7 additions & 1 deletion app/routes/checkout/billing-details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import * as SessionStorage from '~/utils/session-storage'
import formDataToObject from '~/utils/form-data-to-object'
import RequestError from '~/errors/request-error'
import { PHONE_REGEXP } from '~/constants'
import trackPageView from '~/utils/track-page-view'

import type { ActionArgs } from '@remix-run/node'
import type { ActionArgs, LoaderArgs } from '@remix-run/node'
import type { UserInfoPayload } from '~/models/auth'

interface ValidationErrors {
Expand All @@ -28,6 +29,11 @@ const validateForm = (userInfo: UserInfoPayload) => {
return errors
}

export const loader = async ({ request }: LoaderArgs) => {
trackPageView(request)
return null;
}

export const action = async ({ request }: ActionArgs) => {
const formData = await request.formData()
const userInfo = formDataToObject(formData) as UserInfoPayload
Expand Down
8 changes: 7 additions & 1 deletion app/routes/checkout/confirmation-code.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import RequestError from '~/errors/request-error'
import { confirmCode } from '~/models/auth'
import useCountdown from '~/hooks/use-countdown'
import goBack from '~/utils/go-back'
import trackPageView from '~/utils/track-page-view'

import type { ActionArgs } from '@remix-run/node'
import type { ActionArgs, LoaderArgs } from '@remix-run/node'
import type { CodeInfoPayload } from '~/models/auth'

const CODE_EXPIRATION_TIME = 5 * 60 // 5 minutes
Expand All @@ -29,6 +30,11 @@ const validateForm = (codeInfo: CodeInfoPayload) => {
return errors
}

export const loader = async ({ request }: LoaderArgs) => {
trackPageView(request)
return null;
}

export const action = async ({ request }: ActionArgs) => {
const formData = await request.formData()
const { code } = formDataToObject(formData)
Expand Down
8 changes: 7 additions & 1 deletion app/routes/checkout/login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import formDataToObject from '~/utils/form-data-to-object'
import { getOrCreateSessionId } from '~/utils/session-storage'
import RequestError from '~/errors/request-error'
import { login } from '~/models/auth'
import trackPageView from '~/utils/track-page-view'

import type { ActionArgs } from '@remix-run/node'
import type { ActionArgs, LoaderArgs } from '@remix-run/node'
import type { UserInfoPayload } from '~/models/auth'

interface ValidationErrors {
Expand All @@ -21,6 +22,11 @@ const validateForm = (userInfo: UserInfoPayload) => {
return errors
}

export const loader = async ({ request }: LoaderArgs) => {
trackPageView(request)
return null;
}

export const action = async ({ request }: ActionArgs) => {
const formData = await request.formData()
const userInfo = formDataToObject(formData) as UserInfoPayload
Expand Down
7 changes: 6 additions & 1 deletion app/routes/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@ import { HomeHero, CategoriesList, BestAudioBanner, HomeProductBanners } from '~
import { featuredProducts, homepageProducts } from '~/models/product'
import { allProductCategories } from '~/models/product-category'
import getRandom from '~/utils/get-random'
import trackPageView from '~/utils/track-page-view'

import type { LoaderArgs } from '@remix-run/node'

export const loader = async ({ request }: LoaderArgs) => {
trackPageView(request)

export const loader = async () => {
const products = await featuredProducts()
const featuredProduct = getRandom(products)

Expand Down
5 changes: 4 additions & 1 deletion app/routes/products/$productSlug.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ import { getProduct } from '~/models/product'
import { getProductStocks } from '~/models/product-stock'
import { allProductCategories } from '~/models/product-category'
import { ProductHeading, ProductFeatures, ProductGallery, CategoriesList, BestAudioBanner } from '~/components'
import trackPageView from '~/utils/track-page-view'
import goBack from '~/utils/go-back'

import type { LoaderArgs } from '@remix-run/node'

export const loader = async ({ params }: LoaderArgs) => {
export const loader = async ({ params, request }: LoaderArgs) => {
trackPageView(request)

const { productSlug } = params
invariant(productSlug, "Product slug is required")

Expand Down
1 change: 1 addition & 0 deletions app/utils/track-page-view/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './track-page-view'
12 changes: 12 additions & 0 deletions app/utils/track-page-view/track-page-view.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import invariant from 'tiny-invariant'
import { createPageView } from '~/models/page-view'
import { getOrCreateSessionId } from '~/utils/session-storage'

const trackPageView = async (request: Request) => {
const { sessionId } = await getOrCreateSessionId(request)
invariant(sessionId, 'sessionId must exist')

createPageView(sessionId, request.url)
}

export default trackPageView