{"id":19545348,"url":"https://github.com/protoevangelion/interactivetradefloor","last_synced_at":"2025-08-20T12:44:54.300Z","repository":{"id":52127310,"uuid":"85015876","full_name":"protoEvangelion/interactiveTradeFloor","owner":"protoEvangelion","description":"Modern Tradeshow Floorplan Management Tool 🗺","archived":false,"fork":false,"pushed_at":"2021-05-12T00:56:30.000Z","size":5047,"stargazers_count":16,"open_issues_count":15,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-19T07:51:27.540Z","etag":null,"topics":["authentication","enzyme","fullstack-javascript","hot-reloading","jest","mongodb","nodejs","react","redux","travis-ci","universal"],"latest_commit_sha":null,"homepage":"https://tradeshow-floorplan.firebaseapp.com/la/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/protoEvangelion.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-03-15T01:42:41.000Z","updated_at":"2025-03-18T11:59:15.000Z","dependencies_parsed_at":"2022-09-08T12:22:47.628Z","dependency_job_id":null,"html_url":"https://github.com/protoEvangelion/interactiveTradeFloor","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/protoEvangelion/interactiveTradeFloor","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/protoEvangelion%2FinteractiveTradeFloor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/protoEvangelion%2FinteractiveTradeFloor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/protoEvangelion%2FinteractiveTradeFloor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/protoEvangelion%2FinteractiveTradeFloor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/protoEvangelion","download_url":"https://codeload.github.com/protoEvangelion/interactiveTradeFloor/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/protoEvangelion%2FinteractiveTradeFloor/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271321371,"owners_count":24739472,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-20T02:00:09.606Z","response_time":69,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authentication","enzyme","fullstack-javascript","hot-reloading","jest","mongodb","nodejs","react","redux","travis-ci","universal"],"created_at":"2024-11-11T03:38:05.926Z","updated_at":"2025-08-20T12:44:54.269Z","avatar_url":"https://github.com/protoEvangelion.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://codecov.io/gh/protoEvangelion/interactiveTradeFloor\"\u003e\u003cimg src=\"https://img.shields.io/codecov/c/github/protoEvangelion/interactiveTradeFloor.svg?style=flat-square\" alt=\"Build Status\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://aoatradeshow.herokuapp.com/\"\u003e\u003cimg src=\"https://img.shields.io/website-up-down-green-red/http/shields.io.svg\" alt=\"Code Coverage\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://www.codacy.com/app/protoEvangelion/interactiveTradeFloor?utm_source=github.com\u0026amp;utm_medium=referral\u0026amp;utm_content=protoEvangelion/interactiveTradeFloor\u0026amp;utm_campaign=Badge_Grade\"\u003e\u003cimg src=\"https://api.codacy.com/project/badge/Grade/488a2a3f487a4d568d005ec5ef831bfa\" alt=\"Code Grade\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n![tradeshow](https://cloud.githubusercontent.com/assets/20076677/25107976/6cb4abd6-2387-11e7-8faa-69a684bc3054.gif)\n\n# Tradeshow Floorplan Manager\n\nThis is a blazingly fast static site built upon stable modern technologies like React and Firebase with a goal to simplify the trade show management process.\n\nSpecifically, it helps marketers/sales people consolidate their efforts and collaborate in real time with speed.\n\nRather than track everything by paper, you can use this web app to keep track of all booths you are managing and **color code** them according to who is managing the booth.\n\n# Table of Contents\n\n- [Features](#features)\n- [Prerequisites:](#prerequisites)\n- [Setup](#setup)\n\t- [Available Scripts](#available-scripts)\n\t\t\t- [Development Mode](#development-mode)\n\t\t\t- [Production Mode](#production-mode)\n\t- [Changing Booth Layouts in Firebase](#changing-booth-layouts-in-firebase)\n\t\t- [Booth API](#booth-api)\n\t- [How To Deploy Firebase Functions And App To Firebase Hosting](#how-to-deploy-firebase-functions-and-app-to-firebase-hosting)\n\t- [Firebase Authentication:](#firebase-authentication)\n\t- [Firebase Database Rules:](#firebase-database-rules)\n\t- [Firebase Storage Rules:](#firebase-storage-rules)\n\t- [Firebase Functions:](#firebase-functions)\n\t- [Setting Up The Emailing Feature](#setting-up-the-emailing-feature)\n\t- [How On-demand Backups Work](#how-on-demand-backups-work)\n- [License](#license)\n\n## Features\n\n* 🚀 `Gatsby` Static Site Generator for Blazingly Fast Performance \u0026 SEO.\n* 🔩 `Socket.io` for live updating between users.\n* 👀 `react` as the view.\n* 🔀 `react-router` as the router.\n* 🏪 `redux` as the central store for state management.\n* 💅 `Styled Components` as the styling library.\n* 🔥 `Firebase DB` as the database.\n* 👥 `Firebase Auth` for secure user authentication.\n* 💎 `Firebase Functions` to provide serverless architecture.\n* 📁 `Firebase Storage` for on-demand backups.\n* 🔄 Fast development hot reloading with `react-hot-loader`.\n* 👮 Security with `Snyk` and `react-helmet`.\n* 📦 All source is bundled using `Webpack` and `Gatsby`.\n* 👼 `ESlint` Airbnb configuration for code quality.\n* 🌈 `Prettier` for beautiful auto code formatting.\n* 🎭 `Jest` as the testing framework to ensure reliability.\n* ❤️ Continuous integration with `Travis-CI`.\n* 🎯 ES6 Javascript for terse readable code.\n\n## Prerequisites:\n\n1.  [Nodejs \u0026 NPM](https://nodejs.org/)\n2.  [Firebase](https://firebase.google.com/)\n3.  [Firebase tools](https://www.npmjs.com/package/firebase-tools)\n\n## Setup\n\n### Available Scripts\n\n* Scripts are available in the `package.json` file at the root level under the \"**scripts**\" property\n\n##### Development Mode\n\n```shell\nnpm run dev\n```\n\n##### Production Mode\n\n```shell\nnpm run build\nnpm run deploy\n```\n\n### Changing Booth Layouts in Firebase\n\n* Booth locations are computed based on **row**, **column** and **size** which defaults to 1x1\n* Accepts an image url as the `image` key which will center \u0026 resize the custom image over the booth\n* Accepts a custom `size` key which can be specified as `3x2` or whatever\n* Firebase is NoSQL so if a key is not required, you don't have to specify it\n\n#### Booth API\n\n| Option        | Usage      | Type     |\n| ------------- | ---------- | -------- |\n| `_id`         | _Required_ | `String` |\n| `col`         | _Required_ | `Number` |\n| `row`         | _Required_ | `Number` |\n| `company`     | _Optional_ | `String` |\n| `description` | _Optional_ | `String` |\n| `image`       | _Optional_ | `Url`    |\n| `num`         | _Optional_ | `Number` |\n| `owner`       | _Optional_ | `String` |\n| `size`        | _Optional_ | `String` |\n| `status`      | _Optional_ | `String` |\n\nExample:\n\n```json\n\"yourroute\": {\n  \"630\": {\n    \"_id\":\"5910ae25529a13a5bf988a5e\",\n    \"num\":630,\n    \"row\":1,\n    \"col\":13,\n    \"owner\":\"Ryan\",\n    \"status\":\"holding\",\n    \"company\":\"Cool Company\",\n    \"description\":\"The most ultra cool co in existence!\"\n  },\n  \"531\": {  \n    \"_id\":\"5910b02a529a13a5bf988af7\",\n    \"num\":531,\n    \"row\":-1,\n    \"col\":12,\n    \"owner\":\"None\",\n    \"status\":\"good\",\n    \"company\":\"Another cool co\",\n\t\t\"size\":\"2x1\",\n\t\t\"image\":\"urlToImage.com\"\n\t},\n\t\"randomthing\": {\n\t\t\"_id\":\"5910b02a529a13a5bf988af7\",\n    \"row\":10,\n    \"col\":14,\n\t\t\"size\":\"5x10\",\n\t\t\"image\":\"urlToImage.com\"\n\t}\n}\n```\n\n* The second key under \"yourroute\" must be unique\n\t* One of the main reasons for it is **convenience** when trying to find a booth in the firebase console\n\n### How To Deploy Firebase Functions And App To Firebase Hosting\t\n\n* To Set up Firebase head to: https://console.firebase.google.com\n\t* Proceed through the instructions to set up a new project.\n\t* Once you have completed those steps successfully, you can set up each of these sections below:\n\n1. Make sure `.firebaserc` in the root of this project has your **project id**.\n2. With `firebase-tools` installed you can run firebase from the command line\n\n```\nfirebase login\n```\n\n* To get all your credentials\n\n```\nfirebase setup:web\n```\n\n* Create a new file called `config.js` in the root of this repo with the file below\n\t* Add the credentials the `firebase setup:web` command prints out under the key `FIREBASE_CONFIG`\n\t* This file is in `.gitignore` so will not be committed because it contains secrets\n\t* Make sure the first letter of the owner names are captalized in both firebase db and the `config.js` `USER_MAP`\n\n```js\nconst AUTHENTICATED_USER_EMAILS = [\n\t'email1@gmail.com',\n\t'email2@yahoo.com',\n\t...\n]\n\nconst BOOTH_LAYOUT = {\n\tborderWidth: 2,\n\tcolumns: 18,\n\tdimension: 60,\n\trows: 26,\n}\n\n// Click around your console.firebase.google to gather these values\nconst FIREBASE_CONFIG = {\n\tapiKey: 'your api key',\n\tauthDomain: 'tradeshow-floorplan.firebaseapp.com',\n\tdatabaseURL: 'https://tradeshow-floorplan.firebaseio.com/ ',\n\tprojectId: 'tradeshow-floorplan',\n\tstorageBucket: 'gs://tradeshow-floorplan.appspot.com',\n}\n\n/**\n * Allows you to create programmatic routes\n * You can pass a custom BOOTH_LAYOUT object for each page if you would like\n * https://www.gatsbyjs.org/docs/bound-action-creators/#createPage\n */\nconst FLOORPLAN_PAGES = [\n\t{\n\t\tname: 'Los Angeles',\n\t\tpath: '/la',\n\t\tcontext: BOOTH_LAYOUT,\n\t},\n\t{\n\t\tname: 'Long Beach',\n\t\tpath: '/lb',\n\t\tcontext: Object.assign({}, BOOTH_LAYOUT, { columns: 15, rows: 27 }),\n\t},\n]\n\nconst USER_MAP = {\n\tJin: {\n\t\tcolor: '#ff00aa',\n\t\temail: 'email1@gmail.com',\n\t},\n\tRichard: {\n\t\tcolor: '#0800FF',\n\t\temail: 'email2@yahoo.com',\n\t},\n\tTodd: {\n\t\tcolor: '#00B20E',\n\t\temail: 'email3@gmail.com',\n\t},\n}\n\nmodule.exports = {\n\tAUTHENTICATED_USER_EMAILS,\n\tFIREBASE_CONFIG,\n\tFLOORPLAN_PAGES,\n\tUSER_MAP,\n}\n```\n\n### Firebase Authentication:\n\n* Only google auth is currently set up as provider\n\n  ![Firebase Auth](https://user-images.githubusercontent.com/20076677/39107467-4c5c5fc8-4677-11e8-83d7-3461887f9e13.png)\n\n### Firebase Database Rules:\n\n[Firebase DB Docs](https://firebase.google.com/docs/database/web/start?authuser=1)\n\n```\n{\n  \"rules\": {\n    \".read\": true,\n    \".write\": \"auth.token.email == 'email1@gmail.com' || auth.token.email == 'email2@yahoo.com'\"\n  }\n}\n```\n\n### Firebase Storage Rules:\n\n```\nservice firebase.storage {\n  match /b/{bucket}/o {\n    match /{allPaths=**} {\n      allow read: if false;\n      allow write: if request.auth.token.email == 'email1@gmail.com' || request.auth.token.email == 'email2@yahoo.com';\n    }\n  }\n}\n```\n\n### Firebase Functions:\n\n* The only part of this app that would require a server is sending emails\n* However, thanks to Firebase Functions, we can still have a **serverless** web app that is **blazingly fast**\n* To run a **local** firebase shell:\n\n```\nnpm run shell\n```\n\n* You can then call the email function directly from there if you would like to test it out\n\n```\nemailTeam()\n```\n\n* To only deploy functions rather than hosting run:\n\n```\nnpm run deploy:functions\n```\n\n* Otherwise you can just call the function from the web app and check the Firebase function logs:\n  ![Firebase Logs](https://user-images.githubusercontent.com/20076677/39110849-8d1089b2-4687-11e8-9659-06edfc1cf2af.png)\n\n### Setting Up The Emailing Feature\n\n* In the `functions` directory create a new file called `emailConfig.js` that has the content below\n\t* This file is in `.gitignore`\n\n```js\n// functions/emailConfig.js\nconst GMAIL_SETTINGS = {\n\temail: 'theEmailThatWillSendEmails@gmail.com',\n\tpass: 'password',\n}\n\nconst RECIPIENT_EMAILS = [\n\t'email1@gmail.com',\n\t'email2@yahoo.com',\n\t...\n]\n\nmodule.exports = {\n\tGMAIL_SETTINGS,\n\tRECIPIENT_EMAILS,\n}\n```\n\n* _If you need further help setting up your gmail to send emails, we use_ [Nodemailer so check out their docs](https://nodemailer.com/about/) \n* This project just uses a Gmail account to send emails\n\t* [Article on sending with a simple Gmail account](https://medium.com/@manojsinghnegi/sending-an-email-using-nodemailer-gmail-7cfa0712a799)\n\n\n### How On-demand Backups Work\n\n* On-demand backups store the firebase db in json format in firebase storage for easy retrieval\n* The backups are launched when user visits site\n* On-demand client side db backup max 1 backup per day\n\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2017 [Ryan Garant](https://github.com/protoEvangelion)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprotoevangelion%2Finteractivetradefloor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprotoevangelion%2Finteractivetradefloor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprotoevangelion%2Finteractivetradefloor/lists"}