diff --git a/.env.example b/.env.example deleted file mode 100644 index b8bee57..0000000 --- a/.env.example +++ /dev/null @@ -1,4 +0,0 @@ -APP_TITLE='Lyduz | Free Stock Trading Platform' -APP_URL=http://localhost:6969 -API_URL=https://dev-api.lyduz.com/api -API_URL_BROWSER=https://dev-api.lyduz.com/api \ No newline at end of file diff --git a/.eslintrc b/.eslintrc index c75916e..625e863 100644 --- a/.eslintrc +++ b/.eslintrc @@ -30,6 +30,16 @@ ], "@typescript-eslint/indent": ["error", 2], "@typescript-eslint/member-delimiter-style": 0, - "@typescript-eslint/ban-ts-ignore": "off" - } + "@typescript-eslint/ban-ts-ignore": "error", + "@typescript-eslint/explicit-function-return-type": "off" // disable default + }, + "overrides": [ + { + // enable the rule specifically for TypeScript files + "files": ["*.ts", "*.tsx", "*.vue"], + "rules": { + "@typescript-eslint/explicit-function-return-type": ["error"] + } + } + ] } diff --git a/.gitignore b/.gitignore index 5e6f432..72ca799 100644 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,4 @@ hooks platforms # Root Variables -.env **/.DS_Store \ No newline at end of file diff --git a/README.md b/README.md index 1171337..be472da 100644 --- a/README.md +++ b/README.md @@ -1,49 +1,147 @@ -# NS Vue Typescript Sample +# Nitibo -> A native mobile application built with NativeScript-Vue in Typescript +#### A Nativescript-Vue Class Component Starter Template Using Module-Oriented Structure. -## Technologies +## Module-Oriented Structure -### NativeScript -A cross-platform Javascript platform that allows writing native (not hybrid) mobile apps -for iOS and Android using Javascript. +```bash +├── app +│ ├── App_Resources +│ ├── modules +│ │ ├── auth +│ │ │ ├── repository +│ │ │ │ ├── auth.api.ts +│ │ │ │ ├── auth.types.ts +│ │ │ │ └── index.ts +│ │ │ └── store +│ │ │ ├── actions.ts +│ │ │ ├── getters.ts +│ │ │ ├── index.ts +│ │ │ ├── mutations.ts +│ │ │ └── state.ts +│ │ ├── chart +│ │ │ ├── routes +│ │ │ │ └── index.ts +│ │ │ ├── store +│ │ │ └── views +│ │ │ ├── chart.vue +│ │ │ └── index.ts +│ │ ├── home +│ │ └── social +│ ├── repository +│ ├── router +│ ├── store +│ ├── App.vue +│ ├── main.ts +│ ├── package.json +│ └── styles.scss +├── types +│ ├── env.d.ts +│ ├── nativescript-vue.d.ts +│ └── vue-sfc.d.ts +├── .babelrc +├── .eslintignore +├── .eslintrc +├── .gitignore +├── .prettierrc +├── LICENSE +├── package-lock.json +├── package.json +├── README.md +├── tsconfig.esm.json +├── tsconfig.json +└── webpack.config.js +``` + +## The App/ Directory + +> The **App/** namespace is equvalent to **src/** in other Vue projects. The TSLINT reads files frim **App/** and **types** with the following extension: + +- \*.ts +- \*.tsx +- \*.vue +- \*.js + +### modules/ + +> The approach is inspired by Domain-Driven Design (DDD), to focus the structure on every feature (per modules). Each modules may contain the following sub-items: + +- routes/ - contains the modules' navigator route +- repository/ - contains the modules' API calls which extends the base API +- store/ - contains the modules' vuex store configurations +- views/ - contains the `view` of the application. The Component/ is also placed here for easy referencing -https://nativescript.org +### repository/ -### Vue JS -A modern Javascript frontend framework, strongly believing in single file components. +> Contains the base repository initiliazation. By default, the project uses REST API calls via axios -https://vuejs.org +### router/ -#### Vuex -Default state management framework for Vue (made by official maintainers of Vue JS) +> Injects all the declared routes in modules and inject to the Vue instance -https://vuex.vuejs.org/ +### store/ -### Typescript -A language developed by Microsoft that is a superset of Javascript ES2017 standard. -Adds the concept of strong types, interfaces to Javascript. Compiles down to Javascript. +> Injects all the declared modules store and inject to the Vue instance -https://typescriptlang.org +### App.vue -## Usage +> The main vue file -### Installing and Running -Here `` can be `android` or `ios` +### main.ts -``` bash -# Install dependencies -npm install -# -- or -- -yarn +> the main Typescript file -# Build, watch for changes and run the application -tns run --bundle +## The types/ Directory + +> This directory includes Typescript shims files for global and explicit parsing. E.g `env.d.ts` + +## Environmental Variables + +> Environment variables are set in the `webpack.config.js` file within the snippet below: + +```js +plugins: [ + // ... Vue Loader plugin omitted + // make sure to include the plugin! + new VueLoaderPlugin(), + // Define useful constants like TNS_WEBPACK + new webpack.DefinePlugin({ + "global.TNS_WEBPACK": "true", + "TNS_ENV": JSON.stringify(mode), + "TNS_API_URL": (mode === "production") ? JSON.stringify("https://jsonplaceholder.typicode.com") : JSON.stringify("https://jsonplaceholder.typicode.com"), + "process": "global.process" + }), + + ... ``` +> IMPORTANT: TNS_ENV returns mode `development or production`. This is important during builds. + +## Project Setup + +- Clone the project [nitibo master branch (latest stable release)](https://github.com/lyduz/nitibo) +- Confirm from your machine that nativescript is properly installed. Run `tns doctor` and see results +- `cd` to project and run `npm install` +- You may configure your emulators now for [android](https://docs.nativescript.org/tooling/android-virtual-devices) and [iOS](https://docs.nativescript.org/start/ns-setup-os-x) + +## Development Mode -### Debugging vs Production +- To start development with [android](https://www.android.com), run `npm run android` +- To start development with [iOS](https://developer.apple.com/ios/), run `npm run ios` +- Run the configured linter using `npm run lint` +- Run and fix the configure linter using `npm run lint-and-fix` +- Run vue devtools using `npx vue-devtools` and in another terminal, run the platform with the commands above (`npm run android or npm run ios`). Please follow this awesome guide from [nativescript-vue docs](https://nativescript-vue.org/en/docs/getting-started/vue-devtools/) +- You may use the default `tns` commands as usual (e.g `tns run android --bundle, tns run ios --bundle`) +- Append the `--device ` when using actual devices for [android](https://docs.nativescript.org/tooling/docs-cli/project/testing/run-android) and [iOS](https://docs.nativescript.org/tooling/docs-cli/project/testing/run-ios) + +## Production Mode (Docs WIP) + +- Publish your android application following this [guide](https://docs.nativescript.org/tooling/publishing/publishing-android-apps) +- Publish your iOS application following this [guide](https://docs.nativescript.org/tooling/publishing/publishing-ios-apps) + +## Debugging vs Production During usual run, project runs with following settings - + 1. Code is **not** minified 2. Vue.config.silent is false, so every component creation is logged @@ -60,3 +158,43 @@ tns build --bundle --env.production tns run --bundle --env.production ``` + +## Technologies Used + +- [Nativescript](https://nativescript.org) +- [VueJS](https://vuejs.org/) +- [Nativescript-Vue](https://nativescript-vue.org) +- [Nativesript-Vue-Navigator](https://github.com/nativescript-vue/nativescript-vue-navigator) +- [Typescript](https://typescriptlang.org/) +- [Vuex](https://vuex.vuejs.org/) +- [Vue-Class-Component](https://class-component.vuejs.org/) +- [Axios](https://github.com/axios/axios) for REST API + +## Issues + +> Please file issues to further improve this project here https://github.com/Lyduz/nitibo/issues + +- Major Issue: HRM run for checking linters. See https://github.com/Lyduz/nitibo/issues/7 + +## Pull Request + +> Contributions are the most welcome. To request changes, please follow the following: + +- Always branch out with a branch name format: `feature/*` for feature related changes or `bugfix/*` for bug related changes +- No direct push to master branch +- All changes are subject for reviews + +## TODO + +- Fix major issues [#7](https://github.com/Lyduz/nitibo/issues/7) +- Finish production documentation +- Non-breaking upgrade and up to date with latest nativescript core versions (both android and iOS) +- Documentation for optimization +- Preview support and documentation +- CI with TravisCI + +## Contributors ✨ +[![](https://avatars0.githubusercontent.com/u/38805756?s=90&u=96545a7174420f0ae00a9511c74e6ed74a9e5319&v=4)](https://github.com/kabaluyot) +[![](https://avatars3.githubusercontent.com/u/25500525?s=90&u=dca9d68091f2cde34fc93b3ca5cfe2a65d113dc0&v=4)](https://github.com/rttolipas) + +### Thank you so much to our contributors. diff --git a/app/main.ts b/app/main.ts index 186c686..5cd2c2a 100644 --- a/app/main.ts +++ b/app/main.ts @@ -1,18 +1,21 @@ import Vue from 'nativescript-vue' -// FIXME: run vue dev tools and enable -//import VueDevtools from 'nativescript-vue-devtools' -import Navigator from 'nativescript-vue-navigator' +import { VNode } from 'vue/types/umd' +// global dependency import routes from './router' import store from './store' +// main files import App from './App.vue' import './styles.scss' +import Navigator from 'nativescript-vue-navigator' +import VueDevtools from 'nativescript-vue-devtools' +// register global components Vue.use(Navigator, { routes }) if (TNS_ENV !== 'production') { - //Vue.use(VueDevtools); + Vue.use(VueDevtools) } // Prints Vue logs when --env.production is *NOT* set while building @@ -20,5 +23,5 @@ Vue.config.silent = TNS_ENV === 'production' new Vue({ store, - render: (h) => h(App), + render: (h): VNode => h(App), }).$start() diff --git a/app/modules/auth/repository/auth.api.ts b/app/modules/auth/repository/auth.api.ts new file mode 100644 index 0000000..b1147ab --- /dev/null +++ b/app/modules/auth/repository/auth.api.ts @@ -0,0 +1,38 @@ +import { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios' +import { API, Config } from '@/repository' +import { UserInterface } from './auth.types' + +/** + * AuthAPI class contains http requests for the auth module. + */ +class AuthAPI extends API { + /** + * @param {AxiosRequestConfig} config + * + * @return + */ + public constructor(config: AxiosRequestConfig) { + super(config) + } + + /** + * Get all users. + * + * @return {Promise} + */ + public async getUsers(): Promise { + return await this.get('/users') + .then((response: AxiosResponse) => { + const { data } = response + + const users: UserInterface[] = data + + return users + }) + .catch((error: AxiosError) => { + throw error + }) + } +} + +export const AuthRepository = new AuthAPI(Config) diff --git a/app/modules/auth/repository/auth.types.ts b/app/modules/auth/repository/auth.types.ts new file mode 100644 index 0000000..1801487 --- /dev/null +++ b/app/modules/auth/repository/auth.types.ts @@ -0,0 +1,14 @@ +interface UserAddressInterface { + readonly street: string + readonly suite: string +} + +export interface UserInterface { + readonly id: number + readonly name: string + readonly username: string + readonly email: string + readonly address: UserAddressInterface + readonly phone?: string + readonly website?: string +} diff --git a/app/modules/auth/repository/index.ts b/app/modules/auth/repository/index.ts new file mode 100644 index 0000000..00f8231 --- /dev/null +++ b/app/modules/auth/repository/index.ts @@ -0,0 +1 @@ +export { AuthRepository } from './auth.api' diff --git a/app/modules/auth/store/actions.ts b/app/modules/auth/store/actions.ts index ecf7430..56bb262 100644 --- a/app/modules/auth/store/actions.ts +++ b/app/modules/auth/store/actions.ts @@ -1,7 +1,7 @@ import { ActionTree } from 'vuex' import { State } from './state' -export const Actions: ActionTree = { +export const Actions: ActionTree void> = { setTitle(context, payload: string) { context.commit('SET_TITLE', payload) }, diff --git a/app/modules/auth/store/getters.ts b/app/modules/auth/store/getters.ts index 4933d6f..ef90c5a 100644 --- a/app/modules/auth/store/getters.ts +++ b/app/modules/auth/store/getters.ts @@ -1,7 +1,7 @@ import { GetterTree } from 'vuex' import { State } from './state' -export const Getters: GetterTree = { +export const Getters: GetterTree any> = { getTitle(State): string { return State.title }, diff --git a/app/modules/chart/store/actions.ts b/app/modules/chart/store/actions.ts index ecf7430..56bb262 100644 --- a/app/modules/chart/store/actions.ts +++ b/app/modules/chart/store/actions.ts @@ -1,7 +1,7 @@ import { ActionTree } from 'vuex' import { State } from './state' -export const Actions: ActionTree = { +export const Actions: ActionTree void> = { setTitle(context, payload: string) { context.commit('SET_TITLE', payload) }, diff --git a/app/modules/chart/store/getters.ts b/app/modules/chart/store/getters.ts index 4933d6f..ef90c5a 100644 --- a/app/modules/chart/store/getters.ts +++ b/app/modules/chart/store/getters.ts @@ -1,7 +1,7 @@ import { GetterTree } from 'vuex' import { State } from './state' -export const Getters: GetterTree = { +export const Getters: GetterTree any> = { getTitle(State): string { return State.title }, diff --git a/app/modules/chart/views/chart.vue b/app/modules/chart/views/chart.vue index e7d8c44..7fe6a4e 100644 --- a/app/modules/chart/views/chart.vue +++ b/app/modules/chart/views/chart.vue @@ -32,7 +32,7 @@ export default class Chart extends Vue { // data title = 'Chart Page' - mounted() { + mounted(): void { console.log(`Mounted: ${this.chart_get_title}`) } } diff --git a/app/modules/home/views/home.vue b/app/modules/home/views/home.vue index f231181..d63b714 100644 --- a/app/modules/home/views/home.vue +++ b/app/modules/home/views/home.vue @@ -18,12 +18,17 @@