Browse Source

feedback table

master
Karan 3 years ago
parent
commit
27f6335565
  1. 19
      angular.json
  2. 5
      package.json
  3. 26
      src/app/app.module.ts
  4. 19
      src/app/pages/feedbacks/customer.ts
  5. 18
      src/app/pages/feedbacks/customerservice.ts
  6. 16
      src/app/pages/feedbacks/feedback.service.spec.ts
  7. 23
      src/app/pages/feedbacks/feedback.service.ts
  8. 156
      src/app/pages/feedbacks/feedbacks.component.html
  9. 97
      src/app/pages/feedbacks/feedbacks.component.scss
  10. 98
      src/app/pages/feedbacks/feedbacks.component.ts
  11. 2
      src/app/pages/home/home.component.html
  12. 6
      src/app/pages/home/home.component.ts
  13. 100
      src/assets/customers-large.json

19
angular.json

@ -26,12 +26,12 @@
"polyfills": "src/polyfills.ts", "polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json", "tsConfig": "tsconfig.app.json",
"inlineStyleLanguage": "scss", "inlineStyleLanguage": "scss",
"assets": [
"src/favicon.ico",
"src/assets"
],
"assets": ["src/favicon.ico", "src/assets"],
"styles": [ "styles": [
"src/styles.scss"
"src/styles.scss",
"node_modules/primeng/resources/themes/saga-blue/theme.css",
"node_modules/primeng/resources/primeng.min.css",
"node_modules/primeicons/primeicons.css"
], ],
"scripts": [] "scripts": []
}, },
@ -94,13 +94,8 @@
"tsConfig": "tsconfig.spec.json", "tsConfig": "tsconfig.spec.json",
"karmaConfig": "karma.conf.js", "karmaConfig": "karma.conf.js",
"inlineStyleLanguage": "scss", "inlineStyleLanguage": "scss",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.scss"
],
"assets": ["src/favicon.ico", "src/assets"],
"styles": ["src/styles.scss"],
"scripts": [] "scripts": []
} }
} }

5
package.json

@ -14,7 +14,8 @@
}, },
"private": true, "private": true,
"dependencies": { "dependencies": {
"@angular/animations": "~12.0.5",
"@angular/animations": "^12.0.5",
"@angular/cdk": "^13.0.2",
"@angular/common": "~12.0.5", "@angular/common": "~12.0.5",
"@angular/compiler": "~12.0.5", "@angular/compiler": "~12.0.5",
"@angular/core": "~12.0.5", "@angular/core": "~12.0.5",
@ -27,6 +28,8 @@
"cordova": "^10.0.0", "cordova": "^10.0.0",
"install": "^0.13.0", "install": "^0.13.0",
"npm": "^7.20.0", "npm": "^7.20.0",
"primeicons": "^5.0.0",
"primeng": "^13.0.0",
"rxjs": "~6.6.0", "rxjs": "~6.6.0",
"ts-jest": "^27.0.4", "ts-jest": "^27.0.4",
"tslib": "^2.1.0", "tslib": "^2.1.0",

26
src/app/app.module.ts

@ -1,5 +1,9 @@
import { NgModule } from '@angular/core';
import { BrowserModule, HammerModule, HAMMER_GESTURE_CONFIG } from '@angular/platform-browser';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import {
BrowserModule,
HammerModule,
HAMMER_GESTURE_CONFIG,
} from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { AppRoutingModule } from './app-routing.module'; import { AppRoutingModule } from './app-routing.module';
@ -19,7 +23,9 @@ import { HomeComponent } from './pages/home/home.component';
import { fakeBackendProvider, TokenInterceptor } from '../app/shared/helpers'; import { fakeBackendProvider, TokenInterceptor } from '../app/shared/helpers';
import { FeedbacksComponent } from './pages/feedbacks/feedbacks.component'; import { FeedbacksComponent } from './pages/feedbacks/feedbacks.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { TableModule } from 'primeng/table';
import { CustomerService } from './pages/feedbacks/customerservice';
@NgModule({ @NgModule({
declarations: [ declarations: [
@ -27,25 +33,29 @@ import { FeedbacksComponent } from './pages/feedbacks/feedbacks.component';
HeaderComponent, HeaderComponent,
LoginComponent, LoginComponent,
HomeComponent, HomeComponent,
FeedbacksComponent
FeedbacksComponent,
], ],
imports: [ imports: [
BrowserModule, BrowserModule,
BrowserAnimationsModule,
AppRoutingModule, AppRoutingModule,
FormsModule, FormsModule,
HttpClientModule, HttpClientModule,
ReactiveFormsModule
ReactiveFormsModule,
TableModule,
], ],
providers: [ providers: [
RouterService, RouterService,
HttpClientService, HttpClientService,
CustomerService,
// { // {
// provide: HTTP_INTERCEPTORS, // provide: HTTP_INTERCEPTORS,
// useClass: TokenInterceptor, // useClass: TokenInterceptor,
// multi: true // multi: true
// }, // },
fakeBackendProvider
fakeBackendProvider,
], ],
bootstrap: [AppComponent]
bootstrap: [AppComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
}) })
export class AppModule { }
export class AppModule {}

19
src/app/pages/feedbacks/customer.ts

@ -0,0 +1,19 @@
export interface Country {
name?: string;
code?: string;
}
export interface Representative {
name?: string;
image?: string;
}
export interface Customer {
id?: number;
name?: number;
country?: Country;
company?: string;
date?: string;
status?: string;
representative?: Representative;
}

18
src/app/pages/feedbacks/customerservice.ts

@ -0,0 +1,18 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Customer } from './customer';
@Injectable()
export class CustomerService {
constructor(private http: HttpClient) {}
getCustomersLarge() {
return this.http
.get<any>('assets/customers-large.json')
.toPromise()
.then((res) => <Customer[]>res.data)
.then((data) => {
return data;
});
}
}

16
src/app/pages/feedbacks/feedback.service.spec.ts

@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { FeedbackService } from './feedback.service';
describe('FeedbackService', () => {
let service: FeedbackService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(FeedbackService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

23
src/app/pages/feedbacks/feedback.service.ts

@ -0,0 +1,23 @@
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
const httpOptions = {
headers: new HttpHeaders({
Authorization:
'Bearer tfp_Ai5abXUjcSyNVzzBpXUzyd8cqZSeKu5ksLq5Ud59tof7_3pcoJHUpDFAiQp',
}),
};
const typeFromURL = 'https://api.typeform.com/forms/cBKZZuqO/responses';
@Injectable({
providedIn: 'root',
})
export class FeedbackService {
constructor(private http: HttpClient) {}
getFeedbackData(): Observable<any> {
return this.http.get(typeFromURL, httpOptions);
}
}

156
src/app/pages/feedbacks/feedbacks.component.html

@ -3,5 +3,159 @@
<app-header [headerInput]="headerProps"></app-header> <app-header [headerInput]="headerProps"></app-header>
</div> </div>
<main class="main-container">Feedback Code here</main>
<main class="main-container">
<p-table
#dt
[value]="customers"
[(selection)]="selectedCustomers"
dataKey="id"
styleClass="p-datatable-customers"
[rowHover]="true"
[rows]="10"
[showCurrentPageReport]="true"
[rowsPerPageOptions]="[10, 25, 50]"
[loading]="loading"
[paginator]="true"
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} entries"
[filterDelay]="0"
[globalFilterFields]="[
'name',
'country.name',
'representative.name',
'status'
]"
>
<ng-template pTemplate="caption">
<div class="table-header">
<span class="p-input-icon-left">
<input pInputText type="text" placeholder="Global Search" />
</span>
</div>
</ng-template>
<ng-template pTemplate="header">
<tr>
<th style="width: 3rem"></th>
<th pSortableColumn="name">
Name <p-sortIcon field="name"></p-sortIcon>
</th>
<th pSortableColumn="country.name">
Country <p-sortIcon field="country.name"></p-sortIcon>
</th>
<th pSortableColumn="representative.name">
Representative <p-sortIcon field="representative.name"></p-sortIcon>
</th>
<th pSortableColumn="date">
Date <p-sortIcon field="date"></p-sortIcon>
</th>
<th pSortableColumn="status">
Status <p-sortIcon field="status"></p-sortIcon>
</th>
<th pSortableColumn="activity">
Activity <p-sortIcon field="activity"></p-sortIcon>
</th>
<th style="width: 8rem"></th>
</tr>
<tr>
<th>
<input
pInputText
type="text"
placeholder="Search by Name"
class="p-column-filter"
/>
</th>
<th>
<input
pInputText
type="text"
placeholder="Search by Country"
class="p-column-filter"
/>
</th>
<th>
<p-multiSelect
[options]="representatives"
placeholder="All"
(onChange)="onRepresentativeChange($event)"
styleClass="p-column-filter"
optionLabel="name"
>
<ng-template let-option pTemplate="item">
<div class="p-multiselect-representative-option">
<span class="p-ml-1">{{ option.label }}</span>
</div>
</ng-template>
</p-multiSelect>
</th>
<th>
<p-calendar
(onSelect)="onDateSelect($event)"
(onClearClick)="dt.filter('', 'date', 'equals')"
[showButtonBar]="true"
styleClass="p-column-filter"
placeholder="Registration Date"
[readonlyInput]="true"
dateFormat="yy-mm-dd"
></p-calendar>
</th>
<th>
<p-dropdown
[options]="statuses"
styleClass="p-column-filter"
placeholder="Select a Status"
[showClear]="true"
>
<ng-template let-option pTemplate="item">
<span [class]="'customer-badge status-' + option.value"
>&#123;&#123;option.label&#125;&#125;</span
>
</ng-template>
</p-dropdown>
</th>
<th>
<input
pInputText
type="text"
(input)="onActivityChange($event)"
placeholder="Minimum"
class="p-column-filter"
/>
</th>
<th></th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-customer>
<tr class="p-selectable-row">
<td></td>
<td>
<span class="p-column-title">Name</span>
{{ customer.name }}
</td>
<td>
<span class="p-column-title">Country</span>
<span class="image-text">{{ customer.country.name }}</span>
</td>
<td>
<span class="p-column-title">Representative</span>
<span class="image-text">{{ customer.representative.name }}</span>
</td>
<td>
<span class="p-column-title">Date</span>
{{ customer.date }}
</td>
<td>
<span class="p-column-title">Status</span>
<span [class]="'customer-badge status-' + customer.status">{{
customer.status
}}</span>
</td>
</tr>
</ng-template>
<ng-template pTemplate="emptymessage">
<tr>
<td colspan="8">No customers found.</td>
</tr>
</ng-template>
</p-table>
</main>
</div> </div>

97
src/app/pages/feedbacks/feedbacks.component.scss

@ -0,0 +1,97 @@
:host ::ng-deep {
.p-paginator {
.p-paginator-current {
margin-left: auto;
}
}
.p-progressbar {
height: 0.5rem;
background-color: #d8dadc;
.p-progressbar-value {
background-color: #607d8b;
}
}
.table-header {
display: flex;
justify-content: space-between;
}
.p-calendar .p-datepicker {
min-width: 25rem;
td {
font-weight: 400;
}
}
.p-datatable.p-datatable-customers {
.p-datatable-header {
padding: 1rem;
text-align: left;
font-size: 1.5rem;
}
.p-paginator {
padding: 1rem;
}
.p-datatable-thead > tr > th {
text-align: left;
}
.p-datatable-tbody > tr > td {
cursor: auto;
}
.p-dropdown-label:not(.p-placeholder) {
text-transform: uppercase;
}
}
/* Responsive */
.p-datatable-customers .p-datatable-tbody > tr > td .p-column-title {
display: none;
}
}
@media screen and (max-width: 960px) {
:host ::ng-deep {
.p-datatable {
&.p-datatable-customers {
.p-datatable-thead > tr > th,
.p-datatable-tfoot > tr > td {
display: none !important;
}
.p-datatable-tbody > tr {
border-bottom: 1px solid var(--layer-2);
> td {
text-align: left;
display: block;
border: 0 none !important;
width: 100% !important;
float: left;
clear: left;
border: 0 none;
.p-column-title {
padding: 0.4rem;
min-width: 30%;
display: inline-block;
margin: -0.4rem 1rem -0.4rem -0.4rem;
font-weight: bold;
}
.p-progressbar {
margin-top: 0.5rem;
}
}
}
}
}
}
}

98
src/app/pages/feedbacks/feedbacks.component.ts

@ -1,6 +1,11 @@
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, ViewChild } from '@angular/core';
import { backButton, logOutButton } from 'src/app/constants/constants'; import { backButton, logOutButton } from 'src/app/constants/constants';
import IHeaderProps from 'src/app/models/header'; import IHeaderProps from 'src/app/models/header';
import { FeedbackService } from './feedback.service';
import { Customer, Representative } from './customer';
import { CustomerService } from './customerservice';
import { Table } from 'primeng/table';
import { PrimeNGConfig } from 'primeng/api';
@Component({ @Component({
selector: 'app-feedbacks', selector: 'app-feedbacks',
@ -16,7 +21,94 @@ export class FeedbacksComponent implements OnInit {
title: 'FEEDBACKS', title: 'FEEDBACKS',
}; };
constructor() {}
customers: Customer[];
ngOnInit(): void {}
selectedCustomers: Customer[];
representatives: Representative[];
statuses: any[];
loading: boolean = true;
@ViewChild('dt') table: Table;
constructor(
private feedbackService: FeedbackService,
private customerService: CustomerService,
private primengConfig: PrimeNGConfig
) {}
ngOnInit(): void {
this.feedbackService.getFeedbackData().subscribe(
(res) => {
console.log(res);
},
(err) => {
console.log(err);
}
);
this.customerService.getCustomersLarge().then((customers) => {
this.customers = customers;
this.loading = false;
});
this.representatives = [
{ name: 'Amy Elsner', image: 'amyelsner.png' },
{ name: 'Anna Fali', image: 'annafali.png' },
{ name: 'Asiya Javayant', image: 'asiyajavayant.png' },
{ name: 'Bernardo Dominic', image: 'bernardodominic.png' },
{ name: 'Elwin Sharvill', image: 'elwinsharvill.png' },
{ name: 'Ioni Bowcher', image: 'ionibowcher.png' },
{ name: 'Ivan Magalhaes', image: 'ivanmagalhaes.png' },
{ name: 'Onyama Limba', image: 'onyamalimba.png' },
{ name: 'Stephen Shaw', image: 'stephenshaw.png' },
{ name: 'XuXue Feng', image: 'xuxuefeng.png' },
];
this.statuses = [
{ label: 'Unqualified', value: 'unqualified' },
{ label: 'Qualified', value: 'qualified' },
{ label: 'New', value: 'new' },
{ label: 'Negotiation', value: 'negotiation' },
{ label: 'Renewal', value: 'renewal' },
{ label: 'Proposal', value: 'proposal' },
];
this.primengConfig.ripple = true;
}
onActivityChange(event: any) {
const value = event.target.value;
if (value && value.trim().length) {
const activity = parseInt(value);
if (!isNaN(activity)) {
this.table.filter(activity, 'activity', 'gte');
}
}
}
onDateSelect(value: any) {
this.table.filter(this.formatDate(value), 'date', 'equals');
}
formatDate(date: any) {
let month = date.getMonth() + 1;
let day = date.getDate();
if (month < 10) {
month = '0' + month;
}
if (day < 10) {
day = '0' + day;
}
return date.getFullYear() + '-' + month + '-' + day;
}
onRepresentativeChange(event: any) {
this.table.filter(event.value, 'representative', 'in');
}
} }

2
src/app/pages/home/home.component.html

@ -41,7 +41,7 @@
</section> </section>
<section> <section>
<button style="margin-top: 12rem" (click)="feedback()">Feedbacks</button>
<button style="margin-top: 10rem" (click)="feedback()">Feedbacks</button>
</section> </section>
<p class="error font-body-small">{{ error }}</p> <p class="error font-body-small">{{ error }}</p>

6
src/app/pages/home/home.component.ts

@ -23,7 +23,7 @@ export class HomeComponent {
headerProps: IHeaderProps = { headerProps: IHeaderProps = {
rightIcon: logOutButton, rightIcon: logOutButton,
rightIconRoute: 'logout', rightIconRoute: 'logout',
title: 'NPS EXPORTS VIEW',
title: 'NPS EXPORTS BU',
}; };
fileUploadForm: FormGroup; fileUploadForm: FormGroup;
@ -61,6 +61,7 @@ export class HomeComponent {
switchSalesServiceTab() { switchSalesServiceTab() {
this.submitButton = false; this.submitButton = false;
this.submitted = false;
this.removeSelectedFile(); this.removeSelectedFile();
this.isSalesForm = !this.isSalesForm; this.isSalesForm = !this.isSalesForm;
} }
@ -74,7 +75,7 @@ export class HomeComponent {
scenarioKey: '0A9B6D3A044E5EF5D38E688900202DD8', scenarioKey: '0A9B6D3A044E5EF5D38E688900202DD8',
destinations: messages, destinations: messages,
sms: { sms: {
text: 'Hi, Thank you. Bajaj Auto Test Message.',
text: 'Bajaj Auto Test Message. Feedback URL :' + feedbackURL,
regional: { regional: {
indiaDlt: { indiaDlt: {
contentTemplateId: '1107161477011893589', contentTemplateId: '1107161477011893589',
@ -159,6 +160,7 @@ export class HomeComponent {
addfile(event: any) { addfile(event: any) {
this.submitButton = true; this.submitButton = true;
this.submitted = false;
this.file = event.target.files[0]; this.file = event.target.files[0];
} }

100
src/assets/customers-large.json

@ -0,0 +1,100 @@
{
"data": [
{
"id": 1000,
"name": "James Butt",
"country": {
"name": "Algeria",
"code": "dz"
},
"company": "Benton, John B Jr",
"date": "2015-09-13",
"status": "unqualified",
"activity": 17,
"representative": {
"name": "Ioni Bowcher",
"image": "ionibowcher.png"
}
},
{
"id": 1001,
"name": "Josephine Darakjy",
"country": {
"name": "Egypt",
"code": "eg"
},
"company": "Chanay, Jeffrey A Esq",
"date": "2019-02-09",
"status": "proposal",
"activity": 0,
"representative": {
"name": "Amy Elsner",
"image": "amyelsner.png"
}
},
{
"id": 1002,
"name": "Art Venere",
"country": {
"name": "Panama",
"code": "pa"
},
"company": "Chemel, James L Cpa",
"date": "2017-05-13",
"status": "qualified",
"activity": 63,
"representative": {
"name": "Asiya Javayant",
"image": "asiyajavayant.png"
}
},
{
"id": 1000,
"name": "James Butt",
"country": {
"name": "Algeria",
"code": "dz"
},
"company": "Benton, John B Jr",
"date": "2015-09-13",
"status": "unqualified",
"activity": 17,
"representative": {
"name": "Ioni Bowcher",
"image": "ionibowcher.png"
}
},
{
"id": 1001,
"name": "Josephine Darakjy",
"country": {
"name": "Egypt",
"code": "eg"
},
"company": "Chanay, Jeffrey A Esq",
"date": "2019-02-09",
"status": "proposal",
"activity": 0,
"representative": {
"name": "Amy Elsner",
"image": "amyelsner.png"
}
},
{
"id": 1002,
"name": "Art Venere",
"country": {
"name": "Panama",
"code": "pa"
},
"company": "Chemel, James L Cpa",
"date": "2017-05-13",
"status": "qualified",
"activity": 63,
"representative": {
"name": "Asiya Javayant",
"image": "asiyajavayant.png"
}
}
]
}
Loading…
Cancel
Save