From 23f2316e9c39b4ae893aa68398dfed84a4203b85 Mon Sep 17 00:00:00 2001 From: Nick Taylor Date: Tue, 17 Oct 2023 16:21:35 -0400 Subject: [PATCH 1/6] fix: added more info for Posthog analytics --- lib/utils/analytics.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/utils/analytics.ts b/lib/utils/analytics.ts index 6819aad649..f510302820 100644 --- a/lib/utils/analytics.ts +++ b/lib/utils/analytics.ts @@ -1,5 +1,6 @@ import posthog from "posthog-js"; import useSupabaseAuth from "lib/hooks/useSupabaseAuth"; +import { useFetchUser } from "lib/hooks/useFetchUser"; interface AnalyticEvent { title: string; @@ -21,6 +22,7 @@ function initiateAnalytics() { */ function useAnalytics() { const { user } = useSupabaseAuth(); + const userInfo = useFetchUser(user?.user_metadata.user_name || ""); return { captureAnalytics({ title, property, value }: AnalyticEvent) { @@ -30,7 +32,16 @@ function useAnalytics() { // if a user is not logged in, Posthog will generate an anonymous ID if (user) { - posthog.identify(user.user_metadata.sub); + let userProperties = {}; + + if (userInfo?.data) { + const { company, coupon_code, is_open_sauced_member, is_onboarded, role } = userInfo?.data; + + // A pro user is anyone with a role of 50 or higher + userProperties = { company, coupon_code, is_open_sauced_member, is_onboarded, is_pro_user: role >= 50 }; + } + + posthog.identify(user.user_metadata.sub, userProperties); } posthog.capture(title, analyticsObject); From 8f08b23017550aa100ff95faced2a05e1e313b9d Mon Sep 17 00:00:00 2001 From: Nick Taylor Date: Tue, 17 Oct 2023 19:09:25 -0400 Subject: [PATCH 2/6] chore: captureAnalytics no longer in a React hook --- .../molecules/FilterHeader/filter-header.tsx | 3 +- .../organisms/ToolsDisplay/tools-display.tsx | 3 +- lib/utils/analytics.ts | 57 +++++++++++-------- pages/start.tsx | 7 +-- 4 files changed, 37 insertions(+), 33 deletions(-) diff --git a/components/molecules/FilterHeader/filter-header.tsx b/components/molecules/FilterHeader/filter-header.tsx index 95b16f6829..13351080da 100644 --- a/components/molecules/FilterHeader/filter-header.tsx +++ b/components/molecules/FilterHeader/filter-header.tsx @@ -6,7 +6,7 @@ import ContextThumbnail from "components/atoms/ContextThumbnail/context-thumbnai import SuperativeSelector from "components/molecules/SuperlativeSelector/superlative-selector"; import useFilterOptions from "lib/hooks/useFilterOptions"; -import { useAnalytics } from "lib/utils/analytics"; +import { captureAnalytics } from "lib/utils/analytics"; import useFilterPrefetch from "lib/hooks/useFilterPrefetch"; import topicNameFormatting from "lib/utils/topic-name-formatting"; import FilterCardSelect from "components/molecules/FilterCardSelect/filter-card-select"; @@ -16,7 +16,6 @@ import { getInterestOptions } from "lib/utils/getInterestOptions"; const HeaderFilter = () => { const router = useRouter(); - const { captureAnalytics } = useAnalytics(); const filterOptions = useFilterOptions(); const topicOptions = getInterestOptions(); diff --git a/components/organisms/ToolsDisplay/tools-display.tsx b/components/organisms/ToolsDisplay/tools-display.tsx index b0379bf986..f6aa2f8749 100644 --- a/components/organisms/ToolsDisplay/tools-display.tsx +++ b/components/organisms/ToolsDisplay/tools-display.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { useAnalytics } from "lib/utils/analytics"; +import { captureAnalytics } from "lib/utils/analytics"; import useSession from "lib/hooks/useSession"; import Contributors from "../Contributors/contributors"; import Dashboard from "../Dashboard/dashboard"; @@ -13,7 +13,6 @@ interface ToolProps { const Tool = ({ tool, repositories }: ToolProps): JSX.Element => { const { hasReports, waitlisted } = useSession(); - const { captureAnalytics } = useAnalytics(); captureAnalytics({ title: "Tools Display", property: "tools", value: `${tool} selected` }); diff --git a/lib/utils/analytics.ts b/lib/utils/analytics.ts index f510302820..bd9789c02d 100644 --- a/lib/utils/analytics.ts +++ b/lib/utils/analytics.ts @@ -1,6 +1,5 @@ import posthog from "posthog-js"; -import useSupabaseAuth from "lib/hooks/useSupabaseAuth"; -import { useFetchUser } from "lib/hooks/useFetchUser"; +import { supabase } from "./supabase"; interface AnalyticEvent { title: string; @@ -20,33 +19,45 @@ function initiateAnalytics() { * @param {string} property - The property of the event * @param {string} value - The value of the event */ -function useAnalytics() { - const { user } = useSupabaseAuth(); - const userInfo = useFetchUser(user?.user_metadata.user_name || ""); +async function captureAnalytics({ title, property, value }: AnalyticEvent) { + const analyticsObject: Record = {}; + const { + data: { session }, + } = await supabase.auth.getSession(); + const user = session?.user; - return { - captureAnalytics({ title, property, value }: AnalyticEvent) { - const analyticsObject: Record = {}; + analyticsObject[property] = value; - analyticsObject[property] = value; + // if a user is not logged in, Posthog will generate an anonymous ID + if (user) { + const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/auth/session`, { + method: "GET", + headers: { + Accept: "application/json", + "Content-Type": "application/json", + Authorization: `Bearer ${session?.access_token}`, + }, + }); - // if a user is not logged in, Posthog will generate an anonymous ID - if (user) { - let userProperties = {}; + let data: DbUser | undefined; - if (userInfo?.data) { - const { company, coupon_code, is_open_sauced_member, is_onboarded, role } = userInfo?.data; + if (response.status === 200) { + data = await response.json(); + } - // A pro user is anyone with a role of 50 or higher - userProperties = { company, coupon_code, is_open_sauced_member, is_onboarded, is_pro_user: role >= 50 }; - } + let userProperties = {}; - posthog.identify(user.user_metadata.sub, userProperties); - } + if (data) { + const { company, coupon_code, is_open_sauced_member, is_onboarded, role } = data; - posthog.capture(title, analyticsObject); - }, - }; + // A pro user is anyone with a role of 50 or higher + userProperties = { company, coupon_code, is_open_sauced_member, is_onboarded, is_pro_user: role >= 50 }; + } + + posthog.identify(user.id, userProperties); + } + + posthog.capture(title, analyticsObject); } -export { initiateAnalytics, useAnalytics }; +export { initiateAnalytics, captureAnalytics }; diff --git a/pages/start.tsx b/pages/start.tsx index a93a512e0d..6b35de228d 100644 --- a/pages/start.tsx +++ b/pages/start.tsx @@ -25,7 +25,7 @@ import Button from "components/atoms/Button/button"; import useSupabaseAuth from "lib/hooks/useSupabaseAuth"; import { setQueryParams } from "lib/utils/query-params"; import useSession from "lib/hooks/useSession"; -import { useAnalytics } from "lib/utils/analytics"; +import { captureAnalytics } from "lib/utils/analytics"; import useStore from "lib/store"; import { getInterestOptions } from "lib/utils/getInterestOptions"; @@ -45,8 +45,6 @@ interface LoginStep1Props { } const LoginStep1: React.FC = ({ user }) => { - const { captureAnalytics } = useAnalytics(); - captureAnalytics({ title: "User Onboarding", property: "onboardingStep1", @@ -121,7 +119,6 @@ interface LoginStep2Props { } const LoginStep2: React.FC = ({ handleUpdateInterests: handleUpdateInterestsParent }) => { - const { captureAnalytics } = useAnalytics(); const [selectedInterests, setSelectedInterests] = useState([]); const interestArray = getInterestOptions(); @@ -186,8 +183,6 @@ interface LoginStep3Props { } const LoginStep3: React.FC = ({ interests, user }) => { - const { captureAnalytics } = useAnalytics(); - captureAnalytics({ title: "User Onboarding", property: "onboardingStep3", From 74ffe3cffc580977e533cb4ed35fcbc9882f397c Mon Sep 17 00:00:00 2001 From: Nick Taylor Date: Thu, 19 Oct 2023 15:17:50 -0400 Subject: [PATCH 3/6] chore: refactored --- .../molecules/FilterHeader/filter-header.tsx | 52 +++++++++---------- layouts/filter.tsx | 34 +++++++++++- lib/hooks/useFilterPrefetch.ts | 2 +- 3 files changed, 58 insertions(+), 30 deletions(-) diff --git a/components/molecules/FilterHeader/filter-header.tsx b/components/molecules/FilterHeader/filter-header.tsx index 13351080da..b2972710ea 100644 --- a/components/molecules/FilterHeader/filter-header.tsx +++ b/components/molecules/FilterHeader/filter-header.tsx @@ -1,39 +1,35 @@ -import { useRouter } from "next/router"; - import Text from "components/atoms/Typography/text"; import Title from "components/atoms/Typography/title"; import ContextThumbnail from "components/atoms/ContextThumbnail/context-thumbnail"; import SuperativeSelector from "components/molecules/SuperlativeSelector/superlative-selector"; -import useFilterOptions from "lib/hooks/useFilterOptions"; -import { captureAnalytics } from "lib/utils/analytics"; -import useFilterPrefetch from "lib/hooks/useFilterPrefetch"; import topicNameFormatting from "lib/utils/topic-name-formatting"; import FilterCardSelect from "components/molecules/FilterCardSelect/filter-card-select"; import getTopicThumbnail from "lib/utils/getTopicThumbnail"; import { interestsType } from "lib/utils/getInterestOptions"; -import { getInterestOptions } from "lib/utils/getInterestOptions"; - -const HeaderFilter = () => { - const router = useRouter(); - const filterOptions = useFilterOptions(); - const topicOptions = getInterestOptions(); - - const { filterValues } = useFilterPrefetch(); - const { filterName, toolName, selectedFilter } = router.query; - const filterBtnRouting = (filter: string) => { - captureAnalytics({ title: "Filters", property: "toolsFilter", value: `${filter} applied` }); - return router.push(`/${filterName}/${toolName}/filter/${filter.toLocaleLowerCase()}`); - }; - - const cancelFilterRouting = () => { - return router.push(`/${filterName}/${toolName}`); - }; +import { FilterValues } from "lib/hooks/useFilterPrefetch"; - const topicRouting = (topic: string) => { - router.push(`/${topic}/${toolName}${selectedFilter ? `/filter/${selectedFilter}` : ""}`); - }; +interface HeaderFilterProps { + onFilterRouting: (filter: string) => void; + onCancelFilterRouting: () => void; + onTopicRouting: (topic: string) => void; + filterName: string | string[] | undefined; + topicOptions: string[]; + selectedFilter: string | string[] | undefined; + filterOptions: string[]; + filterValues: FilterValues; +} +const HeaderFilter = ({ + onFilterRouting, + onCancelFilterRouting, + onTopicRouting, + filterName, + topicOptions, + selectedFilter, + filterOptions, + filterValues, +}: HeaderFilterProps) => { return ( <>
@@ -54,13 +50,13 @@ const HeaderFilter = () => { selected={filterName as string} options={topicOptions as unknown as []} icon="topic" - handleFilterClick={topicRouting} + handleFilterClick={onTopicRouting} />
diff --git a/layouts/filter.tsx b/layouts/filter.tsx index 7765010f97..8613d1d2f5 100644 --- a/layouts/filter.tsx +++ b/layouts/filter.tsx @@ -1,5 +1,6 @@ import React from "react"; +import { useRouter } from "next/router"; import Footer from "components/organisms/Footer/footer"; import Header from "components/organisms/Header/header"; import Nav from "components/organisms/ToolList/nav"; @@ -7,9 +8,31 @@ import TopNav from "components/organisms/TopNav/top-nav"; import FilterHeader from "components/molecules/FilterHeader/filter-header"; import useNav from "lib/hooks/useNav"; +import useFilterOptions from "lib/hooks/useFilterOptions"; +import { getInterestOptions } from "lib/utils/getInterestOptions"; +import useFilterPrefetch from "lib/hooks/useFilterPrefetch"; +import { captureAnalytics } from "lib/utils/analytics"; const FilterLayout = ({ children }: { children: React.ReactNode }) => { const { toolList, selectedTool, filterName, selectedFilter, userOrg } = useNav(); + const router = useRouter(); + const filterOptions = useFilterOptions(); + const topicOptions = getInterestOptions(); + const { filterValues } = useFilterPrefetch(); + const { toolName } = router.query; + + const filterBtnRouting = (filter: string) => { + captureAnalytics({ title: "Filters", property: "toolsFilter", value: `${filter} applied` }); + return router.push(`/${filterName}/${toolName}/filter/${filter.toLocaleLowerCase()}`); + }; + + const cancelFilterRouting = () => { + return router.push(`/${filterName}/${toolName}`); + }; + + const topicRouting = (topic: string) => { + router.push(`/${topic}/${toolName}${selectedFilter ? `/filter/${selectedFilter}` : ""}`); + }; return (
@@ -17,7 +40,16 @@ const FilterLayout = ({ children }: { children: React.ReactNode }) => {
- +