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 amplitude #215

Merged
merged 2 commits into from
Apr 28, 2023
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
3 changes: 2 additions & 1 deletion apps/widget/.example.env
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
REACT_APP_ENVIRONMENT=dev
REACT_APP_API_URL=http://localhost:3000
REACT_APP_SENTRY_DSN=
REACT_APP_SENTRY_DSN=
REACT_APP_AMPLITUDE_ID=
1 change: 1 addition & 0 deletions apps/widget/craco.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module.exports = {
'@icons': path.resolve(__dirname, './src/icons/index.ts'),
'@util': path.resolve(__dirname, './src/util/index.ts'),
'@hooks': path.resolve(__dirname, './src/hooks'),
'@amplitude': path.resolve(__dirname, './src/util/amplitude/index.ts'),
},
},
};
3 changes: 3 additions & 0 deletions apps/widget/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script>
!function () { "use strict"; !function (e, t) { var r = e.amplitude || { _q: [], _iq: {} }; if (r.invoked) e.console && console.error && console.error("Amplitude snippet has been loaded."); else { var n = function (e, t) { e.prototype[t] = function () { return this._q.push({ name: t, args: Array.prototype.slice.call(arguments, 0) }), this } }, s = function (e, t, r) { return function (n) { e._q.push({ name: t, args: Array.prototype.slice.call(r, 0), resolve: n }) } }, o = function (e, t, r) { e[t] = function () { if (r) return { promise: new Promise(s(e, t, Array.prototype.slice.call(arguments))) } } }, i = function (e) { for (var t = 0; t < g.length; t++)o(e, g[t], !1); for (var r = 0; r < m.length; r++)o(e, m[r], !0) }; r.invoked = !0; var a = t.createElement("script"); a.type = "text/javascript", a.integrity = "sha384-K9gmPAHHNQILXzzesVo3pGFcA3173YpsgdGS9pwEtScsShX30Eqj5WETWjaZb+wg", a.crossOrigin = "anonymous", a.async = !0, a.src = "https://cdn.amplitude.com/libs/analytics-browser-1.9.4-min.js.gz", a.onload = function () { e.amplitude.runQueuedFunctions || console.log("[Amplitude] Error: could not load SDK") }; var c = t.getElementsByTagName("script")[0]; c.parentNode.insertBefore(a, c); for (var u = function () { return this._q = [], this }, p = ["add", "append", "clearAll", "prepend", "set", "setOnce", "unset", "preInsert", "postInsert", "remove", "getUserProperties"], l = 0; l < p.length; l++)n(u, p[l]); r.Identify = u; for (var d = function () { return this._q = [], this }, f = ["getEventProperties", "setProductId", "setQuantity", "setPrice", "setRevenue", "setRevenueType", "setEventProperties"], v = 0; v < f.length; v++)n(d, f[v]); r.Revenue = d; var g = ["getDeviceId", "setDeviceId", "getSessionId", "setSessionId", "getUserId", "setUserId", "setOptOut", "setTransport", "reset"], m = ["init", "add", "remove", "track", "logEvent", "identify", "groupIdentify", "setGroup", "revenue", "flush"]; i(r), r.createInstance = function (e) { return r._iq[e] = { _q: [] }, i(r._iq[e]), r._iq[e] }, e.amplitude = r } }(window, document) }();
</script>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
Expand Down
14 changes: 10 additions & 4 deletions apps/widget/src/components/App.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import * as Sentry from '@sentry/react';
import { Integrations } from '@sentry/tracing';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { CONTEXT_PATH, variables, SENTRY_DSN, ENV } from '@config';
import { WidgetShell } from './ApplicationShell';
import { Container } from './Common/Container';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';

import { Widget } from './widget';
import { initAmplitude } from '@amplitude';
import { AppShell } from './Common/AppShell';
import { Container } from './Common/Container';
import { WidgetShell } from './ApplicationShell';
import { CONTEXT_PATH, variables, SENTRY_DSN, ENV, AMPLITUDE_ID } from '@config';

if (SENTRY_DSN) {
Sentry.init({
Expand All @@ -22,6 +24,10 @@ if (SENTRY_DSN) {
});
}

if (AMPLITUDE_ID) {
initAmplitude(AMPLITUDE_ID);
}

export function App() {
const queryClient = new QueryClient({
defaultOptions: {
Expand Down
13 changes: 8 additions & 5 deletions apps/widget/src/components/Common/Container/Container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@ import { useEffect, useState, PropsWithChildren } from 'react';
import * as WebFont from 'webfontloader';
import { useParams } from 'react-router-dom';
import { Global } from '@emotion/react';
import { API_URL, colors, mantineConfig, variables } from '@config';
import { NotificationsProvider } from '@mantine/notifications';
import { MantineProvider } from '@mantine/core';
import { logAmplitudeEvent } from '@amplitude';

import { Provider } from '../Provider';
import { generateShades, ParentWindow } from '@util';
import { useAuthentication } from '@hooks/useAuthentication';
import { ApiService } from '@impler/client';
import { MessageHandlerDataType } from '@types';
import { generateShades, ParentWindow } from '@util';
import { useAuthentication } from '@hooks/useAuthentication';
import { IInitPayload, IShowPayload, EventTypesEnum } from '@impler/shared';
import { NotificationsProvider } from '@mantine/notifications';
import { MantineProvider } from '@mantine/core';
import { API_URL, colors, mantineConfig, variables } from '@config';

let api: ApiService;

Expand Down Expand Up @@ -52,6 +54,7 @@ export function Container({ children }: PropsWithChildren<{}>) {
refetch();
}
if (data && data.type === EventTypesEnum.SHOW_WIDGET) {
logAmplitudeEvent('OPEN', { hasExtra: data.value.extra !== undefined });
setShowWidget(true);
setSecondaryPayload({ ...data.value, primaryColor: data.value.primaryColor || colors.primary });
}
Expand Down
3 changes: 3 additions & 0 deletions apps/widget/src/components/widget/Phases/Phase3/Phase3.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { Footer } from 'components/Common/Footer';
import { useRef, useState, useEffect } from 'react';
import { ConfirmModal } from '../ConfirmModal';
import useStyles from './Styles';
import { logAmplitudeEvent, resetAmplitude } from '@amplitude';

interface IPhase3Props {
onNextClick: (uploadData: IUpload) => void;
Expand Down Expand Up @@ -53,6 +54,8 @@ export function Phase3(props: IPhase3Props) {
};

const onReviewConfirmed = (exempt: boolean) => {
logAmplitudeEvent('CONFIRM', { exempt });
resetAmplitude();
setShowConfirmModal(false);
onConfirmReview(exempt);
};
Expand Down
3 changes: 3 additions & 0 deletions apps/widget/src/components/widget/Widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { Phase4 } from './Phases/Phase4';
import { PromptModal } from './Phases/PromptModal';
import { Layout } from 'components/Common/Layout';
import { IUpload } from '@impler/shared';
import { logAmplitudeEvent, resetAmplitude } from '@amplitude';

export function Widget() {
const defaultDataCount = 0;
Expand All @@ -21,6 +22,7 @@ export function Widget() {
const [promptContinueAction, setPromptContinueAction] = useState<PromptModalTypesEnum>();

const onUploadResetClick = () => {
logAmplitudeEvent('RESET');
setPromptContinueAction(PromptModalTypesEnum.UPLOAD_AGAIN);
};
const onPromptConfirm = () => {
Expand All @@ -37,6 +39,7 @@ export function Widget() {
else setPromptContinueAction(PromptModalTypesEnum.CLOSE);
};
const closeWidget = () => {
resetAmplitude();
ParentWindow.Close();
resetProgress();
};
Expand Down
2 changes: 2 additions & 0 deletions apps/widget/src/config/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export const API_URL =

export const SENTRY_DSN = window._env_?.REACT_APP_SENTRY_DSN || process.env.REACT_APP_SENTRY_DSN || undefined;

export const AMPLITUDE_ID = window._env_?.REACT_APP_AMPLITUDE_ID || process.env.REACT_APP_AMPLITUDE_ID || undefined;

export const ENV: ENVTypesEnum = window._env_?.REACT_APP_ENVIRONMENT || process.env.REACT_APP_ENVIRONMENT || 'local';

export const CONTEXT_PATH = getContextPath(ImplerComponentEnum.WIDGET);
11 changes: 11 additions & 0 deletions apps/widget/src/config/variable.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,14 @@ export const variables = {
maxColorNumber: 255,
implerWebsite: 'https://impler.io?utm_source=widget',
};

export const AMPLITUDE = {
OPEN: 'open',
UPLOAD: 'upload',
MAPPING: 'mapping',
VALIDATE: 'validate',
DOWNLOAD_INVALID_DATA: 'download invalid data',
CONFIRM: 'confirm',
UPLOAD_AGAIN: 'upload again',
RESET: 'reset',
};
1 change: 1 addition & 0 deletions apps/widget/src/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ declare interface Window {
sendMessage: (payload: IMessagePayload) => void;
};
_env_: any;
amplitude?: any;
}
2 changes: 2 additions & 0 deletions apps/widget/src/hooks/Phase1/usePhase1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useAppState } from '@store/app.context';
import { downloadFileFromURL, getFileNameFromUrl, notifier, ParentWindow } from '@util';
import { IFormvalues, IUploadValues } from '@types';
import { variables } from '@config';
import { logAmplitudeEvent } from '@amplitude';

interface IUsePhase1Props {
goNext: () => void;
Expand Down Expand Up @@ -105,6 +106,7 @@ export function usePhase1({ goNext }: IUsePhase1Props) {
);
if (foundTemplate) {
submitData.template = foundTemplate._id;
logAmplitudeEvent('UPLOAD', { fileSize: submitData.file.size, fileType: submitData.file.type });
submitUpload({
...submitData,
authHeaderValue,
Expand Down
6 changes: 6 additions & 0 deletions apps/widget/src/hooks/Phase2/usePhase2.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { logAmplitudeEvent } from '@amplitude';
import { IMapping, IErrorObject, IMappingFinalize, IUpload } from '@impler/shared';
import { useAPIState } from '@store/api.context';
import { useAppState } from '@store/app.context';
Expand All @@ -22,6 +23,11 @@ export function usePhase2({ goNext }: IUsePhase2Props) {
() => api.getMappings(uploadInfo._id),
{
onSuccess(mappingsResponse) {
logAmplitudeEvent('MAPPING', {
totalKeys: mappingsResponse.length,
totalRecords: uploadInfo.totalRecords,
mappedKeys: mappingsResponse.filter((mapping) => mapping.columnHeading).length, // count how many keys are mapped
});
reset({
mappings: mappingsResponse.map((mapping) => ({
_columnId: mapping.column._columnId,
Expand Down
5 changes: 5 additions & 0 deletions apps/widget/src/hooks/Phase3/usePhase3.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { logAmplitudeEvent } from '@amplitude';
import { variables } from '@config';
import { IErrorObject, IReviewData, IUpload } from '@impler/shared';
import { useAPIState } from '@store/api.context';
Expand Down Expand Up @@ -26,6 +27,9 @@ export function usePhase3({ onNext }: IUsePhase3Props) {
() => api.getReviewData(uploadInfo._id, page),
{
onSuccess(data) {
logAmplitudeEvent('VALIDATE', {
invalidRecords: data.totalRecords,
});
if (!data.totalRecords) {
// Confirm review if spreadsheet do not have invalid records
confirmReview(false);
Expand All @@ -44,6 +48,7 @@ export function usePhase3({ onNext }: IUsePhase3Props) {
([fileUrl]) => api.getSignedUrl(getFileNameFromUrl(fileUrl)),
{
onSuccess(signedUrl, queryVariables) {
logAmplitudeEvent('DOWNLOAD_INVALID_DATA');
downloadFileFromURL(signedUrl, queryVariables[variables.firstIndex]);
},
onError(error: IErrorObject) {
Expand Down
20 changes: 20 additions & 0 deletions apps/widget/src/util/amplitude/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { AMPLITUDE } from '@config';

export const initAmplitude = (id: string) => {
window.amplitude?.init(id, undefined, {
defaultTracking: { sessions: true, formInteractions: true },
});
// const sessionId = window.amplitude.getInstance().getSessionId();
};

export const logAmplitudeEvent = (eventName: keyof typeof AMPLITUDE, eventProperties?: any) => {
window.amplitude?.logEvent(eventName, eventProperties);
};

export const setAmplitudeUserId = (userId: string) => {
window.amplitude?.setUserId(userId);
};

export const resetAmplitude = () => {
window.amplitude?.reset();
};
3 changes: 2 additions & 1 deletion apps/widget/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
"@types": ["types/index.ts"],
"@icons": ["icons/index.ts"],
"@util": ["util/index.ts"],
"@hooks/*": ["hooks/*"]
"@hooks/*": ["hooks/*"],
"@amplitude": ["util/amplitude/index.ts"],
}
},
"include": [
Expand Down
Loading