Skip to content

Commit

Permalink
chore: make tracking work
Browse files Browse the repository at this point in the history
  • Loading branch information
PupoSDC committed Nov 24, 2023
1 parent 171f45f commit 315d55b
Show file tree
Hide file tree
Showing 20 changed files with 125 additions and 134 deletions.
29 changes: 22 additions & 7 deletions apps/next-app/pages/analytics/index.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,42 @@
import { LineChart, Line, CartesianGrid, XAxis, YAxis } from "recharts";
import {
LineChart,
Line,
CartesianGrid,
XAxis,
YAxis,
Tooltip,
Legend,
} from "recharts";
import { trpc } from "@chair-flight/trpc/client";
import { getTrpcHelper } from "@chair-flight/trpc/server";
import type { NextPage } from "next";

const data = [{ name: "Page A", uv: 400, pv: 2400, amt: 2400 }];

const useVisitsPerDay = trpc.analytics.visitsPerDay.useSuspenseQuery;

const AnalyticsPage: NextPage = () => {
useVisitsPerDay();
const [{ views, paths }] = useVisitsPerDay();
return (
<LineChart width={400} height={400} data={data}>
<Line type="monotone" dataKey="uv" stroke="#8884d8" />
<LineChart width={400} height={400} data={views}>
{paths.map((path) => (
<Line key={path} type="monotone" dataKey={path} stroke="#8884d8" />
))}
<CartesianGrid stroke="#ccc" />
<XAxis dataKey="name" />
<YAxis />
<Tooltip />
<Legend />
</LineChart>
);
};

export async function getStaticProps() {
const helper = await getTrpcHelper();

await helper.analytics.visitsPerDay.prefetch();

return {
props: {
posts: [],
trpcState: helper.dehydrate(),
},
revalidate: 60 * 15,
};
Expand Down
2 changes: 1 addition & 1 deletion libs/base/types/src/lib/analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export type PageEvent = {
};

export type TrackEventMap = {
"exploreQuestions.click": Record<string, unknown>;
"themeButton.switch": Record<string, never>;
};

export type TrackEventName = keyof TrackEventMap;
Expand Down
1 change: 0 additions & 1 deletion libs/content/question-bank-atpl/src/question-bank-atpl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ let subjects: Subject[];

export const getAllQuestionTemplates = async () => {
if (!questions) {
console.log(API_PATH_QUESTIONS);
const response = await fetch(API_PATH_QUESTIONS);
questions = (await response.json()) as QuestionTemplate[];
}
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,37 @@ CREATE TABLE "PageEvent" (
"timestamp" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"anonymousId" TEXT NOT NULL,
"title" TEXT NOT NULL,
"url" TEXT NOT NULL,
"referrer" TEXT NOT NULL,
"height" INTEGER NOT NULL,
"width" INTEGER NOT NULL,
"hash" TEXT NOT NULL,
"timeOnPage" INTEGER NOT NULL,
"environment" TEXT NOT NULL,
"path" TEXT NOT NULL,
"resolvedPath" TEXT NOT NULL,

CONSTRAINT "PageEvent_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "PageEventDailyCount" (
"id" TEXT NOT NULL,
"environment" TEXT NOT NULL,
"count" INTEGER NOT NULL,
"path" TEXT NOT NULL,
"timestamp" TIMESTAMP(3) NOT NULL,

CONSTRAINT "PageEventDailyCount_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "TrackEvent" (
"id" TEXT NOT NULL,
"timestamp" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"anonymousId" TEXT NOT NULL,
"eventName" TEXT NOT NULL,
"properties" JSONB NOT NULL,
"environment" TEXT NOT NULL,
"path" TEXT NOT NULL,
"resolvedPath" TEXT NOT NULL,

CONSTRAINT "TrackEvent_pkey" PRIMARY KEY ("id")
);
4 changes: 2 additions & 2 deletions libs/core/analytics/prisma/schema.prisma
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
generator client {
provider = "prisma-client-js"
provider = "prisma-client-js"
}

datasource db {
Expand All @@ -23,10 +23,10 @@ model PageEvent {

model PageEventDailyCount {
id String @id @default(uuid())
timestamp DateTime
environment String
count Int
path String
timestamp DateTime
}

model TrackEvent {
Expand Down
18 changes: 18 additions & 0 deletions libs/core/analytics/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,24 @@
}
}
},
"studio": {
"executor": "nx:run-commands",
"options": {
"cwd": "libs/core/analytics",
"command": "prisma studio"
},
"configurations": {
"local": {
"command": "env-cmd -f ../../../.env.local prisma migrate dev"
},
"dev": {
"command": "env-cmd -f ../../../.env.dev prisma migrate dev"
},
"prod": {
"command": "env-cmd -f ../../../.env.prod prisma migrate dev"
}
}
},
"lint": {
"executor": "@nx/linter:eslint",
"outputs": ["{options.outputFile}"],
Expand Down
50 changes: 39 additions & 11 deletions libs/core/analytics/src/functions/page-visits-analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { prisma } from "../config/postgres-connection";
const FirstDateWeCareAbout = new Date("2023-07-30");

export const getPageVisits = async () => {
return await prisma.pageEventDailyCount.findMany({
const data = await prisma.pageEventDailyCount.findMany({
where: {
timestamp: {
gte: FirstDateWeCareAbout,
Expand All @@ -14,6 +14,26 @@ export const getPageVisits = async () => {
timestamp: "asc",
},
});

const views = data.reduce<Array<Record<string, string | number>>>(
(acc, curr) => {
const { timestamp, path, count } = curr;
const name = DateTime.fromJSDate(timestamp).toFormat("yyyy-MM-dd");
let existingDate = acc.find((item) => item["name"] === name);
if (!existingDate) acc.push({ name });
existingDate ??= acc.at(-1)!;
existingDate[path] = count;
return acc;
},
[],
);

const paths = data.reduce<string[]>((acc, curr) => {
const { path } = curr;
if (!acc.includes(path)) acc.push(path);
return acc;
}, []);
return { views, paths };
};

export const generateDailyCounts = async () => {
Expand All @@ -35,16 +55,24 @@ export const generateDailyCounts = async () => {
};

const dailyCounts = await prisma.$queryRaw<DailyCount[]>`
SELECT
COUNT(*) as "count"
Date(timestamp) as "timestamp"
environment as "environment"
path as "path"
FROM "PageEvent"
GROUP BY "date", "path", "environment"
ORDER BY "date" ASC
WHERE "timestamp" >= ${firstDay}
`;
SELECT
count,
"timestamp2" as "timestamp",
environment,
path
FROM (
SELECT
COUNT(*)::integer as "count",
DATE_TRUNC('day', timestamp) as "timestamp2",
environment as "environment",
path as "path"
FROM "PageEvent"
WHERE "timestamp" >= ${firstDay}
GROUP BY "timestamp2", "path", "environment"
ORDER BY "timestamp2" ASC
) as subquery
ORDER BY "timestamp2" ASC;
`;

await prisma.pageEventDailyCount.createMany({
data: dailyCounts,
Expand Down
4 changes: 2 additions & 2 deletions libs/react/analytics/src/use-analytics-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ export const useAnalyticsPlugin = (): AnalyticsPlugin => {
},
track: (props: OriginalTrackEventProps) => {
trackEvent.mutate({
path: router.pathname,
resolvedPath: router.asPath,
eventName: props.payload.event,
anonymousId: props.payload.anonymousId,
path: router.pathname,
resolvedPath: router.asPath,
properties: props.payload.properties,
timestamp: Date.now(),
});
Expand Down
32 changes: 13 additions & 19 deletions libs/react/analytics/src/use-analytics.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createContext, useContext, useEffect, useState } from "react";
import { createContext, useContext, useState } from "react";
import { useAnalyticsPlugin } from "./use-analytics-plugin";
import type {
TrackEventName,
Expand All @@ -7,27 +7,21 @@ import type {
import type { AnalyticsInstance } from "analytics";
import type { FunctionComponent, PropsWithChildren } from "react";

const analyticsContext = createContext<AnalyticsInstance | null>(null);
const analyticsContext = createContext<Promise<AnalyticsInstance>>(
null as unknown as Promise<AnalyticsInstance>,
);

export const AnalyticsProvider: FunctionComponent<PropsWithChildren> = ({
children,
}) => {
const plugin = useAnalyticsPlugin();
const [analytics, setAnalytics] = useState<AnalyticsInstance | null>(null);

useEffect(() => {
(async () => {
const Analytics = (await import("analytics")).default;
setAnalytics(
Analytics({
app: "chair-flight",
version: "1",
plugins: [plugin],
}),
);
})();
}, [plugin]);

const [analytics] = useState(async () =>
(await import("analytics")).default({
app: "chair-flight",
version: "1",
plugins: [plugin],
}),
);
return (
<analyticsContext.Provider value={analytics}>
{children}
Expand All @@ -40,14 +34,14 @@ export const useAnalytics = () => {

return {
page: () => {
analytics?.page();
analytics.then((a) => a.page());
},

track: <T extends TrackEventName>(
name: T,
payload: TrackEventPayload<T> = {},
) => {
analytics?.track(name, payload);
analytics.then((a) => a.track(name, payload));
},
};
};
Loading

0 comments on commit 315d55b

Please sign in to comment.