This commit is contained in:
Le Deng
2017-03-05 16:32:16 -05:00
parent 3443fe428d
commit eaced98caf
26 changed files with 556 additions and 52 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -12,12 +12,26 @@ import { NavBarComponent } from './components/nav-bar/nav-bar.component';
import { LoginComponent } from './components/login/login.component';
import {LoginService} from './services/login.service';
import { AddNewBookComponent } from './components/add-new-book/add-new-book.component';
import {UploadImageService} from "./services/upload-image.service";
import {AddBookService} from "./services/add-book.service";
// import { BookListComponent } from './components/book-list/book-list.component';
import {GetBookListService} from "./services/get-book-list.service";
// import { ViewBookComponent } from './components/view-book/view-book.component';
import {GetBookService} from "./services/get-book.service";
// import { EditBookComponent } from './components/edit-book/edit-book.component';
import {EditBookService} from "./services/edit-book.service";
@NgModule({
declarations: [
AppComponent,
NavBarComponent,
LoginComponent
LoginComponent,
AddNewBookComponent,
// BookListComponent,
// BookListComponent,
// ViewBookComponent,
// EditBookComponent
],
imports: [
BrowserModule,
@@ -28,7 +42,12 @@ import {LoginService} from './services/login.service';
MaterialModule
],
providers: [
LoginService
LoginService,
UploadImageService,
AddBookService,
GetBookListService,
GetBookService,
EditBookService
],
bootstrap: [AppComponent]
})

View File

@@ -4,6 +4,10 @@
import {ModuleWithProviders} from '@angular/core';
import {Routes, RouterModule} from '@angular/router';
import {LoginComponent} from "./components/login/login.component";
import {AddNewBookComponent} from "./components/add-new-book/add-new-book.component";
// import {BookListComponent} from "./components/book-list/book-list.component";
// import {ViewBookComponent} from "./components/view-book/view-book.component";
// import {EditBookComponent} from "./components/edit-book/edit-book.component";
const appRoutes: Routes = [
{
@@ -14,7 +18,23 @@ const appRoutes: Routes = [
{
path: 'login',
component: LoginComponent
},
{
path: 'addNewBook',
component: AddNewBookComponent
}
// {
// path: 'editBook/:id',
// component: EditBookComponent
// },
// {
// path: 'bookList',
// component: BookListComponent
// },
// {
// path: 'viewBook/:id',
// component: ViewBookComponent
// }
];
export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);

View File

@@ -0,0 +1,177 @@
<div class="container">
<div class="row" [hidden]="bookAdded">
<div class="col s12">
<h3 style="margin-top: 30px;" class="center-align">New Book Information <span style="font-size: small"> * is a required field</span>
</h3>
<form class="col s12" (ngSubmit)="onSubmit()">
<div class="row">
<div class="input-field col s12">
<input id="title" type="text" class="validate" required [(ngModel)]="newBook.title" name="title">
<label for="title">* Title</label>
</div>
</div>
<div class="row">
<div class="input-field col s6">
<input id="author" type="text" class="validate" required [(ngModel)]="newBook.author" name="author">
<label for="author">* Author</label>
</div>
<div class="input-field col s6">
<input id="publisher" type="text" class="validate" [(ngModel)]="newBook.publisher" name="publisher">
<label for="publisher">Publisher</label>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<span class="grey-text">Publication Date
<input id="publicationDate" type="date" class="datepicker" [(ngModel)]="newBook.publicationDate"
name="publicationDate"></span>
</div>
</div>
<div class="row">
</div>
<div class="row">
<div class="input-field col s6">
<span class="grey-text">* Category</span>
<select class="browser-default" id="category" name="category" [(ngModel)]="newBook.category">
<option value="Management">Management</option>
<option value="Fiction">Fiction</option>
<option value="Engineering">Engineering</option>
<option value="Programming">Programming</option>
<option value="Arts &amp; Literature">Arts &amp; Literature</option>
</select>
</div>
<div class="input-field col s6">
<span class="grey-text">Format</span>
<select class="browser-default" id="format" name="format" [(ngModel)]="newBook.format">
<option value="paperback">Paperback</option>
<option value="hardcover">Hardcover</option>
</select>
</div>
</div>
<div class="row">
<div class="input-field col s6">
<input id="pageNumber" type="number" name="numberOfPages" class="validate" step="0.01"
[(ngModel)]="newBook.numberOfPages">
<label for="pageNumber">Number of Pages</label>
</div>
<div class="input-field col s6">
<input id="isbn" type="text" class="validate" [(ngModel)]="newBook.isbn" name="isbn">
<label for="isbn">* ISBN</label>
</div>
</div>
<div class="row">
<div class="input-field col s4">
$
<div class="input-field inline">
<input id="listPrice" type="number" name="listPrice" class="validate" step="0.01"
[(ngModel)]="newBook.listPrice">
<label for="listPrice">List Price</label>
</div>
</div>
<div class="input-field col s4">
$
<div class="input-field inline">
<input id="ourPrice" type="number" name="ourPrice" class="validate" step="0.01"
[(ngModel)]="newBook.ourPrice">
<label for="ourPrice">Our Price</label>
</div>
</div>
</div>
<div class="row">
<div class="input-field col s6">
<div class="input-field inline">
<input id="shippingWeight" type="number" name="shippingWeight" class="validate" step="0.01"
[(ngModel)]="newBook.shippingWeight">
<label for="shippingWeight">Shipping Weight</label>
</div>
ounces
</div>
<div class="input-field col s6">
<span class="grey-text">Language</span>
<select class="browser-default" id="language" name="language" [(ngModel)]="newBook.language">
<option value="english">English</option>
<option value="spanish">Spanish</option>
</select>
</div>
</div>
<div class="row">
<div class="input-field col s6">
<input id="inStockNumber" type="number" name="inStockNumber" class="validate" step="0.01"
[(ngModel)]="newBook.inStockNumber">
<label for="inStockNumber">Number In Stock</label>
</div>
<div class="input-field col s6">
<!-- Switch -->
<div class="switch" id="active">
<label>
Inactive
<input type="checkbox" [(ngModel)]="newBook.active" name="active">
<span class="lever"></span>
Active
</label>
</div>
</div>
</div>
<br/>
<div class="row">
<form class="col s12">
<div class="row">
<div class="input-field col s12">
<textarea id="description" class="materialize-textarea" [(ngModel)]="newBook.description"
name="description"></textarea>
<label for="description">Description</label>
</div>
</div>
</form>
</div>
<div class="row">
<div class="col s10">
<div class="file-field input-field">
<div class="btn">
<span>Image</span>
<input type="file" id="bookImage" name="bookImage"
(change)="uploadImageService.fileChangeEvent($event)"/>
</div>
<div class="file-path-wrapper">
<input class="file-path validate" type="text">
</div>
</div>
</div>
<div class="col s2">
<br/>
<!--<button type="button" (click)="uploadImageService.upload()" class="waves-effect waves-teal btn-flat">Upload</button>-->
</div>
</div>
<div class="row">
<div class="col s12">
<button type="submit" class="waves-effect waves-light btn blue darken-2 text-white">Add Book</button>
<a class="waves-effect waves-light btn red darken-2 text-white">Cancel</a>
</div>
</div>
</form>
</div>
</div>
<div class="row" [hidden]="!bookAdded">
<div class="col s12">
<h3>Book added successfully!</h3>
</div>
</div>
</div>

View File

@@ -0,0 +1,28 @@
/* tslint:disable:no-unused-variable */
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { AddNewBookComponent } from './add-new-book.component';
describe('AddNewBookComponent', () => {
let component: AddNewBookComponent;
let fixture: ComponentFixture<AddNewBookComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ AddNewBookComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AddNewBookComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,42 @@
import { Component, OnInit } from '@angular/core';
import {UploadImageService} from "../../services/upload-image.service";
import {AddBookService} from "../../services/add-book.service";
import {Book} from "../../models/book";
@Component({
selector: 'app-add-new-book',
templateUrl: './add-new-book.component.html',
styleUrls: ['./add-new-book.component.css']
})
export class AddNewBookComponent implements OnInit {
private newBook: Book = new Book();
private bookAdded: boolean;
constructor (private uploadImageService:UploadImageService, private addBookService:AddBookService) {}
onSubmit() {
this.addBookService.sendBook(this.newBook)
.subscribe(
data => {
this.uploadImageService.upload(JSON.parse(JSON.parse(JSON.stringify(data))._body).id);
this.bookAdded = true;
this.newBook = new Book();
this.newBook.active=true;
this.newBook.category="Management";
this.newBook.language="english";
this.newBook.format="paperback";
},
error => console.log(error)
);
}
ngOnInit() {
this.bookAdded=false;
this.newBook.active=true;
this.newBook.category="Management";
this.newBook.language="english";
this.newBook.format="paperback";
}
}

View File

@@ -1,3 +0,0 @@
.full-width {
width: 100%;
}

View File

@@ -1,33 +1,22 @@
<md-grid-list cols="6" [style.margin-top]="'20px'">
<md-grid-tile [colspan]="1"></md-grid-tile>
<md-grid-tile [colspan]="4">
<md-card style="width: 100%;">
<md-card-content>
<div [hidden]="loggedIn">
<form (ngSubmit)="onSubmit()" >
<h3>
<div class="container">
<div [hidden]="loggedIn">
<md-grid-list cols="6" [style.margin-top]="'20px'">
<md-grid-tile [colspan]="1"></md-grid-tile>
<md-grid-tile [colspan]="4">
<form (ngSubmit)="onSubmit()">
<md-input-container class="full-width">
<input type="text" mdInput [(ngModel)]="credential.username" name='username' id='username' placeholder="Your Username">
</md-input-container>
</h3>
<h3>
<md-input-container class="full-width">
<input type="password" mdInput [(ngModel)]="credential.password" name='password' id='password' placeholder="Your Password">
</md-input-container>
</h3>
<h3>
<div class='row'>
<button md-raised-button type="submit" class="primary" [style.color]="'white'">Login</button>
</div>
</h3>
</form>
</div>
<div [hidden]="!loggedIn">
<h2>You have logged in!</h2>
</div>
</md-card-content>
</md-card>
</md-grid-tile>
<md-grid-tile [colspan]="1"></md-grid-tile>
</md-grid-list>
<button class="mat-primary" md-raised-button type="submit" >Login</button>
</form>
</md-grid-tile>
<md-grid-tile [colspan]="1"></md-grid-tile>
</md-grid-list>
</div>
<div [hidden]="!loggedIn">
<h2>You have logged in!</h2>
</div>
</div>

View File

@@ -1,6 +1,5 @@
import { Component, OnInit } from '@angular/core';
import {LoginService} from "../../services/login.service";
import {CookieService} from "angular2-cookie/services/cookies.service";
@Component({
selector: 'app-login',
@@ -21,7 +20,7 @@ export class LoginComponent implements OnInit {
console.log(res);
localStorage.setItem("xAuthToken", res.json().token);
this.loggedIn=true;
// location.reload();
location.reload();
},
error=>{
this.loggedIn=false;

View File

@@ -1,4 +1,8 @@
<md-toolbar class="primary">
<md-toolbar class="mat-primary">
<h3 [style.color]="'white'">ADMIN PORTAL</h3>
<span class="example-spacer"></span>
</md-toolbar>
<span [hidden]="!loggedIn"><a md-button routerLink="/addNewBook" routerLinkActive="active">Add a Book</a></span>
<span [hidden]="!loggedIn"><a md-button routerLink="." (click)="logout()">Logout</a></span>
</md-toolbar>

View File

@@ -10,19 +10,6 @@ import {Router} from "@angular/router";
export class NavBarComponent implements OnInit {
private loggedIn = false;
foods = [
{value: 'steak-0', viewValue: 'Steak'},
{value: 'pizza-1', viewValue: 'Pizza'},
{value: 'tacos-2', viewValue: 'Tacos'}
];
tiles = [
{text: 'One', cols: 3, rows: 1, color: 'lightblue'},
{text: 'Two', cols: 1, rows: 2, color: 'lightgreen'},
{text: 'Three', cols: 1, rows: 1, color: 'lightpink'},
{text: 'Four', cols: 2, rows: 1, color: '#DDBDF1'},
];
constructor(private loginService: LoginService, private router: Router) { }
ngOnInit() {

View File

@@ -0,0 +1,18 @@
export class Book {
public id: number;
public title: string;
public author: string;
public publisher: string;
public publicationDate: string;
public language: string;
public category: string;
public numberOfPages: number;
public format: string;
public isbn: number;
public shippingWeight: number;
public listPrice: number;
public ourPrice: number;
public active: boolean;
public description: string;
public inStockNumber: number;
}

View File

@@ -0,0 +1,7 @@
export class User {
public id: number;
public firstName: string;
public lastName: string;
public username: string;
public password: string;
}

View File

@@ -0,0 +1,16 @@
/* tslint:disable:no-unused-variable */
import { TestBed, async, inject } from '@angular/core/testing';
import { AddBookService } from './add-book.service';
describe('AddBookService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [AddBookService]
});
});
it('should ...', inject([AddBookService], (service: AddBookService) => {
expect(service).toBeTruthy();
}));
});

View File

@@ -0,0 +1,19 @@
import { Injectable } from '@angular/core';
import {Headers, Http} from "@angular/http";
import {Book} from "../models/book";
@Injectable()
export class AddBookService {
constructor (private http: Http) {}
sendBook(book:Book) {
let url = "http://localhost:8181/book/add";
let headers1 = new Headers({
'Content-Type': 'application/json',
'x-auth-token' : localStorage.getItem("xAuthToken")
});
return this.http.post(url, JSON.stringify(book), {headers: headers1});
}
}

View File

@@ -0,0 +1,16 @@
/* tslint:disable:no-unused-variable */
import { TestBed, async, inject } from '@angular/core/testing';
import { EditBookService } from './edit-book.service';
describe('EditBookService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [EditBookService]
});
});
it('should ...', inject([EditBookService], (service: EditBookService) => {
expect(service).toBeTruthy();
}));
});

View File

@@ -0,0 +1,18 @@
import { Injectable } from '@angular/core';
import {Book} from "../models/book";
import {Http, Headers} from "@angular/http";
@Injectable()
export class EditBookService {
constructor (private http: Http) {}
sendBook(book:Book) {
let url = "http://localhost:8181/book/update";
let headers1 = new Headers({
'Content-Type': 'application/json',
'x-auth-token' : localStorage.getItem("xAuthToken")
});
return this.http.post(url, JSON.stringify(book), {headers: headers1});
}
}

View File

@@ -0,0 +1,16 @@
/* tslint:disable:no-unused-variable */
import { TestBed, async, inject } from '@angular/core/testing';
import { GetBookListService } from './get-book-list.service';
describe('GetBookListService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [GetBookListService]
});
});
it('should ...', inject([GetBookListService], (service: GetBookListService) => {
expect(service).toBeTruthy();
}));
});

View File

@@ -0,0 +1,16 @@
import { Injectable } from '@angular/core';
import {Http, Headers} from "@angular/http";
@Injectable()
export class GetBookListService {
constructor (private http: Http) {}
getBookList() {
let url = "http://localhost:8181/book/bookList";
let tokenHeader = new Headers ({
'x-auth-token' : localStorage.getItem("xAuthToken")
});
return this.http.get(url, {headers : tokenHeader});
}
}

View File

@@ -0,0 +1,16 @@
/* tslint:disable:no-unused-variable */
import { TestBed, async, inject } from '@angular/core/testing';
import { GetBookService } from './get-book.service';
describe('GetBookService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [GetBookService]
});
});
it('should ...', inject([GetBookService], (service: GetBookService) => {
expect(service).toBeTruthy();
}));
});

View File

@@ -0,0 +1,16 @@
import { Injectable } from '@angular/core';
import {Headers, Http} from "@angular/http";
@Injectable()
export class GetBookService {
constructor(private http: Http) { }
getBook(id:number) {
let url = "http://localhost:8181/book/"+id;
let tokenHeader = new Headers ({
'x-auth-token' : localStorage.getItem("xAuthToken")
});
return this.http.get(url, {headers : tokenHeader});
}
}

View File

@@ -0,0 +1,16 @@
/* tslint:disable:no-unused-variable */
import { TestBed, async, inject } from '@angular/core/testing';
import { UploadImageService } from './upload-image.service';
describe('UploadImageService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [UploadImageService]
});
});
it('should ...', inject([UploadImageService], (service: UploadImageService) => {
expect(service).toBeTruthy();
}));
});

View File

@@ -0,0 +1,58 @@
import { Injectable } from '@angular/core';
@Injectable()
export class UploadImageService {
filesToUpload: Array<File>;
constructor() {
this.filesToUpload = [];
}
upload(bookId: number) {
this.makeFileRequest("http://localhost:8181/book/add/image?id="+bookId, [], this.filesToUpload).then((result) => {
console.log(result);
}, (error) => {
console.error(error);
});
}
modify(bookId: number) {
console.log(this.filesToUpload);
if (this.filesToUpload!=null) {
this.makeFileRequest("http://localhost:8181/book/update/image?id=" + bookId, [], this.filesToUpload).then((result) => {
console.log(result);
}, (error) => {
console.error(error);
});
}
}
fileChangeEvent(fileInput: any){
this.filesToUpload = <Array<File>> fileInput.target.files;
}
makeFileRequest(url: string, params: Array<string>, files: Array<File>) {
return new Promise((resolve, reject) => {
var formData: any = new FormData();
var xhr = new XMLHttpRequest();
for(var i = 0; i < files.length; i++) {
formData.append("uploads[]", files[i], files[i].name);
}
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
console.log("image upload successful!");
} else {
reject(xhr.response);
}
}
}
xhr.open("POST", url, true);
// xhr.setRequestHeader("Authorization", "Bearer "+localStorage.getItem("token"));
xhr.setRequestHeader("x-auth-token", localStorage.getItem("xAuthToken") );
xhr.send(formData);
});
}
}

View File

@@ -9,7 +9,7 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<body class="mat-app-background">
<app-root>Loading...</app-root>
</body>
</html>

View File

@@ -18,6 +18,16 @@ body {
margin:0;
}
.container {
width:90%;
margin:auto;
}
.full-width {
width: 100%;
}
.primary {
background:#3175e2;
}
color:white;
}