Commit 2188a7ee by Ali Arshad

integrated bootstrap and user login flow

parent 4d5a4ebd
......@@ -19,6 +19,9 @@
"testTsconfig": "tsconfig.spec.json",
"prefix": "app",
"styles": [
"../node_modules/bootstrap-less/bootstrap/bootstrap.less",
"../node_modules/font-awesome/less/font-awesome.less",
"../node_modules/ng2-toastr/bundles/ng2-toastr.min.css",
"styles.less"
],
"scripts": [],
......
......@@ -22,7 +22,12 @@
"@angular/platform-browser": "^5.2.0",
"@angular/platform-browser-dynamic": "^5.2.0",
"@angular/router": "^5.2.0",
"bootstrap": "^4.0.0",
"bootstrap-less": "^3.3.7",
"core-js": "^2.4.1",
"font-awesome": "^4.7.0",
"ng2-toastr": "^4.1.2",
"ngx-bootstrap": "^2.0.2",
"rxjs": "^5.5.6",
"zone.js": "^0.8.19"
},
......
import { TestBed, inject } from '@angular/core/testing';
import { HttpService } from './http.service';
describe('HttpService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [HttpService]
});
});
it('should be created', inject([HttpService], (service: HttpService) => {
expect(service).toBeTruthy();
}));
});
import {Injectable} from '@angular/core';
import {Headers, Http, RequestOptions} from '@angular/http';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/share';
import {ToastsManager} from 'ng2-toastr/ng2-toastr';
import {Constants} from '../constants';
import {Router} from '@angular/router';
@Injectable()
export class HttpService {
private accessTokken: string;
private headers;
private options;
private api = Constants.API_URL;
private sendAuthMsg;
constructor(private http: Http,
private toastr: ToastsManager,
private router: Router) {
this.sendAuthMsg = true;
}
setTokken(value) {
this.accessTokken = value;
}
createHeader() {
if (this.accessTokken) {
this.headers = new Headers({'Content-Type': 'application/json'});
this.headers.append('Authorization', this.accessTokken);
this.options = new RequestOptions({headers: this.headers});
}
else {
this.headers = new Headers({'Content-Type': 'application/json'});
this.options = new RequestOptions({headers: this.headers});
}
return this.options;
}
sendUnAuthorizedMessage(message) {
message = message || 'You need to login first.';
this.sendAuthMsg = false;
this.toastr.error(message, null, {showCloseButton: true});
setTimeout(() => {
this.sendAuthMsg = true;
}, 5000);
}
showError(error, showErrors) {
switch (error.status) {
case 401:
if (showErrors.e401 != false) {
if (this.sendAuthMsg) {
const body = error.json();
const errorMsg = body.message || 'You need to login first';
this.sendUnAuthorizedMessage(errorMsg);
}
this.router.navigate(['/']);
}
break;
case 400:
if (showErrors.e400 != false) {
const body = error.json();
const errorMsg = body.message || 'There seems to be some error.';
this.toastr.error(errorMsg, null, {showCloseButton: true});
}
break;
case 500:
if (showErrors.e500 != false) {
this.toastr.error('We are unable to process your request.', null, {showCloseButton: true});
}
break;
case 404:
if (showErrors.e404 != false) {
this.toastr.error('API resource does not exist', null, {showCloseButton: true});
}
break;
case 422:
if (showErrors.e422 != false) {
let errorMsg;
const body = error.json();
errorMsg = body.message;
this.toastr.error(errorMsg, 'Oops!', {showCloseButton: true});
}
break;
}
}
post(method, value, showErrors = {}) {
const url = this.api + method;
const observable = this.http.post(url, value, this.createHeader()).map((response) => {
return response.json();
}).share();
observable.subscribe(
data => {},
error => {
this.showError(error, showErrors);
}
);
return observable;
}
get(method, value = '', showErrors = {}) {
const url = this.api + method + value;
const observable = this.http.get(url, this.createHeader()).map((response) => {
return response.json();
}).share();
observable.subscribe(
data => {
},
error => {
this.showError(error, showErrors);
}
);
return observable;
}
delete(method, value = '', showErrors = {}) {
const url = this.api + method + value;
const observable = this.http.delete(url, this.createHeader()).map((response) => {
return response.json();
}).share();
observable.subscribe(
data => {
},
error => {
this.showError(error, showErrors);
}
);
return observable;
}
put(method, value, showErrors = {}) {
const url = this.api + method;
const observable = this.http.put(url, value, this.createHeader()).map((response) => {
return response.json();
}).share();
observable.subscribe(
data => {
},
error => {
this.showError(error, showErrors);
}
);
return observable;
}
}
import { TestBed, inject } from '@angular/core/testing';
import { LocalStoreService } from './local-store.service';
describe('LocalStoreService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [LocalStoreService]
});
});
it('should be created', inject([LocalStoreService], (service: LocalStoreService) => {
expect(service).toBeTruthy();
}));
});
import { Injectable } from '@angular/core';
@Injectable()
export class LocalStoreService {
constructor() { }
get(key)// key -> 'userTokken' for access tokken & 'userDetail' for user detail
{
return localStorage.getItem(key);
}
set(key,value)
{
localStorage.setItem(key,value);
}
remove(key)
{
localStorage.removeItem(key);
}
}
import { Component } from '@angular/core';
import {Component, ViewContainerRef} from '@angular/core';
import {Router} from '@angular/router';
import {ToastsManager} from 'ng2-toastr';
import {BsModalService} from 'ngx-bootstrap/modal';
import {BsModalRef} from 'ngx-bootstrap/modal/bs-modal-ref.service';
import {Constants} from './constants';
import {UserService} from './users/user.service';
import {SessionModalComponent} from './shared/session-modal/session-modal.component';
@Component({
selector: 'app-root',
......@@ -6,5 +14,29 @@ import { Component } from '@angular/core';
styleUrls: ['./app.component.less']
})
export class AppComponent {
title = 'wah';
bsModalRef: BsModalRef;
constructor(public toastr: ToastsManager, vRef: ViewContainerRef,
private user: UserService,
private modalService: BsModalService,
private router: Router) {
this.toastr.setRootViewContainerRef(vRef);
this.user.onSessionDestroyed.subscribe(data => {
this.showLogoutPopup();
});
}
showLogoutPopup() {
const initialState = {
title: 'Session has been closed',
body: 'Session has been closed.',
closeBtnName: 'OK'
};
this.bsModalRef = this.modalService.show(SessionModalComponent, {initialState});
this.modalService.onHide.subscribe(data => {
this.router.navigate([Constants.APP_URLS.login]);
}, err => {
});
}
}
import {BrowserModule} from '@angular/platform-browser';
import {ToastModule} from 'ng2-toastr/ng2-toastr';
import {NgModule} from '@angular/core';
import {HttpModule} from '@angular/http';
import {FormsModule} from '@angular/forms';
import {LayoutsModule} from './layouts/layouts.module';
import {RoutesModule} from './routes/routes.module';
import {AppComponent} from './app.component';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import { ModalModule } from 'ngx-bootstrap/modal';
import {HttpService} from './app-services/http.service';
import { SessionModalComponent } from './shared/session-modal/session-modal.component';
@NgModule({
declarations: [
AppComponent
AppComponent,
SessionModalComponent
],
imports: [
BrowserModule,
LayoutsModule,
RoutesModule
RoutesModule,
HttpModule,
FormsModule,
BrowserAnimationsModule,
ToastModule.forRoot(),
ModalModule.forRoot()
],
entryComponents: [ SessionModalComponent ],
providers: [
HttpService
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {
......
let env = 'local';
let API_URL;
const APP_URLS = {
login: '/',
dashboard: '/dashboard',
forgetPassword: '/forgot',
newPassword: '/set-new'
};
if (window.location.hostname.indexOf('stage') === -1) {
env = 'stage';
} else {
env = 'prod';
}
if (env === 'prod') {
API_URL = 'http://localhost/';//will be set after deployment
} else {
API_URL = 'http://localhost/';
}
export class Constants {
public static get API_URL(): string {
return API_URL;
}
public static get APP_URLS(): any {
return APP_URLS;
}
}
......@@ -2,6 +2,7 @@ import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {RoutesModule} from '../routes/routes.module';
import {UsersModule} from '../users/users.module';
import {PublicComponent} from './public/public.component';
import {ProtectedComponent} from './protected/protected.component';
......@@ -9,7 +10,8 @@ import {ProtectedComponent} from './protected/protected.component';
@NgModule({
imports: [
CommonModule,
RoutesModule
RoutesModule,
UsersModule
],
declarations: [PublicComponent, ProtectedComponent]
})
......
.dashboard_body {
background-color: #edebe9;
font-family: MrEavesModOT;
font-size: 16px;
letter-spacing: 0.3px;
color: rgb(75, 87, 95);
line-height: 1.75;
height: 100vh;
}
a, i {
color: #009ee2 !important;
cursor: pointer;
}
.navbar {
background-color: white;
}
.menu {
z-index: 1000;
box-shadow: 0px 3px 15px #636363 !important;
margin-bottom: 0;
}
.navbar {
position: relative;
min-height: 75px !important;
border: 0px;
}
.navbar-nav > li > a {
padding: 28px 25px !important;
font-size: 22px;
}
.navbar-brand {
float: left;
height: 75px;
width: 130px;
padding: 11px 20px;
font-size: 18px;
line-height: 20px;
}
.navbar-brand > img {
width: 100%;
padding: 0px !important;
}
.navbar-toggle {
margin-top: 25px !important;
}
.navbar.navbar-default.navbar.menu.main li {
border-right: 1px solid #dfdfdf !important;
}
.proj {
height: 35px;
}
.colm-chart {
background-color: white;
margin-top: 2%;
padding: 10px;
}
#m-dashboard .first {
margin-top: 2%;
padding-left: 0px;
padding-right: 0px;
padding-bottom: 1%;
}
#m-dashboard li {
border-right: none !important;
}
#m-dashboard .box {
position: relative;
border-radius: 3px;
background: #ffffff;
margin-bottom: 20px;
width: 100%;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
padding: 25px;
}
.box-header {
color: #444;
display: block;
position: relative;
}
.box-body {
margin: 0px;
}
#m-dashboard .box-header h5 {
margin-top: 0px;
font-size: 15px;
font-weight: bold;
}
.no-padd {
padding: 0px !important;
}
#m-dashboard .checkbox-inline, .radio-inline {
position: relative;
display: inline-block;
padding-left: 0px;
}
#bank_chart, #bank_chart1, #bank_chart2, .user_chart, #chart_specifiers, #chart_specifiers {
width: 100%;
height: 350px;
margin: 0 -10px;
}
.highcharts-legend-item.highcharts-bar-series span {
color: #999999 !important;
font-family: 'Raleway', sans-serif !important;
font-weight: initial !important;
height: 28px;
}
.highcharts-legend-item.highcharts-bar-series.highcharts-color-undefined {
line-height: 17px !important;
}
.highcharts-legend-box {
height: 110px !important;
}
.btn-user {
display: inline-block;
background: #009ee2;
height: 76px;
width: 76px;
line-height: 76px;
text-align: center;
border-radius: 0px;
font-size: 31px;
border-right: solid 1px #fff;
}
.btn-user img {
width: 75%;
}
.btn-user .img-back {
display: inline-block;
background: #FFF;
border-radius: 50px;
height: 40px;
width: 40px;
line-height: 40px;
}
.user-dropdown {
left: initial;
border: none;
border-radius: 0px;
background: #009ee2;
padding: 18px 0;
}
.dropdown-menu.user-dropdown > li > a {
display: block;
padding: 3px 20px;
clear: both;
font-weight: 400;
line-height: 1.42857143;
color: #FFF !important;
white-space: nowrap;
}
.dropdown-menu.user-dropdown > li > a:focus, .dropdown-menu > li > a:hover {
color: #009ee2 !important;
text-decoration: none;
background-color: #f5f5f5;
}
.dropdown-menu.user-dropdown li .u_name {
font-size: 22px;
font-weight: 100;
}
.dropdown-menu.user-dropdown li {
border-right: none;
}
.dropdown-menu {
display: block;
}
.box-heading h6 {
font-size: 22px;
font-family: FuturaICGLight;
color: rgb(75, 87, 95);
text-transform: uppercase;
}
.first {
margin-top: 12px;
}
.proj span:nth-child(2) {
font-size: 16px;
font-family: MrEavesModOT;
color: rgb(255, 255, 255);
font-weight: 100;
}
#a_dashboard {
}
#a_dashboard {
}
.show {
margin: 0;
padding: 3% 7%;
}
.pro {
padding-right: 0;
margin-bottom: 1.5%;
}
#a_dashboard .p_down {
text-align: center;
position: relative;
bottom: -20px;
}
#a_dashboard .box-container .radio {
position: relative;
display: block;
margin: 30px 0px -30px 0px !important;
padding: 0px !important;
}
.show {
height: 35px;
margin: 0;
padding: 3% 7%;
float: right;
background-color: #b7b0a7 !important;
z-index: 0;
box-shadow: -2px 6px 9px 4px #cbcbcb;
font-size: 16px;
font-family: MrEavesModOT;
font-weight: bold;
color: rgb(255, 255, 255) !important;
line-height: 1.688;
}
.show p {
color: #FFF !important;
}
/* -------------------------------------css for add-celling page -------------------------------------------*/
.add-celling {
}
.add-celling .proj span:nth-child(1) {
font-size: 16px;
font-family: MrEavesModOT;
color: rgb(0, 158, 226);
line-height: 1.8;
margin-right: 15px;
}
.add-celling .box-container .p_r {
margin-bottom: 35px !important;
}
.add-celling label {
color: rgb(93, 107, 107);
font-weight: 100 !important;
line-height: 2.0;
padding-left: 25px;
}
.add-celling .top_links ul {
padding: 0px;
margin-bottom: 0px;
line-height: 17px;
line-height: 1.5;
}
.add-celling input.noborder.form-control {
border-radius: 0px;
}
.add-celling .col-lg-4.col-md-4.col-sm-4.col-xs-12.last {
padding-right: 0px;
}
.add-celling .top_links li {
border-right: none !important;
}
.add-celling .top_links li a {
font-size: 14px;
text-transform: initial;
font-weight: 100;
color: #ccc !important;
}
.lh-15 {
line-height: 15px !important;
}
.m_b {
margin: 0px 0px -5px 0px !important;
}
.add-celling .top_links li a:hover {
color: #009ee2 !important;
cursor: pointer;
font-size: 16px;
}
.add-celling .top_links {
padding: 1px 0px 0px 15px;
text-align: left;
height: 10vh;
}
.add-celling a.btn.btn-primary {
color: #fff !important;
background: #009ee2;
border-radius: 0px;
border: none;
padding: 7px 14px;
font-size: 15px;
}
.heading2 {
padding: 0px 0 15px !important;
}
.add-celling .col_insulation .form-control {
border-radius: 0px !important;
}
.add-celling .col_insulation .col-lg-3.col-md-3.col-sm-3.col-xs-3.pr {
padding-right: 0px;
}
#add_encasement.add-accaustic-ceiling .e_row {
margin-bottom: 35px !important;
}
.add-accaustic-ceiling .lastDiv2_2 {
margin-top: 7px;
}
.add-accaustic-ceiling .lastDiv2_3 {
margin-top: 16px;
}
.add-accaustic-ceiling .lastDiv3 {
margin-top: 20px;
}
.add-accaustic-ceiling .lastDiv2_4 {
margin-top: 20px;
}
#add_encasement.add-accaustic-ceiling .e_row .col-lg-6.col-md-6.r_size label {
margin-top: -4px;
}
/* -------------------------------------subdomain_software-admin-dash page -------------------------------------------*/
.box-container {
background: #FFF !important;
padding: 30px 30px;
}
.box-container .box-heading {
font-size: 22px;
font-family: FuturaICGLight;
color: rgb(75, 87, 95);
text-transform: uppercase;
padding: 0px 0 25px;
}
.box-container .checkbox, .radio {
position: relative;
display: block;
margin: 1% 0% 1% 0% !important;
}
.p_down {
text-align: center;
position: relative;
bottom: -58px;
}
.btn-down {
background: #009ee2;
color: #fff !important;
/* padding: 10px; */
height: 32px;
width: 32px;
line-height: 30px;
border: solid 2px #FFF;
border-radius: 50px;
text-align: center !important;
}
#cke_editor #cke_46 {
display: none !important;
}
.box-container .table-bordered > tbody > tr > td, .table-bordered > tbody > tr > th, .table-bordered > tfoot > tr > td, .table-bordered > tfoot > tr > th, .table-bordered > thead > tr > td, .table-bordered > thead > tr > th {
border-right: 1px solid #ddd !important;
border: none;
}
.box-container .table > thead > tr > th {
vertical-align: bottom;
border-bottom: 1px solid #ddd;
}
.box-container .input-group .form-control {
position: relative;
z-index: 2;
float: left;
width: 100%;
margin-bottom: 0;
border-radius: 50px;
}
.box-container .input-group-btn:last-child > .btn, .input-group-btn:last-child > .btn-group {
z-index: 2;
border-radius: 50px;
background: #009ee2;
}
.box-container .input-group-btn {
position: relative;
font-size: 0;
white-space: nowrap;
right: 30px;
}
.box-container .btn-primary {
color: #fff !important;
padding: 6px 14px;
background-color: #009ee2 !important;
border-color: #009ee2;
}
.box-container .btn-primary i {
color: #FFF !important;
font-size: 17px;
}
.box-container .input-group {
position: relative;
display: table;
border-collapse: separate;
margin-right: -33px;
}
.container.last .pagination {
display: inline-block;
padding-left: 0;
margin: 0px 0;
}
.container.last .pagination > li {
display: inline;
border-right: none !important;
}
.container.last .pagination > li > a, .pagination > li > span {
border: none !important;
border-radius: 0px;
}
.container.last .pagination > .active > a, .pagination > .active > a:focus, .pagination > .active > a:hover, .pagination > .active > span, .pagination > .active > span:focus, .pagination > .active > span:hover {
z-index: 3;
color: #009ee2;
cursor: default;
background-color: #ffffff;
border-color: #ffffff;
}
.container.last .pagination > .disabled > a, .pagination > .disabled > a:focus, .pagination > .disabled > a:hover, .pagination > .disabled > span, .pagination > .disabled > span:focus, .pagination > .disabled > span:hover {
color: #fff;
cursor: not-allowed;
background-color: #b7b0a7;
border-color: #ddd;
border-radius: 0px !important;
}
.pagination .p_next {
background: #009ee2;
color: #fff !important;
}
.pagination a.p_next:hover {
color: #009ee2 !important;
}
.bd button {
background-color: #009ee2;
font-family: FuturaPT;
color: rgb(255, 255, 255);
font-size: 15px;
font-weight: 500;
line-height: 1.8;
border: none;
letter-spacing: 0.89x;
background-image: url(/assets/img/right.png);
background-repeat: no-repeat;
border: none;
outline: none;
padding: 1.6% 0;
padding-right: 4%;
background-size: 7%;
background-position: 153px 8px;
width: 170px;
}
/* --PAGE CSS END ---*/
/* -------------------------------------single project page -------------------------------------------*/
#project_wrapper {
margin: 0px;
padding: 0px;
}
td a i.fa {
color: #009ee2 !important;
padding-right: 10px;
}
td a i.fa:hover {
color: #25596f !important
}
#project_wrapper .box-container li {
border-right: none !important;
}
#project_wrapper .Project_detail {
border-bottom: solid 1px #e6e6e6;
padding-bottom: 15px;
margin-bottom: 15px;
}
#project_wrapper .box-container .box-heading {
padding: 10px 0;
}
#project_wrapper .box-heading h6 {
font-size: 22px;
font-family: FuturaICGLight;
color: rgb(75, 87, 95);
text-transform: uppercase;
}
#project_wrapper .box-heading .actions {
text-align: right;
font-weight: 600;
font-size: 18px;
font-family: FuturaICGLight;
color: rgb(75, 87, 95);
text-transform: capitalize;
}
.Project_detail li h5 {
font-size: 14px;
font-size: 18px;
font-weight: 600;
margin-top: 10px;
margin-bottom: 0px;
}
.Project_detail li h5 .fa {
color: #009ee2 !important;
padding-left: 15px;
font-weight: 100;
font-size: 20px;
}
#project_wrapper .box-body .Project_detail li span {
color: #899898 !important;
}
#project_wrapper .box-container .box-body .table > thead > tr > th {
vertical-align: bottom;
border-bottom: 1px solid #ddd;
text-align: center;
text-transform: uppercase;
font-size: 15px;
}
#project_wrapper .box-container .box-body .table > thead > tr > th a {
color: #000000 !important;
text-decoration: none !important;
}
#project_wrapper .box-container .box-body .table-bordered > tbody > tr > td {
border-right: 1px solid #ddd !important;
border: none;
text-align: center;
color: #a5a2a2;
}
#project_wrapper .box-container .box-body .table-bordered .th_action {
text-transform: capitalize;
}
#project_wrapper .box-container .box-body .t_headimg h5 {
font-size: 18px;
margin-top: 10px;
margin-bottom: 20px;
}
#project_wrapper .p_down {
text-align: center;
position: relative;
bottom: -48px;
}
#project_wrapper .box-container .box-body .colm-system {
background: #f8f7f6;
padding: 10px;
}
#project_wrapper .box-container .box-body .colm-system img {
width: 100%;
}
#project_wrapper .box-container .box-body .colm-system h1 {
font-size: 22px;
color: #009ee2;
margin: 35px 0px 0px;
text-align: center;
}
#project_wrapper .box-container .box-body .colm-system .col-action {
position: absolute;
bottom: -19px;
right: 15px;
text-align: right;
}
.colm-system .col-action .btn-act {
height: 28px;
width: 28px;
text-align: center;
line-height: 30px;
border-radius: 50px;
background: #009ee2;
color: #fff !important;
font-size: 18px;
font-weight: 200 !important;
}
#project_wrapper .box-container .box-body .r_sm .col-lg-3.col-md-3.col-sm-6.col-xs-12 {
margin-bottom: 25px !important;
}
.m-bot30 {
margin-bottom: 30px !important;
}
.accept i {
color: #fff !important;
padding-left: 8px;
}
.col_opacity {
opacity: 0.4;
}
title {
background: red;
}
.modal.in .modal-dialog.t_modal {
top: 280px;
width: 360px !important;
}
.t_modal .modal-content {
background: transparent;
border-radius: 0px;
border-top: solid 5px #009ee2 !important;
border: none;
box-shadow: none;
}
.t_modal .modal-content .modal-body {
background: #fff;
position: relative;
padding: 15px;
}
.t_modal .modal-content .modal-footer {
padding: 0px;
text-align: right;
border-top: none;
}
.t_modal .modal-content .modal-footer
.btn-back {
text-shadow: none;
background: #b7b0a7;
border-radius: 0px;
color: #fff;
margin-right: -3px;
}
.t_modal .modal-content .modal-footer .btn-save {
text-shadow: none;
background: #009ee2;
border-radius: 0px;
color: #fff;
}
.p-btn {
border: none;
display: inline-block;
padding: 10px 20px;
margin-bottom: 0;
font-size: 14px;
font-weight: 400;
line-height: 1.42857143;
text-align: center;
white-space: nowrap;
vertical-align: middle;
-ms-touch-action: manipulation;
touch-action: manipulation;
cursor: pointer;
}
a.p-btn.btn-back {
color: #fff !important;
text-decoration: none;
}
a.p-btn.btn-save {
color: #fff !important;
text-decoration: none;
}
.row.r_sm {
margin-bottom: 30px;
}
/* --PAGE CSS END ---*/
.add-lining .fontsize > a {
font-size: 13px;
color: #868686 !important;
font-weight: bold !important;
text-transform: capitalize;
}
.add-lining .fontsize > a:hover {
font-size: 16px;
color: #009ee2 !important;
font-weight: bold !important;
}
/* -------------------------------------css for search_results -------------------------------------------*/
#search_results {
margin: 0px;
padding: 0px;
}
#search_results .proj {
background-position: -22px -2px;
}
#search_results .box-heading h6 {
font-size: 22px;
font-family: FuturaICGLight;
color: rgb(75, 87, 95);
text-transform: uppercase;
}
#search_results .box-heading .actions {
text-align: right;
font-weight: 600;
font-size: 18px;
font-family: FuturaICGLight;
color: rgb(75, 87, 95);
text-transform: capitalize;
}
.actions a {
padding: 0 5px;
font-size: 17px;
}
.c-row {
padding: 0 15px;
text-align: center;
}
.c-row .col-b {
border: solid 1px #ccc;
padding: 30px 30px;
color: #009ee2;
}
.c-row .col-b .col-lg-7.col-md-7.col-sm-12.col-xs-12 {
text-align: right;
}
.c-row .col-b h1 {
margin: 0px;
font-weight: 600;
text-align: left;
}
.c-row .col-b span {
font-size: 20px;
font-weight: 200;
}
#search_results .p_down {
text-align: center;
position: relative;
bottom: -49px;
}
.m-top40 {
margin-top: 40px;
}
.box-container .box-heading .sort {
font-size: 12px;
font-weight: 600;
padding: 0px;
text-transform: capitalize;
padding-top: 6px;
}
.td_added_p {
text-align: center;
background: #009ee2;
color: #FFF !important;
}
.td_added_p i {
color: #FFF !important;
padding-left: 15px;
}
.td_add_p {
text-align: center;
color: #009ee2 !important;
}
.td_add_p i {
color: #009ee2 !important;
padding-left: 15px;
}
.s-form.form-group .form-control {
padding: 6px 5px !important;
border-radius: 0px;
}
/* --PAGE CSS END ---*/
tspan.highcharts-text-outline {
stroke: none !important;
}
rect.highcharts-point {
fill: #009ee2;
}
/* -------------------------------------css for ADD-encasement -------------------------------------------*/
#add_encasement {
margin: 0px;
padding: 0px;
}
.add-accaustic-ceiling .proj span:nth-child(1) {
font-size: 16px;
font-family: MrEavesModOT;
color: rgb(0, 158, 226);
line-height: 1.8;
margin-left: -19px;
}
.add-accaustic-ceiling .lastP {
margin-left: 0;
color: #989898;
margin-top: 0%;
}
#add_encasement .box-heading h6 {
font-size: 22px;
font-family: FuturaICGLight;
color: rgb(75, 87, 95);
text-transform: uppercase;
}
.add-accaustic-ceiling h3 {
font-size: 16px;
font-weight: bold;
margin-top: 0px;
margin-bottom: 10px;
color: #4b575f;
}
#add_encasement .box-heading .actions {
text-align: right;
font-weight: 600;
font-size: 18px;
font-family: FuturaICGLight;
color: rgb(75, 87, 95);
text-transform: capitalize;
}
#add_encasement .container.first {
background: #fff;
}
#add_encasement .proj {
background-image: url(/assets/img/button.png);
background-repeat: no-repeat;
border: none;
outline: none;
padding-right: 4%;
width: 220px;
}
#add_encasement a.btn.btn-primary {
color: #fff !important;
background: #009ee2;
border-radius: 0px;
border: none;
padding: 7px 14px;
font-size: 15px;
}
#add_encasement .e_row {
margin-bottom: 25px;
}
#add_encasement .e_row p {
font-size: 16px;
font-weight: bold;
margin-top: 0px;
margin-bottom: 10px;
color: #4b575f;
}
p.sizeX {
font-weight: 100 !important;
color: #4b575f;
}
#add_encasement h2 {
color: #4b575f;
font-size: 18px;
margin: 0;
font-weight: bold;
font-family: FuturaICGLight;
}
#add_encasement .right-side h3 {
font-size: 16px;
font-weight: bold;
margin-top: 0px;
margin-bottom: 10px;
color: #4b575f;
}
#add_encasement .e_row label {
color: rgb(93, 107, 107);
font-weight: 200;
margin-left: -4px;
}
.c-text {
font-size: 13px;
line-height: 1.1;
text-align: justify;
padding: 0px;
}
.c-label {
color: rgb(93, 107, 107);
font-weight: bold;
line-height: 1.19;
font-size: 15px;
}
#add_encasement a.accept {
background-color: #009ee2;
padding: 1.5% 14%;
font-family: FuturaPT;
color: rgb(255, 255, 255);
font-size: 15px;
font-weight: 500;
line-height: 1.8;
}
#add_encasement .accept a {
color: #fff !important;
text-decoration: none;
}
#add_encasement .accept p {
margin-bottom: 0px !important;
}
#add_encasement p.fsr {
margin-top: 30px;
}
#add_encasement .proj {
background-position: -30px -9px;
}
#add_encasement .form-control {
border-radius: 0px;
}
#add_encasement .col-lg-4.col-md-4.col-sm-4.col-xs-4.pr {
padding-right: 0px;
}
.lastDiv1 {
margin-bottom: 15px;
}
.lastDiv1_1 {
margin-bottom: 30px;
}
/* --PAGE CSS END ---*/
/* -------------------------------------css for add_partition page -------------------------------------------*/
.add_partition {
}
.add_partition .proj {
background-position: -22px -2px;
}
.line {
border-bottom: 1px solid #f0f0f0;
margin: 5px 0 10px 0;
}
.add_partition label {
line-height: 30px !important;
}
.add_partition .box-container .input-group .form-control {
position: relative;
z-index: 2;
float: left;
width: 100%;
margin-bottom: 0;
border-radius: 4px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-right: 0px;
}
.add_partition .input-group-addon {
padding: 6px 6px;
font-size: 14px;
font-weight: 400;
line-height: 1;
color: #000000;
text-align: center;
background-color: #fff;
border: 1px solid #ccc;
border-radius: 4px;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-left: 0px !important;
}
.add_partition .input-group-addon a, i {
color: rgb(75, 87, 95) !important;
cursor: pointer;
}
.add_partition .box-container .input-group {
position: relative;
display: table;
border-collapse: separate;
margin-right: 0;
}
.add_partition .box-container h3 {
font-size: 16px;
font-weight: bold;
margin-top: 0px;
margin-bottom: 10px;
color: #4b575f;
}
.add_partition .box-container h2 {
font-size: 16px;
margin: 0px -14px 25px;
}
.add_partition .box-container .p_r {
margin-bottom: 25px;
}
.navbar-default .navbar-nav > .open > a, .navbar-default .navbar-nav > .active > a {
background: #009ee2 !important;
color: #FFF !important;
}
/* -------------------------------------css for add_partition page -------------------------------------------*/
.add-lining .box-container h2 {
font-size: 16px;
margin: 25px 0px 25px !important;
}
.add-lining .box-container .p_r {
margin-bottom: 25px;
}
/* -------------------------------------css for add-accaustic-ceiling page -------------------------------------------*/
.add-accaustic-ceiling .box-container .input-group .form-control {
position: relative;
z-index: 2;
float: left;
width: 100%;
margin-bottom: 0;
border-radius: 4px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-right: 0px;
}
.add-accaustic-ceiling .input-group-addon {
padding: 6px 6px;
font-size: 14px;
font-weight: 400;
line-height: 1;
color: #000000;
text-align: center;
background-color: #fff;
border: 1px solid #ccc;
border-radius: 4px;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-left: 0px !important;
}
.add-accaustic-ceiling .input-group-addon a, i {
color: rgb(75, 87, 95) !important;
cursor: pointer;
}
.add-accaustic-ceiling .box-container .input-group {
position: relative;
display: table;
border-collapse: separate;
margin-right: 0;
}
#add_encasement.add-accaustic-ceiling .e_row label {
color: rgb(93, 107, 107);
font-weight: 200;
margin-left: -4px;
margin-right: 19px;
}
.e_row .radio-btn3 label {
margin-right: 10px !important;
}
.e_row .radio-btn4 label {
margin-right: 10px !important;
}
.e_row .r_size label {
margin-left: 0px !important;
margin-right: 0px !important;
}
.e_row .sizeInput {
float: left;
width: 25%;
border-radius: 0 !important;
}
.e_row .sizeX {
float: left;
margin: 2%;
margin-top: 1%;
}
.lastDiv1 input {
width: 15%;
float: left;
margin-right: 2%;
margin-top: 1%;
padding: 0;
border-radius: 0;
}
.lastDiv1 p {
float: left;
margin-top: 2%;
}
.lastDiv1_1 p {
float: left;
margin-top: 2%;
}
.last input {
width: 15%;
float: left;
margin-right: 1%;
margin-left: 1%;
margin-top: 1%;
padding: 6px 12px;
border-radius: 0;
}
.lastDiv1_1 p {
float: left;
margin-top: 2%;
}
.last p {
font-size: 15px;
font-weight: 100;
}
.last strong {
font-size: 16px;
font-weight: 900;
}
.lastDiv3 p:nth-child(3) {
float: left;
padding: 6px;
}
.lastDiv3 p:nth-child(5) {
float: left;
padding: 6px;
}
.lastDiv2 p:nth-child(3) {
float: left !important;
padding: 6px;
}
.lastDiv2_2 p:nth-child(3) {
float: left !important;
padding: 6px;
}
.lastDiv2_3 p:nth-child(3) {
float: left !important;
padding: 6px;
}
.lastDiv2_4 p:nth-child(3) {
float: left !important;
padding: 6px;
}
#add_encasement.add-accaustic-ceiling .proj {
background-position: -51px -8px;
}
#add_encasement.add-accaustic-ceiling .proj {
background-image: url(/assets/img/button.png);
background-repeat: no-repeat;
border: none;
outline: none;
padding-right: 4%;
width: 240px;
}
/* ------page css end------*/
/* ---------css for add-CREATE A PROJECT ------------*/
#create_project {
padding: 0px;
margin: 0px;
}
#create_project .show {
width: 90px !important;
padding: 5px 20px !important;;
}
#create_project .box-container .input-group .form-control {
position: relative;
z-index: 2;
float: left;
width: 100%;
margin-bottom: 0;
border-radius: 4px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-right: 0px;
}
#create_project .form-group.i_search .form-control {
border-radius: 0px;
}
#create_project .form-group.i_search .input-group-addon {
border-radius: 0px;
}
#create_project .input-group-addon {
padding: 6px 6px;
font-size: 14px;
font-weight: 400;
line-height: 1;
color: #000000;
text-align: center;
background-color: #fff;
border: 1px solid #ccc;
border-radius: 4px;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-left: 0px !important;
}
#create_project .box-container .input-group {
position: relative;
display: table;
border-collapse: separate;
margin-right: 0px;
}
.box-heading .actions a {
font-size: 20px;
font-family: MrEavesModOT;
color: rgb(0, 158, 226);
font-weight: 300;
text-transform: capitalize;
}
.actions {
text-align: right;
}
#create_project .icon.input-group-addon {
border-left: none;
background-color: white;
color: #009EE2;
font-size: 16px;
line-height: 2px;
}
.required_input .form-control {
border-color: #009EE2;
border-radius: 0 !important;
}
.required_input h3 {
color: #009EE2;
}
.required_input .form-control::-moz-placeholder {
color: #009EE2;
opacity: 1;
}
.required_input .form-control:-ms-input-placeholder {
color: #009EE2;
}
.required_input .form-control::-webkit-input-placeholder {
color: #009EE2;
}
.required_input .form-control {
border-color: #009ee2;
color: #009EE2 !important;
}
#create_project .form-group h3 {
font-weight: bold;
font-size: 15px !important;
margin: 0px 0px 10px !important;
}
#create_project a.btn.btn-primary {
color: #fff !important;
background: #009ee2;
border-radius: 0px;
border: none;
padding: 7px 14px;
font-size: 15px;
}
#create_project .form-group {
margin-bottom: 28px !important;
}
#create_project .form-control {
border-radius: 0px;
}
/* --end page css---*/
.row.radio {
margin: 30px 0 0 0 !important;
padding-bottom: 0px !important;
}
.row.radio label.agreement {
font-weight: 100 !important;
line-height: 2;
font-family: FuturaICGLight;
font-size: 15px;
}
#create_project.project-map .show {
width: 90px !important;
padding: 5px 20px !important;
}
#create_project.eula_wrraper .pull-right.show {
width: 140px !important;
padding: 5px 20px !important;
}
/* -----------------------START @media CSS-------------------------*/
.report_error {
margin: 0px;
padding: 0px;
}
#create_project.report_error .show {
width: 130px !important;
padding: 5px 20px !important;
}
.report_error .last.copright {
font-size: 15px;
font-weight: 100;
}
.report_error .error-text p {
font-weight: 500;
font-size: 17px;
font-family: FuturaICGLight;
}
.report_error .error-text span a {
font-size: 21px;
font-weight: 600;
margin-bottom: -10px !important;
}
.report_error a.btn.btn-primary {
color: #fff !important;
background: #009ee2;
border-radius: 0px;
border: none;
padding: 7px 14px;
font-size: 16px;
font-family: Myriad Pro;
}
.report_error a.btn.btn-primary i.fa {
color: #fff !important;
font-size: 18px;
margin-left: 5px;
}
.report_error a.btn.btn-primary img {
width: 10px;
height: 15px;
margin-left: 5px;
vertical-align: middle;
}
.projects {
margin: 0;
padding: 3px 20px;
float: right;
background-color: #b7b0a7;
z-index: 0;
box-shadow: -2px 6px 9px 4px #cbcbcb;
color: white;
font-size: 16px;
font-family: MrEavesModOT;
font-weight: bold;
color: rgb(255, 255, 255);
line-height: 1.688;
p {
margin: 0;
}
}
.mtop240 {
margin-top: 240px;
}
.footer {
margin-top: 1px !important;
}
.copright {
top: 40vh !important;
position: relative;
}
/* -----------------------START @media CSS-------------------------*/
@media screen and (min-width: 2500px) {
}
@media screen and (max-width: 1024px) {
.last input {
width: 25%;
}
.e_row .sizeInput {
float: left;
width: 24%;
border-radius: 0 !important;
}
.radio-btn4.pull-right {
float: left !important;
}
#project_wrapper .box-container .box-body .colm-system {
background: #f8f7f6;
padding: 10px;
margin-top: 20px;
}
.add-celling .top_links {
padding: 1px 0px 0px 15px;
text-align: left;
height: 10vh;
margin-bottom: 100px;
}
}
@media screen and (max-width: 768px) {
.box-container {
background: #FFF !important;
padding: 10px 15px;
}
.last input {
width: 100%;
}
#project_wrapper .p_down {
text-align: center;
position: relative;
bottom: -30px !important;
}
}
@media screen and (max-width: 736px) {
.navbar-nav > li > a {
padding: 15px 15px !important;
}
.layout {
margin-bottom: 35px;
}
.show {
width: 150px;
}
}
@media screen and (max-width: 600px) {
.c-row .col-b h1 {
text-align: center !important;
}
.c-row .col-b .col-lg-7.col-md-7.col-sm-12.col-xs-12 {
text-align: center !important;
}
.c-row .col-b .col-lg-8.col-md-8.col-sm-12.col-xs-12 {
text-align: center !important;
}
}
@media screen and (max-width: 568px) {
}
@media screen and (max-width: 414px) {
#project_wrapper .box-container .box-body .colm-system h1 {
font-size: 18px;
color: #009ee2;
margin: 7px 0px 0px;
text-align: center;
}
.login_form {
background-color: #ffffff;
border-top: 6px solid #009ee2;
vertical-align: middle;
padding: 30px;
width: 100% !important;
padding: 10px 45px;
}
}
@media screen and (max-width: 424px) {
}
\ No newline at end of file
//below line will be removed with actual layout
p protected works!
router-outlet
.dashboard_body((click)='hideUserPopup()')
.container
.row
.navbar.navbar-default.navbar.menu.main
.navbar-header
button.navbar-toggle(type="button" data-toggle="collapse" data-target=".navbar-collapse")
span.icon-bar
span.icon-bar
span.icon-bar
a.navbar-brand([routerLink]='dashboardURL')
img.img-responsive(src="/assets/img/knauf-3.png" alt="knauf_logo")
.pull-left.dropdown
a#dropdownMenu1.btn-user.dropdown-toggle((click)="toggleUserPopup($event)")
.img-back
img(src="/assets/img/User_icon.png" alt="")
ul.dropdown-menu.user-dropdown(*ngIf="userPopup")
li
a(href="#")
span.u_name {{user.user_name}}
li
a((click)='logout()')
span.sign_out Sign Out
.navbar-collapse.collapse
ul.nav.navbar-nav
li
a(href="#") Admin
li
a(href="#") Management
li
a(href="#") Projects
.container.last
.row
.col-lg-3.col-lg-offset-9.col-md-3.col-md-offset-.col-sm-3.col-sm-offset-9.col-xs-5.col-xs-offset-7(style="padding-right: 0;")
.pull-right.projects
p.text-center Management Dashboard
.container.last
.row
.col-lg-12.col-md-12.col-sm-12.col-xs-12
p.lastP
| Copyright Drywall Aptitude © {{currentYear}} 
span.color Knauf Specification Author. 
| All rights reserved.
import { Component, OnInit } from '@angular/core';
import {Component, OnInit} from '@angular/core';
import {Constants} from '../../constants';
import {UserService} from '../../users/user.service';
import {Router} from '@angular/router';
@Component({
selector: 'app-protected',
......@@ -6,10 +9,31 @@ import { Component, OnInit } from '@angular/core';
styleUrls: ['./protected.component.less']
})
export class ProtectedComponent implements OnInit {
currentYear;
userPopup = false;
dashboardURL = Constants.APP_URLS.dashboard;
constructor() { }
constructor(private user: UserService, private router: Router) {
}
ngOnInit() {
this.currentYear = new Date().getFullYear();
}
toggleUserPopup(event) {
console.log(event);
event.stopPropagation();
this.userPopup = !this.userPopup;
}
hideUserPopup() {
this.userPopup = false;
}
logout() {
this.user.logout().subscribe(data => {
this.router.navigate([Constants.APP_URLS.login]);
});
}
}
.login_body {
background: url(/assets/img/layer1.png) no-repeat center center fixed;
background-size: 100% 100%;
height: 100vh;
}
.login-wrapper {
min-height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
\ No newline at end of file
//below line will be removed with actual layout
p public works!
router-outlet
\ No newline at end of file
.login_body
.container.vertical-align.login-wrapper
.row.text-center.login-form-wrapper
.col-md-12
router-outlet
\ No newline at end of file
import {Injectable} from '@angular/core';
import {ActivatedRoute, ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot} from '@angular/router';
import {UserService} from '../users/user.service';
import {Constants} from '../constants';
@Injectable()
export class AppGuard implements CanActivate {
constructor(private router: Router,
public activatedRoute: ActivatedRoute) {
public activatedRoute: ActivatedRoute,
private userService: UserService) {
// nothing in constructor
}
......@@ -13,10 +16,11 @@ export class AppGuard implements CanActivate {
// const roles = next.data['roles']; // would be used later
// const user: any = {}; // would be used later
// specify route protection logic below
if (1) {
if (this.userService.isAuthenticated()) {
// logged in so return true
return true;
} else {
this.router.navigate([Constants.APP_URLS.login]);
// not logged in so redirect to login page with the return url
return false;
}
......
......@@ -5,10 +5,13 @@ import {AppGuard} from './app.guard';
import {PublicComponent} from '../layouts/public/public.component';
import {ProtectedComponent} from '../layouts/protected/protected.component';
import {LoginComponent} from '../users/login/login.component';
import {ForgotComponent} from '../users/forgot/forgot.component';
import {NewPasswordComponent} from '../users/new-password/new-password.component';
const routes: Routes = [
{
path: 'admin',
path: 'dashboard',
canActivate: [AppGuard],
data: {roles: ['admin']},
component: ProtectedComponent,
......@@ -17,7 +20,24 @@ const routes: Routes = [
{
path: '',
component: PublicComponent,
children: []
children: [
{
path: '',
component: LoginComponent,
},
{
path: 'forgot',
component: ForgotComponent,
},
{
path: 'set-new/:token',
component: NewPasswordComponent,
},
{
path: 'set-new/:token/:reason', // reason is optional, reason for 2 routes
component: NewPasswordComponent,
}
]
},
];
......
<div class="loaderWrapper">
<div [style.width.px]="width" style="margin:auto">
<svg class="lds-blocks" [style.width.px]="width" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" class="lds-eclipse" style="background: none;">
<path stroke="none" d="M10 50A40 40 0 0 0 90 50A40 45 0 0 1 10 50" fill="#51CACC" transform="rotate(150 50 52.5)">
<animateTransform attributeName="transform" type="rotate" calcMode="linear" values="0 50 52.5;360 50 52.5" keyTimes="0;1" dur="1s" begin="0s" repeatCount="indefinite"></animateTransform>
</path>
</svg>
</div>
</div>
\ No newline at end of file
.loader-hidden {
visibility: hidden;
}
.loader-overlay {
position: absolute;
width: 100%;
top: 0;
left: 0;
z-index: 500000;
background: rgba(128,128,128,0.4);
border-radius: 10px;
}
.lds-blocks{
display: block;
margin: auto;
}
.loaderWrapper{
display: flex;
align-items: center;
justify-content: center;
height:100%
}
\ No newline at end of file
import {Component, Input, OnInit} from '@angular/core';
@Component({
selector: 'app-loader',
templateUrl: './loader.component.html',
styleUrls: ['./loader.component.less']
})
export class LoaderComponent implements OnInit {
@Input() width: number;
constructor() {
}
ngOnInit() {
if (this.width == undefined) {
this.width = 150;
}
}
}
\ No newline at end of file
.modal-content
.modal-header
button.close.pull-right((click)="bsModalRef.hide()")
span(aria-hidden="true") ×
h4.modal-title {{title}}
.modal-body
| {{body}}
.modal-footer
button.btn.btn-primary((click)="bsModalRef.hide()") {{closeBtnName}}
\ No newline at end of file
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { SessionModalComponent } from './session-modal.component';
describe('SessionModalComponent', () => {
let component: SessionModalComponent;
let fixture: ComponentFixture<SessionModalComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ SessionModalComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(SessionModalComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import {Component, OnInit} from '@angular/core';
import {BsModalRef} from 'ngx-bootstrap/modal/bs-modal-ref.service';
@Component({
selector: 'app-session-modal',
templateUrl: './session-modal.component.pug',
styleUrls: ['./session-modal.component.less']
})
export class SessionModalComponent implements OnInit {
closeBtnName;
title;
body;
constructor(public bsModalRef: BsModalRef) {
}
ngOnInit() {
}
}
@import "../../../assets/css/magic-check_login";
.clear {
clear: both;
}
.lastP {
margin-left: 3%;
color: #989898;
text-align: center;
position: absolute;
bottom: 3px;
width: 100%;
}
.color {
color: #009EE2 !important;
font-weight: bold;
}
.form-control::-webkit-input-placeholder {
font-size: 15px;
font-family: MrEavesModOT;
color: rgb(178, 178, 178);
line-height: 3.02;
}
.logo-img {
display: inline-block;
padding: 12% 0;
}
.login_form {
position: relative;
background-color: #ffffff;
border-top: 6px solid #009ee2;
vertical-align: middle;
padding: 30px;
width: 500px;
padding: 10px 45px;
}
.specification_Author {
font-size: 18px;
font-family: FuturaPT;
color: rgb(0, 158, 226);
line-height: 1.2;
margin-left: 4%;
display: inline-block;
margin-top: 23.5%;
position: absolute;
font-weight: 200;
}
.form-control {
padding: 24px 12px;
border-radius: 0;
border: 1px solid #bcb5ad;
background-image: url(/assets/img/question.png) !important;
background-repeat: no-repeat;
background-size: 15%;
background-position: 60px 10px;
}
.col-lg-6 {
padding-right: 0;
}
.radio-btn3 {
float: left;
}
.magic-radio + label, .magic-checkbox + label {
padding-left: 10px !important;
margin-top: -1%;
padding-bottom: 23%;
}
.magic-radio + label:before, .magic-checkbox + label:before {
top: 15px !important;
left: -13px !important;
}
.magic-radio + label:after {
top: 18px !important;
left: -10px !important;
}
#inputPassword {
background-image: url(/assets/img/question.png) !important;
background-repeat: no-repeat;
background-size: 350%;
background-position: 47% 48%;
}
#inputEmai {
background-image: url(/assets/img/question.png) !important;
background-repeat: no-repeat;
background-size: 350%;
background-position: 47% 48%;
}
.col-lg-8, .col-md-6, .col-sm-10, .col-xs-12 {
padding-right: 0;
}
.footer {
min-height: 0;
}
.no-backgroud{
background-image: none;
}
label {
font-size: 15px;
font-family: MrEavesModOT;
color: rgb(178, 178, 178);
line-height: 3.02;
font-weight: 300;
/*padding-bottom: 5%;
text-align: left;*/
}
@media (min-width: 992px) and (max-width: 1900px) {
.lastP {
width: 90%;
text-align: center !important;
margin-left: 9%;
}
}
@media (min-width: 768px) and (max-width: 991px) {
.logo-img {
width: 120%;
}
.lastP {
width: 90%;
text-align: center !important;
}
}
@media (min-width: 560px) and (max-width: 767px) {
.logo-img {
width: 110%;
}
.lastP {
width: 90%;
text-align: center !important;
}
}
@media (max-width: 736px) {
body {
overflow-x: hidden;
}
.lastP {
margin-left: 3%;
color: #989898;
text-align: center;
position: absolute;
top: 10px;
width: 100%;
}
}
@media (min-width: 480px) and (max-width: 559px) {
.logo-img {
width: 120%;
}
button {
font-size: 13px;
padding: 1.5% 0;
padding-left: 5%;
padding-right: 6%;
background-position: 51px 5px;
}
.lastP {
width: 90%;
text-align: center !important;
}
}
@media (max-width: 414px) {
.login_form {
background-color: #ffffff;
border-top: 6px solid #009ee2;
vertical-align: middle;
padding: 30px;
width: 100% !important;
padding: 10px 45px;
}
button {
font-size: 13px;
padding: 1.5% 0;
padding-left: 5%;
padding-right: 6%;
background-position: 58px 6px !important;
}
.lastP {
margin-left: 3%;
color: #989898;
text-align: center;
position: absolute;
top: 90px !important;
width: 100%;
}
}
@media (max-width: 320px) {
button {
background-position: 53px 6px !important;
}
}
@media (min-width: 320px) and (max-width: 479px) {
.logo-img {
width: 150%;
}
.form-control {
padding: 5% 9%;
}
button {
font-size: 13px;
padding: 1.5% 0;
padding-left: 5%;
padding-right: 6%;
background-position: 51px 5px;
}
.lastP {
width: 90%;
text-align: center !important;
}
}
\ No newline at end of file
form.text-center('name'='forgotForm' '(ngSubmit)'="forgot()")
.login_form
.loaderAbsHolder('*ngIf'='loading')
app-loader
.row
.col-lg-12
.text-center.col-lg-8.col-lg-offset-2.col-md-8.col-md-offset-2.col-sm-8.col-sm-offset-2.col-xs-8.col-xs-offset-2
img.img-responsive.logo-img(src="/assets/img/logo.png" alt="knauf_logo")
.form-group
input#inputEmai.form-control.question(type="email" placeholder="Email address" maxlength="50" 'name'='userEmail' '[(ngModel)]'='userEmail')
label.col-sm-12(class='text-right')
a('[routerLink]'='APP_URLS.login') Back to login...
.form-group
.text-right
button.btn_submit.pull-right.login(type="submit" '*ngIf'='!(loading)') Submit
button.btn_submit.pull-right.login(type="button" '*ngIf'='loading') Please wait!
\ No newline at end of file
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ForgotComponent } from './forgot.component';
describe('ForgotComponent', () => {
let component: ForgotComponent;
let fixture: ComponentFixture<ForgotComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ForgotComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ForgotComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import {Component, OnInit} from '@angular/core';
import {Title} from '@angular/platform-browser';
import {Router} from '@angular/router';
import {UserService} from '../user.service';
import {ToastsManager} from 'ng2-toastr';
import {Constants} from '../../constants';
@Component({
selector: 'app-forgot',
templateUrl: './forgot.component.pug',
styleUrls: ['./forgot.component.less']
})
export class ForgotComponent implements OnInit {
title = 'Recover Password | Knauf Specification Author';
APP_URLS = Constants.APP_URLS;
userEmail = '';
loading = false;
constructor(private titleService: Title,
private router: Router,
private user: UserService,
private toaster: ToastsManager) {
this.titleService.setTitle(this.title);
}
ngOnInit() {
}
forgot() {
if (!this.userEmail) {
this.toaster.error('Please provide your email address');
return;
}
this.loading = true;
this.user.sendPassword(this.userEmail).subscribe(data => {
this.toaster.success(data.message, '', {enableHTML: true});
this.loading = false;
}, err => {
this.loading = false;
});
}
}
@import "../../../assets/css/magic-check_login";
.clear {
clear: both;
}
.lastP {
margin-left: 3%;
color: #989898;
text-align: center;
position: absolute;
bottom: 3px;
width: 100%;
}
.color {
color: #009EE2 !important;
font-weight: bold;
}
.form-control::-webkit-input-placeholder {
font-size: 15px;
font-family: MrEavesModOT;
color: rgb(178, 178, 178);
line-height: 3.02;
}
.logo-img {
display: inline-block;
padding: 12% 0;
}
.login_form {
position: relative;
background-color: #ffffff;
border-top: 6px solid #009ee2;
vertical-align: middle;
padding: 30px;
width: 500px;
padding: 10px 45px;
}
.specification_Author {
font-size: 18px;
font-family: FuturaPT;
color: rgb(0, 158, 226);
line-height: 1.2;
margin-left: 4%;
display: inline-block;
margin-top: 23.5%;
position: absolute;
font-weight: 200;
}
.form-control {
padding: 24px 12px;
border-radius: 0;
border: 1px solid #bcb5ad;
background-image: url(/assets/img/question.png) !important;
background-repeat: no-repeat;
background-size: 15%;
background-position: 60px 10px;
}
.col-lg-6 {
padding-right: 0;
}
.radio-btn3 {
float: left;
}
.magic-radio + label, .magic-checkbox + label {
padding-left: 10px !important;
margin-top: -1%;
padding-bottom: 23%;
}
.magic-radio + label:before, .magic-checkbox + label:before {
top: 15px !important;
left: -13px !important;
}
.magic-radio + label:after {
top: 18px !important;
left: -10px !important;
}
#inputPassword {
background-image: url(/assets/img/question.png) !important;
background-repeat: no-repeat;
background-size: 350%;
background-position: 47% 48%;
}
#inputEmai {
background-image: url(/assets/img/question.png) !important;
background-repeat: no-repeat;
background-size: 350%;
background-position: 47% 48%;
}
.col-lg-8, .col-md-6, .col-sm-10, .col-xs-12 {
padding-right: 0;
}
.footer {
min-height: 0;
}
.no-backgroud{
background-image: none;
}
label {
font-size: 15px;
font-family: MrEavesModOT;
color: rgb(178, 178, 178);
line-height: 3.02;
font-weight: 300;
/*padding-bottom: 5%;
text-align: left;*/
}
@media (min-width: 992px) and (max-width: 1900px) {
.lastP {
width: 90%;
text-align: center !important;
margin-left: 9%;
}
}
@media (min-width: 768px) and (max-width: 991px) {
.logo-img {
width: 120%;
}
.lastP {
width: 90%;
text-align: center !important;
}
}
@media (min-width: 560px) and (max-width: 767px) {
.logo-img {
width: 110%;
}
.lastP {
width: 90%;
text-align: center !important;
}
}
@media (max-width: 736px) {
body {
overflow-x: hidden;
}
.lastP {
margin-left: 3%;
color: #989898;
text-align: center;
position: absolute;
top: 10px;
width: 100%;
}
}
@media (min-width: 480px) and (max-width: 559px) {
.logo-img {
width: 120%;
}
button {
font-size: 13px;
padding: 1.5% 0;
padding-left: 5%;
padding-right: 6%;
background-position: 51px 5px;
}
.lastP {
width: 90%;
text-align: center !important;
}
}
@media (max-width: 414px) {
.login_form {
background-color: #ffffff;
border-top: 6px solid #009ee2;
vertical-align: middle;
padding: 30px;
width: 100% !important;
padding: 10px 45px;
}
button {
font-size: 13px;
padding: 1.5% 0;
padding-left: 5%;
padding-right: 6%;
background-position: 58px 6px !important;
}
.lastP {
margin-left: 3%;
color: #989898;
text-align: center;
position: absolute;
top: 90px !important;
width: 100%;
}
}
@media (max-width: 320px) {
button {
background-position: 53px 6px !important;
}
}
@media (min-width: 320px) and (max-width: 479px) {
.logo-img {
width: 150%;
}
.form-control {
padding: 5% 9%;
}
button {
font-size: 13px;
padding: 1.5% 0;
padding-left: 5%;
padding-right: 6%;
background-position: 51px 5px;
}
.lastP {
width: 90%;
text-align: center !important;
}
}
\ No newline at end of file
form.text-center('name'='loginForm' '(ngSubmit)'="login()")
.login_form
.loaderAbsHolder('*ngIf'='showLoader')
app-loader
.row
.col-lg-12
.text-center.col-lg-8.col-lg-offset-2.col-md-8.col-md-offset-2.col-sm-8.col-sm-offset-2.col-xs-8.col-xs-offset-2
img.img-responsive.logo-img(src="/assets/img/logo.png" alt="knauf_logo")
.form-group
input#inputEmai.form-control.question(type="email" placeholder="Email address" maxlength="255" 'name'='username' '[(ngModel)]'='loginData.username')
.form-group
input#inputPassword.form-control(type="password" placeholder="Password" maxlength="255" 'name'='password' '[(ngModel)]'='loginData.password')
.col-sm-6
.radio-btn3
input#3.magic-radio(type="checkbox" name="bth" value="option")
label(for="3")
| Remember me
.col-sm-6
label
a('[routerLink]'='APP_URLS.forgetPassword') Forgotten your password?
.form-group
.text-right
button.btn_submit.pull-right.login(type="submit" '*ngIf'='!(loading || showLoader)') Log in
button.btn_submit.pull-right.login(type="button" '*ngIf'='loading || showLoader') Please wait!
\ No newline at end of file
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} from '@angular/core';
import {Router} from '@angular/router';
import {Title} from '@angular/platform-browser';
import {ToastsManager} from 'ng2-toastr/ng2-toastr';
import {UserService} from '../user.service';
import {Constants} from '../../constants';
@Component({
selector: 'app-login',
templateUrl: './login.component.pug',
styleUrls: ['./login.component.less']
})
export class LoginComponent implements OnInit {
title = 'User Login | Knauf Specification Author';
APP_URLS = Constants.APP_URLS;
loginData = {
username: '',
password: ''
};
loading = false;
showLoader = false;
constructor(private titleService: Title,
private router: Router,
private user: UserService,
private toaster: ToastsManager) {
this.titleService.setTitle(this.title);
}
ngOnInit() {
this.tryAutoLogin();
}
validateLoginForm() {
if (!this.loginData.username) {
return false;
}
if (!this.loginData.password) {
return false;
}
return true;
}
login() {
if (!this.validateLoginForm()) {
this.toaster.error('Username and/or password missing.');
return;
}
this.loading = true;
this.user.login(this.loginData.username, this.loginData.password).subscribe(data => {
this.loading = false;
this.toaster.success('Login Successful!');
this.router.navigate([this.APP_URLS.dashboard]);
}, error => {
error = error.json();
if (error.message.indexOf('security requirements') > -1 && error.token) {
this.router.navigate([this.APP_URLS.newPassword + '/' + error.token + '/' + this.user.PASSWORD_STRENGTH]);
}
this.loading = false;
});
}
tryAutoLogin() {
this.showLoader = true;
this.user.tryAutoLogin().subscribe(data => {
this.showLoader = false;
this.router.navigate([this.APP_URLS.dashboard]);
}, err => {
this.showLoader = false;
});
}
}
@import "../../../assets/css/magic-check_login";
.clear {
clear: both;
}
.lastP {
margin-left: 3%;
color: #989898;
text-align: center;
position: absolute;
bottom: 3px;
width: 100%;
}
.color {
color: #009EE2 !important;
font-weight: bold;
}
.form-control::-webkit-input-placeholder {
font-size: 15px;
font-family: MrEavesModOT;
color: rgb(178, 178, 178);
line-height: 3.02;
}
.logo-img {
display: inline-block;
padding: 12% 0;
}
.login_form {
position: relative;
background-color: #ffffff;
border-top: 6px solid #009ee2;
vertical-align: middle;
padding: 30px;
width: 500px;
padding: 10px 45px;
}
.specification_Author {
font-size: 18px;
font-family: FuturaPT;
color: rgb(0, 158, 226);
line-height: 1.2;
margin-left: 4%;
display: inline-block;
margin-top: 23.5%;
position: absolute;
font-weight: 200;
}
.form-control {
padding: 24px 12px;
border-radius: 0;
border: 1px solid #bcb5ad;
background-image: url(/assets/img/question.png) !important;
background-repeat: no-repeat;
background-size: 15%;
background-position: 60px 10px;
}
.col-lg-6 {
padding-right: 0;
}
.radio-btn3 {
float: left;
}
.magic-radio + label, .magic-checkbox + label {
padding-left: 10px !important;
margin-top: -1%;
padding-bottom: 23%;
}
.magic-radio + label:before, .magic-checkbox + label:before {
top: 15px !important;
left: -13px !important;
}
.magic-radio + label:after {
top: 18px !important;
left: -10px !important;
}
#inputPassword {
background-image: url(/assets/img/question.png) !important;
background-repeat: no-repeat;
background-size: 350%;
background-position: 47% 48%;
}
#inputEmai {
background-image: url(/assets/img/question.png) !important;
background-repeat: no-repeat;
background-size: 350%;
background-position: 47% 48%;
}
.col-lg-8, .col-md-6, .col-sm-10, .col-xs-12 {
padding-right: 0;
}
.footer {
min-height: 0;
}
.no-backgroud{
background-image: none;
}
label {
font-size: 15px;
font-family: MrEavesModOT;
color: rgb(178, 178, 178);
line-height: 3.02;
font-weight: 300;
/*padding-bottom: 5%;
text-align: left;*/
}
@media (min-width: 992px) and (max-width: 1900px) {
.lastP {
width: 90%;
text-align: center !important;
margin-left: 9%;
}
}
@media (min-width: 768px) and (max-width: 991px) {
.logo-img {
width: 120%;
}
.lastP {
width: 90%;
text-align: center !important;
}
}
@media (min-width: 560px) and (max-width: 767px) {
.logo-img {
width: 110%;
}
.lastP {
width: 90%;
text-align: center !important;
}
}
@media (max-width: 736px) {
body {
overflow-x: hidden;
}
.lastP {
margin-left: 3%;
color: #989898;
text-align: center;
position: absolute;
top: 10px;
width: 100%;
}
}
@media (min-width: 480px) and (max-width: 559px) {
.logo-img {
width: 120%;
}
button {
font-size: 13px;
padding: 1.5% 0;
padding-left: 5%;
padding-right: 6%;
background-position: 51px 5px;
}
.lastP {
width: 90%;
text-align: center !important;
}
}
@media (max-width: 414px) {
.login_form {
background-color: #ffffff;
border-top: 6px solid #009ee2;
vertical-align: middle;
padding: 30px;
width: 100% !important;
padding: 10px 45px;
}
button {
font-size: 13px;
padding: 1.5% 0;
padding-left: 5%;
padding-right: 6%;
background-position: 58px 6px !important;
}
.lastP {
margin-left: 3%;
color: #989898;
text-align: center;
position: absolute;
top: 90px !important;
width: 100%;
}
}
@media (max-width: 320px) {
button {
background-position: 53px 6px !important;
}
}
@media (min-width: 320px) and (max-width: 479px) {
.logo-img {
width: 150%;
}
.form-control {
padding: 5% 9%;
}
button {
font-size: 13px;
padding: 1.5% 0;
padding-left: 5%;
padding-right: 6%;
background-position: 51px 5px;
}
.lastP {
width: 90%;
text-align: center !important;
}
}
.message{
font-weight: bold;
color: #666;
}
\ No newline at end of file
form.text-center('name'='newPasswordForm' '(ngSubmit)'="updatePassword()")
.login_form
.row
.col-lg-12
.text-center.col-lg-8.col-lg-offset-2.col-md-8.col-md-offset-2.col-sm-8.col-sm-offset-2.col-xs-8.col-xs-offset-2
img.img-responsive.logo-img(src="/assets/img/logo.png" alt="knauf_logo")
.col-lg-12.message(*ngIf='messages[reason]') {{messages[reason]}}
.form-group
input#inputEmai.form-control.question(type="password" placeholder='Enter new password.' 'name'='password' '[(ngModel)]'='data.password')
.form-group
input#inputPassword.form-control(type="password" placeholder='Re-Enter new password.' 'name'='cpassword' '[(ngModel)]'='data.cpassword')
.col-sm-12
label &nbsp;
.form-group
.text-right
button.btn_submit.pull-right.login(type="submit" '*ngIf'='!(showLoader)') Update
button.btn_submit.pull-right.login(type="button" '*ngIf'='showLoader') Please wait!
\ No newline at end of file
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { NewPasswordComponent } from './new-password.component';
describe('NewPasswordComponent', () => {
let component: NewPasswordComponent;
let fixture: ComponentFixture<NewPasswordComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ NewPasswordComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(NewPasswordComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import {Component, OnDestroy, OnInit} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import {ToastsManager} from 'ng2-toastr/ng2-toastr';
import {UserService} from '../user.service';
import {Constants} from '../../constants';
import {Title} from '@angular/platform-browser';
@Component({
selector: 'app-new-password',
templateUrl: './new-password.component.pug',
styleUrls: ['./new-password.component.less']
})
export class NewPasswordComponent implements OnInit, OnDestroy {
title = 'Recover Password | Knauf Specification Author';
data = {
password: '',
cpassword: ''
};
query;
token;
APP_URLS = Constants.APP_URLS;
messages = [];
reason;
showLoader = false;
constructor(private titleService: Title,
private route: ActivatedRoute,
private user: UserService,
private router: Router,
private toaster: ToastsManager) {
this.titleService.setTitle(this.title);
this.messages[this.user.CHANGE_REQUESTED] = '';
this.messages[this.user.PASSWORD_EXPIRED] = 'Your password has expired and should be changed.';
this.messages[this.user.PASSWORD_STRENGTH] = 'Your password doesn\'t meet the security requirements and should be changed.';
}
ngOnInit() {
this.query = this.route.params.subscribe(params => {
console.log(params);
this.token = params['token'];
this.reason = params['reason'] || this.user.CHANGE_REQUESTED;
});
}
ngOnDestroy() {
this.query.unsubscribe();
}
updatePassword() {
this.showLoader = true;
const validation = this.user.validatePassword(this.data.password);
if (!validation.valid) {
this.toaster.error(validation.message);
return;
}
if (this.data.password !== this.data.cpassword) {
this.toaster.error('Password & confirm password must match');
return;
}
this.user.updatePassword(this.token, this.data.password).subscribe(data => {
this.showLoader = false;
this.toaster.success('Password updated successfully');
this.router.navigate([this.APP_URLS.login]);
}, err => {
this.showLoader = false;
});
}
}
import { TestBed, inject } from '@angular/core/testing';
import { UserService } from './user.service';
describe('UserService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [UserService]
});
});
it('should be created', inject([UserService], (service: UserService) => {
expect(service).toBeTruthy();
}));
});
import {Injectable} from '@angular/core';
import {HttpService} from '../app-services/http.service';
import {LocalStoreService} from '../app-services/local-store.service';
import {Observable} from 'rxjs/Observable';
import {Subject} from 'rxjs/Subject';
@Injectable()
export class UserService {
public id;
public user_name;
public user_mail;
public contact;
public user_desig;
public user_region;
public user_terms;
public attempt;
public user_role;
public avatar;
public tooltip;
public token;
public token_expire;
public CHANGE_REQUESTED = 1;
public PASSWORD_EXPIRED = 2;
public PASSWORD_STRENGTH = 3;
private passwordValidations = [
{message: 'be at least 8 characters', rule: /^.{8}/},
{message: 'be at most 255 characters', rule: /^.{0,255}$/},
{message: 'contain at least one lowercase letter', rule: /[a-z]/},
{message: 'contain at least one uppercase letter', rule: /[A-Z]/},
{message: 'contain at least one number', rule: /[0-9]/}
];
private LOGIN = 'api-users/dologin';
private VERIFY = 'api-users/verifytoken';
private FORGOT = 'user/send-password';
private UPDATE_PASSWORD = 'api-users/new-password';
private ALIVE = 'api-users/alive';
private LOGOUT = 'api-users/logout';
private password;
private keepAliveTime = 160;
private pollingIntervalId;
private emitSessionDestroyed = new Subject<any>();
onSessionDestroyed = this.emitSessionDestroyed.asObservable();
constructor(private http: HttpService,
private localStoreService: LocalStoreService) {
}
isAuthenticated($checkFromServer = false) {
if (this.id) {
return true;
}
}
validatePassword(password) {
let valid = true;
let message = 'Password must ';
this.passwordValidations.forEach(data => {
if (data.rule.test(password) === false) {
valid = false;
message += data.message + ', ';
}
});
message = message.substr(0, message.length - 2);
message += '.';
return {
valid,
message
};
}
populate(data) {
const keys = Object.keys(data);
keys.forEach(key => {
this[key] = data[key];
});
}
sendPassword(email_address) {
const postData = {
email_address
};
const promise = this.http.post(this.FORGOT, postData);
return promise;
}
updatePassword(token, password) {
const postData = {
password,
token
};
return this.http.post(this.UPDATE_PASSWORD, postData);
}
alive() {
const showErrors = {
e401: false,
};
return this.http.get(this.ALIVE, '', showErrors).subscribe(data => {
if (data.active === false) {
this.emitSessionDestroyed.next('Session Destroyed');
if (this.pollingIntervalId) {
clearInterval(this.pollingIntervalId);
}
}
}, er => {
this.emitSessionDestroyed.next('Session Destroyed');
if (this.pollingIntervalId) {
clearInterval(this.pollingIntervalId);
}
});
}
startAlivePolling() {
this.pollingIntervalId = setInterval(() => {
this.alive();
}, this.keepAliveTime * 1000);
}
login(username, password) {
const postData = {
username,
password
};
const showErrors = {
e401: true
};
const promise = this.http.post(this.LOGIN, postData, showErrors);
promise.subscribe(data => {
this.http.setTokken(data.access_token);
this.populate(data.user);
this.localStoreService.set('access_token', data.access_token);
this.startAlivePolling();
}, error => {
});
return promise;
}
logout() {
const data = {
e401: false
};
if (this.pollingIntervalId) {
clearInterval(this.pollingIntervalId);
}
return this.http.get(this.LOGOUT, '', data);
}
tryAutoLogin() {
return new Observable(observer => {
const access_token = this.localStoreService.get('access_token');
if (access_token) {
const showErrors = {
e401: false
};
this.http.setTokken(access_token);
this.http.get(this.VERIFY, '', showErrors).subscribe(data => {
if (data.verified) {
this.populate(data.user);
observer.next(data.user);
observer.complete();
this.startAlivePolling();
} else {
this.localStoreService.remove('access_token');
observer.error('Unable to veryfy access_token');
}
}, err => {
this.localStoreService.remove('access_token');
observer.error('Unable to veryfy access_token');
});
} else {
observer.error('No access_token found');
}
});
}
}
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
import {RouterModule} from '@angular/router';
import {LocalStoreService} from '../app-services/local-store.service';
import {LoginComponent} from './login/login.component';
import {UserService} from './user.service';
import {LoaderComponent} from '../shared/loader/loader.component';
import { ForgotComponent } from './forgot/forgot.component';
import { NewPasswordComponent } from './new-password/new-password.component';
@NgModule({
imports: [
CommonModule,
FormsModule,
RouterModule
],
providers: [
UserService,
LocalStoreService
],
declarations: [LoginComponent, LoaderComponent, ForgotComponent, NewPasswordComponent]
})
export class UsersModule {
}
\ No newline at end of file
@keyframes hover-color {
from {
border-color: #c0c0c0; }
to {
border-color: #3e97eb; } }
.magic-radio,
.magic-checkbox {
position: absolute;
display: none; }
.magic-radio[disabled],
.magic-checkbox[disabled] {
cursor: not-allowed; }
.magic-radio + label,
.magic-checkbox + label {
position: relative;
display: block;
padding-left: 30px;
cursor: pointer;
vertical-align: middle; }
.magic-radio + label:hover:before,
.magic-checkbox + label:hover:before {
animation-duration: 0.4s;
animation-fill-mode: both;
animation-name: hover-color; }
.magic-radio + label:before,
.magic-checkbox + label:before {
position: absolute;
top: 4px;
left: 2px;
display: inline-block;
width: 16px;
height: 16px;
content: '';
border: 1px solid #c0c0c0;
}
.magic-radio + label:after,
.magic-checkbox + label:after {
position: absolute;
display: none;
content: ''; }
.magic-radio[disabled] + label,
.magic-checkbox[disabled] + label {
cursor: not-allowed;
color: #e4e4e4; }
.magic-radio[disabled] + label:hover, .magic-radio[disabled] + label:before, .magic-radio[disabled] + label:after,
.magic-checkbox[disabled] + label:hover,
.magic-checkbox[disabled] + label:before,
.magic-checkbox[disabled] + label:after {
cursor: not-allowed; }
.magic-radio[disabled] + label:hover:before,
.magic-checkbox[disabled] + label:hover:before {
border: 1px solid #e4e4e4;
animation-name: none; }
.magic-radio[disabled] + label:before,
.magic-checkbox[disabled] + label:before {
border-color: #e4e4e4; }
.magic-radio:checked + label:before,
.magic-checkbox:checked + label:before {
animation-name: none; }
.magic-radio:checked + label:after,
.magic-checkbox:checked + label:after {
display: block; }
.magic-radio + label:before {
border-radius: 50%; }
.magic-radio + label:after {
top: 7px;
left: 5px;
width: 10px;
height: 10px;
border-radius: 50%;
background: #3e97eb;
}
.magic-radio:checked + label:before {
border: 1px solid #3e97eb; }
.magic-radio:checked[disabled] + label:before {
border: 1px solid #c9e2f9; }
.magic-radio:checked[disabled] + label:after {
background: #c9e2f9; }
.magic-checkbox + label:before {
border-radius: 3px; }
.magic-checkbox + label:after {
top: 2px;
left: 7px;
box-sizing: border-box;
width: 6px;
height: 12px;
transform: rotate(45deg);
border-width: 2px;
border-style: solid;
border-color: #fff;
border-top: 0;
border-left: 0; }
.magic-checkbox:checked + label:before {
border: #3e97eb;
background: #3e97eb; }
.magic-checkbox:checked[disabled] + label:before {
border: #c9e2f9;
background: #c9e2f9; }
<svg id="Слой_1" data-name="Слой 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10405.38 6166.66"><defs><style>.cls-1{fill:#45a2d1;}</style></defs><title>Монтажная область 4</title><path class="cls-1" d="M6894.6,1353.66h786.21c-20.28,138.69-43.06,289.61-62.58,418.91q-153.1,1014.2-306.65,2028.34c-30.88,204.32-60.4,408.85-92.62,613-17.37,110,11.17,166.33,99.46,183.67,126.76,24.9,213.54-23.09,230.14-133.09,39.54-262,75.63-524.52,114.07-786.69q93.9-640.39,189.08-1280.6,72.79-490.8,146.56-981.46c3.09-20.6,7.84-40.95,11.94-62h735.53c-23.07,157.94-45.17,311-67.81,463.95q-139.27,941.28-278.74,1882.53c-38.47,260.3-67.14,522.44-116.48,780.65C8220,4809,8010.41,5015.67,7695.65,5112.22c-257.24,78.91-520,79.09-780.16,12.56-349.18-89.28-516.77-363.05-459.94-719.94,65-407.87,119.94-817.32,179.65-1226Q6737,2481.89,6839.39,1785.06C6859.41,1648,6875.37,1489.37,6894.6,1353.66Z"/><polygon class="cls-1" points="752.03 0 1526.85 0 1155.39 2705.03 1645.35 1369.61 2370.04 1367.33 1693.21 3071.93 1923.38 4972.52 1118.93 4972.52 1036.89 3463.9 783.94 4972.52 0 4972.52 752.03 0"/><polygon class="cls-1" points="2695.35 1353.66 3510.62 1353.66 3611.46 2707.31 3838.78 1353.66 4512.19 1353.66 3990.89 4948.02 3184.17 4939.48 3083.33 3361.92 2823.53 4972.52 2139.87 4972.52 2695.35 1353.66"/><path class="cls-1" d="M5336,1353.66,4204.54,4972.52H5001L5182.18,4225l259.79,6.84-30.76,740.64h728.1l153.82-3618.87ZM5571.87,3685H5274.47L5701.76,2071.5Z"/><polygon class="cls-1" points="9092.74 1316.06 10405.38 1316.06 10330.17 1893.75 9837.94 1893.75 9749.06 2683.38 10217.37 2683.38 10138.75 3254.24 9649.93 3254.24 9226.06 6166.66 8361.22 6166.66 9092.74 1316.06"/></svg>
\ No newline at end of file
......@@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="utf-8">
<title>SPA</title>
<title>Knauf Specification Author</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
......
/* You can add global styles to this file, and also import other style files */
@font-face {
font-family: FuturaICGLight;
src: url(/assets/fonts/Futura_ICG_Light.ttf);
}
@font-face {
font-family: FuturaPT;
src: url(/assets/fonts/FuturaPTBook.otf);
}
@font-face {
font-family: MrEavesModOT;
src: url(/assets/fonts/MrEavesModOT-Reg.otf);
}
@font-face {
font-family: MrEavesModOTLight;
src: url(/assets/fonts/FuturaPTLight.otf);
}
.lastP {
margin-left: -1.5%;
margin-top: 4.5%;
color: #989898;
}
.color {
color: #009EE2;
font-weight: bold;
}
.loaderAbsHolder{
position: absolute;
width: 100%;
left: 0px;
top: 0px;
height: 100%;
z-index: 1000;
background: rgba(0,0,0,0.2);
}
button {
&.login{
background-image: url("/assets/img/right.png");
background-repeat: no-repeat;
border: none;
outline: none;
font-size: 15px;
font-family: FuturaPT;
color: rgb(255, 255, 255);
line-height: 1.2;
background-color: #009ee2;
padding: 1.6% 0;
padding-left: 4%;
padding-right: 4%;
letter-spacing: 0.9px;
font-weight: 500;
background-size: 13%;
background-position: calc(100% - 4px);
}
}
.modal{
background: rgba(0,0,0,0.4);
}
\ No newline at end of file
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