dev #14607 Море. Правки по сайту: change interface and api

This commit is contained in:
nikolay 2023-06-29 11:53:38 +04:00
parent 06f668cd3d
commit 0abdb264f5
12 changed files with 422 additions and 395 deletions

View File

@ -1,4 +1 @@
<img src="/assets/logo-light-theme.png" alt="Логотип">
<h3>Горячая линия</h3>
<a class="phone-number" href="tel:88003334130">8 (800) 333-41-30</a>
<app-social-media-buttons></app-social-media-buttons>

View File

@ -9,11 +9,7 @@
&:hover {
background-color: var(--main-color_hover);
}
.title {
color: var(--text-color);
}
.icon {
}

View File

@ -7,7 +7,7 @@
<div *ngIf="showDropdown" class="backdrop" (click)="closeMenu()"></div>
<div *ngIf="showMenu" class="menu">
<button mat-button (click)="toggleMenu()">
<span class="material-icons" style="color: white !important">
<span class="material-icons" style="color: var(--background-color)">
more_horiz
</span>
</button>
@ -15,7 +15,7 @@
<div class="menu__dropdown" *ngIf="showDropdown">
<ul>
<menu-item [handler]="handler(aboutApp)">
<span class="material-icons icon" style="color: var(--main-color)">
<span class="material-icons icon" style="color: var(--background-color)">
info
</span>
<span class="item_title">О приложении</span>
@ -40,7 +40,9 @@
(click)="messagingService.requestPermission()"
class="notification"
>
<img src="./assets/notification.svg" alt="notification" />
<span class="material-icons">
notifications
</span>
</button>
<button mat-stroked-button appDownloadApp>Установить</button>
</div>

View File

@ -1,9 +1,9 @@
:host {
width: 100%;
.notification {
.notification {
img {
width: 28px;
width: 28px;
height: 28px;
}
}
@ -60,7 +60,7 @@
box-shadow: 0px 2px 5px -3px black;
.item_title {
color: var(--text-color);
color: var(--background-color);
font-size: 14px;
font-style: normal;
}

View File

@ -39,7 +39,7 @@ export class NavbarComponent implements OnInit {
ngOnInit(): void {
const deviceType = getTypeDevice();
this.showMenu = deviceType === DeviceType.ios;
this.showMenu = deviceType !== DeviceType.ios;
}
toggleMenu() {

View File

@ -1,77 +1,39 @@
<app-navbar title="Карта гостя" [backEvent]="showBack ? logout : undefined"></app-navbar>
<ng-container *ngIf="!authService.loading && authService.userInfo">
<div class="guest-card">
<div class="top-info">
<div class="top-info__level">
<p id="level">Уровень {{ authService.userInfo.customer_level }}</p>
<p id="level-percent">Кэшбек {{ authService.currentLvlPeriod.percent }}%</p>
</div>
<p class="top-info__bonus">
<ng-container *ngIf="!isNegativeBalance">
{{ Math.floor(authService.getBalanceAmount($any(authService.userInfo.walletBalances))) }}
бонусов
</ng-container>
<ng-container *ngIf="isNegativeBalance">
Ошибка! Отрицательный баланс бонусов
</ng-container>
</p>
<div *ngIf="authService.userInfo?.name" class="owner">
<span>Владелец карты</span>
<span class="name">{{authService.userInfo.name}}</span>
</div>
<div class="bonuses">
<span>Бонусы</span>
<span>{{authService.getBalanceAmount($any(authService.userInfo?.walletBalances))}}</span>
</div>
<div class="guest-card__qr" (click)="qrCodeClick()">
<qr-code
[value]="authService.userInfo?.phone?.substr(1) || 'Данные не найдены'"
[margin]="0"
[size]="qrCodeSize"
errorCorrectionLevel="H"
></qr-code>
</div>
<div class="guest-card__user-description">
<p>
<ng-container *ngIf="authService.currentLvlPeriod.end">
Осталось купить на сумму
<span class="price">{{
authService.currentLvlPeriod.end -
(authService.userInfo.OrdersSum) +
1
}}</span>
рублей, тогда кэшбек будет
<span class="percent"
>{{ authService.getNextLevel().percent }}%</span
>
с
{{
authService.purchaseData.currentPeriod[1]
.locale("ru")
.format("D MMMM")
}}
</ng-container>
<ng-container *ngIf="!authService.currentLvlPeriod.end">
У Вас последний уровень бонусной программы. Процент начисляемых
бонусов:
{{ authService.currentLvlPeriod.percent }}%
</ng-container>
</p>
</div>
<span id="bonuses-condition"></span>
<app-last-order
[lastOrder]="authService.purchaseData.lastPurchase"
[loading]="authService.loading"
></app-last-order>
<a class="guest-card__loyalty-program" routerLink="loyality-program"
>Подробнее о правилах <br />
Программы лояльности</a
>
[value]="authService.userInfo?.phone?.substr(1) || 'Данные не найдены'"
[margin]="0"
[size]="qrCodeSize"
darkColor="#000000FF"
lightColor="#FFFFFFFF"
errorCorrectionLevel="H"
></qr-code>
<span class="qr-value">{{authService.userInfo?.phone}}</span>
</div>
</div>
<app-footer></app-footer>
</ng-container>
<ng-container *ngIf="!authService.loading && !authService.userInfo">
<div class="not-found">
<p>Данные недоступны, попробуйте позже</p>
</div>
</ng-container>
<ng-container *ngIf="authService.loading">
<ng-container
*ngTemplateOutlet="spinner; context: { $implicit: 85 }"
></ng-container>
<div class="spinner-container">
<ng-container
*ngTemplateOutlet="spinner; context: { $implicit: 85 }"
></ng-container>
</div>
</ng-container>
<ng-template #spinner let-diameter>

View File

@ -1,217 +1,268 @@
:host {
.guest-card {
display: flex;
flex-direction: column;
align-items: center;
max-width: 600px;
margin: 0 auto;
// .guest-card {
// display: flex;
// flex-direction: column;
// align-items: center;
// max-width: 600px;
// margin: 0 auto;
.top-info {
padding: 8px 0 0;
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
// .top-info {
// padding: 8px 0 0;
// width: 100%;
// display: flex;
// flex-direction: column;
// align-items: center;
&__level {
width: 100%;
// &__level {
// width: 100%;
display: flex;
align-items: center;
justify-content: space-around;
// display: flex;
// align-items: center;
// justify-content: space-around;
font-size: 16px;
}
// font-size: 16px;
// }
& p {
color: var(--button-color);
}
// & p {
// color: var(--button-color);
// }
p.top-info__bonus {
font-size: 20px;
}
}
// p.top-info__bonus {
// font-size: 20px;
// }
// }
&__qr {
margin: 10px;
padding: 5px;
width: fit-content;
// background-image: linear-gradient(
// #008251 33%,
// transparent 0px,
// transparent 67%,
// #008251 0px
// ),
// linear-gradient(
// 90deg,
// #008251 33%,
// transparent 0px,
// transparent 66%,
// #008251 0px
// ),
// linear-gradient(#008251 33%, transparent 0px, transparent 67%, #008251 0),
// linear-gradient(90deg, #008251 33%, transparent 0, transparent 66%, #008251 0);
// background-size: 3px 100%, 100% 3px, 3px 100%, 100% 3px;
// background-position: 0 0, 0 0, 100% 100%, 100% 100%;
// background-repeat: no-repeat, no-repeat, no-repeat, no-repeat;
cursor: pointer;
}
// &__qr {
// margin: 10px;
// padding: 5px;
// width: fit-content;
// // background-image: linear-gradient(
// // #008251 33%,
// // transparent 0px,
// // transparent 67%,
// // #008251 0px
// // ),
// // linear-gradient(
// // 90deg,
// // #008251 33%,
// // transparent 0px,
// // transparent 66%,
// // #008251 0px
// // ),
// // linear-gradient(#008251 33%, transparent 0px, transparent 67%, #008251 0),
// // linear-gradient(90deg, #008251 33%, transparent 0, transparent 66%, #008251 0);
// // background-size: 3px 100%, 100% 3px, 3px 100%, 100% 3px;
// // background-position: 0 0, 0 0, 100% 100%, 100% 100%;
// // background-repeat: no-repeat, no-repeat, no-repeat, no-repeat;
// cursor: pointer;
// }
&__user-description {
padding: 14px 24px;
// &__user-description {
// padding: 14px 24px;
p {
width: 60%;
text-align: center;
margin: 0 auto;
font-style: normal;
font-weight: 400;
font-size: 16px;
line-height: 19px;
letter-spacing: -0.5px;
}
// p {
// width: 60%;
// text-align: center;
// margin: 0 auto;
// font-style: normal;
// font-weight: 400;
// font-size: 16px;
// line-height: 19px;
// letter-spacing: -0.5px;
// }
.price,
.percent {
font-weight: bold;
}
}
// .price,
// .percent {
// font-weight: bold;
// }
// }
&__purchases-description {
margin: 0;
padding: 14px 24px;
width: 100%;
text-align: center;
font-style: normal;
font-weight: 400;
font-size: 16px;
line-height: 19px;
letter-spacing: -0.5px;
grid-template-columns: calc(100% - 24px) 24px;
// &__purchases-description {
// margin: 0;
// padding: 14px 24px;
// width: 100%;
// text-align: center;
// font-style: normal;
// font-weight: 400;
// font-size: 16px;
// line-height: 19px;
// letter-spacing: -0.5px;
// grid-template-columns: calc(100% - 24px) 24px;
span {
color: #219653;
}
}
// span {
// color: #219653;
// }
// }
&__level-info {
padding-top: 36px;
padding-left: 36px;
padding-right: 36px;
display: flex;
flex-direction: column;
align-items: center;
// &__level-info {
// padding-top: 36px;
// padding-left: 36px;
// padding-right: 36px;
// display: flex;
// flex-direction: column;
// align-items: center;
h2 {
font-style: normal;
font-weight: 700;
font-size: 17px;
line-height: 22px;
text-align: center;
letter-spacing: -0.408px;
}
// h2 {
// font-style: normal;
// font-weight: 700;
// font-size: 17px;
// line-height: 22px;
// text-align: center;
// letter-spacing: -0.408px;
// }
input[type="range"] {
-webkit-appearance: none;
width: 100%;
height: 6px;
border-radius: 5px;
display: block;
position: relative;
background: #231f20;
box-shadow: 0px 0px 3px #f2c94c59;
background-image: linear-gradient(#f2c94c, #f2c94c);
background-size: 70% 100%;
background-repeat: no-repeat;
// input[type="range"] {
// -webkit-appearance: none;
// width: 100%;
// height: 6px;
// border-radius: 5px;
// display: block;
// position: relative;
// background: #231f20;
// box-shadow: 0px 0px 3px #f2c94c59;
// background-image: linear-gradient(#f2c94c, #f2c94c);
// background-size: 70% 100%;
// background-repeat: no-repeat;
&::before,
&::after {
content: " ";
display: block;
width: 16px;
height: 16px;
border-radius: 100%;
position: absolute;
top: -5px;
}
// &::before,
// &::after {
// content: " ";
// display: block;
// width: 16px;
// height: 16px;
// border-radius: 100%;
// position: absolute;
// top: -5px;
// }
&::before {
background-color: #f2c94c;
left: 0px;
}
// &::before {
// background-color: #f2c94c;
// left: 0px;
// }
&::after {
background-color: #f2c94c;
right: 0px;
}
// &::after {
// background-color: #f2c94c;
// right: 0px;
// }
&::-webkit-slider-thumb {
-webkit-appearance: none;
background: #f2c94c;
width: 16px;
height: 16px;
border-radius: 100%;
}
// &::-webkit-slider-thumb {
// -webkit-appearance: none;
// background: #f2c94c;
// width: 16px;
// height: 16px;
// border-radius: 100%;
// }
&::-ms-thumb {
-webkit-appearance: none;
height: 20px;
width: 20px;
border-radius: 50%;
background: #f2c94c;
cursor: ew-resize;
box-shadow: 0 0 2px 0 #555;
transition: background 0.3s ease-in-out;
}
// &::-ms-thumb {
// -webkit-appearance: none;
// height: 20px;
// width: 20px;
// border-radius: 50%;
// background: #f2c94c;
// cursor: ew-resize;
// box-shadow: 0 0 2px 0 #555;
// transition: background 0.3s ease-in-out;
// }
&::-moz-range-thumb {
-webkit-appearance: none;
height: 20px;
width: 20px;
border-radius: 50%;
background: #f2c94c;
cursor: ew-resize;
box-shadow: 0 0 2px 0 #555;
transition: background 0.3s ease-in-out;
}
}
}
// &::-moz-range-thumb {
// -webkit-appearance: none;
// height: 20px;
// width: 20px;
// border-radius: 50%;
// background: #f2c94c;
// cursor: ew-resize;
// box-shadow: 0 0 2px 0 #555;
// transition: background 0.3s ease-in-out;
// }
// }
// }
&__download-app {
width: 100%;
position: relative;
margin-top: 32px;
display: flex;
justify-content: flex-end;
img {
width: 100%;
max-width: calc(100% - 16px);
}
}
// &__download-app {
// width: 100%;
// position: relative;
// margin-top: 32px;
// display: flex;
// justify-content: flex-end;
// img {
// width: 100%;
// max-width: calc(100% - 16px);
// }
// }
&__loyalty-program {
text-align: center;
color: var(--button-color);
font-style: normal;
font-weight: bold;
font-size: 12px;
line-height: 16px;
text-decoration: none;
margin: 17px 0 0;
}
}
// &__loyalty-program {
// text-align: center;
// color: var(--button-color);
// font-style: normal;
// font-weight: bold;
// font-size: 12px;
// line-height: 16px;
// text-decoration: none;
// margin: 17px 0 0;
// }
// }
.wrapper {
padding-top: 20px;
}
// .wrapper {
// padding-top: 20px;
// }
.not-found {
.not-found {
display: flex;
width: 100%;
height: 100%;
justify-content: center;
align-items: center;
}
}
.guest-card {
max-width: 600px;
margin: 0 auto;
margin-top: 20px;
display: flex;
flex-direction: column;
gap: 20px;
span {
color: var(--text-color);
font-style: italic;
}
.owner {
display: flex;
flex-direction: column;
span {
font-size: 12px;
}
span.name {
font-size: 16px;
}
}
.bonuses {
display: flex;
justify-content: space-between;
align-items: center;
span {
font-size: 18px;
}
}
.guest-card__qr {
margin: 0 auto;
margin-top: 100px;
width: fit-content;
padding: 8px;
border-radius: 6px;
background: #ffffff;
display: flex;
flex-direction: column;
align-items: center;
cursor: pointer;
.qr-value {
color: var(--background-color);
}
}
}
.spinner-container {
margin-top: 40px;
}
}
app-accordion {

View File

@ -3,102 +3,98 @@
[title]="phoneForm.value.phone"
[backEvent]="backToPhoneForm"
[ngStyle]="{
position: 'absolute',
top: 0
}"
></app-navbar>
<h1>Участвуй в программе лояльности COFFEE LIKE</h1>
<p class="description">Начни получать бонусы прямо сейчас</p>
<form
*ngIf="isShowNumber; else smsCode"
(ngSubmit)="submitNumber()"
[formGroup]="phoneForm"
>
<!-- <div class="input-container"> -->
<mat-form-field appearance="outline">
<mat-label>Ваше имя</mat-label>
<input formControlName="name" matInput type="text" />
</mat-form-field>
<!-- </div> -->
<div class="input-container">
<!-- <label for="number">Номер телефона</label>
<input id="number" type="text" placeholder="Введите номер" /> -->
<mat-form-field appearance="outline">
<mat-label>Номер телефона</mat-label>
<ngx-mat-intl-tel-input
formControlName="phone"
[enablePlaceholder]="true"
[enableSearch]="false"
[onlyCountries]="['ru', 'kg', 'by', 'kz', 'fi', 'de']"
[preferredCountries]="['ru']"
name="phone"
#phone
>
</ngx-mat-intl-tel-input>
</mat-form-field>
</div>
<p class="offer">
Используя приложение, вы принимаете <a href="https://docs.google.com/document/d/1tOZyI9DKerQpMY_N-hMExMB15j2F98E3VDqwIVMkk4I">условия</a>
и соглашаетесь на получение рекламно-информационных сообщений
</p>
<button>Принять участие</button>
</form>
<ng-template #smsCode>
<h2>Введите код из SMS</h2>
<form class="code-form" [formGroup]="codeForm" (ngSubmit)="submitCode()">
<div class="inputs-container">
<label class="box"
><input
class="field"
id="field"
type="tel"
placeholder="•"
#field
formControlName="code"
maxlength="1"
/></label>
<label class="box"
><input
class="field"
id="field1"
type="tel"
placeholder="•"
#field1
formControlName="code1"
maxlength="1"
/></label>
<label class="box"
><input
class="field"
id="field2"
type="tel"
placeholder="•"
#field2
formControlName="code2"
maxlength="1"
/></label>
<label class="box"
><input
class="field"
id="field3"
type="tel"
placeholder="•"
#field3
formControlName="code3"
maxlength="1"
/></label>
position: 'absolute',
top: 0
}"
></app-navbar>
<div class="wrapper" *ngIf="isShowNumber; else smsCode">
<form
(ngSubmit)="submitNumber()"
[formGroup]="phoneForm"
>
<!-- <div class="input-container"> -->
<mat-form-field appearance="outline">
<mat-label>Ваше имя</mat-label>
<input formControlName="name" matInput type="text" />
</mat-form-field>
<!-- </div> -->
<div class="input-container">
<!-- <label for="number">Номер телефона</label>
<input id="number" type="text" placeholder="Введите номер" /> -->
<mat-form-field appearance="outline">
<mat-label>Номер телефона</mat-label>
<ngx-mat-intl-tel-input
formControlName="phone"
[enablePlaceholder]="true"
[enableSearch]="false"
[onlyCountries]="['ru', 'kg', 'by', 'kz', 'fi', 'de']"
[preferredCountries]="['ru']"
name="phone"
#phone
>
</ngx-mat-intl-tel-input>
</mat-form-field>
</div>
<button>Войти</button>
<button>Принять участие</button>
</form>
<p class="resend-code">
Не пришло SMS?<br />
<ng-container *ngIf="authService.timeLeft">
Отправим повторно через {{authService.timeLeft}}с
</ng-container>
<ng-container *ngIf="!authService.timeLeft">
<span class="resend" (click)="submitNumber()">Отправить повторно</span>
</ng-container>
</p>
</div>
<ng-template #smsCode>
<div class="wrapper">
<h2>Введите код из SMS</h2>
<form class="code-form" [formGroup]="codeForm" (ngSubmit)="submitCode()">
<div class="inputs-container">
<label class="box"
><input
class="field"
id="field"
type="tel"
placeholder="•"
#field
formControlName="code"
maxlength="1"
/></label>
<label class="box"
><input
class="field"
id="field1"
type="tel"
placeholder="•"
#field1
formControlName="code1"
maxlength="1"
/></label>
<label class="box"
><input
class="field"
id="field2"
type="tel"
placeholder="•"
#field2
formControlName="code2"
maxlength="1"
/></label>
<label class="box"
><input
class="field"
id="field3"
type="tel"
placeholder="•"
#field3
formControlName="code3"
maxlength="1"
/></label>
</div>
<button>Войти</button>
</form>
<p class="resend-code">
Не пришло SMS?<br />
<ng-container *ngIf="authService.timeLeft">
Отправим повторно через {{authService.timeLeft}}с
</ng-container>
<ng-container *ngIf="!authService.timeLeft">
<span class="resend" (click)="submitNumber()">Отправить повторно</span>
</ng-container>
</p>
</div>
</ng-template>
<app-footer></app-footer>

View File

@ -1,13 +1,19 @@
:host {
padding-top: 48px;
display: flex;
flex-direction: column;
align-items: center;
max-width: 600px;
margin: 0 auto 52px;
display: flex;
flex-direction: column;
align-items: center;
padding-left: 20px;
padding-right: 20px;
color: var(--text-color);
.wrapper {
max-width: 600px;
width: 100%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
h1 {
margin-top: 20px;
width: 302px;
@ -41,7 +47,8 @@
}
form {
display: flex;
display: flex;
width: 100%;
flex-direction: column;
align-items: center;
margin-top: 35px;

View File

@ -27,12 +27,12 @@ export class LoginComponent implements OnInit {
code2: new FormControl('', [Validators.required]),
code3: new FormControl('', [Validators.required]),
});
private inputIds = ['field', 'field1', 'field2', 'field3'];
private inputIds = ['field', 'field1', 'field2', 'field3'];
constructor(
public authService: AuthService,
private router: Router,
private messageService: MessageService,
private messageService: MessageService,
) { }
ngOnInit(): void { }
@ -104,12 +104,12 @@ export class LoginComponent implements OnInit {
if (this.phoneForm.invalid) {
this.phoneForm.markAsTouched();
this.messageService.clear();
this.messageService.add({
this.messageService.clear();
this.messageService.add({
severity: 'error',
summary: 'Введите имя и телефон',
summary: 'Введите имя и телефон',
});
return;
}
const data = this.phoneForm.value;
@ -125,7 +125,7 @@ export class LoginComponent implements OnInit {
const phoneData = this.phoneForm.value;
this.authService.submitCode(
Object.values(data).join(''), phoneData.phone!, phoneData.name!);
Object.values(data).join(''), phoneData.phone!, phoneData.name!);
}
backToPhoneForm = () => {

View File

@ -90,8 +90,6 @@ export class AuthService {
this.userInfo = value.customer_info;
this.cookiesService.setCookie('phone-number', this.userInfo!.phone?.slice(2));
this.getLastPurchase();
}
},
error: (e) => {

View File

@ -2,21 +2,21 @@
@include mat.core();
$primary: (
50 : #f0e4ec,
100 : #d9bcd0,
200 : #bf90b0,
300 : #a56390,
400 : #924179,
500 : #7f2061,
600 : #771c59,
700 : #6c184f,
800 : #621345,
900 : #4f0b33,
A100 : #ff85c7,
A200 : #ff52b0,
A400 : #ff1f99,
A700 : #ff068d,
$accent: (
50 : #e0e0e0,
100 : #b3b3b3,
200 : #808080,
300 : #4d4d4d,
400 : #262626,
500 : #000000,
600 : #000000,
700 : #000000,
800 : #000000,
900 : #000000,
A100 : #a6a6a6,
A200 : #8c8c8c,
A400 : #737373,
A700 : #666666,
contrast: (
50 : #000000,
100 : #000000,
@ -35,7 +35,7 @@ $primary: (
)
);
$accent: (
$primary: (
50 : #ffffff,
100 : #ffffff,
200 : #ffffff,
@ -111,24 +111,34 @@ body {
}
:root {
--main-color: #7F2061;
--main-color: #000000;
--main-border-radius: 35px;
--background-color: #ffffff;
--background-color: #000000;
--text-color: #222222;
--text-color_1: #666666;
--text-color: #ffffff;
--text-color_1: #aaaaaa;
--button-color: #7F2061;
--button-color_disabled: #4a0d37;
--button-color: #ffffff;
--button-color_disabled: #aaaaaa;
--button-text-color: #ffffff;
--button-text-color: #000000;
--button-text-color_disabled: #cccccc;
--main-color_hover: rgba(127, 32, 97, 0.3);
}
.mdc-button__label {
color: var(--button-text-color) !important;
color: var(--background-color) !important;
}
.mdc-text-field--outlined:not(.mdc-text-field--disabled, .mdc-text-field--invalid) .mdc-notched-outline__leading,
.mdc-text-field--outlined:not(.mdc-text-field--disabled, .mdc-text-field--invalid) .mdc-notched-outline__notch,
.mdc-text-field--outlined:not(.mdc-text-field--disabled, .mdc-text-field--invalid) .mdc-notched-outline__trailing {
border-color: var(--text-color_1);
}
.mdc-text-field--outlined:not(.mdc-text-field--disabled, .mdc-text-field--invalid) .mdc-notched-outline__leading {
}
.mat-mdc-outlined-button:not(:disabled) {
@ -151,6 +161,14 @@ body {
font-family: Montserrat, sans-serif;
}
.mdc-text-field:not(.mdc-text-field--disabled, .mdc-text-field--invalid) .mdc-floating-label {
color: var(--text-color_1);
}
.mdc-text-field:not(.mdc-text-field--disabled) .mdc-text-field__input {
color: var(--text-color);
}
hr {
width: 100%;
border-top: 1px solid #BDBDBD;