Skip to content

Commit bc84a27

Browse files
committed
feat(click logging): Create HOC
- Add HOC for logging UI events (tested for onClick)
1 parent 7e2ae75 commit bc84a27

File tree

4 files changed

+88
-14
lines changed

4 files changed

+88
-14
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
export interface Tracker {
2+
context: string;
3+
type: keyof React.DOMAttributes<string>;
4+
data: Object<any>;
5+
callback: (e: any, data: Object<any>) => void;
6+
}
7+
8+
type Object<T> = {
9+
[P in keyof T]: T[P]
10+
};
11+
12+
type TrackerProps = {
13+
trackers: Tracker[]
14+
} & Object<any>;
15+
16+
export function withTracking (
17+
Component: React.ComponentType<any>
18+
) {
19+
return function fn(props: TrackerProps) {
20+
let eventObject: Object<any> = {};
21+
const { trackers, ...rest } = props;
22+
23+
trackers.forEach(tracker => {
24+
eventObject[tracker.type] = (tracker.type in rest) ? function(e: any) {
25+
rest[tracker.type](e);
26+
tracker.callback(e, {
27+
context: tracker.context,
28+
type: tracker.type,
29+
data: tracker.data
30+
});
31+
} : function (e: any) {
32+
tracker.callback(e, {
33+
context: tracker.context,
34+
type: tracker.type,
35+
data: tracker.data
36+
});
37+
}
38+
})
39+
40+
return (
41+
<Component
42+
{ ...props }
43+
{ ...eventObject }
44+
/>
45+
);
46+
};
47+
};

src/components/elements/Button/index.tsx

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,13 @@ import {
66

77
import 'antd/lib/button/style/css';
88

9-
import { withDataContext } from '../../contexts/withDataContext';
9+
import {
10+
withDataContext,
11+
} from '../../contexts/withDataContext';
12+
13+
import {
14+
withTracking,
15+
} from '../../contexts/withTracking';
1016

1117
interface ButtonStateProps extends AntButtonProps {
1218
label: string;
@@ -22,14 +28,14 @@ export type ButtonProps = ButtonStateProps & ButtonActionProps
2228
function Button(props: ButtonProps) {
2329
const { label, context, onClick, customCallback, ...rest } = props;
2430

25-
function handleClick(e: React.MouseEvent) {
26-
customCallback && customCallback(context);
27-
}
31+
// function handleClick(e: React.MouseEvent) {
32+
// customCallback && customCallback(context);
33+
// }
2834

2935
return (
3036
<AntButton
3137
{...rest}
32-
onClick={handleClick}
38+
onClick={onClick}
3339
>
3440
{props.label}
3541
</AntButton>
@@ -38,4 +44,5 @@ function Button(props: ButtonProps) {
3844

3945
export default Button;
4046

41-
export const ButtonWithContext = withDataContext(Button)
47+
export const ButtonWithContext = withDataContext(Button)
48+
export const ButtonWithTracking = withTracking(Button)

src/components/elements/Input/index.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,12 @@ import { Input as AntInput, InputProps as AntInputProps } from 'antd';
33

44
import 'antd/lib/input/style/css';
55

6-
export interface InputProps extends AntInputProps {
6+
import {
7+
withTracking,
8+
} from '../../contexts/withTracking';
79

10+
export interface InputProps extends AntInputProps {
11+
812
}
913

1014
function Input(props: InputProps) {
@@ -16,4 +20,6 @@ function Input(props: InputProps) {
1620
);
1721
}
1822

19-
export default Input;
23+
export default Input;
24+
25+
export const InputWithTracking = withTracking(Input)

src/components/templates/LoginForm/index.tsx

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import { useState, useEffect, createContext } from 'react';
21
import { DataContext } from '../../contexts/withDataContext';
3-
import Button, {ButtonWithContext} from '../../elements/Button';
2+
import Button, { ButtonWithContext, ButtonWithTracking } from '../../elements/Button';
43

54
import Input from '../../elements/Input';
65

@@ -16,23 +15,38 @@ const data = {
1615
}
1716

1817
function LoginForm(props: LoginFormProps) {
19-
function getContext (data: any) {
20-
// console.log(data);
18+
19+
function verifyUsernameAndPassword (e: React.MouseEvent<HTMLElement, MouseEvent>) {
20+
// app logic goes here
21+
}
22+
23+
function logMouseEvent (event: React.MouseEvent<HTMLElement, MouseEvent>, data: any) {
24+
// tracking logic goes here
2125
}
2226

2327
return (
2428
<DataContext.Provider value={data}>
2529
<Card
2630
title="Login"
2731
actions={[
28-
<ButtonWithContext
32+
<ButtonWithTracking
2933
type="primary"
3034
label="Login"
31-
customCallback={getContext}
35+
onClick={(e: any) => verifyUsernameAndPassword(e.value)}
36+
trackers={[{
37+
context: "Login and Signup",
38+
type: "onClick",
39+
callback: logMouseEvent,
40+
data: {
41+
element: "Login button",
42+
...data,
43+
}
44+
}]}
3245
/>,
3346
<Button
3447
type="ghost"
3548
label="Sign Up"
49+
onClick={verifyUsernameAndPassword}
3650
/>
3751
]}>
3852
<Input

0 commit comments

Comments
 (0)