Word Count: 1121
  • Post category:Lets Share App
  • Post last modified:2022-09-02

Purpose

This app calculates the shares of payment for each participant (or sharer) for snooker events. Since not all participants are using Payme or other e-payment tools, these rules have to be implemented:

  • Only TF will pay the snooker bill to the club house.
  • Either TF or Lam will pay the meal bill to the restaurant.
  • If Lam paid the meal bill, other sharers will pay their shares to Lam via TF.
  • Only Lung will top up his balance with cash.

App Features

  • Supports up to 6 participants in the snooker event.
    • These are Lung, Lam, SC, TF and 2 Guests.
  • Participants can take part either in Meal or Snooker session or both.
  • Maintains 4 most recent transaction history. This value can be changed in HomeView.vue
  • Remark text can be added to Transaction history.

Technologies

This project attempts to dominstrate the use of some important technologies around the Vue framework, so as to get a better experience of using Vue for development.

  • Vue – JS framework
  • Vite – App builder, better than Webpack
  • Pine – State management. The states are keep under the src/stores directory.
  • vue-router – manages the URL routes.
  • Local Storage – the browser storage is used to keep presisent data used by the application.

Conceptual Diagram

Operations

index.html

The top level of the App. All content rendered by App.vue are inserted into the <div> with id=’app’. This is done by the codes in main.js.

src/App.vue

This is the second level of the app which forms the SPA structure. The hierarchy is:

  • Navigation component
  • Router-view
    • Different view templates called by the navigation menus are inserted into this router-view section.
  • Footer markup

At the ‘onBeforeMount’ hook, the setup script checks whether ‘local_sharers’ value is existing in the Local Storage. If negative, that means the App is freshly installed and has not been initialized. Under this condition, the script at this hook will create a dummy ‘local_sharers’ to prevent the ‘undefined’ error.

src/main.js

This JS file mounts the contents rendered by App.vue to the <div id=’app’> in index.html.

import { createApp } from 'vue'
import App from './App.vue'
import router from '@/router'
import { createPinia } from 'pinia'

import './style.css'

const pinia = createPinia()

createApp(App).use(router).use(pinia).mount('#app')

Stores – the state management framework from Pine

stores/SharerStore.js

This manages the state of Sharers and the state (or value) is available across the whole application.

  • It reads in the ‘local_sharers’ (stored as a Json file) from the Local Storage and convert it into an array of JS object.
  • It returns this array for any coming requests.
  • The getter function ‘sharerCount( )’ returns the number of sharers.
  • The updateLocalStore( ) function overwrite the Local Storage with the current state.
  • The getSharerRecord(name) function returns the sharer record with name = name.
  • Local_sharers data structure:
[
  0: {id: "clc", name: "Lung", balance: "155.15", timestamp: "17/8/2022, 24:12:02"},
  1: {....}
  ...
]

stores/SnookerRateStore.js

This manages the state of the snooker rate.

  • It reads in the ‘local_snookerRate’ from Local Storage which is stored as a simple key / value pair.

stores/MobileNavStore.js

This stores the state of the mobileNav variable. If the variable is true, the mobile navigation panel containing the dropdown menu is displayed and vice versa.

This variable is used to control the display either the ‘burger’ or ‘close’ icon in the Navigation component.

Views – the templates go into the SPA router-view section

src/views/AdminView.vue

This page is to initalize the app before the first use or subsequent updates.

  • Set the snooker hourly rate.
  • Set / Change the wallet balance for Lung and Lam respectively.

src/views/HomeView.vue

This is the home page of the app.

  • As some values are from the local storage which are not reactive, so it is necessary to refresh this SPA (single page application) when the home view is called up by other views. The boolean with key ‘firstLoad’ in the Local Storage is used for this purpose.
  • At the ‘onMounted’ hook, check whether the SharerStore is using the dummy ‘local_sharers’ created by App.vue. If positive, the front end will display a message to request the user to go to the Admin page to initialize the app.
  • After the user has entered the required data and clicked the ‘Update Balance’ button, the script performs these operations:
    • Read in the ‘local_txHistory’ from Local Storage and assign it to ‘txHistory’ as an array of objects.
    • Append the new transaction to the ‘txHistory’ array.
    • If the length of txHistory is longer than the value in ‘keep’ variable, remove the older elements to keep the length.
    • Update the sharer balances in ShareStore.
    • Overwrite the ‘local_sharers’ in Local Storage by calling the updateLocalStore action in SharerStore.

src/views/LsHistory.vue

This displays the recent transaction history. The file reads the ‘local_txHistory’ from Local Storage and format it into an array for output to the front-end.

src/views/About.vue

Display the version number and provide a brief description of the app.

Site Address

To run the application, go to lets-share.innovriver.com

It is important to note that this site only download the code to the requesting device. All user data are kept locally on the device.

Source Code

The source code is located on the 32MB usb drive named ‘ESD-USB’. The use of usb drive is to allow development on any PC or Notebook that have Vue and other tools installed.

To build the production code for distribution, follow this procedure:

  • Remove the ‘dist’ directory, if any, in the project folder.
  • In a terminal open under the project folder, run “npm run build”.
    • this will rebuild the ‘dist’ folder from the latest source code.
  • Copy the files in ‘dist’ to the root of lets-share.innivriver.com, to replace existing files.
  • In a terminal of the web server, run www-chxy.sh to change permissions and ownerships.

Fix 404 Error after page refresh

SPA is not server side rendering. If the access is not through index.html, error 404 occurs. However, if the nav menu link is clicked, it will work due to the fact that the javascript got in action, but not the server side.

To solve this, use .htaccess and redirect all requests to index.html as follows:

<ifModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</ifModule>

Coming Phase 2

The proposed work for Phase 2 are:

  • To avoid the initialization step required for new devices, the presistence data storage will be moved from device’s Local Storage to the web server. The connection between devices and storage will through the REST APIs.
  • Convert this SPA application to an Android application.