102 changed files with 2225 additions and 544 deletions
-
10angular.json
-
8mobileApp/.gitignore
-
25mobileApp/config.xml
-
27mobileApp/package.json
-
1mobileApp/www
-
106package.json
-
10src/app/app-routing.module.ts
-
500src/app/app.component.html
-
11src/app/app.component.spec.ts
-
2src/app/app.component.ts
-
41src/app/app.module.ts
-
9src/app/configs/hammerjs.ts
-
17src/app/constants/constants.ts
-
4src/app/constants/environments.ts
-
1src/app/constants/errorConstants.ts
-
17src/app/mock/http-mock-api.interceptor.ts
-
129src/app/mock/mock.config.ts
-
23src/app/mock/mock.module.ts
-
10src/app/model/forgotPassword.ts
-
11src/app/model/home.ts
-
9src/app/model/login.ts
-
9src/app/model/otp.ts
-
9src/app/models/googleFormData.ts
-
7src/app/models/header.ts
-
7src/app/models/leadScore.ts
-
7src/app/models/navigation.ts
-
13src/app/models/user.ts
-
36src/app/pages/home/home.component.html
-
69src/app/pages/home/home.component.scss
-
62src/app/pages/home/home.component.spec.ts
-
58src/app/pages/home/home.component.ts
-
21src/app/pages/home/home.service.ts
-
36src/app/pages/login/login/login.component.html
-
68src/app/pages/login/login/login.component.scss
-
61src/app/pages/login/login/login.component.spec.ts
-
75src/app/pages/login/login/login.component.ts
-
21src/app/pages/login/login/login.service.ts
-
16src/app/shared/components/header/header.component.html
-
9src/app/shared/components/header/header.component.scss
-
34src/app/shared/components/header/header.component.spec1.ts
-
68src/app/shared/components/header/header.component.ts
-
22src/app/shared/directives/app-password.directive.ts
-
24src/app/shared/helpers/auth.guard.ts
-
79src/app/shared/helpers/fake-backend.ts
-
3src/app/shared/helpers/index.ts
-
24src/app/shared/helpers/token.interceptor.ts
-
54src/app/shared/services/authentication.service.ts
-
0src/app/shared/services/httpClient/httpClient.service.spec.ts
-
44src/app/shared/services/httpClient/httpClient.service.ts
-
55src/app/shared/services/leadscore.service.ts
-
50src/app/shared/services/routerService.ts
-
29src/app/shared/utilities/utils.ts
-
BINsrc/assets/fonts/Blender-Bold.otf
-
BINsrc/assets/fonts/BlenderPro-Heavy.otf
-
BINsrc/assets/fonts/BlenderPro-Medium.otf
-
BINsrc/assets/fonts/PRIMETIME ∏ PERSONAL USE ONLY.ttf
-
BINsrc/assets/fonts/ProximaNova-Bold_0.otf
-
BINsrc/assets/fonts/ProximaNova-Reg_0.otf
-
BINsrc/assets/fonts/Rupee_Foradian.ttf
-
BINsrc/assets/fonts/TradeGothicLTCom-Bold.ttf
-
BINsrc/assets/fonts/TradeGothicLTCom-Cn18.ttf
-
BINsrc/assets/fonts/TradeGothicLTStd-BdCn20.otf
-
44src/assets/mockApi/enquiriesList.json
-
4src/assets/mockApi/forgotPassword.json
-
4src/assets/mockApi/generateOTP.json
-
22src/assets/mockApi/home.json
-
4src/assets/mockApi/login.json
-
5src/assets/mockApi/otp.json
-
8src/assets/mockApi/password_response.json
-
5src/assets/svg/add-icon.svg
-
4src/assets/svg/bajaj-logo.svg
-
4src/assets/svg/close.svg
-
9src/assets/svg/common-header-background.svg
-
4src/assets/svg/edit.svg
-
13src/assets/svg/icon-close-enquiry.svg
-
4src/assets/svg/input-password-eye.svg
-
17src/assets/svg/login-background.svg
-
4src/assets/svg/logo.svg
-
1src/assets/svg/logout.svg
-
3src/assets/svg/navigation-back-icon.svg
-
3src/assets/svg/notification-white-icon.svg
-
5src/assets/svg/password-disabled-dark.svg
-
4src/assets/svg/password-enabled-dark.svg
-
3src/assets/svg/star-selected.svg
-
3src/assets/svg/star.svg
-
3src/assets/svg/thumbs-down.svg
-
3src/assets/svg/thumbs-up.svg
-
4src/environments/environment.mock.ts
-
3src/environments/environment.ts
-
3src/index.html
-
22src/setup-jest.ts
-
6src/styles.scss
-
136src/styles/common.scss
-
15src/styles/css-reset.scss
-
141src/styles/fonts.scss
-
135src/styles/form-inputs.scss
-
32src/styles/variables/colors.scss
-
3src/styles/variables/index.scss
-
11src/styles/variables/mixins.scss
-
5src/styles/variables/rest.scss
@ -0,0 +1,8 @@ |
|||||
|
.DS_Store |
||||
|
|
||||
|
# Generated by package manager |
||||
|
node_modules/ |
||||
|
|
||||
|
# Generated by Cordova |
||||
|
/plugins/ |
||||
|
/platforms/ |
@ -0,0 +1,25 @@ |
|||||
|
<?xml version='1.0' encoding='utf-8'?> |
||||
|
<widget id="com.bajaj.psv" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0"> |
||||
|
<name>PSV Bajaj</name> |
||||
|
<description> |
||||
|
A sample Apache Cordova application that responds to the deviceready event. |
||||
|
</description> |
||||
|
<author email="dev@cordova.apache.org" href="http://cordova.io"> |
||||
|
Apache Cordova Team |
||||
|
</author> |
||||
|
<content src="index.html" /> |
||||
|
<access origin="*" /> |
||||
|
<allow-intent href="http://*/*" /> |
||||
|
<allow-intent href="https://*/*" /> |
||||
|
<allow-intent href="tel:*" /> |
||||
|
<allow-intent href="sms:*" /> |
||||
|
<allow-intent href="mailto:*" /> |
||||
|
<allow-intent href="geo:*" /> |
||||
|
<platform name="android"> |
||||
|
<allow-intent href="market:*" /> |
||||
|
</platform> |
||||
|
<platform name="ios"> |
||||
|
<allow-intent href="itms:*" /> |
||||
|
<allow-intent href="itms-apps:*" /> |
||||
|
</platform> |
||||
|
</widget> |
@ -0,0 +1,27 @@ |
|||||
|
{ |
||||
|
"name": "com.bajaj.psv", |
||||
|
"displayName": "HelloCordova", |
||||
|
"version": "1.0.0", |
||||
|
"description": "A sample Apache Cordova application that responds to the deviceready event.", |
||||
|
"main": "index.js", |
||||
|
"scripts": { |
||||
|
"test": "echo \"Error: no test specified\" && exit 1" |
||||
|
}, |
||||
|
"keywords": [ |
||||
|
"ecosystem:cordova" |
||||
|
], |
||||
|
"author": "Apache Cordova Team", |
||||
|
"license": "Apache-2.0", |
||||
|
"devDependencies": { |
||||
|
"cordova-android": "^9.1.0", |
||||
|
"cordova-plugin-whitelist": "^1.3.5" |
||||
|
}, |
||||
|
"cordova": { |
||||
|
"plugins": { |
||||
|
"cordova-plugin-whitelist": {} |
||||
|
}, |
||||
|
"platforms": [ |
||||
|
"android" |
||||
|
] |
||||
|
} |
||||
|
} |
@ -0,0 +1 @@ |
|||||
|
../dist/www |
@ -1,501 +1 @@ |
|||||
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * --> |
|
||||
<!-- * * * * * * * * * * * The content below * * * * * * * * * * * --> |
|
||||
<!-- * * * * * * * * * * is only a placeholder * * * * * * * * * * --> |
|
||||
<!-- * * * * * * * * * * and can be replaced. * * * * * * * * * * * --> |
|
||||
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * --> |
|
||||
<!-- * * * * * * * * * Delete the template below * * * * * * * * * * --> |
|
||||
<!-- * * * * * * * to get started with your project! * * * * * * * * --> |
|
||||
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * --> |
|
||||
|
|
||||
<style> |
|
||||
:host { |
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; |
|
||||
font-size: 14px; |
|
||||
color: #333; |
|
||||
box-sizing: border-box; |
|
||||
-webkit-font-smoothing: antialiased; |
|
||||
-moz-osx-font-smoothing: grayscale; |
|
||||
} |
|
||||
|
|
||||
h1, |
|
||||
h2, |
|
||||
h3, |
|
||||
h4, |
|
||||
h5, |
|
||||
h6 { |
|
||||
margin: 8px 0; |
|
||||
} |
|
||||
|
|
||||
p { |
|
||||
margin: 0; |
|
||||
} |
|
||||
|
|
||||
.spacer { |
|
||||
flex: 1; |
|
||||
} |
|
||||
|
|
||||
.toolbar { |
|
||||
position: absolute; |
|
||||
top: 0; |
|
||||
left: 0; |
|
||||
right: 0; |
|
||||
height: 60px; |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
background-color: #1976d2; |
|
||||
color: white; |
|
||||
font-weight: 600; |
|
||||
} |
|
||||
|
|
||||
.toolbar img { |
|
||||
margin: 0 16px; |
|
||||
} |
|
||||
|
|
||||
.toolbar #twitter-logo { |
|
||||
height: 40px; |
|
||||
margin: 0 8px; |
|
||||
} |
|
||||
|
|
||||
.toolbar #youtube-logo { |
|
||||
height: 40px; |
|
||||
margin: 0 16px; |
|
||||
} |
|
||||
|
|
||||
.toolbar #twitter-logo:hover, |
|
||||
.toolbar #youtube-logo:hover { |
|
||||
opacity: 0.8; |
|
||||
} |
|
||||
|
|
||||
.content { |
|
||||
display: flex; |
|
||||
margin: 82px auto 32px; |
|
||||
padding: 0 16px; |
|
||||
max-width: 960px; |
|
||||
flex-direction: column; |
|
||||
align-items: center; |
|
||||
} |
|
||||
|
|
||||
svg.material-icons { |
|
||||
height: 24px; |
|
||||
width: auto; |
|
||||
} |
|
||||
|
|
||||
svg.material-icons:not(:last-child) { |
|
||||
margin-right: 8px; |
|
||||
} |
|
||||
|
|
||||
.card svg.material-icons path { |
|
||||
fill: #888; |
|
||||
} |
|
||||
|
|
||||
.card-container { |
|
||||
display: flex; |
|
||||
flex-wrap: wrap; |
|
||||
justify-content: center; |
|
||||
margin-top: 16px; |
|
||||
} |
|
||||
|
|
||||
.card { |
|
||||
all: unset; |
|
||||
border-radius: 4px; |
|
||||
border: 1px solid #eee; |
|
||||
background-color: #fafafa; |
|
||||
height: 40px; |
|
||||
width: 200px; |
|
||||
margin: 0 8px 16px; |
|
||||
padding: 16px; |
|
||||
display: flex; |
|
||||
flex-direction: row; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
transition: all 0.2s ease-in-out; |
|
||||
line-height: 24px; |
|
||||
} |
|
||||
|
|
||||
.card-container .card:not(:last-child) { |
|
||||
margin-right: 0; |
|
||||
} |
|
||||
|
|
||||
.card.card-small { |
|
||||
height: 16px; |
|
||||
width: 168px; |
|
||||
} |
|
||||
|
|
||||
.card-container .card:not(.highlight-card) { |
|
||||
cursor: pointer; |
|
||||
} |
|
||||
|
|
||||
.card-container .card:not(.highlight-card):hover { |
|
||||
transform: translateY(-3px); |
|
||||
box-shadow: 0 4px 17px rgba(0, 0, 0, 0.35); |
|
||||
} |
|
||||
|
|
||||
.card-container .card:not(.highlight-card):hover .material-icons path { |
|
||||
fill: rgb(105, 103, 103); |
|
||||
} |
|
||||
|
|
||||
.card.highlight-card { |
|
||||
background-color: #1976d2; |
|
||||
color: white; |
|
||||
font-weight: 600; |
|
||||
border: none; |
|
||||
width: auto; |
|
||||
min-width: 30%; |
|
||||
position: relative; |
|
||||
} |
|
||||
|
|
||||
.card.card.highlight-card span { |
|
||||
margin-left: 60px; |
|
||||
} |
|
||||
|
|
||||
svg#rocket { |
|
||||
width: 80px; |
|
||||
position: absolute; |
|
||||
left: -10px; |
|
||||
top: -24px; |
|
||||
} |
|
||||
|
|
||||
svg#rocket-smoke { |
|
||||
height: calc(100vh - 95px); |
|
||||
position: absolute; |
|
||||
top: 10px; |
|
||||
right: 180px; |
|
||||
z-index: -10; |
|
||||
} |
|
||||
|
|
||||
a, |
|
||||
a:visited, |
|
||||
a:hover { |
|
||||
color: #1976d2; |
|
||||
text-decoration: none; |
|
||||
} |
|
||||
|
|
||||
a:hover { |
|
||||
color: #125699; |
|
||||
} |
|
||||
|
|
||||
.terminal { |
|
||||
position: relative; |
|
||||
width: 80%; |
|
||||
max-width: 600px; |
|
||||
border-radius: 6px; |
|
||||
padding-top: 45px; |
|
||||
margin-top: 8px; |
|
||||
overflow: hidden; |
|
||||
background-color: rgb(15, 15, 16); |
|
||||
} |
|
||||
|
|
||||
.terminal::before { |
|
||||
content: "\2022 \2022 \2022"; |
|
||||
position: absolute; |
|
||||
top: 0; |
|
||||
left: 0; |
|
||||
height: 4px; |
|
||||
background: rgb(58, 58, 58); |
|
||||
color: #c2c3c4; |
|
||||
width: 100%; |
|
||||
font-size: 2rem; |
|
||||
line-height: 0; |
|
||||
padding: 14px 0; |
|
||||
text-indent: 4px; |
|
||||
} |
|
||||
|
|
||||
.terminal pre { |
|
||||
font-family: SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace; |
|
||||
color: white; |
|
||||
padding: 0 1rem 1rem; |
|
||||
margin: 0; |
|
||||
} |
|
||||
|
|
||||
.circle-link { |
|
||||
height: 40px; |
|
||||
width: 40px; |
|
||||
border-radius: 40px; |
|
||||
margin: 8px; |
|
||||
background-color: white; |
|
||||
border: 1px solid #eeeeee; |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
cursor: pointer; |
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); |
|
||||
transition: 1s ease-out; |
|
||||
} |
|
||||
|
|
||||
.circle-link:hover { |
|
||||
transform: translateY(-0.25rem); |
|
||||
box-shadow: 0px 3px 15px rgba(0, 0, 0, 0.2); |
|
||||
} |
|
||||
|
|
||||
footer { |
|
||||
margin-top: 8px; |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
line-height: 20px; |
|
||||
} |
|
||||
|
|
||||
footer a { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
} |
|
||||
|
|
||||
.github-star-badge { |
|
||||
color: #24292e; |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
font-size: 12px; |
|
||||
padding: 3px 10px; |
|
||||
border: 1px solid rgba(27,31,35,.2); |
|
||||
border-radius: 3px; |
|
||||
background-image: linear-gradient(-180deg,#fafbfc,#eff3f6 90%); |
|
||||
margin-left: 4px; |
|
||||
font-weight: 600; |
|
||||
} |
|
||||
|
|
||||
.github-star-badge:hover { |
|
||||
background-image: linear-gradient(-180deg,#f0f3f6,#e6ebf1 90%); |
|
||||
border-color: rgba(27,31,35,.35); |
|
||||
background-position: -.5em; |
|
||||
} |
|
||||
|
|
||||
.github-star-badge .material-icons { |
|
||||
height: 16px; |
|
||||
width: 16px; |
|
||||
margin-right: 4px; |
|
||||
} |
|
||||
|
|
||||
svg#clouds { |
|
||||
position: fixed; |
|
||||
bottom: -160px; |
|
||||
left: -230px; |
|
||||
z-index: -10; |
|
||||
width: 1920px; |
|
||||
} |
|
||||
|
|
||||
/* Responsive Styles */ |
|
||||
@media screen and (max-width: 767px) { |
|
||||
.card-container > *:not(.circle-link) , |
|
||||
.terminal { |
|
||||
width: 100%; |
|
||||
} |
|
||||
|
|
||||
.card:not(.highlight-card) { |
|
||||
height: 16px; |
|
||||
margin: 8px 0; |
|
||||
} |
|
||||
|
|
||||
.card.highlight-card span { |
|
||||
margin-left: 72px; |
|
||||
} |
|
||||
|
|
||||
svg#rocket-smoke { |
|
||||
right: 120px; |
|
||||
transform: rotate(-5deg); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
@media screen and (max-width: 575px) { |
|
||||
svg#rocket-smoke { |
|
||||
display: none; |
|
||||
visibility: hidden; |
|
||||
} |
|
||||
} |
|
||||
</style> |
|
||||
|
|
||||
<!-- Toolbar --> |
|
||||
<div class="toolbar" role="banner"> |
|
||||
<img |
|
||||
width="40" |
|
||||
alt="Angular Logo" |
|
||||
src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg==" |
|
||||
/> |
|
||||
<span>Welcome</span> |
|
||||
<div class="spacer"></div> |
|
||||
<a aria-label="Angular on twitter" target="_blank" rel="noopener" href="https://twitter.com/angular" title="Twitter"> |
|
||||
<svg id="twitter-logo" height="24" data-name="Logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400"> |
|
||||
<rect width="400" height="400" fill="none"/> |
|
||||
<path d="M153.62,301.59c94.34,0,145.94-78.16,145.94-145.94,0-2.22,0-4.43-.15-6.63A104.36,104.36,0,0,0,325,122.47a102.38,102.38,0,0,1-29.46,8.07,51.47,51.47,0,0,0,22.55-28.37,102.79,102.79,0,0,1-32.57,12.45,51.34,51.34,0,0,0-87.41,46.78A145.62,145.62,0,0,1,92.4,107.81a51.33,51.33,0,0,0,15.88,68.47A50.91,50.91,0,0,1,85,169.86c0,.21,0,.43,0,.65a51.31,51.31,0,0,0,41.15,50.28,51.21,51.21,0,0,1-23.16.88,51.35,51.35,0,0,0,47.92,35.62,102.92,102.92,0,0,1-63.7,22A104.41,104.41,0,0,1,75,278.55a145.21,145.21,0,0,0,78.62,23" fill="#fff"/> |
|
||||
</svg> |
|
||||
</a> |
|
||||
<a aria-label="Angular on YouTube" target="_blank" rel="noopener" href="https://youtube.com/angular" title="YouTube"> |
|
||||
<svg id="youtube-logo" height="24" width="24" data-name="Logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#fff"> |
|
||||
<path d="M0 0h24v24H0V0z" fill="none"/> |
|
||||
<path d="M21.58 7.19c-.23-.86-.91-1.54-1.77-1.77C18.25 5 12 5 12 5s-6.25 0-7.81.42c-.86.23-1.54.91-1.77 1.77C2 8.75 2 12 2 12s0 3.25.42 4.81c.23.86.91 1.54 1.77 1.77C5.75 19 12 19 12 19s6.25 0 7.81-.42c.86-.23 1.54-.91 1.77-1.77C22 15.25 22 12 22 12s0-3.25-.42-4.81zM10 15V9l5.2 3-5.2 3z"/> |
|
||||
</svg> |
|
||||
</a> |
|
||||
</div> |
|
||||
|
|
||||
<div class="content" role="main"> |
|
||||
|
|
||||
<!-- Highlight Card --> |
|
||||
<div class="card highlight-card card-small"> |
|
||||
|
|
||||
<svg id="rocket" xmlns="http://www.w3.org/2000/svg" width="101.678" height="101.678" viewBox="0 0 101.678 101.678"> |
|
||||
<title>Rocket Ship</title> |
|
||||
<g id="Group_83" data-name="Group 83" transform="translate(-141 -696)"> |
|
||||
<circle id="Ellipse_8" data-name="Ellipse 8" cx="50.839" cy="50.839" r="50.839" transform="translate(141 696)" fill="#dd0031"/> |
|
||||
<g id="Group_47" data-name="Group 47" transform="translate(165.185 720.185)"> |
|
||||
<path id="Path_33" data-name="Path 33" d="M3.4,42.615a3.084,3.084,0,0,0,3.553,3.553,21.419,21.419,0,0,0,12.215-6.107L9.511,30.4A21.419,21.419,0,0,0,3.4,42.615Z" transform="translate(0.371 3.363)" fill="#fff"/> |
|
||||
<path id="Path_34" data-name="Path 34" d="M53.3,3.221A3.09,3.09,0,0,0,50.081,0,48.227,48.227,0,0,0,18.322,13.437c-6-1.666-14.991-1.221-18.322,7.218A33.892,33.892,0,0,1,9.439,25.1l-.333.666a3.013,3.013,0,0,0,.555,3.553L23.985,43.641a2.9,2.9,0,0,0,3.553.555l.666-.333A33.892,33.892,0,0,1,32.647,53.3c8.55-3.664,8.884-12.326,7.218-18.322A48.227,48.227,0,0,0,53.3,3.221ZM34.424,9.772a6.439,6.439,0,1,1,9.106,9.106,6.368,6.368,0,0,1-9.106,0A6.467,6.467,0,0,1,34.424,9.772Z" transform="translate(0 0.005)" fill="#fff"/> |
|
||||
</g> |
|
||||
</g> |
|
||||
</svg> |
|
||||
|
|
||||
<span>{{ title }} app is running!</span> |
|
||||
|
|
||||
<svg id="rocket-smoke" xmlns="http://www.w3.org/2000/svg" width="516.119" height="1083.632" viewBox="0 0 516.119 1083.632"> |
|
||||
<title>Rocket Ship Smoke</title> |
|
||||
<path id="Path_40" data-name="Path 40" d="M644.6,141S143.02,215.537,147.049,870.207s342.774,201.755,342.774,201.755S404.659,847.213,388.815,762.2c-27.116-145.51-11.551-384.124,271.9-609.1C671.15,139.365,644.6,141,644.6,141Z" transform="translate(-147.025 -140.939)" fill="#f5f5f5"/> |
|
||||
</svg> |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
<!-- Resources --> |
|
||||
<h2>Resources</h2> |
|
||||
<p>Here are some links to help you get started:</p> |
|
||||
|
|
||||
<div class="card-container"> |
|
||||
<a class="card" target="_blank" rel="noopener" href="https://angular.io/tutorial"> |
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M5 13.18v4L12 21l7-3.82v-4L12 17l-7-3.82zM12 3L1 9l11 6 9-4.91V17h2V9L12 3z"/></svg> |
|
||||
<span>Learn Angular</span> |
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></svg> </a> |
|
||||
|
|
||||
<a class="card" target="_blank" rel="noopener" href="https://angular.io/cli"> |
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"/></svg> |
|
||||
<span>CLI Documentation</span> |
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></svg> |
|
||||
</a> |
|
||||
|
|
||||
<a class="card" target="_blank" rel="noopener" href="https://blog.angular.io/"> |
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M13.5.67s.74 2.65.74 4.8c0 2.06-1.35 3.73-3.41 3.73-2.07 0-3.63-1.67-3.63-3.73l.03-.36C5.21 7.51 4 10.62 4 14c0 4.42 3.58 8 8 8s8-3.58 8-8C20 8.61 17.41 3.8 13.5.67zM11.71 19c-1.78 0-3.22-1.4-3.22-3.14 0-1.62 1.05-2.76 2.81-3.12 1.77-.36 3.6-1.21 4.62-2.58.39 1.29.59 2.65.59 4.04 0 2.65-2.15 4.8-4.8 4.8z"/></svg> |
|
||||
<span>Angular Blog</span> |
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></svg> |
|
||||
</a> |
|
||||
|
|
||||
<a class="card" target="_blank" rel="noopener" href="https://angular.io/devtools/"> |
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g><rect fill="none" height="24" width="24"/></g><g><g><path d="M14.73,13.31C15.52,12.24,16,10.93,16,9.5C16,5.91,13.09,3,9.5,3S3,5.91,3,9.5C3,13.09,5.91,16,9.5,16 c1.43,0,2.74-0.48,3.81-1.27L19.59,21L21,19.59L14.73,13.31z M9.5,14C7.01,14,5,11.99,5,9.5S7.01,5,9.5,5S14,7.01,14,9.5 S11.99,14,9.5,14z"/><polygon points="10.29,8.44 9.5,6 8.71,8.44 6.25,8.44 8.26,10.03 7.49,12.5 9.5,10.97 11.51,12.5 10.74,10.03 12.75,8.44"/></g></g></svg> |
|
||||
<span>Angular DevTools</span> |
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></svg> |
|
||||
</a> |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
<!-- Next Steps --> |
|
||||
<h2>Next Steps</h2> |
|
||||
<p>What do you want to do next with your app?</p> |
|
||||
|
|
||||
<input type="hidden" #selection> |
|
||||
|
|
||||
<div class="card-container"> |
|
||||
<button class="card card-small" (click)="selection.value = 'component'" tabindex="0"> |
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg> |
|
||||
<span>New Component</span> |
|
||||
</button> |
|
||||
|
|
||||
<button class="card card-small" (click)="selection.value = 'material'" tabindex="0"> |
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg> |
|
||||
<span>Angular Material</span> |
|
||||
</button> |
|
||||
|
|
||||
<button class="card card-small" (click)="selection.value = 'pwa'" tabindex="0"> |
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg> |
|
||||
<span>Add PWA Support</span> |
|
||||
</button> |
|
||||
|
|
||||
<button class="card card-small" (click)="selection.value = 'dependency'" tabindex="0"> |
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg> |
|
||||
<span>Add Dependency</span> |
|
||||
</button> |
|
||||
|
|
||||
<button class="card card-small" (click)="selection.value = 'test'" tabindex="0"> |
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg> |
|
||||
<span>Run and Watch Tests</span> |
|
||||
</button> |
|
||||
|
|
||||
<button class="card card-small" (click)="selection.value = 'build'" tabindex="0"> |
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg> |
|
||||
<span>Build for Production</span> |
|
||||
</button> |
|
||||
</div> |
|
||||
|
|
||||
<!-- Terminal --> |
|
||||
<div class="terminal" [ngSwitch]="selection.value"> |
|
||||
<pre *ngSwitchDefault>ng generate component xyz</pre> |
|
||||
<pre *ngSwitchCase="'material'">ng add @angular/material</pre> |
|
||||
<pre *ngSwitchCase="'pwa'">ng add @angular/pwa</pre> |
|
||||
<pre *ngSwitchCase="'dependency'">ng add _____</pre> |
|
||||
<pre *ngSwitchCase="'test'">ng test</pre> |
|
||||
<pre *ngSwitchCase="'build'">ng build</pre> |
|
||||
</div> |
|
||||
|
|
||||
<!-- Links --> |
|
||||
<div class="card-container"> |
|
||||
<a class="circle-link" title="Animations" href="https://angular.io/guide/animations" target="_blank" rel="noopener"> |
|
||||
<svg id="Group_20" data-name="Group 20" xmlns="http://www.w3.org/2000/svg" width="21.813" height="23.453" viewBox="0 0 21.813 23.453"> |
|
||||
<path id="Path_15" data-name="Path 15" d="M4099.584,972.736h0l-10.882,3.9,1.637,14.4,9.245,5.153,9.245-5.153,1.686-14.4Z" transform="translate(-4088.702 -972.736)" fill="#ffa726"/> |
|
||||
<path id="Path_16" data-name="Path 16" d="M4181.516,972.736v23.453l9.245-5.153,1.686-14.4Z" transform="translate(-4170.633 -972.736)" fill="#fb8c00"/> |
|
||||
<path id="Path_17" data-name="Path 17" d="M4137.529,1076.127l-7.7-3.723,4.417-2.721,7.753,3.723Z" transform="translate(-4125.003 -1058.315)" fill="#ffe0b2"/> |
|
||||
<path id="Path_18" data-name="Path 18" d="M4137.529,1051.705l-7.7-3.723,4.417-2.721,7.753,3.723Z" transform="translate(-4125.003 -1036.757)" fill="#fff3e0"/> |
|
||||
<path id="Path_19" data-name="Path 19" d="M4137.529,1027.283l-7.7-3.723,4.417-2.721,7.753,3.723Z" transform="translate(-4125.003 -1015.199)" fill="#fff"/> |
|
||||
</svg> |
|
||||
</a> |
|
||||
|
|
||||
<a class="circle-link" title="CLI" href="https://cli.angular.io/" target="_blank" rel="noopener"> |
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="21.762" height="23.447" viewBox="0 0 21.762 23.447"> |
|
||||
<title>Angular CLI Logo</title> |
|
||||
<g id="Group_21" data-name="Group 21" transform="translate(0)"> |
|
||||
<path id="Path_20" data-name="Path 20" d="M2660.313,313.618h0l-10.833,3.9,1.637,14.4,9.2,5.152,9.244-5.152,1.685-14.4Z" transform="translate(-2649.48 -313.618)" fill="#37474f"/> |
|
||||
<path id="Path_21" data-name="Path 21" d="M2741.883,313.618v23.447l9.244-5.152,1.685-14.4Z" transform="translate(-2731.05 -313.618)" fill="#263238"/> |
|
||||
<path id="Path_22" data-name="Path 22" d="M2692.293,379.169h11.724V368.618h-11.724Zm11.159-.6h-10.608v-9.345h10.621v9.345Z" transform="translate(-2687.274 -362.17)" fill="#fff"/> |
|
||||
<path id="Path_23" data-name="Path 23" d="M2709.331,393.688l.4.416,2.265-2.28-2.294-2.294-.4.4,1.893,1.893Z" transform="translate(-2702.289 -380.631)" fill="#fff"/> |
|
||||
<rect id="Rectangle_12" data-name="Rectangle 12" width="3.517" height="0.469" transform="translate(9.709 13.744)" fill="#fff"/> |
|
||||
</g> |
|
||||
</svg> |
|
||||
</a> |
|
||||
|
|
||||
<a class="circle-link" title="Find a Local Meetup" href="https://www.meetup.com/find/?keywords=angular" target="_blank" rel="noopener"> |
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24.607" height="23.447" viewBox="0 0 24.607 23.447"> |
|
||||
<title>Meetup Logo</title> |
|
||||
<path id="logo--mSwarm" d="M21.221,14.95A4.393,4.393,0,0,1,17.6,19.281a4.452,4.452,0,0,1-.8.069c-.09,0-.125.035-.154.117a2.939,2.939,0,0,1-2.506,2.091,2.868,2.868,0,0,1-2.248-.624.168.168,0,0,0-.245-.005,3.926,3.926,0,0,1-2.589.741,4.015,4.015,0,0,1-3.7-3.347,2.7,2.7,0,0,1-.043-.38c0-.106-.042-.146-.143-.166a3.524,3.524,0,0,1-1.516-.69A3.623,3.623,0,0,1,2.23,14.557a3.66,3.66,0,0,1,1.077-3.085.138.138,0,0,0,.026-.2,3.348,3.348,0,0,1-.451-1.821,3.46,3.46,0,0,1,2.749-3.28.44.44,0,0,0,.355-.281,5.072,5.072,0,0,1,3.863-3,5.028,5.028,0,0,1,3.555.666.31.31,0,0,0,.271.03A4.5,4.5,0,0,1,18.3,4.7a4.4,4.4,0,0,1,1.334,2.751,3.658,3.658,0,0,1,.022.706.131.131,0,0,0,.1.157,2.432,2.432,0,0,1,1.574,1.645,2.464,2.464,0,0,1-.7,2.616c-.065.064-.051.1-.014.166A4.321,4.321,0,0,1,21.221,14.95ZM13.4,14.607a2.09,2.09,0,0,0,1.409,1.982,4.7,4.7,0,0,0,1.275.221,1.807,1.807,0,0,0,.9-.151.542.542,0,0,0,.321-.545.558.558,0,0,0-.359-.534,1.2,1.2,0,0,0-.254-.078c-.262-.047-.526-.086-.787-.138a.674.674,0,0,1-.617-.75,3.394,3.394,0,0,1,.218-1.109c.217-.658.509-1.286.79-1.918a15.609,15.609,0,0,0,.745-1.86,1.95,1.95,0,0,0,.06-1.073,1.286,1.286,0,0,0-1.051-1.033,1.977,1.977,0,0,0-1.521.2.339.339,0,0,1-.446-.042c-.1-.092-.2-.189-.307-.284a1.214,1.214,0,0,0-1.643-.061,7.563,7.563,0,0,1-.614.512A.588.588,0,0,1,10.883,8c-.215-.115-.437-.215-.659-.316a2.153,2.153,0,0,0-.695-.248A2.091,2.091,0,0,0,7.541,8.562a9.915,9.915,0,0,0-.405.986c-.559,1.545-1.015,3.123-1.487,4.7a1.528,1.528,0,0,0,.634,1.777,1.755,1.755,0,0,0,1.5.211,1.35,1.35,0,0,0,.824-.858c.543-1.281,1.032-2.584,1.55-3.875.142-.355.28-.712.432-1.064a.548.548,0,0,1,.851-.24.622.622,0,0,1,.185.539,2.161,2.161,0,0,1-.181.621c-.337.852-.68,1.7-1.018,2.552a2.564,2.564,0,0,0-.173.528.624.624,0,0,0,.333.71,1.073,1.073,0,0,0,.814.034,1.22,1.22,0,0,0,.657-.655q.758-1.488,1.511-2.978.35-.687.709-1.37a1.073,1.073,0,0,1,.357-.434.43.43,0,0,1,.463-.016.373.373,0,0,1,.153.387.7.7,0,0,1-.057.236c-.065.157-.127.316-.2.469-.42.883-.846,1.763-1.262,2.648A2.463,2.463,0,0,0,13.4,14.607Zm5.888,6.508a1.09,1.09,0,0,0-2.179.006,1.09,1.09,0,0,0,2.179-.006ZM1.028,12.139a1.038,1.038,0,1,0,.01-2.075,1.038,1.038,0,0,0-.01,2.075ZM13.782.528a1.027,1.027,0,1,0-.011,2.055A1.027,1.027,0,0,0,13.782.528ZM22.21,6.95a.882.882,0,0,0-1.763.011A.882.882,0,0,0,22.21,6.95ZM4.153,4.439a.785.785,0,1,0,.787-.78A.766.766,0,0,0,4.153,4.439Zm8.221,18.22a.676.676,0,1,0-.677.666A.671.671,0,0,0,12.374,22.658ZM22.872,12.2a.674.674,0,0,0-.665.665.656.656,0,0,0,.655.643.634.634,0,0,0,.655-.644A.654.654,0,0,0,22.872,12.2ZM7.171-.123A.546.546,0,0,0,6.613.43a.553.553,0,1,0,1.106,0A.539.539,0,0,0,7.171-.123ZM24.119,9.234a.507.507,0,0,0-.493.488.494.494,0,0,0,.494.494.48.48,0,0,0,.487-.483A.491.491,0,0,0,24.119,9.234Zm-19.454,9.7a.5.5,0,0,0-.488-.488.491.491,0,0,0-.487.5.483.483,0,0,0,.491.479A.49.49,0,0,0,4.665,18.936Z" transform="translate(0 0.123)" fill="#f64060"/> |
|
||||
</svg> |
|
||||
</a> |
|
||||
|
|
||||
<a class="circle-link" title="Join the Conversation on Discord" href="https://discord.gg/angular" target="_blank" rel="noopener"> |
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 245 240"> |
|
||||
<title>Discord Logo</title> |
|
||||
<path d="M104.4 103.9c-5.7 0-10.2 5-10.2 11.1s4.6 11.1 10.2 11.1c5.7 0 10.2-5 10.2-11.1.1-6.1-4.5-11.1-10.2-11.1zM140.9 103.9c-5.7 0-10.2 5-10.2 11.1s4.6 11.1 10.2 11.1c5.7 0 10.2-5 10.2-11.1s-4.5-11.1-10.2-11.1z"/> |
|
||||
<path d="M189.5 20h-134C44.2 20 35 29.2 35 40.6v135.2c0 11.4 9.2 20.6 20.5 20.6h113.4l-5.3-18.5 12.8 11.9 12.1 11.2 21.5 19V40.6c0-11.4-9.2-20.6-20.5-20.6zm-38.6 130.6s-3.6-4.3-6.6-8.1c13.1-3.7 18.1-11.9 18.1-11.9-4.1 2.7-8 4.6-11.5 5.9-5 2.1-9.8 3.5-14.5 4.3-9.6 1.8-18.4 1.3-25.9-.1-5.7-1.1-10.6-2.7-14.7-4.3-2.3-.9-4.8-2-7.3-3.4-.3-.2-.6-.3-.9-.5-.2-.1-.3-.2-.4-.3-1.8-1-2.8-1.7-2.8-1.7s4.8 8 17.5 11.8c-3 3.8-6.7 8.3-6.7 8.3-22.1-.7-30.5-15.2-30.5-15.2 0-32.2 14.4-58.3 14.4-58.3 14.4-10.8 28.1-10.5 28.1-10.5l1 1.2c-18 5.2-26.3 13.1-26.3 13.1s2.2-1.2 5.9-2.9c10.7-4.7 19.2-6 22.7-6.3.6-.1 1.1-.2 1.7-.2 6.1-.8 13-1 20.2-.2 9.5 1.1 19.7 3.9 30.1 9.6 0 0-7.9-7.5-24.9-12.7l1.4-1.6s13.7-.3 28.1 10.5c0 0 14.4 26.1 14.4 58.3 0 0-8.5 14.5-30.6 15.2z"/> |
|
||||
</svg> |
|
||||
</a> |
|
||||
</div> |
|
||||
|
|
||||
<!-- Footer --> |
|
||||
<footer> |
|
||||
Love Angular? |
|
||||
<a href="https://github.com/angular/angular" target="_blank" rel="noopener"> Give our repo a star. |
|
||||
<div class="github-star-badge"> |
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"/></svg> |
|
||||
Star |
|
||||
</div> |
|
||||
</a> |
|
||||
<a href="https://github.com/angular/angular" target="_blank" rel="noopener"> |
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" fill="#1976d2"/><path d="M0 0h24v24H0z" fill="none"/></svg> |
|
||||
</a> |
|
||||
</footer> |
|
||||
|
|
||||
<svg id="clouds" xmlns="http://www.w3.org/2000/svg" width="2611.084" height="485.677" viewBox="0 0 2611.084 485.677"> |
|
||||
<title>Gray Clouds Background</title> |
|
||||
<path id="Path_39" data-name="Path 39" d="M2379.709,863.793c10-93-77-171-168-149-52-114-225-105-264,15-75,3-140,59-152,133-30,2.83-66.725,9.829-93.5,26.25-26.771-16.421-63.5-23.42-93.5-26.25-12-74-77-130-152-133-39-120-212-129-264-15-54.084-13.075-106.753,9.173-138.488,48.9-31.734-39.726-84.4-61.974-138.487-48.9-52-114-225-105-264,15a162.027,162.027,0,0,0-103.147,43.044c-30.633-45.365-87.1-72.091-145.206-58.044-52-114-225-105-264,15-75,3-140,59-152,133-53,5-127,23-130,83-2,42,35,72,70,86,49,20,106,18,157,5a165.625,165.625,0,0,0,120,0c47,94,178,113,251,33,61.112,8.015,113.854-5.72,150.492-29.764a165.62,165.62,0,0,0,110.861-3.236c47,94,178,113,251,33,31.385,4.116,60.563,2.495,86.487-3.311,25.924,5.806,55.1,7.427,86.488,3.311,73,80,204,61,251-33a165.625,165.625,0,0,0,120,0c51,13,108,15,157-5a147.188,147.188,0,0,0,33.5-18.694,147.217,147.217,0,0,0,33.5,18.694c49,20,106,18,157,5a165.625,165.625,0,0,0,120,0c47,94,178,113,251,33C2446.709,1093.793,2554.709,922.793,2379.709,863.793Z" transform="translate(142.69 -634.312)" fill="#eee"/> |
|
||||
</svg> |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * --> |
|
||||
<!-- * * * * * * * * * * * The content above * * * * * * * * * * * --> |
|
||||
<!-- * * * * * * * * * * is only a placeholder * * * * * * * * * * --> |
|
||||
<!-- * * * * * * * * * * and can be replaced. * * * * * * * * * * * --> |
|
||||
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * --> |
|
||||
<!-- * * * * * * * * * * End of Placeholder * * * * * * * * * * * --> |
|
||||
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * --> |
|
||||
|
|
||||
<router-outlet></router-outlet> |
<router-outlet></router-outlet> |
@ -1,18 +1,49 @@ |
|||||
import { NgModule } from '@angular/core'; |
import { NgModule } from '@angular/core'; |
||||
import { BrowserModule } from '@angular/platform-browser'; |
|
||||
|
|
||||
|
import { BrowserModule, HammerModule, HAMMER_GESTURE_CONFIG } from '@angular/platform-browser'; |
||||
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms'; |
||||
import { AppRoutingModule } from './app-routing.module'; |
import { AppRoutingModule } from './app-routing.module'; |
||||
|
|
||||
|
// configs
|
||||
|
import { HammerConfig } from './configs/hammerjs'; |
||||
|
|
||||
|
// components
|
||||
import { AppComponent } from './app.component'; |
import { AppComponent } from './app.component'; |
||||
|
import { HeaderComponent } from './shared/components/header/header.component'; |
||||
|
|
||||
|
import { LoginComponent } from './pages/login/login/login.component'; |
||||
|
import { RouterService } from './shared/services/routerService'; |
||||
|
|
||||
|
import { HttpClientService } from './shared/services/httpClient/httpClient.service'; |
||||
|
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; |
||||
|
import { HomeComponent } from './pages/home/home.component'; |
||||
|
|
||||
|
import { fakeBackendProvider, TokenInterceptor } from '../app/shared/helpers'; |
||||
|
|
||||
|
|
||||
@NgModule({ |
@NgModule({ |
||||
declarations: [ |
declarations: [ |
||||
AppComponent |
|
||||
|
AppComponent, |
||||
|
HeaderComponent, |
||||
|
LoginComponent, |
||||
|
HomeComponent |
||||
], |
], |
||||
imports: [ |
imports: [ |
||||
BrowserModule, |
BrowserModule, |
||||
AppRoutingModule |
|
||||
|
AppRoutingModule, |
||||
|
FormsModule, |
||||
|
HttpClientModule, |
||||
|
ReactiveFormsModule |
||||
|
], |
||||
|
providers: [ |
||||
|
RouterService, |
||||
|
HttpClientService, |
||||
|
// {
|
||||
|
// provide: HTTP_INTERCEPTORS,
|
||||
|
// useClass: TokenInterceptor,
|
||||
|
// multi: true
|
||||
|
// },
|
||||
|
fakeBackendProvider |
||||
], |
], |
||||
providers: [], |
|
||||
bootstrap: [AppComponent] |
bootstrap: [AppComponent] |
||||
}) |
}) |
||||
export class AppModule { } |
export class AppModule { } |
@ -0,0 +1,9 @@ |
|||||
|
import { HammerGestureConfig } from '@angular/platform-browser'; |
||||
|
|
||||
|
declare var Hammer: any; |
||||
|
|
||||
|
export class HammerConfig extends HammerGestureConfig { |
||||
|
overrides = <any> { |
||||
|
swipe: { direction: Hammer.DIRECTION_ALL }, |
||||
|
}; |
||||
|
} |
@ -0,0 +1,17 @@ |
|||||
|
// common constants
|
||||
|
|
||||
|
// footer constants goes here
|
||||
|
export const home = "home"; |
||||
|
export const login = "login"; |
||||
|
export const toDolist = "newProspectPage"; |
||||
|
export const more = "more"; |
||||
|
|
||||
|
// enquiry list constants goes here
|
||||
|
export const backButton = 'backButton'; |
||||
|
|
||||
|
// api response
|
||||
|
export const success = "success"; |
||||
|
|
||||
|
// Notification
|
||||
|
export const logOutButton = "logOutButton"; |
||||
|
export const logoButton = "logoButton"; |
@ -0,0 +1,4 @@ |
|||||
|
// navigating urls
|
||||
|
export const enquiriesListApi = "enquiriesList"; |
||||
|
export const loginApi = "login"; |
||||
|
export const homeApi = "home"; |
@ -0,0 +1 @@ |
|||||
|
export const invalidUsernameAndPassword = "Invalid Username or Password"; |
@ -0,0 +1,17 @@ |
|||||
|
// Angular imports
|
||||
|
import {Injectable} from '@angular/core'; |
||||
|
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http'; |
||||
|
import {Observable} from 'rxjs'; |
||||
|
// Local imports
|
||||
|
import {selectHandler} from './mock.config'; |
||||
|
|
||||
|
@Injectable() |
||||
|
export class HttpMockApiInterceptor implements HttpInterceptor { |
||||
|
constructor() { |
||||
|
} |
||||
|
|
||||
|
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { |
||||
|
const mockEndpointHandler = selectHandler(request); |
||||
|
return mockEndpointHandler ? mockEndpointHandler(request) : next.handle(request); |
||||
|
} |
||||
|
} |
@ -0,0 +1,129 @@ |
|||||
|
// Angular imports
|
||||
|
import { of } from 'rxjs'; |
||||
|
import { HttpRequest, HttpResponse } from '@angular/common/http'; |
||||
|
import { delay } from 'rxjs/operators'; |
||||
|
|
||||
|
// Local imports
|
||||
|
// api response structures
|
||||
|
import { IHomeResponse } from '../model/home'; |
||||
|
import { IOtpResponse } from '../model/otp'; |
||||
|
import { ILoginResponse } from '../../app/model/login'; |
||||
|
|
||||
|
// mock reponse imports
|
||||
|
import * as mockHomeApi from '../../assets/mockApi/home.json'; |
||||
|
import * as mockLoginApiResponse from '../../assets/mockApi/login.json'; |
||||
|
import * as mockForgotPasswordApiResponse from '../../assets/mockApi/login.json'; |
||||
|
import * as mockOtpApiResponse from '../../assets/mockApi/otp.json'; |
||||
|
import * as mockEnquiriesListApi from '../../assets/mockApi/enquiriesList.json'; |
||||
|
import { enquiriesListApi, homeApi, loginApi } from '../constants/environments'; |
||||
|
|
||||
|
|
||||
|
|
||||
|
// post request's here
|
||||
|
const postLoginData = (request: HttpRequest<any>) => { |
||||
|
let loginResponse: ILoginResponse = mockLoginApiResponse; |
||||
|
|
||||
|
return of(new HttpResponse({ |
||||
|
status: 200, body: loginResponse |
||||
|
})).pipe(delay(1000)); |
||||
|
}; |
||||
|
|
||||
|
const postForgotPasswordData = (request: HttpRequest<any>) => { |
||||
|
let apiResponse: IHomeResponse = mockForgotPasswordApiResponse; |
||||
|
|
||||
|
return of(new HttpResponse({ |
||||
|
status: 200, body: apiResponse |
||||
|
})).pipe(delay(1000)); |
||||
|
}; |
||||
|
|
||||
|
const getTodoListData = (request: HttpRequest<any>) => { |
||||
|
let homeResponse: any = mockHomeApi; |
||||
|
|
||||
|
return of(new HttpResponse({ |
||||
|
status: 200, body: JSON.stringify(homeResponse) |
||||
|
})).pipe(delay(2000)); |
||||
|
}; |
||||
|
|
||||
|
const getEnquiriesListData = (request: HttpRequest<any>) => { |
||||
|
let enquiriesList: any = mockEnquiriesListApi; |
||||
|
|
||||
|
return of(new HttpResponse({ |
||||
|
status: 200, body: JSON.stringify(enquiriesList) |
||||
|
})).pipe(delay(2000)); |
||||
|
}; |
||||
|
|
||||
|
const getCountry = (request: HttpRequest<any>) => { |
||||
|
// const id = extractIdPathParamFromUrl(request);
|
||||
|
// const country = countries.find(c => c.id === id);
|
||||
|
// return of(new HttpResponse({
|
||||
|
// status: 200, body: country
|
||||
|
// }));
|
||||
|
}; |
||||
|
|
||||
|
const extractIdPathParamFromUrl = (request: HttpRequest<any>) => { |
||||
|
// const requestUrl = new URL(request.url);
|
||||
|
// return requestUrl.pathname.split('/').pop();
|
||||
|
}; |
||||
|
|
||||
|
const addCountry = (request: HttpRequest<any>) => { |
||||
|
// const country = request.body as Country;
|
||||
|
// countries.push(country);
|
||||
|
// return of(new HttpResponse({
|
||||
|
// status: 200, body: country
|
||||
|
// }));
|
||||
|
}; |
||||
|
|
||||
|
const editCountry = (request: HttpRequest<any>) => { |
||||
|
// const id = extractIdPathParamFromUrl(request);
|
||||
|
// const countryIndex = countries.findIndex(c => c.id === id);
|
||||
|
// const country = request.body as Country;
|
||||
|
// countries[countryIndex] = country;
|
||||
|
// return of(new HttpResponse({
|
||||
|
// status: 200, body: country
|
||||
|
// }));
|
||||
|
}; |
||||
|
|
||||
|
// GET request's here
|
||||
|
const getOtp = (request: HttpRequest<any>) => { |
||||
|
let apiResponse: IOtpResponse = mockOtpApiResponse; |
||||
|
|
||||
|
return of(new HttpResponse({ |
||||
|
status: 200, body: apiResponse |
||||
|
})).pipe(delay(1000)); |
||||
|
}; |
||||
|
|
||||
|
export const selectHandler = (request: HttpRequest<any>) => { |
||||
|
const requestUrl = new URL(request.url); |
||||
|
let pathname = requestUrl.pathname; |
||||
|
|
||||
|
switch (request.method) { |
||||
|
case 'POST': |
||||
|
switch (pathname) { |
||||
|
case '/login': |
||||
|
return postLoginData; |
||||
|
case '/home': |
||||
|
return getTodoListData; |
||||
|
case '/forgotPassword': |
||||
|
return postForgotPasswordData; |
||||
|
case '/forgotPassword': |
||||
|
return postForgotPasswordData; |
||||
|
case `/${enquiriesListApi}`: |
||||
|
return getEnquiriesListData; |
||||
|
default: |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
case 'GET': |
||||
|
switch (pathname) { |
||||
|
case ((pathname.match(/otp/)) ? pathname : undefined): |
||||
|
return getOtp; |
||||
|
default: |
||||
|
|
||||
|
console.log('default', pathname); |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
default: |
||||
|
return null; |
||||
|
} |
||||
|
}; |
@ -0,0 +1,23 @@ |
|||||
|
// Angular imports
|
||||
|
import {NgModule} from '@angular/core'; |
||||
|
import {CommonModule} from '@angular/common'; |
||||
|
import {HTTP_INTERCEPTORS} from '@angular/common/http'; |
||||
|
// Local imports
|
||||
|
import {HttpMockApiInterceptor} from './http-mock-api.interceptor'; |
||||
|
|
||||
|
|
||||
|
@NgModule({ |
||||
|
declarations: [], |
||||
|
imports: [ |
||||
|
CommonModule, |
||||
|
], |
||||
|
providers: [ |
||||
|
{ |
||||
|
provide: HTTP_INTERCEPTORS, |
||||
|
useClass: HttpMockApiInterceptor, |
||||
|
multi: true |
||||
|
} |
||||
|
] |
||||
|
}) |
||||
|
export class MockModule { |
||||
|
} |
@ -0,0 +1,10 @@ |
|||||
|
export interface IForgotPasswordRequest{ |
||||
|
mobileNumber: string; |
||||
|
password: string; |
||||
|
otp: string; |
||||
|
} |
||||
|
|
||||
|
export interface IForgotPasswordResponse { |
||||
|
result: string; |
||||
|
error: string; |
||||
|
} |
@ -0,0 +1,11 @@ |
|||||
|
export interface IHomeRequest{ |
||||
|
user: string; |
||||
|
quotation: string; |
||||
|
bike:string; |
||||
|
status:string; |
||||
|
} |
||||
|
|
||||
|
export interface IHomeResponse { |
||||
|
result: string; |
||||
|
token: string; |
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
export interface ILoginRequest{ |
||||
|
username: string; |
||||
|
password: string; |
||||
|
} |
||||
|
|
||||
|
export interface ILoginResponse { |
||||
|
result: string; |
||||
|
token: string; |
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
export interface IOtpRequest{ |
||||
|
mobileNumber: string; |
||||
|
} |
||||
|
|
||||
|
export interface IOtpResponse { |
||||
|
result: string; |
||||
|
otp: string; |
||||
|
error: string; |
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
export interface IGoogleFormData { |
||||
|
customerName: string; |
||||
|
customerPhoneNumber: string; |
||||
|
leadId: string; |
||||
|
leadScore: string; |
||||
|
wasFeedbackHelpful: string; |
||||
|
reasonIfNotHelpful: string; |
||||
|
salesPersonLoginId: string; |
||||
|
} |
@ -0,0 +1,7 @@ |
|||||
|
export default interface IHeaderProps{ |
||||
|
title?: string; |
||||
|
leftIcon?: string; |
||||
|
rightIcon?: string; |
||||
|
leftIconRoute?: string; |
||||
|
rightIconRoute?: string; |
||||
|
} |
@ -0,0 +1,7 @@ |
|||||
|
export interface ILeadScoreResponse{ |
||||
|
id: string; |
||||
|
lead_score: string; |
||||
|
Products?: string; |
||||
|
next_best_action?: string; |
||||
|
third_party_data?: string; |
||||
|
} |
@ -0,0 +1,7 @@ |
|||||
|
export default interface INavigationProps{ |
||||
|
title1?: string; |
||||
|
title2?: string; |
||||
|
title3?: string; |
||||
|
iconHidden?: boolean; |
||||
|
fontType?:string; |
||||
|
} |
@ -0,0 +1,13 @@ |
|||||
|
export default interface User{ |
||||
|
username?: string; |
||||
|
password?: string; |
||||
|
} |
||||
|
|
||||
|
export interface LoginApiResponse{ |
||||
|
ACCESS_TOKEN: string | null, |
||||
|
USER_ID: string, |
||||
|
TOKEN_TYPE: string, |
||||
|
EXPIRES_IN: string, |
||||
|
MESSAGE_CODE: number, |
||||
|
MESSAGE_DESCRIPTION: string |
||||
|
} |
@ -0,0 +1,36 @@ |
|||||
|
<div class="page-container" id="home-page"> |
||||
|
|
||||
|
<div class="header-container"> |
||||
|
<app-header [headerInput]="headerProps"></app-header> |
||||
|
</div> |
||||
|
<main class="main-container"> |
||||
|
|
||||
|
<div class="switch-tab"> |
||||
|
<p [ngClass]="{active: isSalesForm}" (click)="switchSalesServiceTab()">Sales Upload</p> |
||||
|
<p [ngClass]="{active: !isSalesForm}" (click)="switchSalesServiceTab()">Service Upload</p> |
||||
|
</div> |
||||
|
|
||||
|
<section id="from-first-section"> |
||||
|
<form [formGroup]="fileUploadForm" (submit)="submitForm()"> |
||||
|
<div class="input-wrapper"> |
||||
|
<br/> |
||||
|
<input |
||||
|
type="file" |
||||
|
formControlName="fileUpload" |
||||
|
class="user-input font-body-small-bold file-input" |
||||
|
placeholder="Upload sales file" |
||||
|
/> |
||||
|
</div> |
||||
|
|
||||
|
<button |
||||
|
[disabled]="(!fileUploadForm.valid || isLoading)"> |
||||
|
{{isLoading ? 'Sending messages' : 'Submit'}} |
||||
|
</button> |
||||
|
|
||||
|
</form> |
||||
|
</section> |
||||
|
|
||||
|
<p class="error font-body-small">{{error}}</p> |
||||
|
</main> |
||||
|
|
||||
|
</div> |
@ -0,0 +1,69 @@ |
|||||
|
@import '../../../styles.scss'; |
||||
|
|
||||
|
#home-page{ |
||||
|
|
||||
|
.main-container{ |
||||
|
@include flex-box(column, flex-start); |
||||
|
padding: 0%; |
||||
|
|
||||
|
section{ |
||||
|
width: 100%; |
||||
|
padding: 7% 5% 5% 5%; |
||||
|
|
||||
|
label{ |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
.error{ |
||||
|
color: red; |
||||
|
} |
||||
|
|
||||
|
.file-input{ |
||||
|
margin-left: 34%; |
||||
|
} |
||||
|
|
||||
|
form{ |
||||
|
button{ |
||||
|
margin-top: 10%; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.switch-tab{ |
||||
|
margin-top: 10%; |
||||
|
width: 100%; |
||||
|
@include flex-box(row); |
||||
|
p{ |
||||
|
margin-right: 1%; |
||||
|
padding: 5%; |
||||
|
background-color: whitesmoke; |
||||
|
border: 1px solid $clr-blue-light; |
||||
|
&.active{ |
||||
|
background-color: $clr-blue-light; |
||||
|
color: white; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
|
|
||||
|
/* HIDE RADIO */ |
||||
|
[type=radio] { |
||||
|
position: absolute; |
||||
|
opacity: 0; |
||||
|
width: 0; |
||||
|
height: 0; |
||||
|
} |
||||
|
|
||||
|
/* IMAGE STYLES */ |
||||
|
[type=radio] + img { |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
|
||||
|
/* CHECKED STYLES */ |
||||
|
[type=radio]:checked + img { |
||||
|
outline: 2px solid #f00; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,62 @@ |
|||||
|
import { HttpClientModule } from '@angular/common/http'; |
||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing'; |
||||
|
import { ReactiveFormsModule } from '@angular/forms'; |
||||
|
import { of } from 'rxjs'; |
||||
|
import { RouterService } from 'src/app/shared/services/routerService'; |
||||
|
|
||||
|
import { HomeComponent } from './home.component'; |
||||
|
import { HomeService } from './home.service'; |
||||
|
|
||||
|
describe('HomeComponent', () => { |
||||
|
let component: HomeComponent; |
||||
|
let fixture: ComponentFixture<HomeComponent>; |
||||
|
let homeSevice: HomeService; |
||||
|
let homeObj = { |
||||
|
todoList: [ |
||||
|
{ |
||||
|
user: "Nishanth Patil", |
||||
|
quotation: "Send quotation", |
||||
|
bike: "Pulsar 220", |
||||
|
status: "Overdue" |
||||
|
}, |
||||
|
{ |
||||
|
user: "Nishanth Patil", |
||||
|
quotation: "Send quotation", |
||||
|
bike: "Pulsar 220", |
||||
|
status: "Overdue" |
||||
|
} |
||||
|
], |
||||
|
myPerformance: { |
||||
|
sales: "5", |
||||
|
rides: "26", |
||||
|
bookings: "60", |
||||
|
nps: "60" |
||||
|
} |
||||
|
} |
||||
|
beforeEach(async () => { |
||||
|
await TestBed.configureTestingModule({ |
||||
|
declarations: [HomeComponent], imports: [ |
||||
|
ReactiveFormsModule, |
||||
|
HttpClientModule |
||||
|
], |
||||
|
providers: [ |
||||
|
RouterService |
||||
|
] |
||||
|
}) |
||||
|
.compileComponents(); |
||||
|
}); |
||||
|
|
||||
|
beforeEach(() => { |
||||
|
|
||||
|
fixture = TestBed.createComponent(HomeComponent); |
||||
|
component = fixture.componentInstance; |
||||
|
|
||||
|
homeSevice = TestBed.inject(HomeService); |
||||
|
spyOn(homeSevice, 'post').and.returnValue(of(JSON.stringify(homeObj))); |
||||
|
fixture.detectChanges(); |
||||
|
}); |
||||
|
|
||||
|
it('should create', () => { |
||||
|
expect(component).toBeTruthy(); |
||||
|
}); |
||||
|
}); |
@ -0,0 +1,58 @@ |
|||||
|
import { Component, OnInit } from '@angular/core'; |
||||
|
import IHeaderProps from 'src/app/models/header'; |
||||
|
|
||||
|
import { logOutButton, login, home } from 'src/app/constants/constants'; |
||||
|
import { RouterService } from 'src/app/shared/services/routerService'; |
||||
|
import { FormGroup, FormBuilder, Validators } from '@angular/forms'; |
||||
|
import { LeadscoreService } from 'src/app/shared/services/leadscore.service'; |
||||
|
import { first, finalize } from 'rxjs/operators'; |
||||
|
import { IGoogleFormData } from 'src/app/models/googleFormData'; |
||||
|
import { AuthenticationService } from 'src/app/shared/services/authentication.service'; |
||||
|
|
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'app-home', |
||||
|
templateUrl: './home.component.html', |
||||
|
styleUrls: ['./home.component.scss'] |
||||
|
}) |
||||
|
export class HomeComponent { |
||||
|
|
||||
|
headerProps: IHeaderProps = { |
||||
|
rightIcon: logOutButton, |
||||
|
rightIconRoute: 'logout', |
||||
|
title: 'NPS EXPORTS VIEW', |
||||
|
}; |
||||
|
|
||||
|
fileUploadForm: FormGroup; |
||||
|
isLoading = false; |
||||
|
error = ''; |
||||
|
isSalesForm = true; |
||||
|
|
||||
|
|
||||
|
constructor(private routerService: RouterService, |
||||
|
private formBuilder: FormBuilder) { |
||||
|
this.fileUploadForm = this.formBuilder.group( |
||||
|
{ |
||||
|
fileUpload: [ |
||||
|
'', |
||||
|
[ |
||||
|
Validators.required, |
||||
|
Validators.minLength(10), |
||||
|
Validators.pattern('^[0-9]*') |
||||
|
] |
||||
|
] |
||||
|
} |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
get f() { return this.fileUploadForm.controls; } |
||||
|
|
||||
|
switchSalesServiceTab(){ |
||||
|
this.isSalesForm = !this.isSalesForm; |
||||
|
} |
||||
|
|
||||
|
submitForm() { |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,21 @@ |
|||||
|
// Angular imports
|
||||
|
import { Injectable } from '@angular/core'; |
||||
|
import { HttpClient } from '@angular/common/http'; |
||||
|
import { Observable } from 'rxjs'; |
||||
|
// Local imports
|
||||
|
import { IHomeRequest, IHomeResponse } from '../../../app/model/home'; |
||||
|
|
||||
|
@Injectable({ |
||||
|
providedIn: 'root' |
||||
|
}) |
||||
|
export class HomeService { |
||||
|
private baseUrl = 'http://localhost:8000/home'; |
||||
|
|
||||
|
constructor(private http: HttpClient) { |
||||
|
} |
||||
|
|
||||
|
post(data: any): Observable<any> { |
||||
|
return this.http.post<any>(this.baseUrl, data); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,36 @@ |
|||||
|
<div class="page-container" id="login-page"> |
||||
|
|
||||
|
<header> |
||||
|
<img alt="bajaj logo" src="assets/svg/bajaj-logo.svg" /> |
||||
|
<h1 class="font-body-large"> NPS EXPORTS VIEW </h1> |
||||
|
|
||||
|
</header> |
||||
|
|
||||
|
<main class="main-container"> |
||||
|
<form class="login-form" [formGroup]="loginForm" (submit)="loginClickHandler()"> |
||||
|
<input |
||||
|
type="text" |
||||
|
id="username" |
||||
|
formControlName="username" |
||||
|
class="user-input" |
||||
|
placeholder="Username" |
||||
|
value="" |
||||
|
/> |
||||
|
<!-- password input --> |
||||
|
<div class="input-wrapper"> |
||||
|
<span class="input-display-icon" appPassword></span> |
||||
|
<input |
||||
|
type="password" |
||||
|
id="password" |
||||
|
formControlName="password" |
||||
|
class="user-input" |
||||
|
placeholder="Password" |
||||
|
value="" |
||||
|
/> |
||||
|
</div> |
||||
|
<div class="errorMessage" *ngIf="error.length>0">{{error}}</div> |
||||
|
<button [disabled]="loading || !loginForm.valid" >{{ loading ? 'Please wait!' : 'LOGIN' }}</button> |
||||
|
</form> |
||||
|
</main> |
||||
|
|
||||
|
</div> |
@ -0,0 +1,68 @@ |
|||||
|
@import '../../../../styles.scss'; |
||||
|
|
||||
|
#login-page{ |
||||
|
color: $clr-white; |
||||
|
|
||||
|
header{ |
||||
|
@include flex-box(); |
||||
|
height: 60%; |
||||
|
width: 100%; |
||||
|
background-image: url("../../../../assets/svg/login-background.svg"); |
||||
|
background-repeat: no-repeat; |
||||
|
background-size: cover; |
||||
|
|
||||
|
h1{ |
||||
|
margin-top: 5%; |
||||
|
} |
||||
|
|
||||
|
p{ |
||||
|
width: 90%; |
||||
|
margin-top: 3%; |
||||
|
text-align: center; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.main-container{ |
||||
|
@include flex-box(); |
||||
|
width: 100%; |
||||
|
bottom: 2%; |
||||
|
position: absolute; |
||||
|
background-color: $clr-white; |
||||
|
border-radius: 3%; |
||||
|
z-index: 10; |
||||
|
|
||||
|
input{ |
||||
|
margin-bottom: 3%; |
||||
|
} |
||||
|
|
||||
|
.input-display-icon{ |
||||
|
top: 38%; |
||||
|
} |
||||
|
|
||||
|
button{ |
||||
|
margin-top: 4%; |
||||
|
} |
||||
|
|
||||
|
.input-wrapper{ |
||||
|
background-color: $clr-white; |
||||
|
margin-bottom: 3%; |
||||
|
|
||||
|
input{ |
||||
|
margin: 0; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.login-form { |
||||
|
@include flex-box(column, flex-end); |
||||
|
position: relative; |
||||
|
width: 100%; |
||||
|
|
||||
|
.forgot-password{ |
||||
|
@include flex-box(row, flex-end); |
||||
|
width: 100%; |
||||
|
color: $clr-blue; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,61 @@ |
|||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing'; |
||||
|
import { ReactiveFormsModule } from '@angular/forms'; |
||||
|
import { RouterService } from '../../../shared/services/routerService'; |
||||
|
import { LoginComponent } from './login.component'; |
||||
|
import { introductoryPage, login, success } from '../../../constants/constants'; |
||||
|
import { RouterTestingModule } from '@angular/router/testing'; |
||||
|
import { Router } from '@angular/router'; |
||||
|
import { HttpClientModule } from '@angular/common/http'; |
||||
|
import { IntroductoryComponent } from '../introductory/introductory.component'; |
||||
|
import { LoginService } from './login.service'; |
||||
|
import { of } from 'rxjs'; |
||||
|
|
||||
|
describe('LoginComponent', () => { |
||||
|
let component: LoginComponent; |
||||
|
let fixture: ComponentFixture<LoginComponent>; |
||||
|
let router: Router; |
||||
|
let loginService: LoginService; |
||||
|
let loginObj: any = {username:'sales', password:'bajaj'}; |
||||
|
|
||||
|
beforeEach(async () => { |
||||
|
await TestBed.configureTestingModule({ |
||||
|
declarations: [ LoginComponent ], imports: [ |
||||
|
ReactiveFormsModule, |
||||
|
RouterTestingModule.withRoutes([ |
||||
|
{ path: login, component: LoginComponent}, |
||||
|
{ path: introductoryPage, component: IntroductoryComponent} |
||||
|
]), |
||||
|
HttpClientModule |
||||
|
], |
||||
|
providers: [ |
||||
|
RouterService, |
||||
|
LoginService |
||||
|
] |
||||
|
}) |
||||
|
.compileComponents(); |
||||
|
}); |
||||
|
|
||||
|
beforeEach(() => { |
||||
|
fixture = TestBed.createComponent(LoginComponent); |
||||
|
component = fixture.componentInstance; |
||||
|
loginService = TestBed.inject(LoginService); |
||||
|
spyOn(loginService, 'post').and.returnValue(of(loginObj)); |
||||
|
loginService.post(loginObj).subscribe(data => 'success'); |
||||
|
fixture.detectChanges(); |
||||
|
}); |
||||
|
|
||||
|
it('should create', () => { |
||||
|
expect(component).toBeTruthy(); |
||||
|
}); |
||||
|
|
||||
|
it('should call click handler on form submit', ()=>{ |
||||
|
component.loginForm.setValue({ |
||||
|
username: 'bajaj', |
||||
|
password: 'sales' |
||||
|
}); |
||||
|
component.loginClickHandler(); |
||||
|
let userValue = component.username; |
||||
|
expect(userValue).toEqual('bajaj'); |
||||
|
}) |
||||
|
|
||||
|
}); |
@ -0,0 +1,75 @@ |
|||||
|
import { Component, OnInit } from '@angular/core'; |
||||
|
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; |
||||
|
import { home, success, login } from 'src/app/constants/constants'; |
||||
|
import { invalidUsernameAndPassword } from 'src/app/constants/errorConstants'; |
||||
|
import { RouterService } from 'src/app/shared/services/routerService'; |
||||
|
import { LoginService } from './login.service'; |
||||
|
import { ILoginRequest } from '../../../model/login'; |
||||
|
import { AuthenticationService } from 'src/app/shared/services/authentication.service'; |
||||
|
import { first } from 'rxjs/operators'; |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'app-login', |
||||
|
templateUrl: './login.component.html', |
||||
|
styleUrls: ['./login.component.scss'] |
||||
|
}) |
||||
|
export class LoginComponent implements OnInit { |
||||
|
|
||||
|
loginForm: FormGroup; |
||||
|
username = ''; |
||||
|
password = ''; |
||||
|
error = ''; |
||||
|
loading = false; |
||||
|
|
||||
|
constructor(private routerService: RouterService, |
||||
|
private authenticationService: AuthenticationService, |
||||
|
private formBuilder: FormBuilder) { |
||||
|
|
||||
|
// redirect to home if already logged in
|
||||
|
if (localStorage.getItem('loggedInUser')) { |
||||
|
this.routerService.navigate(home); |
||||
|
} |
||||
|
this.loginForm = this.formBuilder.group({ |
||||
|
username: ['', Validators.required], |
||||
|
password: ['', Validators.required] |
||||
|
}) |
||||
|
|
||||
|
this.loginForm.valueChanges.subscribe(() => { |
||||
|
this.error = ''; |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
get f() { return this.loginForm.controls; } |
||||
|
|
||||
|
/** |
||||
|
* Login button click handler |
||||
|
* To navigate to introduction screens for success scenario |
||||
|
* To display error messages incase of failure scenario |
||||
|
*/ |
||||
|
loginClickHandler() { |
||||
|
this.loading = true; |
||||
|
if(this.authenticationService.login(this.f.username.value, this.f.password.value)){ |
||||
|
this.routerService.navigate(home); |
||||
|
} |
||||
|
else { |
||||
|
this.loading = false; |
||||
|
this.error = 'Login failed, Please try again!' |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
inputChangeHandler() { |
||||
|
} |
||||
|
|
||||
|
ngOnInit(): void { |
||||
|
|
||||
|
if (localStorage.getItem('loggedInUser')) { |
||||
|
// logged in so return true
|
||||
|
this.routerService.navigate(home); |
||||
|
} else{ |
||||
|
this.routerService.navigate(login); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,21 @@ |
|||||
|
// Angular imports
|
||||
|
import { Injectable } from '@angular/core'; |
||||
|
import { HttpClient } from '@angular/common/http'; |
||||
|
import { Observable } from 'rxjs'; |
||||
|
// Local imports
|
||||
|
import { ILoginRequest, ILoginResponse } from '../../../model/login'; |
||||
|
|
||||
|
@Injectable({ |
||||
|
providedIn: 'root' |
||||
|
}) |
||||
|
export class LoginService { |
||||
|
private baseUrl = 'http://localhost:8000/login'; |
||||
|
|
||||
|
constructor(private http: HttpClient) { |
||||
|
} |
||||
|
|
||||
|
post(country: ILoginRequest): Observable<ILoginResponse> { |
||||
|
return this.http.post<any>(this.baseUrl, country); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,16 @@ |
|||||
|
<header class="common-header"> |
||||
|
<div class="backButtonClass"> |
||||
|
<span> |
||||
|
<img [src]="getLeftIconPath()" (click)="leftIconClickFunc()"/> |
||||
|
</span> |
||||
|
</div> |
||||
|
<div class="titleClass"> |
||||
|
<h1 class="font-header-medium">{{headerInput.title}}</h1> |
||||
|
</div> |
||||
|
<div> |
||||
|
<span> |
||||
|
<img [src]="getRightIconPath()" (click)="rightIconClickFunc()"/> |
||||
|
</span> |
||||
|
</div> |
||||
|
</header> |
||||
|
|
@ -0,0 +1,9 @@ |
|||||
|
@import '../../../../styles.scss'; |
||||
|
|
||||
|
.common-header { |
||||
|
@include flex-box(row, space-between); |
||||
|
width: 100%; |
||||
|
padding: 4%; |
||||
|
color: $clr-white; |
||||
|
background-image: url('../../../../assets/svg/common-header-background.svg'); |
||||
|
} |
@ -0,0 +1,34 @@ |
|||||
|
import { HttpClientModule } from '@angular/common/http'; |
||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing'; |
||||
|
import { ReactiveFormsModule } from '@angular/forms'; |
||||
|
import { RouterService } from '../../services/routerService'; |
||||
|
|
||||
|
import { HeaderComponent } from './header.component'; |
||||
|
|
||||
|
describe('HeaderComponent', () => { |
||||
|
let component: HeaderComponent; |
||||
|
let fixture: ComponentFixture<HeaderComponent>; |
||||
|
|
||||
|
beforeEach(async () => { |
||||
|
await TestBed.configureTestingModule({ |
||||
|
declarations: [ HeaderComponent ], imports: [ |
||||
|
ReactiveFormsModule, |
||||
|
HttpClientModule |
||||
|
], |
||||
|
providers: [ |
||||
|
RouterService |
||||
|
] |
||||
|
}) |
||||
|
.compileComponents(); |
||||
|
}); |
||||
|
|
||||
|
beforeEach(() => { |
||||
|
fixture = TestBed.createComponent(HeaderComponent); |
||||
|
component = fixture.componentInstance; |
||||
|
fixture.detectChanges(); |
||||
|
}); |
||||
|
|
||||
|
it('should create', () => { |
||||
|
expect(component).toBeTruthy(); |
||||
|
}); |
||||
|
}); |
@ -0,0 +1,68 @@ |
|||||
|
import { Component, Input, OnInit } from '@angular/core'; |
||||
|
import IHeaderProps from 'src/app/models/header'; |
||||
|
import { RouterService } from '../../services/routerService'; |
||||
|
import { AuthenticationService } from '../../services/authentication.service'; |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'app-header', |
||||
|
templateUrl: './header.component.html', |
||||
|
styleUrls: ['./header.component.scss'] |
||||
|
}) |
||||
|
export class HeaderComponent implements OnInit { |
||||
|
|
||||
|
leftIconPath:string = ''; |
||||
|
rightIconPath:string = ''; |
||||
|
initPath: string = ''; |
||||
|
@Input() |
||||
|
headerInput!: IHeaderProps; |
||||
|
|
||||
|
constructor(private routerService:RouterService, |
||||
|
private authenticationService: AuthenticationService) { |
||||
|
} |
||||
|
|
||||
|
ngOnInit(): void { |
||||
|
this.initPath = 'assets/svg/'; |
||||
|
} |
||||
|
|
||||
|
getLeftIconPath():string { |
||||
|
if(this.headerInput.leftIcon === "backButton"){ |
||||
|
this.leftIconPath = this.initPath+'navigation-back-icon.svg'; |
||||
|
} |
||||
|
if(this.headerInput.leftIcon === "closeButton"){ |
||||
|
this.leftIconPath = this.initPath+'close.svg'; |
||||
|
} |
||||
|
if(this.headerInput.leftIcon === "logoButton"){ |
||||
|
this.leftIconPath = this.initPath+'bajaj-logo.svg'; |
||||
|
} |
||||
|
|
||||
|
return this.leftIconPath; |
||||
|
} |
||||
|
|
||||
|
leftIconClickFunc(): void{ |
||||
|
this.headerInput.leftIconRoute |
||||
|
? this.routerService.navigate(this.headerInput.leftIconRoute) |
||||
|
: null; |
||||
|
} |
||||
|
|
||||
|
rightIconClickFunc(): void{ |
||||
|
this.headerInput.rightIconRoute |
||||
|
? this.authenticationService.logout() |
||||
|
: null; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
getRightIconPath():string{ |
||||
|
if(this.headerInput.rightIcon === "logOutButton"){ |
||||
|
this.rightIconPath= this.initPath+'logout.svg'; |
||||
|
} |
||||
|
return this.rightIconPath; |
||||
|
} |
||||
|
|
||||
|
navigateToPreviousScreen(){ |
||||
|
if(this.headerInput.leftIcon === "closeButton"){ |
||||
|
this.routerService.navigate(this.routerService.previousPage); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,22 @@ |
|||||
|
import { Directive, ElementRef, HostListener } from '@angular/core'; |
||||
|
@Directive({ |
||||
|
selector: '[appPassword]' |
||||
|
}) |
||||
|
export class AppPasswordDirective { |
||||
|
private _shown = false; |
||||
|
constructor(private el: ElementRef) { |
||||
|
this.el.nativeElement.style.backgroundImage = "url('/assets/svg/password-enabled-dark.svg')";; |
||||
|
} |
||||
|
@HostListener('click', ['$event.target']) |
||||
|
onClick() { |
||||
|
const parentNode = this.el.nativeElement.parentNode.querySelector('input'); |
||||
|
this._shown = !this._shown; |
||||
|
if (this._shown) { |
||||
|
parentNode.setAttribute('type', 'text'); |
||||
|
this.el.nativeElement.style.backgroundImage = "url('/assets/svg/password-disabled-dark.svg')";; |
||||
|
} else { |
||||
|
parentNode.setAttribute('type', 'password'); |
||||
|
this.el.nativeElement.style.backgroundImage = "url('/assets/svg/password-enabled-dark.svg')";; |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,24 @@ |
|||||
|
import { Injectable } from '@angular/core'; |
||||
|
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; |
||||
|
|
||||
|
import { AuthenticationService } from '../services/authentication.service'; |
||||
|
|
||||
|
@Injectable({ providedIn: 'root' }) |
||||
|
export class AuthGuard implements CanActivate { |
||||
|
constructor( |
||||
|
private router: Router, |
||||
|
private authenticationService: AuthenticationService |
||||
|
) { } |
||||
|
|
||||
|
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { |
||||
|
const currentUser = localStorage.getItem('loggedInUser'); |
||||
|
if (currentUser) { |
||||
|
// logged in so return true
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
// not logged in so redirect to login page with the return url
|
||||
|
this.router.navigate(['/login']); |
||||
|
return false; |
||||
|
} |
||||
|
} |
@ -0,0 +1,79 @@ |
|||||
|
import { Injectable } from '@angular/core'; |
||||
|
import { HttpRequest, HttpResponse, HttpHandler, HttpEvent, HttpInterceptor, HTTP_INTERCEPTORS } from '@angular/common/http'; |
||||
|
import { Observable, of, throwError } from 'rxjs'; |
||||
|
import { delay, mergeMap, materialize, dematerialize } from 'rxjs/operators'; |
||||
|
|
||||
|
import User from '../../models/user'; |
||||
|
|
||||
|
const users: User[] = [{ username: 'test', password: 'test' },{ username: 'Test', password: 'test' },{ username: 'Test', password: 'Test' }]; |
||||
|
|
||||
|
@Injectable() |
||||
|
export class FakeBackendInterceptor implements HttpInterceptor { |
||||
|
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { |
||||
|
const { url, method, headers, body } = request; |
||||
|
|
||||
|
// wrap in delayed observable to simulate server api call
|
||||
|
return of(null) |
||||
|
.pipe(mergeMap(handleRoute)) |
||||
|
.pipe(materialize()) // call materialize and dematerialize to ensure delay even if an error is thrown (https://github.com/Reactive-Extensions/RxJS/issues/648)
|
||||
|
.pipe(delay(500)) |
||||
|
.pipe(dematerialize()); |
||||
|
|
||||
|
function handleRoute() { |
||||
|
switch (true) { |
||||
|
case url.endsWith('/users/authenticate') && method === 'POST': |
||||
|
return authenticate(); |
||||
|
case url.endsWith('/users') && method === 'GET': |
||||
|
return getUsers(); |
||||
|
default: |
||||
|
// pass through any requests not handled above
|
||||
|
return next.handle(request); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// route functions
|
||||
|
|
||||
|
function authenticate() { |
||||
|
const { username, password } = body; |
||||
|
const user = users.find(x => x.username === username && x.password === password); |
||||
|
if (!user) return error('Username or password is incorrect'); |
||||
|
return ok({ |
||||
|
"ACCESS_TOKEN": "fake-jwt-token", |
||||
|
"TOKEN_TYPE": "bearer", |
||||
|
"EXPIRES_IN": "1440", |
||||
|
"MESSAGE_CODE": 1, |
||||
|
"MESSAGE_DESCRIPTION": "SUCCESS" |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
function getUsers() { |
||||
|
if (!isLoggedIn()) return unauthorized(); |
||||
|
return ok(users); |
||||
|
} |
||||
|
|
||||
|
// helper functions
|
||||
|
|
||||
|
function ok(body?: any) { |
||||
|
return of(new HttpResponse({ status: 200, body })) |
||||
|
} |
||||
|
|
||||
|
function error(message: any) { |
||||
|
return throwError({ error: { message } }); |
||||
|
} |
||||
|
|
||||
|
function unauthorized() { |
||||
|
return throwError({ status: 401, error: { message: 'Unauthorised' } }); |
||||
|
} |
||||
|
|
||||
|
function isLoggedIn() { |
||||
|
return headers.get('Authorization') === 'Bearer fake-jwt-token'; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export let fakeBackendProvider = { |
||||
|
// use fake backend in place of Http service for backend-less development
|
||||
|
provide: HTTP_INTERCEPTORS, |
||||
|
useClass: FakeBackendInterceptor, |
||||
|
multi: true |
||||
|
}; |
@ -0,0 +1,3 @@ |
|||||
|
export * from './auth.guard'; |
||||
|
export * from './fake-backend'; |
||||
|
export * from './token.interceptor'; |
@ -0,0 +1,24 @@ |
|||||
|
import { Injectable } from '@angular/core'; |
||||
|
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http'; |
||||
|
import { Observable } from 'rxjs'; |
||||
|
|
||||
|
import { AuthenticationService } from '../services/authentication.service'; |
||||
|
|
||||
|
@Injectable() |
||||
|
export class TokenInterceptor implements HttpInterceptor { |
||||
|
constructor(private authenticationService: AuthenticationService) { } |
||||
|
|
||||
|
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { |
||||
|
// add authorization header with jwt token if available
|
||||
|
// let currentUser = this.authenticationService.currentUserValue;
|
||||
|
// if (currentUser && currentUser.ACCESS_TOKEN) {
|
||||
|
// request = request.clone({
|
||||
|
// setHeaders: {
|
||||
|
// Authorization: `Bearer ${currentUser.ACCESS_TOKEN}`
|
||||
|
// }
|
||||
|
// });
|
||||
|
// }
|
||||
|
|
||||
|
return next.handle(request); |
||||
|
} |
||||
|
} |
@ -0,0 +1,54 @@ |
|||||
|
import { Injectable } from '@angular/core'; |
||||
|
import { HttpClient } from '@angular/common/http'; |
||||
|
import { BehaviorSubject, Observable, from } from 'rxjs'; |
||||
|
import { map } from 'rxjs/operators'; |
||||
|
import {home, login} from '../../constants/constants'; |
||||
|
|
||||
|
import { LoginApiResponse } from '../../models/user'; |
||||
|
import { RouterService } from './routerService'; |
||||
|
|
||||
|
@Injectable({ providedIn: 'root' }) |
||||
|
export class AuthenticationService { |
||||
|
|
||||
|
userList = [ |
||||
|
{username: 'sandeep', password: '12345'}, |
||||
|
{username: 'astik', password: '12345'} |
||||
|
] |
||||
|
|
||||
|
constructor(private routerService: RouterService) { |
||||
|
|
||||
|
} |
||||
|
|
||||
|
login(username: string, password: string) { |
||||
|
// check if user exist in userList Array
|
||||
|
// if yes then save it in the local storage and move
|
||||
|
// it to home/dashboard screen
|
||||
|
// else throw error message.
|
||||
|
|
||||
|
const result = this.userList.find(function(val){ |
||||
|
return val.username === username && val.password === password |
||||
|
}) |
||||
|
|
||||
|
if(result){ |
||||
|
localStorage.setItem('loggedInUser', result.password); |
||||
|
return true; |
||||
|
} else{ |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
logout() { |
||||
|
// remove user from local storage to log user out
|
||||
|
localStorage.removeItem('loggedInUser'); |
||||
|
this.routerService.navigate(login); |
||||
|
} |
||||
|
|
||||
|
isUserLoggedIn(): boolean{ |
||||
|
if(localStorage.getItem('loggedInUser')){ |
||||
|
return true; |
||||
|
} else{ |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,44 @@ |
|||||
|
import {Injectable} from '@angular/core'; |
||||
|
import {HttpClient, HttpHeaders} from '@angular/common/http'; |
||||
|
import {Observable} from 'rxjs'; |
||||
|
|
||||
|
@Injectable({ |
||||
|
providedIn: 'root' |
||||
|
}) |
||||
|
|
||||
|
export class HttpClientService { |
||||
|
url: string = ''; |
||||
|
httpOptions = { |
||||
|
withCredentials: false, |
||||
|
//headers: new HttpHeaders().set('Content-Type', 'application/json').set('responseType', 'json'),
|
||||
|
}; |
||||
|
|
||||
|
post(path: string, payload: any): Observable<any> { |
||||
|
this.url = path; |
||||
|
// return this.http.post(this.url, payload, this.httpOptions);
|
||||
|
return this.http.get(this.url, this.httpOptions); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
postWithOptions(path: string, payload: any, options: any): Observable<any> { |
||||
|
this.url = path; |
||||
|
this.httpOptions = {...this.httpOptions, ...options}; |
||||
|
return this.http.post(this.url, payload, this.httpOptions); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Created this method to get the customization json file using the http |
||||
|
* get method. |
||||
|
* @method get |
||||
|
*/ |
||||
|
get(urlString: string): Observable<any> { |
||||
|
this.url = urlString; |
||||
|
return this.http.get(this.url, this.httpOptions); |
||||
|
} |
||||
|
|
||||
|
constructor( |
||||
|
private http: HttpClient, |
||||
|
) { |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,55 @@ |
|||||
|
import { Injectable } from '@angular/core'; |
||||
|
import { HttpClient } from '@angular/common/http'; |
||||
|
import { map } from 'rxjs/operators'; |
||||
|
|
||||
|
import { LoginApiResponse } from '../../models/user'; |
||||
|
import { RouterService } from './routerService'; |
||||
|
import { IGoogleFormData } from '../../models/googleFormData'; |
||||
|
|
||||
|
@Injectable({ providedIn: 'root' }) |
||||
|
export class LeadscoreService { |
||||
|
constructor(private http: HttpClient) { } |
||||
|
|
||||
|
private apiUrl = 'https://psvapiprd.bajajauto.com/unified'; |
||||
|
|
||||
|
getLeadScore(mobile: string, fullName: string) { |
||||
|
|
||||
|
let reqJson = { |
||||
|
"Main_source": "Sales_Man_App", |
||||
|
"only_cookie_device_id_flag": "Y", |
||||
|
"id": 0, |
||||
|
"fullname": fullName, |
||||
|
"mobile": mobile |
||||
|
} |
||||
|
return this.http.post<any>(this.apiUrl, reqJson).pipe(map((user) => { |
||||
|
return user.unified_stored_procedure[0][0]; |
||||
|
})); |
||||
|
} |
||||
|
|
||||
|
postSalesPersonFeedback(data: IGoogleFormData) { |
||||
|
// let formdata = new FormData();
|
||||
|
// formdata.append("entry.983963658", data.leadId);
|
||||
|
// formdata.append("entry.1410804331", data.leadScore);
|
||||
|
// formdata.append("entry.1812101229", data.wasFeedbackHelpful);
|
||||
|
// formdata.append("entry.1423216644", data.reasonIfNotHelpful);
|
||||
|
// formdata.append("entry.87461451", data.customerName);
|
||||
|
// formdata.append("entry.275790094", data.customerPhoneNumber);
|
||||
|
// formdata.append("entry.556699590", data.salesPersonLoginId);
|
||||
|
|
||||
|
// const googleFormUrl = "https://docs.google.com/forms/u/0/d/e/1FAIpQLSfK8u5H1jBlRFZ7hvzPmrIAF2vUZpu87J0ZF-UpO1IGVBhn5g/formResponse";
|
||||
|
|
||||
|
// return this.http.post<any>(googleFormUrl, formdata).pipe(map((data) => {
|
||||
|
// return data;
|
||||
|
// }));
|
||||
|
const msFromUrl = "https://forms.office.com/formapi/api/87fc9629-a636-4c03-abe9-a76cd0abeb59/users/82f42eb5-6096-49b8-a075-a5a94f79adce/forms('KZb8hzamA0yr6ads0KvrWbUu9IKWYLhJoHWlqU95rc5UQzJRMVpVTFdOV0JUQlBGRzFFQllVVzRDVS4u')/responses"; |
||||
|
|
||||
|
let rawReqData = { |
||||
|
"answers": "[{\"questionId\":\"r210dd05fc62c4653b361757ec7e942a8\",\"answer1\":\"" + data.customerName + "\"},{\"questionId\":\"r6fafaac8422e42f283e191f118a1f11c\",\"answer1\":\"" + data.customerPhoneNumber + "\"},{\"questionId\":\"rd6e56403898842a3907f3cdb53248a0c\",\"answer1\":\"" + data.salesPersonLoginId + "\"},{\"questionId\":\"r7b3a3619a68944868b55cb8aa39046d1\",\"answer1\":\"" + data.leadId + "\"},{\"questionId\":\"rab6dd551df7d43ada03ea596e53e8f68\",\"answer1\":\"" + data.leadScore + "\"},{\"questionId\":\"rc36b37f394b548cdba3289063a3d4db5\",\"answer1\":\"" + data.wasFeedbackHelpful + "\"},{\"questionId\":\"raeb09b241474480a866e41d3025ec5ff\",\"answer1\":\"" + data.reasonIfNotHelpful + "\"}]" |
||||
|
} |
||||
|
|
||||
|
return this.http.post<any>(msFromUrl, rawReqData).pipe(map((data) => { |
||||
|
return data; |
||||
|
})); |
||||
|
|
||||
|
} |
||||
|
} |
@ -0,0 +1,50 @@ |
|||||
|
import { Router, NavigationEnd } from '@angular/router'; |
||||
|
import { Injectable } from '@angular/core'; |
||||
|
import { Subject } from 'rxjs'; |
||||
|
import { filter } from 'rxjs/operators'; |
||||
|
|
||||
|
interface IStateChanges { |
||||
|
previousRoute: string; |
||||
|
currentRoute: string; |
||||
|
} |
||||
|
|
||||
|
@Injectable() |
||||
|
export class RouterService { |
||||
|
|
||||
|
private static previousRoute: string; |
||||
|
private static currentRoute: string; |
||||
|
public previousPage:string; |
||||
|
private _stateChanges: Subject<IStateChanges> = new Subject<IStateChanges>(); |
||||
|
|
||||
|
constructor(private _router: Router) { |
||||
|
this.previousPage = ''; |
||||
|
} |
||||
|
|
||||
|
public navigate(route: string) { |
||||
|
// **
|
||||
|
// Note: replaceUrl is used in future by us to replace the urlParams based on the route
|
||||
|
// **
|
||||
|
this._router.navigateByUrl(route, { replaceUrl: true }); |
||||
|
} |
||||
|
|
||||
|
public navigateRelatively(route: string) { |
||||
|
this._router.navigate([route], { relativeTo: this._router.routerState.root.firstChild }); |
||||
|
} |
||||
|
|
||||
|
public navigateBack() { |
||||
|
window.history.back(); |
||||
|
} |
||||
|
|
||||
|
public get previousRoute() { |
||||
|
return RouterService.previousRoute; |
||||
|
} |
||||
|
|
||||
|
public get currentRoute() { |
||||
|
return RouterService.currentRoute; |
||||
|
} |
||||
|
|
||||
|
public get stateChanges() { |
||||
|
return this._stateChanges.asObservable(); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,29 @@ |
|||||
|
import { FormGroup } from '@angular/forms'; |
||||
|
|
||||
|
export const filterEnquiriesList = (enquiryList:any) => { |
||||
|
let filterObject:any={}; |
||||
|
filterObject.hotFilter = enquiryList.filter((item: any) => { |
||||
|
return item.score > 25; |
||||
|
}); |
||||
|
filterObject.warmFilter = enquiryList.filter((item: any) => { |
||||
|
return (item.score > 20 && item.score < 25) |
||||
|
}); |
||||
|
filterObject.cold = enquiryList.filter((item: any) => { |
||||
|
return (item.score < 20) |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
export function ConfirmedValidator(controlName: string, matchingControlName: string){ |
||||
|
return (formGroup: FormGroup) => { |
||||
|
const control = formGroup.controls[controlName]; |
||||
|
const matchingControl = formGroup.controls[matchingControlName]; |
||||
|
if (matchingControl.errors && !matchingControl.errors.confirmedValidator) { |
||||
|
return; |
||||
|
} |
||||
|
if (control.value !== matchingControl.value) { |
||||
|
matchingControl.setErrors({ confirmedValidator: true }); |
||||
|
} else { |
||||
|
matchingControl.setErrors(null); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,44 @@ |
|||||
|
{ |
||||
|
"enquiriesList": [ |
||||
|
{ |
||||
|
"user": "Ganesh Kumar", |
||||
|
"createdOn": "23 May 2021", |
||||
|
"enquiryId": "10582", |
||||
|
"phone": "+91 99237 12357", |
||||
|
"stage": "Booking", |
||||
|
"score": "26" |
||||
|
}, |
||||
|
{ |
||||
|
"user": "Ram Krishnan Gowda", |
||||
|
"createdOn": "29 May 2021", |
||||
|
"enquiryId": "10809", |
||||
|
"phone": "+91 88817 12888", |
||||
|
"stage": "Booking", |
||||
|
"score": "27" |
||||
|
}, |
||||
|
{ |
||||
|
"user": "Nishant Patel", |
||||
|
"createdOn": "29 May 2021", |
||||
|
"enquiryId": "10809", |
||||
|
"phone": "+91 88817 12888", |
||||
|
"stage": "Booking", |
||||
|
"score": "28" |
||||
|
}, |
||||
|
{ |
||||
|
"user": "Gopal Haragball", |
||||
|
"createdOn": "29 May 2021", |
||||
|
"enquiryId": "10809", |
||||
|
"phone": "+91 88817 12888", |
||||
|
"stage": "Booking", |
||||
|
"score": "29" |
||||
|
}, |
||||
|
{ |
||||
|
"user": "Kiran Savalke", |
||||
|
"createdOn": "29 May 2021", |
||||
|
"enquiryId": "10582", |
||||
|
"phone": "+91 88817 12888", |
||||
|
"stage": "Booking", |
||||
|
"score": "30" |
||||
|
} |
||||
|
] |
||||
|
} |
@ -0,0 +1,4 @@ |
|||||
|
{ |
||||
|
"result": "success", |
||||
|
"error": "An internal server error occured" |
||||
|
} |
@ -0,0 +1,4 @@ |
|||||
|
{ |
||||
|
"messengerId":"8192836451", |
||||
|
"phoneNumber":"393331234567" |
||||
|
} |
@ -0,0 +1,22 @@ |
|||||
|
{ |
||||
|
"todoList": [ |
||||
|
{ |
||||
|
"user": "Nishanth Patil", |
||||
|
"quotation": "Send quotation", |
||||
|
"bike": "Pulsar 220", |
||||
|
"status": "Overdue" |
||||
|
}, |
||||
|
{ |
||||
|
"user": "Nishanth Patil", |
||||
|
"quotation": "Send quotation", |
||||
|
"bike": "Pulsar 220", |
||||
|
"status": "Overdue" |
||||
|
} |
||||
|
], |
||||
|
"myPerformance": { |
||||
|
"sales": "5", |
||||
|
"rides": "26", |
||||
|
"bookings": "60", |
||||
|
"nps": "60" |
||||
|
} |
||||
|
} |
@ -0,0 +1,4 @@ |
|||||
|
{ |
||||
|
"result": "success", |
||||
|
"token": "1234" |
||||
|
} |
@ -0,0 +1,5 @@ |
|||||
|
{ |
||||
|
"result": "success", |
||||
|
"otp": "123456", |
||||
|
"error": "An internal error occured" |
||||
|
} |
@ -0,0 +1,8 @@ |
|||||
|
{ |
||||
|
"id":1, |
||||
|
"firstName":"Jason", |
||||
|
"lastName":"Watmore", |
||||
|
"username":"jason", |
||||
|
"password":"my-super-secret-password", |
||||
|
"token":"123456" |
||||
|
} |
@ -0,0 +1,5 @@ |
|||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> |
||||
|
<circle cx="12" cy="12" r="11" stroke="#14142B" stroke-width="2"/> |
||||
|
<path d="M12 6V18" stroke="#14142B" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> |
||||
|
<path d="M6 12H18" stroke="#14142B" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> |
||||
|
</svg> |
@ -0,0 +1,4 @@ |
|||||
|
<svg width="40" height="41" viewBox="0 0 40 41" fill="none" xmlns="http://www.w3.org/2000/svg"> |
||||
|
<path d="M9.86506 15.1778L5 12.78V6.56126L16.2366 12.0421L19.2495 10.5665C19.447 10.4611 19.5952 10.2767 19.5952 10.0395C19.5952 9.80236 19.447 9.61791 19.2001 9.48616L9.0995 4.58498L18.1134 0.158103C18.3357 0.0527009 18.6074 0 18.879 0C19.1507 0 19.4223 0.0527009 19.6446 0.158103L33.2273 6.79841C33.8693 7.11462 34.6102 7.48352 34.6102 8.37944C34.6102 9.3017 33.9187 9.61791 33.2273 9.96046L22.5834 15.1778L33.2519 20.3952C33.9187 20.7114 34.6349 21.054 34.6349 21.9763C34.6349 22.8985 33.894 23.2411 33.2519 23.5573L19.6693 30.1976C19.447 30.303 19.1754 30.3557 18.9037 30.3557C18.6321 30.3557 18.3604 30.303 18.1381 30.1976L9.0995 25.7707L19.2001 20.8168C19.4223 20.7114 19.5952 20.5006 19.5952 20.2635C19.5952 20.0263 19.447 19.8419 19.2495 19.7365L16.2366 18.2609L5 23.7681V17.5494L9.86506 15.1778Z" fill="white"/> |
||||
|
<path d="M5 40.1516V35.3558H8.92663C9.74159 35.3558 11.0505 35.4612 11.0505 36.6207C11.0505 37.174 10.6059 37.5693 10.0626 37.7274C10.7294 37.9382 11.0505 38.3334 11.0505 38.8868C11.0505 40.0726 9.81567 40.178 8.92663 40.178H5V40.1516ZM6.45705 38.1226L6.87688 37.3848C6.95097 37.2267 7.17323 37.1213 7.3461 37.1213H8.13636H8.95132C9.24767 37.1213 9.46993 36.9896 9.46993 36.7261C9.46993 36.4889 9.24767 36.3308 8.95132 36.3308H6.45705V38.1226ZM6.45705 38.1226V40.1516L6.87688 39.4138C6.95097 39.2557 7.17323 39.1503 7.3461 39.1503H8.92663C9.22298 39.1503 9.46993 38.9131 9.46993 38.6496C9.46993 38.3598 9.24767 38.149 8.92663 38.149H6.45705V38.1226ZM14.5326 36.5153L12.5816 40.178H10.8776L13.5941 35.3822H14.5326H15.471L18.1875 40.178H16.4835L16.039 39.3348H13.4953L13.9152 38.5969C13.9893 38.4388 14.2115 38.3334 14.3844 38.3334H15.471L14.5326 36.5153ZM26.3124 36.5153L24.3615 40.178H22.6575L25.374 35.3822H26.3124H27.2509L29.9674 40.178H28.2634L27.8189 39.3348H25.2999L25.7197 38.5969C25.7938 38.4388 26.0161 38.3334 26.189 38.3334H27.2756L26.3124 36.5153ZM20.7806 39.1503C21.1016 39.1503 21.3733 38.9658 21.3733 38.6233V35.3558H22.8056V38.7814C22.8056 39.8354 22.1636 40.178 21.3486 40.178H18.9531C18.7802 40.178 18.558 40.0726 18.4839 39.9145L18.0641 39.1766H20.7806V39.1503ZM32.5852 39.1503C32.9062 39.1503 33.1779 38.9658 33.1779 38.6233V35.3558H34.6102V38.7814C34.6102 39.8354 33.9681 40.178 33.1532 40.178H30.7577C30.5848 40.178 30.3872 40.0726 30.2885 39.9145L29.8686 39.1766H32.5852V39.1503Z" fill="white"/> |
||||
|
</svg> |
@ -0,0 +1,4 @@ |
|||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> |
||||
|
<path d="M6 6L18.7742 18.7742" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> |
||||
|
<path d="M6 18.7742L18.7742 5.99998" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> |
||||
|
</svg> |
9
src/assets/svg/common-header-background.svg
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,4 @@ |
|||||
|
<svg width="23" height="20" viewBox="0 0 23 20" fill="none" xmlns="http://www.w3.org/2000/svg"> |
||||
|
<path d="M4.25057 13.1069L17.0018 1.48903C17.0264 1.48218 17.0536 1.47496 17.0834 1.46762C17.2611 1.42377 17.5171 1.37818 17.8177 1.3744C18.398 1.36711 19.167 1.51163 19.9198 2.19751C20.6726 2.88338 20.8312 3.58407 20.8232 4.11279C20.8191 4.38663 20.769 4.61992 20.7209 4.78181C20.7128 4.80891 20.7049 4.83372 20.6974 4.8561L7.94613 16.4739L3.74663 16.9331L4.25057 13.1069Z" stroke="#006AD0" stroke-width="2" stroke-linecap="round"/> |
||||
|
<path d="M13.927 2.94336L18.8546 7.43293" stroke="#006AD0" stroke-width="2"/> |
||||
|
</svg> |
@ -0,0 +1,13 @@ |
|||||
|
<svg width="56" height="56" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg"> |
||||
|
<rect x="0.75" y="0.75" width="38.5" height="38.5" rx="19.25" stroke="#006AD0" stroke-width="1.5"/> |
||||
|
<mask id="mask0" mask-type="alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="40" height="40"> |
||||
|
<rect width="40" height="40" rx="20" fill="#4F26C4"/> |
||||
|
</mask> |
||||
|
<g mask="url(#mask0)"> |
||||
|
<rect x="-16.646" y="29.6084" width="55.5147" height="41.8617" transform="rotate(-45 -16.646 29.6084)" fill="#006AD0"/> |
||||
|
</g> |
||||
|
<path d="M10 10.25L16.3871 17.1694" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> |
||||
|
<path d="M10 17.1689L16.3871 10.2496" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> |
||||
|
<line x1="35.7071" y1="5.70711" x2="5.70711" y2="35.7071" stroke="white" stroke-width="2"/> |
||||
|
<path d="M21.3333 28.1826L24.6331 31.4824L31.2327 24.8828" stroke="white" stroke-width="2" stroke-linecap="round"/> |
||||
|
</svg> |
@ -0,0 +1,4 @@ |
|||||
|
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> |
||||
|
<path d="M1.11246 11.0467C0.740267 10.3984 0.740265 9.60163 1.11245 8.95337C3.07078 5.54246 6.20313 3.33331 9.73314 3.33331C13.2631 3.33331 16.3955 5.54243 18.3538 8.9533C18.726 9.60155 18.726 10.3984 18.3538 11.0466C16.3955 14.4575 13.2631 16.6667 9.73311 16.6667C6.20312 16.6667 3.07079 14.4576 1.11246 11.0467Z" stroke="#006AD0" stroke-width="1.3"/> |
||||
|
<ellipse cx="9.73309" cy="10" rx="2.5" ry="2.5" stroke="#006AD0" stroke-width="1.3"/> |
||||
|
</svg> |
17
src/assets/svg/login-background.svg
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,4 @@ |
|||||
|
<svg width="100%" height="100%" viewBox="0 0 40 41" fill="none" xmlns="http://www.w3.org/2000/svg"> |
||||
|
<path d="M9.86506 15.1778L5 12.78V6.56126L16.2366 12.0421L19.2495 10.5665C19.447 10.4611 19.5952 10.2767 19.5952 10.0395C19.5952 9.80236 19.447 9.61791 19.2001 9.48616L9.0995 4.58498L18.1134 0.158103C18.3357 0.0527009 18.6074 0 18.879 0C19.1507 0 19.4223 0.0527009 19.6446 0.158103L33.2273 6.79841C33.8693 7.11462 34.6102 7.48352 34.6102 8.37944C34.6102 9.3017 33.9187 9.61791 33.2273 9.96046L22.5834 15.1778L33.2519 20.3952C33.9187 20.7114 34.6349 21.054 34.6349 21.9763C34.6349 22.8985 33.894 23.2411 33.2519 23.5573L19.6693 30.1976C19.447 30.303 19.1754 30.3557 18.9037 30.3557C18.6321 30.3557 18.3604 30.303 18.1381 30.1976L9.0995 25.7707L19.2001 20.8168C19.4223 20.7114 19.5952 20.5006 19.5952 20.2635C19.5952 20.0263 19.447 19.8419 19.2495 19.7365L16.2366 18.2609L5 23.7681V17.5494L9.86506 15.1778Z" fill="#0052A1"/> |
||||
|
<path d="M5 40.1516V35.3558H8.92663C9.74159 35.3558 11.0505 35.4612 11.0505 36.6206C11.0505 37.174 10.6059 37.5692 10.0626 37.7273C10.7294 37.9381 11.0505 38.3334 11.0505 38.8868C11.0505 40.0725 9.81567 40.1779 8.92663 40.1779H5V40.1516ZM6.45705 38.1226L6.87688 37.3848C6.95097 37.2267 7.17323 37.1213 7.3461 37.1213H8.13636H8.95132C9.24767 37.1213 9.46993 36.9895 9.46993 36.726C9.46993 36.4889 9.24767 36.3308 8.95132 36.3308H6.45705V38.1226ZM6.45705 38.1226V40.1516L6.87688 39.4138C6.95097 39.2557 7.17323 39.1503 7.3461 39.1503H8.92663C9.22298 39.1503 9.46993 38.9131 9.46993 38.6496C9.46993 38.3597 9.24767 38.1489 8.92663 38.1489H6.45705V38.1226ZM14.5326 36.5152L12.5816 40.1779H10.8776L13.5941 35.3821H14.5326H15.471L18.1875 40.1779H16.4835L16.039 39.3347H13.4953L13.9152 38.5969C13.9893 38.4388 14.2115 38.3334 14.3844 38.3334H15.471L14.5326 36.5152ZM26.3124 36.5152L24.3615 40.1779H22.6575L25.374 35.3821H26.3124H27.2509L29.9674 40.1779H28.2634L27.8189 39.3347H25.2999L25.7197 38.5969C25.7938 38.4388 26.0161 38.3334 26.189 38.3334H27.2756L26.3124 36.5152ZM20.7806 39.1503C21.1016 39.1503 21.3733 38.9658 21.3733 38.6232V35.3558H22.8056V38.7814C22.8056 39.8354 22.1636 40.1779 21.3486 40.1779H18.9531C18.7802 40.1779 18.558 40.0725 18.4839 39.9144L18.0641 39.1766H20.7806V39.1503ZM32.5852 39.1503C32.9062 39.1503 33.1779 38.9658 33.1779 38.6232V35.3558H34.6102V38.7814C34.6102 39.8354 33.9681 40.1779 33.1532 40.1779H30.7577C30.5848 40.1779 30.3872 40.0725 30.2885 39.9144L29.8686 39.1766H32.5852V39.1503Z" fill="#0052A1"/> |
||||
|
</svg> |
@ -0,0 +1 @@ |
|||||
|
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#FFFFFF"><g><path d="M0,0h24v24H0V0z" fill="none"/></g><g><path d="M17,8l-1.41,1.41L17.17,11H9v2h8.17l-1.58,1.58L17,16l4-4L17,8z M5,5h7V3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h7v-2H5V5z"/></g></svg> |
@ -0,0 +1,3 @@ |
|||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> |
||||
|
<path d="M14.9634 5L8.00021 11.9632L14.9634 18.9263" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> |
||||
|
</svg> |
@ -0,0 +1,3 @@ |
|||||
|
<svg width="26" height="23" viewBox="0 0 26 23" fill="none" xmlns="http://www.w3.org/2000/svg"> |
||||
|
<path d="M20.3333 8.01449C20.3333 6.15413 19.5607 4.36997 18.1855 3.0545C16.8102 1.73902 14.9449 1 13 1C11.0551 1 9.18982 1.73902 7.81455 3.0545C6.43928 4.36997 5.66667 6.15413 5.66667 8.01449C5.66667 13.9484 3.21304 16.809 1.86406 17.9333C1.6615 18.1021 1.79337 18.5362 2.05706 18.5362H8.52214C8.6391 18.5362 8.74073 18.6154 8.77521 18.7271C8.99911 19.4529 9.99866 22 13 22C16.0013 22 17.0009 19.4529 17.2248 18.7271C17.2593 18.6154 17.3609 18.5362 17.4779 18.5362H23.9429C24.2066 18.5362 24.3385 18.1021 24.1359 17.9333C22.787 16.809 20.3333 13.9484 20.3333 8.01449Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> |
||||
|
</svg> |
@ -0,0 +1,5 @@ |
|||||
|
<svg width="21" height="20" viewBox="0 0 21 20" fill="none" xmlns="http://www.w3.org/2000/svg"> |
||||
|
<path d="M2.11264 11.0464C1.74045 10.3981 1.74045 9.60132 2.11263 8.95307C4.07096 5.54215 7.20331 3.33301 10.7333 3.33301C14.2633 3.33301 17.3956 5.54212 19.354 8.95299C19.7262 9.60125 19.7262 10.3981 19.354 11.0463C17.3957 14.4572 14.2633 16.6664 10.7333 16.6664C7.20331 16.6664 4.07097 14.4573 2.11264 11.0464Z" stroke="#444444" stroke-width="2"/> |
||||
|
<ellipse cx="10.7329" cy="10" rx="2.5" ry="2.5" stroke="#444444" stroke-width="2"/> |
||||
|
<line x1="17.3412" y1="17.335" x2="2.34123" y2="2.33504" stroke="#444444" stroke-width="2"/> |
||||
|
</svg> |
@ -0,0 +1,4 @@ |
|||||
|
<svg width="21" height="20" viewBox="0 0 21 20" fill="none" xmlns="http://www.w3.org/2000/svg"> |
||||
|
<path d="M2.11264 11.0464C1.74045 10.3981 1.74045 9.60132 2.11263 8.95307C4.07096 5.54215 7.20331 3.33301 10.7333 3.33301C14.2633 3.33301 17.3956 5.54212 19.354 8.95299C19.7262 9.60125 19.7262 10.3981 19.354 11.0463C17.3957 14.4572 14.2633 16.6664 10.7333 16.6664C7.20331 16.6664 4.07097 14.4573 2.11264 11.0464Z" stroke="#444444" stroke-width="2"/> |
||||
|
<ellipse cx="10.7329" cy="10" rx="2.5" ry="2.5" stroke="#444444" stroke-width="2"/> |
||||
|
</svg> |
@ -0,0 +1,3 @@ |
|||||
|
<svg width="34" height="34" viewBox="0 0 34 34" fill="none" xmlns="http://www.w3.org/2000/svg"> |
||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.6814 10.4075L15.7296 2.20629C16.2493 1.15347 17.7506 1.15347 18.2703 2.20629L22.3185 10.4075L31.3715 11.7307C32.5331 11.9005 32.996 13.3283 32.1551 14.1473L25.6056 20.5266L27.1513 29.5389C27.3498 30.6962 26.1349 31.5787 25.0956 31.0322L17 26.7748L8.90437 31.0322C7.86506 31.5787 6.6502 30.6962 6.8487 29.5389L8.3944 20.5266L1.84485 14.1473C1.00393 13.3283 1.46687 11.9005 2.62842 11.7307L11.6814 10.4075Z" fill="#006AD0"/> |
||||
|
</svg> |
@ -0,0 +1,3 @@ |
|||||
|
<svg width="34" height="34" viewBox="0 0 34 34" fill="none" xmlns="http://www.w3.org/2000/svg"> |
||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.8928 12.3287C13.6866 12.7464 13.2883 13.0361 12.8274 13.1034L5.87689 14.1193L10.9051 19.0168C11.2392 19.3423 11.3918 19.8114 11.3129 20.2711L10.1266 27.1882L16.3406 23.9203C16.7534 23.7032 17.2466 23.7032 17.6594 23.9203L23.8734 27.1882L22.687 20.2711C22.6082 19.8114 22.7607 19.3423 23.0948 19.0168L28.1231 14.1193L21.1726 13.1034C20.7117 13.0361 20.3133 12.7464 20.1071 12.3287L17 6.03394L13.8928 12.3287ZM11.6814 10.4075L15.7296 2.20629C16.2493 1.15347 17.7506 1.15347 18.2703 2.20629L22.3185 10.4075L31.3715 11.7307C32.5331 11.9005 32.996 13.3283 32.1551 14.1473L25.6056 20.5266L27.1513 29.5389C27.3498 30.6962 26.1349 31.5787 25.0956 31.0322L17 26.7748L8.90437 31.0322C7.86506 31.5787 6.6502 30.6962 6.8487 29.5389L8.3944 20.5266L1.84485 14.1473C1.00393 13.3283 1.46687 11.9005 2.62842 11.7307L11.6814 10.4075Z" fill="#888888"/> |
||||
|
</svg> |
@ -0,0 +1,3 @@ |
|||||
|
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"> |
||||
|
<path d="M3.99999 17.9035C3.99999 18.9511 4.84999 19.8082 5.88888 19.8082H15.6733L14.4267 25.8654L14.3889 26.3035C14.3889 26.8939 14.6344 27.4273 15.0122 27.8273L16.5044 29.332L25.8355 19.9225C26.3455 19.4082 26.6667 18.6844 26.6667 17.9035V5.52251C26.6667 3.94155 25.4011 2.66536 23.8333 2.66536H11.0833C9.91221 2.66536 8.9111 3.38917 8.47666 4.3987L4.20777 14.4749C4.07555 14.7987 3.99999 15.1606 3.99999 15.5225V17.9035ZM7.77777 15.7511L11.7067 6.47489H22.8889V17.5035L19.2433 21.1796L20.32 15.9987H7.77777V15.7511Z" fill="#C92A1C"/> |
||||
|
</svg> |
@ -0,0 +1,3 @@ |
|||||
|
<svg width="23" height="28" viewBox="0 0 23 28" fill="none" xmlns="http://www.w3.org/2000/svg"> |
||||
|
<path d="M23 12.0965C23 11.0489 22.15 10.1918 21.1111 10.1918H11.3266L12.5733 4.13464L12.6111 3.69654C12.6111 3.10606 12.3655 2.57273 11.9878 2.17273L10.4955 0.667969L1.16442 10.0775C0.654424 10.5918 0.333313 11.3156 0.333313 12.0965V24.4775C0.333313 26.0584 1.59887 27.3346 3.16665 27.3346H15.9166C17.0878 27.3346 18.0889 26.6108 18.5233 25.6013L22.7922 15.5251C22.9244 15.2013 23 14.8394 23 14.4775V12.0965ZM19.2222 14.2489L15.2933 23.5251H4.11109V12.4965L7.75665 8.82035L6.67998 14.0013H19.2222V14.2489Z" fill="#48C426"/> |
||||
|
</svg> |
@ -0,0 +1,4 @@ |
|||||
|
export const environment = { |
||||
|
production: false, |
||||
|
mockApi: true |
||||
|
}; |
@ -0,0 +1,22 @@ |
|||||
|
import 'jest-preset-angular'; |
||||
|
|
||||
|
/* global mocks for jsdom */ |
||||
|
const mock = () => { |
||||
|
let storage: { [key: string]: string } = {}; |
||||
|
return { |
||||
|
getItem: (key: string) => (key in storage ? storage[key] : null), |
||||
|
setItem: (key: string, value: string) => (storage[key] = value || ''), |
||||
|
removeItem: (key: string) => delete storage[key], |
||||
|
clear: () => (storage = {}) |
||||
|
}; |
||||
|
}; |
||||
|
|
||||
|
Object.defineProperty(window, 'localStorage', { value: mock() }); |
||||
|
Object.defineProperty(window, 'sessionStorage', { value: mock() }); |
||||
|
Object.defineProperty(window, 'location', { value: mock() }); |
||||
|
Object.defineProperty(window, 'getComputedStyle', { |
||||
|
value: () => ['-webkit-appearance'], |
||||
|
}); |
||||
|
|
||||
|
/* output shorter and more meaningful Zone error stack traces */ |
||||
|
// Error.stackTraceLimit = 2;
|
@ -1 +1,5 @@ |
|||||
/* You can add global styles to this file, and also import other style files */ |
|
||||
|
@import "styles/variables/index"; |
||||
|
@import "styles/css-reset"; |
||||
|
@import "styles/form-inputs"; |
||||
|
@import "styles/fonts"; |
||||
|
@import "styles/common"; |
@ -0,0 +1,136 @@ |
|||||
|
body{ |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
} |
||||
|
|
||||
|
*{ |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
|
||||
|
.header-container{ |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
width: 100%; |
||||
|
top: 0; |
||||
|
position: relative; |
||||
|
} |
||||
|
|
||||
|
.container{ |
||||
|
background-color: $clr-white-dark; |
||||
|
max-height: 60%; |
||||
|
width: 100%; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
overflow-y: auto; |
||||
|
} |
||||
|
|
||||
|
.page-container { |
||||
|
height: 100%; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
} |
||||
|
|
||||
|
.main-container{ |
||||
|
background: #F7F7F7; |
||||
|
padding: 3.5%; |
||||
|
flex: 1; |
||||
|
overflow: auto; |
||||
|
} |
||||
|
|
||||
|
form, label{ |
||||
|
width: 100%; |
||||
|
} |
||||
|
|
||||
|
label{ |
||||
|
padding: 0 0 2% 1%; |
||||
|
color: #181818; |
||||
|
} |
||||
|
|
||||
|
.card-flex-row { |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
box-sizing: border-box; |
||||
|
padding: 3.5%; |
||||
|
background: $clr-white; |
||||
|
width: 100%; |
||||
|
} |
||||
|
|
||||
|
.card-flex-column { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
box-sizing: border-box; |
||||
|
padding: 3.5%; |
||||
|
background: $clr-white; |
||||
|
width: 100%; |
||||
|
} |
||||
|
|
||||
|
.two-coloumn-grid{ |
||||
|
display: grid; |
||||
|
width: 100%; |
||||
|
grid-template-columns: 1fr 1fr; |
||||
|
margin-bottom: 3%; |
||||
|
} |
||||
|
|
||||
|
.no-padding{ |
||||
|
padding: 0; |
||||
|
} |
||||
|
|
||||
|
.small-margin-bottom{ |
||||
|
margin-bottom: 5%; |
||||
|
} |
||||
|
|
||||
|
.round-borders{ |
||||
|
border-radius: 0O.7em; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
.space-between { |
||||
|
justify-content: space-between; |
||||
|
} |
||||
|
|
||||
|
.action-button-icons{ |
||||
|
height: 24px; |
||||
|
width: 24px; |
||||
|
} |
||||
|
|
||||
|
/* Common components */ |
||||
|
.card-row{ |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.seperator{ |
||||
|
border-top: 1px solid $clr-grey-border; |
||||
|
width: 100%; |
||||
|
margin: 5%; |
||||
|
} |
||||
|
|
||||
|
.bg-container{ |
||||
|
background-color: $clr-grey; |
||||
|
} |
||||
|
|
||||
|
.title-space{ |
||||
|
padding-bottom: 20px; |
||||
|
} |
||||
|
|
||||
|
.hot-status{ |
||||
|
background-color: $clr-red; |
||||
|
color: $clr-white; |
||||
|
padding:2%; |
||||
|
border-radius: 5px; |
||||
|
} |
||||
|
|
||||
|
.flex-row{ |
||||
|
flex-direction: row; |
||||
|
display: flex; |
||||
|
} |
||||
|
|
||||
|
.errorMessage{ |
||||
|
color: $clr-red; |
||||
|
} |
@ -0,0 +1,15 @@ |
|||||
|
html,body, app-root{ |
||||
|
font-family: Trade Gothic LT Com Bold; |
||||
|
background-color: $clr-white; |
||||
|
margin: 0; |
||||
|
padding: 0; |
||||
|
height: 100%; |
||||
|
} |
||||
|
|
||||
|
ul, li, a, p, h1, h2, h3, h4, h5{ |
||||
|
text-decoration: none; |
||||
|
list-style: none; |
||||
|
margin: 0; |
||||
|
padding: 0; |
||||
|
font-weight: normal; |
||||
|
} |
@ -0,0 +1,141 @@ |
|||||
|
// adding font family |
||||
|
@font-face { |
||||
|
font-family: "Trade Gothic LT Com"; |
||||
|
src: url("../assets/fonts/TradeGothicLTCom-Cn18.ttf") format("truetype"); |
||||
|
} |
||||
|
@font-face { |
||||
|
font-family: "Trade Gothic LT Com Bold"; |
||||
|
src: url(/assets/fonts/TradeGothicLTCom-Bold.ttf) format("truetype"); |
||||
|
} |
||||
|
@font-face { |
||||
|
font-family: "Blender Pro"; |
||||
|
src: url("../assets/fonts/Blender-Bold.otf") format("truetype"); |
||||
|
} |
||||
|
@font-face { |
||||
|
font-family: "Blender Pro Bold"; |
||||
|
src: url("../assets/fonts/BlenderPro-Heavy.otf") format("truetype"); |
||||
|
} |
||||
|
|
||||
|
@font-face { |
||||
|
font-family: "Proxima Nova"; |
||||
|
src: url("../assets/fonts/ProximaNova-Reg_0.otf") format("truetype"); |
||||
|
} |
||||
|
|
||||
|
@font-face { |
||||
|
font-family: "Proxima Nova Bold"; |
||||
|
src: url("../assets/fonts/ProximaNova-Bold_0.otf") format("truetype"); |
||||
|
} |
||||
|
|
||||
|
// below 4 classes will be used for headings |
||||
|
@mixin font-header-common{ |
||||
|
letter-spacing: 1px; |
||||
|
font-family: Blender Pro Bold; |
||||
|
text-transform: uppercase; |
||||
|
} |
||||
|
|
||||
|
@mixin font-body-common($isBold: false){ |
||||
|
@if $isBold { |
||||
|
font-family: Proxima Nova Bold; |
||||
|
letter-spacing: 0.5px; |
||||
|
} @else{ |
||||
|
font-family: Proxima Nova; |
||||
|
letter-spacing: 0.3px; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
.font-header-xlarge{ |
||||
|
font-size: 3rem; |
||||
|
line-height: 3.125rem; |
||||
|
@include font-header-common; |
||||
|
} |
||||
|
|
||||
|
.font-header-large{ |
||||
|
font-size: 1.875rem; |
||||
|
line-height: 2rem; |
||||
|
@include font-header-common; |
||||
|
} |
||||
|
|
||||
|
.font-header-medium{ |
||||
|
font-size: 1.25rem; |
||||
|
line-height: 1.5rem; |
||||
|
@include font-header-common; |
||||
|
} |
||||
|
|
||||
|
.font-header-small{ |
||||
|
font-size: 1rem; |
||||
|
line-height: 1.125rem; |
||||
|
@include font-header-common; |
||||
|
} |
||||
|
|
||||
|
// below 4 fonts will be used for body |
||||
|
// Bold fonts |
||||
|
|
||||
|
.font-body-large-bold{ |
||||
|
font-size: 1.25rem; |
||||
|
line-height: 1.625rem; |
||||
|
@include font-body-common(true); |
||||
|
} |
||||
|
|
||||
|
.font-body-medium-bold{ |
||||
|
font-size: 1rem; |
||||
|
line-height: 1.375rem; |
||||
|
@include font-body-common(true); |
||||
|
} |
||||
|
|
||||
|
.font-body-small-bold{ |
||||
|
font-size: 0.875rem; |
||||
|
line-height: 1rem; |
||||
|
letter-spacing: 0.75px; |
||||
|
@include font-body-common(true); |
||||
|
} |
||||
|
|
||||
|
.font-body-xsmall-bold{ |
||||
|
font-size: 0.812rem; |
||||
|
line-height: 1.125rem; |
||||
|
@include font-body-common(true); |
||||
|
} |
||||
|
|
||||
|
.text-grey-label{ |
||||
|
color: $clr-grey-label; |
||||
|
font-size: 1.25rem; |
||||
|
@include font-body-common(true); |
||||
|
} |
||||
|
|
||||
|
// below 4 fonts will be used for body |
||||
|
// Regular fonts |
||||
|
|
||||
|
.font-body-large{ |
||||
|
font-size: 1.25rem; |
||||
|
line-height: 1.625rem; |
||||
|
@include font-body-common; |
||||
|
} |
||||
|
|
||||
|
.font-body-medium{ |
||||
|
font-size: 1rem; |
||||
|
line-height: 1.375rem; |
||||
|
@include font-body-common; |
||||
|
} |
||||
|
|
||||
|
.font-body-small{ |
||||
|
font-size: 0.875rem; |
||||
|
line-height: 1rem; |
||||
|
@include font-body-common; |
||||
|
} |
||||
|
|
||||
|
.font-body-xsmall{ |
||||
|
font-size: 0.813rem; |
||||
|
line-height: 1.125rem; |
||||
|
@include font-body-common; |
||||
|
} |
||||
|
|
||||
|
.text-black{ |
||||
|
color: $clr-black; |
||||
|
@include font-body-common; |
||||
|
} |
||||
|
|
||||
|
.text-grey-noresults{ |
||||
|
color: $clr-grey-noresults; |
||||
|
text-align: center; |
||||
|
@include font-body-common; |
||||
|
} |
@ -0,0 +1,135 @@ |
|||||
|
input.ng-invalid.ng-touched{ |
||||
|
border: 1px solid $clr-red; |
||||
|
} |
||||
|
|
||||
|
.input-errors{ |
||||
|
position: relative; |
||||
|
top: -2%; |
||||
|
color: $clr-red; |
||||
|
} |
||||
|
|
||||
|
input[type="text"],input[type="number"], input[type="password"], textarea, select { |
||||
|
font-family: Trade Gothic LT Com Bold; |
||||
|
height: 50px; |
||||
|
width: 100%; |
||||
|
color: $clr-grey-medium; |
||||
|
background: $clr-white; |
||||
|
border: 1px solid $clr-grey-border; |
||||
|
border-radius: 5px; |
||||
|
font-size: 0.87rem; |
||||
|
line-height: 50px; |
||||
|
letter-spacing: 0.75px; |
||||
|
padding: 0 3%; |
||||
|
appearance: none; |
||||
|
|
||||
|
.search{ |
||||
|
background: $clr-grey; |
||||
|
border: none; |
||||
|
border-radius: 5px; |
||||
|
} |
||||
|
|
||||
|
&::placeholder{ |
||||
|
color: $clr-grey-light-dark; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
//radio button |
||||
|
input[type="radio"] { |
||||
|
height: 20px; |
||||
|
width: 20px; |
||||
|
background: $clr-grey; |
||||
|
border: 1px solid #E0E0E0; |
||||
|
} |
||||
|
|
||||
|
// checkbox |
||||
|
|
||||
|
input[type="checkbox"] { |
||||
|
width: 22px; |
||||
|
height: 22px; |
||||
|
&::before{ |
||||
|
content: ""; |
||||
|
display: inline-block; |
||||
|
width: 18px; |
||||
|
height: 18px; |
||||
|
border-radius: 20%; |
||||
|
border: 2px solid $clr-blue; |
||||
|
flex-shrink: 0; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.input-wrapper { |
||||
|
@include flex-box(); |
||||
|
position: relative; |
||||
|
width: 100%; |
||||
|
margin-bottom: 6%; |
||||
|
|
||||
|
.input-display-icon { |
||||
|
right: 3%; |
||||
|
top: 55%; |
||||
|
height: 30px; |
||||
|
min-width: 30px; |
||||
|
max-width: auto; |
||||
|
position: absolute; |
||||
|
cursor: pointer; |
||||
|
color: $clr-blue; |
||||
|
background-repeat: no-repeat; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.otp-wrapper{ |
||||
|
@include flex-box(row, space-between); |
||||
|
width: 100%; |
||||
|
|
||||
|
input{ |
||||
|
height: 50px; |
||||
|
width: 40px; |
||||
|
text-align: center; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
button { |
||||
|
background: $clr-blue-gradient; |
||||
|
border-radius: 10px; |
||||
|
border: 1px solid $clr-blue-light; |
||||
|
height: 50px; |
||||
|
width: 100%; |
||||
|
font-size: 1rem; |
||||
|
line-height: 50px; |
||||
|
letter-spacing: 1px; |
||||
|
color: $clr-white; |
||||
|
font-weight: bold; |
||||
|
font-family: Blender Pro Bold; |
||||
|
|
||||
|
&.modify-state{ |
||||
|
background: $clr-white; |
||||
|
border: 1px solid $clr-blue; |
||||
|
color: $clr-blue; |
||||
|
} |
||||
|
|
||||
|
&:disabled{ |
||||
|
background: $clr-grey-button-disable; |
||||
|
border: none; |
||||
|
color: $clr-black-light; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.search-box .input-wrapper{ |
||||
|
width: 80%; |
||||
|
} |
||||
|
|
||||
|
:focus-visible{ |
||||
|
outline: none; |
||||
|
} |
||||
|
|
||||
|
//radio buttons |
||||
|
.form-radio{ |
||||
|
background: $clr-grey; |
||||
|
justify-content: space-between; |
||||
|
display: flex; |
||||
|
} |
||||
|
|
||||
|
//texthe-area |
||||
|
textarea{ |
||||
|
height:83px; |
||||
|
} |
@ -0,0 +1,32 @@ |
|||||
|
// grey shade |
||||
|
$clr-grey-light: #888888; |
||||
|
$clr-grey: #F7F7F7; |
||||
|
$clr-grey-light-dark: #A0A0A0; |
||||
|
$clr-grey-border: #E0E0E0; |
||||
|
$clr-grey-medium:#444444; |
||||
|
$clr-grey-label:#181818; |
||||
|
$clr-grey-lite-border:#212121; |
||||
|
$clr-grey-noresults: #5D5D5D; |
||||
|
$clr-grey-button-disable: #CECECE; |
||||
|
// blue shade |
||||
|
$clr-blue:#006AD0; |
||||
|
$clr-blue-light:#009CDE; |
||||
|
$clr-blue-dark:#003087; |
||||
|
$clr-blue-gradient: linear-gradient(178.84deg, #009CDE 0.07%, #003087 95.33%); |
||||
|
|
||||
|
// black shade |
||||
|
$clr-black:#181818; |
||||
|
$clr-black-light:#5D5D5D; |
||||
|
|
||||
|
// white shade |
||||
|
$clr-white:#FFFFFF; |
||||
|
$clr-white-dark:#F7F7F7; |
||||
|
|
||||
|
// yellow shades |
||||
|
$clr-yellow:#FF9C23; |
||||
|
|
||||
|
// red shades |
||||
|
$clr-red: #C92A1C; |
||||
|
|
||||
|
// green shades |
||||
|
$clr-green-light: #48C426; |
@ -0,0 +1,3 @@ |
|||||
|
@import 'mixins'; |
||||
|
@import 'colors'; |
||||
|
@import 'rest'; |
@ -0,0 +1,11 @@ |
|||||
|
// flex card mixins goes here |
||||
|
|
||||
|
@mixin flex-box($direction: column, |
||||
|
$justify-content: center, |
||||
|
$align-items: center |
||||
|
) { |
||||
|
display: flex; |
||||
|
flex-direction: $direction; |
||||
|
justify-content: $justify-content; |
||||
|
align-items: $align-items; |
||||
|
} |
@ -0,0 +1,5 @@ |
|||||
|
$txt-small:0.8rem; |
||||
|
$txt-medium-title: 1.25rem; |
||||
|
|
||||
|
$margin-small:10px; |
||||
|
$margin-none:0px; |
Some files were not shown because too many files changed in this diff
Write
Preview
Loading…
Cancel
Save
Reference in new issue