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

Add ArcxAnalyticxProvider and an example CRA app #21

Merged
merged 6 commits into from
Nov 17, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
move the helper outside the analytics sdk class
add window object typing

rm comments and log

do not save the url on the window object and add medium option to attribute call

make the current url private

add arcx analyticx provider and CRA example project

log page events

track event clicks on console view

update readme

fix installations

add missing peer dependencies

ignore webpack config ts to avoid eslint errors

update header and favicon

support react versions >=16
  • Loading branch information
gtupak committed Nov 15, 2022
commit fb2fe19a35c32e77e38fde5895f6374fd0b856ec
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
webpack.config.ts
2 changes: 1 addition & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "./*/tsconfig.json",
"project": "./tsconfig.json",
"sourceType": "module"
},
"rules": {
Expand Down
3 changes: 2 additions & 1 deletion .npmignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
**/test/**
test/**
example/**
5 changes: 5 additions & 0 deletions example/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Mandatory
REACT_APP_ARCX_API_KEY =

# Optional
REACT_APP_ARCX_API_URL =
23 changes: 23 additions & 0 deletions example/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*
25 changes: 25 additions & 0 deletions example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).

# Usage of ARCx Analyticx React Provider

If you have a React app, one easy way to integrate the SDK is to simply add the `ArcxAnalyticsProvider` at the root of your application:

You must pass an `API_KEY` as specified in the [SDK's documentation](https://github.com/arcxmoney/analytics-sdk) and, optionally, a `config` object. This is the same `config` as described [here](https://github.com/arcxmoney/analytics-sdk#init).

```jsx
return (
<ArcxAnalyticsProvider apiKey={API_KEY} config={config}>
<div>
gtupak marked this conversation as resolved.
Show resolved Hide resolved
...the rest of your app here
</div>
</ArcxAnalyticsProvider>
)
```

Then, in children components, you will have access to the `useArcxAnalytics()` hook which exposes an instance of the SDK, as described by the API [here](https://github.com/arcxmoney/analytics-sdk#api).

## Note

You can test this app with the local package by linking it locally with [yarn link](https://classic.yarnpkg.com/lang/en/docs/cli/link/). If you face "two copies of react" problems, you can fix it by temporarily deleting the `react` and `react-dom` folders inside `../node_modules`.

This is why there is a `rm ../node_modules/{react,react-dom}` at the beginning of the `start` script in `package.json`.
47 changes: 47 additions & 0 deletions example/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"name": "example",
"version": "0.1.0",
"private": true,
"dependencies": {
"@arcxmoney/analytics": "^1.0.2",
"@babel/plugin-syntax-flow": "^7.14.5",
"@babel/plugin-transform-react-jsx": "^7.14.9",
"@types/node": "^16.7.13",
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.4.3",
"react-scripts": "5.0.1",
"typescript": "^4.4.2",
"web-vitals": "^2.1.0"
},
"scripts": {
"start": "rm -rf ../node_modules/{react,react-dom} && react-scripts start",
"build": "react-scripts build",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
xitronix marked this conversation as resolved.
Show resolved Hide resolved
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"autoprefixer": "^10.4.13",
"postcss": "^8.4.18",
"tailwindcss": "^3.2.3"
}
}
6 changes: 6 additions & 0 deletions example/postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
Binary file added example/public/favicon.ico
Binary file not shown.
43 changes: 43 additions & 0 deletions example/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.

Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>ARCx Analytics Example</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.

You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.

To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
Binary file added example/public/logo192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added example/public/logo512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions example/public/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
3 changes: 3 additions & 0 deletions example/public/robots.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
xitronix marked this conversation as resolved.
Show resolved Hide resolved
xitronix marked this conversation as resolved.
Show resolved Hide resolved
Disallow:
48 changes: 48 additions & 0 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { ConsoleView } from './ConsoleView'
import { TestEventButtons } from './TestEventButtons'
import { TestPageButtons } from './TestPageButtons'
import { ArcxAnalyticsProvider } from '@arcxmoney/analytics'
import { BrowserRouter, Route, Routes } from 'react-router-dom'

function App() {
const API_KEY = process.env.REACT_APP_ARCX_API_KEY
if (!API_KEY) {
throw new Error('REACT_APP_ARCX_API_KEY is not set')
}
const url = process.env.REACT_APP_ARCX_API_URL

return (
<BrowserRouter>
<ArcxAnalyticsProvider apiKey={API_KEY} config={{ url }}>
<div className="min-w-screen min-h-screen">
<div className="container mx-auto">
<div className="flex flex-col justify-center items-center mt-24 gap-4">
<h1 className="text-5xl font-bold">
ARCx Analytics Example Page |{' '}
<span>
<Routes>
<Route path="/" element="Home" />
<Route path="/page-1" element="Page 1" />
<Route path="/page-2" element="Page 2" />
<Route path="/page-3" element="Page 3" />
</Routes>
</span>
</h1>
<p className="text-center">
Welcome to the ARCx Analytics example page!
<br />
Click on the buttons below to change routes and fire events. You can observe what is
being sent to the API below
</p>
<TestPageButtons />
<TestEventButtons />
<ConsoleView />
</div>
</div>
</div>
</ArcxAnalyticsProvider>
</BrowserRouter>
)
}

export default App
38 changes: 38 additions & 0 deletions example/src/ConsoleView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { useEffect, useState } from 'react'
import { Attributes, useArcxAnalytics } from '@arcxmoney/analytics'

export const ConsoleView = () => {
const [output, setOutput] = useState<string[]>([])
const sdk = useArcxAnalytics()

useEffect(() => {
if (!sdk) return

setOutput((output) => [...output, '> SDK initialized with ID: ' + sdk.identityId])

// Hijack the event call to output the events to the console

const originalEventCall = sdk.event.bind(sdk)
sdk.event = (event: string, attributes?: Attributes) => {
setOutput((output) => [
...output,
'> Event: ' + event + '\nAttributes: ' + JSON.stringify(attributes, null, 2),
])

return originalEventCall(event, attributes)
}
}, [sdk])

return (
<div className="mt-8 h-[30rem] overflow-auto scroll-smooth w-full bg-slate-900 p-4 font-mono flex flex-col gap-4 text-yellow-500">
<div className="font-bold mb-4">
Requests are being sent to {process.env.REACT_APP_ARCX_API_URL ?? 'api.arcx.money'}...
</div>
<div>
{output.map((line, i) => (
<div key={i}>{line}</div>
))}
</div>
</div>
)
}
22 changes: 22 additions & 0 deletions example/src/TestEventButtons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { useArcxAnalytics } from '@arcxmoney/analytics'

export const TestEventButtons = () => {
const sdk = useArcxAnalytics()

return (
<div className="flex gap-4">
<button
className="rounded-full bg-blue-500 px-4 py-2 hover:bg-blue-300 font-bold"
onClick={() => sdk?.event('BLUE_BUTTON', { attr1: '1', attr2: '2' })}
>
Test event: blue button
</button>
<button
className="rounded-full bg-red-500 px-4 py-2 hover:bg-red-300 font-bold"
onClick={() => sdk?.event('RED_EVENT', { attr1: 'a', attr2: 'b' })}
>
Test event: red button
</button>
</div>
)
}
33 changes: 33 additions & 0 deletions example/src/TestPageButtons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { useLocation, useNavigate } from 'react-router-dom'

export const TestPageButtons = () => {
const location = useLocation()
const navigate = useNavigate()

const getRedirectUrl = (path: string) => {
return location.pathname === path ? '/' : path
}

return (
<div className="flex gap-4">
<button
className="rounded-full bg-blue-500 px-4 py-2 hover:bg-blue-300 font-bold"
onClick={() => navigate(getRedirectUrl('/page-1'))}
>
Go to {location.pathname === '/page-1' ? 'Home' : '/page-1'}
</button>
<button
className="rounded-full bg-green-500 px-4 py-2 hover:bg-green-300 font-bold"
onClick={() => navigate(getRedirectUrl('/page-2'))}
>
Go to {location.pathname === '/page-2' ? 'Home' : '/page-2'}
</button>
<button
className="rounded-full bg-red-500 px-4 py-2 hover:bg-red-300 font-bold"
onClick={() => navigate(getRedirectUrl('/page-3'))}
>
Go to {location.pathname === '/page-3' ? 'Home' : '/page-3'}
</button>
</div>
)
}
19 changes: 19 additions & 0 deletions example/src/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
background-color: #36454F;
color: whitesmoke;
}

code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}
19 changes: 19 additions & 0 deletions example/src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
1 change: 1 addition & 0 deletions example/src/react-app-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/// <reference types="react-scripts" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

15 changes: 15 additions & 0 deletions example/src/reportWebVitals.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ReportHandler } from 'web-vitals';

const reportWebVitals = (onPerfEntry?: ReportHandler) => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry);
getFID(onPerfEntry);
getFCP(onPerfEntry);
getLCP(onPerfEntry);
getTTFB(onPerfEntry);
});
}
};

export default reportWebVitals;
Loading