Hello, this is my submession for turing challenge.
- Getting Started
- Project Tech Stack
- Folder Structure
- App Core
- Global Components
- PWA Support & Optimization
- API Improvement
- Guidelines
- Time Estimations
prerequisites:
- NodeJS version 10 or higher
- NPM
- @vue/cli-service
npm install
npm run serve
npm run build
npm run test:unit
npm run test:e2e
add --coverage
after any test command to see tests coverage
- Vue.js
- Vuex
- Vue Router
- Buefy
- Axios
- date-fns
- Vee Validate
- vue-awesome-swiper
- vue-content-loader
- vue-facebook-login-component
- vue-star-rating
- Jest
- NightmareJS
.
├── public
| |────── img/icons
├── src
| |────── assets
| | |────── fonts/webfonts
| | |────── images
| | |────── scss
| |────── components
| | |────── Authentication
| | |────── Footer
| | |────── Forms
| | |────── Home
| | |────── Navbar
| | |────── SingleProduct
| |────── constants
| |────── layouts
| |────── mixins
| |────── plugins
| |────── store
| | |────── modules
| |────── view
|
├── tests
| |────── unit
| | |────── components
| | |────── mixins
| | |────── views
| |────── e2e
| | |────── views
| | |────── components
├── LICENSE
└── README.md
src/mixins/asyncHelpers.js
The whole logic of fetching and sending data in this project built on the top of two major methods located in
- $_async_query
$_async_query(payload)
/**
* it takes only one parameter 'payload'
*/
payload: {
query: {
path: /* rest API path || action: # vuex action name */,
params: /* query params */
},
done: res => {} /* Done Callback status: 200 */,
unauthorized: res => {} /* unauthorized Callback status: 401 */
}
/**
* @return response comming from API
*/
- $_async_mutation
$_async_mutation(payload)
/* Payload Structure */
payload: {
mutation: {
path: /* rest API path || action: # vuex action name */,
method: /* request method (post, delete, ...etc) */,
variables: /* mutation variables */
},
done: res => {} /* Done Callback status: 200 */,
unauthorized: res => {} /* unauthorized Callback status: 401 */,
badRequest: res => {} /* bad request callback status: 400 */
/**
* notification callbacks, by default in each action * a default notification
* will be invoked but you can override it
* @return response comming from API
*/ ,
doneNtf: res => ({}),
badRequestNtf: res => ({}),
unauthorizedNtf: res => ({})
}
The idea of creating these two function comes from the fact that sometimes you may want to follow a different approach for every query in the case of being successful or not.
Example: In the case of a bad request (400 status) I automatically injected the
errors coming from the server into an object called server_errors
so
you do not have to worry about handling the errors you can access
errors anywhere using this.server_errors
you can consider them as a wrapper with callbacks
src/constants/rest_paths.js
I mapped the REST API into the constants objects. This way I have only one place to update if any updates happened to the REST API since some paths are repeated in different files.
I used the vuex module's mode in this project, for more details about that: https://vuex.vuejs.org/guide/modules.html
The Following Components registered globally, so you can use them everywhere
-
Confirm
-
Props
Name Type Parameters Default title String Confirm message String Continue on this task? cancelText String Disagree confirmText String Agree type String is-primary, is-info, is-success,
is-warning, is-danger, is-dark
is-textis-primary -
Events
Name Description accept emit when user agree the confirm
-
-
CustomButton
-
Props
Name Type Parameters Default type String outlined, outlined-fuchsia,
filled-white, filled-fuchsiafilled-fuchsia size String medium, large medium icon String loading Boolean false
-
-
LazylodaImage
-
Props
Name Type Parameters Default src String
-
This Application is a Progressive web app, PWA is:
- Fast
- Reliable
- Engaging
This App follows the App Shell Model, App Shell architecture
Progressive web apps bring the best from the web and the best from apps - Pete LePage
- All assets pre-cached and all API requests cached with network-and-cache strategy
- Activate Nginx Cache Control
- Activate Nginx gzip compression
- Chunks code spliting
- Prefetching, Preloading assets
- Defer unneeded scripts (for the inital load)
- Lazy loading for components
- Cart
what I noticed about the cart that there is no link between the cart and user, so if someone takes the cart_id he can checkout or edit someone else cart - Attributes
This is not about the attributes only, the API contains many routes to fetch critical data, for example, attributes values, according to the design, attributes name will never be fetched without its values, because of the two routes/attributes/{attribute_id}
and/attributes/values/{attribute_id}
I had to fetch the attributes first and wait for it its ids, then I had to fetch it one by one, I know may the reason is that the API is REST, but something like attributes must have values resolver
Generally, the API is awesome, but I wished if the API was a GraphQL one
I enrolled in this challenge since 34 days ago,
I spent 50 hours on this challenge in total
I missed 5 standups, but I wish you consider two things that forced me to miss the 5 standups and forced me to take 32 days:
- Currently, I am working on a company as a full-time web developer
- During this period, my father had heart issues and I had to spend some days with him in the hospital to take care of him.
I hope you consider my submission as I put an immense work in it. I hope you also understand my reasons for missing some of the standups and taking an extended time to finish this.
That's it!, this is the end!
Thanks for your time
Kamal Eddin Alhumsi @ 2019/20/9