-
Notifications
You must be signed in to change notification settings - Fork 46
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
Mixpanel experimentation (wip) #1252
base: dev
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,20 +48,23 @@ | |
"@parcel/watcher": "~2.2.0", | ||
"@types/amqplib": "^0.10.1", | ||
"@types/busboy": "^1.5.0", | ||
"@types/mixpanel-browser": "^2.47.3", | ||
"@types/react": "^18.2.14", | ||
"@types/react-dom": "^18.2.7", | ||
"@types/styled-components": "^5.1.26", | ||
"@typescript-eslint/eslint-plugin": "^5.58.0", | ||
"@typescript-eslint/parser": "^5.61.0", | ||
"@typescript-eslint/utils": "^5.58.0", | ||
"@wagmi/cli": "^1.3.0", | ||
"crypto-browserify": "^3.12.0", | ||
"eslint": "^8.38.0", | ||
"eslint-config-prettier": "^8.8.0", | ||
"eslint-import-resolver-parcel": "^1.10.6", | ||
"eslint-plugin-react": "^7.33.0", | ||
"eslint-plugin-react-hooks": "^4.6.0", | ||
"lru-cache": "^7.18.3", | ||
"parcel": "2.8.3", | ||
"string_decoder": "^1.3.0", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider moving string_decoder to dependencies The addition of Consider applying this change: - "devDependencies": {
- ...
- "string_decoder": "^1.3.0",
- ...
- },
+ "dependencies": {
+ ...
+ "string_decoder": "^1.3.0",
+ ...
+ },
|
||
"typescript": "^4.9.5" | ||
}, | ||
"dependencies": { | ||
|
@@ -81,6 +84,7 @@ | |
"ethers": "^5.7.2", | ||
"graphql": "^16.7.1", | ||
"graphql-request": "~6.1.0", | ||
"mixpanel-browser": "^2.47.0", | ||
"moment": "^2.29.4", | ||
"overlayscrollbars": "^2.3.0", | ||
"overlayscrollbars-react": "^0.5.2", | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,8 +14,10 @@ import Cases from "./pages/Cases"; | |
import Dashboard from "./pages/Dashboard"; | ||
import Courts from "./pages/Courts"; | ||
import DisputeTemplateView from "./pages/DisputeTemplateView"; | ||
import mixpanel from "./utils/mixpanel"; | ||
|
||
const App: React.FC = () => { | ||
mixpanel.track("App"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider optimizing the Mixpanel tracking call. While adding analytics is beneficial, the current implementation may lead to excessive tracking. The "App" event will be logged on every render of the App component, which could result in redundant data and potentially impact performance. Consider the following improvements:
import { useEffect } from 'react';
const App: React.FC = () => {
useEffect(() => {
mixpanel.track("App Loaded");
}, []); // Empty dependency array ensures this runs only once on mount
// ... rest of the component
};
|
||
return ( | ||
<StyledComponentsProvider> | ||
<QueryClientProvider> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ import styled from "styled-components"; | |
import Search from "./Search"; | ||
import StatsAndFilters from "./StatsAndFilters"; | ||
import CasesGrid, { ICasesGrid } from "./CasesGrid"; | ||
import useTracking from "../../hooks/useTracking"; | ||
|
||
const StyledHR = styled.hr` | ||
margin-top: 24px; | ||
|
@@ -22,26 +23,37 @@ const CasesDisplay: React.FC<ICasesDisplay> = ({ | |
casesPerPage, | ||
title = "Cases", | ||
className, | ||
}) => ( | ||
<div {...{ className }}> | ||
<h1>{title}</h1> | ||
<Search /> | ||
<StatsAndFilters /> | ||
<StyledHR /> | ||
{disputes.length > 0 ? ( | ||
<CasesGrid | ||
{...{ | ||
disputes, | ||
currentPage, | ||
setCurrentPage, | ||
numberDisputes, | ||
casesPerPage, | ||
}} | ||
/> | ||
) : ( | ||
<h1>wow no cases</h1> | ||
)} | ||
</div> | ||
); | ||
}) => { | ||
useTracking("CasesDisplay", { | ||
disputes, | ||
currentPage, | ||
setCurrentPage, | ||
numberDisputes, | ||
casesPerPage, | ||
title, | ||
className, | ||
}); | ||
Comment on lines
+27
to
+35
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Consider refining the data passed to useTracking. While the For example, you might want to track only the following: useTracking("CasesDisplay", {
currentPage,
numberDisputes,
casesPerPage,
title,
}); This would provide meaningful analytics without including potentially sensitive or unnecessary data. |
||
return ( | ||
<div {...{ className }}> | ||
<h1>{title}</h1> | ||
<Search /> | ||
<StatsAndFilters /> | ||
<StyledHR /> | ||
{disputes.length > 0 ? ( | ||
<CasesGrid | ||
{...{ | ||
disputes, | ||
currentPage, | ||
setCurrentPage, | ||
numberDisputes, | ||
casesPerPage, | ||
}} | ||
/> | ||
) : ( | ||
<h1>wow no cases</h1> | ||
)} | ||
</div> | ||
); | ||
}; | ||
|
||
export default CasesDisplay; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// useTracking.ts | ||
import { useEffect } from "react"; | ||
import mixpanel from "../utils/mixpanel"; | ||
import crypto from "crypto"; | ||
|
||
const useTracking = (eventName: string, props?: object) => { | ||
useEffect(() => { | ||
mixpanel.track(eventName, { | ||
pathname: window.location.pathname, | ||
...(props ?? {}), | ||
}); | ||
}, [eventName, props]); | ||
}; | ||
|
||
export const useIdentify = (userId: string | undefined, props?: object) => { | ||
useEffect(() => { | ||
if (userId) { | ||
mixpanel.identify(crypto.createHash("sha256").update(userId).digest("hex")); | ||
} | ||
}, [userId, props]); | ||
}; | ||
Comment on lines
+15
to
+21
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Improve error handling, remove unused parameter, and check crypto availability The
Here's a suggested implementation addressing these points: export const useIdentify = (userId: string | undefined) => {
useEffect(() => {
if (userId && typeof crypto !== 'undefined') {
try {
const hashedUserId = crypto.createHash("sha256").update(userId).digest("hex");
mixpanel.identify(hashedUserId);
} catch (error) {
console.error("Error identifying user:", error);
}
}
}, [userId]);
}; This implementation:
Note: If you plan to use the |
||
|
||
export default useTracking; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,6 +16,7 @@ import { useCourtDetails } from "hooks/queries/useCourtDetails"; | |
import { wrapWithToast } from "utils/wrapWithToast"; | ||
import { isUndefined } from "utils/index"; | ||
import { EnsureChain } from "components/EnsureChain"; | ||
import mixpanel from "../../../../utils/mixpanel"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Consider relocating the Mixpanel utility for better organization. The current import statement uses a relative path that goes up four directory levels. This might indicate that the Mixpanel utility could be placed in a more accessible location within the project structure. Consider moving it to a common utilities folder that's easier to access from various parts of the application. |
||
|
||
export enum ActionType { | ||
allowance = "allowance", | ||
|
@@ -87,6 +88,10 @@ const StakeWithdrawButton: React.FC<IActionButton> = ({ | |
wrapWithToast(async () => await increaseAllowance().then((response) => response.hash), publicClient).finally( | ||
() => { | ||
setIsSending(false); | ||
mixpanel.track("increaseAllowance", { | ||
pathname: window.location.pathname, | ||
amount: increaseAllowanceConfig.request.args[1].toString(), | ||
}); | ||
} | ||
); | ||
} | ||
|
@@ -104,6 +109,12 @@ const StakeWithdrawButton: React.FC<IActionButton> = ({ | |
.then(() => setIsPopupOpen(true)) | ||
.finally(() => { | ||
setIsSending(false); | ||
mixpanel.track("setStake", { | ||
pathname: window.location.pathname, | ||
action: isStaking ? "stake" : "withdraw", | ||
courtId: id, | ||
stakeChange: (isStaking ? "" : "-") + parsedAmount.toString(), | ||
}); | ||
}); | ||
} | ||
}; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import mixpanel from "mixpanel-browser"; | ||
|
||
mixpanel.init(process.env.REACT_APP_MIXPANEL_TOKEN!, { | ||
debug: true, | ||
track_pageview: true, | ||
persistence: "localStorage", | ||
}); | ||
|
||
export default mixpanel; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider moving crypto-browserify to dependencies
The addition of
crypto-browserify
suggests that the project needs cryptographic functionality in a browser environment. However, it's unusual to see this as a devDependency. If this package is used at runtime (which is typically the case), it should be moved to thedependencies
section instead.Consider applying this change: