dev #13995
припилил СА, iikocard (но пока только customer_info), доработки
This commit is contained in:
parent
1da7556aed
commit
af60b55e94
@ -87,7 +87,8 @@
|
|||||||
"browserTarget": "coffee-like:build:production"
|
"browserTarget": "coffee-like:build:production"
|
||||||
},
|
},
|
||||||
"development": {
|
"development": {
|
||||||
"browserTarget": "coffee-like:build:development"
|
"browserTarget": "coffee-like:build:development",
|
||||||
|
"proxyConfig": "proxy.confi.json"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"defaultConfiguration": "development"
|
"defaultConfiguration": "development"
|
||||||
|
|||||||
36
angular/package-lock.json
generated
36
angular/package-lock.json
generated
@ -30,7 +30,9 @@
|
|||||||
"firebase": "^9.9.3",
|
"firebase": "^9.9.3",
|
||||||
"google-libphonenumber": "^3.2.30",
|
"google-libphonenumber": "^3.2.30",
|
||||||
"jsbarcode": "^3.11.5",
|
"jsbarcode": "^3.11.5",
|
||||||
|
"libphonenumber-js": "^1.10.28",
|
||||||
"ng-qrcode": "^7.0.0",
|
"ng-qrcode": "^7.0.0",
|
||||||
|
"ngx-mat-intl-tel-input": "^5.0.0",
|
||||||
"ngx-sharebuttons": "^11.0.0",
|
"ngx-sharebuttons": "^11.0.0",
|
||||||
"primeicons": "^5.0.0",
|
"primeicons": "^5.0.0",
|
||||||
"primeng": "^14.0.1",
|
"primeng": "^14.0.1",
|
||||||
@ -8862,6 +8864,11 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/libphonenumber-js": {
|
||||||
|
"version": "1.10.28",
|
||||||
|
"resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.28.tgz",
|
||||||
|
"integrity": "sha512-1eAgjLrZA0+2Wgw4hs+4Q/kEBycxQo8ZLYnmOvZ3AlM8ImAVAJgDPlZtISLEzD1vunc2q8s2Pn7XwB7I8U3Kzw=="
|
||||||
|
},
|
||||||
"node_modules/license-webpack-plugin": {
|
"node_modules/license-webpack-plugin": {
|
||||||
"version": "4.0.2",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-4.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-4.0.2.tgz",
|
||||||
@ -9636,6 +9643,22 @@
|
|||||||
"@angular/core": ">=14 <15"
|
"@angular/core": ">=14 <15"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ngx-mat-intl-tel-input": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ngx-mat-intl-tel-input/-/ngx-mat-intl-tel-input-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-3XwA0zzcxBF/p+BQqBuGxPa7Mi+upehbrR6WvgwWcd+T9NcjImNEAf/Pd8R37OarN3fLrxFq/8g6B2zqYZtBCg==",
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.x"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@angular/common": ">=14.x",
|
||||||
|
"@angular/core": ">=14.x",
|
||||||
|
"@angular/forms": ">=14.x",
|
||||||
|
"@angular/platform-browser": ">=14.x",
|
||||||
|
"@angular/platform-browser-dynamic": ">=14.x",
|
||||||
|
"libphonenumber-js": "^1.10.11"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ngx-sharebuttons": {
|
"node_modules/ngx-sharebuttons": {
|
||||||
"version": "11.0.0",
|
"version": "11.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/ngx-sharebuttons/-/ngx-sharebuttons-11.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/ngx-sharebuttons/-/ngx-sharebuttons-11.0.0.tgz",
|
||||||
@ -20274,6 +20297,11 @@
|
|||||||
"klona": "^2.0.4"
|
"klona": "^2.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"libphonenumber-js": {
|
||||||
|
"version": "1.10.28",
|
||||||
|
"resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.28.tgz",
|
||||||
|
"integrity": "sha512-1eAgjLrZA0+2Wgw4hs+4Q/kEBycxQo8ZLYnmOvZ3AlM8ImAVAJgDPlZtISLEzD1vunc2q8s2Pn7XwB7I8U3Kzw=="
|
||||||
|
},
|
||||||
"license-webpack-plugin": {
|
"license-webpack-plugin": {
|
||||||
"version": "4.0.2",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-4.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-4.0.2.tgz",
|
||||||
@ -20862,6 +20890,14 @@
|
|||||||
"tslib": "^2.4.0"
|
"tslib": "^2.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"ngx-mat-intl-tel-input": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ngx-mat-intl-tel-input/-/ngx-mat-intl-tel-input-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-3XwA0zzcxBF/p+BQqBuGxPa7Mi+upehbrR6WvgwWcd+T9NcjImNEAf/Pd8R37OarN3fLrxFq/8g6B2zqYZtBCg==",
|
||||||
|
"requires": {
|
||||||
|
"tslib": "^2.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
"ngx-sharebuttons": {
|
"ngx-sharebuttons": {
|
||||||
"version": "11.0.0",
|
"version": "11.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/ngx-sharebuttons/-/ngx-sharebuttons-11.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/ngx-sharebuttons/-/ngx-sharebuttons-11.0.0.tgz",
|
||||||
|
|||||||
@ -32,7 +32,9 @@
|
|||||||
"firebase": "^9.9.3",
|
"firebase": "^9.9.3",
|
||||||
"google-libphonenumber": "^3.2.30",
|
"google-libphonenumber": "^3.2.30",
|
||||||
"jsbarcode": "^3.11.5",
|
"jsbarcode": "^3.11.5",
|
||||||
|
"libphonenumber-js": "^1.10.28",
|
||||||
"ng-qrcode": "^7.0.0",
|
"ng-qrcode": "^7.0.0",
|
||||||
|
"ngx-mat-intl-tel-input": "^5.0.0",
|
||||||
"ngx-sharebuttons": "^11.0.0",
|
"ngx-sharebuttons": "^11.0.0",
|
||||||
"primeicons": "^5.0.0",
|
"primeicons": "^5.0.0",
|
||||||
"primeng": "^14.0.1",
|
"primeng": "^14.0.1",
|
||||||
|
|||||||
38
angular/proxy.confi.json
Normal file
38
angular/proxy.confi.json
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"/api": {
|
||||||
|
"target": "https://apple-push-notifications.it-retail.tech/apns/api",
|
||||||
|
"secure": false,
|
||||||
|
"pathRewrite": {
|
||||||
|
"^/api": ""
|
||||||
|
},
|
||||||
|
"changeOrigin": true,
|
||||||
|
"logLevel": "debug"
|
||||||
|
},
|
||||||
|
"/icard-proxy": {
|
||||||
|
"target": "https://sakura.lk.crm4retail.ru/api/icard-proxy",
|
||||||
|
"secure": false,
|
||||||
|
"pathRewrite": {
|
||||||
|
"^/icard-proxy": ""
|
||||||
|
},
|
||||||
|
"changeOrigin": true,
|
||||||
|
"logLevel": "debug"
|
||||||
|
},
|
||||||
|
"/static": {
|
||||||
|
"target": "https://sakura.lk.crm4retail.ru/static",
|
||||||
|
"secure": false,
|
||||||
|
"pathRewrite": {
|
||||||
|
"^/static": ""
|
||||||
|
},
|
||||||
|
"changeOrigin": true,
|
||||||
|
"logLevel": "debug"
|
||||||
|
},
|
||||||
|
"/it-retail": {
|
||||||
|
"target": "https://sakura.lk.crm4retail.ru/it-retail",
|
||||||
|
"secure": false,
|
||||||
|
"pathRewrite": {
|
||||||
|
"^/it-retail": ""
|
||||||
|
},
|
||||||
|
"changeOrigin": true,
|
||||||
|
"logLevel": "debug"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,9 +7,9 @@ import { AppComponent } from './app.component';
|
|||||||
import { MainComponent } from './pages/main/main.component';
|
import { MainComponent } from './pages/main/main.component';
|
||||||
import { NavbarComponent } from './components/navbar/navbar.component';
|
import { NavbarComponent } from './components/navbar/navbar.component';
|
||||||
import { CardComponent } from './components/card/card.component';
|
import { CardComponent } from './components/card/card.component';
|
||||||
import {InputMaskModule} from "primeng/inputmask";
|
import { InputMaskModule } from 'primeng/inputmask';
|
||||||
import { AuthComponent } from './pages/account/auth/auth.component';
|
import { AuthComponent } from './pages/account/auth/auth.component';
|
||||||
import {ProgressSpinnerModule} from "primeng/progressspinner";
|
import { ProgressSpinnerModule } from 'primeng/progressspinner';
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { AccountComponent } from './pages/account/account.component';
|
import { AccountComponent } from './pages/account/account.component';
|
||||||
import { ExitComponent } from './components/exit/exit.component';
|
import { ExitComponent } from './components/exit/exit.component';
|
||||||
@ -23,17 +23,17 @@ import { ServiceWorkerModule } from '@angular/service-worker';
|
|||||||
import { environment } from '../environments/environment';
|
import { environment } from '../environments/environment';
|
||||||
import { AngularFireModule } from '@angular/fire/compat';
|
import { AngularFireModule } from '@angular/fire/compat';
|
||||||
import { AngularFireMessagingModule } from '@angular/fire/compat/messaging';
|
import { AngularFireMessagingModule } from '@angular/fire/compat/messaging';
|
||||||
import {ToastModule} from 'primeng/toast';
|
import { ToastModule } from 'primeng/toast';
|
||||||
import { MessageService } from 'primeng/api';
|
import { MessageService } from 'primeng/api';
|
||||||
import { FooterButtonsComponent } from './components/footer-buttons/footer-buttons.component';
|
import { FooterButtonsComponent } from './components/footer-buttons/footer-buttons.component';
|
||||||
import { UserDataComponent } from './pages/account/user-data/user-data.component';
|
import { UserDataComponent } from './pages/account/user-data/user-data.component';
|
||||||
import { RefSystemComponent } from './pages/account/ref-system/ref-system.component';
|
import { RefSystemComponent } from './pages/account/ref-system/ref-system.component';
|
||||||
import { ShareButtonsModule } from 'ngx-sharebuttons/buttons';
|
import { ShareButtonsModule } from 'ngx-sharebuttons/buttons';
|
||||||
import { ShareIconsModule } from 'ngx-sharebuttons/icons';
|
import { ShareIconsModule } from 'ngx-sharebuttons/icons';
|
||||||
import { MessagingService } from './services/messaging.service';
|
import { MessagingService } from './services/messaging.service';
|
||||||
import { NotFoundComponent } from './pages/not-found/not-found.component';
|
import { NotFoundComponent } from './pages/not-found/not-found.component';
|
||||||
import { DownloadAppDirective } from './directives/download-app.directive';
|
import { DownloadAppDirective } from './directives/download-app.directive';
|
||||||
import {MatIconModule} from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { GuestCardComponent } from './pages/guest-card/guest-card.component';
|
import { GuestCardComponent } from './pages/guest-card/guest-card.component';
|
||||||
import { QrCodeModule } from 'ng-qrcode';
|
import { QrCodeModule } from 'ng-qrcode';
|
||||||
import { AccordionComponent } from './components/accordion/accordion.component';
|
import { AccordionComponent } from './components/accordion/accordion.component';
|
||||||
@ -42,6 +42,16 @@ import { InviteFriendsComponent } from './components/invite-friends/invite-frien
|
|||||||
import { FooterComponent } from './components/footer/footer.component';
|
import { FooterComponent } from './components/footer/footer.component';
|
||||||
import { SocialMediaButtonsComponent } from './components/social-media-buttons/social-media-buttons.component';
|
import { SocialMediaButtonsComponent } from './components/social-media-buttons/social-media-buttons.component';
|
||||||
import { LoginComponent } from './pages/login/login.component';
|
import { LoginComponent } from './pages/login/login.component';
|
||||||
|
import { NgxMatIntlTelInputComponent } from 'ngx-mat-intl-tel-input';
|
||||||
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||||
|
import { MatInputModule } from '@angular/material/input';
|
||||||
|
import { FocusNextInputDirective } from './directives/focus-next-input.directive';
|
||||||
|
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||||
|
import {
|
||||||
|
MAT_BOTTOM_SHEET_DATA,
|
||||||
|
MatBottomSheetModule,
|
||||||
|
MatBottomSheetRef,
|
||||||
|
} from '@angular/material/bottom-sheet';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
@ -66,7 +76,8 @@ import { LoginComponent } from './pages/login/login.component';
|
|||||||
InviteFriendsComponent,
|
InviteFriendsComponent,
|
||||||
FooterComponent,
|
FooterComponent,
|
||||||
SocialMediaButtonsComponent,
|
SocialMediaButtonsComponent,
|
||||||
LoginComponent
|
LoginComponent,
|
||||||
|
FocusNextInputDirective,
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
@ -81,20 +92,31 @@ import { LoginComponent } from './pages/login/login.component';
|
|||||||
enabled: environment.production,
|
enabled: environment.production,
|
||||||
// Register the ServiceWorker as soon as the application is stable
|
// Register the ServiceWorker as soon as the application is stable
|
||||||
// or after 30 seconds (whichever comes first).
|
// or after 30 seconds (whichever comes first).
|
||||||
registrationStrategy: 'registerWhenStable:30000'
|
registrationStrategy: 'registerWhenStable:30000',
|
||||||
}),
|
}),
|
||||||
AngularFireModule.initializeApp(environment.firebase),
|
AngularFireModule.initializeApp(environment.firebase),
|
||||||
AngularFireMessagingModule,
|
AngularFireMessagingModule,
|
||||||
ToastModule,
|
ToastModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
ShareButtonsModule.withConfig({
|
ShareButtonsModule.withConfig({
|
||||||
debug: true
|
debug: true,
|
||||||
}),
|
}),
|
||||||
ShareIconsModule,
|
ShareIconsModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
QrCodeModule
|
QrCodeModule,
|
||||||
|
NgxMatIntlTelInputComponent,
|
||||||
|
MatFormFieldModule,
|
||||||
|
MatInputModule,
|
||||||
|
MatSnackBarModule,
|
||||||
|
MatBottomSheetModule,
|
||||||
],
|
],
|
||||||
providers: [DialogService, MessageService, MessagingService ],
|
providers: [
|
||||||
bootstrap: [AppComponent]
|
DialogService,
|
||||||
|
MessageService,
|
||||||
|
MessagingService,
|
||||||
|
{ provide: MatBottomSheetRef, useValue: {} },
|
||||||
|
{ provide: MAT_BOTTOM_SHEET_DATA, useValue: {} },
|
||||||
|
],
|
||||||
|
bootstrap: [AppComponent],
|
||||||
})
|
})
|
||||||
export class AppModule { }
|
export class AppModule {}
|
||||||
|
|||||||
@ -1,13 +1,7 @@
|
|||||||
<div>
|
<span class="example-pizza-party" matSnackBarLabel>
|
||||||
<H2>Вы действительно хотите выйти?</H2>
|
Вы действительно хотите выйти?
|
||||||
<button
|
</span>
|
||||||
class="woocommerce-button button"
|
<div class="buttons-container">
|
||||||
style="margin-right: 1rem"
|
<button mat-button (click)="rejection()" style="background: red;">Нет</button>
|
||||||
(click)="onClick(true)"
|
<button mat-button (click)="logout()">Да</button>
|
||||||
>
|
|
||||||
Да
|
|
||||||
</button>
|
|
||||||
<button class="woocommerce-button button" (click)="onClick(false)">
|
|
||||||
Нет
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,9 +1,22 @@
|
|||||||
|
:host {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.buttons-container {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
margin-right: 1rem;
|
padding: 10px 62px;
|
||||||
padding: 4px 21px;
|
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
background-color: var(--main-color);
|
background-color: var(--main-color);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
border: none;
|
border: none;
|
||||||
|
width: calc(50% - 12px);
|
||||||
}
|
}
|
||||||
@ -1,19 +1,21 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { DynamicDialogRef } from 'primeng/dynamicdialog';
|
import { MatBottomSheetRef } from '@angular/material/bottom-sheet';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-exit',
|
selector: 'app-exit',
|
||||||
templateUrl: './exit.component.html',
|
templateUrl: './exit.component.html',
|
||||||
styleUrls: ['./exit.component.scss']
|
styleUrls: ['./exit.component.scss'],
|
||||||
})
|
})
|
||||||
export class ExitComponent {
|
export class ExitComponent {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public dialogRef: DynamicDialogRef
|
private _bottomSheetRef: MatBottomSheetRef<ExitComponent>
|
||||||
) { }
|
) {}
|
||||||
|
|
||||||
onClick(val: boolean): void {
|
rejection() {
|
||||||
this.dialogRef.close(val);
|
this._bottomSheetRef.dismiss(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logout() {
|
||||||
|
this._bottomSheetRef.dismiss(true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<mat-icon aria-hidden="false" aria-label="Назад" fontIcon="arrow_back_ios" class="back-arrow"></mat-icon>
|
<mat-icon aria-hidden="false" aria-label="Назад" fontIcon="arrow_back_ios" class="back-arrow" (click)="back()"></mat-icon>
|
||||||
<h1 class="title">{{title}}</h1>
|
<h1 class="title">{{title}}</h1>
|
||||||
<div class="plug"></div>
|
<div class="plug"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,3 +1,7 @@
|
|||||||
|
:host {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: 12px 16px;
|
padding: 12px 16px;
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Component, Input, OnInit } from '@angular/core';
|
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-navbar[title]',
|
selector: 'app-navbar[title]',
|
||||||
@ -7,10 +7,15 @@ import { Component, Input, OnInit } from '@angular/core';
|
|||||||
})
|
})
|
||||||
export class NavbarComponent implements OnInit {
|
export class NavbarComponent implements OnInit {
|
||||||
@Input() title: string = 'Название не задано'
|
@Input() title: string = 'Название не задано'
|
||||||
|
@Output() backEvent = new EventEmitter<null>();
|
||||||
|
|
||||||
constructor() { }
|
constructor() { }
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
back() {
|
||||||
|
this.backEvent.emit(null)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,8 @@
|
|||||||
|
import { FocusNextInputDirective } from './focus-next-input.directive';
|
||||||
|
|
||||||
|
describe('FocusNextInputDirective', () => {
|
||||||
|
it('should create an instance', () => {
|
||||||
|
const directive = new FocusNextInputDirective();
|
||||||
|
expect(directive).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
23
angular/src/app/directives/focus-next-input.directive.ts
Normal file
23
angular/src/app/directives/focus-next-input.directive.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { Directive, EventEmitter, Input, Renderer2 } from '@angular/core';
|
||||||
|
|
||||||
|
@Directive({
|
||||||
|
selector: '[appFocusNextInput]'
|
||||||
|
})
|
||||||
|
export class FocusNextInputDirective {
|
||||||
|
@Input('appFocusNextInput') eventEmitter!: EventEmitter<string>;
|
||||||
|
|
||||||
|
constructor(private renderer: Renderer2) { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.eventEmitter.subscribe(elementId => {
|
||||||
|
try {
|
||||||
|
this.renderer.selectRootElement(elementId).focus();
|
||||||
|
this.renderer.selectRootElement(elementId).click();
|
||||||
|
} catch (ex) {
|
||||||
|
(document.activeElement as HTMLElement).blur();
|
||||||
|
// If the element doesn't exist or if the element disappears when this called then no need to do anything
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,134 +1,153 @@
|
|||||||
<app-navbar title="Карта гостя"></app-navbar>
|
<app-navbar title="Карта гостя" (backEvent)="logout()"></app-navbar>
|
||||||
<div class="guest-card">
|
|
||||||
<div class="guest-card__qr" (click)="qrCodeClick()">
|
<ng-container
|
||||||
<qr-code
|
*ngTemplateOutlet="appTpl; context: { user: customerInfo | async }"
|
||||||
value="9917997225"
|
></ng-container>
|
||||||
[margin]="0"
|
|
||||||
[size]="qrCodeSize"
|
<ng-template #appTpl let-user="user">
|
||||||
errorCorrectionLevel="M"
|
<div class="guest-card">
|
||||||
></qr-code>
|
<div class="guest-card__qr" (click)="qrCodeClick()">
|
||||||
|
<qr-code
|
||||||
|
[value]="user?.customer_info?.phone.substr(2) || 'Данные не найдены'"
|
||||||
|
[margin]="0"
|
||||||
|
[size]="qrCodeSize"
|
||||||
|
errorCorrectionLevel="M"
|
||||||
|
></qr-code>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="guest-card__user-description">
|
||||||
|
За период с 11.01.2023 по 31.03.2023 вам начислено
|
||||||
|
<span>360 бонусов</span>
|
||||||
|
</div>
|
||||||
|
<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">
|
||||||
|
Сумма ваших покупок за период с 01.04.2023г. - <span>1200 руб.</span>
|
||||||
|
</div>
|
||||||
|
<app-accordion header="Узнать % начисляемых бонусов">
|
||||||
|
<p>
|
||||||
|
Начисление Бонусных баллов происходит по дифференцированной шкале в
|
||||||
|
зависимости от уровня:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<span style="color: #f2c94c">Уровень 1</span>
|
||||||
|
<li>Сумма покупок за предыдущий период 0-1600 руб.</li>
|
||||||
|
<li>Начисляемый бонус 3% от суммы покупки</li>
|
||||||
|
</ul>
|
||||||
|
<br />
|
||||||
|
<ul>
|
||||||
|
<span style="color: #f2994a">Уровень 2</span>
|
||||||
|
<li>Сумма покупок за предыдущий период 1601-3600 руб.</li>
|
||||||
|
<li>Начисляемый бонус 6% от суммы покупки</li>
|
||||||
|
</ul>
|
||||||
|
<br />
|
||||||
|
<ul>
|
||||||
|
<span style="color: #6fcf97">Уровень 3</span>
|
||||||
|
<li>Сумма покупок за предыдущий период 3601-8600 руб.</li>
|
||||||
|
<li>Начисляемый бонус 10% от суммы покупки</li>
|
||||||
|
</ul>
|
||||||
|
<br />
|
||||||
|
<ul>
|
||||||
|
<span style="color: #6fcf97">Уровень 4</span>
|
||||||
|
<li>Сумма покупок за предыдущий период — от 8601 руб.</li>
|
||||||
|
<li>Начисляемый бонус, в % от суммы покупки - 15%</li>
|
||||||
|
</ul>
|
||||||
|
</app-accordion>
|
||||||
|
|
||||||
|
<div class="guest-card__level-info">
|
||||||
|
<h2>
|
||||||
|
До следующего уровня за период с 01.04.2023 по 30.06.2023г осталось
|
||||||
|
совершить покупки на 401 рублей
|
||||||
|
</h2>
|
||||||
|
<input
|
||||||
|
type="range"
|
||||||
|
[(ngModel)]="discountLevel"
|
||||||
|
[min]="3"
|
||||||
|
[max]="6"
|
||||||
|
[step]="0.1"
|
||||||
|
[ngStyle]="{
|
||||||
|
'background-size': ((discountLevel - 3) / (6 - 3)) * 100 + '% 100%'
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<p class="show-more">Узнать условия начисления бонусов</p>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<app-last-order></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>
|
</div>
|
||||||
<div class="guest-card__user-description">
|
</ng-template>
|
||||||
За период с 11.01.2023 по 31.03.2023 вам начислено <span>360 бонусов</span>
|
|
||||||
</div>
|
|
||||||
<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">
|
|
||||||
Сумма ваших покупок за период с 01.04.2023г. - <span>1200 руб.</span>
|
|
||||||
</div>
|
|
||||||
<app-accordion header="Узнать % начисляемых бонусов">
|
|
||||||
<p>
|
|
||||||
Начисление Бонусных баллов происходит по дифференцированной шкале в
|
|
||||||
зависимости от уровня:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<span style="color: #f2c94c">Уровень 1</span>
|
|
||||||
<li>Сумма покупок за предыдущий период 0-1600 руб.</li>
|
|
||||||
<li>Начисляемый бонус 3% от суммы покупки</li>
|
|
||||||
</ul>
|
|
||||||
<br />
|
|
||||||
<ul>
|
|
||||||
<span style="color: #f2994a">Уровень 2</span>
|
|
||||||
<li>Сумма покупок за предыдущий период 1601-3600 руб.</li>
|
|
||||||
<li>Начисляемый бонус 6% от суммы покупки</li>
|
|
||||||
</ul>
|
|
||||||
<br />
|
|
||||||
<ul>
|
|
||||||
<span style="color: #6fcf97">Уровень 3</span>
|
|
||||||
<li>Сумма покупок за предыдущий период 3601-8600 руб.</li>
|
|
||||||
<li>Начисляемый бонус 10% от суммы покупки</li>
|
|
||||||
</ul>
|
|
||||||
<br />
|
|
||||||
<ul>
|
|
||||||
<span style="color: #6fcf97">Уровень 4</span>
|
|
||||||
<li>Сумма покупок за предыдущий период — от 8601 руб.</li>
|
|
||||||
<li>Начисляемый бонус, в % от суммы покупки - 15%</li>
|
|
||||||
</ul>
|
|
||||||
</app-accordion>
|
|
||||||
|
|
||||||
<div class="guest-card__level-info">
|
|
||||||
<h2>
|
|
||||||
До следующего уровня за период с 01.04.2023 по 30.06.2023г осталось
|
|
||||||
совершить покупки на 401 рублей
|
|
||||||
</h2>
|
|
||||||
<input type="range" [(ngModel)]="discountLevel" [min]="3" [max]="6" [step]="0.1" [ngStyle]="{
|
|
||||||
'background-size': (discountLevel - 3) / (6 - 3) * 100 + '% 100%'
|
|
||||||
}">
|
|
||||||
|
|
||||||
<p class="show-more">Узнать условия начисления бонусов</p>
|
|
||||||
</div>
|
|
||||||
<hr>
|
|
||||||
<app-last-order></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>
|
|
||||||
|
|||||||
@ -1,5 +1,16 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { IAccordionData } from 'src/app/components/accordion/accordion.component';
|
import { MatBottomSheet } from '@angular/material/bottom-sheet';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { ExitComponent } from 'src/app/components/exit/exit.component';
|
||||||
|
import { CookiesService } from 'src/app/services/cookies.service';
|
||||||
|
import { WpJsonService } from 'src/app/services/wp-json.service';
|
||||||
|
import { environment } from 'src/environments/environment';
|
||||||
|
import moment from 'moment';
|
||||||
|
|
||||||
|
interface Moment extends moment.Moment {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-guest-card',
|
selector: 'app-guest-card',
|
||||||
@ -9,15 +20,49 @@ import { IAccordionData } from 'src/app/components/accordion/accordion.component
|
|||||||
export class GuestCardComponent implements OnInit {
|
export class GuestCardComponent implements OnInit {
|
||||||
public qrCodeSize: number = 85;
|
public qrCodeSize: number = 85;
|
||||||
private isQrCodeClicked: boolean = false;
|
private isQrCodeClicked: boolean = false;
|
||||||
|
public customerInfo!: Observable<any>;
|
||||||
|
public purchases!: Observable<any>;
|
||||||
|
|
||||||
public discountLevel: number = 4.2;
|
public discountLevel: number = 4.2;
|
||||||
|
|
||||||
constructor() {}
|
constructor(
|
||||||
|
private _bottomSheet: MatBottomSheet,
|
||||||
|
private cookiesService: CookiesService,
|
||||||
|
private router: Router,
|
||||||
|
private wpJsonService: WpJsonService
|
||||||
|
) {}
|
||||||
|
|
||||||
ngOnInit(): void {}
|
ngOnInit(): void {
|
||||||
|
const token = this.cookiesService.getItem('token')
|
||||||
|
this.customerInfo = this.wpJsonService.getCustomerInfo(environment.systemId, token || '', environment.icardProxy)
|
||||||
|
this.purchases = this.getPurchases()
|
||||||
|
// this.purchases.subscribe((value) => console.log(value));
|
||||||
|
}
|
||||||
|
|
||||||
qrCodeClick() {
|
qrCodeClick() {
|
||||||
this.isQrCodeClicked = !this.isQrCodeClicked;
|
this.isQrCodeClicked = !this.isQrCodeClicked;
|
||||||
this.qrCodeSize = this.isQrCodeClicked ? 180 : 85;
|
this.qrCodeSize = this.isQrCodeClicked ? 180 : 85;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deleteToken(): void {
|
||||||
|
this.cookiesService.deleteCookie('token');
|
||||||
|
}
|
||||||
|
|
||||||
|
logout() {
|
||||||
|
const bottomSheet = this._bottomSheet.open(ExitComponent)
|
||||||
|
bottomSheet.afterDismissed().subscribe({
|
||||||
|
next: (val) => {
|
||||||
|
if (val) {
|
||||||
|
this.deleteToken();
|
||||||
|
this.router.navigate(['/login']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
getPurchases(start: Date | Moment = moment().startOf('month'), end: Date | Moment = moment()): Observable<any> {
|
||||||
|
const token = this.cookiesService.getItem('token')
|
||||||
|
const delta = moment(end).diff(moment(start), 'days')
|
||||||
|
return this.wpJsonService.getTransactionsInfo(environment.systemId, token ?? '', environment.icardProxy)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,26 +1,99 @@
|
|||||||
|
<app-navbar
|
||||||
|
*ngIf="phoneForm.value.phone && !isShowNumber"
|
||||||
|
[title]="phoneForm.value.phone"
|
||||||
|
(backEvent)="backToPhoneForm()"
|
||||||
|
[ngStyle]="{
|
||||||
|
position: 'absolute',
|
||||||
|
top: 0
|
||||||
|
}"
|
||||||
|
></app-navbar>
|
||||||
<h1>Участвуй в программе лояльности COFFEE LIKE</h1>
|
<h1>Участвуй в программе лояльности COFFEE LIKE</h1>
|
||||||
<p class="description">Начни получать бонусы прямо сейчас</p>
|
<p class="description">Начни получать бонусы прямо сейчас</p>
|
||||||
<form *ngIf="isShowNumber; else smsCode" (ngSubmit)="submitNumber()" action="">
|
<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">
|
<div class="input-container">
|
||||||
<label for="name">Ваше имя</label>
|
<!-- <label for="number">Номер телефона</label>
|
||||||
<input id="name" type="text" placeholder="Введите ваше имя" />
|
<input id="number" type="text" placeholder="Введите номер" /> -->
|
||||||
</div>
|
<mat-form-field appearance="outline">
|
||||||
<div class="input-container">
|
<mat-label>Номер телефона</mat-label>
|
||||||
<label for="number">Номер телефона</label>
|
<ngx-mat-intl-tel-input
|
||||||
<input id="number" type="text" placeholder="Введите номер" />
|
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>
|
</div>
|
||||||
<p class="offer">
|
<p class="offer">
|
||||||
Используя приложение, вы принимаете условия в <span>соглашениях</span> и
|
Используя приложение, вы принимаете условия в <span>соглашениях</span> и
|
||||||
соглашаетесь на получение рекламно-информационных сообщений
|
соглашаетесь на получение рекламно-информационных сообщений
|
||||||
</p>
|
</p>
|
||||||
<button>Принять участие</button>
|
<button [disabled]="phoneForm.invalid">Принять участие</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<ng-template #smsCode>
|
<ng-template #smsCode>
|
||||||
<h2>Введите код из SMS</h2>
|
<h2>Введите код из SMS</h2>
|
||||||
<form class="code-form" action="" (ngSubmit)="submitCode()">
|
<form class="code-form" [formGroup]="codeForm" (ngSubmit)="submitCode()">
|
||||||
<input type="text" placeholder="Код" />
|
<div class="inputs-container">
|
||||||
|
<label class="box"
|
||||||
|
><input
|
||||||
|
class="field"
|
||||||
|
id="field"
|
||||||
|
type="tel"
|
||||||
|
placeholder="•"
|
||||||
|
#field
|
||||||
|
[appFocusNextInput]="inputFocusEmitter"
|
||||||
|
formControlName="code"
|
||||||
|
maxlength="1"
|
||||||
|
/></label>
|
||||||
|
<label class="box"
|
||||||
|
><input
|
||||||
|
class="field"
|
||||||
|
id="field1"
|
||||||
|
type="tel"
|
||||||
|
placeholder="•"
|
||||||
|
#field1
|
||||||
|
[appFocusNextInput]="inputFocusEmitter"
|
||||||
|
formControlName="code1"
|
||||||
|
maxlength="1"
|
||||||
|
/></label>
|
||||||
|
<label class="box"
|
||||||
|
><input
|
||||||
|
class="field"
|
||||||
|
id="field2"
|
||||||
|
type="tel"
|
||||||
|
placeholder="•"
|
||||||
|
#field2
|
||||||
|
[appFocusNextInput]="inputFocusEmitter"
|
||||||
|
formControlName="code2"
|
||||||
|
maxlength="1"
|
||||||
|
/></label>
|
||||||
|
<label class="box"
|
||||||
|
><input
|
||||||
|
class="field"
|
||||||
|
id="field3"
|
||||||
|
type="tel"
|
||||||
|
placeholder="•"
|
||||||
|
#field3
|
||||||
|
[appFocusNextInput]="inputFocusEmitter"
|
||||||
|
formControlName="code3"
|
||||||
|
maxlength="1"
|
||||||
|
/></label>
|
||||||
|
</div>
|
||||||
<button>Войти</button>
|
<button>Войти</button>
|
||||||
</form>
|
</form>
|
||||||
<p class="resend-code" >Не пришло SMS?<br>Отправим повторно через секунд</p>
|
<p class="resend-code">Не пришло SMS?<br />Отправим повторно через секунд</p>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
margin: 0 auto 52px;
|
margin: 0 auto 52px;
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
|
margin-top: 20px;
|
||||||
width: 302px;
|
width: 302px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
@ -106,24 +107,92 @@
|
|||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
font-size: 17px;
|
font-size: 17px;
|
||||||
line-height: 22px;
|
line-height: 22px;
|
||||||
|
&:disabled {
|
||||||
|
background-color: #344a3a;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.code-form {
|
.code-form {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
input {
|
// input {
|
||||||
width: 100%;
|
// width: 100%;
|
||||||
padding: 24px 16px 8px;
|
// padding: 24px 16px 8px;
|
||||||
background-color: #252323;
|
// background-color: #252323;
|
||||||
margin-bottom: 16px;
|
// margin-bottom: 16px;
|
||||||
border: none;
|
// border: none;
|
||||||
border-top: solid #6a737c 1px;
|
// border-top: solid #6a737c 1px;
|
||||||
border-bottom: solid #6a737c 1px;
|
// border-bottom: solid #6a737c 1px;
|
||||||
color: #6a737c;
|
// color: #6a737c;
|
||||||
font-style: normal;
|
// font-style: normal;
|
||||||
font-weight: 400;
|
// font-weight: 400;
|
||||||
font-size: 22px;
|
// font-size: 22px;
|
||||||
line-height: 28px;
|
// line-height: 28px;
|
||||||
|
// }
|
||||||
|
.inputs-container {
|
||||||
|
width: 102px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
|
||||||
|
// code
|
||||||
|
.box {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 42px;
|
||||||
|
width: 42px;
|
||||||
|
border-radius: 6px;
|
||||||
|
// box-shadow: 0 0 6px 1px hsla(240, 54%, 61%, 0.2);
|
||||||
|
overflow: hidden;
|
||||||
|
will-change: transform;
|
||||||
|
}
|
||||||
|
.box:focus-within {
|
||||||
|
box-shadow: 0 0 6px 1px rgba($color: #28af49, $alpha: 0.2),
|
||||||
|
0 0 0 2px rgba($color: #28af49, $alpha: 0.6);
|
||||||
|
}
|
||||||
|
.box::before,
|
||||||
|
.box::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
border-radius: 6px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.box::before {
|
||||||
|
// background: hsl(240, 54%, 97%);
|
||||||
|
z-index: 1;
|
||||||
|
transition: background-color 450ms cubic-bezier(0.25, 0.01, 0.25, 1);
|
||||||
|
}
|
||||||
|
.box::after {
|
||||||
|
transform: translateY(100%);
|
||||||
|
background-color: hsl(145, 0%, 42%);
|
||||||
|
opacity: 0;
|
||||||
|
z-index: 10;
|
||||||
|
transition: transform 450ms cubic-bezier(0.25, 0.01, 0.25, 1),
|
||||||
|
opacity 450ms cubic-bezier(0.25, 0.01, 0.25, 1),
|
||||||
|
background-color 450ms cubic-bezier(0.25, 0.01, 0.25, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.field {
|
||||||
|
position: relative;
|
||||||
|
border: 0;
|
||||||
|
outline: 0;
|
||||||
|
font-size: 25.21px;
|
||||||
|
line-height: 42px;
|
||||||
|
color: #fff;
|
||||||
|
background-color: transparent;
|
||||||
|
text-align: center;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
.field::placeholder {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,5 +202,10 @@
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
line-height: 16px;
|
line-height: 16px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
margin-top: 23px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mat-form-field {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|||||||
@ -1,25 +1,158 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import {
|
||||||
|
AfterViewInit,
|
||||||
|
Component,
|
||||||
|
EventEmitter,
|
||||||
|
HostListener,
|
||||||
|
OnInit
|
||||||
|
} from '@angular/core';
|
||||||
|
import { FormControl, FormGroup, Validators } from '@angular/forms';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
|
import { MessageService } from 'primeng/api';
|
||||||
import { CookiesService } from 'src/app/services/cookies.service';
|
import { CookiesService } from 'src/app/services/cookies.service';
|
||||||
|
import { JsonrpcService, RpcService } from 'src/app/services/jsonrpc.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-login',
|
selector: 'app-login',
|
||||||
templateUrl: './login.component.html',
|
templateUrl: './login.component.html',
|
||||||
styleUrls: ['./login.component.scss'],
|
styleUrls: ['./login.component.scss'],
|
||||||
})
|
})
|
||||||
export class LoginComponent implements OnInit {
|
export class LoginComponent implements OnInit, AfterViewInit {
|
||||||
isShowNumber: boolean = true;
|
public isShowNumber: boolean = true;
|
||||||
|
public phoneForm = new FormGroup({
|
||||||
|
name: new FormControl('', [Validators.required]),
|
||||||
|
phone: new FormControl('', [Validators.required]),
|
||||||
|
});
|
||||||
|
public codeForm = new FormGroup({
|
||||||
|
code: new FormControl('', [Validators.required]),
|
||||||
|
code1: new FormControl('', [Validators.required]),
|
||||||
|
code2: new FormControl('', [Validators.required]),
|
||||||
|
code3: new FormControl('', [Validators.required]),
|
||||||
|
});
|
||||||
|
private inputIds = ['field', 'field1', 'field2', 'field3'];
|
||||||
|
|
||||||
constructor(private cookiesService: CookiesService, private router: Router) {}
|
constructor(
|
||||||
|
private cookiesService: CookiesService,
|
||||||
|
private router: Router,
|
||||||
|
private jsonrpc: JsonrpcService,
|
||||||
|
private messageService: MessageService
|
||||||
|
) {}
|
||||||
|
|
||||||
ngOnInit(): void {}
|
ngOnInit(): void {}
|
||||||
|
|
||||||
|
ngAfterViewInit() {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.inputFocusEmitter.emit(`#${this.inputIds[0]}`);
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
public inputFocusEmitter = new EventEmitter<string>();
|
||||||
|
|
||||||
|
@HostListener('window:keyup', ['$event'])
|
||||||
|
HandlKeyEvents(event: any) {
|
||||||
|
if (!event.target.classList.contains('field')) return;
|
||||||
|
const key = event.key.toLocaleLowerCase();
|
||||||
|
let elementId = '';
|
||||||
|
|
||||||
|
switch (key) {
|
||||||
|
case 'backspace':
|
||||||
|
elementId = event.target.id;
|
||||||
|
event.target.value = '';
|
||||||
|
const prevInputIndex = this.inputIds.indexOf(elementId) - 1;
|
||||||
|
if (prevInputIndex >= 0) {
|
||||||
|
this.inputFocusEmitter.emit(`#${this.inputIds[prevInputIndex]}`);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
elementId = event.target.id;
|
||||||
|
const index = this.inputIds.indexOf(elementId);
|
||||||
|
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]}`);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
submitNumber() {
|
submitNumber() {
|
||||||
|
const data = this.phoneForm.value;
|
||||||
|
console.log(data);
|
||||||
this.isShowNumber = false;
|
this.isShowNumber = false;
|
||||||
|
this.jsonrpc.rpc({
|
||||||
|
method: 'sendVerifyByPhone',
|
||||||
|
params: [data.phone]
|
||||||
|
}, RpcService.authService, false).subscribe({
|
||||||
|
next: (result) => {
|
||||||
|
if (result.code === -1) {
|
||||||
|
this.messageService.add({
|
||||||
|
severity: 'error',
|
||||||
|
summary: 'Произошла ошибка, попробуйте позже!',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// if (result.code === 0) {
|
||||||
|
// this.isCodeConfirm = true;
|
||||||
|
// this.timeLeft = 60;
|
||||||
|
// const interval = setInterval(() => {
|
||||||
|
// if(this.timeLeft > 0) {
|
||||||
|
// this.timeLeft--;
|
||||||
|
// } else {
|
||||||
|
// clearInterval(interval);
|
||||||
|
// }
|
||||||
|
// },1000)
|
||||||
|
// }
|
||||||
|
// this.loading = false;
|
||||||
|
this.isShowNumber = false;
|
||||||
|
},
|
||||||
|
error: (error) => {
|
||||||
|
console.error('Error: ', error);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
setTimeout(() => {
|
||||||
|
this.inputFocusEmitter.emit(`#${this.inputIds[0]}`);
|
||||||
|
}, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
submitCode() {
|
submitCode() {
|
||||||
this.cookiesService.setCookie('token', 'test')
|
const data = this.codeForm.value;
|
||||||
this.router.navigate(['/'])
|
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.phoneConfirmed.emit(null);
|
||||||
|
} else {
|
||||||
|
// this.errorConfirmCode = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: (error) => {
|
||||||
|
console.error(error);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
backToPhoneForm() {
|
||||||
|
this.codeForm.setValue({
|
||||||
|
code: '',
|
||||||
|
code1: '',
|
||||||
|
code2: '',
|
||||||
|
code3: ''
|
||||||
|
})
|
||||||
|
this.isShowNumber = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,7 +42,27 @@ export class WpJsonService {
|
|||||||
return this._request(`products/${id}`, 'GET');
|
return this._request(`products/${id}`, 'GET');
|
||||||
}
|
}
|
||||||
|
|
||||||
_request(path: string, method: string, body?: any, auth = false): Observable<any> {
|
getCustomerInfo(systemId: string, token: string, url: string): Observable<any> {
|
||||||
|
return this._request(`customer_info/${systemId}/${token}/`, 'GET', null, false, url)
|
||||||
|
}
|
||||||
|
|
||||||
|
getTransactions(systemId: string, token: string, url: string, delta?: number): Observable<any> {
|
||||||
|
return this._request(`trans/${systemId}/${token}/${delta || ''}`, 'GET', null, false, url)
|
||||||
|
}
|
||||||
|
|
||||||
|
getTransactionsInfo(systemId: string, token: string, url: string, delta?: number): Observable<any> {
|
||||||
|
return this._request(`purchase/${systemId}/${token}/${delta || ''}`, 'GET', null, false, url)
|
||||||
|
}
|
||||||
|
|
||||||
|
// getSiteConfig(): Observable<any> {
|
||||||
|
// return this._request(`/assets/site-config.json`, 'GET', null, false)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// getSiteConfigFromIiko(): Observable<any> {
|
||||||
|
// return this._request(`/static/settings.json`, 'GET', null, false)
|
||||||
|
// }
|
||||||
|
|
||||||
|
_request(path: string, method: string, body?: any, auth = false, baseUrl?: string): Observable<any> {
|
||||||
const token = decodeURI(this.cookiesService.getItem('token') ?? '');
|
const token = decodeURI(this.cookiesService.getItem('token') ?? '');
|
||||||
let headers = new HttpHeaders();
|
let headers = new HttpHeaders();
|
||||||
headers = headers.set('Content-Type', 'application/json');
|
headers = headers.set('Content-Type', 'application/json');
|
||||||
@ -56,8 +76,10 @@ export class WpJsonService {
|
|||||||
body: this.body,
|
body: this.body,
|
||||||
};
|
};
|
||||||
|
|
||||||
const url = environment.production ? window.location.origin + '/wp-json/woofood/v1/' : this.api
|
let url = environment.production ? window.location.origin + '/' : this.api
|
||||||
|
if (baseUrl) {
|
||||||
|
url = baseUrl
|
||||||
|
}
|
||||||
return this.http
|
return this.http
|
||||||
.request( method, url + path + urlToken, options);
|
.request( method, url + path + urlToken, options);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ export const environment = {
|
|||||||
appBonusEndpoint: 'https://customerapi2.mi.crm4retail.ru/json.rpc/',
|
appBonusEndpoint: 'https://customerapi2.mi.crm4retail.ru/json.rpc/',
|
||||||
appWPEndpoint: 'http://213.239.210.240:4500/wp-json/woofood/v1/',
|
appWPEndpoint: 'http://213.239.210.240:4500/wp-json/woofood/v1/',
|
||||||
hasBonusProgram: true,
|
hasBonusProgram: true,
|
||||||
systemId: 'g6zyv8tj53w28ov7cl',
|
systemId: 'tsQ2cu59Xz9qgGTm3z',
|
||||||
defaultUrl: 'https://coffee-like.lk.crm4retail.ru',
|
defaultUrl: 'https://coffee-like.lk.crm4retail.ru',
|
||||||
firebase: {
|
firebase: {
|
||||||
apiKey: "AIzaSyCnKvln5itnrBj62POCPHxshAN_Vmd0zds",
|
apiKey: "AIzaSyCnKvln5itnrBj62POCPHxshAN_Vmd0zds",
|
||||||
@ -19,6 +19,7 @@ export const environment = {
|
|||||||
},
|
},
|
||||||
version: packageJson.version,
|
version: packageJson.version,
|
||||||
appleWalletEndpoint: 'https://apple-push-notifications.it-retail.tech/apns/api',
|
appleWalletEndpoint: 'https://apple-push-notifications.it-retail.tech/apns/api',
|
||||||
|
icardProxy: 'https://coffee-like.lk.crm4retail.ru/api/icard-proxy/',
|
||||||
appleWalletSecret: 'Token F5mbzEERAznGKVbB6l',
|
appleWalletSecret: 'Token F5mbzEERAznGKVbB6l',
|
||||||
clientName: 'coffeeLike'
|
clientName: 'coffeeLike'
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ export const environment = {
|
|||||||
appBonusEndpoint: 'https://customerapi2.mi.crm4retail.ru/json.rpc/',
|
appBonusEndpoint: 'https://customerapi2.mi.crm4retail.ru/json.rpc/',
|
||||||
appWPEndpoint: 'http://192.168.0.179:4200/wp-json/woofood/v1/',
|
appWPEndpoint: 'http://192.168.0.179:4200/wp-json/woofood/v1/',
|
||||||
hasBonusProgram: true,
|
hasBonusProgram: true,
|
||||||
systemId: 'g6zyv8tj53w28ov7cl',
|
systemId: 'tsQ2cu59Xz9qgGTm3z',
|
||||||
defaultUrl: 'http://192.168.0.179:4200',
|
defaultUrl: 'http://192.168.0.179:4200',
|
||||||
firebase: {
|
firebase: {
|
||||||
apiKey: 'AIzaSyCnKvln5itnrBj62POCPHxshAN_Vmd0zds',
|
apiKey: 'AIzaSyCnKvln5itnrBj62POCPHxshAN_Vmd0zds',
|
||||||
@ -19,6 +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/',
|
||||||
appleWalletSecret: 'Token F5mbzEERAznGKVbB6l',
|
appleWalletSecret: 'Token F5mbzEERAznGKVbB6l',
|
||||||
clientName: 'coffeeLike'
|
clientName: 'coffeeLike'
|
||||||
};
|
};
|
||||||
|
|||||||
@ -30,6 +30,55 @@ hr {
|
|||||||
border-top: 1px solid#BDBDBD;
|
border-top: 1px solid#BDBDBD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mat-form-field-wrapper {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-form-field-outline-start, .mat-form-field-outline-end {
|
||||||
|
border-radius: 0 !important;
|
||||||
|
}
|
||||||
|
.mat-form-field-outline-start {
|
||||||
|
border-left: none !important;
|
||||||
|
}
|
||||||
|
.mat-form-field-outline-end {
|
||||||
|
border-right: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-focused .mat-form-field-outline > div {
|
||||||
|
border-color: #28af49;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-focused .mat-form-field-label {
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-form-field-invalid .mat-form-field-outline > div {
|
||||||
|
border-color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.country-list-button {
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-menu-panel {
|
||||||
|
background: #231f20;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.country-selector {
|
||||||
|
opacity: 1 !important;
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngx-floating .country-selector {
|
||||||
|
display: block !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.country-selector-code {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
qr-code canvas {
|
qr-code canvas {
|
||||||
transition: all 0.3s ease 0s;
|
transition: all 0.3s ease 0s;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user