refactor: Move the tracking model into commons
This commit is contained in:
parent
2963e089d8
commit
22ded2ec38
16
common/models/tracker.ts
Normal file
16
common/models/tracker.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
export enum TrackerEvent {
|
||||||
|
LOG_IN = "LOG_IN",
|
||||||
|
LOG_OUT = "LOG_OUT",
|
||||||
|
START_LEARNING = "START_LEARNING",
|
||||||
|
CANCEL_LEARNING = "CANCEL_LEARNING",
|
||||||
|
FINISH_LEARNING = "FINISH_LEARNING",
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface ITrackerRequest {
|
||||||
|
session: string;
|
||||||
|
event: TrackerEvent;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ITrackerDBModel = ITrackerRequest & {
|
||||||
|
timestamp: number;
|
||||||
|
};
|
@ -24,8 +24,8 @@ prod: node_modules clean
|
|||||||
|
|
||||||
dev: node_modules clean
|
dev: node_modules clean
|
||||||
@echo Building with parcel
|
@echo Building with parcel
|
||||||
NODE_ENV=development ./node_modules/.bin/parcel build --out-dir dist/app --public-url /app/ src/index.hbs
|
NODE_ENV=development ./node_modules/.bin/parcel build --out-dir dist/app --public-url /app/ --no-autoinstall src/index.hbs
|
||||||
NODE_ENV=development ./node_modules/.bin/parcel build --out-dir dist src/lost.html src/error.html
|
NODE_ENV=development ./node_modules/.bin/parcel build --out-dir dist --no-autoinstall src/lost.html src/error.html
|
||||||
|
|
||||||
chmod 604 -R dist/app/*
|
chmod 604 -R dist/app/*
|
||||||
chmod 604 dist/error.html dist/lost.html
|
chmod 604 dist/error.html dist/lost.html
|
||||||
|
21
frontend/src/api/tracker.ts
Normal file
21
frontend/src/api/tracker.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { TrackerEvent } from "../models/tracker";
|
||||||
|
|
||||||
|
import { BACKEND_URL } from "../config.in";
|
||||||
|
|
||||||
|
// Sends a tracker event to the remote API
|
||||||
|
// @event: The kind of event to track
|
||||||
|
export function trackAction(event: TrackerEvent) {
|
||||||
|
// Get the tracker ID
|
||||||
|
const sid = window.sessionStorage.getItem("tracker_session");
|
||||||
|
|
||||||
|
fetch(`${BACKEND_URL}/api/tracker`, {
|
||||||
|
headers: new Headers({
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
}),
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({
|
||||||
|
session: sid,
|
||||||
|
event,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
};
|
@ -14,11 +14,13 @@ import SummaryPage from "../containers/SummaryPage";
|
|||||||
import WelcomePage from "../pages/intro";
|
import WelcomePage from "../pages/intro";
|
||||||
import RegisterPage from "../containers/Register";
|
import RegisterPage from "../containers/Register";
|
||||||
import VocabPage from "../containers/VocabPage";
|
import VocabPage from "../containers/VocabPage";
|
||||||
|
|
||||||
import Drawer from "../containers/Drawer";
|
import Drawer from "../containers/Drawer";
|
||||||
|
|
||||||
|
import { trackAction } from "../api/tracker";
|
||||||
|
|
||||||
import { BACKEND_URL } from "../config.in";
|
import { BACKEND_URL } from "../config.in";
|
||||||
|
|
||||||
|
import { TrackerEvent } from "../models/tracker";
|
||||||
import { ILevel } from "../models/level";
|
import { ILevel } from "../models/level";
|
||||||
import { TopTen } from "../models/learner";
|
import { TopTen } from "../models/learner";
|
||||||
import { IVocab } from "../models/vocab";
|
import { IVocab } from "../models/vocab";
|
||||||
@ -56,16 +58,7 @@ export default class Application extends React.Component<IProps> {
|
|||||||
|
|
||||||
checkAuthStatus = (token: string): Promise<IUser> => {
|
checkAuthStatus = (token: string): Promise<IUser> => {
|
||||||
// Track the end of a review
|
// Track the end of a review
|
||||||
fetch(`${BACKEND_URL}/api/tracker`, {
|
trackAction(TrackerEvent.LOG_IN);
|
||||||
headers: new Headers({
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
}),
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify({
|
|
||||||
session: window.sessionStorage.getItem("tracker_session"),
|
|
||||||
event: "LOG_IN",
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
return new Promise((res, rej) => {
|
return new Promise((res, rej) => {
|
||||||
fetch(`${BACKEND_URL}/api/user/me`, {
|
fetch(`${BACKEND_URL}/api/user/me`, {
|
||||||
@ -161,16 +154,7 @@ export default class Application extends React.Component<IProps> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Track the end of a review
|
// Track the end of a review
|
||||||
fetch(`${BACKEND_URL}/api/tracker`, {
|
trackAction(TrackerEvent.FINISH_LEARNING);
|
||||||
headers: new Headers({
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
}),
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify({
|
|
||||||
session: window.sessionStorage.getItem("tracker_session"),
|
|
||||||
event: "FINISH_LEARNING",
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getReviewQueue = (): Promise<IVocab[]> => {
|
getReviewQueue = (): Promise<IVocab[]> => {
|
||||||
@ -300,16 +284,7 @@ export default class Application extends React.Component<IProps> {
|
|||||||
|
|
||||||
login = (username: string, password: string): Promise<IUser | IResponse> => {
|
login = (username: string, password: string): Promise<IUser | IResponse> => {
|
||||||
// Track the login
|
// Track the login
|
||||||
fetch(`${BACKEND_URL}/api/tracker`, {
|
trackAction(TrackerEvent.LOG_IN);
|
||||||
headers: new Headers({
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
}),
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify({
|
|
||||||
session: window.sessionStorage.getItem("tracker_session"),
|
|
||||||
event: "LOG_IN",
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
return new Promise((res, rej) => {
|
return new Promise((res, rej) => {
|
||||||
fetch(`${BACKEND_URL}/api/login`, {
|
fetch(`${BACKEND_URL}/api/login`, {
|
||||||
@ -344,16 +319,7 @@ export default class Application extends React.Component<IProps> {
|
|||||||
|
|
||||||
logout = () => {
|
logout = () => {
|
||||||
// Track the logout
|
// Track the logout
|
||||||
fetch(`${BACKEND_URL}/api/tracker`, {
|
trackAction(TrackerEvent.LOG_OUT);
|
||||||
headers: new Headers({
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
}),
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify({
|
|
||||||
session: window.sessionStorage.getItem("tracker_session"),
|
|
||||||
event: "LOG_OUT",
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
// NOTE: No promise, since we don't care about the result
|
// NOTE: No promise, since we don't care about the result
|
||||||
fetch(`${BACKEND_URL}/api/user/logout`, {
|
fetch(`${BACKEND_URL}/api/user/logout`, {
|
||||||
|
1
frontend/src/models/tracker.ts
Symbolic link
1
frontend/src/models/tracker.ts
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../common/models/tracker.ts
|
@ -20,6 +20,9 @@ import { withRouter } from "react-router-dom";
|
|||||||
|
|
||||||
import VocabularyData from "../components/VocabularyData";
|
import VocabularyData from "../components/VocabularyData";
|
||||||
|
|
||||||
|
import { TrackerEvent } from "../models/tracker";
|
||||||
|
import { trackAction } from "../api/tracker";
|
||||||
|
|
||||||
import { IVocab, VocabType } from "../models/vocab";
|
import { IVocab, VocabType } from "../models/vocab";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
@ -100,6 +103,10 @@ const LevelPageWithRouter = withRouter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
cancelLevel = () => {
|
cancelLevel = () => {
|
||||||
|
// Track the cancellation of a level
|
||||||
|
trackAction(TrackerEvent.CANCEL_LEARNING);
|
||||||
|
|
||||||
|
// Close the dialog and go to the dashboard
|
||||||
this.closeLeave();
|
this.closeLeave();
|
||||||
this.props.history.push("/dashboard");
|
this.props.history.push("/dashboard");
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,9 @@ import {
|
|||||||
} from "../models/vocab";
|
} from "../models/vocab";
|
||||||
import { ReviewType, IReviewMetadata } from "../models/review";
|
import { ReviewType, IReviewMetadata } from "../models/review";
|
||||||
|
|
||||||
|
import { TrackerEvent } from "../models/tracker";
|
||||||
|
import { trackAction } from "../api/tracker";
|
||||||
|
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
import lev from "js-levenshtein";
|
import lev from "js-levenshtein";
|
||||||
import {
|
import {
|
||||||
@ -104,16 +107,7 @@ const ReviewPageWithRouter = withRouter(
|
|||||||
}[reviewType];
|
}[reviewType];
|
||||||
|
|
||||||
// Track the start of a session
|
// Track the start of a session
|
||||||
fetch(`${BACKEND_URL}/api/tracker`, {
|
trackAction(TrackerEvent.START_LEARNING);
|
||||||
headers: new Headers({
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
}),
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify({
|
|
||||||
session: window.sessionStorage.getItem("tracker_session"),
|
|
||||||
event: "START_LEARNING",
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
getVocab().then((res: IVocab[]) => {
|
getVocab().then((res: IVocab[]) => {
|
||||||
// Check if we received any vocabulary
|
// Check if we received any vocabulary
|
||||||
@ -158,16 +152,7 @@ const ReviewPageWithRouter = withRouter(
|
|||||||
this.closeDialog();
|
this.closeDialog();
|
||||||
|
|
||||||
// Track the cancellation of a learning session
|
// Track the cancellation of a learning session
|
||||||
fetch(`${BACKEND_URL}/api/tracker`, {
|
trackAction(TrackerEvent.CANCEL_LEARNING);
|
||||||
headers: new Headers({
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
}),
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify({
|
|
||||||
session: window.sessionStorage.getItem("tracker_session"),
|
|
||||||
event: "CANCEL_LEARNING",
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
// Show the drawer button again
|
// Show the drawer button again
|
||||||
this.props.drawerButtonState(true);
|
this.props.drawerButtonState(true);
|
||||||
|
Reference in New Issue
Block a user