shop-challenge-vue
Shopper store is an application that lists shops near your by distance.
Project maintained by tmacharia
Hosted on GitHub Pages — Theme by mattgraham
Shopper Store
Shopper store is an application that lists shops near your by distance. It allows you to have your own personal list of favourite/preferred shops that you like for easier access rather than browsing through the entire collection all shops.
Table of Contents
Introduction
To adhere to the technical specifications of the challenge requiring the solution to be a single page application,
the application uses Vue.js in the front-end for routing & navigation between pages while the backend is written
in Asp.Net Core 2.2.1
Prerequisites
Below is a list of all the tools & developer resources required to get the project up and running.
Installation
To get the application started on your local machine, first clone this git repository by running the following command on a
terminal in a folder of your choice.
git clone https://github.com/tmacharia/shop-challenge-vue.git
Navigate to the cloned directory as follows by running cd shop-challenge-vue
Restore/Install Dependencies
First, let’s get all dependecies & npm packages installed by consecutively running the following commands
Packages Restore/Install
This command will run two commands, dotnet restore to restore all .NET nuget packages & npm install that will install all devDependencies needed as outlined in package.json
Build
We now need to generate the static resources i.e js,and css files that will be rendered by the browser and also build the .NET project (the backend) to ascertain that it builds successfully and therefore can run. There are two sets of scripts in package.json for building the project. Both will build the project & generate our static resources in our public folder wwwroot
Development Build
Builds the project in Debug mode and generates sitemaps for the static resources as you will see after running this command. You can checkout webpack.config.js to how we instruct webpack to generate our files in Development mode.
Production Build
Builds the project in Release mode, generates our static resources & optimizes them by applying UglifyJsPlugin to reduce the size of the output js files.
Database Seeding
To create database schemas & initial seed data to get our application up running, we need to apply the migrations in the 📁 Migrations folder.
Before you run the migrations, you need to confirm that the database ConnectionString is correct in appsettings.json. Make sure that is points to a valid instance of Microsoft SQL Server.
Command to apply migrations & seed initial data:
dotnet ef database update --verbose
That’s it! The application is now ready to run.
Running Application
Just run the following command on a terminal in the root directory of the project
The application will immediately start running:
http://locahost:5000
Application Features
- View Nearby Shops - access this on the main page or by navigating to either of the following paths on your browser: (
/shops
)
- Like Shop - like a shop so that it appears under My Preferred Shops for easy access & hidden from the main page.
- Dislike Shop - unfavourite a shop by disliking it so that it’s hidden from the mainpage for the next 2 hours.
- Remove Preferred Shop - deletes a shop from the list of My Preferred Shops and unhides from the mainpage. (
/shops/preferred
)
- User SignUp - allows users to signup/register an account using an email address, username & password. (
/account/signup
)
- User SignIn - allows already registered users to sign in to their account. (
/account/signin
)
Architecture
Frontend</h2>
Using vue.js, we modularize all our features/requirements into components with each having it's own folder as shown in the figure below.
```
📦ClientApp
┣ 📂components
┃ ┣ 📂account
┃ ┃ ┣ 📜account.css
┃ ┃ ┣ 📜account.ts
┃ ┃ ┣ 📜account.vue.html
┃ ┃ ┣ 📜signin.ts
┃ ┃ ┣ 📜signin.vue.html
┃ ┃ ┣ 📜signup.ts
┃ ┃ ┗ 📜signup.vue.html
┃ ┣ 📂app
┃ ┃ ┣ 📜app.ts
┃ ┃ ┗ 📜app.vue.html
┃ ┣ 📂navmenu
┃ ┃ ┣ 📜navmenu.css
┃ ┃ ┣ 📜navmenu.ts
┃ ┃ ┗ 📜navmenu.vue.html
┃ ┣ 📂preferred-shops
┃ ┃ ┣ 📜preferred-shops.ts
┃ ┃ ┗ 📜preferred-shops.vue.html
┃ ┣ 📂shops
┃ ┃ ┣ 📜shops.ts
┃ ┃ ┗ 📜shops.vue.html
┃ ┗ 📜cookiesHelper.ts
┣ 📂css
┃ ┗ 📜site.css
┗ 📜boot.ts
```
Routing
In _boot.ts_, which acts as the main entry point for our frontend application, we register routes for all our features that will instruct the browser what to render for what routes.
Backend</h2>
Server-side solution architecture, structure & organization.
Design Patterns & Principles
Below is a list of some of the design patterns, principles and best practises in accordance to the framework used (AspNet Core) & general software engineering guidelines:
1 [Inversion of Control Containers & Dependency Injection Pattern](https://martinfowler.com/articles/injection.html#InversionOfControl)
> Inversion of control is all about giving control to the container to get instance objects rather than creating objects using the **new operator**, let the container do that for you.
As you can see in the figure above, we are adding ShopDbContext to the default Asp.Net Core container so that it can be available to any controller at runtime.
We are also configuring Microsoft ASP.NET Core Identity Users model, Roles model, and the storage provider for these models. This will in turn avail identity interfaces, and other methods to use in user account membership & access control.
Let's now see how we use the added services in our controllers/Api Endpoints.
**Dependency Injection in AccountsController**
Here, we are using constructor injection to provide our controller with the services it requires which are already created/initialized by the DI container. This services are used in user account login & registration.
**Dependency Injection in ShopsController**
Here, we are also using contructor injection to avail this controller with ShopsDbContext from the DI container so that we access the list of registered shops in the database.
Contributing
Just fork this repository to get started.
>**N.B** Follow the project's current structure & methodologies when adding new features to enable consitency in throughout the project.
#### For Example:
Let's say you want to add a new feature, below are some guidelines to get you started:
1. Create a new page - by adding a new component in _ClientApp/components/{feature-name}/_. Remember to use a descriptive name that symbolizes what your feature does.
2. Add html, css, and Typescript file as it is in the other components.
3. Register route - add a route in _ClientApp/boot.ts_ that points to your component so users can access it.
4. If your feature does/requires some server processing, you may need to create a controller in _Controllers/_ folder and add the API endpoints you need. You can call your endpoints from the frontend in your Typescript file using Axios as it is the case _ClientApp/components/shops.ts_ component.
5. If you need a new database table, all schema definitions are in the _Models/_ folder, once you've added your new class, remember to add it to **ShopDbContext** class so that EntityFramework knows that a new table/migration should be generated.
Once you've made your updates; be it updates, fixes, or new feature developments, create a pull request and your changes will get reviewed and merged to master.
Author
Project written by Timothy Macharia
Incase of any questions, drop me an inbox at my
📧Email
Credits
This project is part of a coding challenge by United Remote