перевел некоторые элементы с primeNG на AngularMaterial, так как в первое случае были баги с айфоном
добавил отображение описания в карточке товара,
подтянул имя при оформлении заказа,
добавил список терминалов при оформлении заказа, по умолчанию показывается активный терминал в disabled=true
This commit is contained in:
gofnnp 2023-02-27 22:49:33 +04:00
parent ed2e73e598
commit 10ad10d922
26 changed files with 646 additions and 321 deletions

View File

@ -34,7 +34,7 @@
"src/firebase-messaging-sw.js" "src/firebase-messaging-sw.js"
], ],
"styles": [ "styles": [
"./node_modules/@angular/material/prebuilt-themes/pink-bluegrey.css", "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
"node_modules/mdb-angular-ui-kit/assets/scss/mdb.scss", "node_modules/mdb-angular-ui-kit/assets/scss/mdb.scss",
"node_modules/primeng/resources/themes/saga-blue/theme.css", "node_modules/primeng/resources/themes/saga-blue/theme.css",
"node_modules/primeicons/primeicons.css", "node_modules/primeicons/primeicons.css",
@ -114,7 +114,7 @@
"src/manifest.webmanifest" "src/manifest.webmanifest"
], ],
"styles": [ "styles": [
"./node_modules/@angular/material/prebuilt-themes/pink-bluegrey.css", "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
"src/styles.scss" "src/styles.scss"
], ],
"scripts": [] "scripts": []

View File

@ -1,23 +1,20 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { PrimeNGConfig } from 'primeng/api'; import { PrimeNGConfig } from 'primeng/api';
import * as ConfigActions from './state/config/config.actions' import * as ConfigActions from './state/config/config.actions';
@Component({ @Component({
selector: 'app-root', selector: 'app-root',
templateUrl: './app.component.html', templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'] styleUrls: ['./app.component.scss'],
}) })
export class AppComponent implements OnInit { export class AppComponent implements OnInit {
title = 'Sakura'; title = 'Sakura';
constructor(private primengConfig: PrimeNGConfig, constructor(private primengConfig: PrimeNGConfig, private store: Store) {}
private store: Store) {}
ngOnInit() { ngOnInit() {
this.primengConfig.ripple = true; this.primengConfig.ripple = false;
this.store.dispatch(ConfigActions.getConfig()); this.store.dispatch(ConfigActions.getConfig());
} }
} }

View File

@ -60,6 +60,15 @@ import {MatTabsModule} from '@angular/material/tabs';
import { ModifierComponent } from './components/modifier/modifier.component'; import { ModifierComponent } from './components/modifier/modifier.component';
import { OptionComponent } from './components/option/option.component'; import { OptionComponent } from './components/option/option.component';
import { ChangeQuantityOptionDirective } from './directives/change-quantity-option.directive'; import { ChangeQuantityOptionDirective } from './directives/change-quantity-option.directive';
import {MatSelectModule} from '@angular/material/select';
import {MatFormFieldModule, MAT_FORM_FIELD_DEFAULT_OPTIONS} from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import {MatBottomSheetModule} from '@angular/material/bottom-sheet';
import { TerminalListComponent } from './components/terminal-list/terminal-list.component';
import {MatButtonModule} from '@angular/material/button';
import {MatListModule} from '@angular/material/list';
import {MatSnackBarModule} from '@angular/material/snack-bar';
import { SnackBarComponent } from './components/snack-bar/snack-bar.component';
const routes: Routes = [ const routes: Routes = [
{ path: '', redirectTo: 'products', pathMatch: 'full' }, { path: '', redirectTo: 'products', pathMatch: 'full' },
@ -95,7 +104,9 @@ const routes: Routes = [
MenuComponent, MenuComponent,
ModifierComponent, ModifierComponent,
OptionComponent, OptionComponent,
ChangeQuantityOptionDirective ChangeQuantityOptionDirective,
TerminalListComponent,
SnackBarComponent
], ],
imports: [ imports: [
BrowserModule, BrowserModule,
@ -137,9 +148,16 @@ const routes: Routes = [
InputTextModule, InputTextModule,
SidebarModule, SidebarModule,
RippleModule, RippleModule,
MatTabsModule MatTabsModule,
MatSelectModule,
MatFormFieldModule,
MatInputModule,
MatBottomSheetModule,
MatButtonModule,
MatListModule,
MatSnackBarModule
], ],
providers: [DialogService, MessageService, MessagingService ], providers: [DialogService, MessageService, MessagingService, {provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, useValue: {appearance: 'outline'}} ],
bootstrap: [AppComponent] bootstrap: [AppComponent]
}) })
export class AppModule { } export class AppModule { }

View File

@ -1,3 +1,5 @@
@import "src/sass/mixins";
:host { :host {
.main-menu-container { .main-menu-container {
// position: fixed; // position: fixed;
@ -41,7 +43,7 @@
} }
} }
&:hover { @include hover-supported() {
color: #252525; color: #252525;
a { a {

View File

@ -8,7 +8,7 @@
}}" }}"
alt="{{ product.name }}" alt="{{ product.name }}"
/> />
<p class="product-modal__description">Lorem ipsum dolor sit amet consectetur adipisicing elit. Quasi quas libero consequatur dolorum itaque dolor deserunt aut facilis debitis!</p> <p class="product-modal__description">{{product.description}}</p>
</div> </div>
<div <div

View File

@ -0,0 +1,16 @@
<div class="snack-bar">
<span>{{ data.text }}</span>
<div class="buttons">
<button mat-stroked-button matSnackBarAction (click)="buttonClick('no')">
Нет
</button>
<button
mat-stroked-button
matSnackBarAction
color="error"
(click)="buttonClick('yes')"
>
Да
</button>
</div>
</div>

View File

@ -0,0 +1,18 @@
:host {
.snack-bar {
display: flex;
align-items: center;
justify-content: space-between;
span {
color: #323232;
}
.buttons {
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: nowrap;
flex-direction: row;
gap: 8px;
}
}
}

View File

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { SnackBarComponent } from './snack-bar.component';
describe('SnackBarComponent', () => {
let component: SnackBarComponent;
let fixture: ComponentFixture<SnackBarComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ SnackBarComponent ]
})
.compileComponents();
fixture = TestBed.createComponent(SnackBarComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,23 @@
import { Component, Inject, OnInit } from '@angular/core';
import { MatSnackBarRef, MAT_SNACK_BAR_DATA } from '@angular/material/snack-bar';
@Component({
selector: 'app-snack-bar',
templateUrl: './snack-bar.component.html',
styleUrls: ['./snack-bar.component.scss']
})
export class SnackBarComponent implements OnInit {
constructor(@Inject(MAT_SNACK_BAR_DATA) public data: {text: string}, private _matSnackBarRef: MatSnackBarRef<SnackBarComponent>) { }
ngOnInit(): void {
}
buttonClick(result: 'yes' | 'no') {
if (result === 'yes') {
this._matSnackBarRef.dismissWithAction()
} else {
this._matSnackBarRef.dismiss()
}
}
}

View File

@ -0,0 +1,13 @@
<mat-nav-list>
<div
mat-list-item
*ngFor="let item of data.list"
[ngClass]="{
'list-item': true,
active: item.id === data.active.id
}"
(click)="selectItem(item)"
>
<span matListItemTitle>{{ item.label }}</span>
</div>
</mat-nav-list>

View File

@ -0,0 +1,21 @@
@import 'src/sass/mixins';
:host {
.list-item {
padding: 12px;
font-size: 14px;
border-radius: 6px;
transition: all .4s ease;
text-align: center;
font-weight: 600;
cursor: pointer;
&.active {
background-color: var(--orange-main);
color: #fff;
}
@include hover-supported() {
background-color: #eee;
color: #000;
}
}
}

View File

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { TerminalListComponent } from './terminal-list.component';
describe('TerminalListComponent', () => {
let component: TerminalListComponent;
let fixture: ComponentFixture<TerminalListComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ TerminalListComponent ]
})
.compileComponents();
fixture = TestBed.createComponent(TerminalListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,25 @@
import { Component, Inject, OnInit } from '@angular/core';
import { MatBottomSheetRef, MAT_BOTTOM_SHEET_DATA } from '@angular/material/bottom-sheet';
export interface IListData {
list: Array<any>;
active: any;
}
@Component({
selector: 'app-terminal-list',
templateUrl: './terminal-list.component.html',
styleUrls: ['./terminal-list.component.scss']
})
export class TerminalListComponent implements OnInit {
constructor(@Inject(MAT_BOTTOM_SHEET_DATA) public data: IListData, private _bottomSheetRef: MatBottomSheetRef<TerminalListComponent>) { }
ngOnInit(): void {
}
selectItem(item: any) {
this._bottomSheetRef.dismiss(item)
}
}

View File

@ -1,26 +1,69 @@
<div *ngIf="mainFormGroup && !loading; else loadingEl" class="woocommerce-shipping-fields__field-wrapper"> <div
<form *ngIf="!showAuthoriztion; else authEl" (ngSubmit)="submit()" [formGroup]="mainFormGroup" action="false" autocomplete="on"> *ngIf="mainFormGroup && !loading; else loadingEl"
<h2 class="order_form__title">Оформление заказа</h2> class="woocommerce-shipping-fields__field-wrapper"
<p *ngIf="hasError" class="request-error-message"> >
Произошла ошибка. Попробуйте позже. <form
*ngIf="!showAuthoriztion; else authEl"
(ngSubmit)="submit()"
[formGroup]="mainFormGroup"
action="false"
autocomplete="on"
>
<h2 class="order_form__title">Оформление заказа</h2>
<p *ngIf="hasError" class="request-error-message">
Произошла ошибка. Попробуйте позже.
</p>
<div class="order_form" formGroupName="userDataForm">
<p сlass="form-row form-row-wide">
<input
formControlName="first_name"
id="first_name"
pInputText
placeholder="Ваше имя"
type="text"
/>
</p>
<div *ngIf="deliverData.deliveryType?.name === 'Доставка'">
<p сlass="form-row form-row-last">
<input
formControlName="flat"
id="flat"
pInputText
placeholder="Квартира"
type="number"
min="1"
/>
</p> </p>
<div class="order_form" formGroupName="userDataForm"> <p сlass="form-row form-row-wide">
<p сlass="form-row form-row-wide"> <input
<input formControlName="first_name" id="first_name" pInputText placeholder="Ваше имя" type="text"> formControlName="street"
</p> id="street"
<div *ngIf="deliverData.deliveryType?.name === 'Доставка'"> pInputText
<p сlass="form-row form-row-last"> placeholder="Улица"
<input formControlName="flat" id="flat" pInputText placeholder="Квартира" type="number" min="1"> type="text"
</p> />
<p сlass="form-row form-row-wide"> </p>
<input formControlName="street" id="street" pInputText placeholder="Улица" type="text"> <p сlass="form-row form-row-first">
</p> <input
<p сlass="form-row form-row-first"> formControlName="house"
<input formControlName="house" id="house" pInputText placeholder="Номер дома" type="text"> id="house"
</p> pInputText
</div> placeholder="Номер дома"
<label class="terminal-list-label">Пункты самовывоза</label> type="text"
<div *ngIf="deliverData.deliveryType?.name === 'Самовывоз'" class="terminal-list-container"> />
</p>
</div>
<p сlass="form-row form-row-wide">
<label class="terminal-list-label">Пункты самовывоза</label>
<p-dropdown
*ngIf="deliverData.deliveryType?.name === 'Самовывоз'"
[options]="terminalList"
formControlName="selectedTerminal"
placeholder="Пункты выдачи"
optionLabel="label"
></p-dropdown>
</p>
<!-- <div *ngIf="deliverData.deliveryType?.name === 'Самовывоз'" class="terminal-list-container">
<div *ngFor="let terminal of terminalList" [ngClass]="{ <div *ngFor="let terminal of terminalList" [ngClass]="{
'terminal-container': true, 'terminal-container': true,
'selected': terminal.label === selectedTerminal.label 'selected': terminal.label === selectedTerminal.label
@ -29,52 +72,88 @@
<span class="terminal-container__name">{{terminal.label}}</span> <span class="terminal-container__name">{{terminal.label}}</span>
<span class="terminal-container__address">{{terminal.address}}</span> <span class="terminal-container__address">{{terminal.address}}</span>
</div> </div>
</div> </div> -->
</div> </div>
<div formGroupName="deliveryDataForm"> <div formGroupName="deliveryDataForm">
<p сlass="form-row form-row-wide"> <p сlass="form-row form-row-wide">
<p-dropdown [options]="deliveryTypes" formControlName="deliveryType" placeholder="Доставка" <label class="terminal-list-label">Способ получения</label>
optionLabel="name" (onChange)="changeDeliveryType($event)"></p-dropdown> <p-dropdown
</p> [options]="deliveryTypes"
<p сlass="form-row form-row-wide"> formControlName="deliveryType"
<label id="deliveryDate">Время выдачи</label> placeholder="Доставка"
<p-calendar formControlName="deliveryDate" [showTime]="true" [showSeconds]="false" optionLabel="name"
[touchUI]="true" inputId="time" placeholder="Время выдачи" dateFormat="dd.mm.yy"></p-calendar> (onChange)="changeDeliveryType($event)"
</p> ></p-dropdown>
<p сlass="form-row form-row-wide"> </p>
<p-dropdown [options]="paymentMethods" formControlName="paymentMethod" optionLabel="label" placeholder="Тип оплаты"> <p сlass="form-row form-row-wide">
</p-dropdown> <label id="deliveryDate">Время выдачи</label>
<!-- *Оплата бонусами --> <p-calendar
</p> formControlName="deliveryDate"
<!-- <p сlass="form-row form-row-last"> [showTime]="true"
[showSeconds]="false"
[touchUI]="true"
inputId="time"
placeholder="Время выдачи"
dateFormat="dd.mm.yy"
></p-calendar>
</p>
<p сlass="form-row form-row-wide">
<p-dropdown
[options]="paymentMethods"
formControlName="paymentMethod"
optionLabel="label"
placeholder="Тип оплаты"
>
</p-dropdown>
<!-- *Оплата бонусами -->
</p>
<!-- <p сlass="form-row form-row-last">
<input [maxLength]="255" id="promo-code" pInputText placeholder="Промокод" type="text"> <input [maxLength]="255" id="promo-code" pInputText placeholder="Промокод" type="text">
</p> --> </p> -->
<p сlass="form-row form-row-wide"> <p сlass="form-row form-row-wide">
<textarea [maxLength]="255" cols="30" formControlName="comment" pInputTextarea placeholder="Комментарий" <textarea
rows="1"></textarea> [maxLength]="255"
</p> cols="30"
</div> formControlName="comment"
<div class="bootom-info"> pInputTextarea
<div class="subtotal"> placeholder="Комментарий"
<span class="products-count">Товаров: {{order.products.length}}</span> rows="1"
<span class="woocommerce-Price-amount amount"><bdi><span ></textarea>
class="woocommerce-Price-currencySymbol">{{order.products[0].currency_symbol}}</span>{{order.price}}</bdi></span> </p>
</div> </div>
<button <div class="bootom-info">
class="elementor-button elementor-button--checkout elementor-size-md"> <div class="subtotal">
<span class="elementor-button-text">Оформить заказ</span> <span class="products-count">Товаров: {{ order.products.length }}</span>
</button> <span class="woocommerce-Price-amount amount"
</div> ><bdi
<p *ngIf="showMyMessage" style="color: red; font-size: 20px">Такой адрес не найден! Введите правильный адрес</p> ><span class="woocommerce-Price-currencySymbol">{{
</form> order.products[0].currency_symbol
}}</span
>{{ order.price }}</bdi
></span
>
</div>
<button
class="elementor-button elementor-button--checkout elementor-size-md"
>
<span class="elementor-button-text">Оформить заказ</span>
</button>
</div>
<p *ngIf="showMyMessage" style="color: red; font-size: 20px">
Такой адрес не найден! Введите правильный адрес
</p>
</form>
</div> </div>
<ng-template #loadingEl> <ng-template #loadingEl>
<div class="angular-spinner-container" style="width: fit-content; height: 100%; margin: 16px auto;"> <div
<p-progressSpinner styleClass="angular-spinner"></p-progressSpinner> class="angular-spinner-container"
</div> style="width: fit-content; height: 100%; margin: 16px auto"
>
<p-progressSpinner styleClass="angular-spinner"></p-progressSpinner>
</div>
</ng-template> </ng-template>
<ng-template #authEl> <ng-template #authEl>
<app-auth (phoneConfirmed)="phoneConfirmed()"></app-auth> <app-auth (phoneConfirmed)="phoneConfirmed()"></app-auth>
</ng-template> </ng-template>

View File

@ -1,6 +1,6 @@
:host { :host {
.woocommerce-shipping-fields__field-wrapper { .woocommerce-shipping-fields__field-wrapper {
margin: 8px auto 0 auto; margin: 8px auto 100px auto;
max-width: 400px; max-width: 400px;
} }

View File

@ -16,6 +16,7 @@ import { Order } from 'src/app/models/order';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import * as fromConfig from '../../state/config/config.reducer' import * as fromConfig from '../../state/config/config.reducer'
import { lastValueFrom } from 'rxjs'; import { lastValueFrom } from 'rxjs';
import { GetTerminalsService } from 'src/app/services/get-terminals.service';
@ -43,6 +44,7 @@ export class UserDataOrderComponent implements OnInit, OnDestroy {
private intervalTimeDelivery!: any private intervalTimeDelivery!: any
public userData: UserData = { public userData: UserData = {
name: '',
first_name: null, first_name: null,
last_name: null, last_name: null,
street: null, street: null,
@ -50,6 +52,7 @@ export class UserDataOrderComponent implements OnInit, OnDestroy {
flat: null, flat: null,
city: this.cities[0], city: this.cities[0],
phone: null, phone: null,
selectedTerminal: null
}; };
public deliverData: DeliveryData = { public deliverData: DeliveryData = {
deliveryDate: null, deliveryDate: null,
@ -75,14 +78,14 @@ export class UserDataOrderComponent implements OnInit, OnDestroy {
private wpJsonService: WpJsonService, private wpJsonService: WpJsonService,
private http: HttpClient, private http: HttpClient,
private cookiesService: CookiesService, private cookiesService: CookiesService,
private store: Store private store: Store,
private _getTerminals: GetTerminalsService
) { } ) { }
async ngOnInit() { async ngOnInit() {
this.checkAuthorization(true) this.checkAuthorization(true)
this._createMainForm(); this._createMainForm();
this.getTerminalList(); this.getTerminalList();
this.selectedTerminal = JSON.parse(this.cookiesService.getItem('selectedTerminal') || '')
this.checkoutConfig$.subscribe({ this.checkoutConfig$.subscribe({
next: (value: any) => { next: (value: any) => {
this.checkoutConfig = value this.checkoutConfig = value
@ -99,21 +102,18 @@ export class UserDataOrderComponent implements OnInit, OnDestroy {
} }
getTerminalList() { async getTerminalList() {
this.http.get('./assets/terminal_list1.json').subscribe({ // this.http.get('./assets/terminal_list1.json').subscribe({
next: (value) => {
this.terminalList = value
},
error: (err) => {
console.error(err);
}
})
// this.wpJsonService.getTerminalList().subscribe({
// next: (value) => { // next: (value) => {
// this.terminalList = value // this.terminalList = value
// },
// error: (err) => {
// console.error(err);
// } // }
// }) // })
const _getTerminals = await this._getTerminals.getTerminalList()
this.terminalList = _getTerminals.list
this.selectedTerminal = _getTerminals.active
} }
checkAuthorization(showAuthoriztion: boolean, forced = false) { checkAuthorization(showAuthoriztion: boolean, forced = false) {
@ -235,8 +235,9 @@ export class UserDataOrderComponent implements OnInit, OnDestroy {
// await this.autoCompleteService.setCity(this.userData.city); // await this.autoCompleteService.setCity(this.userData.city);
const isSelfDelivery = this.deliverData.deliveryType?.name === "Самовывоз" const isSelfDelivery = this.deliverData.deliveryType?.name === "Самовывоз"
return this.fb.group({ return this.fb.group({
selectedTerminal: [{ value: this.selectedTerminal, disabled: true }, []],
phone: [this.userData.phone], phone: [this.userData.phone],
first_name: [this.userData.first_name, [Validators.required, Validators.minLength(2), Validators.maxLength(255),]], first_name: [this.userData.name, [Validators.required, Validators.minLength(2), Validators.maxLength(255),]],
// last_name: [this.userData.last_name, [Validators.required, Validators.minLength(2), Validators.maxLength(255),]], // last_name: [this.userData.last_name, [Validators.required, Validators.minLength(2), Validators.maxLength(255),]],
street: [{ value: this.userData.street, disabled: isSelfDelivery }, isSelfDelivery ?? [Validators.required, Validators.minLength(2), Validators.maxLength(255),]], street: [{ value: this.userData.street, disabled: isSelfDelivery }, isSelfDelivery ?? [Validators.required, Validators.minLength(2), Validators.maxLength(255),]],
house: [{ value: this.userData.house, disabled: isSelfDelivery }, isSelfDelivery ?? [Validators.required, Validators.maxLength(10), Validators.pattern('^\\d+[-|\\d]+\\d+$|^\\d*$')]], house: [{ value: this.userData.house, disabled: isSelfDelivery }, isSelfDelivery ?? [Validators.required, Validators.maxLength(10), Validators.pattern('^\\d+[-|\\d]+\\d+$|^\\d*$')]],
@ -250,7 +251,7 @@ export class UserDataOrderComponent implements OnInit, OnDestroy {
this.deliverData.deliveryType = this.deliveryTypes[0]; this.deliverData.deliveryType = this.deliveryTypes[0];
return this.fb.group({ return this.fb.group({
deliveryDate: [{ value: this.deliverData.deliveryDate, disabled: this.checkoutConfig.timeDelivery.changeTime.disabled }, []], deliveryDate: [{ value: this.deliverData.deliveryDate, disabled: this.checkoutConfig.timeDelivery.changeTime.disabled }, []],
deliveryType: [{ value: this.deliverData.deliveryType, disabled: this.checkoutConfig.delivery.disabled }, [Validators.required]], deliveryType: [{ value: this.deliverData.deliveryType, disabled: this.checkoutConfig.delivery.disabled || this.deliveryTypes.length < 2 }, [Validators.required]],
paymentMethod: [{ value: this.deliverData.paymentMethod, disabled: this.checkoutConfig.payments.disabled }, [Validators.required]], paymentMethod: [{ value: this.deliverData.paymentMethod, disabled: this.checkoutConfig.payments.disabled }, [Validators.required]],
persons: [this.deliverData.persons, [Validators.required, Validators.minLength(2), Validators.maxLength(255),]], persons: [this.deliverData.persons, [Validators.required, Validators.minLength(2), Validators.maxLength(255),]],
comment: [this.deliverData.comment, [Validators.maxLength(255),]] comment: [this.deliverData.comment, [Validators.maxLength(255),]]

View File

@ -251,4 +251,11 @@ export interface UserData {
flat: string | null; flat: string | null;
city: string; city: string;
phone: string | null; phone: string | null;
selectedTerminal: ITerminal | null;
name: string
}
export interface ITerminal {
label: string;
id: string;
} }

View File

@ -62,7 +62,7 @@ export class Order {
city: '' city: ''
}, },
amount: this.price, amount: this.price,
terminal_id: this.terminal_id terminal_id: this.userData?.selectedTerminal?.id || this.terminal_id
}, },
} }
} }

View File

@ -1,14 +1,25 @@
import { Component, EventEmitter, HostListener, OnInit, Output } from '@angular/core'; import {
Component,
EventEmitter,
HostListener,
OnInit,
Output,
} from '@angular/core';
import { MatSnackBar } from '@angular/material/snack-bar';
import { MessageService } from 'primeng/api'; import { MessageService } from 'primeng/api';
import { SnackBarComponent } from 'src/app/components/snack-bar/snack-bar.component';
import { Order } from 'src/app/models/order'; import { Order } from 'src/app/models/order';
import { OrderProduct } from 'src/app/models/order-product'; import { OrderProduct } from 'src/app/models/order-product';
import { CartService, ProductAmountAction } from 'src/app/services/cart.service'; import {
CartService,
ProductAmountAction,
} from 'src/app/services/cart.service';
import { OrderService } from 'src/app/services/order.service'; import { OrderService } from 'src/app/services/order.service';
@Component({ @Component({
selector: 'app-cart', selector: 'app-cart',
templateUrl: './cart.component.html', templateUrl: './cart.component.html',
styleUrls: ['./cart.component.scss'] styleUrls: ['./cart.component.scss'],
}) })
export class CartComponent implements OnInit { export class CartComponent implements OnInit {
@Output() showAuthoriztion = new EventEmitter<boolean>(); @Output() showAuthoriztion = new EventEmitter<boolean>();
@ -24,25 +35,26 @@ export class CartComponent implements OnInit {
private orderService: OrderService, private orderService: OrderService,
private cartService: CartService, private cartService: CartService,
private messageService: MessageService, private messageService: MessageService,
) { } private _snackBar: MatSnackBar
) {}
ngOnInit(): void { ngOnInit(): void {
this.width = window.innerWidth; this.width = window.innerWidth;
this.changeDullScreenMode() this.changeDullScreenMode();
this.loadCart() this.loadCart();
} }
// Изменение размера окна // Изменение размера окна
@HostListener('window:resize', ['$event']) @HostListener('window:resize', ['$event'])
onResize(event: any) { onResize(event: any) {
this.width = event.target.innerWidth; this.width = event.target.innerWidth;
this.changeDullScreenMode() this.changeDullScreenMode();
} }
toggleSideBar(): void{ toggleSideBar(): void {
this.visibleSidebar = !this.visibleSidebar; this.visibleSidebar = !this.visibleSidebar;
this.orderConfirmed = false; this.orderConfirmed = false;
this.loadCart() this.loadCart();
} }
hide() { hide() {
@ -51,25 +63,25 @@ export class CartComponent implements OnInit {
changeDullScreenMode() { changeDullScreenMode() {
if (this.width < 650) { if (this.width < 650) {
this.isFullScreen = true this.isFullScreen = true;
} else { } else {
this.isFullScreen = false this.isFullScreen = false;
} }
} }
async loadCart(): Promise<void> { async loadCart(): Promise<void> {
this.loading = true; this.loading = true;
this.order = await this.orderService.getOrder(true); this.order = await this.orderService.getOrder(true);
if (this.order) this.price = this.order.price if (this.order) this.price = this.order.price;
this.loading = false; this.loading = false;
} }
removeFromCart(event: Event, guid: string): void{ removeFromCart(event: Event, guid: string): void {
event.preventDefault(); event.preventDefault();
this.orderService.removeFromCart(guid); this.orderService.removeFromCart(guid);
} }
confirmOrder(event: Event): void{ confirmOrder(event: Event): void {
event.preventDefault(); event.preventDefault();
this.showAuthoriztion.emit(true); this.showAuthoriztion.emit(true);
this.orderConfirmed = true; this.orderConfirmed = true;
@ -78,23 +90,42 @@ export class CartComponent implements OnInit {
setAmount(product: OrderProduct, method: 'plus' | 'minus') { setAmount(product: OrderProduct, method: 'plus' | 'minus') {
if (method === 'plus') { if (method === 'plus') {
this.cartService.changeAmountProduct(product.guid, ProductAmountAction.increment) this.cartService.changeAmountProduct(
product.amount++ product.guid,
ProductAmountAction.increment
);
product.amount++;
this.price = this.price + Number(product.price); this.price = this.price + Number(product.price);
} else if (method === 'minus' && product.amount > 1) { } else if (method === 'minus' && product.amount > 1) {
this.cartService.changeAmountProduct(product.guid, ProductAmountAction.decrement) this.cartService.changeAmountProduct(
product.amount-- product.guid,
ProductAmountAction.decrement
);
product.amount--;
this.price = this.price - Number(product.price); this.price = this.price - Number(product.price);
} }
} }
orderSubmitted(orderid: number) { orderSubmitted(orderid: number) {
this.visibleSidebar = false this.visibleSidebar = false;
this.messageService.add({ severity: 'success', summary: `Заказ оформлен! Номер заказа: ${orderid}` }); this._snackBar.open(`Заказ оформлен! Номер заказа: ${orderid}`, 'Ок')
} }
confirmClearCart() { confirmClearCart() {
this.messageService.add({ key: 'c', sticky: true, severity: 'warn', summary: 'Вы уверены, что хотите очистить корзину?' }); const snackBar = this._snackBar.openFromComponent(SnackBarComponent, {
duration: 4000,
data: {
text: 'Очистить корзину?',
},
});
snackBar.afterDismissed().subscribe(({ dismissedByAction }) => {
if (dismissedByAction) {
this.cartService.clearCart();
this.loadCart();
this.visibleSidebar = false;
}
});
// this.messageService.add({ key: 'c', sticky: true, severity: 'warn', summary: 'Вы уверены, что хотите очистить корзину?' });
} }
onReject() { onReject() {
@ -102,10 +133,9 @@ export class CartComponent implements OnInit {
} }
onConfirm() { onConfirm() {
this.cartService.clearCart() this.cartService.clearCart();
this.loadCart() this.loadCart();
this.visibleSidebar = false this.visibleSidebar = false;
this.messageService.clear('c'); this.messageService.clear('c');
} }
} }

View File

@ -1,9 +1,6 @@
<p-toast position="top-center"></p-toast> <p-toast position="top-center"></p-toast>
<div *ngIf="!loading; else loadingEl" class="products-container"> <div *ngIf="!loading; else loadingEl" class="products-container">
<div class="products-container__filters-container"> <div class="products-container__filters-container">
<!-- <label>Категория</label>
<p-treeSelect *ngIf="groups" [(ngModel)]="selectedGroup" [options]="groups"
(onNodeSelect)="changeGroup()" (onNodeUnselect)="onGroupUnselect($event)" placeholder="Группа"></p-treeSelect> -->
<div class="products-container__categories-container"> <div class="products-container__categories-container">
<div <div
*ngFor="let group of groups; let first = first" *ngFor="let group of groups; let first = first"
@ -19,20 +16,10 @@
</span> </span>
</div> </div>
</div> </div>
<p-treeSelect <button mat-stroked-button [disabled]="!!cartService.cartCount" (click)="showTerminals()">
*ngIf="terminalList" {{ selectedTerminal.label }}
[(ngModel)]="selectedTerminal" </button>
[options]="terminalList"
(onNodeSelect)="changeTerminal()"
(onNodeUnselect)="onTerminalUnselect($event)"
placeholder="Пункт самовывоза"
[disabled]="!!cartService.cartCount"
></p-treeSelect>
<!-- <label>Пункт выдачи</label> -->
</div> </div>
<!-- <p-paginator [style]="{'background': 'transparent', padding: '8px 0'}" [alwaysShow]="false" [first]="currentPage" [rows]="10"
[totalRecords]="filterByGroup().length" (onPageChange)="onPageChange($event)" [pageLinkSize]="3"
[showPageLinks]="true"></p-paginator> -->
<div <div
*ngIf="selectedGroup && selectedGroup.label !== 'Все'" *ngIf="selectedGroup && selectedGroup.label !== 'Все'"
class="products-container__category-name-container" class="products-container__category-name-container"
@ -72,7 +59,7 @@
<p>{{ product.name }}</p> <p>{{ product.name }}</p>
</div> </div>
<p class="products-container__product-composition"> <p class="products-container__product-composition">
{{product.description}} {{ product.description }}
</p> </p>
<div class="products-container__item-footer"> <div class="products-container__item-footer">
<span>{{ product.price }}₽</span> <span>{{ product.price }}₽</span>
@ -104,8 +91,7 @@
<p>{{ product.name }}</p> <p>{{ product.name }}</p>
</div> </div>
<p class="products-container__product-composition"> <p class="products-container__product-composition">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Odio {{ product.description }}
consequuntur voluptates est.
</p> </p>
<div class="products-container__item-footer"> <div class="products-container__item-footer">
<span>{{ product.price }}₽</span> <span>{{ product.price }}₽</span>
@ -114,45 +100,6 @@
</div> </div>
</div> </div>
</ng-container> </ng-container>
<!-- <p-paginator [style]="{'background': 'transparent', padding: '8px 0'}" [alwaysShow]="false" [first]="currentPage" [rows]="10"
[totalRecords]="filterByGroup().length" (onPageChange)="onPageChange($event)" [pageLinkSize]="3"
[showPageLinks]="true"></p-paginator> -->
<p-toast
position="bottom-center"
key="c"
(onClose)="onReject()"
[baseZIndex]="5000"
>
<ng-template let-message pTemplate="message">
<div class="flex flex-column" style="flex: 1">
<div class="text-center">
<i class="pi pi-exclamation-triangle" style="font-size: 3rem"></i>
<h4>{{ message.summary }}</h4>
<p style="font-weight: 600">{{ message.detail }}</p>
</div>
<div class="grid p-fluid">
<div class="col-6">
<button
type="button"
pButton
(click)="onConfirm()"
label="Да"
class="p-button-success"
></button>
</div>
<div class="col-6">
<button
type="button"
pButton
(click)="onReject()"
label="Нет"
class="p-button-secondary"
></button>
</div>
</div>
</div>
</ng-template>
</p-toast>
</div> </div>
<ng-template #loadingEl> <ng-template #loadingEl>
<div <div

View File

@ -1,3 +1,5 @@
@import 'src/sass/mixins';
:host { :host {
.products-container { .products-container {
width: 100%; width: 100%;
@ -53,7 +55,7 @@
font-size: 14px; font-size: 14px;
align-items: center; align-items: center;
overflow-x: auto; overflow-x: auto;
width: 100%; width: auto;
margin-right: 16px; margin-right: 16px;
gap: 8px; gap: 8px;
@ -93,7 +95,7 @@
border: none; border: none;
} }
&:hover { @include hover-supported() {
color: #fff; color: #fff;
background: var(--orange-main); background: var(--orange-main);
border: none; border: none;
@ -135,7 +137,7 @@
color: #fff; color: #fff;
transition: all 0.3s; transition: all 0.3s;
&:hover { @include hover-supported() {
box-shadow: 0 0 10px 5px rgb(211 211 211); box-shadow: 0 0 10px 5px rgb(211 211 211);
} }
} }
@ -163,7 +165,7 @@
transition: all 0.3s; transition: all 0.3s;
} }
&:hover { @include hover-supported() {
scale: 1.01; scale: 1.01;
border: none; border: none;
@ -244,3 +246,11 @@
} }
} }
} }
.mat-input-element {
cursor: pointer;
}
.mat-stroked-button {
border-radius: 1.125rem;
}

View File

@ -1,5 +1,5 @@
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'; import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { Group, Modifier, ModifiersGroup, Product } from "../../interface/data"; import { Group, Modifier, ModifiersGroup, Product } from '../../interface/data';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
import { DialogService } from 'primeng/dynamicdialog'; import { DialogService } from 'primeng/dynamicdialog';
import { ProductModalComponent } from 'src/app/components/product-modal/product-modal.component'; import { ProductModalComponent } from 'src/app/components/product-modal/product-modal.component';
@ -9,12 +9,16 @@ import { lastValueFrom } from 'rxjs';
import { CartService } from 'src/app/services/cart.service'; import { CartService } from 'src/app/services/cart.service';
import { CookiesService } from 'src/app/services/cookies.service'; import { CookiesService } from 'src/app/services/cookies.service';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { MatSelectChange } from '@angular/material/select';
import { MatBottomSheet } from '@angular/material/bottom-sheet';
import { TerminalListComponent } from 'src/app/components/terminal-list/terminal-list.component';
import { GetTerminalsService } from 'src/app/services/get-terminals.service';
@Component({ @Component({
selector: 'app-products', selector: 'app-products',
templateUrl: './products.component.html', templateUrl: './products.component.html',
styleUrls: ['./products.component.scss'], styleUrls: ['./products.component.scss'],
providers: [MessageService] providers: [MessageService],
}) })
export class ProductsComponent implements OnInit { export class ProductsComponent implements OnInit {
public products!: Product[]; public products!: Product[];
@ -25,95 +29,60 @@ export class ProductsComponent implements OnInit {
public terminalList!: any; public terminalList!: any;
public selectedTerminal!: any; public selectedTerminal!: any;
public loading: boolean = false; public loading: boolean = false;
public currentPage: number = 0 public currentPage: number = 0;
constructor( constructor(
public dialogService: DialogService, public dialogService: DialogService,
private wpJsonService: WpJsonService, private wpJsonService: WpJsonService,
private messageService: MessageService,
public cartService: CartService, public cartService: CartService,
private cookiesService: CookiesService,
private router: Router, private router: Router,
private route: ActivatedRoute, private route: ActivatedRoute,
) { } private _bottomSheet: MatBottomSheet,
private _getTerminals: GetTerminalsService
) {}
async ngOnInit() { async ngOnInit() {
this.loading = true; this.loading = true;
await this.getTerminalList() await this.getTerminalList();
this.getData() this.getData();
this.messageService.add({ // this.messageService.add({
severity: 'info', // severity: 'info',
summary: 'В одном заказе могут быть товары только из выбранного пункта выдачи', // summary: 'В одном заказе могут быть товары только из выбранного пункта выдачи',
life: 5000 // life: 5000
}); // });
setTimeout(() => {
this.confirmTerminalList()
}, 0)
this.loading = false; this.loading = false;
} }
async getTerminalList() { async getTerminalList() {
const terminalList = (await lastValueFrom( const _getTerminals = await this._getTerminals.getTerminalList()
this.wpJsonService.getTerminalList() this.terminalList = _getTerminals.list
)) this.selectedTerminal = _getTerminals.active
this.terminalList = this.toTreeJson(this.keyValue(terminalList), terminalList)
const terminalFromCookie = JSON.parse(this.cookiesService.getItem('selectedTerminal') || 'null')
const conditionDelete = this.terminalList.find((terminal: any) => JSON.stringify(terminal) === JSON.stringify(terminalFromCookie))
if (!conditionDelete) {
this.cookiesService.deleteCookie('selectedTerminal')
}
this.selectedTerminal = JSON.parse(this.cookiesService.getItem('selectedTerminal') || 'null') || this.terminalList[0]
this.cartService.changeTerminal(this.selectedTerminal)
}
confirmTerminalList() {
if (this.cartService.cartCount) return
this.messageService.clear();
this.messageService.add({ key: 'c', sticky: true, severity: 'warn', summary: 'Вам подходит пункт выдачи?', detail: this.selectedTerminal.label });
}
onConfirm() {
this.messageService.add({
severity: 'info',
summary: 'В одном заказе могут быть товары только из выбранного пункта выдачи',
life: 5000
});
this.messageService.clear('c');
}
onReject() {
this.messageService.clear('c');
this.messageService.add({
severity: 'info',
summary: 'Выберите пункт выдачи. В одном заказе могут быть товары только из выбранного пункта.',
life: 6000
});
} }
getData() { getData() {
this.wpJsonService.getAllData(`${this.selectedTerminal.label}${this.selectedTerminal.id}`).subscribe({ this.wpJsonService
next: (value) => { .getAllData(`${this.selectedTerminal.label}${this.selectedTerminal.id}`)
this.products = value.products .subscribe({
this.groups = value.groups next: (value) => {
this.groups.unshift( this.products = value.products;
{ this.groups = value.groups;
this.groups.unshift({
id: uuidv4(), id: uuidv4(),
label: 'Все' label: 'Все',
} });
) this.selectedGroup = this.groups[0];
this.selectedGroup = this.groups[0] this.modifiersGroups = value.modifiers_groups;
this.modifiersGroups = value.modifiers_groups this.modifiers = value.modifiers;
this.modifiers = value.modifiers
this.route.queryParams.subscribe((params) => { this.route.queryParams.subscribe((params) => {
if (params['group']) { if (params['group']) {
this.selectedGroup = this.groups.find((group) => group.label === params['group']) || this.groups[0] this.selectedGroup =
} this.groups.find((group) => group.label === params['group']) ||
}) this.groups[0];
} }
}) });
},
});
} }
onPageChange(event: any) { onPageChange(event: any) {
@ -121,24 +90,37 @@ export class ProductsComponent implements OnInit {
} }
filterByGroup(group?: Group) { filterByGroup(group?: Group) {
if (!this.selectedGroup) return [] if (!this.selectedGroup) return [];
if (this.selectedGroup.label === 'Все') { if (this.selectedGroup.label === 'Все') {
if (group) return JSON.parse(JSON.stringify(this.products.filter((product) => product.groupId === group.id))).slice(0, 4) if (group)
return this.products return JSON.parse(
JSON.stringify(
this.products.filter((product) => product.groupId === group.id)
)
).slice(0, 4);
return this.products;
} }
return JSON.parse(JSON.stringify(this.products.filter((product) => product.groupId === this.selectedGroup.id))) return JSON.parse(
JSON.stringify(
this.products.filter(
(product) => product.groupId === this.selectedGroup.id
)
)
);
} }
cropList(list: Array<any>, quantity: number) { cropList(list: Array<any>, quantity: number) {
return list.slice(this.currentPage, this.currentPage + quantity) return list.slice(this.currentPage, this.currentPage + quantity);
} }
addToCart(event: MouseEvent, product: Product) { addToCart(event: MouseEvent, product: Product) {
if (event) { if (event) {
event.preventDefault() event.preventDefault();
} }
const productModalWidth = product.modifiers_group.length ? '94vw' : '50vw' const productModalWidth = product.modifiers_group.length ? '94vw' : '50vw';
const productModalMaxWidth = product.modifiers_group.length ? '1400px' : '500px' const productModalMaxWidth = product.modifiers_group.length
? '1400px'
: '500px';
const ref = this.dialogService.open(ProductModalComponent, { const ref = this.dialogService.open(ProductModalComponent, {
header: product.name, header: product.name,
width: 'fit-content', width: 'fit-content',
@ -147,7 +129,7 @@ export class ProductsComponent implements OnInit {
'min-width': '300px', 'min-width': '300px',
'max-height': '90vh', 'max-height': '90vh',
'border-radius': '1.125rem', 'border-radius': '1.125rem',
width: productModalWidth width: productModalWidth,
}, },
contentStyle: { contentStyle: {
'max-height': '90vh', 'max-height': '90vh',
@ -158,67 +140,46 @@ export class ProductsComponent implements OnInit {
data: { data: {
product: product, product: product,
modifiersGroups: this.modifiersGroups, modifiersGroups: this.modifiersGroups,
modifiers: this.modifiers modifiers: this.modifiers,
}, },
baseZIndex: 10000, baseZIndex: 10000,
autoZIndex: true, autoZIndex: true,
dismissableMask: true, dismissableMask: true,
closeOnEscape: true, closeOnEscape: true,
}); });
} }
changeTerminal() { showTerminals() {
setTimeout(() => { const bottomSheet = this._bottomSheet.open(TerminalListComponent, {
this.products.length = 0; data: {
this.loading = true; list: this.terminalList,
this.getData() active: this.selectedTerminal,
this.cartService.changeTerminal(this.selectedTerminal); },
this.loading = false; ariaLabel: 'Список точек',
this.router.navigate([]); });
this.currentPage = 0 bottomSheet.afterDismissed().subscribe((selectedTerminal) => {
}, 0); if (!selectedTerminal) return;
setTimeout(() => {
this.products.length = 0;
this.loading = true;
this.selectedTerminal = selectedTerminal;
this.getData();
this.cartService.changeTerminal(this.selectedTerminal);
this.loading = false;
this.router.navigate([]);
this.currentPage = 0;
}, 0);
});
} }
changeGroup(group: Group) { changeGroup(group: Group) {
this.selectedGroup = group this.selectedGroup = group;
this.router.navigate([], { this.router.navigate([], {
queryParams: { queryParams: {
group: group.label, group: group.label,
}, },
queryParamsHandling: 'merge', queryParamsHandling: 'merge',
}); });
this.currentPage = 0 this.currentPage = 0;
} }
onGroupUnselect(event: any) {
setTimeout(() => {
this.selectedGroup = event.node
}, 0);
}
onTerminalUnselect(event: any) {
setTimeout(() => {
this.selectedTerminal = event.node
this.cartService.changeTerminal(this.selectedTerminal)
}, 0);
}
keyValue(obj: Object) {
return Object.keys(obj)
}
toTreeJson(array: Array<string>, terminalList: any): Array<any> {
let treeJson: Object[] = []
for (const key of array) {
treeJson.push(
{
label: key,
id: terminalList[key]
}
)
}
return treeJson
}
} }

View File

@ -0,0 +1,76 @@
import { Injectable } from '@angular/core';
import { lastValueFrom } from 'rxjs';
import { ITerminal } from '../interface/data';
import { CartService } from './cart.service';
import { CookiesService } from './cookies.service';
import { WpJsonService } from './wp-json.service';
export interface IGetTerminalList {
list: ITerminal[];
active: ITerminal;
}
@Injectable({
providedIn: 'root'
})
export class GetTerminalsService {
public terminalList!: ITerminal[];
public selectedTerminal!: ITerminal;
constructor(
private wpJsonService: WpJsonService,
public cartService: CartService,
private cookiesService: CookiesService,
) { }
async getTerminalList(): Promise<IGetTerminalList> {
const terminalList = await lastValueFrom(
this.wpJsonService.getTerminalList()
);
this.terminalList = this.toTreeJson(
this.keyValue(terminalList),
terminalList
);
const terminalFromCookie = JSON.parse(
this.cookiesService.getItem('selectedTerminal') || 'null'
);
const conditionDelete = this.terminalList.find(
(terminal: any) =>
JSON.stringify(terminal) === JSON.stringify(terminalFromCookie)
);
if (!conditionDelete) {
this.cookiesService.deleteCookie('selectedTerminal');
}
const selectedTerminal = terminalFromCookie
? this.terminalList.find(
(value: any) => value.id === terminalFromCookie.id
)
: null;
if (!selectedTerminal) {
this.cartService.clearCart();
}
this.selectedTerminal = selectedTerminal || this.terminalList[0];
this.cartService.changeTerminal(this.selectedTerminal);
return {
list: this.terminalList,
active: this.selectedTerminal
}
}
toTreeJson(array: Array<string>, terminalList: any): Array<ITerminal> {
let treeJson: ITerminal[] = [];
for (const key of array) {
treeJson.push({
label: key,
id: terminalList[key],
});
}
return treeJson;
}
keyValue(obj: Object) {
return Object.keys(obj);
}
}

View File

@ -42,14 +42,20 @@ export class OrderService {
const cart = this.cartService.getCart(); const cart = this.cartService.getCart();
if (cart.products.length) { if (cart.products.length) {
const token = this.cookiesService.getItem('token') || '';
const products = await this.getProducts(cart); const products = await this.getProducts(cart);
const additionalInfo = this.jsonRpcService.rpc( // const additionalInfo = this.jsonRpcService.rpc(
{ // {
method: 'getAdditionalInfo', // method: 'getAdditionalInfo',
params: [], // params: [],
}, // },
RpcService.authService, // RpcService.authService,
true // true
// );
const additionalInfo = this.wpJsonService.getCustomerInfo(
environment.systemId,
token,
environment.icardProxy
); );
const tokenData = this.jsonRpcService.rpc( const tokenData = this.jsonRpcService.rpc(
@ -64,14 +70,15 @@ export class OrderService {
const info = await lastValueFrom( const info = await lastValueFrom(
forkJoin([additionalInfo, tokenData, products]) forkJoin([additionalInfo, tokenData, products])
); );
const token = this.cookiesService.getItem('token'); const customer_info = info[0]?.customer_info
const terminal = const terminal =
JSON.parse( JSON.parse(
this.cookiesService.getItem('selectedTerminal') || 'null' this.cookiesService.getItem('selectedTerminal') || 'null'
) || this.cartService.selectedTerminal$; ) || this.cartService.selectedTerminal$;
this.order = new Order({ this.order = new Order({
products: products, products: products,
userData: info[0]?.data, userData: customer_info,
phone: info[1].data?.mobile_number, phone: info[1].data?.mobile_number,
token: token, token: token,
terminal_id: terminal.id, terminal_id: terminal.id,
@ -95,6 +102,10 @@ export class OrderService {
const productSub = allData.products.find( const productSub = allData.products.find(
(product: any) => product.id === cart.products[i].id (product: any) => product.id === cart.products[i].id
); );
if (!productSub) {
this.cartService.removeFromCart(cart.products[i].guid);
break;
}
const product = Object.assign(cloneDeep(cart.products[i]), { const product = Object.assign(cloneDeep(cart.products[i]), {
category_id: 0, category_id: 0,
price: productSub.price, price: productSub.price,

View File

@ -0,0 +1,7 @@
@mixin hover-supported {
@media not all and (pointer: coarse) {
&:hover {
@content;
}
}
}

View File

@ -3,6 +3,7 @@
@import '~@fortawesome/fontawesome-free/scss/solid.scss'; @import '~@fortawesome/fontawesome-free/scss/solid.scss';
@import '~@fortawesome/fontawesome-free/scss/regular.scss'; @import '~@fortawesome/fontawesome-free/scss/regular.scss';
@import '~@fortawesome/fontawesome-free/scss/brands.scss'; @import '~@fortawesome/fontawesome-free/scss/brands.scss';
@import 'src/sass/mixins';
// @import '~mdb-angular-ui-kit/assets/scss/mdb.scss'; // @import '~mdb-angular-ui-kit/assets/scss/mdb.scss';
@ -24,6 +25,17 @@ table{border-collapse:collapse;border-spacing:0}
font-family: 'Raleway', sans-serif; font-family: 'Raleway', sans-serif;
} }
div.cdk-overlay-container {
z-index: 11200;
}
.mat-snack-bar-container {
transform: scale(1);
opacity: 1;
background: #fff;
color: #323232;
}
.p-inputtext { .p-inputtext {
width: 100%; width: 100%;
border: 1px solid #B8DEFF; border: 1px solid #B8DEFF;
@ -52,9 +64,11 @@ table{border-collapse:collapse;border-spacing:0}
border-color: #f9b004; border-color: #f9b004;
} }
.p-selectbutton .p-button.p-highlight:hover { .p-selectbutton .p-button.p-highlight {
background: #f9b004; @include hover-supported() {
border-color: #f9b004; background: #f9b004;
border-color: #f9b004;
}
} }
mark { mark {
@ -254,3 +268,6 @@ body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; background:
html, body { height: 100%; } html, body { height: 100%; }
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; } body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
html, body { height: 100%; }
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }