Merge remote-tracking branch 'remotes/origin/coffee-like' into coffee-like-test
This commit is contained in:
commit
e062f05f36
@ -5,8 +5,8 @@
|
||||
gap: 20px;
|
||||
padding-bottom: 100px;
|
||||
h3 {
|
||||
margin: 0;
|
||||
font-family: Montserrat;
|
||||
margin: 0;
|
||||
font-family: Montserrat;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-size: 15px;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
:host {
|
||||
padding: 16px;
|
||||
h2 {
|
||||
font-family: Montserrat;
|
||||
padding: 16px;
|
||||
h2 {
|
||||
font-family: Montserrat;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-size: 17px;
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
padding: 24px 16px 0px;
|
||||
|
||||
& > h2 {
|
||||
font-family: Montserrat;
|
||||
font-family: Montserrat;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-size: 15px;
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
padding-bottom: 100px;
|
||||
h3 {
|
||||
margin: 0;
|
||||
font-family: Montserrat;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-size: 15px;
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
:host {
|
||||
padding: 16px;
|
||||
padding: 16px;
|
||||
h2 {
|
||||
font-family: Montserrat;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-size: 17px;
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
:host {
|
||||
padding: 24px 16px 56px;
|
||||
padding: 24px 16px 0px;
|
||||
|
||||
& > h2 {
|
||||
font-family: Montserrat;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-size: 15px;
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
visibility: hidden;
|
||||
}
|
||||
.title {
|
||||
font-family: "Gotham Pro", sans-serif;
|
||||
font-family: "Montserrat", sans-serif;
|
||||
font-weight: 700;
|
||||
font-size: 17px;
|
||||
line-height: 22px;
|
||||
|
||||
@ -4,6 +4,7 @@ import { IndexComponent } from './components/index/index.component';
|
||||
import { GuestCardComponent } from './pages/guest-card/guest-card.component';
|
||||
import { AuthGuard } from 'src/app/guards/auth-guard.guard';
|
||||
import { LoginComponent } from './pages/login/login.component';
|
||||
import { LoyalityProgramComponent } from './pages/loyality-program/loyality-program.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
@ -15,6 +16,10 @@ const routes: Routes = [
|
||||
path: 'login',
|
||||
component: LoginComponent
|
||||
},
|
||||
{
|
||||
path: 'loyality-program',
|
||||
component: LoyalityProgramComponent,
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
||||
@ -18,6 +18,7 @@ import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { NgxMatIntlTelInputComponent } from 'ngx-mat-intl-tel-input';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { DirectivesModule } from 'src/app/directives/directives.module';
|
||||
import { LoyalityProgramComponent } from './pages/loyality-program/loyality-program.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@ -29,7 +30,8 @@ import { DirectivesModule } from 'src/app/directives/directives.module';
|
||||
AccordionComponent,
|
||||
LastOrderComponent,
|
||||
InviteFriendsComponent,
|
||||
LoginComponent
|
||||
LoginComponent,
|
||||
LoyalityProgramComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
|
||||
@ -1,197 +1,104 @@
|
||||
<app-navbar title="Карта гостя" (backEvent)="logout()"></app-navbar>
|
||||
|
||||
<div class="guest-card">
|
||||
<div class="guest-card__qr" (click)="qrCodeClick()">
|
||||
<ng-container *ngIf="customerInfo || cookiesService.getItem('phone-number')">
|
||||
<qr-code
|
||||
[value]="cookiesService.getItem('phone-number') || customerInfo?.phone.substr(2) || 'Данные не найдены'"
|
||||
[margin]="0"
|
||||
[size]="qrCodeSize"
|
||||
errorCorrectionLevel="M"
|
||||
></qr-code>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="!cookiesService.getItem('phone-number') && !customerInfo">
|
||||
<ng-container
|
||||
*ngTemplateOutlet="spinner; context: { $implicit: 85 }"
|
||||
></ng-container>
|
||||
</ng-container>
|
||||
</div>
|
||||
<div class="guest-card__user-description">
|
||||
Текущий баланс бонусов:
|
||||
<span *ngIf="customerInfo">
|
||||
{{ loyaltyProgram.getBalanceAmount(customerInfo?.walletBalances) }}
|
||||
бонусов</span
|
||||
<ng-container *ngIf="!this.loyaltyProgram.purchaseData.$loading">
|
||||
<div class="guest-card">
|
||||
<div class="top-info">
|
||||
<div class="top-info__level">
|
||||
<p id="level">Уровень {{ loyaltyProgram.currentLvl }}</p>
|
||||
<p id="level-percent">Кэшбек {{ loyaltyProgram.currentLvlPeriod.percent }}%</p>
|
||||
</div>
|
||||
<p class="top-info__bonus">
|
||||
{{ loyaltyProgram.getBalanceAmount(customerInfo?.walletBalances) }}
|
||||
бонусов
|
||||
</p>
|
||||
</div>
|
||||
<div class="guest-card__qr" (click)="qrCodeClick()">
|
||||
<ng-container *ngIf="customerInfo">
|
||||
<qr-code
|
||||
[value]="customerInfo?.phone.substr(2) || 'Данные не найдены'"
|
||||
[margin]="0"
|
||||
[size]="qrCodeSize"
|
||||
errorCorrectionLevel="M"
|
||||
></qr-code>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="!customerInfo">
|
||||
<ng-container
|
||||
*ngTemplateOutlet="spinner; context: { $implicit: 85 }"
|
||||
></ng-container>
|
||||
</ng-container>
|
||||
</div>
|
||||
<div class="guest-card__user-description">
|
||||
<p>
|
||||
<ng-container *ngIf="loyaltyProgram.currentLvlPeriod.end">
|
||||
Осталось купить на сумму
|
||||
<span class="price">{{
|
||||
loyaltyProgram.currentLvlPeriod.end -
|
||||
(loyaltyProgram.purchaseData.currentAmount || 0) +
|
||||
1
|
||||
}}</span>
|
||||
рублей, тогда кэшбек будет
|
||||
<span class="percent"
|
||||
>{{ loyaltyProgram.getNextLevel().percent }}%</span
|
||||
>
|
||||
с
|
||||
{{
|
||||
loyaltyProgram.purchaseData.currentPeriod[1]
|
||||
.locale("ru")
|
||||
.format("D MMMM")
|
||||
}}
|
||||
</ng-container>
|
||||
<ng-container *ngIf="!loyaltyProgram.currentLvlPeriod.end">
|
||||
У Вас последний уровень бонусной программы. Процент начисляемых
|
||||
бонусов:
|
||||
{{ loyaltyProgram.currentLvlPeriod.percent }}%
|
||||
</ng-container>
|
||||
</p>
|
||||
</div>
|
||||
<span id="bonuses-condition"></span>
|
||||
|
||||
<!-- <div class="guest-card__level-info"> -->
|
||||
<!-- <ng-container *ngIf="!purchaseData.$loading"> -->
|
||||
<!-- <ng-container *ngIf="currentLvlPeriod.end"> -->
|
||||
<!-- <\!-- <input -\-> -->
|
||||
<!-- <\!-- type="range" -\-> -->
|
||||
<!-- <\!-- [value]="purchaseData.currentAmount" -\-> -->
|
||||
<!-- <\!-- [min]="currentLvlPeriod.start" -\-> -->
|
||||
<!-- <\!-- [max]="currentLvlPeriod.end" -\-> -->
|
||||
<!-- <\!-- [step]="0.01" -\-> -->
|
||||
<!-- <\!-- disabled="true" -\-> -->
|
||||
<!-- <\!-- [ngStyle]="{ -\-> -->
|
||||
<!-- <\!-- 'background-size': ((purchaseData.currentAmount! - currentLvlPeriod.start) / (currentLvlPeriod.end - currentLvlPeriod.start + 1)) * 100 + '% 100%' -\-> -->
|
||||
<!-- <\!-- }" -\-> -->
|
||||
<!-- <\!-- /> -\-> -->
|
||||
<!-- </ng-container> -->
|
||||
<!-- <ng-container *ngIf="!currentLvlPeriod.end"> -->
|
||||
<!-- <h2> -->
|
||||
<!-- У Вас последний уровень бонусной программы. Процент начисляемых бонусов: {{currentLvlPeriod.percent}}% -->
|
||||
<!-- </h2> -->
|
||||
<!-- </ng-container> -->
|
||||
<!-- </ng-container> -->
|
||||
<!-- <ng-container *ngIf="purchaseData.$loading"> -->
|
||||
<!-- <ng-container -->
|
||||
<!-- *ngTemplateOutlet="spinner; context: { $implicit: 48 }" -->
|
||||
<!-- ></ng-container> -->
|
||||
<!-- </ng-container> -->
|
||||
|
||||
<!-- </div> -->
|
||||
<app-last-order
|
||||
[lastOrder]="lastPurchase"
|
||||
[loading]="loyaltyProgram.purchaseData.$loading"
|
||||
></app-last-order>
|
||||
<a class="guest-card__loyalty-program" routerLink="loyality-program"
|
||||
>Подробнее о правилах <br />
|
||||
Программы лояльности</a
|
||||
>
|
||||
</div>
|
||||
<span id="bonuses-condition"></span>
|
||||
<app-accordion header="Условия начисления бонусов">
|
||||
<p>
|
||||
Расчет начисления бонусов - 10% от суммы покупок за период с 11.01.2023г.
|
||||
по 31.03.2023 г.
|
||||
</p>
|
||||
<p>
|
||||
За период с 11.01.2023г. по 31.03.2023 г. сумма ваших покупок составила
|
||||
3700 руб.
|
||||
</p>
|
||||
<p>Начисляемый бонус 10% от суммы покупок</p>
|
||||
</app-accordion>
|
||||
<app-accordion header="Условия «оплаты» покупки бонусами">
|
||||
<p>
|
||||
Участник может использовать Бонусы для «оплаты» до 100% стоимости любой
|
||||
покупки.
|
||||
</p>
|
||||
<p>
|
||||
Списание Бонусов происходит из расчета 1:1 (один Бонус дает скидку 1
|
||||
российский рубль / 1 тенге / 1 белорусский рубль. Скидка, предоставляемая
|
||||
Участнику при списании Бонусов, уменьшает цену товаров в заказе в
|
||||
соответствии с условиями ПЛ.
|
||||
</p>
|
||||
<p>
|
||||
Для списания Бонусов Участник должен попросить об этом в кофе-баре сети
|
||||
«COFFEE LIKE» кассира до момента пробития фискального чека, после чего им
|
||||
будет проверена возможность списания Бонусов.
|
||||
</p>
|
||||
<p>
|
||||
Для всех Участников возможно списание без использования мобильного
|
||||
приложения.
|
||||
</p>
|
||||
<p>Полученные Бонусы не подлежат обмену на денежные средства.</p>
|
||||
</app-accordion>
|
||||
<app-accordion header="Особые условия">
|
||||
<p>
|
||||
Начисленные на счет бонусы сгорают по прошествии 90 дней с момента
|
||||
совершения последней покупки с начислением или списанием бонусов.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
Возврат покупки, за которую бонусы были начислены:
|
||||
<li>
|
||||
В случае, если бонусов на счету достаточно для списания, бонусы
|
||||
списываются в полном ранее начисленном за возвращаемый товар объеме.
|
||||
</li>
|
||||
<li>
|
||||
В случае, если бонусов на счету недостаточно, формируется минусовой
|
||||
баланс.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
Возврат покупки, которая была оплачена бонусами:
|
||||
<li>
|
||||
В случае предъявления Участником кассового или товарного чека, сумма
|
||||
бонусов, списанная для оплаты возвращаемого товара, зачисляется на счет
|
||||
участника.
|
||||
</li>
|
||||
<li>
|
||||
В случае возврата товара с применением оплаты бонусами, клиенту
|
||||
возвращается денежная сумма в размере, внесенном Участником в оплату
|
||||
товара при покупке, за вычетом суммы, оплаченной бонусами.
|
||||
</li>
|
||||
</ul>
|
||||
</app-accordion>
|
||||
|
||||
<div
|
||||
class="guest-card__purchases-description"
|
||||
[ngStyle]="{
|
||||
display: loyaltyProgram.purchaseData.$loading ? 'grid' : 'block'
|
||||
}"
|
||||
>
|
||||
Сумма ваших покупок за период с
|
||||
{{ loyaltyProgram.purchaseData.currentPeriod[0].format("DD.MM.yyyyг.") }} -
|
||||
<span *ngIf="!loyaltyProgram.purchaseData.$loading"
|
||||
>{{ loyaltyProgram.purchaseData.currentAmount }} руб.</span
|
||||
>
|
||||
<ng-container *ngIf="loyaltyProgram.purchaseData.$loading">
|
||||
<ng-container
|
||||
*ngTemplateOutlet="spinner; context: { $implicit: 24 }"
|
||||
></ng-container>
|
||||
</ng-container>
|
||||
</div>
|
||||
<app-accordion header="Узнать % начисляемых бонусов">
|
||||
<p>
|
||||
Начисление Бонусных баллов происходит по дифференцированной шкале в
|
||||
зависимости от уровня:
|
||||
</p>
|
||||
|
||||
<ng-container
|
||||
*ngFor="let item of lvlPeriods; let index = index; let last = last"
|
||||
>
|
||||
<ng-container *ngIf="!last">
|
||||
<ul>
|
||||
<span [style]="{ color: item.color }">Уровень {{ index + 1 }}</span>
|
||||
<li>
|
||||
Сумма покупок за предыдущий период {{ item.start }}-{{ item.end }}
|
||||
руб.
|
||||
</li>
|
||||
<li>Начисляемый бонус {{ item.percent }}% от суммы покупки</li>
|
||||
</ul>
|
||||
<br />
|
||||
</ng-container>
|
||||
<ng-container *ngIf="last">
|
||||
<ul>
|
||||
<span [style]="{ color: item.color }">Уровень {{ index + 1 }}</span>
|
||||
<li>Сумма покупок за предыдущий период — от {{ item.start }} руб.</li>
|
||||
<li>Начисляемый бонус, в % от суммы покупки - {{ item.percent }}%</li>
|
||||
</ul>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
</app-accordion>
|
||||
|
||||
<div class="guest-card__level-info">
|
||||
<ng-container *ngIf="!loyaltyProgram.purchaseData.$loading">
|
||||
<ng-container *ngIf="currentLvlPeriod.end">
|
||||
<h2>
|
||||
До следующего уровня за период с
|
||||
{{ loyaltyProgram.purchaseData.currentPeriod[0].format("DD.MM.yyyyг") }} по
|
||||
{{ loyaltyProgram.purchaseData.currentPeriod[1].format("DD.MM.yyyyг") }}
|
||||
осталось совершить покупки на {{ currentLvlPeriod.end - (loyaltyProgram.purchaseData.currentAmount || 0) + 1 }} рублей
|
||||
</h2>
|
||||
<input
|
||||
type="range"
|
||||
[value]="loyaltyProgram.purchaseData.currentAmount"
|
||||
[min]="currentLvlPeriod.start"
|
||||
[max]="currentLvlPeriod.end"
|
||||
[step]="0.01"
|
||||
disabled="true"
|
||||
[ngStyle]="{
|
||||
'background-size': ((loyaltyProgram.purchaseData.currentAmount! - currentLvlPeriod.start) / (currentLvlPeriod.end - currentLvlPeriod.start + 1)) * 100 + '% 100%'
|
||||
}"
|
||||
/>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="!currentLvlPeriod.end">
|
||||
<h2>
|
||||
У Вас последний уровень бонусной программы. Процент начисляемых бонусов: {{currentLvlPeriod.percent}}%
|
||||
</h2>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="loyaltyProgram.purchaseData.$loading">
|
||||
<ng-container
|
||||
*ngTemplateOutlet="spinner; context: { $implicit: 48 }"
|
||||
></ng-container>
|
||||
</ng-container>
|
||||
|
||||
<p class="show-more">
|
||||
<a href="#bonuses-condition">
|
||||
Узнать условия начисления бонусов
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<hr />
|
||||
<app-last-order
|
||||
[lastOrder]="lastPurchase"
|
||||
[loading]="loyaltyProgram.purchaseData.$loading"
|
||||
></app-last-order>
|
||||
<hr />
|
||||
<app-invite-friends></app-invite-friends>
|
||||
<hr />
|
||||
<div class="guest-card__download-app">
|
||||
<img src="/assets/download-app.svg" alt="Скачай приложение" />
|
||||
</div>
|
||||
<a class="guest-card__loyalty-program" routerLink="loyalty-program"
|
||||
>Подробнее о правилах <br />
|
||||
Программы лояльности</a
|
||||
>
|
||||
</div>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="this.loyaltyProgram.purchaseData.$loading">
|
||||
<ng-container
|
||||
*ngTemplateOutlet="spinner; context: { $implicit: 85 }"
|
||||
></ng-container>
|
||||
</ng-container>
|
||||
|
||||
<ng-template #spinner let-diameter>
|
||||
<mat-spinner [strokeWidth]="3" [diameter]="diameter"></mat-spinner>
|
||||
|
||||
@ -3,11 +3,42 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 8px 0 0;
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
|
||||
.top-info {
|
||||
padding: 8px 0 0;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
background-color: #292929;
|
||||
border-bottom-left-radius: 10px;
|
||||
border-bottom-right-radius: 10px;
|
||||
border: 1px solid #000000;
|
||||
border-top: 1px solid #888888;
|
||||
|
||||
&__level {
|
||||
width: 100%;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
& p {
|
||||
color: #28af49;
|
||||
}
|
||||
|
||||
p.top-info__bonus {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
&__qr {
|
||||
margin: 10px;
|
||||
padding: 10px;
|
||||
width: fit-content;
|
||||
background-image: linear-gradient(
|
||||
@ -32,21 +63,23 @@
|
||||
}
|
||||
|
||||
&__user-description {
|
||||
margin: 18px 0 0;
|
||||
background-color: #292929;
|
||||
padding: 14px 24px;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
border-top: 1px solid #fff;
|
||||
border-bottom: 1px solid #fff;
|
||||
// font-family: "Goldman";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
line-height: 19px;
|
||||
letter-spacing: -0.5px;
|
||||
|
||||
span {
|
||||
color: #f2994a;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,9 +87,7 @@
|
||||
margin: 0;
|
||||
padding: 14px 24px;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid #fff;
|
||||
// font-family: "Goldman";
|
||||
text-align: center;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
@ -70,13 +101,16 @@
|
||||
}
|
||||
|
||||
&__level-info {
|
||||
padding: 36px;
|
||||
padding-top: 36px;
|
||||
padding-left: 36px;
|
||||
padding-right: 36px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
h2 {
|
||||
font-style: normal;
|
||||
font-family: Montserrat;
|
||||
font-weight: 700;
|
||||
font-size: 17px;
|
||||
line-height: 22px;
|
||||
@ -124,7 +158,6 @@
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 100%;
|
||||
display: none;
|
||||
}
|
||||
|
||||
&::-ms-thumb {
|
||||
@ -149,19 +182,6 @@
|
||||
transition: background 0.3s ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
& > .show-more {
|
||||
margin-top: 42px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
text-align: center;
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: #28af49;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__download-app {
|
||||
@ -178,9 +198,9 @@
|
||||
|
||||
&__loyalty-program {
|
||||
text-align: center;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
color: #28af49;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-weight: bold;
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
text-decoration: none;
|
||||
|
||||
@ -24,8 +24,6 @@ export class GuestCardComponent implements OnInit {
|
||||
public purchases!: Purchase[];
|
||||
public lastPurchase!: Purchase;
|
||||
|
||||
public lvlPeriods: lvlPeriod[] = lvlPeriods;
|
||||
public currentLvlPeriod!: lvlPeriod;
|
||||
|
||||
constructor(
|
||||
private _bottomSheet: MatBottomSheet,
|
||||
@ -55,7 +53,8 @@ export class GuestCardComponent implements OnInit {
|
||||
this.loyaltyProgram.setCurrentPurchases(this.purchases)
|
||||
|
||||
const currentAmount = this.loyaltyProgram.purchaseData.currentAmount || 0
|
||||
this.currentLvlPeriod = this.lvlPeriods.find((item) => item.start <= currentAmount && currentAmount <= (item.end || Infinity))!
|
||||
this.loyaltyProgram.setCurrentLvl(currentAmount)
|
||||
// this.currentLvlPeriod = this.lvlPeriods.find((item) => item.start <= currentAmount && currentAmount <= (item.end || Infinity))!
|
||||
this.loyaltyProgram.purchaseData.$loading = false;
|
||||
});
|
||||
},
|
||||
|
||||
@ -3,7 +3,7 @@ import {
|
||||
Component,
|
||||
EventEmitter,
|
||||
HostListener,
|
||||
OnInit
|
||||
OnInit,
|
||||
} from '@angular/core';
|
||||
import { FormControl, FormGroup, Validators } from '@angular/forms';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
@ -37,7 +37,8 @@ export class LoginComponent implements OnInit, AfterViewInit {
|
||||
private router: Router,
|
||||
private jsonrpc: JsonrpcService,
|
||||
private messageService: MessageService,
|
||||
private _snackBar: MatSnackBar
|
||||
private _snackBar: MatSnackBar,
|
||||
private jsonRpcService: JsonrpcService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {}
|
||||
@ -45,7 +46,7 @@ export class LoginComponent implements OnInit, AfterViewInit {
|
||||
ngAfterViewInit() {
|
||||
setTimeout(() => {
|
||||
this.inputFocusEmitter.emit(`#${this.inputIds[0]}`);
|
||||
}, 1000)
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
public inputFocusEmitter = new EventEmitter<string>();
|
||||
@ -72,7 +73,6 @@ export class LoginComponent implements OnInit, AfterViewInit {
|
||||
const nextInputIndex = index + 1;
|
||||
if (event.target.value.length > 1) {
|
||||
event.target.value = event.target.value.slice(-1);
|
||||
|
||||
}
|
||||
if (nextInputIndex > 0 && nextInputIndex <= this.inputIds.length) {
|
||||
this.inputFocusEmitter.emit(`#${this.inputIds[nextInputIndex]}`);
|
||||
@ -91,68 +91,95 @@ export class LoginComponent implements OnInit, AfterViewInit {
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.jsonrpc.rpc({
|
||||
method: 'sendVerifyByPhone',
|
||||
params: [data.phone]
|
||||
}, RpcService.authService, false).subscribe({
|
||||
this.jsonrpc
|
||||
.rpc(
|
||||
{
|
||||
method: 'sendVerifyByPhone',
|
||||
params: [data.phone],
|
||||
},
|
||||
RpcService.authService,
|
||||
false
|
||||
)
|
||||
.subscribe({
|
||||
next: (result) => {
|
||||
if (result.code !== 0) {
|
||||
this._snackBar.open('Произошла ошибка! Попробуйте позже', '', {
|
||||
duration: 3000
|
||||
})
|
||||
duration: 3000,
|
||||
});
|
||||
}
|
||||
if (result.code === 0) {
|
||||
this.timeLeft = 60;
|
||||
const interval = setInterval(() => {
|
||||
if(this.timeLeft > 0) {
|
||||
if (this.timeLeft > 0) {
|
||||
this.timeLeft--;
|
||||
} else {
|
||||
clearInterval(interval);
|
||||
}
|
||||
},1000)
|
||||
}, 1000);
|
||||
}
|
||||
this.isShowNumber = false;
|
||||
},
|
||||
error: (error) => {
|
||||
console.error('Error: ', error);
|
||||
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
});
|
||||
setTimeout(() => {
|
||||
this.inputFocusEmitter.emit(`#${this.inputIds[0]}`);
|
||||
}, 0)
|
||||
}, 0);
|
||||
}
|
||||
|
||||
submitCode() {
|
||||
const data = this.codeForm.value;
|
||||
this.jsonrpc.rpc({
|
||||
method: 'getTokenByPhone',
|
||||
params: [this.phoneForm.value.phone, Object.values(data).join('')]
|
||||
}, RpcService.authService, false).subscribe({
|
||||
this.jsonrpc
|
||||
.rpc(
|
||||
{
|
||||
method: 'getTokenByPhone',
|
||||
params: [this.phoneForm.value.phone, Object.values(data).join('')],
|
||||
},
|
||||
RpcService.authService,
|
||||
false
|
||||
)
|
||||
.subscribe({
|
||||
next: (result) => {
|
||||
if (result.code === 0) {
|
||||
this.cookiesService.setCookie('token', result?.data?.token);
|
||||
this.router.navigate(['/'], {
|
||||
queryParams: {
|
||||
token: result?.data?.token
|
||||
this.jsonRpcService.rpc(
|
||||
{
|
||||
method: 'updateAdditionalInfo',
|
||||
params: [
|
||||
{
|
||||
first_name: this.phoneForm.value.name,
|
||||
birth_day: '01.01.1999'
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
RpcService.authService,
|
||||
true
|
||||
).subscribe({
|
||||
next: (value) => {
|
||||
this.router.navigate(['/'], {
|
||||
queryParams: {
|
||||
token: result?.data?.token,
|
||||
},
|
||||
});
|
||||
},
|
||||
error: (err) => {
|
||||
console.error(err);
|
||||
|
||||
}
|
||||
})
|
||||
// this.phoneConfirmed.emit(null);
|
||||
} else if (result.code === 230) {
|
||||
this._snackBar.open('Неверный код!', '', {
|
||||
duration: 3000
|
||||
})
|
||||
duration: 3000,
|
||||
});
|
||||
// this.errorConfirmCode = true;
|
||||
|
||||
}
|
||||
},
|
||||
error: (error) => {
|
||||
console.error(error);
|
||||
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
backToPhoneForm() {
|
||||
@ -160,8 +187,8 @@ export class LoginComponent implements OnInit, AfterViewInit {
|
||||
code: '',
|
||||
code1: '',
|
||||
code2: '',
|
||||
code3: ''
|
||||
})
|
||||
this.isShowNumber = true
|
||||
code3: '',
|
||||
});
|
||||
this.isShowNumber = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,99 @@
|
||||
<app-navbar title="Программа лояльности" (backEvent)="goBack()"></app-navbar>
|
||||
|
||||
<div class="loyality-program">
|
||||
<app-accordion header="Условия начисления бонусов">
|
||||
<p>
|
||||
Расчет начисления бонусов - 10% от суммы покупок за период с 11.01.2023г.
|
||||
по 31.03.2023 г.
|
||||
</p>
|
||||
<p>
|
||||
За период с 11.01.2023г. по 31.03.2023 г. сумма ваших покупок составила
|
||||
3700 руб.
|
||||
</p>
|
||||
<p>Начисляемый бонус 10% от суммы покупок</p>
|
||||
</app-accordion>
|
||||
<app-accordion header="Условия «оплаты» покупки бонусами">
|
||||
<p>
|
||||
Участник может использовать Бонусы для «оплаты» до 100% стоимости любой
|
||||
покупки.
|
||||
</p>
|
||||
<p>
|
||||
Списание Бонусов происходит из расчета 1:1 (один Бонус дает скидку 1
|
||||
российский рубль / 1 тенге / 1 белорусский рубль. Скидка, предоставляемая
|
||||
Участнику при списании Бонусов, уменьшает цену товаров в заказе в
|
||||
соответствии с условиями ПЛ.
|
||||
</p>
|
||||
<p>
|
||||
Для списания Бонусов Участник должен попросить об этом в кофе-баре сети
|
||||
«COFFEE LIKE» кассира до момента пробития фискального чека, после чего им
|
||||
будет проверена возможность списания Бонусов.
|
||||
</p>
|
||||
<p>
|
||||
Для всех Участников возможно списание без использования мобильного
|
||||
приложения.
|
||||
</p>
|
||||
<p>Полученные Бонусы не подлежат обмену на денежные средства.</p>
|
||||
</app-accordion>
|
||||
<app-accordion header="Особые условия">
|
||||
<p>
|
||||
Начисленные на счет бонусы сгорают по прошествии 90 дней с момента
|
||||
совершения последней покупки с начислением или списанием бонусов.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
Возврат покупки, за которую бонусы были начислены:
|
||||
<li>
|
||||
В случае, если бонусов на счету достаточно для списания, бонусы
|
||||
списываются в полном ранее начисленном за возвращаемый товар объеме.
|
||||
</li>
|
||||
<li>
|
||||
В случае, если бонусов на счету недостаточно, формируется минусовой
|
||||
баланс.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
Возврат покупки, которая была оплачена бонусами:
|
||||
<li>
|
||||
В случае предъявления Участником кассового или товарного чека, сумма
|
||||
бонусов, списанная для оплаты возвращаемого товара, зачисляется на счет
|
||||
участника.
|
||||
</li>
|
||||
<li>
|
||||
В случае возврата товара с применением оплаты бонусами, клиенту
|
||||
возвращается денежная сумма в размере, внесенном Участником в оплату
|
||||
товара при покупке, за вычетом суммы, оплаченной бонусами.
|
||||
</li>
|
||||
</ul>
|
||||
</app-accordion>
|
||||
|
||||
<app-accordion header="Узнать % начисляемых бонусов">
|
||||
<p>
|
||||
Начисление Бонусных баллов происходит по дифференцированной шкале в
|
||||
зависимости от уровня:
|
||||
</p>
|
||||
|
||||
<ng-container
|
||||
*ngFor="let item of lvlPeriods; let index = index; let last = last"
|
||||
>
|
||||
<ng-container *ngIf="!last">
|
||||
<ul>
|
||||
<span [style]="{ color: item.color }">Уровень {{ index + 1 }}</span>
|
||||
<li>
|
||||
Сумма покупок за предыдущий период {{ item.start }}-{{ item.end }}
|
||||
руб.
|
||||
</li>
|
||||
<li>Начисляемый бонус {{ item.percent }}% от суммы покупки</li>
|
||||
</ul>
|
||||
<br />
|
||||
</ng-container>
|
||||
<ng-container *ngIf="last">
|
||||
<ul>
|
||||
<span [style]="{ color: item.color }">Уровень {{ index + 1 }}</span>
|
||||
<li>Сумма покупок за предыдущий период — от {{ item.start }} руб.</li>
|
||||
<li>Начисляемый бонус, в % от суммы покупки - {{ item.percent }}%</li>
|
||||
</ul>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
</app-accordion>
|
||||
</div>
|
||||
@ -0,0 +1,3 @@
|
||||
.loyality-program {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Location } from '@angular/common';
|
||||
import { lvlPeriod } from 'src/app/interface/data';
|
||||
import { lvlPeriods } from 'src/app/app.constants';
|
||||
|
||||
@Component({
|
||||
selector: 'loyality-program',
|
||||
templateUrl: './loyality-program.component.html',
|
||||
styleUrls: ['./loyality-program.component.scss'],
|
||||
})
|
||||
export class LoyalityProgramComponent implements OnInit {
|
||||
constructor(private _location: Location) {}
|
||||
|
||||
public lvlPeriods: lvlPeriod[] = lvlPeriods;
|
||||
|
||||
goBack() {
|
||||
this._location.back();
|
||||
}
|
||||
|
||||
ngOnInit(): void {}
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import moment from 'moment';
|
||||
import { Moment, Purchase } from '../interface/data';
|
||||
import { Moment, Purchase, lvlPeriod } from '../interface/data';
|
||||
import { lvlPeriods } from '../app.constants';
|
||||
|
||||
export interface IPurchaseData {
|
||||
currentPeriod: Moment[];
|
||||
@ -25,12 +26,20 @@ export class LoyaltyProgramService {
|
||||
get currentAmount(): number {
|
||||
const amount = this.currentPurchases.reduce(
|
||||
(accumulator, currentValue) => {
|
||||
if (['CancelPayFromWallet', 'CancelRefillWalletFromOrder'].includes(currentValue.transactionType || '')) {
|
||||
if (
|
||||
['CancelPayFromWallet', 'CancelRefillWalletFromOrder'].includes(
|
||||
currentValue.transactionType || ''
|
||||
)
|
||||
) {
|
||||
return accumulator - currentValue.orderSum!;
|
||||
} else if (['PayFromWallet', 'RefillWalletFromOrder'].includes(currentValue.transactionType || '')) {
|
||||
} else if (
|
||||
['PayFromWallet', 'RefillWalletFromOrder'].includes(
|
||||
currentValue.transactionType || ''
|
||||
)
|
||||
) {
|
||||
return accumulator + currentValue.orderSum!;
|
||||
}
|
||||
return accumulator
|
||||
return accumulator;
|
||||
},
|
||||
0
|
||||
);
|
||||
@ -39,17 +48,29 @@ export class LoyaltyProgramService {
|
||||
},
|
||||
get lastAmount(): number {
|
||||
const amount = this.lastPurchases.reduce((accumulator, currentValue) => {
|
||||
if (['CancelPayFromWallet', 'CancelRefillWalletFromOrder'].includes(currentValue.transactionType || '')) {
|
||||
if (
|
||||
['CancelPayFromWallet', 'CancelRefillWalletFromOrder'].includes(
|
||||
currentValue.transactionType || ''
|
||||
)
|
||||
) {
|
||||
return accumulator - currentValue.orderSum!;
|
||||
} else if (['PayFromWallet', 'RefillWalletFromOrder'].includes(currentValue.transactionType || '')) {
|
||||
} else if (
|
||||
['PayFromWallet', 'RefillWalletFromOrder'].includes(
|
||||
currentValue.transactionType || ''
|
||||
)
|
||||
) {
|
||||
return accumulator + currentValue.orderSum!;
|
||||
}
|
||||
return accumulator
|
||||
return accumulator;
|
||||
}, 0);
|
||||
return amount * 1;
|
||||
},
|
||||
};
|
||||
|
||||
public currentLvl: number = 1;
|
||||
public currentLvlPeriod!: lvlPeriod;
|
||||
public lvlPeriods: lvlPeriod[] = lvlPeriods;
|
||||
|
||||
constructor() {
|
||||
this.getCurrentQuarterOfYear();
|
||||
}
|
||||
@ -60,7 +81,10 @@ export class LoyaltyProgramService {
|
||||
moment().subtract(1, 'years').endOf('year').subtract(3, 'months'),
|
||||
moment().startOf('year').add(10, 'days'),
|
||||
],
|
||||
[moment().startOf('year').add(10, 'days'), moment().startOf('year').add(3, 'months')],
|
||||
[
|
||||
moment().startOf('year').add(10, 'days'),
|
||||
moment().startOf('year').add(3, 'months'),
|
||||
],
|
||||
[
|
||||
moment().startOf('year').add(3, 'months'),
|
||||
moment().startOf('year').add(6, 'months'),
|
||||
@ -84,13 +108,13 @@ export class LoyaltyProgramService {
|
||||
}
|
||||
|
||||
getBalanceAmount(loyaltyPrograms: any[]) {
|
||||
return loyaltyPrograms.reduce((accumulator, currentValue) => {
|
||||
return (loyaltyPrograms || []).reduce((accumulator, currentValue) => {
|
||||
return accumulator + currentValue.balance;
|
||||
}, 0);
|
||||
}
|
||||
|
||||
setLastPurchases(purchases: Purchase[]) {
|
||||
this.purchaseData.lastPurchases = purchases.filter((value: Purchase) => {
|
||||
this.purchaseData.lastPurchases = (purchases || []).filter((value: Purchase) => {
|
||||
return moment(value.transactionCreateDate).isBetween(
|
||||
this.purchaseData.lastPeriod[0],
|
||||
this.purchaseData.lastPeriod[1]
|
||||
@ -99,7 +123,7 @@ export class LoyaltyProgramService {
|
||||
}
|
||||
|
||||
setCurrentPurchases(purchases: Purchase[]) {
|
||||
this.purchaseData.currentPurchases = purchases.filter((value: Purchase) => {
|
||||
this.purchaseData.currentPurchases = (purchases || []).filter((value: Purchase) => {
|
||||
return moment(value.transactionCreateDate).isBetween(
|
||||
this.purchaseData.currentPeriod[0],
|
||||
this.purchaseData.currentPeriod[1]
|
||||
@ -108,7 +132,7 @@ export class LoyaltyProgramService {
|
||||
}
|
||||
|
||||
filterPurchases(purchases: Purchase[]) {
|
||||
return purchases.filter((purchase: Purchase) =>
|
||||
return (purchases || []).filter((purchase: Purchase) =>
|
||||
[
|
||||
'PayFromWallet',
|
||||
'RefillWalletFromOrder',
|
||||
@ -125,4 +149,22 @@ export class LoyaltyProgramService {
|
||||
)
|
||||
)[0];
|
||||
}
|
||||
|
||||
setCurrentLvl(currentAmount: number) {
|
||||
const index = this.lvlPeriods.findIndex(
|
||||
(item) =>
|
||||
item.start <= currentAmount && currentAmount <= (item.end || Infinity)
|
||||
)!;
|
||||
if (index != -1) {
|
||||
this.currentLvlPeriod = this.lvlPeriods[index];
|
||||
this.currentLvl = index + 1;
|
||||
}
|
||||
}
|
||||
|
||||
getNextLevel(): lvlPeriod {
|
||||
if(this.currentLvl == this.lvlPeriods.length) {
|
||||
return lvlPeriods[this.currentLvl - 1];
|
||||
}
|
||||
return lvlPeriods[this.currentLvl];
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ export const environment = {
|
||||
},
|
||||
version: packageJson.version,
|
||||
appleWalletEndpoint: 'http://192.168.0.179:4200/apns/api',
|
||||
icardProxy: 'http://localhost:4200/icard-proxy/',
|
||||
icardProxy: 'http://192.168.0.14:4200/icard-proxy/',
|
||||
appleWalletSecret: 'Token F5mbzEERAznGKVbB6l',
|
||||
clientName: 'coffeeLike'
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user