Skip to content

Commit

Permalink
Create administration feature
Browse files Browse the repository at this point in the history
  • Loading branch information
Popovkov57 committed Sep 29, 2022
1 parent 3081847 commit d533154
Show file tree
Hide file tree
Showing 11 changed files with 155 additions and 11 deletions.
2 changes: 1 addition & 1 deletion authMiddleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ module.exports = function(req, res, next ) {
res.end();
return;
} else if ((((req.url.startsWith("/api/products") || req.url.startsWith("/products"))
||(res.url.startsWith("/api/categories") || req.url.startsWith("/categories"))) && req.method != "GET")
||(req.url.startsWith("/api/categories") || req.url.startsWith("/categories"))) && req.method != "GET")
||((req.url.startsWith("/api/orders") || req.url.startsWith("/orders")) && req.method != "POST")) {
let token = req.headers["authorization"];
if(token != null && token.startsWith("Bearer<")){
Expand Down
3 changes: 2 additions & 1 deletion data.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module.exports = function() {
{ id: 8, name: "Human Chess Board", category: "Chess", description: "A fun game for the family", price: 75 },
{ id: 9, name: "Bling Bling King", category: "Chess", description: "Gold-plated, diamond-studded King", price: 1200 }
],
orders: []
orders: [],
categories: ["Watersports", "Soccer", "Chess"]
}
}
29 changes: 27 additions & 2 deletions src/app/admin/admin.component.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,28 @@
<div class="bg-info p-2 text-white">
<h3>Placeholder for Admin Features</h3>
<div class="container-fluid">
<div class="row">
<div class="col bg-dark text-white">
<a class="navbar-brand">SPORTS STORE</a>
</div>
</div>
<div class="row mt-2">
<div class="col-3">
<div class="d-grid gap-2">
<button class="btn btn-outline-info btn-block"
routerLink="/admin/main/products" routerLinkActive="active">
Products
</button>
<button class="btn btn-outline-info btn-block"
routerLink="/admin/main/orders" routerLinkActive="active">
Orders
</button>
<button class="btn btn-outline-danger btn-block"
(click)="logout()">
Logout
</button>
</div>
</div>
<div class="col-9">
<router-outlet></router-outlet>
</div>
</div>
</div>
12 changes: 11 additions & 1 deletion src/app/admin/admin.component.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
import { Component } from "@angular/core";
import { Router } from "@angular/router";
import { AuthService } from "../model/auth.service";

@Component({
templateUrl: "admin.component.html"
})

export class AdminComponent {}
export class AdminComponent {

constructor(private auth: AuthService, private router: Router) {}

logout() {
this.auth.clear();
this.router.navigateByUrl("/");
}
}
15 changes: 13 additions & 2 deletions src/app/admin/admin.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,27 @@ import { RouterModule } from "@angular/router";
import { AuthComponent } from "./auth.component";
import { AdminComponent } from "./admin.component";
import { AuthGard } from "./auth.gard";
import { ProductTableComponent } from "./productTable.component";
import { ProductEditorComponent } from "./productEditor.component";
import { OrderTableComponent } from "./orderTable.component";

let routing = RouterModule.forChild([
{ path: "auth", component: AuthComponent },
{ path: "main", component: AdminComponent, canActivate: [AuthGard] },
{ path: "main", component: AdminComponent, canActivate: [AuthGard],
children: [
{ path: "products/:mode/:id", component: ProductEditorComponent },
{ path: "products/:mode", component: ProductEditorComponent },
{ path: "products", component: ProductTableComponent },
{ path: "orders", component: OrderTableComponent },
{ path: "**", redirectTo: "product" },
]
},
{ path: "**", redirectTo: "auth" },
])

@NgModule({
imports: [CommonModule, FormsModule, routing],
providers: [AuthGard],
declarations: [AuthComponent, AdminComponent]
declarations: [AuthComponent, AdminComponent, ProductEditorComponent, ProductTableComponent, OrderTableComponent]
})
export class AdminModule{}
7 changes: 7 additions & 0 deletions src/app/admin/orderTable.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Component } from "@angular/core";

@Component({
template: `<div class="bg-info p-2 text-white"><h3>Order Table placeholder</h3></div>`
})

export class OrderTableComponent {}
7 changes: 7 additions & 0 deletions src/app/admin/productEditor.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Component } from "@angular/core";

@Component({
template: `<div class="bg-info p-2 text-white"><h3>Product Editor placeholder</h3></div>`
})

export class ProductEditorComponent {}
7 changes: 7 additions & 0 deletions src/app/admin/productTable.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Component } from "@angular/core";

@Component({
template: `<div class="bg-info p-2 text-white"><h3>Product Table placeholder</h3></div>`
})

export class ProductTableComponent {}
28 changes: 26 additions & 2 deletions src/app/model/order.repository.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,44 @@
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";
import { Order } from "./order.model";
import { StaticDataSource } from "./static.datasource";
//import { StaticDataSource } from "./static.datasource";
import { RestDataSource } from "./rest.datasource";

@Injectable()
export class OrderRepository {

private orders: Order[] = [];
private loaded: boolean = false;

constructor(private dataSource: StaticDataSource) {}
constructor(private dataSource: RestDataSource) {}

loadOrders() {
this.loaded = true;
this.dataSource.getOrders().subscribe(o => {
this.orders = o;
});
}

getOrders(): Order[] {
if (!this.loaded) {
this.loadOrders();
}
return this.orders;
}

saveOrder(order: Order): Observable<Order> {
return this.dataSource.saveOrder(order);
}

updateOrder(order: Order) {
this.dataSource.updateOrder(order).subscribe(o => {
this.orders.splice(this.orders.findIndex(o => o.id = order.id), 1, order);
})
}

deleteOrder(id: number) {
this.dataSource.deleteOrder(id).subscribe(o => {
this.orders.splice(this.orders.findIndex(o => o.id == id), 1);
})
}
}
23 changes: 21 additions & 2 deletions src/app/model/product.repository.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { Injectable } from "@angular/core";
import { Product } from "./product.model";
import { StaticDataSource } from "./static.datasource";
//import { StaticDataSource } from "./static.datasource";
import { RestDataSource } from "./rest.datasource";

@Injectable()
export class ProductRepository {
private products: Product[] = [];
private categories: string[] = [];

constructor(private dataSource: StaticDataSource) {
constructor(private dataSource: RestDataSource) {
dataSource.getProducts().subscribe(data => {
this.products = data;
this.categories = data.map(p => p.category).filter((c, index, array) => array.indexOf(c) == index).sort();
Expand All @@ -25,4 +26,22 @@ export class ProductRepository {
getCategories(): string[] {
return this.categories;
}

saveProduct(product: Product) {
if (product.id == null || product.id == 0) {
this.dataSource.saveProduct(product).subscribe(p => this.products.push(p));
} else {
this.dataSource.updateProduct(product)
.subscribe(p => {
this.products.splice(this.products.
findIndex(p => p.id == product.id), 1, product);
});
}
}

deleteProduct(id: number) {
this.dataSource.deleteProduct(id).subscribe(p => {
this.products.slice(this.products.findIndex(p => p.id == id), 1);
});
}
}
33 changes: 33 additions & 0 deletions src/app/model/rest.datasource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Product } from "./product.model";
import { Cart } from "./cart.model";
import { Order } from "./order.model";
import { map } from "rxjs";
import { HttpHeaders } from "@angular/common/http";

const PROTOCOL = "http";
const PORT = 3500;
Expand Down Expand Up @@ -36,4 +37,36 @@ export class RestDataSource {
return response.success;
}))
}

saveProduct(product: Product): Observable<Product> {
return this.http.post<Product>(this.baseUrl + "products", product, this.getOptions());
}

updateProduct(product: Product): Observable<Product> {
return this.http.put<Product>(`${this.baseUrl}products/${product.id}`, product, this.getOptions());
}

deleteProduct(id: number): Observable<Product> {
return this.http.delete<Product>(`${this.baseUrl}products/${id}`, this.getOptions());
}

getOrders(): Observable<Order[]> {
return this.http.get<Order[]>(this.baseUrl + "orders", this.getOptions());
}

deleteOrder(id: number): Observable<Order> {
return this.http.delete<Order>(`${this.baseUrl}orders/${id}`, this.getOptions());
}

updateOrder(order: Order): Observable<Order> {
return this.http.put<Order>(`${this.baseUrl}order/${order.id}`, order, this.getOptions());
}

private getOptions() {
return {
headers: new HttpHeaders({
"Authotization": `Bearer<${this.auth_token}>`
})
}
}
}

0 comments on commit d533154

Please sign in to comment.