Skip to content

Commit

Permalink
Added some utility classes for triggering analytics related events (o…
Browse files Browse the repository at this point in the history
…nly for Booking at the moment). Also updated some config files.
  • Loading branch information
JBergVincit committed Jul 15, 2024
1 parent c8adaf1 commit ac02431
Show file tree
Hide file tree
Showing 10 changed files with 135 additions and 41 deletions.
3 changes: 2 additions & 1 deletion frontend/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
# Set the same value as <VAPID_PUBLIC_KEY> in backend .env file
VITE_REACT_APP_SERVER_KEY=''

CLARITY_ID=''
VITE_CLARITY_ID=''
VITE_GOOGLE_ANALYTICS_ID=''
16 changes: 16 additions & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
"eslint-config-prettier": "^9.1.0",
"happy-dom": "^14.12.3",
"vite": "^5.3.1",
"vite-plugin-radar": "^0.9.6",
"vite-plugin-svgr": "^4.2.0",
"vite-tsconfig-paths": "^4.3.2",
"vitest": "^1.6.0",
Expand Down
9 changes: 9 additions & 0 deletions frontend/src/analytics/AnalyticsEvent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export enum AnalyticsEventEnum {
BOOKING,
CANCEL_BOOKING
}

export const analyticsEventMap: { [key in AnalyticsEventEnum]: string } = {
[AnalyticsEventEnum.BOOKING]: 'booking',
[AnalyticsEventEnum.CANCEL_BOOKING]: 'cancelBooking'
};
17 changes: 17 additions & 0 deletions frontend/src/analytics/clarityService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { AnalyticsEventEnum, analyticsEventMap } from './AnalyticsEvent';

function isClarityEnabled(): boolean {
// @ts-ignore
if (!window.clarity) {
console.log('Clarity is not enabled!');
return false;
}
return true;
}

export function triggerClarityEvent(event: AnalyticsEventEnum) {
if (isClarityEnabled()) {
// @ts-ignore
window.clarity('event', analyticsEventMap[event]);
}
}
28 changes: 28 additions & 0 deletions frontend/src/analytics/googleAnalyticsService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { AnalyticsEventEnum, analyticsEventMap } from './AnalyticsEvent';

export const analyticsGAEventMap: { [key in AnalyticsEventEnum]: object } = {
[AnalyticsEventEnum.BOOKING]: { booking: 'Booked a Room' },
[AnalyticsEventEnum.CANCEL_BOOKING]: {
cancelBooking: 'Cancelled a booked room'
}
};

function isGAEnabled(): boolean {
// @ts-ignore
if (!window.gtag) {
console.log('Google Analytics is not enabled!');
return false;
}
return true;
}

export function triggerGoogleAnalyticsEvent(event: AnalyticsEventEnum) {
if (isGAEnabled()) {
// @ts-ignore
window.gtag(
'event',
analyticsEventMap[event],
analyticsGAEventMap[event]
);
}
}
2 changes: 0 additions & 2 deletions frontend/src/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,13 @@ import { theme_2024 } from '../theme_2024';
import { UserSettingsProvider } from '../contexts/UserSettingsContext';
import { clarity } from 'react-microsoft-clarity';
import GETAROOM_ENV from '../util/getARoomEnv';
import { checkEnvVariables } from '../util/checkEnvVariables';

export const GarApp = styled(Divider)(() => ({}));

const App = () => {
if (GETAROOM_ENV().VITE_CLARITY_ID != null) {
// Start seeing data on the Clarity dashboard with your id
clarity.init(GETAROOM_ENV().VITE_CLARITY_ID as string);

// Check if Clarity has been initialized before calling its methods
if (clarity.hasStarted()) {
clarity.identify('USER_ID', { userProperty: 'value' });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import { LocalizationProvider } from '@mui/x-date-pickers';
import dayjs from 'dayjs';
import { sortByFavoritedAndName } from '../../util/arrayUtils';
import { triggerClarityEvent } from '../../analytics/clarityService';
import { AnalyticsEventEnum } from '../../analytics/AnalyticsEvent';
import { triggerGoogleAnalyticsEvent } from '../../analytics/googleAnalyticsService';

const SKIP_CONFIRMATION = true;

Expand Down Expand Up @@ -288,6 +291,8 @@ const AvailableRoomList = (props: BookingListProps) => {
createSuccessNotification('Booking was successful');
setBookingLoading('false');
document.getElementById('main-view-content')?.scrollTo(0, 0);
triggerGoogleAnalyticsEvent(AnalyticsEventEnum.BOOKING);
triggerClarityEvent(AnalyticsEventEnum.BOOKING);
})
.catch(() => {
createErrorNotification('Could not create booking');
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/util/checkEnvVariables.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import GETAROOM_ENV from './getARoomEnv';

export const checkEnvVariables = () => {
const { VITE_REACT_APP_SERVER_KEY, VITE_CLARITY_ID } = GETAROOM_ENV();
const {
VITE_REACT_APP_SERVER_KEY,
VITE_CLARITY_ID,
VITE_GOOGLE_ANALYTICS_ID
} = GETAROOM_ENV();

if (!VITE_REACT_APP_SERVER_KEY) {
throw new Error('Application server key not set');
Expand Down
89 changes: 52 additions & 37 deletions frontend/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,45 +1,60 @@
import { defineConfig } from 'vite';
import { defineConfig, loadEnv } from 'vite';
import react from '@vitejs/plugin-react';
import viteTsconfigPaths from 'vite-tsconfig-paths';
import svgr from 'vite-plugin-svgr';
import { VitePluginRadar } from 'vite-plugin-radar';

export default defineConfig({
// depending on your application, base can also be "/"
base: './',
plugins: [
// here is the main update
react({
jsxImportSource: '@emotion/react',
include: /\.(jsx|tsx)$/,
babel: {
plugins: ['@emotion/babel-plugin']
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd(), '');

return {
// depending on your application, base can also be "/"
base: './',
plugins: [
// here is the main update
react({
jsxImportSource: '@emotion/react',
include: /\.(jsx|tsx)$/,
babel: {
plugins: ['@emotion/babel-plugin']
}
}),
viteTsconfigPaths(),
svgr({
svgrOptions: { exportType: 'named' },
include: '/**/*.svg'
}),
VitePluginRadar({
enableDev: true,
// Google Analytics tag injection
analytics: {
id: env.VITE_GOOGLE_ANALYTICS_ID as string
}
})
],
optimizeDeps: {
include: ['@emotion/styled', '@mui/styled-engine']
},
server: {
// this ensures that the browser opens upon server start
open: true,
// this sets a default port to 3000
port: 3000,
proxy: {
// with options: http://localhost:5173/api/bar-> http://jsonplaceholder.typicode.com/bar
'/api': {
target: 'http://localhost:8080',
changeOrigin: false,
secure: true
// rewrite: (path) => path.replace(/^\/api/, '')
}
}
}),
viteTsconfigPaths(),
svgr({ svgrOptions: { exportType: 'named' }, include: '/**/*.svg' })
],
optimizeDeps: {
include: ['@emotion/styled', '@mui/styled-engine']
},
server: {
// this ensures that the browser opens upon server start
open: true,
// this sets a default port to 3000
port: 3000,
proxy: {
// with options: http://localhost:5173/api/bar-> http://jsonplaceholder.typicode.com/bar
'/api': {
target: 'http://localhost:8080',
changeOrigin: false,
secure: true
// rewrite: (path) => path.replace(/^\/api/, '')
},
build: {
outDir: './build',
rollupOptions: {
external: ['**.test.ts']
}
}
},
build: {
outDir: './build',
rollupOptions: {
external: ['**.test.ts']
}
}
};
});

0 comments on commit ac02431

Please sign in to comment.