Skip to content

Commit

Permalink
Merge pull request #4 from Indexu/polishing
Browse files Browse the repository at this point in the history
Polishing
  • Loading branch information
Indexu authored Mar 11, 2017
2 parents bf6326b + 1a31031 commit 82b8850
Show file tree
Hide file tree
Showing 16 changed files with 412 additions and 112 deletions.
File renamed without changes.
90 changes: 89 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,90 @@
# Kyber
A storefront application using Angular 2

An Angular 2 REST storefront application.

## Features

* Sellers list
* Name and category listing
* Links to their own product page
* Add/Edit sellers through a modal
* Seller details
* Seller name, category and image
* Product listing in 2 tabs
* All products tab displays all of the seller's products
* Top 10 tab displays the seller's top selling products
* Responsive layout
* Toast notifications
* Unit tested
* 100% code coverage
* TSLint
* Conforms with the default TSLint configuration for Angular 2
* With the exception of us changing to double quotes
* Custom favicon
* This amazing README

## Getting Started

In order to run Kyber on your own machine, you will need [node.js](https://nodejs.org/en/download/) in order to use npm to install the dependencies and run the server.

### Prerequisites

#### Angular-CLI

Run the following command in order to start up the client.

```
$ sudo npm install -g angular-cli
```

#### Dependencies

Run the following command in the Kyber/src/client/ and Kyber/src/server/ folders.

```
$ npm install
```

### Running the server

You start up the server by running index.js, located in the Kyber/src/server/ directory, with node.
From the root directory of the project run the following command in your CLI.

```
$ node src/server/chatserver.js
```

Now the server is up and running on port 5000 by default.

### Starting up the client

You start up the client by using angular-cli
From the client folder of the project (Kyber/src/client/) run the following command in your CLI.

```
$ ng serve
```

Wait a bit while it starts up and afterwards the client is accessible via localhost:4200

### Development

We use the Angular-CLI as our build system which has webpack at it's core.

## Built With
* [Angular 2](https://angular.io/) - Framework
* [Bootstrap 4](https://material.angular.io/) ([ng-bootstrap](https://ng-bootstrap.github.io/)) - Styling and UI
* [Toastr](https://github.com/CodeSeven/toastr) ([ng2-toastr](https://github.com/PointInside/ng2-toastr)) - Toast notifications
* [ExpressJS](http://expressjs.com/) - Server
* [NPM](https://www.npmjs.com/) - Dependency Management
* [Jasmine](https://jasmine.github.io/) - Unit testing framework
* [Karma](https://karma-runner.github.io/) - Test runner

## Authors

* [Christian A. Jacobsen](https://github.com/ChristianJacobsen/)
* [Hilmar Tryggvason](https://github.com/Indexu/)

## License

This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details
33 changes: 19 additions & 14 deletions src/client/src/app/app.component.html
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
<!-- Header -->
<header>
<nav class="navbar navbar-inverse bg-primary">
<h1 class="navbar-brand mb-0 text-center"><span (click)="onHome()">{{title}}</span></h1>
</nav>
</header>
<!-- Main -->
<main>
<router-outlet></router-outlet>
</main>
<!-- Footer -->
<footer>

</footer>
<div class="wrapper">
<!-- Header -->
<header>
<nav class="navbar navbar-inverse bg-primary">
<h1 class="navbar-brand mb-0 text-center"><span (click)="onHome()">{{title}}</span></h1>
</nav>
</header>
<!-- Main -->
<main>
<router-outlet></router-outlet>
</main>
<!-- Footer -->
<footer class="navbar navbar-inverse bg-primary">
<span class="navbar-brand text-center ">
Made with <span class="text-danger">&hearts;</span> using
<a href="http://v4-alpha.getbootstrap.com/" class="text-info">Bootstrap 4</a>
</span>
</footer>
</div>
21 changes: 21 additions & 0 deletions src/client/src/app/app.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,24 @@ h1 {
h1>span {
cursor: pointer;
}

footer>span {
font-size: 1em;
}

.navbar-brand {
margin-right: 0;
}


/* Sticky footer */

.wrapper {
display: flex;
min-height: 100vh;
flex-direction: column;
}

main {
flex: 1;
}
149 changes: 84 additions & 65 deletions src/client/src/app/details/details.component.html
Original file line number Diff line number Diff line change
@@ -1,86 +1,105 @@
<div class="container mt-2">
<!-- Header -->
<div class="row">
<!-- Seller info -->
<div class="col-sm-12 col-lg-9">
<div class="row">
<!-- Image -->
<div class="col-sm-12 col-lg-6">
<img class="mx-auto d-block" src="{{ seller.imagePath }}" alt="seller image" />
</div>
<!-- Name and category -->
<div class="col-sm-12 col-lg-6">
<h3>{{ seller.name }}</h3>
<h4>{{ seller.category }}</h4>
</div>
<div *ngIf="notFound">
<div class="container">
<div class="row">
<div class="col-sm-12 text-center">
<h3 class="mt-2">404</h3>
<h5>Seller not found</h5>
</div>
</div>
<!-- Add product button -->
<div class="col-sm-12 col-lg-3">
</div>
</div>

<div *ngIf="!notFound" class="wrapper">
<!-- Header -->
<div class="mt-2 pb-2 seller">
<div class="container">
<div class="row">
<div class="col-md-12 col-lg-12">
<button type="button" class="btn btn-primary w-100" (click)="onAdd()">Add product</button>
<!-- Seller info -->
<div class="col-sm-12 col-lg-9">
<div class="row">
<!-- Image -->
<div class="col-sm-12 col-lg-6">
<img class="mx-auto d-block rounded" src="{{ seller.imagePath }}" alt="seller image" />
</div>
<!-- Name and category -->
<div class="col-sm-12 col-lg-6">
<h3>{{ seller.name }}</h3>
<h4>{{ seller.category }}</h4>
</div>
</div>
</div>
<!-- Add product button -->
<div class="col-sm-12 col-lg-3">
<div class="row">
<div class="col-md-12 col-lg-12">
<button type="button" class="btn btn-primary w-100" (click)="onAdd()">Add product</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- List -->
<div class="row mt-2">
<div *ngIf="products?.length > 0" class="col">
<ngb-tabset #t="ngbTabset">
<ngb-tab title="All products" id="allproducts">
<template ngbTabContent>
<div class="row">
<div class="col-sm-12 col-md-4 col-lg-3 mt-2" *ngFor="let product of products">
<div class="card">
<img *ngIf="product.imagePath" class="card-img-top" src="{{ product.imagePath }}" alt="Product image">
<div class="card-block">
<div class="row">
<div class="col-sm-7">
<h6 class="card-text">{{ product.name }}</h6>
</div>
<div class="col-sm-5">
<h6 class="card-text text-right">{{ product.price }} kr.</h6>
<div class="container pb-2">
<div class="row pt-2">
<div *ngIf="products?.length > 0" class="col">
<ngb-tabset #t="ngbTabset">
<ngb-tab title="All products" id="allproducts">
<template ngbTabContent>
<div class="row">
<div class="col-sm-12 col-md-4 col-lg-3 mt-2" *ngFor="let product of products">
<div class="card">
<img *ngIf="product.imagePath" class="card-img-top" src="{{ product.imagePath }}" alt="Product image">
<img *ngIf="!product.imagePath" class="card-img-top" src="../../assets/missing-image.png" alt="Product image">
<div class="card-block">
<div class="row">
<div class="col-sm-7">
<h6 class="card-text">{{ product.name }}</h6>
</div>
<div class="col-sm-5">
<h6 class="card-text text-right">{{ product.price }} kr.</h6>
</div>
</div>
<button type="button" class="btn btn-primary mt-2 w-100" (click)="onEdit(product.id)">Edit</button>
</div>
<button type="button" class="btn btn-primary mt-2 w-100" (click)="onEdit(product.id)">Edit</button>
</div>
</div>
</div>
</div>
</template>
</ngb-tab>
<ngb-tab id="topten">
<template ngbTabTitle>Top 10</template>
<template ngbTabContent>
<div class="row">
<div class="col-sm-12 col-md-4 col-lg-3 mt-2" *ngFor="let product of topProducts">
<div class="card">
<img *ngIf="product.imagePath" class="card-img-top" src="{{ product.imagePath }}" alt="Product image">
<div class="card-block">
<div class="row">
<div class="col-sm-7">
<h6 class="card-text">{{ product.name }}</h6>
</div>
<div class="col-sm-5">
<h6 class="card-text text-right">{{ product.price }} kr.</h6>
</template>
</ngb-tab>
<ngb-tab id="topten">
<template ngbTabTitle>Top 10</template>
<template ngbTabContent>
<div class="row">
<div class="col-sm-12 col-md-4 col-lg-3 mt-2" *ngFor="let product of topProducts">
<div class="card">
<img *ngIf="product.imagePath" class="card-img-top" src="{{ product.imagePath }}" alt="Product image">
<img *ngIf="!product.imagePath" class="card-img-top" src="../../assets/missing-image.png" alt="Product image">
<div class="card-block">
<div class="row">
<div class="col-sm-7">
<h6 class="card-text">{{ product.name }}</h6>
</div>
<div class="col-sm-5">
<h6 class="card-text text-right">{{ product.price }} kr.</h6>
</div>
</div>
<button type="button" class="btn btn-primary mt-2 w-100" (click)="onEdit(product.id)">Edit</button>
</div>
<button type="button" class="btn btn-primary mt-2 w-100" (click)="onEdit(product.id)">Edit</button>
</div>
</div>
</div>
</div>
</template>
</ngb-tab>
</ngb-tabset>
</div>
<div *ngIf="products?.length == 0" class="col">
<p>
<ngb-alert [dismissible]="false">
This seller has no products yet!
</ngb-alert>
</p>
</template>
</ngb-tab>
</ngb-tabset>
</div>
<div *ngIf="products?.length == 0" class="col">
<p>
<ngb-alert [dismissible]="false">
This seller has no products yet!
</ngb-alert>
</p>
</div>
</div>
</div>
</div>
Expand Down
8 changes: 8 additions & 0 deletions src/client/src/app/details/details.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,11 @@ img {
img.mx-auto {
border: 2px solid rgb(0, 0, 0);
}

.wrapper {
background-color: rgb(247, 247, 247);
}

.seller {
background-color: rgb(255, 255, 255);
}
7 changes: 4 additions & 3 deletions src/client/src/app/details/details.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ describe("DetailsComponent", () => {
// Assert
expect(component.products).toEqual([]);

var elem = fixture.debugElement.queryAll(By.css("p"))[0];
const elem = fixture.debugElement.queryAll(By.css("p"))[0];

expect(elem).toBeDefined();
});
Expand Down Expand Up @@ -283,15 +283,16 @@ describe("DetailsComponent", () => {
// No need to verify getProducts in this scope, since ngOnInit tests it
});

it("should not do anything if invalid id", () => {
it("should call toastr error if invalid id", () => {
// Arrange
const id = 1337;

// Act
component.onEdit(id);

// Assert
expect(mockToastr.success).toHaveBeenCalledTimes(0);
expect(mockToastr.error).toHaveBeenCalled();
expect(mockToastr.error).toHaveBeenCalledWith("Product not found", "Error");
});
});
});
Loading

0 comments on commit 82b8850

Please sign in to comment.