Skip to content

IgorKrupenja/zaino

Repository files navigation

Zaino

Hiking and mountaineering equipment app for the meticulous adventurer.

🚨 This was my early first-year university project so some things could have been done better. 😉 It is no longer maintained but live demo is up. Running the app and self-hosting it is also possible after completing setup.
Built with Typescript, React and Firebase.

Screenshot

Contents

Setup

Before starting, make sure that you have Node 16 installed — or use something like nvm.

Common

  1. Install Google's Cloud SDK and run gcloud auth login to log in.
  2. Run npm install -g firebase-tools to install Firebase CLI globally and run firebase login to log in.
  3. Run npm install in the root directory of the cloned/forked repo.
  4. Go to Firebase console and create two projects, one for development environment and one for production environment.
  5. In Firebase console, create Web apps for the two projects you just made. Refer to this article for additional information.
  6. In Firebase console, open Project Settings and note the Project IDs for the projects you created.
  7. Create a .firebaserc file in the root of this repo and add the Project IDs there. Example with dummy values below:
{
  "projects": {
    "development": "zaino-dev-3ea56",
    "production": "zaino-prod-236c2"
  }
}

Web app

  1. Go to Firebase console and open Project Settings for your projects.
  2. Scroll down to Your Apps section and locate the code snippet with firebaseConfig.
  3. Go to packages/web-app and create .env.development and .env.production files with the variables from firebaseConfig. Example with correct format and dummy values below:
REACT_APP_FIREBASE_API_KEY="AIzaSkR_FfdseFcsE3fgg7pdjjjof6jhDSA-dTM"
REACT_APP_FIREBASE_AUTH_DOMAIN="zaino-dev-3ea56.firebaseapp.com"
REACT_APP_FIREBASE_DATABASE_URL="https://zaino-dev-3ea56.firebaseio.com"
REACT_APP_FIREBASE_PROJECT_ID="zaino-dev-3ea56"
REACT_APP_FIREBASE_STORAGE_BUCKET="zaino-dev-3ea56.appspot.com"
REACT_APP_FIREBASE_MESSAGING_SENDER_ID="550657824795"
REACT_APP_FIREBASE_APP_ID="1:550657824795:web:29da52b66934c3ea494f74"
REACT_APP_FIREBASE_MEASUREMENT_ID="G-EWJOIOADSK"

Caveats ⚠️

  • Most of the images used in the live demo were purchased from GraphicRiver and Freepik and cannot be made part of this repo due to copyright restrictions. To get images in the app, you can add your own to packages/web-app/src/images/copyrighted directory with the following structure:
├── categories
│   ├── backpack.svg
│   ├── boots.svg
│   ├── compass.svg
│   ├── gloves.svg
│   ├── gps.svg
│   ├── hat.svg
│   ├── hook.svg
│   ├── jacket.svg
│   ├── knife.svg
│   ├── pickaxe.svg
│   ├── poles.svg
│   ├── shorts.svg
│   ├── socks.svg
│   ├── stove.svg
│   └── tent.svg
└── mountain.svg <--- loader image
  • Privacy policy content used in the live demo is not part of the repo. You can add your own to packages/web-app/src/components/pages/PrivacyPolicyPage/PrivacyPolicyContent.tsx. Otherwise, it shows a placeholder.

Firebase

  1. Create a Firestore database in Firebase console for your projects, a detailed guide is available here.
  2. Go to packages/firebase and create .env.development and .env.production files with the variables for your Project IDs. Example with dummy values below:
FB_PROJECT_ID="zaino-dev-3ea56"

Note: You can change additional settings like regions and Cloud Storage bucket name in the .env file.

Deployment

  1. Make sure you did everything in Setup above.
  2. Go to packages/web-app and run npm run deploy to deploy production or npm run deploy-dev to deploy development.
  3. Go to packages/firebase and run npm run deploy to deploy production or npm run deploy-dev to deploy development.

Doing this will also enable periodic Firestore backups and seed the database with demo data, see firebase below.

Running locally

  1. Make sure you did everything in Setup and Deployment above.
  2. Go to packages/web-app, run npm start and open localhost:4200. This will run against a deployed development Firebase project.

Project structure

The project is a monorepo. I suggest to open the root folder in editor. It has some root-level config, including shared VSCode settings.

Code is split into several packages. Each package is a separate npm workspace. These are:

A bit of shared code (types).

  • src/components/ App components and pages, along with per-component styles. Styles are in SCSS and follow the BEM convention.
  • src/firebase/ Firebase initialisation and a couple of util functions to work with Firestore data.
  • src/routes/ React Router config and routes.
  • src/state/ State management with Redux.
  • src/styles/ Style variables and settings that apply to the whole app.
  • config and scripts have some JS files, mostly for Webpack, build and dev server. These is because the app started as a Create React App but was then ejected.

Technologies

  • Typescript
  • React, React Router, Redux
  • Some React UI components: React Select, react-modal, react-tiny-popover
  • SCSS (no frameworks)
  • npm workspaces
  • Cloud Firestore, Firebase Authentication, Firebase Functions, Google Cloud Storage, Firebase Hosting

Functionality

  • Log-in with Google account. Fast and secure log in with your Google account.
  • Data storage with Firestore. Your data is safely stored in a Cloud Firestore database both with live demo and if you self-host Zaino.
  • Robust search and filtering. Easily filter and sort your items by name, category, label, weight, etc.
  • Efficient packing for your next adventure. Pack list offers a convenient overview of the items you want to take with you, including weight.
  • Flexible label system. Organise your items in any way you want with custom labels.
  • Demo data. Want to try the app without entering your own data first? Click Load under Demo data in header to populate your inventory with a comprehensive set of sample items. These can be easily removed later.
  • Self-hosting support. Concerned about privacy and want to completely self-host your data? This is possible and I have provided a detailed guide in the Setup section below.

Possible improvements

Most of the code was written as a summer project after my first year in uni. So there are quite a few areas for possible improvement:

  • The app needs tests.
  • Custom categories would make a nice feature.
  • There is no infinite scroll.
  • State management with Redux is a bit convoluted and could be simpler.
  • The overall inventory and pack management UX could be better.
  • There is no support for mobile screens, narrower than 600px.
  • Add support for multiple packs.
  • Improve accesibility

Changelog

0.1.1 (4th November 2020)

  • Added privacy and cookie policy.
  • Fixed usability issue with accidentally closing New item modal on clicking category or labels.
  • Fixed incorrect input being occasionally focused when clicking on a label in Edit label form.
  • Fixed minor styling issues with New label form.
  • Made text selection color less bright.
  • Updated README with a better screenshot.

See full changelog.

Acknowledgements

  • Dmitri Shastin for his ideas and sharing his inventory data with me.
  • All the people proving me with feedback.