Skip to content

Commit 190fd72

Browse files
committed
Initial commit
1 parent eceaeb9 commit 190fd72

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+248352
-0
lines changed

Angular2/ClientApp/app/app.module.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { NgModule } from '@angular/core';
2+
import { RouterModule } from '@angular/router';
3+
import { UniversalModule } from 'angular2-universal';
4+
import { AppComponent } from './components/app/app.component'
5+
import { NavMenuComponent } from './components/navmenu/navmenu.component';
6+
import { BooksComponent } from './components/books/books.component';
7+
import { CharacterComponent } from './components/characters/characters.component';
8+
import { AboutComponent } from './components/about/about.component';
9+
10+
@NgModule({
11+
bootstrap: [ AppComponent ],
12+
declarations: [
13+
AppComponent,
14+
NavMenuComponent,
15+
CharacterComponent,
16+
BooksComponent,
17+
AboutComponent
18+
],
19+
imports: [
20+
UniversalModule, // Must be first import. This automatically imports BrowserModule, HttpModule, and JsonpModule too.
21+
RouterModule.forRoot([
22+
{ path: '', redirectTo: 'books', pathMatch: 'full' },
23+
{ path: 'books', component: BooksComponent },
24+
{ path: 'characters', component: CharacterComponent },
25+
{ path: 'about', component: AboutComponent },
26+
{ path: '**', redirectTo: 'about' }
27+
])
28+
]
29+
})
30+
export class AppModule {
31+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<h1>Discworld Disorganiser</h1>
2+
3+
<div class="row">
4+
<div class="col-xs-12">
5+
<p>Welcome to the Discworld Disorganiser.</p>
6+
<p>This application is designed to be a book and character search engine interface for the Discworld series of books.</p>
7+
<p>To use this application, click on either 'Books' or 'Characters', these will take you to a search screen where you can search for a book or character within the Discworld series</p>
8+
</div>
9+
</div>
10+
11+
<h3>Technology Used</h3>
12+
<div class='row'>
13+
<div class='col-xs-12'>
14+
<p>This application runs on .NET Core and Angular2, with TypeScript compiled client-side scripting</p>
15+
<p>The search functionality is provided by my dwCheckApi project. The source code for dwCheckApi can be found <a href="https://github.com/GaProgMan/dwCheckApi" target="_blank">here</a></p>
16+
</div>
17+
</div>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { Component } from '@angular/core';
2+
import { Http } from '@angular/http';
3+
4+
@Component({
5+
selector: 'about',
6+
templateUrl: './about.component.html'
7+
})
8+
export class AboutComponent {
9+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
@media (max-width: 767px) {
2+
/* On small screens, the nav menu spans the full width of the screen. Leave a space for it. */
3+
.body-content {
4+
padding-top: 50px;
5+
}
6+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<div class='container-fluid'>
2+
<div class='row'>
3+
<div class='col-sm-3'>
4+
<nav-menu></nav-menu>
5+
</div>
6+
<div class='col-sm-9 body-content'>
7+
<router-outlet></router-outlet>
8+
</div>
9+
</div>
10+
</div>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { Component } from '@angular/core';
2+
3+
@Component({
4+
selector: 'app',
5+
templateUrl: './app.component.html',
6+
styleUrls: ['./app.component.css']
7+
})
8+
export class AppComponent {
9+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<h1>Book Search</h1>
2+
3+
<div class="row">
4+
<div class="col-xs-12">
5+
<input [value]="searchString" (input)="searchString = $event.target.value"/>
6+
<button (click)="getDwBook()">Search</button>
7+
</div>
8+
</div>
9+
10+
<div class="loader" *ngIf="loading">
11+
<p>Searching, please wait</p>
12+
</div>
13+
14+
<div class="table-responsive" *ngIf="!loading && books">
15+
<table class='table'>
16+
<thead>
17+
<tr>
18+
<th colspan="2">Cover</th>
19+
<th colspan="2">Name</th>
20+
<th>ISBN 10</th>
21+
<th>ISBN 13</th>
22+
<th>Description</th>
23+
</tr>
24+
</thead>
25+
<tbody>
26+
<tr *ngFor="let book of books">
27+
<td colspan="2"><img src="{{book.bookCoverImageUrl}}" class="img-responsive"/></td>
28+
<td colspan="2">{{ book.bookName }}</td>
29+
<td>{{ book.bookIsbn10 }}</td>
30+
<td>{{ book.bookIsbn13 }}</td>
31+
<td>{{ book.bookDescription }}</td>
32+
</tr>
33+
</tbody>
34+
</table>
35+
</div>
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import { Component } from '@angular/core';
2+
import { Http } from '@angular/http';
3+
4+
@Component({
5+
selector: 'books',
6+
templateUrl: './books.component.html'
7+
})
8+
export class BooksComponent {
9+
constructor(http: Http) {
10+
this.http = http;
11+
12+
this.loading = false;
13+
this.baseApiUrl = 'http://dwcheckapi-test.azurewebsites.net/Books/Search?searchString=';
14+
this.books = null;
15+
this.registerFunctions();
16+
}
17+
// private vars
18+
private http: Http;
19+
20+
// public bound vars
21+
success: boolean;
22+
loading: boolean;
23+
baseApiUrl: string;
24+
searchString = '';
25+
books: Book[];
26+
27+
// public functions
28+
getDwBook: () => void;
29+
30+
private registerFunctions() {
31+
this.getDwBook = () => {
32+
var route = `${this.baseApiUrl}${this.searchString}`;
33+
this.loading = true;
34+
this.http.get(route).subscribe((result) => {
35+
var resultJson = result.json() as ResultJson;
36+
if(resultJson.success) {
37+
this.books = new Array<Book>();
38+
result.json().result.forEach(element => {
39+
this.books.push(new Book(element.bookName, element.bookIsbn10,
40+
element.bookIsbn13, element.bookDescription,
41+
element.bookCoverImageUrl));
42+
});
43+
}
44+
this.loading = false;
45+
});
46+
}
47+
}
48+
}
49+
50+
interface ResultJson{
51+
success: boolean;
52+
result: string;
53+
}
54+
55+
class Book implements IBook {
56+
constructor(bookName: string, bookIsbn10: string, bookIsbn13:
57+
string, bookDescription: string, bookCoverImageUrl: string){
58+
this.bookName = bookName;
59+
this.bookIsbn10 = bookIsbn10;
60+
this.bookIsbn13 = bookIsbn13;
61+
this.bookDescription = bookDescription;
62+
this.bookCoverImageUrl = bookCoverImageUrl;
63+
}
64+
65+
bookName: string;
66+
bookIsbn10: string;
67+
bookIsbn13: string;
68+
bookDescription: string;
69+
bookCoverImageUrl: string;
70+
71+
72+
}
73+
74+
interface IBook {
75+
bookName: string;
76+
bookIsbn10: string;
77+
bookIsbn13: string;
78+
bookDescription: string;
79+
bookCoverImageUrl: string;
80+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<h1>Character Search</h1>
2+
3+
<div class="row">
4+
<div class="col-xs-12">
5+
<input [value]="searchString" (input)="searchString = $event.target.value"/>
6+
<button (click)="getDwCharacter()">Search</button>
7+
</div>
8+
</div>
9+
10+
<div class="loader" *ngIf="!success">
11+
<p>Could not find any results</p>
12+
</div>
13+
14+
<div class="table-responsive" *ngIf="success">
15+
<table class='table' *ngIf="characters">
16+
<thead>
17+
<tr>
18+
<th colspan="2">Name</th>
19+
<th>Books</th>
20+
</tr>
21+
</thead>
22+
<tbody>
23+
<tr *ngFor="let char of characters">
24+
<td colspan="2">{{ char.characterName }}</td>
25+
<td>{{ char.booksAsString() }}</td>
26+
</tr>
27+
</tbody>
28+
</table>
29+
</div>
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { Component } from '@angular/core';
2+
import { Http } from '@angular/http';
3+
4+
@Component({
5+
selector: 'characters',
6+
templateUrl: './characters.component.html'
7+
})
8+
export class CharacterComponent {
9+
constructor(http: Http) {
10+
this.http = http;
11+
12+
this.success = true;
13+
this.loading = false;
14+
this.baseApiUrl = 'http://dwcheckapi-test.azurewebsites.net/Characters/Search?searchString=';
15+
this.registerFunctions();
16+
}
17+
// private vars
18+
private http: Http;
19+
20+
// public bound vars
21+
success: boolean;
22+
loading: boolean;
23+
baseApiUrl: string;
24+
searchString = '';
25+
characters: ICharacter[];
26+
27+
// public functions
28+
getDwCharacter: () => void;
29+
30+
private registerFunctions() {
31+
this.getDwCharacter = () => {
32+
this.success = false;
33+
var route = `${this.baseApiUrl}${this.searchString}`;
34+
this.http.get(route).subscribe((result) => {
35+
var resultJson = result.json() as ResultJson;
36+
if(resultJson.success) {
37+
this.success = true;
38+
this.characters = new Array<ICharacter>();
39+
result.json().result.forEach(element => {
40+
this.characters.push(new Character(element.characterName, element.books));
41+
});
42+
}
43+
});
44+
}
45+
}
46+
}
47+
48+
interface ResultJson{
49+
success: boolean;
50+
result: string;
51+
}
52+
53+
class Character implements ICharacter {
54+
constructor(characterName: string, books: string[]){
55+
this.characterName = characterName;
56+
this.books = books;
57+
58+
this.booksAsString = (): string =>{
59+
return books.map(b => b).join(', ');
60+
}
61+
}
62+
characterName: string;
63+
books: string[];
64+
booksAsString: () => string;
65+
66+
67+
}
68+
69+
interface ICharacter {
70+
characterName: string;
71+
books: string[];
72+
73+
booksAsString:() => string;
74+
}

0 commit comments

Comments
 (0)