Skip to content

Commit

Permalink
feat: add react-ga events
Browse files Browse the repository at this point in the history
  • Loading branch information
AykutSarac committed Jul 20, 2023
1 parent 5bcc9b0 commit d2b7d94
Show file tree
Hide file tree
Showing 12 changed files with 74 additions and 6 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"react": "^18.2.0",
"react-color": "^2.19.3",
"react-dom": "^18.2.0",
"react-ga": "^3.3.1",
"react-hot-toast": "^2.4.1",
"react-icons": "^4.10.1",
"react-linkify-it": "^1.0.7",
Expand Down
3 changes: 3 additions & 0 deletions src/components/GoogleAnalytics/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import React from "react";
import Script from "next/script";
import ReactGA from "react-ga";

const isDevelopment = process.env.NODE_ENV === "development";
const GA_TRACKING_ID = process.env.NEXT_PUBLIC_GA_ID;

ReactGA.initialize(GA_TRACKING_ID, { testMode: isDevelopment });

const GoogleAnalytics: React.FC = () => {
if (isDevelopment) return null;

Expand Down
8 changes: 7 additions & 1 deletion src/components/Graph/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,13 @@ export const Graph = ({ isWidget = false }: GraphProps) => {
return (
<>
<Loading message="Painting graph..." loading={loading} />
<StyledEditorWrapper onContextMenu={e => e.preventDefault()} widget={isWidget}>
<StyledEditorWrapper
onClick={() => {
if ("activeElement" in document) (document.activeElement as HTMLElement)?.blur();
}}
onContextMenu={e => e.preventDefault()}
widget={isWidget}
>
<TransformWrapper
maxScale={2}
minScale={0.05}
Expand Down
2 changes: 2 additions & 0 deletions src/components/SearchInput/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from "react";
import { Flex, Input, Text } from "@mantine/core";
import { getHotkeyHandler } from "@mantine/hooks";
import { event } from "react-ga";
import { AiOutlineSearch } from "react-icons/ai";
import { useFocusNode } from "src/hooks/useFocusNode";

Expand All @@ -14,6 +15,7 @@ export const SearchInput: React.FC = () => {
id="search-node"
value={searchValue}
onChange={e => setValue(e.currentTarget.value)}
onFocus={() => event({ action: "focus_node_search", category: "User" })}
placeholder="Search Node"
onKeyDown={getHotkeyHandler([["Enter", skip]])}
icon={<AiOutlineSearch />}
Expand Down
21 changes: 17 additions & 4 deletions src/containers/Editor/LiveEditor/Tools.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from "react";
import styled from "styled-components";
import { Flex, Group, MediaQuery, Menu, Select, Text } from "@mantine/core";
import { useHotkeys } from "@mantine/hooks";
import { event } from "react-ga";
import toast from "react-hot-toast";
import { AiOutlineFullscreen, AiOutlineMinus, AiOutlinePlus } from "react-icons/ai";
import { CgArrowsMergeAltH, CgArrowsShrinkH, CgChevronDown } from "react-icons/cg";
Expand Down Expand Up @@ -207,7 +208,10 @@ export const Tools: React.FC<{ isWidget?: boolean }> = ({ isWidget = false }) =>
<Menu.Dropdown>
<Menu.Item
fz={12}
onClick={toggleEditor}
onClick={() => {
toggleEditor();
event({ action: "toggle_hide_editor", category: "User", label: "Tools" });
}}
icon={fullscreen ? <VscLayoutSidebarLeft /> : <VscLayoutSidebarLeftOff />}
rightSection={
<Text ml="md" fz={10} color="dimmed">
Expand All @@ -219,7 +223,10 @@ export const Tools: React.FC<{ isWidget?: boolean }> = ({ isWidget = false }) =>
</Menu.Item>
<Menu.Item
fz={12}
onClick={toggleDirection}
onClick={() => {
toggleDirection();
event({ action: "toggle_layout_direction", category: "User", label: "Tools" });
}}
icon={<StyledFlowIcon rotate={rotateLayout(direction)} />}
rightSection={
<Text ml="md" fz={10} color="dimmed">
Expand All @@ -231,7 +238,10 @@ export const Tools: React.FC<{ isWidget?: boolean }> = ({ isWidget = false }) =>
</Menu.Item>
<Menu.Item
fz={12}
onClick={toggleFoldNodes}
onClick={() => {
toggleFoldNodes();
event({ action: "toggle_fold_nodes", category: "User", label: "Tools" });
}}
icon={foldNodes ? <CgArrowsShrinkH /> : <CgArrowsMergeAltH />}
rightSection={
<Text ml="md" fz={10} color="dimmed">
Expand All @@ -243,7 +253,10 @@ export const Tools: React.FC<{ isWidget?: boolean }> = ({ isWidget = false }) =>
</Menu.Item>
<Menu.Item
fz={12}
onClick={toggleExpandCollapseGraph}
onClick={() => {
toggleExpandCollapseGraph();
event({ action: "toggle_collapse_nodes", category: "User", label: "Tools" });
}}
icon={graphCollapsed ? <VscExpandAll /> : <VscCollapseAll />}
rightSection={
<Text ml="md" fz={10} color="dimmed">
Expand Down
3 changes: 3 additions & 0 deletions src/containers/Modals/DownloadModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
Stack,
} from "@mantine/core";
import { toBlob, toPng, toSvg } from "html-to-image";
import { event } from "react-ga";
import toast from "react-hot-toast";
import { FiCopy, FiDownload } from "react-icons/fi";

Expand Down Expand Up @@ -83,6 +84,7 @@ export const DownloadModal: React.FC<ModalProps> = ({ opened, onClose }) => {
toast.error("Failed to copy to clipboard");
} finally {
toast.dismiss("toastClipboard");
event({ action: "click_clipboard_image", category: "User" });
onClose();
}
};
Expand All @@ -105,6 +107,7 @@ export const DownloadModal: React.FC<ModalProps> = ({ opened, onClose }) => {
toast.error("Failed to download image!");
} finally {
toast.dismiss("toastDownload");
event({ action: "click_download_image", category: "User" });
onClose();
}
};
Expand Down
16 changes: 16 additions & 0 deletions src/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import React from "react";
import type { AppProps } from "next/app";
import dynamic from "next/dynamic";
import { useRouter } from "next/router";
import { ThemeProvider } from "styled-components";
import { MantineProvider, MantineThemeOverride } from "@mantine/core";
import { pageview } from "react-ga";
import { monaSans } from "src/constants/customFonts";
import GlobalStyle from "src/constants/globalStyle";
import { lightTheme } from "src/constants/theme";
Expand All @@ -20,6 +22,20 @@ const mantineTheme: MantineThemeOverride = {
};

function JsonCrack({ Component, pageProps }: AppProps) {
const router = useRouter();

React.useEffect(() => {
const handleRouteChange = (url: string) => {
pageview(url);
};

router.events.on("routeChangeComplete", handleRouteChange);

return () => {
router.events.off("routeChangeComplete", handleRouteChange);
};
}, [router.events]);

return (
<>
<GoogleAnalytics />
Expand Down
2 changes: 2 additions & 0 deletions src/store/useFile.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import debounce from "lodash.debounce";
import _get from "lodash.get";
import _set from "lodash.set";
import { event } from "react-ga";
import { toast } from "react-hot-toast";
import { create } from "zustand";
import { defaultJson } from "src/constants/data";
Expand Down Expand Up @@ -105,6 +106,7 @@ const useFile = create<FileStates & JsonActions>()((set, get) => ({
const jsonContent = await jsonToContent(JSON.stringify(contentJson, null, 2), format);

get().setContents({ contents: jsonContent, hasChanges: false });
event({ action: "change_data_format", category: "User" });
} catch (error) {
get().clear();
console.info("The content was unable to be converted, so it was cleared instead.");
Expand Down
2 changes: 2 additions & 0 deletions src/store/useModal.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { modalview } from "react-ga";
import { create } from "zustand";
import { Modal } from "src/containers/Modals";
import useUser from "./useUser";
Expand Down Expand Up @@ -40,6 +41,7 @@ const useModal = create<ModalState & ModalActions>()(set => ({
return set({ premium: true });
}

if (visible) modalview(modal);
set({ [modal]: visible });
},
}));
Expand Down
8 changes: 7 additions & 1 deletion src/store/useUser.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { setUser } from "@sentry/nextjs";
import { set as gaSet } from "react-ga";
import toast from "react-hot-toast";
import { create } from "zustand";
import { altogic } from "src/lib/api/altogic";
Expand Down Expand Up @@ -57,7 +58,10 @@ const useUser = create<UserStates & UserActions>()(set => ({
toast.success("Logged out.");
useModal.setState({ account: false });
},
login: user => set({ user: user as unknown as User, isAuthenticated: true }),
login: user => {
set({ user: user as unknown as User, isAuthenticated: true });
gaSet({ userId: (user as User)._id });
},
checkSession: async () => {
if (isDevelopment) {
return set({ user: devUser as User, isAuthenticated: true, premium: true });
Expand All @@ -84,6 +88,7 @@ const useUser = create<UserStates & UserActions>()(set => ({
premium: premiumData.premium,
premiumCancelled: premiumData?.status === "cancelled" || false,
});
gaSet({ userId: user._id });
} else if (new URLSearchParams(window.location.search).get("access_token")) {
const { errors, user } = await altogic.auth.getAuthGrant();

Expand All @@ -97,6 +102,7 @@ const useUser = create<UserStates & UserActions>()(set => ({

setUser({ id: user._id, email: user.email, username: user.name });
set({ user: user as User, isAuthenticated: true, premium: premiumData.premium });
gaSet({ userId: user._id });
}
}
},
Expand Down
9 changes: 9 additions & 0 deletions src/types/env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace NodeJS {
interface ProcessEnv {
NEXT_PUBLIC_BASE_URL: string;
NEXT_PUBLIC_ALTOGIC_ENV_URL: string;
NEXT_PUBLIC_ALTOGIC_CLIENT_KEY: string;
NEXT_PUBLIC_PAYMENT_URL: string;
NEXT_PUBLIC_GA_ID: string;
}
}
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3719,6 +3719,11 @@ react-fast-compare@^3.2.0:
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49"
integrity sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==

react-ga@^3.3.1:
version "3.3.1"
resolved "https://registry.yarnpkg.com/react-ga/-/react-ga-3.3.1.tgz#d8e1f4e05ec55ed6ff944dcb14b99011dfaf9504"
integrity sha512-4Vc0W5EvXAXUN/wWyxvsAKDLLgtJ3oLmhYYssx+YzphJpejtOst6cbIHCIyF50Fdxuf5DDKqRYny24yJ2y7GFQ==

react-hot-toast@^2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/react-hot-toast/-/react-hot-toast-2.4.1.tgz#df04295eda8a7b12c4f968e54a61c8d36f4c0994"
Expand Down

0 comments on commit d2b7d94

Please sign in to comment.