Merge branch 'coffee-like' of https://git.hlcompany.ru/git/usersite into coffee-like

This commit is contained in:
gofnnp 2023-05-12 20:18:37 +04:00
commit 6a075ec773
15 changed files with 268 additions and 215 deletions

View File

@ -1,12 +1,12 @@
{ {
"name": "coffee-like", "name": "coffee-like",
"version": "0.0.1", "version": "0.0.2",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "coffee-like", "name": "coffee-like",
"version": "0.0.1", "version": "0.0.2",
"dependencies": { "dependencies": {
"@angular/animations": "^14.0.0", "@angular/animations": "^14.0.0",
"@angular/cdk": "^14.2.1", "@angular/cdk": "^14.2.1",

View File

@ -4,6 +4,7 @@ import { MainComponent } from './pages/main/main.component';
import { GuestCardComponent } from './pages/guest-card/guest-card.component'; import { GuestCardComponent } from './pages/guest-card/guest-card.component';
import { LoginComponent } from './pages/login/login.component'; import { LoginComponent } from './pages/login/login.component';
import { AuthGuard } from './guards/auth-guard.guard'; import { AuthGuard } from './guards/auth-guard.guard';
import { LoyalityProgramComponent } from './pages/loyality-program/loyality-program.component';
const routes: Routes = [ const routes: Routes = [
{ {
@ -16,6 +17,10 @@ const routes: Routes = [
path: 'login', path: 'login',
component: LoginComponent component: LoginComponent
}, },
{
path: 'loyality-program',
component: LoyalityProgramComponent,
}
// { path: '**', component: NotFoundComponent } // { path: '**', component: NotFoundComponent }
]; ];

View File

@ -2,6 +2,7 @@ import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser'; import { BrowserModule } from '@angular/platform-browser';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
import { LoyalityProgramComponent } from './pages/loyality-program/loyality-program.component';
import { AppRoutingModule } from './app-routing.module'; import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { MainComponent } from './pages/main/main.component'; import { MainComponent } from './pages/main/main.component';
@ -80,6 +81,7 @@ import { DirectivesModule } from './directives/directives.module';
SocialMediaButtonsComponent, SocialMediaButtonsComponent,
LoginComponent, LoginComponent,
// FocusNextInputDirective, // FocusNextInputDirective,
LoyalityProgramComponent,
], ],
imports: [ imports: [
BrowserModule, BrowserModule,

View File

@ -5,7 +5,8 @@
gap: 20px; gap: 20px;
padding-bottom: 100px; padding-bottom: 100px;
h3 { h3 {
margin: 0; margin: 0;
font-family: Montserrat;
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
font-size: 15px; font-size: 15px;

View File

@ -1,6 +1,7 @@
:host { :host {
padding: 16px; padding: 16px;
h2 { h2 {
font-family: Montserrat;
font-style: normal; font-style: normal;
font-weight: 700; font-weight: 700;
font-size: 17px; font-size: 17px;

View File

@ -1,7 +1,8 @@
:host { :host {
padding: 24px 16px 56px; padding: 24px 16px 0px;
& > h2 { & > h2 {
font-family: Montserrat;
font-style: normal; font-style: normal;
font-weight: 700; font-weight: 700;
font-size: 15px; font-size: 15px;

View File

@ -24,7 +24,7 @@
visibility: hidden; visibility: hidden;
} }
.title { .title {
font-family: "Gotham Pro", sans-serif; font-family: "Montserrat", sans-serif;
font-weight: 700; font-weight: 700;
font-size: 17px; font-size: 17px;
line-height: 22px; line-height: 22px;

View File

@ -1,6 +1,13 @@
<app-navbar title="Карта гостя" (backEvent)="logout()"></app-navbar> <app-navbar title="Карта гостя" (backEvent)="logout()"></app-navbar>
<div class="guest-card"> <div class="guest-card">
<div class="top-info">
<div class="top-info__level">
<p id="level">Уровень {{ currentLvl }}</p>
<p id="level-percent">Кэшбек {{ currentLvlPeriod.percent }}%</p>
</div>
<p class="top-info__bonus">{{ getBalanceAmount(customerInfo?.walletBalances) }} бонусов</p>
</div>
<div class="guest-card__qr" (click)="qrCodeClick()"> <div class="guest-card__qr" (click)="qrCodeClick()">
<ng-container *ngIf="customerInfo"> <ng-container *ngIf="customerInfo">
<qr-code <qr-code
@ -15,179 +22,56 @@
*ngTemplateOutlet="spinner; context: { $implicit: 85 }" *ngTemplateOutlet="spinner; context: { $implicit: 85 }"
></ng-container> ></ng-container>
</ng-container> </ng-container>
</div> </div>
<div class="guest-card__user-description"> <div class="guest-card__user-description">
Текущий баланс бонусов: <p>
<span *ngIf="customerInfo"> <ng-container *ngIf="currentLvlPeriod.end">
{{ getBalanceAmount(customerInfo?.walletBalances) }} Осталось купить на сумму <span class="price">{{ currentLvlPeriod.end - (purchaseData.currentAmount || 0) + 1 }}</span>
бонусов</span рублей, тогда кэшбек будет <span class="percent">{{ getNextLevel().percent }}%</span> с
> {{ purchaseData.currentPeriod[1].locale('ru').format('D MMMM')}}
</ng-container>
<ng-container *ngIf="!currentLvlPeriod.end">
У Вас последний уровень бонусной программы. Процент начисляемых бонусов:
{{currentLvlPeriod.percent}}%
</ng-container>
</p>
</div> </div>
<span id="bonuses-condition"></span> <span id="bonuses-condition"></span>
<app-accordion header="Условия начисления бонусов">
<p> <!-- <div class="guest-card__level-info"> -->
Расчет начисления бонусов - 10% от суммы покупок за период с 11.01.2023г. <!-- <ng-container *ngIf="!purchaseData.$loading"> -->
по 31.03.2023 г. <!-- <ng-container *ngIf="currentLvlPeriod.end"> -->
</p> <!-- <\!-- <input -\-> -->
<p> <!-- <\!-- type="range" -\-> -->
За период с 11.01.2023г. по 31.03.2023 г. сумма ваших покупок составила <!-- <\!-- [value]="purchaseData.currentAmount" -\-> -->
3700 руб. <!-- <\!-- [min]="currentLvlPeriod.start" -\-> -->
</p> <!-- <\!-- [max]="currentLvlPeriod.end" -\-> -->
<p>Начисляемый бонус 10% от суммы покупок</p> <!-- <\!-- [step]="0.01" -\-> -->
</app-accordion> <!-- <\!-- disabled="true" -\-> -->
<app-accordion header="Условия «оплаты» покупки бонусами"> <!-- <\!-- [ngStyle]="{ -\-> -->
<p> <!-- <\!-- 'background-size': ((purchaseData.currentAmount! - currentLvlPeriod.start) / (currentLvlPeriod.end - currentLvlPeriod.start + 1)) * 100 + '% 100%' -\-> -->
Участник может использовать Бонусы для «оплаты» до 100% стоимости любой <!-- <\!-- }" -\-> -->
покупки. <!-- <\!-- /> -\-> -->
</p> <!-- </ng-container> -->
<p> <!-- <ng-container *ngIf="!currentLvlPeriod.end"> -->
Списание Бонусов происходит из расчета 1:1 (один Бонус дает скидку 1 <!-- <h2> -->
российский рубль / 1 тенге / 1 белорусский рубль. Скидка, предоставляемая <!-- У Вас последний уровень бонусной программы. Процент начисляемых бонусов: {{currentLvlPeriod.percent}}% -->
Участнику при списании Бонусов, уменьшает цену товаров в заказе в <!-- </h2> -->
соответствии с условиями ПЛ. <!-- </ng-container> -->
</p> <!-- </ng-container> -->
<p> <!-- <ng-container *ngIf="purchaseData.$loading"> -->
Для списания Бонусов Участник должен попросить об этом в кофе-баре сети <!-- <ng-container -->
«COFFEE LIKE» кассира до момента пробития фискального чека, после чего им <!-- *ngTemplateOutlet="spinner; context: { $implicit: 48 }" -->
будет проверена возможность списания Бонусов. <!-- ></ng-container> -->
</p> <!-- </ng-container> -->
<p>
Для всех Участников возможно списание без использования мобильного
приложения.
</p>
<p>Полученные Бонусы не подлежат обмену на денежные средства.</p>
</app-accordion>
<app-accordion header="Особые условия">
<p>
Начисленные на счет бонусы сгорают по прошествии 90 дней с момента
совершения последней покупки с начислением или списанием бонусов.
</p>
<ul> <!-- </div> -->
Возврат покупки, за которую бонусы были начислены:
<li>
В случае, если бонусов на счету достаточно для списания, бонусы
списываются в полном ранее начисленном за возвращаемый товар объеме.
</li>
<li>
В случае, если бонусов на счету недостаточно, формируется минусовой
баланс.
</li>
</ul>
<ul>
Возврат покупки, которая была оплачена бонусами:
<li>
В случае предъявления Участником кассового или товарного чека, сумма
бонусов, списанная для оплаты возвращаемого товара, зачисляется на счет
участника.
</li>
<li>
В случае возврата товара с применением оплаты бонусами, клиенту
возвращается денежная сумма в размере, внесенном Участником в оплату
товара при покупке, за вычетом суммы, оплаченной бонусами.
</li>
</ul>
</app-accordion>
<div
class="guest-card__purchases-description"
[ngStyle]="{
display: purchaseData.$loading ? 'grid' : 'block'
}"
>
Сумма ваших покупок за период с
{{ purchaseData.currentPeriod[0].format("DD.MM.yyyyг.") }} -
<span *ngIf="!purchaseData.$loading"
>{{ purchaseData.currentAmount }} руб.</span
>
<ng-container *ngIf="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="!purchaseData.$loading">
<ng-container *ngIf="currentLvlPeriod.end">
<h2>
До следующего уровня за период с
{{ purchaseData.currentPeriod[0].format("DD.MM.yyyyг") }} по
{{ purchaseData.currentPeriod[1].format("DD.MM.yyyyг") }}
осталось совершить покупки на {{ currentLvlPeriod.end - (purchaseData.currentAmount || 0) + 1 }} рублей
</h2>
<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>
<p class="show-more">
<a href="#bonuses-condition">
Узнать условия начисления бонусов
</a>
</p>
</div>
<hr />
<app-last-order <app-last-order
[lastOrder]="lastPurchase" [lastOrder]="lastPurchase"
[loading]="purchaseData.$loading" [loading]="purchaseData.$loading"
></app-last-order> ></app-last-order>
<hr /> <a class="guest-card__loyalty-program" routerLink="loyality-program"
<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 /> >Подробнее о правилах <br />
Программы лояльности</a Программы лояльности</a
> >

View File

@ -2,12 +2,43 @@
.guest-card { .guest-card {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
padding: 8px 0 0;
max-width: 600px; max-width: 600px;
margin: 0 auto; 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 { &__qr {
margin: 10px;
padding: 10px; padding: 10px;
width: fit-content; width: fit-content;
background-image: linear-gradient( background-image: linear-gradient(
@ -32,31 +63,31 @@
} }
&__user-description { &__user-description {
margin: 18px 0 0; background-color: #292929;
padding: 14px 24px; 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 { p {
color: #f2994a; 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;
}
} }
&__purchases-description { &__purchases-description {
margin: 0; margin: 0;
padding: 14px 24px; padding: 14px 24px;
width: 100%; width: 100%;
text-align: left; text-align: center;
border-bottom: 1px solid #fff;
// font-family: "Goldman";
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
font-size: 16px; font-size: 16px;
@ -69,15 +100,18 @@
} }
} }
&__level-info { &__level-info {
padding: 36px; padding-top: 36px;
padding-left: 36px;
padding-right: 36px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
h2 { h2 {
font-style: normal; font-style: normal;
font-weight: 700; font-family: Montserrat;
font-weight: 700;
font-size: 17px; font-size: 17px;
line-height: 22px; line-height: 22px;
text-align: center; text-align: center;
@ -150,18 +184,6 @@
} }
} }
& > .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 { &__download-app {
@ -178,9 +200,9 @@
&__loyalty-program { &__loyalty-program {
text-align: center; text-align: center;
color: rgba(255, 255, 255, 0.5); color: #28AF49;
font-style: normal; font-style: normal;
font-weight: 400; font-weight: bold;
font-size: 12px; font-size: 12px;
line-height: 16px; line-height: 16px;
text-decoration: none; text-decoration: none;

View File

@ -58,6 +58,7 @@ export class GuestCardComponent implements OnInit {
public discountLevel: number = 4.2; public discountLevel: number = 4.2;
public lvlPeriods: lvlPeriod[] = lvlPeriods; public lvlPeriods: lvlPeriod[] = lvlPeriods;
public currentLvlPeriod!: lvlPeriod; public currentLvlPeriod!: lvlPeriod;
public currentLvl: number = 1;
constructor( constructor(
private _bottomSheet: MatBottomSheet, private _bottomSheet: MatBottomSheet,
@ -103,13 +104,24 @@ export class GuestCardComponent implements OnInit {
return moment(value.transactionCreateDate).isBetween(this.purchaseData.currentPeriod[0], this.purchaseData.currentPeriod[1]) return moment(value.transactionCreateDate).isBetween(this.purchaseData.currentPeriod[0], this.purchaseData.currentPeriod[1])
}) })
const currentAmount = this.purchaseData.currentAmount || 0 const currentAmount = this.purchaseData.currentAmount || 0
this.currentLvlPeriod = this.lvlPeriods.find((item) => item.start <= currentAmount && currentAmount <= (item.end || Infinity))! const index = this.lvlPeriods.findIndex((item) => item.start <= currentAmount && currentAmount <= (item.end || Infinity))!
this.purchaseData.$loading = false; if(index != -1) {
this.currentLvlPeriod = this.lvlPeriods[index];
this.currentLvl = index + 1;
this.purchaseData.$loading = false;
}
}); });
}, },
}); });
} }
getNextLevel(): lvlPeriod {
if(this.currentLvl == this.lvlPeriods.length) {
return lvlPeriods[this.currentLvl - 1];
}
return lvlPeriods[this.currentLvl];
}
qrCodeClick() { qrCodeClick() {
this.isQrCodeClicked = !this.isQrCodeClicked; this.isQrCodeClicked = !this.isQrCodeClicked;
this.qrCodeSize = this.isQrCodeClicked ? 180 : 85; this.qrCodeSize = this.isQrCodeClicked ? 180 : 85;

View File

@ -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>

View File

@ -0,0 +1,3 @@
.loyality-program {
margin-bottom: 20px;
}

View File

@ -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 {}
}

View File

@ -19,7 +19,7 @@ export const environment = {
}, },
version: packageJson.version, version: packageJson.version,
appleWalletEndpoint: 'http://192.168.0.179:4200/apns/api', appleWalletEndpoint: 'http://192.168.0.179:4200/apns/api',
icardProxy: 'http://192.168.0.14:4200/icard-proxy/', icardProxy: 'http://localhost:4200/icard-proxy/',
appleWalletSecret: 'Token F5mbzEERAznGKVbB6l', appleWalletSecret: 'Token F5mbzEERAznGKVbB6l',
clientName: 'coffeeLike' clientName: 'coffeeLike'
}; };

View File

@ -9,13 +9,15 @@ blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}
table{border-collapse:collapse;border-spacing:0} table{border-collapse:collapse;border-spacing:0}
// @import url('./app/styles/_fonts.scss'); // @import url('./app/styles/_fonts.scss');
@import url('https://fonts.cdnfonts.com/css/gotham-pro'); // @import url('https://fonts.cdnfonts.com/css/gotham-pro');
@import url('https://fonts.googleapis.com/css2?family=Montserrat&display=swap');
* { * {
font-family: 'Gotham Pro'; // font-family: 'Gotham Pro';
font-family: 'Montserrat', sans-serif;
} }
body { body {
background-color: #231F20; background-color: #231F20;
} }