add promotion module

This commit is contained in:
Zuhdan Ubay 2020-05-18 05:18:30 +07:00
parent 49c95141d2
commit db8b04ae3f
19 changed files with 446 additions and 128 deletions

View file

@ -0,0 +1,30 @@
export interface PromotionList {
id: number;
customerType: string;
customerID: string;
code: string;
promotionType: string;
value?: number;
maximumDiscount: number;
maximumDiscountValue: number;
minimumOrderWeight: number;
minimumOrderAmount?: number;
quota: number;
maximumPerUser: number;
product: string;
paymentMethod: string;
deviceType: string;
description: string;
validDay: string;
validFrom: string;
validTo: string;
image: string;
lastUdpateTm: string;
status: number;
target: string;
coverage: string;
}
export interface RootObject {
promotionList: PromotionList[];
}

View file

@ -5,14 +5,8 @@ import { Component } from '@angular/core';
styleUrls: ['./footer.component.scss'],
template: `
<span class="created-by">
Created with by <b><a href="https://akveo.page.link/8V2f" target="_blank">Akveo</a></b> 2019
Created with by HQ-Teams @2020
</span>
<div class="socials">
<a href="#" target="_blank" class="ion ion-social-github"></a>
<a href="#" target="_blank" class="ion ion-social-facebook"></a>
<a href="#" target="_blank" class="ion ion-social-twitter"></a>
<a href="#" target="_blank" class="ion ion-social-linkedin"></a>
</div>
`,
})
export class FooterComponent {

View file

@ -5,18 +5,16 @@
</a>
<a class="logo" href="#" (click)="navigateHome()">symfonia</a>
</div>
<nb-select [selected]="currentTheme" (selectedChange)="changeTheme($event)" status="primary">
<nb-option *ngFor="let theme of themes" [value]="theme.value"> {{ theme.name }}</nb-option>
</nb-select>
</div>
<div class="header-container">
<nb-select [selected]="currentTheme" (selectedChange)="changeTheme($event)" status="primary">
<nb-option *ngFor="let theme of themes" [value]="theme.value"> {{ theme.name }}</nb-option>
</nb-select>
<nb-actions size="small">
<nb-action class="control-item">
<nb-search type="rotate-layout"></nb-search>
</nb-action>
<nb-action class="control-item" icon="email-outline"></nb-action>
<nb-action class="control-item" icon="bell-outline"></nb-action>
<nb-action class="user-action" *nbIsGranted="['view', 'user']" >
<nb-user [nbContextMenu]="userMenu"

View file

@ -3,43 +3,32 @@ import { NbMenuItem } from '@nebular/theme';
export const MENU_ITEMS: NbMenuItem[] = [
{
title: 'Service Agreement',
icon: 'shopping-cart-outline',
link: '/pages/dashboard',
home: true,
icon: 'edit-2-outline',
link: '/pages/tbd',
home: false,
},
{
title: 'Partner Price',
icon: 'shopping-cart-outline',
link: '/pages/dashboard',
home: true,
icon: 'keypad-outline',
link: '/pages/tbd',
home: false,
},
{
title: 'Billing',
icon: 'shopping-cart-outline',
link: '/pages/dashboard',
home: true,
link: '/pages/tbd',
home: false,
},
{
title: 'Promotion',
icon: 'shopping-cart-outline',
icon: 'map-outline',
link: '/pages/promotion',
home: true,
home: false,
},
{
title: 'Partner Branch',
icon: 'shopping-cart-outline',
link: '/pages/dashboard',
home: true,
},
{
title: 'E-commerce',
icon: 'shopping-cart-outline',
link: '/pages/dashboard',
home: true,
},
{
title: 'IoT Dashboard',
icon: 'home-outline',
link: '/pages/iot-dashboard',
icon: 'shuffle-2-outline',
link: '/pages/tbd',
home: false,
},
];

View file

@ -1,85 +1,21 @@
import { RouterModule, Routes } from '@angular/router';
import { NgModule } from '@angular/core';
import {RouterModule, Routes} from '@angular/router';
import {NgModule} from '@angular/core';
import { PagesComponent } from './pages.component';
import { DashboardComponent } from './dashboard/dashboard.component';
import { ECommerceComponent } from './e-commerce/e-commerce.component';
import { NotFoundComponent } from './miscellaneous/not-found/not-found.component';
import {PagesComponent} from './pages.component';
import {NotFoundComponent} from './miscellaneous/not-found/not-found.component';
import {PromotionComponent} from './promotion/promotion.component';
import {ServerExamplesComponent} from './sample/server-examples.component';
const routes: Routes = [{
path: '',
component: PagesComponent,
children: [
{
path: 'dashboard',
component: ECommerceComponent,
},
{
path: 'promotion',
component: PromotionComponent,
},
{
path: 'iot-dashboard',
component: DashboardComponent,
},
{
path: 'layout',
loadChildren: () => import('./layout/layout.module')
.then(m => m.LayoutModule),
},
{
path: 'forms',
loadChildren: () => import('./forms/forms.module')
.then(m => m.FormsModule),
},
{
path: 'ui-features',
loadChildren: () => import('./ui-features/ui-features.module')
.then(m => m.UiFeaturesModule),
},
{
path: 'modal-overlays',
loadChildren: () => import('./modal-overlays/modal-overlays.module')
.then(m => m.ModalOverlaysModule),
},
{
path: 'extra-components',
loadChildren: () => import('./extra-components/extra-components.module')
.then(m => m.ExtraComponentsModule),
},
{
path: 'maps',
loadChildren: () => import('./maps/maps.module')
.then(m => m.MapsModule),
},
{
path: 'charts',
loadChildren: () => import('./charts/charts.module')
.then(m => m.ChartsModule),
},
{
path: 'editors',
loadChildren: () => import('./editors/editors.module')
.then(m => m.EditorsModule),
},
{
path: 'tables',
loadChildren: () => import('./tables/tables.module')
.then(m => m.TablesModule),
},
{
path: 'miscellaneous',
loadChildren: () => import('./miscellaneous/miscellaneous.module')
.then(m => m.MiscellaneousModule),
},
{
path: '',
redirectTo: 'dashboard',
pathMatch: 'full',
},
{
path: '**',
path: 'tbd',
component: NotFoundComponent,
},
],

View file

@ -0,0 +1,12 @@
@import '../../../@theme/styles/themes';
@include nb-install-component() {
::ng-deep .form {
display: flex;
flex-direction: column;
.text-label {
margin-top: 1.5rem;
}
}
}

View file

@ -0,0 +1,22 @@
import { Component } from '@angular/core';
import { NbWindowRef } from '@nebular/theme';
@Component({
template: `
<form class="form">
<label for="subject">Subject:</label>
<input nbInput id="subject" type="text">
<label class="text-label" for="text">Text:</label>
<textarea nbInput id="text"></textarea>
</form>
`,
styleUrls: ['promotion-detail.component.scss'],
})
export class PromotionDetailComponent {
constructor(public windowRef: NbWindowRef) {}
close() {
this.windowRef.close();
}
}

View file

@ -4,7 +4,8 @@
</nb-card-header>
<nb-card-body>
<ng2-smart-table [settings]="settings" [source]="source" (deleteConfirm)="onDeleteConfirm($event)">
<ng2-smart-table [settings]="settings" [source]="source" (deleteConfirm)="onDeleteConfirm($event)"
(userRowSelect)="openWindowForm()">
</ng2-smart-table>
</nb-card-body>
</nb-card>
</nb-card>

View file

@ -1,15 +1,15 @@
import { Component } from '@angular/core';
import { LocalDataSource } from 'ng2-smart-table';
import { SmartTableData } from '../../@core/data/smart-table';
import { Component, OnInit } from '@angular/core';
import { PromotionList } from '../../@core/data/promotion';
import { PromotionService } from './promotion.service';
import { PromotionDetailComponent } from './promotion-detail/promotion-detail.component';
import { NbWindowService } from '@nebular/theme';
@Component({
selector: 'ngx-promotion',
templateUrl: './promotion.component.html',
styleUrls: ['./promotion.component.scss'],
})
export class PromotionComponent {
export class PromotionComponent implements OnInit {
settings = {
add: {
addButtonContent: '<i class="nb-plus"></i>',
@ -26,34 +26,36 @@ export class PromotionComponent {
confirmDelete: true,
},
columns: {
couponCode: {
code: {
title: 'Coupon Code',
type: 'string',
},
period: {
validDay: {
title: 'Period',
type: 'string',
},
validStart: {
validFrom: {
title: 'Valid Start',
type: 'string',
type: 'date',
},
validEnd: {
validTo: {
title: 'Valid End',
type: 'string',
},
action: {
title: 'Action',
type: 'string',
type: 'date',
},
},
};
source: LocalDataSource = new LocalDataSource();
source: PromotionList[] = [];
constructor(private service: SmartTableData) {
const data = this.service.getData();
this.source.load(data);
constructor(private service: PromotionService, private windowService: NbWindowService) {
}
ngOnInit(): void {
this.service.getPromotion().subscribe((result) => {
this.source = Object.assign([], result);
console.log(this.source);
});
}
onDeleteConfirm(event): void {
@ -63,4 +65,8 @@ export class PromotionComponent {
event.confirm.reject();
}
}
openWindowForm() {
this.windowService.open(PromotionDetailComponent, { title: `Promotion Detail` });
}
}

View file

@ -4,6 +4,8 @@ import { Ng2SmartTableModule } from 'ng2-smart-table';
import { ThemeModule } from '../../@theme/theme.module';
import { PromotionComponent } from './promotion.component';
import { PromotionService } from './promotion.service';
import { PromotionDetailComponent } from './promotion-detail/promotion-detail.component';
@NgModule({
imports: [
@ -16,6 +18,13 @@ import { PromotionComponent } from './promotion.component';
],
declarations: [
PromotionComponent,
PromotionDetailComponent,
],
providers: [
PromotionService,
],
entryComponents: [
PromotionDetailComponent,
],
})
export class PromotionModule { }

View file

@ -0,0 +1,49 @@
import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {Observable, throwError} from 'rxjs';
import {map, catchError} from 'rxjs/operators';
import {HttpErrorResponse, HttpHeaders} from '@angular/common/http';
import { PromotionList } from '../../@core/data/promotion';
@Injectable({
providedIn: 'root'
})
export class PromotionService {
constructor(private http: HttpClient) {
}
getPromotion(): Observable<any> {
const url = 'http://localhost:8011/api/promotions/all';
const headers = new HttpHeaders({
'Content-Type': 'application/json',
'X-Requested-Url': url,
'X-Requested-Method': 'GET',
});
const options = {headers: headers};
return this.http.get(url).pipe(
map(this.extractData),
catchError(this.handleError),
);
}
private extractData(body: any): PromotionList[] {
return Object.assign(body.promotionList);
}
private handleError(error: HttpErrorResponse | any) {
let errMsg: string;
let errObj: any;
if (error instanceof HttpErrorResponse) {
const err = error.message || JSON.stringify(error);
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
errObj = error.error.message;
} else {
errMsg = error.message ? error.message : error.toString();
const body = error.message || '';
errObj = body;
}
return throwError(errObj);
}
}

View file

@ -0,0 +1,36 @@
import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { ServerDataSource } from 'ng2-smart-table';
@Component({
selector: 'ngx-advanced-example-server',
styleUrls: ['./examples.component.scss'],
template: `
<ng2-smart-table [settings]="settings" [source]="source"></ng2-smart-table>
`,
})
export class AdvancedExampleServerComponent {
settings = {
columns: {
id: {
title: 'ID',
},
albumId: {
title: 'Album',
},
title: {
title: 'Title',
},
url: {
title: 'Url',
},
},
};
source: ServerDataSource;
constructor(http: HttpClient) {
this.source = new ServerDataSource(http, { endPoint: 'https://jsonplaceholder.typicode.com/photos' });
}
}

View file

@ -0,0 +1,45 @@
import { Component } from '@angular/core';
import { LocalDataSource } from 'ng2-smart-table';
import { BasicExampleLoadService } from './basic-example-load.service';
@Component({
selector: 'ngx-basic-example-load',
providers: [BasicExampleLoadService],
styleUrls: ['./examples.component.scss'],
template: `
<ng2-smart-table [settings]="settings" [source]="source"></ng2-smart-table>
`,
})
export class BasicExampleLoadComponent {
source: LocalDataSource;
settings = {
columns: {
id: {
title: 'ID',
editable: false,
addable: false,
},
name: {
title: 'Full Name',
},
username: {
title: 'User Name',
},
email: {
title: 'Email',
},
},
};
constructor(protected service: BasicExampleLoadService) {
this.source = new LocalDataSource();
this.service.getData().then((data) => {
this.source.load(data);
});
}
}

View file

@ -0,0 +1,34 @@
import { Injectable } from '@angular/core';
@Injectable()
export class BasicExampleLoadService {
static DATA_SIZE = 500;
// emulating request to the server
getData(): Promise<any> {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(this.generateData());
}, 2000);
});
}
getNewExampleObj(n?: number): any {
n = typeof n !== 'undefined' ? n : Math.random() * 1000;
return {
id: n,
name: `Jack London ${n}`,
username: `jack_london_${n}`,
email: `jack_london_${n}@example.com`,
};
}
protected generateData(): Array<any> {
const data = [];
for (let i = 0; i < BasicExampleLoadService.DATA_SIZE; i++) {
data.push(this.getNewExampleObj(i));
}
return data;
}
}

View file

@ -0,0 +1,65 @@
.with-sidebar {
position: relative;
.main-content-body {
padding-left: 16rem;
}
.fixed-sidebar {
display: block;
padding: 0 1rem;
margin-top: 2rem;
position: fixed;
top: 0;
padding-top: 290px;
width: 16rem;
font-size: 0.875rem;
.back-top {
display: none;
margin-bottom: 1rem;
font-weight: bold;
}
ul {
padding-left: 1rem;
list-style: none;
margin-bottom: 0.875rem;
}
&.scrolled {
position: fixed;
top: 0;
.back-top {
display: block;
}
}
.examples-menu {
a.active {
font-weight: bold;
}
}
}
}
@media screen and (max-width: 64em) {
.with-sidebar {
.fixed-sidebar {
display: none;
}
}
}
@media screen and (min-width: 42em) and (max-width: 64em) {
.with-sidebar {
padding: 2rem 4rem;
}
}
@media screen and (max-width: 42em) {
.with-sidebar {
padding: 2rem 1rem;
}
}

View file

@ -0,0 +1,19 @@
import {NgModule} from '@angular/core';
import {HttpClientModule} from '@angular/common/http';
import {ServerExamplesComponent} from './server-examples.component';
import {BasicExampleLoadComponent} from './basic-example-load.component';
import {AdvancedExampleServerComponent} from './advanced-example-server.component';
import {Ng2SmartTableModule} from 'ng2-smart-table';
@NgModule({
imports: [
HttpClientModule,
Ng2SmartTableModule,
],
declarations: [
ServerExamplesComponent,
BasicExampleLoadComponent,
AdvancedExampleServerComponent,
],
})
export class SampleModule { }

View file

@ -0,0 +1,17 @@
<h2>Get data from external source example</h2>
<h3><a id="from-server" class="anchor" href="#from-server" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Loading From Server Example</h3>
<p>
This example shows how to pass the data loaded from some API to the table DataSource.
</p>
<div class="with-source">
<ngx-basic-example-load></ngx-basic-example-load>
</div>
<h3><a id="server" class="anchor" href="#server" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Server Data Source Example</h3>
<p>
An example on how to load data user Server DataSource:
</p>
<div class="with-source">
<ngx-advanced-example-server></ngx-advanced-example-server>
</div>

View file

@ -0,0 +1,8 @@
import { Component } from '@angular/core';
@Component({
selector: 'ngx-server-examples',
styleUrls: ['./examples.component.scss'],
templateUrl: './server-examples.component.html',
})
export class ServerExamplesComponent { }

View file

@ -0,0 +1,48 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { LocalDataSource } from 'ng2-smart-table';
import { map } from 'rxjs/operators';
@Injectable()
export class CustomServerDataSource extends LocalDataSource {
lastRequestCount: number = 0;
constructor(protected http: HttpClient) {
super();
}
count(): number {
return this.lastRequestCount;
}
getElements(): Promise<any> {
let url = 'https://jsonplaceholder.typicode.com/photos?';
if (this.sortConf) {
this.sortConf.forEach((fieldConf) => {
url += `_sort=${fieldConf.field}&_order=${fieldConf.direction.toUpperCase()}&`;
});
}
if (this.pagingConf && this.pagingConf['page'] && this.pagingConf['perPage']) {
url += `_page=${this.pagingConf['page']}&_limit=${this.pagingConf['perPage']}&`;
}
if (this.filterConf.filters) {
this.filterConf.filters.forEach((fieldConf) => {
if (fieldConf['search']) {
url += `${fieldConf['field']}_like=${fieldConf['search']}&`;
}
});
}
return this.http.get(url, { observe: 'response' })
.pipe(
map(res => {
this.lastRequestCount = +res.headers.get('x-total-count');
return res.body;
}),
).toPromise();
}
}