├── .babelrc ├── .circleci └── config.yml ├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── app.json ├── next.config.js ├── package.json ├── pages ├── _app.js ├── _document.js └── index.js ├── public └── dashboard.png └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["next/babel"], 3 | "plugins": [ 4 | [ 5 | "import", 6 | { 7 | "libraryName": "antd" 8 | } 9 | ], 10 | [ 11 | "inline-import", 12 | { 13 | "extensions": [".css"] 14 | } 15 | ] 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # Javascript Node CircleCI 2.0 configuration file 2 | # 3 | # Check https://circleci.com/docs/2.0/language-javascript/ for more details 4 | # 5 | version: 2 6 | jobs: 7 | build: 8 | docker: 9 | # specify the version you desire here 10 | - image: circleci/node:10 11 | 12 | # Specify service dependencies here if necessary 13 | # CircleCI maintains a library of pre-built images 14 | # documented at https://circleci.com/docs/2.0/circleci-images/ 15 | # - image: circleci/mongo:3.4.4 16 | 17 | working_directory: ~/repo 18 | 19 | steps: 20 | - checkout 21 | 22 | # Download and cache dependencies 23 | - restore_cache: 24 | keys: 25 | - v1-dependencies-{{ checksum "package.json" }} 26 | # fallback to using the latest cache if no exact match is found 27 | - v1-dependencies- 28 | 29 | - run: yarn install 30 | 31 | - save_cache: 32 | paths: 33 | - node_modules 34 | key: v1-dependencies-{{ checksum "package.json" }} 35 | 36 | # build project 37 | - run: yarn build 38 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # VSCode workspaces 2 | *.code-workspace 3 | 4 | # Logs 5 | logs 6 | *.log 7 | npm-debug.log* 8 | yarn-debug.log* 9 | yarn-error.log* 10 | lerna-debug.log* 11 | 12 | # Diagnostic reports (https://nodejs.org/api/report.html) 13 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 14 | 15 | # Runtime data 16 | pids 17 | *.pid 18 | *.seed 19 | *.pid.lock 20 | 21 | # Directory for instrumented libs generated by jscoverage/JSCover 22 | lib-cov 23 | 24 | # Coverage directory used by tools like istanbul 25 | coverage 26 | *.lcov 27 | 28 | # nyc test coverage 29 | .nyc_output 30 | 31 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 32 | .grunt 33 | 34 | # Bower dependency directory (https://bower.io/) 35 | bower_components 36 | 37 | # node-waf configuration 38 | .lock-wscript 39 | 40 | # Compiled binary addons (https://nodejs.org/api/addons.html) 41 | build/Release 42 | 43 | # Dependency directories 44 | node_modules/ 45 | jspm_packages/ 46 | 47 | # TypeScript v1 declaration files 48 | typings/ 49 | 50 | # TypeScript cache 51 | *.tsbuildinfo 52 | 53 | # Optional npm cache directory 54 | .npm 55 | 56 | # Optional eslint cache 57 | .eslintcache 58 | 59 | # Optional REPL history 60 | .node_repl_history 61 | 62 | # Output of 'npm pack' 63 | *.tgz 64 | 65 | # Yarn Integrity file 66 | .yarn-integrity 67 | 68 | # dotenv environment variables file 69 | .env 70 | .env.test 71 | 72 | # parcel-bundler cache (https://parceljs.org/) 73 | .cache 74 | 75 | # next.js build output 76 | .next 77 | 78 | # nuxt.js build output 79 | .nuxt 80 | 81 | # vuepress build output 82 | .vuepress/dist 83 | 84 | # Serverless directories 85 | .serverless/ 86 | 87 | # FuseBox cache 88 | .fusebox/ 89 | 90 | # DynamoDB Local files 91 | .dynamodb/ 92 | 93 | # OSX 94 | .DS_Store 95 | 96 | # Heroku 97 | /*.env -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Alexander Graebe 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | HyperTrack logo 3 | 4 | 5 | # Sample Frontend Integration: Placeline 6 | 7 | ![](https://img.shields.io/circleci/build/gh/hypertrack/placeline-nextjs?style=flat-square) 8 | ![](https://img.shields.io/david/hypertrack/placeline-nextjs?style=flat-square) 9 | ![](https://img.shields.io/github/license/hypertrack/placeline-nextjs?style=flat-square) 10 | 11 | Placeline is a ReactJS/NextJS sample application to track the movement of your mobile workforce through the workday. Use this web app to track the live location, activity, and outages of your business assets; track summaries for miles driven, steps walked, stops taken and inactive times; drill down to device locations organized in activity segments for each day, and export selected segments to 3rd party applications such as expense management software. 12 | 13 | > 💬 [Check out this blog post](https://hypertrack.com/blog/2019/09/09/open-sourcing-placeline-a-sample-app-to-track-the-movement-history-of-your-workforce/) to learn why this is important, how HyperTrack is using it internally, and how it all ties together with HyperTrack platform. 14 | 15 | Placeline is built with HyperTrack Views. 16 | 17 | ## Overview 18 | 19 | - [Sample Frontend Integration: Placeline](#sample-frontend-integration-placeline) 20 | - [Overview](#overview) 21 | - [Features](#features) 22 | - [Requirements](#requirements) 23 | - [Installation and setup](#installation-and-setup) 24 | - [Local setup](#local-setup) 25 | - [Heroku setup](#heroku-setup) 26 | - [Usage](#usage) 27 | - [Related](#related) 28 | - [Credits](#credits) 29 | - [License](#license) 30 | 31 | ## Features 32 | 33 | | Dashboard | 34 | | -------------------------------- | 35 | | | 36 | 37 | - Embed HyperTrack Views in a dashboard 38 | - Map the live locations of all devices 39 | - Search and browse devices by day and timezone 40 | - Drill down to live tracking views and day’s history for each device 41 | - Review tracking summaries for duration, distance, activities, and more 42 | - Export tracking summaries 43 | 44 | ## Requirements 45 | 46 | The goal of this project is to get you to a deployed integration in minutes. For this to work, you need to have: 47 | 48 | - [ ] Set up a [HyperTrack account](https://dashboard.hypertrack.com/signup) and obtain your `AccountId` and `SecretKey` from the [Dashboard](https://dashboard.hypertrack.com/) 49 | - [ ] Integrate the HyperTrack SDK in your mobile application ([iOS](https://github.com/hypertrack/quickstart-ios), [Android](https://github.com/hypertrack/quickstart-android), or [React Native](https://github.com/hypertrack/quickstart-react-native)) or use our sample app to send location data ([iOS](https://github.com/hypertrack/live-app-ios) or [Android](https://github.com/hypertrack/live-app-android)) 50 | 51 | ## Installation and setup 52 | 53 | You can install this project on your local machine and deploy it quickly to Heroku for free. 54 | 55 | ### Local setup 56 | 57 | After cloning or forking this repository, you should install all dependencies on your machine: 58 | 59 | ```shell 60 | # with npm 61 | npm install 62 | 63 | # or with Yarn 64 | yarn 65 | ``` 66 | 67 | Next, you need to set your environmental variables. The project uses [dotenv](https://github.com/motdotla/dotenv), so it's best to create a `.env` file in the root folder of the project. This file is listed in `.gitignore` and shall not be checked into public repositories. Below is the content on the file - please ensure to replace the keys with your own: 68 | 69 | ```shell 70 | # HyperTrack 71 | HT_PUBLISHABLE_KEY = 72 | ``` 73 | 74 | With the dependencies and configuration in place, you can start the server in development mode: 75 | 76 | ```shell 77 | # with npm 78 | npm run dev 79 | 80 | # or with Yarn 81 | yarn dev 82 | ``` 83 | 84 | **Congratulations!** You just completed a web app for your HyperTrack integration. 85 | 86 | ### Heroku setup 87 | 88 | This project is set up to be deployed to Heroku within seconds. You need a Heroku account. All you need to do is to click on the one-click-deploy button below. It will provide the following services and add-ons: 89 | 90 | - Web Dyno - to run the server on Heroku (free) 91 | - NodeJS buildpack - to run NextJS on Heroku (free) 92 | - PaperTrail - hosted logging system (free) 93 | 94 | Similar to the local setup, you need to have your keys ready before the deployment. The Heroku page will ask you for the following: 95 | 96 | - `HT_PUBLISHABLE_KEY`: Your HyperTrack publishable key 97 | 98 | You need to enter all of these keys for the project to run successfully. Heroku uses the input to pre-set the environmental variables for the deployment. You can change after the setup as well. 99 | 100 | **Deploy this project now on Heroku:** 101 | 102 | [![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/hypertrack/placeline-nextjs) 103 | 104 | ## Usage 105 | 106 | Once the main page (_index.js_) is opened, it will load an embeddable view from HyperTrack to display all tracked devices. The HyperTrack View enables interaction, so drilling down onto a single device and its history is easily possible. 107 | 108 | ## Related 109 | 110 | This web application is using [HyperTrack Views](https://www.hypertrack.com/docs/guides/track-devices-with-api#embed-views-in-your-dashboard). 111 | 112 | ## Credits 113 | 114 | This project uses the following open-source packages: 115 | 116 | - [nextjs](https://github.com/zeit/next.js/): SSR React Framework 117 | - [dotenv](https://github.com/motdotla/dotenv): Load environment variables from .env files 118 | - [ant-design](https://github.com/ant-design/ant-design): An enterprise-class UI design language and React implementation 119 | 120 | ## License 121 | 122 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details 123 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Sample Frontend NextJS", 3 | "website": "https://www.hypertrack.com/", 4 | "success_url": "/", 5 | "description": "Sample NextJS frontend integration for Placeline application", 6 | "addons": ["papertrail:choklad"], 7 | "buildpacks": [ 8 | { 9 | "url": "heroku/nodejs" 10 | } 11 | ], 12 | "env": { 13 | "HT_PUBLISHABLE_KEY": { 14 | "description": "Your HyperTrack Publishable Key from https://dashboard.hypertrack.com/setup", 15 | "value": "" 16 | } 17 | }, 18 | "repository": "https://github.com/hypertrack/placeline-nextjs", 19 | "logo": "https://dashboard.hypertrack.com/assets/hypertrack-bw.svg", 20 | "keywords": [ 21 | "sample", 22 | "hypertrack", 23 | "placeline", 24 | "integration", 25 | "nextjs", 26 | "react" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | const { parsed: localEnv } = require("dotenv").config(); 2 | 3 | module.exports = { 4 | env: { 5 | HT_PUBLISHABLE_KEY: process.env.HT_PUBLISHABLE_KEY 6 | }, 7 | webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => { 8 | // Note: we provide webpack above so you should not `require` it 9 | // Perform customizations to webpack config 10 | // Important: return the modified config 11 | 12 | // Setup dotenv 13 | config.plugins.push(new webpack.EnvironmentPlugin(localEnv)); 14 | 15 | return config; 16 | }, 17 | webpackDevMiddleware: config => { 18 | // Perform customizations to webpack dev middleware config 19 | // Important: return the modified config 20 | return config; 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "placeline-nextjs", 3 | "description": "Sample NextJS frontend integration for Placeline application", 4 | "version": "1.0.0", 5 | "main": "index.js", 6 | "scripts": { 7 | "dev": "next", 8 | "build": "next build", 9 | "start": "next start -p $PORT" 10 | }, 11 | "author": "Alexander Graebe ", 12 | "license": "MIT", 13 | "keywords": [ 14 | "sample", 15 | "hypertrack", 16 | "placeline", 17 | "integration", 18 | "nextjs", 19 | "react", 20 | "antd", 21 | "heroku" 22 | ], 23 | "engines": { 24 | "node": "10.x" 25 | }, 26 | "dependencies": { 27 | "antd": "^3.26.11", 28 | "babel-plugin-import": "^1.13.0", 29 | "babel-plugin-inline-import": "^3.0.0", 30 | "dotenv": "^8.2.0", 31 | "gensync": "^1.0.0-beta.1", 32 | "next": "^9.2.2", 33 | "react": "^16.12.0", 34 | "react-dom": "^16.12.0", 35 | "react-iframe": "^1.8.0" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /pages/_app.js: -------------------------------------------------------------------------------- 1 | import App from "next/app"; 2 | import Head from "next/head"; 3 | import React from "react"; 4 | 5 | export default class MyApp extends App { 6 | static async getInitialProps({ Component, ctx }) { 7 | let pageProps = {}; 8 | 9 | if (Component.getInitialProps) { 10 | pageProps = await Component.getInitialProps(ctx); 11 | } 12 | 13 | return { pageProps }; 14 | } 15 | 16 | render() { 17 | const { Component, pageProps } = this.props; 18 | 19 | return ( 20 | <> 21 | 22 | 26 | 27 | Placeline Dashboard 28 | 29 | 30 | 31 | ); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /pages/_document.js: -------------------------------------------------------------------------------- 1 | import Document, { Head, Main, NextScript } from "next/document"; 2 | import stylesheet from "antd/dist/antd.min.css"; 3 | 4 | export default class MyDocument extends Document { 5 | render() { 6 | return ( 7 | 8 | 9 |