A few months ago I decided to look in to writing a real application with Vue.js. I had dropped it in views with Express before, but this time I was going all in with single file components and the whole nine yards. BillTrackr was the result.

I have been debating on whether or not to release the code because I just did not know if anyone would find it useful. This is a little bit more involved than a todo app, but it does cover quite a few questions I see quite a bit like how to configure Vuex, how to load your state using Axios, refreshing your state and how to check if your state has been initialized. If I can help some folks out then I think it is worth releasing, bonus points for helping me correct things I could handle better.

I have not released the API portion of the code so you will be stuck using my API. I will say the Mongoose models have not really changed from what is outlined in node-billz.

Developer Notes

Once cloned, the application can be run with yarn dev but you cannot change listening port since that will break the callback used by Auth0 authentication.

The application uses Nuxt which is a great convention-based framework for Vue.js. The framework handles most of the hard work for you as far as webpack, router and vuex configuration.

Auth0 is used for authentication based off of the Nuxt Auth0 example application. Pages that should be protected use the authenticated middleware. By default most pages require authentication. Nuxt will allow you to set the middleware in the default exports for a page.

// dashboard.vue
export default {
  middleware: 'authenticated',
  created () {
    return {
      ref: new Moment().format('YYYY-MM-DD')
    }
  },
  ... more code here
}

There are two other layouts leveraged by the system. The anon layout is used for pages that do not require authentication and finally the sign-in layout is used for the sign-in page.

The application layout itself was generated using the Nuxt+Vuetify template. This cuts out a lot of the complexity of getting started. Vuetify allows you to create a clean UI but it does come with a bit of a learning curve, but I believe it was worth it.

BillTrackr relies heavily on Vuex state management to make things run smoothly. The three main "silos" of data are userSettings, payees and payments. The userSettings are the container for user related data such as start of week and the user's time zone information. Synonymous with bills, payees contains all the information about the people you pay each month. Payments contain just that, all payments a user has made that is tracked by the system.

The Vuex data store is only loaded in the created() lifecycle hook inside the default layout using Axios. If a new bill or payment is added a refresh is dispatched to update the data store.

The current reference date and currently selected calendar type (weekly or monthly) is also retained in Vuex so all components have access to the current settings.

The forecast() methods in the weekly and monthly views were a lot of fun to code. The weekly forecast is a little heavier since it has to account for the user's week offset and other calendar oddities. All date calculations should take the user's timezone into account.

If you are running the application on your local machine and you have the Vue Dev Tools installed you will be able to inspect the application and vuex state. This functionality is turned off in the production environment.

Wrapping it all up

I have seen a lot of simple demos out there outlining authentication or vuex, but nothing that ever really tied everything together. This project covers all of that and then some.

Hopefully seeing a more complete application will help somebody out. If there are some features you would like to see added I welcome pull requests.

BillTrackr on GitHub: https://github.com/robertz/billtrackr
BillTracker: https://billtrackr.com