Commit f18fe534 by amalk

10-07-2019

parents
# Editor configuration, see https://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
max_line_length = off
trim_trailing_whitespace = false
# See http://help.github.com/ignore-files/ for more about ignoring files.
# compiled output
/dist
/tmp
/out-tsc
# dependencies
/node_modules
# profiling files
chrome-profiler-events.json
speed-measure-plugin.json
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
# misc
/.sass-cache
/connect.lock
/coverage
/libpeerconnection.log
npm-debug.log
yarn-error.log
testem.log
/typings
# System Files
.DS_Store
Thumbs.db
# TangerineWeb
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 7.1.4.
## Development server
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
## Code scaffolding
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
## Build
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build.
## Running unit tests
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
## Running end-to-end tests
Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
## Further help
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"tangerine-web": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {
"@schematics/angular:component": {
"styleext": "sass"
}
},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/tangerine-web",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": [
"src/favicon-common.png",
"src/assets",
"src/firebase-messaging-sw.js",
"src/manifest.json"
],
"styles": [
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"node_modules/mapbox-gl/dist/mapbox-gl.css",
"node_modules/@mapbox/mapbox-gl-geocoder/lib/mapbox-gl-geocoder.css",
"node_modules/ngx-toastr/toastr.css",
"src/main.sass",
"src/styles.sass",
"src/obd-shared.sass",
"src/user-shared.sass"
],
"scripts": []
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
}
]
},
"staging": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.staging.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
}
]
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "tangerine-web:build"
},
"configurations": {
"production": {
"browserTarget": "tangerine-web:build:production"
},
"staging": {
"browserTarget": "tangerine-web:build:staging"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "tangerine-web:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.spec.json",
"karmaConfig": "src/karma.conf.js",
"styles": [
"src/styles.sass"
],
"scripts": [],
"assets": [
"src/favicon-common.png",
"src/assets"
]
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"src/tsconfig.app.json",
"src/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**"
]
}
}
}
},
"tangerine-web-e2e": {
"root": "e2e/",
"projectType": "application",
"prefix": "",
"architect": {
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "tangerine-web:serve"
},
"configurations": {
"production": {
"devServerTarget": "tangerine-web:serve:production"
}
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": "e2e/tsconfig.e2e.json",
"exclude": [
"**/node_modules/**"
]
}
}
}
}
},
"defaultProject": "tangerine-web"
}
const io = require('socket.io-client');
// Key params for auth
const SECRET = 'DVOOtItNDnkwugzgyVDmEUpllHjTgPrORQhq';
const CLIENT = 'Generic Client';
const CONTENT = 'application/json';
const SOCKET_HOST = 'https://test1-jido.nevaventures.com';
const SOCKET_PORT = 3000;
var count = 0;
var output_dict = [];
var final_output_dict = [];
var channel_list = [
'trips',
'users-count',
'drive-data',
'risk-category',
'os-wise-user-count',
'claims-count',
'user-drive-category',
'gender-based-count',
'age-wise-users-count'
];
var arguments_list = [];
// Header and hash algo
const HEADER = {
"alg" : "HS256",
"typ" : "jwt"
};
var token = "38ec7cb38bad5be62f1ae76f5b9a3e987467ff43";
var timestamp = Date.now();
var payload = {
"timestamp" : timestamp,
"client" : CLIENT,
"content" : CONTENT,
"bearer" : token
};
var jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6Imp3dCJ9.eyJ0aW1lc3RhbXAiOjE1MzQ3NTg3NDc1OTAsImNsaWVudCI6IkdlbmVyaWMgQ2xpZW50IiwiY29udGVudCI6ImFwcGxpY2F0aW9uL2pzb24iLCJiZWFyZXIiOiIzOGVjN2NiMzhiYWQ1YmU2MmYxYWU3NmY1YjlhM2U5ODc0NjdmZjQzIn0=.49f32cf8b40b2f55ee51ed9f003f20fffb6000e2075548238b2ef313c1af6d28"
// console.log(jwt);
var query = {
query:{
token: jwt
}
}
const socket = io(SOCKET_HOST+":"+SOCKET_PORT, query);
// console.dir(socket, {depth: 6, colors: true});
socket.on('connect', function() {
var sessionid = socket;
});
socket.on("disconnect", function(){
console.log("Server responded with error: client disconnected from server");
});
socket.on('trips', function(msg){
count += 1;
console.log(msg[0])
});
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts
const { SpecReporter } = require('jasmine-spec-reporter');
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./src/**/*.e2e-spec.ts'
],
capabilities: {
'browserName': 'chrome'
},
directConnect: true,
baseUrl: 'http://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function() {}
},
onPrepare() {
require('ts-node').register({
project: require('path').join(__dirname, './tsconfig.e2e.json')
});
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
}
};
\ No newline at end of file
import { AppPage } from './app.po';
describe('workspace-project App', () => {
let page: AppPage;
beforeEach(() => {
page = new AppPage();
});
it('should display welcome message', () => {
page.navigateTo();
expect(page.getTitleText()).toEqual('Welcome to tangerine-web!');
});
});
import { browser, by, element } from 'protractor';
export class AppPage {
navigateTo() {
return browser.get('/');
}
getTitleText() {
return element(by.css('app-root h1')).getText();
}
}
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/app",
"module": "commonjs",
"target": "es5",
"types": [
"jasmine",
"jasminewd2",
"node"
]
}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "tangerine-web",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
"private": true,
"dependencies": {
"@angular/animations": "^7.1.4",
"@angular/cdk": "^7.3.7",
"@angular/common": "~7.1.0",
"@angular/compiler": "~7.1.0",
"@angular/core": "~7.1.0",
"@angular/fire": "^5.1.2",
"@angular/forms": "~7.1.0",
"@angular/material": "^7.3.7",
"@angular/platform-browser": "~7.1.0",
"@angular/platform-browser-dynamic": "~7.1.0",
"@angular/router": "~7.1.0",
"@ng-bootstrap/ng-bootstrap": "^4.2.1",
"@ng-select/ng-select": "^2.19.0",
"@ngui/map": "^0.30.3",
"@types/googlemaps": "^3.30.19",
"bootstrap": "^4.3.1",
"core-js": "^2.5.4",
"crypto-js": "^3.1.9-1",
"d3": "^4.9.0",
"decode-google-map-polyline": "^1.0.1",
"firebase": "^5.9.3",
"jquery": "^3.4.1",
"mapbox-gl": "^0.54.0",
"md5": "^2.2.1",
"mydatepicker": "^2.6.6",
"ngx-mapbox-gl": "^3.3.0",
"ngx-toastr": "^10.0.4",
"rxjs": "~6.3.3",
"tslib": "^1.9.0",
"zone.js": "~0.8.26"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.11.0",
"@angular/cli": "~7.1.4",
"@angular/compiler-cli": "~7.1.0",
"@angular/language-service": "~7.1.0",
"@types/crypto-js": "^3.1.43",
"@types/d3": "^5.7.2",
"@types/jasmine": "~2.8.8",
"@types/jasminewd2": "~2.0.3",
"@types/mapbox-gl": "^0.51.10",
"@types/node": "~8.9.4",
"@types/socket.io-client": "^1.4.32",
"codelyzer": "~4.5.0",
"jasmine-core": "~2.99.1",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~3.1.1",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "~2.0.1",
"karma-jasmine": "~1.1.2",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "~5.4.0",
"ts-node": "~7.0.0",
"tslint": "~5.11.0",
"typescript": "~3.1.6"
}
}
<app-header *ngIf="hideHeader"></app-header>
<app-side-menu *ngIf="hideHeader"></app-side-menu>
<app-notification *ngIf="showNotif"></app-notification>
<app-push-notification *ngIf="showPushNotif"></app-push-notification>
<div class="content-wrapper" [ngClass]="{ 'full-container': !hideHeader, 'bg-lite': util.liteBg}">
<app-breadcrumb></app-breadcrumb>
<router-outlet (deactivate)="onDeactivate()" *ngIf='mapReady'></router-outlet>
<app-footer></app-footer>
</div>
\ No newline at end of file
@import "../styles.sass"
*
margin: 0
padding: 0
box-sizing: border-box
-moz-box-sizing: border-box
-webkit-box-sizing: border-box
-webkit-touch-callout: none
-webkit-user-select: none
-khtml-user-select: none
-moz-user-select: none
-ms-user-select: none
user-select: none
-webkit-tap-highlight-color: transparent
-webkit-overflow-scrolling: touch
.btn
-webkit-box-shadow: none!important
-moz-box-shadow: none!important
box-shadow: none!important
html, body
height: 100%
width: 100%
cursor: default
font-family: $openSansRegular
input
-webkit-user-select: text
ul li
list-style-type: none
ngui-map
height: 270px!important
select::-ms-expand
display: none
button:active,
button:visited,
button:focus,
button:hover
outline: none
button:active
top: 0 !important
.content-wrapper
width: 100%
padding-top: 69px
padding-left: 70px
overflow-y: hidden
overflow-x: hidden
position: relative
min-height: 100%
background-color: $pageBgColor
float: left
&.full-container
padding: 0
&.bg-lite
background-color: $white
padding-left: 0;
&.bg-dark
background-color: $pageBgColor
padding-left: 70px;
#not-found
position: absolute
top: 50%
left: 50%
transform: translateX(-50%) translateY(-50%)
text-align: center
.access-denied-title
font-size: 16px
font-weight: bold
.no-access-detail
font-size: 14px
.no-access-icon
background: url(#{$loaderPath}/accessdenied-illustration.png) center no-repeat
background-size: contain
width: 89px
height: 98px
margin: 0 auto 30px auto
font-weight: bold
.not-found-icon
background: url(#{$loaderPath}/404-illustration.svg) center no-repeat
background-size: contain
width: 196px
height: 140px
margin: 180px auto 30px auto
font-weight: bold
.maintainance-icon
background: url(#{$loaderPath}/Maint.gif) center no-repeat
background-size: contain;
margin: 50px auto 0 auto;
font-weight: bold;
max-width: 1200px;
min-height: 310px;
span
font-size: 20px
.goto-btn
display: block
background-color: #00b140
border-radius: 23px
color: #ffffff
width: 195px
margin: 0 auto
margin-top: 60px
.fs-18
font-size: 18px !important
input:focus
outline: none
button
position: relative
border: none
outline: none
&:active
top: 1px
.full-width-title
width: 100%!important
.unsubscribe-wrapper
padding-bottom: 90px;
.toast-message
left: 58%;
color: red;
.no-access-detail
width: 73%
margin: 0 auto;
display: block;
.unsubscribe-icon
background: url(#{$loaderPath}/unsubscribe-illustration.svg) center no-repeat
width: 89px;
height: 110px;
margin: 0 auto 30px auto;
font-weight: bold;
.unsubscribed-icon
background: url(#{$loaderPath}/unsubscribe-sucess-illustration.svg) center no-repeat
width: 89px;
height: 110px;
margin: 0 auto 30px auto;
font-weight: bold;
.subscribed-icon
background: url(#{$loaderPath}/subscribe-sucess-illustration.svg) center no-repeat
width: 89px;
height: 110px;
margin: 0 auto 30px auto;
font-weight: bold;
.button
width: 195px;
height: 46px;
border-radius: 23px;
border: solid 1px #00b140;
color: #00b140;
margin-top: 50px;
margin-bottom: 50px;
.unsubscribe-btn
background-color: #fff;
.subscribe-btn
margin-left: 20px;
.green-btn
background-color: #00b140;
color: #fff;
margin-left: 20px;
.loader
background: url(#{$loaderPath}/loader_new.gif) center no-repeat
position: absolute
top: 0
width: 100%
height: 100%
left: 0
z-index: 1060
-webkit-border-radius: 4px
-moz-border-radius: 4px
border-radius: 4px
&.pos-rel
position: relative
.txt-error
font-size: 15px
font-family: $openSansSemiBold
color: $errorColor
.txt-success
font-size: 15px
font-family: $openSansSemiBold
color: $blueViolet
#breadcrumd-container
.breadcrumb-list
cursor: pointer
padding: 18px 5px 10px 10px
margin-top: 10px
background-color: transparent
cursor: pointer
li
&:first-child
&:before
content: ""
&:before
content: ">>"
color: $lightBlack
padding: 0 9px 0 5px
a
font-family: $openSansSemiBold
font-size : 14px
color: $lightBlack
&:last-child
a
font-family: $openSansBold
select
input
cursor: default
.padding-30
padding-left: 30px!important
#lastChild
a
cursor: default
&:hover
text-decoration: none
.bold
font-family: $openSansBold !important
.semi-bold
font-family: $openSansSemiBold !important
import { TestBed, async } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule
],
declarations: [
AppComponent
],
}).compileComponents();
}));
it('should create the app', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app).toBeTruthy();
});
it(`should have as title 'tangerine-web'`, () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app.title).toEqual('tangerine-web');
});
it('should render title in a h1 tag', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain('Welcome to tangerine-web!');
});
});
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { AuthService } from '@shared/services/auth.service';
import { SessionService } from '@shared/services/session.service';
import { UtilityService } from '@shared/services/utility.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.sass']
})
export class AppComponent implements OnInit {
public hideHeader: boolean;
public ifLoggedIn: boolean = false;
public showNotif: boolean = false;
public showPushNotif: boolean;
public mapReady: boolean;
constructor(private _router: Router,
public util: UtilityService,
public session: SessionService,
private AuthService: AuthService) {
_router.events.subscribe((val) => {
this.ngOnInit();
});
let count = 0;
let mapInterval = setInterval(() => {
count++;
if (typeof google !== 'undefined') {
console.log('gapi is there', count)
this.mapReady = true;
clearInterval(mapInterval);
}
if (count >= 6000) {
console.log('gapi not is working');
this.mapReady = true;
clearInterval(mapInterval);
}
}, 10);
}
ngOnInit() {
// Remove booking header condition
this.hideHeader = (this._router.url === "/" || this._router.url === "/login" || this._router.url === "/support-login" || this._router.url === "/bookings") ? false : true;
if (this.AuthService.isUserAuthorized() && this._router.url !== "/bookings") {
this.showPushNotif = true;
} else {
this.showPushNotif = false;
}
}
onDeactivate() {
document.body.scrollTop = 0;
}
checkIFloggedIn() {
if (this.session.getValFromLocalStorage("authTokens")) {
this.ifLoggedIn = true;
}
}
}
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AngularFireMessagingModule } from '@angular/fire/messaging';
import { AngularFireModule } from '@angular/fire';
import { DashboardModule } from './dashboard/dashboard.module';
import { AuthModule } from './auth/auth.module';
import { RideHistoryModule } from './ride-history/ride-history.module';
import { SharedModule } from './shared/shared.module';
import { SupportModule } from './support/support.module';
import { UserModule } from './user/user.module';
import { UserCategoriesModule } from './user-categories/user-categories.module';
import { LiveMapModule } from './live-map/live-map.module';
import { ObdDashboardModule } from './obd-dashboard/obd-dashboard.module';
import { BookingModule } from "./booking/booking.module";
import { AUTH_PROVIDERS } from '@shared/services/auth-guard.service';
import { AUTH_USER_PROVIDERS } from '@shared/services/user-guard.service';
import { AppConstants } from './app.constants';
import { AppComponent } from './app.component';
import { NotFoundComponent } from './not-found/not-found.component';
import { NoAccessComponent } from './no-access/no-access.component';
import { BreadcrumbComponent } from './breadcrumb/breadcrumb.component';
import { environment } from '../environments/environment';
import { UnsubscribeComponent } from './unsubscribe/unsubscribe.component';
import { SubscribedComponent } from './subscribed.component';
import { UnsubscribedComponent } from './unsubscribed.component';
import { MaintainanceComponent } from './maintainance.component';
import {NgbModule} from '@ng-bootstrap/ng-bootstrap';
import { NgxMapboxGLModule } from 'ngx-mapbox-gl';
@NgModule({
declarations: [
AppComponent,
NotFoundComponent,
NoAccessComponent,
BreadcrumbComponent,
UnsubscribeComponent,
SubscribedComponent,
UnsubscribedComponent,
MaintainanceComponent
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule,
FormsModule,
ReactiveFormsModule,
DashboardModule,
AuthModule,
RideHistoryModule,
SharedModule,
SupportModule,
UserModule,
UserCategoriesModule,
LiveMapModule,
ObdDashboardModule,
BookingModule,
AngularFireMessagingModule,
AngularFireModule.initializeApp(environment.FIREBASE),
NgbModule.forRoot(),
NgxMapboxGLModule.withConfig({
accessToken: 'pk.eyJ1IjoiYW1hbC10ZWNod2FyZTEyMyIsImEiOiJjanhvOXVhZ3MwNHJxM2lzNzVob2NidzFzIn0.deBOPOjsOIZ_vmik6ZUfpQ', // Optionnal, can also be set per map (accessToken input of mgl-map)
geocoderAccessToken: 'TOKEN' // Optionnal, specify if different from the map access token, can also be set per mgl-geocoder (accessToken input of mgl-geocoder)
})
],
providers: [
AppConstants,
AUTH_PROVIDERS,
AUTH_USER_PROVIDERS
],
bootstrap: [AppComponent]
})
export class AppModule { }
<div id="login-container">
<div class="banner-section">
<div class="banner-image">
<div class="logo-wrapper">
<div class="logo"></div>
</div>
</div>
<div class="form-wrapper">
<form class="form-container" #loginForm="ngForm" (ngSubmit)="onSubmit(loginForm)" novalidate>
<span class="welcome-heading">Hello Admin</span><br>
<span class="tangerine-heading bold">Welcome to Jido Key Portal</span><br><br>
<input type="text" placeholder="Your Email ID" [(ngModel)]="username" name="username" autocomplete="off" [ngClass]="{ 'error-input': errorMsgUsername.length }" required/>
<label class="error">{{errorMsgUsername}}</label><br>
<input type="password" placeholder="Enter Password" [(ngModel)]="password" name="password" minlength="3" [ngClass]="{ 'error-input': errorMsg.length }" required/>
<label class="error">{{errorMsg}}</label><br>
<div class="progress-button">
<button type="submit" [disabled]="!loginForm.valid" [ngClass]="{ 'submit-disabled': !loginForm.valid }">Login
<span class="progress-admin-login">
<span id="progress-bar" class="progress-inner notransition" style="width: 0%; opacity: 0.3;"></span>
</span>
</button>
</div>
<br>
<a class="forgot-pass" (click)="gotoForgotPass()"> Forgot Password? </a>
<div class="loader loader-background" *ngIf="showLoader"></div>
</form>
</div>
<div>
</div>
@import "../../../styles.sass"
#login-container
width: 100%
height: 100%
margin: 0
padding: 0
z-index: 999
-webkit-font-smoothing: antialiased
-webkit-text-stroke-width: 0 !important
a:hover
text-decoration: none
.banner-section
position: relative
height: 100%
.banner-image
background: url(#{$supportAdminLogin}/bg-image.jpg) no-repeat
-webkit-background-size: 100% 100%
-moz-background-size: 100% 100%
-o-background-size: 100% 100%
background-size: 100% 100%
width: 100vw
height: 100vh
.logo-wrapper
width: 94px
height: 70px
padding: 21px 15px 15px
.logo
width: 103px;
height: 38px;
background: url(#{$loginPath}/login-forgot-logo.svg) no-repeat
position: absolute
background-size: contain
left: 2%
.form-wrapper
position: absolute
width: 41%
height: 50%
min-width: 497px
min-height: 470px
background-color: #ffffff
top: 22%
border-radius: 8px
left: 7%
padding: 50px
.form-container
text-align: center
.loader
&.loader-background
background-color: #ffffff
opacity: 0.5
.error
text-align: right
width: 95%
font-size: 14px
color: #f61818
max-width: 450px
.welcome-heading
font-size: 20px
margin-bottom: 10px
.tangerine-heading
font-size: 27px
input
margin: 10px 0 0 0
-webkit-appearance: none
border: 0
background-color: #ffffff
font-size: 15px
.progress-button
position: relative
overflow: hidden
display: inline-block
.progress-admin-login
background-color: red
.progress-inner
width: 0%
opacity: 0.3
transition: width 0.3s, opacity 0.3s
position: absolute
bottom: 0
left: 0
height: 100%
border-radius: 14px
background-color: #019737
input[type=email],input[type=password], input[type=text]
height: 40px
width: 95%
border-bottom: 1px solid #acacac
font-family: $openSansSemiBold
font-size: 14px
&.error-input
color: #f61818
border-bottom: 1px solid #f61818
input[type=submit], button
margin: 50px 0 35px 0
padding: 0 34px
border-radius: 14px
background: $green
color: $white
height: 30px
.forgot-pass
color: $blue
font-size: 14px
cursor: pointer
&:hover
opacity: 0.7
.submit-disabled
opacity: 0.5 !important
color: #ffffffab !important
@media only screen and (min-width: 1450px)
#login-container
.banner-section
.form-wrapper
.form-container
input[type=email],input[type=password], input[type=text]
max-width: 450px
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { AdminLoginComponent } from './admin-login.component';
describe('AdminLoginComponent', () => {
let component: AdminLoginComponent;
let fixture: ComponentFixture<AdminLoginComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ AdminLoginComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AdminLoginComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit, Input, ChangeDetectorRef, Inject, ViewEncapsulation } from '@angular/core';
import { NgForm } from '@angular/forms';
import { Router, ActivatedRoute } from "@angular/router";
import { DashboardPageComponent } from '../../dashboard/dashboard-page/dashboard-page.component';
import { AppComponent } from '../../app.component';
import { AppConstants } from '../../app.constants';
import { ApiService } from '@shared/services/api.service';
import { AuthService } from '@shared/services/auth.service';
import { SessionService } from '@shared/services/session.service';
import { FooterService } from "@shared/services/footer.service";
import { ApiWrapperService } from "@shared/services/api-wrapper.service";
import * as CryptoJS from 'crypto-js';
@Component({
selector: 'app-admin-login',
templateUrl: './admin-login.component.html',
styleUrls: ['./admin-login.component.sass']
})
export class AdminLoginComponent implements OnInit {
public username: string;
public password: string;
public user: string;
public showLoader: boolean = false;
public errorMsg: string = "";
public errorMsgUsername: string = "";
public documentHead: any;
public adminType: any;
public SECRET = 'DVOOtItNDnkwugzgyVDmEUpllHjTgPrORQhq';
constructor(private activatedRoute: ActivatedRoute,
public dashComp: DashboardPageComponent,
private _apiCallService: ApiService,
private _AppConstants: AppConstants,
private _apiWrapperService: ApiWrapperService,
@Inject(AppComponent) private parent: AppComponent,
private _SessionService: SessionService,
private _Router: Router,
public footer: FooterService,
private AuthService: AuthService,
private cdRef: ChangeDetectorRef) {
this.documentHead = document.getElementsByTagName('head')[0];
// this.changeFavicon();
// var now = new Date().getTime();
// if (document.getElementById("customStyleTag"))
// document.getElementById("customStyleTag").setAttribute("href", document.getElementById("customStyleTag").getAttribute("href") + "?t=" + now);
// if (document.getElementById("customScriptTag"))
// document.getElementById("customScriptTag").setAttribute("src", document.getElementById("customScriptTag").getAttribute("src") + "?t=" + now);
}
ngOnInit() {
if (this.AuthService.isUserAuthorized()) {
this.parent.showPushNotif = true;
this.cdRef.detectChanges();
this._Router.navigate(['/bookings']);
}
}
gotoForgotPass() {
this._Router.navigate(['/user/forgot_password']);
}
changeFavicon() {
let src = "";
if (this.user === "liteUser") {
src = AppConstants.FAVICONLITEPATH;
} else {
src = AppConstants.FAVICONPROPATH;
}
if (src) {
let link = document.createElement('link'),
oldLink = document.getElementById('dynamic-favicon');
link.id = 'dynamic-favicon';
link.rel = 'shortcut icon';
link.href = src;
if (oldLink) {
this.documentHead.removeChild(oldLink);
}
this.documentHead.appendChild(link);
}
}
onSubmit(loginForm: NgForm) {
var el = document.getElementById('progress-bar');
var oswidth = document.getElementById('progress-bar').offsetWidth;
var target_width = 100;
var id;
var router = this._Router;
if (loginForm.value.username && loginForm.value.password) {
loginForm.value.grant_type = "password";
loginForm.value.username = loginForm.value.username.trim();
loginForm.value.username = encodeURI(loginForm.value.username);
this.errorMsg = "";
this.errorMsgUsername = "";
this._apiCallService.adminlogin(loginForm.value)
.subscribe((data) => {
this.showLoader = false;
this._SessionService.setToLocalStorage("authTokens", JSON.stringify(data.data));
console.log(data)
AppConstants.VIEW_DASH = 'dashboard'
this.dashComp.setViews(AppConstants.VIEW_DASH)
console.log("jhgvjhgj")
this._apiCallService.getAdminDetails()
.subscribe((response) => {
this.user = AppConstants.USER_CATEGORY[response.data.company_access.toString()];
this.adminType = AppConstants.LOGIN_TYPE[response.data.role.toString()];
console.log(response.data.role, this.adminType)
let encryptAdmintype = CryptoJS.HmacSHA256(this.adminType, this.SECRET).toString(CryptoJS.enc.Hex);
this._SessionService.setToLocalStorage("Admintype", JSON.stringify(encryptAdmintype));
let encryptUser = { user: CryptoJS.HmacSHA256(this.user, this.SECRET).toString(CryptoJS.enc.Hex) };
this._SessionService.setToLocalStorage("userCategory", JSON.stringify(encryptUser));
this._Router.navigateByUrl('/bookings');
});
}, (error) => {
clearInterval(id);
switch (error.error.code) {
case -5003:
case -4000:
this.errorMsg = "";
this.errorMsgUsername = "Account not found";
break;
case -2101:
this.errorMsgUsername = "";
this.errorMsg = error.error.message
break;
}
});
} else {
this.errorMsgUsername = (!loginForm.value.username || loginForm.value.username.length === 0) ? "Please enter a valid email id" : "";
this.errorMsg = (!loginForm.value.password || loginForm.value.password.length === 0) ? "Please enter a valid password" : "";
}
}
}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { SharedModule } from "@shared/shared.module";
import { LoginComponent } from './login/login.component';
import { DashboardPageComponent } from '../dashboard/dashboard-page/dashboard-page.component';
import { AdminLoginComponent } from './admin-login/admin-login.component';
@NgModule({
declarations: [LoginComponent, AdminLoginComponent],
imports: [
CommonModule,
FormsModule,
SharedModule
],
exports: [LoginComponent, AdminLoginComponent],
providers: [ DashboardPageComponent ]
})
export class AuthModule { }
<div id="login-container">
<div class="banner-section">
<div class="banner-image">
<div class="logo-wrapper">
<div class="logo"></div>
</div>
</div>
<div class="form-wrapper">
<form class="form-container" #loginForm="ngForm" (ngSubmit)="onSubmit(loginForm)" novalidate>
<span class="welcome-heading">Hello Admin</span><br>
<span class="tangerine-heading bold">Welcome to Tangerine Dashboard</span><br><br>
<input type="text" placeholder="Your Email ID" [(ngModel)]="username" name="username" autocomplete="off" [ngClass]="{ 'error-input': errorMsgUsername.length }" required/>
<label class="error">{{errorMsgUsername}}</label><br>
<input type="password" placeholder="Enter Password" [(ngModel)]="password" name="password" minlength="3" [ngClass]="{ 'error-input': errorMsg.length }" required/>
<label class="error">{{errorMsg}}</label><br>
<div class="progress-button">
<button type="submit" [disabled]="!loginForm.valid" [ngClass]="{ 'submit-disabled': !loginForm.valid }">Login
<span class="progress-login">
<span id="progress-bar" class="progress-inner notransition" style="width: 0%; opacity: 0.3;"></span>
</span>
</button>
</div>
<br>
<a class="forgot-pass" (click)="gotoForgotPass()"> Forgot Password? </a>
<div class="loader loader-background" *ngIf="showLoader"></div>
</form>
</div>
<div>
</div>
@import "../../../styles.sass"
#login-container
width: 100%
height: 100%
margin: 0
padding: 0
z-index: 999
a:hover
text-decoration: none
.banner-section
position: relative
height: 100%
.banner-image
background: url(#{$loginPath}/bg-image.png) no-repeat
-webkit-background-size: 100% 100%
-moz-background-size: 100% 100%
-o-background-size: 100% 100%
background-size: 100% 100%
width: 100vw
height: 100vh
.logo-wrapper
width: 94px
height: 70px
padding: 15px
.logo
width: 103px;
height: 38px;
background: url(#{$loginPath}/login-forgot-logo.svg) no-repeat
position: absolute
background-size: contain
left: 2%
.form-wrapper
position: absolute
width: 41%
height: 50%
min-width: 400px
min-height: 470px
background-color: #ffffff
top: 22%
border-radius: 5px
left: 7%
padding: 50px
.form-container
text-align: center
.loader
&.loader-background
background-color: #ffffff
opacity: 0.5
.error
text-align: right
width: 95%
font-size: 14px
color: #f61818
max-width: 450px
.welcome-heading
font-size: 20px
margin-bottom: 10px
.tangerine-heading
font-size: 27px
input
margin: 10px 0 0 0
-webkit-appearance: none
border: 0
background-color: #ffffff
font-size: 15px
.progress-button
position: relative
overflow: hidden
display: inline-block
.progress-login
background-color: red
.progress-inner
width: 0%
opacity: 0.3
transition: width 0.3s, opacity 0.3s
position: absolute
bottom: 0
left: 0
height: 100%
border-radius: 14px
background-color: #019737
input[type=email],input[type=password], input[type=text]
height: 40px
width: 95%
border-bottom: 1px solid #acacac
&.error-input
color: #f61818
border-bottom: 1px solid #f61818
input[type=submit], button
margin: 15px 0 15px 0
padding: 0 34px
border-radius: 14px
background: $green
color: $white
height: 30px
.forgot-pass
color: $blue
font-size: 14px
cursor: pointer
&:hover
opacity: 0.7
.submit-disabled
opacity: 0.5 !important
color: #ffffffab !important
@media only screen and (min-width: 1450px)
#login-container
.banner-section
.form-wrapper
.form-container
input[type=email],input[type=password], input[type=text]
max-width: 450px
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { LoginComponent } from './login.component';
describe('LoginComponent', () => {
let component: LoginComponent;
let fixture: ComponentFixture<LoginComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ LoginComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(LoginComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit, Input, ChangeDetectorRef, Inject, ViewEncapsulation } from '@angular/core';
import { NgForm } from '@angular/forms';
import { Router } from "@angular/router";
import { DashboardPageComponent } from '../../dashboard/dashboard-page/dashboard-page.component';
import { AppComponent } from '../../app.component';
import { AppConstants } from '../../app.constants';
import { ApiService } from '@shared/services/api.service';
import { AuthService } from '@shared/services/auth.service';
import { SessionService } from '@shared/services/session.service';
import * as CryptoJS from 'crypto-js';
import { isNullOrUndefined } from 'util';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.sass'],
encapsulation: ViewEncapsulation.None
})
export class LoginComponent implements OnInit {
@Inject(AppComponent)
public username: string;
public password: string;
public user: string;
public showLoader: boolean = false;
public errorMsg: string = "";
public errorMsgUsername: string = "";
public documentHead: any;
public adminType: any;
public SECRET = 'DVOOtItNDnkwugzgyVDmEUpllHjTgPrORQhq';
constructor(private apiService: ApiService,
private router: Router,
public dashComp: DashboardPageComponent,
private session: SessionService,
private cdRef: ChangeDetectorRef,
private authService: AuthService,
private parent: AppComponent) {
this.documentHead = document.getElementsByTagName('head')[0];
}
ngOnInit() {
if (this.authService.isUserAuthorized()) {
this.parent.showPushNotif = true;
this.cdRef.detectChanges();
let encryptAdmin = CryptoJS.HmacSHA256('Admin', this.SECRET).toString(CryptoJS.enc.Hex);
let encryptSupportAdmin = CryptoJS.HmacSHA256('SupportAdmin', this.SECRET).toString(CryptoJS.enc.Hex);
let admintype = this.session.getValFromLocalStorage("Admintype");
if (encryptAdmin == admintype) {
this.router.navigate(['/map']);
} else if (encryptSupportAdmin == admintype) {
this.router.navigate(['/bookings']);
} else if (isNullOrUndefined(admintype)) {
this.router.navigate(['/login']);
}
}
}
gotoForgotPass() {
this.router.navigate(['/user/forgot_password']);
}
changeFavicon() {
let src = "";
if (this.user === "liteUser") {
src = AppConstants.FAVICONLITEPATH;
} else {
src = AppConstants.FAVICONPROPATH;
}
if (src) {
let link = document.createElement('link'),
oldLink = document.getElementById('dynamic-favicon');
link.id = 'dynamic-favicon';
link.rel = 'shortcut icon';
link.href = src;
if (oldLink) {
this.documentHead.removeChild(oldLink);
}
this.documentHead.appendChild(link);
}
}
onSubmit(loginForm: NgForm) {
var el = document.getElementById('progress-bar');
var oswidth = document.getElementById('progress-bar').offsetWidth;
var target_width = 100;
var id;
var router = this.router;
if (loginForm.value.username && loginForm.value.password) {
loginForm.value.grant_type = "password";
loginForm.value.username = loginForm.value.username.trim();
loginForm.value.username = encodeURI(loginForm.value.username);
this.errorMsg = "";
this.errorMsgUsername = "";
this.apiService.login(loginForm.value)
.subscribe((data) => {
this.showLoader = false;
this.session.setToLocalStorage("authTokens", JSON.stringify(data.data));
AppConstants.VIEW_DASH = 'dashboard'
this.dashComp.setViews(AppConstants.VIEW_DASH)
this.apiService.getAdminDetails()
.subscribe((response) => {
this.user = AppConstants.USER_CATEGORY[response.data.company_access.toString()];
this.adminType = AppConstants.LOGIN_TYPE[response.data.role.toString()];
// this.adminType = 'Admin';
// this.changeFavicon();
let encryptUser = { user: CryptoJS.HmacSHA256(this.user, this.SECRET).toString(CryptoJS.enc.Hex) };
let encryptAdmintype = CryptoJS.HmacSHA256(this.adminType, this.SECRET).toString(CryptoJS.enc.Hex);
this.session.setToLocalStorage("userCategory", JSON.stringify(encryptUser));
this.session.setToLocalStorage("Admintype", JSON.stringify(encryptAdmintype));
let that = this;
id = setInterval(function hello() {
if (oswidth < target_width) {
oswidth += 25;
} else {
clearInterval(id);
// router.navigate(['/map'])
that.parent.showPushNotif = true;
if (!that.cdRef['destroyed'])
that.cdRef.detectChanges();
if (that.user == "proUser" || that.user == "both") router.navigate(['/map'])
else if (that.user == "liteUser") router.navigate(['/dashboard'])
}
el.style.width = oswidth + '%';
return hello;
}(), 500);
});
}, (response) => {
clearInterval(id);
// this.showLoader = false;
switch (response.error.code) {
case -5003:
case -4000:
this.errorMsg = "";
this.errorMsgUsername = "Account not found";
break;
case -2101:
this.errorMsgUsername = "";
this.errorMsg = response.error.message
break;
}
});
} else {
this.errorMsgUsername = (!loginForm.value.username || loginForm.value.username.length === 0) ? "Please enter a valid email id" : "";
this.errorMsg = (!loginForm.value.password || loginForm.value.password.length === 0) ? "Please enter a valid password" : "";
}
}
}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from "@angular/forms";
import { SharedModule } from "./../shared/shared.module";
import { BookingsDetailsComponent } from "./bookings-details/bookings-details.component";
import { MyDatePickerModule } from 'mydatepicker';
import { ObdDashboardModule } from "../obd-dashboard/obd-dashboard.module";
import { NgSelectModule } from '@ng-select/ng-select';
import { DeleteModalComponent } from './bookings-details/delete-modal/delete-modal.component';
import { ModifyModalComponent } from './bookings-details/modify-modal/modify-modal.component';
@NgModule({
declarations: [
BookingsDetailsComponent,
DeleteModalComponent,
ModifyModalComponent
],
imports: [
CommonModule,
FormsModule,
SharedModule,
MyDatePickerModule,
ObdDashboardModule,
NgSelectModule,
],
exports: [BookingsDetailsComponent],
entryComponents: [
DeleteModalComponent,
ModifyModalComponent
]
})
export class BookingModule { }
.custom-modal
.modal-dialog
max-width: 834px
.modal-content
border-radius: 8px
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 2px 0 4px 0 rgba(0, 0, 0, 0.2)
background-color: #ffffff
border: none
.modal-header, .modal-footer
border: none
.modal-footer
.btn
flex-grow: 1
max-width: 262px
border: solid 1px #00b140
background-color: #ffffff
color: #00b140
&.green-btn
background-color: #00b140
color: #ffffff
&.red-btn
background-color: #f12b2b
color: #ffffff
border: none
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { BookingsDetailsComponent } from './bookings-details.component';
describe('BookingsDetailsComponent', () => {
let component: BookingsDetailsComponent;
let fixture: ComponentFixture<BookingsDetailsComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ BookingsDetailsComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(BookingsDetailsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
<div class="modal-header">
<h4 class="modal-title fs-16 bold light-black">Are you sure?</h4>
</div>
<div class="modal-body">
<p class="fs-14 semi-bold light-black">Are you sure you want to delete booking refrence number “<span
class="bold italic">{{item.reference}} </span>”, thereby ending the trip?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn red-btn fs-16 bold" (click)="deleteItem()">Yes</button>
<button type="button" class="btn fs-16 semi-bold bold-600" (click)="activeModal.close(false)">No, Dismiss</button>
</div>
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { DeleteModalComponent } from './delete-modal.component';
describe('DeleteModalComponent', () => {
let component: DeleteModalComponent;
let fixture: ComponentFixture<DeleteModalComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ DeleteModalComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(DeleteModalComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, Input, OnInit, ViewEncapsulation } from '@angular/core';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { ApiService } from '@shared/services/api.service';
import { ToastrService } from 'ngx-toastr';
@Component({
selector: 'app-delete-modal',
templateUrl: './delete-modal.component.html',
styleUrls: ['./delete-modal.component.sass'],
encapsulation: ViewEncapsulation.None
})
export class DeleteModalComponent implements OnInit {
@Input() public item;
constructor(public activeModal: NgbActiveModal,
private apiService: ApiService,
private toastr: ToastrService) { }
ngOnInit() {
}
deleteItem() {
let params = {
booking_reference: this.item.reference
}
this.apiService.deleteBookingKey(params)
.subscribe((response) => {
this.activeModal.close(true)
this.toastr.error(response.message);
}, (error) => {
this.activeModal.close(false)
});
}
}
<div class="modal-header">
<h4 class="modal-title fs-16 bold light-black">Modify - {{item.reference}}</h4>
</div>
<div class="modal-body">
<div class="d-flex">
<div class="form-item flex-grow-1 w-50 mr-3" [ngClass]="{'pointer-none-event': item.is_ongoing != 0}">
<span class="label-text fs-14 semi-bold light-black d-inline-block mb-2 bold-500"
[ngClass]="{'opacity-4 ': item.is_ongoing != 0}">Start Date & Time</span>
<div class="d-flex">
<div class="date-picker w-50 mr-2">
<my-date-picker (input)="onChange($event.target.value)" placeholder="Select Start Date" name="mydate"
[selector]="selector" [defaultMonth]="defaultMonth" [options]="myDatePickerOptionsFrom"
(dateChanged)="onDateChanged($event, 'FROM')" [(ngModel)]="selDatefrom" required
[disabled]="item.is_ongoing != 0"></my-date-picker>
</div>
<div class="time-picker w-50"
[ngClass]="{'focus-border': startTimeActiveFocus, 'opacity-4 ': item.is_ongoing != 0}">
<ng-select [items]="startTimeArray" bindLabel="text" (change)="timeIntervalOnChange($event, 'start')"
(focus)="onFocusSelect($event, 'startTime')" (blur)="onBlurSelect($event, 'startTime')"
placeholder="Select Start Time" [(ngModel)]="startTimeSelectModal" [disabled]="item.is_ongoing != 0">
</ng-select>
</div>
</div>
</div>
<div class="form-item flex-grow-1 w-50 ml-2">
<span class="label-text fs-14 semi-bold light-black d-inline-block mb-2 bold-500">End Date & Time</span>
<div class="d-flex">
<div class="date-picker w-50 mr-2">
<my-date-picker (input)="onToChange($event.target.value)" placeholder="Select End Date" name="mydate"
[selector]="selector" [defaultMonth]="defaultMonth" [options]="myDatePickerOptions"
(dateChanged)="onDateChanged($event, 'TO')" [(ngModel)]="selDateto" required></my-date-picker>
</div>
<div class="time-picker w-50" [ngClass]="{'focus-border': endTimeActiveFocus}">
<ng-select [items]="endTimeArray" bindLabel="text" (change)="timeIntervalOnChange($event, 'end')"
(focus)="onFocusSelect($event, 'endTime')" (blur)="onBlurSelect($event, 'endTime')"
placeholder="Select End Time" [(ngModel)]="endTimeSelectModal">
</ng-select>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn green-btn fs-16 bold bold-500" (click)="updateEndDateTime()"
[disabled]='(isdisableUpdateBtn || !isValidForm())'><span
[ngClass]="{'opacity-5 not-allowed': (isdisableUpdateBtn || !isValidForm())}">Update</span></button>
<button type="button" class="btn fs-16 semi-bold bold-500" (click)="activeModal.close(false)">Cancel</button>
</div>
@import './../_modal';
.modal-header
padding: 30px 24px
.modal-body
padding: 0 24px
.date-picker
.mydp
.selectiongroup
input
font-size: 16px
font-weight: 500
font-family: OpenSans-Bold
color: #222222
.selectiondisabled
background-color: #fff;
opacity: 0.5;
.selbtngroup
height: 47px!important
opacity: 0;
.selectiongroup input
height: 48px !important
padding-left: 10px !important
color: #222222 !important
font-weight: 500 !important
font-size: 16px !important
border: solid 1px #e7e7e7
font-family: OpenSans-Bold
&::placeholder
font-size: 14px !important
font-weight: normal !important
color: #666666 !important
font-family: OpenSans-Regular !important
.btnpicker.btnpickerenabled
margin-top: 1px;
margin-right: 1px;
height: 46px;
opacity: 0;
.icon-mydpcalendar
&:before
top: 18px;
.invaliddate
background-color: #F1DEDE
.time-picker
.ng-select-container
border: solid 1px #e7e7e7
.ng-arrow-wrapper, .ng-clear-wrapper
display: none
.ng-value-label
font-size: 16px
font-weight: 500
font-family: OpenSans-Bold
color: #222222
.ng-select-container
height: 48px
border: solid 1px #e7e7e7
&:hover
box-shadow: none;
.ng-arrow
display: none
.ng-input
top: 12px
input
font-family: OpenSans-Bold
font-weight: 500
.ng-value
font-size: 16px
font-family: OpenSans-Bold
font-weight: 500
color: #222222
.ng-placeholder
font-size: 14px
font-family: OpenSans-Regular
font-weight: normal
color: #666666
.ng-dropdown-panel-items
.ng-option
font-size: 14px
font-weight: bold
color: #222222
&.ng-option-marked
color: #00b140
background-color: #ffffff
.ng-option-label
font-family: OpenSans-bold
font-size: 14px
font-weight: 500
.modal-footer
padding: 67px 24px 34px 24px
\ No newline at end of file
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ModifyModalComponent } from './modify-modal.component';
describe('ModifyModalComponent', () => {
let component: ModifyModalComponent;
let fixture: ComponentFixture<ModifyModalComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ModifyModalComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ModifyModalComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
<div id="breadcrumd-container" *ngIf="!hideBreadCrumbs">
<ol class="breadcrumb-list">
<!-- <li *ngIf="!hideBreadcrum_obd"><a routerLink="/dashboard" class="breadcrumb" (click)="has1Sibling=false; has2Sibling=false;" >{{parent}}</a></li> -->
<li *ngFor="let item of breadcrumbList; let i = index" >
<a (click) = "goBack(item.path)" *ngIf="i!==breadcrumbList.length-1" class="breadcrumb-list">
{{item.name}}</a>
<span *ngIf="i===breadcrumbList.length-1" class="breadcrumb-list fs-14">{{ item.name }}</span>
</li>
</ol>
</div>
@import "../../styles.sass"
#breadcrumd-container
.breadcrumb-list
// cursor: pointer
padding: 18px 5px 10px 10px
margin-top: 10px
background-color: transparent
// cursor: pointer
li
cursor: pointer
&:first-child
&:before
content: ""
&:before
content: ">>"
color: $lightBlack
padding: 0 9px 0 5px
a
font-family: $openSansSemiBold
font-size : 14px
color: $lightBlack
&:last-child
span
font-family: $openSansBold
cursor: default
#lastChild
a
cursor: default
&:hover
text-decoration: none
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { BreadcrumbComponent } from './breadcrumb.component';
describe('BreadcrumbComponent', () => {
let component: BreadcrumbComponent;
let fixture: ComponentFixture<BreadcrumbComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ BreadcrumbComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(BreadcrumbComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
<div id="bar-chart">
<label *ngIf="objList" class="graph-label">% of Users <span>&#8594;</span> </label>
<label *ngIf="objList" class="horizontal-label">Age <span>&#8594;</span> </label>
<div class="graph-plots">
<div class="plots" *ngFor="let t of objList; let i = index;">
<div class="bar-wrapper">
<div class="bar aixs" [ngClass]="{ 'first': i==0, 'last': i==objList.length - 1 }"></div>
<div class="bar" [ngStyle]="{ 'height': graphData[t]+'%', 'background-color': '#00b140' }">
<div class="value">{{graphData[t]}}%</div>
</div>
</div>
<label>{{t}}</label>
</div>
</div>
</div>
@import "../../../styles.sass"
#bar-chart
width: 54%
height: 100%
display: inline-block
float: right
position: relative
.graph-label
transform: rotate(-90deg)
transform-origin: 0 100%
position: absolute
font-size: 13px
z-index: 10
height: 25px
left: 35px;
bottom: 20px
font-weight: normal
color: $bodyTxtColor
font-family: $openSansRegular
text-transform: uppercase
span
font-size: 22px
position: relative
top: 2px
font-weight: normal
.horizontal-label
position: absolute
bottom: -9px
font-size: 12px
font-weight: normal
color: $bodyTxtColor
font-family: $openSansRegular
text-transform: uppercase
span
font-size: 22px
font-weight: normal
position: relative
top: 4px
.graph-plots
width: 100%
height: 100%
padding-left: 50px
.plots
width: 12%
height: 100%
float: left
position: relative
&:nth-child(1)
.bar-wrapper
border-left: solid 1px #9c9c9c
.bar-wrapper
height: 80%
position: relative
.bar
width: 56%
position: absolute
bottom: 0
left: 0
border-bottom: 1px solid #9c9c9c;
&.aixs
width: 100%
border-bottom: 1px solid #9c9c9c
&.first
left: 0
&.last
left: 0
.value
width: 100%
text-align: center
margin-top: -20px
font-size: 14px
font-family: $openSansSemiBold
label
width: 58%
position: absolute
bottom: -6px
font-size: 12px
text-align: center
color: $bodyTxtColor
font-family: $openSansRegular
font-weight: normal
@media only screen and (max-width: 1024px)
#bar-chart
margin: 45px 0 20px 0
width: 100%
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { BarChartComponent } from './bar-chart.component';
describe('BarChartComponent', () => {
let component: BarChartComponent;
let fixture: ComponentFixture<BarChartComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ BarChartComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(BarChartComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit, Output, EventEmitter } from '@angular/core';
import { ApiService } from '@shared/services/api.service';
@Component({
selector: 'app-bar-chart',
templateUrl: './bar-chart.component.html',
styleUrls: ['./bar-chart.component.sass']
})
export class BarChartComponent implements OnInit {
public graphData: any;
public colorCodes: string[] = [ "#ffb72c", "#feae2d", "#fc9730", "#fa8133", "#f96d36", "#f86237", "#f75a38", "#f04b28" ];
public objList: string[];
@Output() onApiSuccess: EventEmitter<any> = new EventEmitter();
constructor(public _apiCallService: ApiService) { }
ngOnInit() {
this.getChartVales();
}
getChartVales() {
this._apiCallService.getChartValue()
.subscribe( (response: any) => {
delete response.data.age_count.total
this.graphData = response.data.age_count;
this.objList = Object.keys(this.graphData);
this.onApiSuccess.next(true);
}, (error: any) => {
this.onApiSuccess.next(true);
});
}
}
<div class="category-chart-wrapper" [ngClass]="{ 'align-right': category === 'risk' }" (window:resize)="onResize($event)">
<div class="heading">{{ heading }}</div>
<div class="chart-wrapper">
<div class="chart" #chart>
<svg id="{{category}}"></svg>
<div id="{{category}}-tooltip" class="hidden">
<span id="{{category}}-value">100</span>
</div>
</div>
<div class="legend">
<ul>
<li *ngFor="let legend of pieData.legends; let i = index;"><div class="legend-dot" [ngStyle]="{ 'background-color': colorCodes[i] }"></div><span>{{legend}}</span></li>
</ul>
</div>
</div>
</div>
@import "../../../styles.sass"
.category-chart-wrapper
width: 49%
float: left
height: 345px
margin: 22px 0 0 0
border-radius: 5px
border: solid 1px $borderLightGray
background-color: $white
&.align-right
float: right
.heading
padding: 20px 0 0 24px
font-size: 14px
color: $lightBlack
font-family: $openSansSemiBold
.chart-wrapper
height: 88%
width: 100%
float: left
position: relative
.chart
width: 60%
height: 100%
float: left
padding: 10px 0 0 0
svg
width: 100%
height: 100%
display: block
margin: 0 auto
text
font-family: $openSansSemiBold
font-size: 12px
fill: white
#risk-tooltip, #user-tooltip
background-color: #2196f3
color: #ffffff
text-align: center
z-index: 100000
position: absolute
width: auto
height: auto
padding: 5px 10px
border-radius: 10px
-webkit-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4)
-mox-box-shadow: 4px 4px 4px 10px rgba(0, 0, 0, 0.4)
box-shadow: 4px 4px 10px rbga(0, 0, 0, 0.4)
pointer-events: none
#risk-tooltip.hidden, #user-tooltip.hidden
opacity: 0
#risk-tooltip p, #user-tooltip p
margin: 0
font-family: $openSansSemiBold
font-size: 16px
line-height: 20px
.legend
width: 40%
height: 100%
float: right
ul
position: absolute
top: 33%
transform: translateY(-45%)
width: 40%
color: #6b7784
li
margin-top: 20px
position: relative
span
padding-left: 40px
font-size: 16px
color: $bodyTxtColor
font-family: $openSansRegular
.legend-dot
width: 12px
height: 12px
top: 5px
left: 0
border-radius: 50%
display: block
position: absolute
@media only screen and (max-width: 1082px)
.category-chart-wrapper
margin: 15px 0 20px 0
width: 100%
@media only screen and (max-width: 768px)
.vehicle-stat-num
font-size: 14px!important
.chart-wrapper .legend ul li span
padding-left: 25px
font-size: 14px
.veh-progressbar-chart
margin-left: -11px!important
table td .label
width: 100px
word-wrap: break-word
display: block
white-space: normal
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { CategoriesChartComponent } from './categories-chart.component';
describe('CategoriesChartComponent', () => {
let component: CategoriesChartComponent;
let fixture: ComponentFixture<CategoriesChartComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ CategoriesChartComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(CategoriesChartComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, Input, OnInit, ElementRef, ViewChild, Output, EventEmitter, NgZone } from '@angular/core';
import { Router } from '@angular/router';
import * as d3 from 'd3';
import { SessionService } from '@shared/services/session.service';
import { ApiService } from '@shared/services/api.service';
import { AppConstants } from '../../app.constants';
@Component({
selector: 'app-categories-chart',
templateUrl: './categories-chart.component.html',
styleUrls: ['./categories-chart.component.sass']
})
export class CategoriesChartComponent implements OnInit {
public type: any;
public heading: string;
@Input() category: string;
public pieData: any = {};
@ViewChild('chart') elementView: ElementRef;
@Output() onApiSuccess: EventEmitter<any> = new EventEmitter();
public dataSet: Object[];
public colorCodes: Array<any> = ["#1d1e52", "#008b8f", "#ff9c2b", "#f65a38", "#d11d55"];
public margin = {top: 20, right: 20, bottom: 30, left: 50};
public width: number;
public height: number;
public radius: number;
public arc: any;
public labelArc: any;
public pie: any;
public color: any;
public svg: any;
constructor(private zone:NgZone,
private route: Router,
private SessionService: SessionService,
public _apiCallService: ApiService) {}
ngOnInit() {
this.type = AppConstants.HTML_MODERATE;
( this.category === "user" ) ? this.getCategoryData("driveCategory") : this.getCategoryData("riskCategory");
}
getCategoryData(apiName) {
this._apiCallService.getCategoryData(apiName)
.subscribe( (response: any) => {
if(this.category === "user"){
this.pieData = {
dataSet: response.data.drive_category,
legends: AppConstants.USER_LEGENDS,
dataSetMap: AppConstants.USER_DATASETMAP,
totalVal: response.data.drive_category.total_users
}
} else {
this.pieData = {
dataSet: response.data.risk_category,
legends: AppConstants.COMMON_LEGENDS,
dataSetMap: AppConstants.COMMON_DATASETMAP,
totalVal: response.data.risk_category.total_users
}
}
this.buildChart();
this.onApiSuccess.next(true);
}, (error: any) => {
this.onApiSuccess.next(true);
});
}
buildData() {
let newDataCollection: Array<any> = [];
this.pieData.dataSetMap.forEach( (key, i) => {
let obj: Object = {
val: this.pieData.dataSet[key],
perCentVal: ((this.pieData.dataSet[key] / this.pieData.totalVal) * 100),
label: this.pieData.legends[i].toUpperCase()
};
newDataCollection.push(obj);
});
return newDataCollection;
}
buildChart() {
this.dataSet = this.buildData();
this.width = this.elementView.nativeElement.offsetWidth - this.margin.left - this.margin.right ;
this.height = this.elementView.nativeElement.offsetHeight - this.margin.top - this.margin.bottom;
this.radius = Math.min(this.width, this.height) / 2 - 13;
this.heading = ( this.category === "user" ) ? "User Categories" : "Risk Categories";
setTimeout(() => {
this.initSvg()
this.drawPie();
}, 10);
}
public initSvg() {
this.color = d3.scaleOrdinal()
.range(this.colorCodes);
this.arc = d3.arc()
.outerRadius(this.radius - 10)
.innerRadius(0);
this.labelArc = d3.arc()
.outerRadius(this.radius - 40)
.innerRadius(this.radius - 40);
this.pie = d3.pie()
.sort(null)
.value((d: any) => d.perCentVal);
this.svg = d3.select("#" + this.category)
.append("g")
.attr("class", "parent-g")
.attr("transform", "translate(" + ((this.width / 2)+35) + "," + this.height / 2 + ")");
}
public drawPie() {
let g = this.svg.selectAll(".arc")
.data(this.pie(this.dataSet))
.enter().append("g")
.attr("class", "arc");
g.append("path").attr("d", this.arc)
.style("fill", (d: any) => this.colorCodes[d.index] );
g.append("text").attr("font-weight", "bold")
.attr("fill", "#ffffff")
.attr("font-size", "12")
.attr("transform", (d: any) => "translate(" + this.labelArc.centroid(d) + ")")
.attr("dy", "-0.2em")
.attr("dx", "-0.6em")
.text((d: any) => { if(d.data.perCentVal > 0) {
if(d.data.perCentVal == 0) return " "
else if(d.data.perCentVal > 0 && d.data.perCentVal < 1){
return d.data.perCentVal.toFixed(2)+ "%"
} else if(d.data.perCentVal >= 1) return Math.round(d.data.perCentVal)+ "%"
}
});
g.on("mouseover", (d) => {
d3.select("#" + this.category + "-tooltip")
.attr("class", "")
.style("position", "absolute")
.style("left", d3.event.pageX - 70 + "px")
.style("top", d3.event.pageY - 580 + "px")
.style("opacity", 1)
.select("#" + this.category + "-value")
.text(d.data.val);
}).on("mouseout", () => {
d3.select("#" + this.category + "-tooltip")
.style("opacity", 0);;
})
if(this.category === "user") {
g.attr("cursor", "pointer")
.on("click", (d) => {
this.SessionService.deleteCategory()
let label = d.data.label === "NEW USERS" ? "UNCATEGORIZED" : d.data.label;
localStorage.setItem('userType', label);
// this.route.navigate(["user-categories/categories"]);
this.route.navigate(["dashboard/categories"]);
// this.route.navigate(["user-categories/categories"], { queryParams: {type: label, page: "1"} });
});
}
}
onResize(e){
let width = this.elementView.nativeElement.offsetWidth - this.margin.left - this.margin.right ;
let height = this.elementView.nativeElement.offsetHeight - this.margin.top - this.margin.bottom;
let g = d3.select("#" + this.category).select("g.parent-g").attr("transform", "translate("+ width/2 +", " + height/2 + ")");
}
}
<div id="claims">
<div class="heading">Claims</div>
<!-- <ul>
<li>
<h5>{{claimDetails.total_claims}}</h5>
<span>Total</span>
</li>
<li>
<h5>{{claimDetails.new_claims}}</h5>
<span>New</span>
</li>
<li>
<h5>{{claimDetails.inprogress_claims}}</h5>
<span>In Progress</span>
</li>
<li>
<h5>{{claimDetails.rejected_claims}}</h5>
<span>Rejected</span>
</li>
<li>
<h5>{{claimDetails.approved_users}}</h5>
<span>Approved</span>
</li>
</ul> -->
<div class="no-claims-wrapper">
<div class="no-claims"></div>
<div class="fs-14 bold-600 light-black">No Claims!</div>
</div>
</div>
@import "../../../styles.sass"
#claims
float: right
width: 49%
height: 140px
margin: 22px 0 0
padding-top: 10px
border-radius: 5px
background-color: $white
border: solid 1px $borderLightGray
font-family: $openSansSemiBold
.heading
padding: 15px 0 10px 24px
font-size: 14px
color: $lightBlack
font-family: $openSansSemiBold
ul
list-style: none
width: 100%
li
display: inline-block
width: 19%
text-align: center
h5
font-size: 20px
color: $green
font-family: $openSansBold
span
color: $bodyTxtColor
font-size: 14px
font-family: $openSansRegular
.no-claims-wrapper
width: 100%
height: 65%
text-align: center
font-size: 16px
.no-claims
background: url(#{$dashboardClaimsAssetPath}/noclaims-illustration.svg) no-repeat
width: 48px
height: 53px
position: relative
left: 50%
transform: translateX(-50%)
@media only screen and (max-width: 1082px)
#claims
width: 100%
margin-bottom: 20px
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ClaimsComponent } from './claims.component';
describe('ClaimsComponent', () => {
let component: ClaimsComponent;
let fixture: ComponentFixture<ClaimsComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ClaimsComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ClaimsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit, Output, EventEmitter } from '@angular/core';
import { ApiService } from '@shared/services/api.service';
@Component({
selector: 'app-claims',
templateUrl: './claims.component.html',
styleUrls: ['./claims.component.sass']
})
export class ClaimsComponent {
public claimDetails: any = {};
@Output() onApiSuccess: EventEmitter<any> = new EventEmitter();
constructor( public _apiCallService: ApiService ) {
this._apiCallService.getWebDashboardClaimDetails()
.subscribe( (response:any) => {
this.claimDetails = response.data.claims_count
this.onApiSuccess.next(true);
}, (error: any) => {
this.onApiSuccess.next(true);
});
}
}
<div id="dashboard-welcome-wrapper" *ngIf="view=='welcome'">
<app-welcome></app-welcome>
</div>
<div id="dashboard-wrapper" *ngIf="view=='dashboard'">
<div class="loader white" *ngIf="showLoader"></div>
<div class="top-content">
<app-dashboard-user-count (onApiSuccess)="checkLoader($event)"></app-dashboard-user-count>
<app-bar-chart (onApiSuccess)="checkLoader($event)"></app-bar-chart>
</div>
<app-operating-system (onApiSuccess)="checkLoader($event)"></app-operating-system>
<app-product-overview (onApiSuccess)="checkLoader($event)"></app-product-overview>
<app-categories-chart category="user" (onApiSuccess)="checkLoader($event)"></app-categories-chart>
<!-- <app-category-chart category="risk" (onApiSuccess)="checkLoader($event)"></app-category-chart> -->
<app-claims (onApiSuccess)="checkLoader($event)"></app-claims>
<app-status-details (onApiSuccess)="checkLoader($event)"></app-status-details>
</div>
@import "../../../styles.sass";
#dashboard-wrapper
width: 94%
float: left
padding: 0 0 40px 30px
font-family: $openSansSemiBold
.white
background-color: #f1f2f3
.top-content
margin: 0
width: 100%
height: 123px
.bottom-wrapper
width: 100%
height: 10px
float: left
#dashboard-welcome-wrapper
margin: 50px auto
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { DashboardPageComponent } from './dashboard-page.component';
describe('DashboardPageComponent', () => {
let component: DashboardPageComponent;
let fixture: ComponentFixture<DashboardPageComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ DashboardPageComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(DashboardPageComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute, Params } from '@angular/router';
import { AppComponent } from "../../app.component";
import { AppConstants } from "../../app.constants";
import { ApiService } from "@shared/services/api.service";
import { HeaderService } from "@shared/services/header.service";
import { SideMenuService } from "@shared/services/side-menu.service";
import { FooterService } from "@shared/services/footer.service";
import { UtilityService } from "@shared/services/utility.service";
@Component({
selector: 'app-dashboard-page',
templateUrl: './dashboard-page.component.html',
styleUrls: ['./dashboard-page.component.sass']
})
export class DashboardPageComponent implements OnInit {
public userCount: any;
public graphData: any;
public claimDetails: any;
public productOverviewDetails: any;
public userData: any;
public riskData: any;
public view;
public showLoader: boolean;
public osData: any;
public statusDetails: any;
public loaderArr: any = [];
constructor(public util: UtilityService,
private _apiCallService: ApiService,
public sideMenu: SideMenuService,
public footer: FooterService,
public header:HeaderService,
private Router: Router ) {
this.view = AppConstants.VIEW_DASH;
}
setViews(val) {
this.view = val;
if(this.view == 'welcome') {
this.sideMenu.hide();
this.footer.show();
this.header.setCommonHead();
this.util.setLiteBg();
}
else if(this.view == 'dashboard') {
this.footer.hide();
this.header.setDashHead();
this.util.setDarkBg();
this.sideMenu.show();
this.sideMenu.setActiveClass("/dashboard");
this.sideMenu.dashIcon = true;
this.sideMenu.hideSelectionIcon = false;
}
}
ngOnInit() {
this.setViews('dashboard');
this.showLoader = true;
}
checkLoader(e: any) {
this.loaderArr.push(e);
console.log(this.loaderArr);
// Checks to no of api's called. Since there are 8 components, 8 respective api calls initiated
if(this.loaderArr.length === 7){
this.showLoader = false;
}
}
}
<div id="total-user-count">
<div class="total-users">
<h4>{{userCounts?.total}}</h4>
<span>Total Users</span>
</div>
<div class="total-users line" (click)="navigateToUserCategories()"></div>
<div class="gender-numbers">
<div class="male">
<div class="icon male-icon"></div>
<span>{{userCounts?.male}}</span>
</div>
<div class="female">
<div class="icon female-icon"></div>
<span>{{userCounts?.female}}</span>
</div>
</div>
</div>
@import "../../../styles.sass"
#total-user-count
font-family: $openSansSemiBold
background-color: #ffffff
display: inline-block
width: 43%
height: 100%
float: left
border: solid 1px $borderLightGray
background-color: $white
border-radius: 5px
position: relative
.total-users
width: 45%
font-size: 31px
text-align: center
position: absolute
transform: translateY(-50%)
line-height: 30px
top: 50%
h4
font-size: 31px
margin-bottom: 0
font-family: $openSansSemiBold
span
font-size: 18px
text-align: center
color: $bodyTxtColor
font-family: $openSansRegular
&.line
height: 100%;
border-right: 1px solid $lineGray;
cursor: pointer
.gender-numbers
width: 55%
float: right
position: absolute
top: 60%
left: 45%
line-height: 35px
transform: translateY(-50%)
.icon
width: 30px
height: 35px
margin: auto
.male
width: 50%
height: 100%
text-align: center
float: left
padding-left: 30px
.male-icon
background: url(#{$dashboardUserCountAssetPath}/male.svg) no-repeat
background-size: contain
.female
width: 50%
height: 100%
text-align: center
float: right
padding-right: 30px
.female-icon
background: url(#{$dashboardUserCountAssetPath}/female.svg) no-repeat
background-size: contain
span
font-size: 18px
color: $bodyTxtColor
font-family: $openSansRegular
@media only screen and (max-width: 1000px)
#total-user-count
.gender-numbers
.male
padding: 0
@media only screen and (max-width: 1024px)
#total-user-count
width: 100%
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { DashboardUserCountComponent } from './dashboard-user-count.component';
describe('DashboardUserCountComponent', () => {
let component: DashboardUserCountComponent;
let fixture: ComponentFixture<DashboardUserCountComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ DashboardUserCountComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(DashboardUserCountComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit, Output, EventEmitter } from '@angular/core';
import { Router } from '@angular/router';
import { ApiService } from '@shared/services/api.service';
@Component({
selector: 'app-dashboard-user-count',
templateUrl: './dashboard-user-count.component.html',
styleUrls: ['./dashboard-user-count.component.sass']
})
export class DashboardUserCountComponent {
public userCounts: any;
@Output() onApiSuccess: EventEmitter<any> = new EventEmitter;
constructor(private Router: Router, public _apiCallService: ApiService) {
this.getUserCount();
}
getUserCount() {
this._apiCallService.getUserCount()
.subscribe((response: any) => {
this.userCounts = response.data.gender_count;
}, (error: any) => {
})
}
navigateToUserCategories() {
// this.Router.navigate(['/user-categories/users']);
if (this.Router.url.includes('dashboard')) {
this.Router.navigate([`dashboard/users`]);
} else {
this.Router.navigate([`users`]);
}
}
}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SharedModule } from "./../shared/shared.module";
import { BarChartComponent } from './bar-chart/bar-chart.component';
import { CategoriesChartComponent } from './categories-chart/categories-chart.component';
import { ClaimsComponent } from './claims/claims.component';
import { DashboardUserCountComponent } from './dashboard-user-count/dashboard-user-count.component';
import { OperatingSystemComponent } from './operating-system/operating-system.component';
import { ProductOverviewComponent } from './product-overview/product-overview.component';
import { StatusDetailsComponent } from './status-details/status-details.component';
import { WelcomeComponent } from './welcome/welcome.component';
import { DashboardPageComponent } from './dashboard-page/dashboard-page.component';
@NgModule({
declarations: [BarChartComponent, CategoriesChartComponent, ClaimsComponent, DashboardUserCountComponent, OperatingSystemComponent, ProductOverviewComponent, StatusDetailsComponent, WelcomeComponent, DashboardPageComponent],
imports: [
CommonModule,
SharedModule
],
exports: [
DashboardPageComponent
]
})
export class DashboardModule { }
<div class="row" *ngIf="userType !=='proUser'" id="operating-system">
<!-- <div class="heading">
<h4>OPERATING SYSTEM</h4>
</div> -->
<div class="col-sm-12 dashCol">
<div class="os-details dashboard row">
<div *ngIf="userType!=='liteUser'" class="os-single-detail-dash col-sm-4">
<ul>
<li>Jido Sense:</li>
<li>{{operatingSysData?.obd?.in_percentage ? operatingSysData?.obd?.in_percentage + "%" : '-'}}</li>
<li>{{operatingSysData?.obd?.in_count ? operatingSysData?.obd?.in_count : '-'}}</li>
</ul>
</div>
<div class="os-single-detail-dash col-sm-4">
<ul>
<li>Android:</li>
<li>{{operatingSysData?.android.in_percentage ? operatingSysData?.android.in_percentage + "%" : '-'}}</li>
<li>{{operatingSysData?.android.in_count ? operatingSysData?.android.in_count : '-'}}</li>
</ul>
</div>
<div class="os-single-detail-dash col-sm-4">
<ul>
<li>iOS:</li>
<li>{{operatingSysData?.ios.in_percentage ? operatingSysData?.ios.in_percentage + "%" : '-'}}</li>
<li>{{operatingSysData?.ios.in_count ? operatingSysData?.ios.in_count : '-'}}</li>
</ul>
</div>
</div>
</div>
</div>
@import "../../../styles.sass"
$bgColor: #bebebe;
$borderGray: #a9a9a9;
#operating-system
width: 100%
height: 43px
margin: 23px 0 0 0
border-radius: 5px
background-color: $bgColor
border: solid 1px $borderGray
font-family: $openSansSemiBold
line-height: 2.3
clear: both
.heading
width: 20%
float: left
height: 100%
h4
font-size: 17px
font-weight: 600
color: $white
text-align: center
font-family: $openSansSemiBold
.os-details.dashboard
margin: 0
width: 100%
height: 100%;
float: none
.os-single-detail-dash
height: 100%
ul
list-style: none
color: $white
font-size: 17px
li
display: inline-block
width: 28%
text-align: center
line-height: 17px
// margin: 12px 0
font-family: $openSansSemiBold
li:first-child
text-align: right
li:nth-child(2)
border-right: 2px solid $white
.dashCol
padding: 0
@media only screen and (max-width: 1000px)
#operating-system
.heading
width: 25%
@media only screen and (max-width: 800px)
#operating-system
.heading
h4
font-size: 14px
line-height: 3
@media only screen and (max-width: 725px)
#operating-system
.heading
h4
font-size: 10px
line-height: 3
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { OperatingSystemComponent } from './operating-system.component';
describe('OperatingSystemComponent', () => {
let component: OperatingSystemComponent;
let fixture: ComponentFixture<OperatingSystemComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ OperatingSystemComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(OperatingSystemComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit, Output, EventEmitter } from '@angular/core';
import { ApiService } from '@shared/services/api.service';
import { AuthService } from '@shared/services/auth.service';
@Component({
selector: 'app-operating-system',
templateUrl: './operating-system.component.html',
styleUrls: ['./operating-system.component.sass']
})
export class OperatingSystemComponent {
public operatingSysData: any;
public userType: string;
@Output() onApiSuccess: EventEmitter<any> = new EventEmitter();
constructor(public _apiCallService: ApiService,
private AuthService: AuthService) {
if (this.AuthService.userCategoryAuthorized()) {
this.userType = this.AuthService.userCategoryAuthorized();
console.log("this.userType", this.userType)
}
this._apiCallService.getOsDetails()
.subscribe( (response: any) => {
this.operatingSysData = response.data.operating_system;
this.onApiSuccess.next(true);
}, (error: any) => {
this.onApiSuccess.next(true);
})
}
}
<div id="product-overview">
<div class="heading fs-14 bold-600">Fleet Summary</div>
<ul>
<li>
<h5>{{productDetails?.tripDetails.kms || 0}}</h5>
<span>km Covered</span>
</li>
<li>
<h5>{{productDetails?.tripDetails.trips}}</h5>
<span>Total Trips</span>
</li>
<li>
<!-- <h5>{{productDetails?.deviceDetails.insured_users}}</h5> -->
<h5>0</h5>
<span>Insured Users</span>
</li>
<!-- <li>
<h5>{{productDetails?.deviceDetails.hband_users}}</h5>
<span>Health Band Users</span>
</li> -->
</ul>
</div>
@import "../../../styles.sass"
#product-overview
width: 100%
background-color: #ffffff
font-family: $openSansSemiBold
height: 168px
margin: 22px 0 0 0
border: solid 1px $borderLightGray
position: relative
border-radius: 5px
background-color: $white
.heading
padding: 20px 0 0 24px
color: $lightBlack
font-family: $openSansSemiBold
ul
list-style: none
width: 100%
position: absolute
top: 50%
transform: translateY(-50%)
font-family: $openSansBold
li
display: inline-block
width: 33%
text-align: center
padding-top: 24px
h5
font-size: 26px
font-weight: bold
color: #222222
font-family: $openSansBold
span
color: $bodyTxtColor
font-size: 14px
font-family: $openSansRegular
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ProductOverviewComponent } from './product-overview.component';
describe('ProductOverviewComponent', () => {
let component: ProductOverviewComponent;
let fixture: ComponentFixture<ProductOverviewComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ProductOverviewComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ProductOverviewComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit, Output, EventEmitter } from '@angular/core';
import { ApiService } from '@shared/services/api.service';
@Component({
selector: 'app-product-overview',
templateUrl: './product-overview.component.html',
styleUrls: ['./product-overview.component.sass']
})
export class ProductOverviewComponent {
public productDetails: any = {
tripDetails: {},
deviceDetails: {}
};
@Output() onApiSuccess: EventEmitter<any> = new EventEmitter();
constructor(public _apiCallService: ApiService) {
this._apiCallService.getProductDetails()
.subscribe( (response: any) => {
this.productDetails.tripDetails = response.data.drive_data;
this.onApiSuccess.next(true);
}, (error: any) => {
this.onApiSuccess.next(true);
});
this._apiCallService.getBandDetails()
.subscribe( (response: any) => {
this.productDetails.deviceDetails = response.data.user_count;
this.onApiSuccess.next(true);
}, (error: any) => {
this.onApiSuccess.next(true);
});
}
returnApiSuccess() {
}
}
<div id="status-bar">
<div class="no-of-incidents">
<span class="title">No of Incidents Reported:</span>
<!-- <span class="number">{{statusDetails?.incidents_reported ? (statusDetails?.incidents_reported | number) : '0' }}</span> -->
<span class="number">-</span>
</div>
<div class="premium-reduction">
<span class="title">Total Premium Reduction/Hike:</span>
<!-- <span class="number">+&nbsp;S$ {{statusDetails?.total_premium ? (statusDetails?.total_premium | number): '0.00'}}</span> -->
<span class="number">-</span>
</div>
</div>
@import "../../../styles.sass"
#status-bar
float: right
width: 49%
height: 160px
margin-top: 45px
position: relative
.no-of-incidents
height: 41%
width: 100%
border-radius: 5px
background-color: #bebebe
border: solid 1px #a9a9a9
padding: 20px 24px 10px 24px
span
color: #ffffff
font-family: $openSansSemiBold
&.title
font-size: 17px
&.number
padding-left: 20px
font-size: 17px
float: right
.premium-reduction
height: 40%
width: 100%
border-radius: 5px
background-color: #2196f3
margin-top: 30px
padding: 20px 24px 10px 24px
span
color: #ffffff
font-family: $openSansSemiBold
&.title
font-size: 17px
&.number
float: right
font-size: 19px
@media only screen and (max-width: 1000px)
#status-bar
.premium-reduction
span.title
font-size: 15px
span.number
font-size: 17px
@media only screen and (max-width: 1082px)
#status-bar
width: 100%
margin-bottom: 0
.premium-reduction
span.title
font-size: 17px
span.number
font-size: 19px
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { StatusDetailsComponent } from './status-details.component';
describe('StatusDetailsComponent', () => {
let component: StatusDetailsComponent;
let fixture: ComponentFixture<StatusDetailsComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ StatusDetailsComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(StatusDetailsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit, Output, EventEmitter } from '@angular/core';
import { ApiService } from '@shared/services/api.service';
@Component({
selector: 'app-status-details',
templateUrl: './status-details.component.html',
styleUrls: ['./status-details.component.sass']
})
export class StatusDetailsComponent {
public statusDetails: any;
@Output() onApiSuccess: EventEmitter<any> = new EventEmitter();
constructor(public _apiCallService: ApiService) {
this._apiCallService.getInsuaranceDetails()
.subscribe( (response: any) => {
this.statusDetails = response.data;
this.onApiSuccess.next(true);
}, (error: any) => {
this.onApiSuccess.next(true);
})
}
}
<div class="container-fluid text-center">
<div class="row">
<div class="col-sm-12">
<div class="well">
<div class="welcome-image img-responsive center-block"></div>
<h4>Hi Elene, Welcome to Sompo Dashboard!</h4>
<br><p>Congratulations, you’ve joined the SOMPO Admin Dashboard! We’re here to help simplify the way you work.</p>
<br><button class="goto-btn" (click)="gotoDashBoard()"><span>GO TO DASHBOARD</span></button>
</div>
</div>
</div>
</div>
@import "../../../styles.sass"
.container-fluid
padding: 0 15px 0 0
.welcome-image
background: url(#{$welcomePath}/ic-welcomepassword@3x.png) no-repeat
width: 188px
height: 103px
background-size: contain
margin-bottom: 50px
.goto-btn
width: 236px
height: 50px
border-radius: 8px
color: $white
background-color: $lightOrange
.well
border: none
background-color: $white
-webkit-box-shadow: none
box-shadow: none
h4
font-family: $helveticaNeueBold
font-size: 24px
p
font-family: $helveticaNeue
font-size: 16px
span
font-family: $helveticaNeueBold
font-size: 18px
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { WelcomeComponent } from './welcome.component';
describe('WelcomeComponent', () => {
let component: WelcomeComponent;
let fixture: ComponentFixture<WelcomeComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ WelcomeComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(WelcomeComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit } from '@angular/core';
import { AppConstants } from '../../app.constants';
import { FooterService } from '@shared/services/footer.service';
import { DashboardPageComponent } from '../../dashboard/dashboard-page/dashboard-page.component';
@Component({
selector: 'app-welcome',
templateUrl: './welcome.component.html',
styleUrls: ['./welcome.component.sass']
})
export class WelcomeComponent implements OnInit {
constructor(private footer: FooterService,
private dashComp: DashboardPageComponent) { }
ngOnInit() {
this.footer.show();
}
gotoDashBoard() {
AppConstants.VIEW_DASH = 'dashboard'
this.dashComp.setViews(AppConstants.VIEW_DASH)
}
}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { SharedModule } from "../shared/shared.module";
import { MapBoxComponent } from './map-box/map-box.component';
import { NgxMapboxGLModule } from 'ngx-mapbox-gl';
@NgModule({
declarations: [MapBoxComponent],
imports: [
CommonModule,
FormsModule,
ReactiveFormsModule,
SharedModule,
NgxMapboxGLModule.withConfig({
accessToken: 'pk.eyJ1IjoiYW1hbC10ZWNod2FyZTEyMyIsImEiOiJjanhvOXVhZ3MwNHJxM2lzNzVob2NidzFzIn0.deBOPOjsOIZ_vmik6ZUfpQ', // Optionnal, can also be set per map (accessToken input of mgl-map)
geocoderAccessToken: 'TOKEN' // Optionnal, specify if different from the map access token, can also be set per mgl-geocoder (accessToken input of mgl-geocoder)
})
]
})
export class LiveMapModule { }
export const mapStyle = [
{
elementType: 'geometry',
stylers: [
{
color: '#fef9f7'
}
]
},
{
elementType: 'labels.text.fill',
stylers: [
{
color: '#523735'
}
]
},
{
elementType: 'labels.text.stroke',
stylers: [
{
color: '#f5f1e6'
}
]
},
{
featureType: 'administrative',
elementType: 'geometry.stroke',
stylers: [
{
color: '#c9b2a6'
}
]
},
{
featureType: 'administrative.country',
elementType: 'geometry.fill',
stylers: [
{
color: '#ffffff'
}
]
},
{
featureType: 'administrative.country',
elementType: 'labels.icon',
stylers: [
{
color: '#120ac4'
}
]
},
{
featureType: 'administrative.country',
elementType: 'labels.text',
stylers: [
{
color: '#929191'
}
]
},
{
featureType: 'administrative.country',
elementType: 'labels.text.fill',
stylers: [
{
color: '#ffffff'
}
]
},
{
featureType: 'administrative.country',
elementType: 'labels.text.stroke',
stylers: [
{
color: '#929191'
}
]
},
{
featureType: 'administrative.land_parcel',
elementType: 'geometry.stroke',
stylers: [
{
color: '#ecebe7'
}
]
},
{
featureType: 'administrative.land_parcel',
elementType: 'labels.text.fill',
stylers: [
{
color: '#ae9e90'
}
]
},
{
featureType: 'landscape.natural',
elementType: 'geometry',
stylers: [
{
color: '#ecebe7'
}
]
},
{
featureType: 'landscape.natural.terrain',
elementType: 'geometry',
stylers: [
{
color: '#ecebe7'
}
]
},
{
featureType: 'landscape.natural.terrain',
elementType: 'geometry.fill',
stylers: [
{
color: '#fbfaf6'
}
]
},
{
featureType: 'poi',
elementType: 'all',
stylers: [
{
visibility: 'off'
}
]
},
{
featureType: 'poi',
elementType: 'labels.text.fill',
stylers: [
{
color: '#93817c'
}
]
},
{
featureType: 'poi.park',
elementType: 'geometry.fill',
stylers: [
{
visibility: 'off'
}
]
},
{
featureType: 'poi.park',
elementType: 'labels.text.fill',
stylers: [
{
color: '#447530'
}
]
},
{
featureType: 'road',
elementType: 'geometry',
stylers: [
{
color: '#f5f1e6'
}
]
},
{
featureType: 'road.arterial',
elementType: 'geometry',
stylers: [
{
color: '#fdfcf8'
}
]
},
{
featureType: 'road.highway',
elementType: 'geometry',
stylers: [
{
color: '#a9b2af'
}
]
},
{
featureType: 'road.highway',
elementType: 'geometry.fill',
stylers: [
{
color: '#91cab5'
}
]
},
{
featureType: 'road.highway',
elementType: 'geometry.stroke',
stylers: [
{
color: '#6c9e8c'
}
]
},
{
featureType: 'road.highway',
elementType: 'labels.text',
stylers: [
{
color: '#366152'
}
]
},
{
featureType: 'road.highway',
elementType: 'labels.text.fill',
stylers: [
{
color: '#4d612d'
}
]
},
{
featureType: 'road.highway',
elementType: 'labels.text.stroke',
stylers: [
{
color: '#fdfff9'
}
]
},
{
featureType: 'road.highway.controlled_access',
elementType: 'geometry',
stylers: [
{
color: '#cbded8'
}
]
},
{
featureType: 'road.highway.controlled_access',
elementType: 'geometry.stroke',
stylers: [
{
color: '#c0dcd2'
}
]
},
{
featureType: 'road.local',
elementType: 'labels.text.fill',
stylers: [
{
color: '#806b63'
}
]
},
{
featureType: 'transit.line',
elementType: 'geometry',
stylers: [
{
color: '#c0d3cd'
}
]
},
{
featureType: 'transit.line',
elementType: 'labels.text.fill',
stylers: [
{
color: '#8f7d77'
}
]
},
{
featureType: 'transit.line',
elementType: 'labels.text.stroke',
stylers: [
{
color: '#ebe3cd'
}
]
},
{
featureType: 'transit.station',
elementType: 'geometry',
stylers: [
{
color: '#fcf5ef'
}
]
},
{
featureType: 'water',
elementType: 'geometry.fill',
stylers: [
{
color: '#9fd4dc'
}
]
},
{
featureType: 'water',
elementType: 'labels.text.fill',
stylers: [
{
color: '#92998d'
}
]
}
]
\ No newline at end of file
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { MapBoxComponent } from './map-box.component';
describe('MapBoxComponent', () => {
let component: MapBoxComponent;
let fixture: ComponentFixture<MapBoxComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ MapBoxComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MapBoxComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { Router } from '@angular/router';
import { HeaderService } from "@shared/services/header.service";
import { UtilityService } from "@shared/services/utility.service";
import { SideMenuService } from "@shared/services/side-menu.service";
@Component({
selector: 'app-maintainance',
template: `
<div id="not-found">
<div class="maintainance-icon"></div>
<div class="content">
<h2 class="fs-18 bold-600 light-black">New Features Are On The Way! </h2>
<span class="fs-16 light-black">Our team is working on adding new features, we will be back in 20mins (11:20PM),
<br>We apologize for the inconvenience.</span>
</div>
</div>
`,
styleUrls: ['./app.component.sass'],
encapsulation: ViewEncapsulation.None
})
export class MaintainanceComponent implements OnInit {
constructor( private HeaderService: HeaderService,
public util: UtilityService,
public sideMenu: SideMenuService ){
}
ngOnInit() {
this.HeaderService.setWhiteHeader();
this.util.setDarkBg();
this.sideMenu.show();
}
}
<div id="not-found" class="no-access">
<div class="no-access-icon"></div>
<h2 class="access-denied-title">Access Denied!</h2>
<span class="no-access-detail">This feature is available only for JIDO Pro version users</span>
</div>
@import "../../styles.sass"
#not-found
position: absolute
top: 50%
left: 50%
transform: translateX(-50%) translateY(-50%)
text-align: center
.access-denied-title
font-size: 16px
font-weight: bold
.no-access-detail
font-size: 14px
.no-access-icon
background: url(#{$loaderPath}/accessdenied-illustration.png) center no-repeat
background-size: contain
width: 89px
height: 98px
margin: 0 auto 30px auto
font-weight: bold
.not-found-icon
background: url(#{$loaderPath}/404.png) center no-repeat
background-size: contain
width: 336px
height: 336px
margin: 0 auto 30px auto
font-weight: bold
span
font-size: 20px
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { NoAccessComponent } from './no-access.component';
describe('NoAccessComponent', () => {
let component: NoAccessComponent;
let fixture: ComponentFixture<NoAccessComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ NoAccessComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(NoAccessComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { HeaderService } from "@shared/services/header.service";
import { SideMenuService } from '@shared/services/side-menu.service';
import { UtilityService } from "@shared/services/utility.service";
@Component({
selector: 'app-no-access',
templateUrl: './no-access.component.html',
styleUrls: ['./no-access.component.sass']
})
export class NoAccessComponent implements OnInit {
constructor(private HeaderService: HeaderService,
private sideMenuService: SideMenuService,
public util: UtilityService) { }
ngOnInit() {
this.sideMenuService.show();
this.HeaderService.setDashHead();
this.util.setDarkBg();
}
}
<div id="not-found">
<div class="not-found-icon"></div>
<h2 class="fs-18 bold-600 light-black sub-title">Something Went Wrong!</h2>
<span class="fs-18 light-black content">The link you followed may be broken or the page may
have been removed.</span>
<a href="/" class="btn goto-btn fs-18 bold-600">Go To Homepage</a>
</div>
@import "../../styles.sass"
#not-found
position: absolute
top: 50%
left: 50%
transform: translateX(-50%) translateY(-50%)
text-align: center
.sub-title
font-weight: bold
padding-bottom: 10px;
.access-denied-title
font-size: 16px
font-weight: bold
.no-access-detail
font-size: 14px
.content
width: 79%;
display: block;
margin: 0 auto;
.no-access-icon
background: url(#{$loaderPath}/accessdenied-illustration.png) center no-repeat
background-size: contain
width: 89px
height: 98px
margin: 0 auto 30px auto
font-weight: bold
.not-found-icon
background: url(#{$loaderPath}/404-illustration.svg) center no-repeat
background-size: contain
width: 196px
height: 140px
margin: 180px auto 30px auto
font-weight: bold
.maintainance-icon
background: url(#{$loaderPath}/Maint.gif) center no-repeat
background-size: contain;
margin: 50px auto 0 auto;
font-weight: bold;
max-width: 1200px;
min-height: 310px;
span
font-size: 20px
.goto-btn
display: block
background-color: #00b140
border-radius: 23px
color: #ffffff
width: 195px
margin: 0 auto
margin-top: 60px
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { NotFoundComponent } from './not-found.component';
describe('NotFoundComponent', () => {
let component: NotFoundComponent;
let fixture: ComponentFixture<NotFoundComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ NotFoundComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(NotFoundComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { HeaderService } from "@shared/services/header.service";
import { UtilityService } from "@shared/services/utility.service";
import { SideMenuService } from "@shared/services/side-menu.service";
@Component({
selector: 'app-not-found',
templateUrl: './not-found.component.html',
styleUrls: ['./not-found.component.sass']
})
export class NotFoundComponent implements OnInit {
constructor(private HeaderService: HeaderService,
public util: UtilityService,
public sideMenu: SideMenuService) { }
ngOnInit() {
this.HeaderService.setWhiteHeader();
this.util.setDarkBg();
this.sideMenu.hide();
}
}
<div class="loader white" *ngIf="showLoader"></div>
<div *ngIf="!showLoader">
<div id="aggressive-driver-container" class="obddashboard-section-wrapper row">
<div class="section-header no-border">
<h2 class="dashboard-title">Summary</h2>
<!-- Dropdown -->
<div class="dropdown obd-dropdown" [ngClass]="{selected: openRangeDropdown}">
<button (click)="rangeDropdownSelect()" class="dropbtn">
<span>{{rangeDropdown}}</span>
<span class="arrow"></span>
</button>
<div class="type-dropdown dropdown-content">
<span [ngClass]="{selectedItem: rangeDropdown == item}" *ngFor="let item of rangeDropdownList;" (click)="rangeDropdownChange($event,item)">{{item}}</span>
</div>
</div>
<!-- **** -->
<a class="pull-right downloaod-csv" (click)="openModal();"><i class="icon-download"></i> Download Report</a>
</div>
<div class="section-warpper col-xs-12 w-100" (window:resize)="onResize($event)">
<div class="no-data" [hidden]="fuelBasedLineGraphDetails?.length != 0 || topModelsDetails?.length != 0">
<div class="image"></div>
<h3 class="bold">No Data!</h3>
<p>We have insufficient data to show for the
selected time period.</p>
</div>
<div class="row">
<div class="col-sm-7" id="aggressive-driver-rankng-left-graph-div">
<div class="row">
<!-- line graph sections -->
<div #boxWidth class="col-sm-6" *ngFor="let item of fuelBasedLineGraphDetails; let i = index;">
<div class="boxes graph-box">
<h2 class="dashboard-title line-graph-title text-capitalize">{{item.field.replace('_', ' ')}}</h2>
<div class="reading-wrapper">
{{item.percentage | roundOff:2}} <span class="reading-unit">%</span>
<!-- <span [ngClass]="{ 'upicon': (item.indicator == 1), 'downIcon': (item.indicator == -1), 'noIcon': (item.indicator == 0)}">
<i></i>{{item.difference | roundOff:2}}%
</span> -->
<span *ngIf="lineGraphDetails && getBoxWidth">
<app-line-chart *ngIf="loadChart" getBoxWidth="{{getBoxWidth}}" [dataList]="lineGraphDetails[item.field].data"
type="{{item.field}}" graphType="{{lineGraphDetails[item.field].graphType}}" [labelArray]="loadChartLabels" graphPage="aggressive" tooltipText="Drivers"></app-line-chart>
</span>
</div>
</div>
</div>
<!-- ********* -->
</div>
</div>
<div class="col-sm-5 aggressive-driver-rankng-right-div">
<div class="boxes top-models" *ngIf="topModelsDetails && topModelsDetails.length != 0" id="aggressive-driver-rankng-right-table-div">
<h4>Top Models</h4>
<table class="top-model-list">
<tr *ngFor="let item of topModelsDetails">
<td>
<!-- <div class="model-name">{{item.vehicle_name}}</div> -->
<div class="model-brand">{{item.vehicle_brand}} {{item.vehicle_name}}</div>
<div class="model-rating">Avg. Driver Rating - <span>{{item.avg_user_score | roundOff:2}}</span></div>
<div class="model-type">{{item.fuel_type_value | roundOff:1}}
<!-- <span>{{item.vehicle_brand}}</span>
<span *ngIf="!item.vehicle_brand"> - </span> -->
</div>
</td>
<td>
<div class="model-title">{{item.total_users}}</div>
<div class="model-sub">No. of Drivers</div>
</td>
<td>
<div class="model-title">{{item.fuel_percentage | roundOff:1}}%</div>
<div class="model-sub">of {{item.fuel_type_value}}</div>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="table-section aggressive-table-section" *ngIf="aggreessiveDriverDetails">
<div class="table-header">
<h2 class="dashboard-title">Vehicles</h2>
<div class="pull-right title-search-wrap">
<div class="title-search">
<input type="text" (keyup)="showClearbutton(searchInput.value)" placeholder="Search by Driver name or Vehicle number"
#searchInput (keyup.enter)="searchUser(searchInput.value)">
<i *ngIf="clearbutton" class="clear-search pull-right" (click)="searchInput.value = ''; clearInput()"></i>
</div>
<!-- Dropdown -->
<div class="dropdown obd-dropdown" [ngClass]="{selected: vehicleTypeDropdown}">
<button (click)="vehicleTypeDropDownSelect()" class="dropbtn">
<span>{{fuelDropdownValue | capitalizeFirst }}</span>
<span class="arrow"></span>
</button>
<div class="type-dropdown dropdown-content">
<span [ngClass]="{selectedItem: fuelDropdownValue == item}" *ngFor="let item of fuelDropdown;" (click)="fuelBasedDropdown($event,item)">{{item}}</span>
</div>
</div>
<!-- **** -->
</div>
</div>
<div class="white-box table-loader">
<div class="loader white" *ngIf="showTableLoader"></div>
<div class="section-wrap">
<app-obd-table *ngIf="tableDetails && !showTableLoader" [tableData]="tableDetails" tableType="driverDetails"
[allDetails]="aggreessiveDriverDetails" [search]="searchInput.value"></app-obd-table>
<app-pagination [hidden]="hidePagination" singlePageLength={{paginationDataLength}} paginationLength={{paginationLength}}
(selectPage)="pageChanged($event)" *ngIf="!noContent && !showPaginationLoader && paginationDataLength && paginationLength"></app-pagination>
<div class="no-table-content" *ngIf="tableDetails && tableDetails.body.length == 0 && !showTableLoader && !searchInput.value">
<div class="image"></div>
<h3 class="bold">No Vehicles Found!</h3>
<p>We didn’t find any vehicles.</p>
</div>
</div>
</div>
</div>
<div id="download-csv-modal" [ngClass]="{'show': this.showModal, 'hide' : !this.showModal}" *ngIf="this.showModal">
<div id="myModal" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" (click)="closeModal()" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">Download Data</h4>
<p>Select a metric option and date range to export data</p>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-7">
<ul class="metric-option-list">
<li>
<input type="radio" name="metric-option" id="all" checked><label for="all">Summary</label>
<p>
Metrics of Avg. Aggressive driver ranking for Petrol, Diesel, Hybrid and Electric and Top Vehicle
Models
</p>
</li>
</ul>
</div>
<div class="col-md-5">
<div class="date-range">
<h4>Date Range</h4>
<div class="form-group">
<div class="form-date-row">
<my-date-picker (input)="onChange($event.target.value)" id="date-selector" name="mydate"
[selector]="selector" placeholder="From" [defaultMonth]="defaultMonth" [options]="myDatePickerOptionsFrom"
(dateChanged)="onDateChanged($event, 'FROM')" [selDate]="selDatefrom" required></my-date-picker>
</div>
<div class="form-date-row">
<my-date-picker (input)="onToChange($event.target.value)" id="date-selector" name="mydate"
[selector]="selector" placeholder="To" [defaultMonth]="defaultMonth" [options]="myDatePickerOptions"
(dateChanged)="onDateChanged($event, 'TO')" [selDate]="selDateto" required></my-date-picker>
</div>
</div>
</div>
<!-- <div class="file-format">
<h4>File Format</h4>
<select class="" name="" disabled>
<option value="">.csv</option>
</select>
</div> -->
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" [disabled]="isCsvDownloadBtn" class="btn" (click)="downloadInformation()">Download
Data</button>
</div>
</div>
</div>
</div>
</div>
</div>
@import "../../../styles.sass"
@import "../../../obd-shared.sass"
#aggressive-driver-container
.graph-box.boxes
height: 230px
.reading-wrapper
text-align: left
color: #222222
font-size: 30px;
font-family: $openSansBold;
padding: 30px 18px;
.reading-unit
font-size: 22px;
font-family: $openSansRegular;
.no-data
padding: 15px 0 35px!important;
.section-header
.downloaod-csv
color: #00b140;
.top-models
padding: 20px
padding-bottom: 0
h4
font-family: $openSansSemiBold
.top-model-list
width: 100%
tr
td
&:first-child
width: 50%
tr
&:not(:last-child)
td
border-bottom: 1px solid #eaeaea
td
padding: 18px 0
font-size: 16px
&:last-child
padding-left: 20px
li
display: flex
align-items: center
padding: 18px 0
font-size: 16px
&:not(:last-child)
border-bottom: 1px solid #eaeaea
.col-1
flex-grow: 1
.col-2
padding-right: 50px
.model-name
font-family: $openSansBold
.model-brand
font-family: $openSansSemiBold
.model-rating
color: #666666
padding: 4px 0
font-family: $openSansSemiBold
span
color: #222222
font-family: $openSansSemiBold
.model-type
color: #666666
font-family: $openSansBold
font-size: 14px
text-transform: capitalize
span
font-family: $openSansBold
.model-title
text-align: center
font-family: $openSansBold
font-size: 22px
color: #222222
.model-sub
text-align: center
font-size: 12px
color: #666666
font-family: $openSansSemiBold
.title-search
margin-right: 20px
.table-loader
position: relative
min-height: 300px
#aggressive-driver-rankng-right-table-div
overflow-y: auto
.aggressive-table-section
.title-search
input
float: left
@media only screen and (max-width: 991px)
#aggressive-driver-rankng-left-graph-div
width: 100%
.aggressive-driver-rankng-right-div
width: 100%
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { AggressiveDriverComponent } from './aggressive-driver.component';
describe('AggressiveDriverComponent', () => {
let component: AggressiveDriverComponent;
let fixture: ComponentFixture<AggressiveDriverComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ AggressiveDriverComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AggressiveDriverComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment