https://github.com/igorkrupenja/zaino
First-year university project. Hiking and mountaineering equipment web app.
https://github.com/igorkrupenja/zaino
firebase firestore hiking react redux sports typescript
Last synced: about 1 year ago
JSON representation
First-year university project. Hiking and mountaineering equipment web app.
- Host: GitHub
- URL: https://github.com/igorkrupenja/zaino
- Owner: IgorKrupenja
- License: mit
- Created: 2020-07-17T16:24:14.000Z (almost 6 years ago)
- Default Branch: main
- Last Pushed: 2023-07-23T18:12:46.000Z (almost 3 years ago)
- Last Synced: 2023-07-23T19:25:55.014Z (almost 3 years ago)
- Topics: firebase, firestore, hiking, react, redux, sports, typescript
- Language: TypeScript
- Homepage: https://zaino.cc
- Size: 4.79 MB
- Stars: 6
- Watchers: 1
- Forks: 0
- Open Issues: 111
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
️
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.
Live demo ᐧ Setup ᐧ Changelog
Built with Typescript, React and Firebase.

## Contents
- [Setup](#setup)
- [Deployment](#deployment)
- [Running locally](#running-locally)
- [Project structure](#project-structure)
- [Technologies](#technologies)
- [Functionality](#functionality)
- [Possible improvements](#possible-improvements)
- [Changelog](#changelog)
- [Acknowledgements](#acknowledgements)
## Setup
Before starting, make sure that you have Node 16 installed — or use something like [nvm](https://github.com/nvm-sh/nvm).
### Common
1. [Install Google's Cloud SDK](https://cloud.google.com/sdk/docs/install) 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](https://console.firebase.google.com/u/0/) 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](https://support.google.com/firebase/answer/9326094) 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:
```json
{
"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:
```shell
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](https://zaino.cc) were purchased from [GraphicRiver](https://zaino.cc) and [Freepik](https://www.freepik.com/) 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:
```shell
├── 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](https://zaino.cc) 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](https://firebase.google.com/docs/firestore/quickstart#create).
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:
```shell
FB_PROJECT_ID="zaino-dev-3ea56"
```
Note: You can change additional settings like regions and Cloud Storage bucket name in [the `.env` file](packages/firebase/.env).
## Deployment
1. Make sure you did everything in [Setup](#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](#firebase-1) below.
## Running locally
1. Make sure you did everything in [Setup](#setup) and [Deployment](#deployment) above.
2. Go to `packages/web-app`, run `npm start` and open [localhost:4200](http://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](.vscode).
Code is split into several [packages](packages). Each package is a separate [npm workspace](https://docs.npmjs.com/cli/v7/using-npm/workspaces). These are:
### [shared](packages/shared)
A bit of shared code (types).
### [firebase](packages/firebase)
- A config file with Firestore rules: [firestore.rules](packages/firebase/firestore.rules).
- A [cloud function](packages/firebase/src/database/functions/addSeedData.ts) that seeds the Firestore with demo data from JSON, [seed-data.json](packages/firebase/src/seed-data/seed-data.json). The original [was provided to me by Dmitri](#acknowledgements) as an Excel file. Kudos!
- Another [function](packages/firebase/src/database/functions/backupDb.ts) for periodic DB backups.
### [web-app](packages/web-app)
- [src/components/](packages/web-app/src/components) App components and [pages](packages/web-app/src/components/pages), along with per-component styles. Styles are in SCSS and follow the BEM convention.
- [src/firebase/](packages/web-app/src/firebase) Firebase initialisation and a couple of util functions to work with Firestore data.
- [src/routes/](packages/web-app/src/routes) React Router config and routes.
- [src/state/](packages/web-app/src/state) State management with Redux.
- [src/styles/](packages/web-app/src/styles) Style variables and settings that apply to the whole app.
- [config](packages/web-app/config) and [scripts](packages/web-app/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](https://create-react-app.dev/docs/available-scripts/#npm-run-eject).
## Technologies
- Typescript
- React, React Router, Redux
- Some React UI components: [React Select](https://react-select.com/home), [react-modal](https://github.com/reactjs/react-modal), [react-tiny-popover](https://github.com/alexkatz/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](https://zaino.cc) 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](#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](CHANGELOG.md).
## Acknowledgements
- Dmitri Shastin for his ideas and sharing his inventory data with me.
- All the people proving me with feedback.