parent
694dbbfb8d
commit
b5fd880379
@ -1 +1,19 @@
|
||||
<p>checkbox-group works!</p>
|
||||
<div *ngFor="let option of options" class="extra_options_checkbox">
|
||||
<div class="extra_options_label"><label>{{option.name}}</label></div>
|
||||
<div class="extra_options_value">
|
||||
<div class="woofood-cbx-wrapper">
|
||||
<input class="inp-woofood-cbx"
|
||||
[disabled]="!optionIsSelected(option) && selectedOptions.length >= modifier.restrictions.maxQuantity"
|
||||
[checked]="optionIsSelected(option)" type="checkbox" style="display: none" name="add_extra_option"
|
||||
value="{{option.id}}" id="{{option.id}}" (change)="onToggle(option)">
|
||||
<label class="woofood-cbx" for="{{option.id}}">
|
||||
<span>
|
||||
<svg width="12px" height="10px" viewBox="0 0 12 10">
|
||||
<polyline points="1.5 6 4.5 9 10.5 1"></polyline>
|
||||
</svg>
|
||||
</span>
|
||||
<span>{{currencySymbol}}{{0}}</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -0,0 +1,89 @@
|
||||
:host {
|
||||
.extra_options_checkbox {
|
||||
width: 100%;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.extra_options_label {
|
||||
width: 70%;
|
||||
float: left;
|
||||
font-size: 14px;
|
||||
|
||||
label {
|
||||
margin: 5px;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.extra_options_value {
|
||||
width: 30%;
|
||||
float: left;
|
||||
|
||||
.woofood-cbx-wrapper {
|
||||
width: 100%;
|
||||
float: left;
|
||||
|
||||
.woofood-cbx {
|
||||
margin: auto;
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
line-height: 30px;
|
||||
margin-bottom: 0px;
|
||||
|
||||
span:first-child {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
margin-right: 8px;
|
||||
border-radius: 3px;
|
||||
transform: scale(1);
|
||||
vertical-align: middle;
|
||||
border: 1px solid #9098A9;
|
||||
transition: all 0.2s ease;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #cc0000;
|
||||
display: block;
|
||||
transform: scale(0);
|
||||
opacity: 1;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
svg {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
left: 2px;
|
||||
fill: none;
|
||||
stroke: #FFFFFF;
|
||||
stroke-width: 2;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
stroke-dasharray: 16px;
|
||||
stroke-dashoffset: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.inp-woofood-cbx:checked+.woofood-cbx span:first-child {
|
||||
background: #cc0000;
|
||||
border-color: #cc0000;
|
||||
animation: wave 0.4s ease;
|
||||
svg {
|
||||
stroke-dashoffset: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.inp-woofood-cbx:disabled+.woofood-cbx span:first-child {
|
||||
border-color: #dfdfdf !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
|
||||
import {Modifier, Option} from 'src/app/interface/data';
|
||||
import {Modifier, ModifiersGroup, Option} from 'src/app/interface/data';
|
||||
import { cloneDeep } from 'lodash/fp';
|
||||
|
||||
@Component({
|
||||
@ -11,23 +11,22 @@ export class CheckboxGroupComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
@Input() modifier!: Modifier;
|
||||
@Input() modifier!: ModifiersGroup;
|
||||
@Input() options!: Modifier[];
|
||||
@Input() currencySymbol!: string;
|
||||
|
||||
@Output() toggle = new EventEmitter<Option>();
|
||||
@Output() toggle = new EventEmitter<Modifier>();
|
||||
|
||||
@Input() selectedOptions: Option[] = [];
|
||||
public options: Option[] = [];
|
||||
@Input() selectedOptions: Modifier[] = [];
|
||||
|
||||
ngOnInit() {
|
||||
// this.options = cloneDeep<Option[]>(this.modifier.options);
|
||||
}
|
||||
|
||||
optionIsSelected(option: Option): boolean{
|
||||
optionIsSelected(option: Modifier): boolean{
|
||||
return !!this.selectedOptions.find(selected => selected.id === option.id);
|
||||
}
|
||||
|
||||
onToggle(option: Option){
|
||||
onToggle(option: Modifier){
|
||||
this.toggle.emit(option);
|
||||
}
|
||||
|
||||
|
||||
@ -4,18 +4,30 @@
|
||||
|
||||
<div class="product-modal__modifiers-container">
|
||||
<ng-container *ngIf="product.modifiers_group.length">
|
||||
<div *ngFor="let modifier of modifiersFilter()" class="product-card__modifier">
|
||||
<h4>{{modifier.name}}</h4>
|
||||
<!-- <app-checkbox-group [modifier]="modifier" currencySymbol="₽"
|
||||
[selectedOptions]="selectedOptions(modifier)" (toggle)="addOption(modifier, $event)">
|
||||
</app-checkbox-group> -->
|
||||
<div *ngFor="let modifierGroup of modifiersFilter()" [attr.isShow]="false" class="product-modal__modifier" #modifierContainer>
|
||||
<a (click)="setOptionsView($event, modifierContainer)">
|
||||
{{modifierGroup.name}}
|
||||
<span [ngClass]="{
|
||||
'product-modal__modifier-icon': true,
|
||||
'isShow': getIsShow(modifierContainer)
|
||||
}"></span>
|
||||
</a>
|
||||
<div [ngClass]="{
|
||||
'options-container': true,
|
||||
'isShow': getIsShow(modifierContainer)
|
||||
}">
|
||||
<app-checkbox-group [modifier]="modifierGroup" [options]="optionsFilter(modifierGroup)"
|
||||
currencySymbol="₽" [selectedOptions]="selectedOptions(modifierGroup)"
|
||||
(toggle)="addOption(modifierGroup, $event)">
|
||||
</app-checkbox-group>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<div class="product-modal__footer">
|
||||
<span>{{product.price}}₽</span>
|
||||
<button class="product-modal__add-to-cart">
|
||||
<span class="product-modal__footer-price">{{product.price}}₽</span>
|
||||
<button class="product-modal__add-to-cart" (click)="addToCart($event)">
|
||||
Добавить
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@ -2,7 +2,8 @@
|
||||
.product-modal {
|
||||
position: relative;
|
||||
padding-bottom: 60px;
|
||||
& > img {
|
||||
|
||||
&>img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@ -18,6 +19,12 @@
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&__footer-price {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
&__add-to-cart {
|
||||
padding: 8px;
|
||||
border: none;
|
||||
@ -25,5 +32,53 @@
|
||||
background-color: #0d457e;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&__modifier {
|
||||
border: 1px solid rgba(128, 128, 128, 0.23);
|
||||
margin: 0.5em 0;
|
||||
padding-bottom: 6px;
|
||||
a {
|
||||
width: 100%;
|
||||
display: block;
|
||||
padding: 0.75em;
|
||||
border-radius: 0.15em;
|
||||
transition: background .3s ease;
|
||||
}
|
||||
.options-container {
|
||||
transition: opacity .5s ease;
|
||||
padding-left: 16px;
|
||||
display: none;
|
||||
opacity: 0;
|
||||
&.isShow {
|
||||
display: block;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__modifier-icon {
|
||||
float: right;
|
||||
&::before, &::after {
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
transition: transform .5s ease;
|
||||
}
|
||||
&::before {
|
||||
content: "\\";
|
||||
transform: rotate(346deg);
|
||||
}
|
||||
&::after {
|
||||
content: "/";
|
||||
transform: rotate(14deg);
|
||||
}
|
||||
&.isShow {
|
||||
&::before {
|
||||
transform: rotate(76deg);
|
||||
}
|
||||
&::after {
|
||||
transform: rotate(104deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,8 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog';
|
||||
import { AllData, Modifier, ModifiersGroup, Product } from 'src/app/interface/data';
|
||||
import { AllData, Modifier, ModifiersGroup, Option, Product } from 'src/app/interface/data';
|
||||
import { CartProduct } from 'src/app/models/cart-product';
|
||||
import { CartService } from 'src/app/services/cart.service';
|
||||
import { WpJsonService } from 'src/app/services/wp-json.service';
|
||||
|
||||
@Component({
|
||||
@ -13,24 +15,66 @@ export class ProductModalComponent implements OnInit {
|
||||
public allData!: AllData;
|
||||
public modifiersGroups!: ModifiersGroup[];
|
||||
public modifiers!: Modifier[];
|
||||
public cartProduct!: CartProduct;
|
||||
|
||||
constructor(
|
||||
public dialogRef: DynamicDialogRef,
|
||||
public config: DynamicDialogConfig,
|
||||
private wpJsonService: WpJsonService
|
||||
private wpJsonService: WpJsonService,
|
||||
private cartService: CartService,
|
||||
) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.product = this.config.data.product
|
||||
this.modifiersGroups = this.config.data.modifiersGroups
|
||||
this.modifiers = this.config.data.modifiers
|
||||
this.modifiers = this.config.data.modifiers
|
||||
this.cartProduct = new CartProduct(this.product.id, this.product.name, this.modifiersFilter(), this.modifiers);
|
||||
}
|
||||
|
||||
modifiersFilter() {
|
||||
modifiersFilter(): ModifiersGroup[] {
|
||||
return this.modifiersGroups.filter((value) => this.product.modifiers_group.includes(value.id))
|
||||
}
|
||||
|
||||
// selectedOptions(modifier: Modifier): Option[]{
|
||||
// return this.cartProduct.modifiers.find(cartModifier => cartModifier.id === modifier.id)?.options ?? [];
|
||||
// }
|
||||
optionsFilter(modifierGroup: ModifiersGroup): Modifier[] {
|
||||
return this.modifiers.filter((modifier) => modifier.groupId === modifierGroup.id)
|
||||
}
|
||||
|
||||
selectedOptions(modifier: ModifiersGroup): Modifier[]{
|
||||
return this.cartProduct.modifiers.find(cartModifier => cartModifier.id === modifier.id)?.options ?? [];
|
||||
}
|
||||
|
||||
addOption(modifier: ModifiersGroup, option: Modifier){
|
||||
const modif = this.cartProduct.modifiers.find((modif) => modif.id === modifier.id);
|
||||
const optionSelectedCartIndex = modif?.options.findIndex((modif) => modif.id === option.id)
|
||||
if ((optionSelectedCartIndex || optionSelectedCartIndex === 0) && optionSelectedCartIndex !== -1) {
|
||||
modif?.options.splice(optionSelectedCartIndex, 1)
|
||||
return
|
||||
}
|
||||
modif?.options.push(option)
|
||||
}
|
||||
|
||||
getIsShow(element: HTMLDivElement) {
|
||||
const isShow = Object.values(element.attributes).find((value) => value.name === 'isshow')?.value
|
||||
return isShow === 'true'
|
||||
}
|
||||
|
||||
setOptionsView(event: Event, element: HTMLDivElement) {
|
||||
if (event) {
|
||||
event.preventDefault()
|
||||
}
|
||||
const isShow = this.getIsShow(element)
|
||||
if (isShow) {
|
||||
element.setAttribute('isShow', 'false')
|
||||
return
|
||||
}
|
||||
element.setAttribute('isShow', 'true')
|
||||
}
|
||||
|
||||
addToCart(event: Event) {
|
||||
if (event) {
|
||||
event.preventDefault()
|
||||
}
|
||||
this.cartService.addToCart(this.cartProduct);
|
||||
this.dialogRef.close();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
<div class="products-container">
|
||||
<p-listbox [options]="groups" [(ngModel)]="selectedGroup" optionLabel="name" [style]="{'width':'fit-content', 'margin-bottom': '16px'}"></p-listbox>
|
||||
<div class="products-container__filters-container">
|
||||
<p-treeSelect [(ngModel)]="selectedGroup" [options]="groups" placeholder="Группа"></p-treeSelect>
|
||||
|
||||
</div>
|
||||
<div class="products-container__items">
|
||||
<div *ngFor="let product of filterByGroup()" class="products-container__item">
|
||||
<img *ngIf="!product.image" src="./assets/no-image.png" alt="{{product.name}}">
|
||||
|
||||
@ -5,12 +5,24 @@
|
||||
flex-direction: column;
|
||||
margin-bottom: 16px;
|
||||
|
||||
&__filters-container {
|
||||
width: 100%;
|
||||
max-width: 700px;
|
||||
margin: 12px auto 24px auto;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: space-between;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
&__items {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
gap: 16px;
|
||||
max-width: 700px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
&__item {
|
||||
|
||||
@ -15,7 +15,7 @@ export class ProductsComponent implements OnInit {
|
||||
public groups: Group[] = [
|
||||
{
|
||||
id: uuidv4(),
|
||||
name: 'Все'
|
||||
label: 'Все'
|
||||
}
|
||||
];
|
||||
public modifiersGroups!: ModifiersGroup[];
|
||||
@ -43,7 +43,7 @@ export class ProductsComponent implements OnInit {
|
||||
}
|
||||
|
||||
filterByGroup() {
|
||||
if (this.selectedGroup.name === 'Все') return this.products
|
||||
if (this.selectedGroup.label === 'Все') return this.products
|
||||
return this.products.filter((product) => product.groupId === this.selectedGroup.id)
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"groups": [
|
||||
{
|
||||
"name": "тестовая категория",
|
||||
"label": "тестовая категория",
|
||||
"id": "05126d92-0e17-4c0f-b4c3-db6a9a1afdeb"
|
||||
}
|
||||
],
|
||||
@ -66,7 +66,7 @@
|
||||
"id": "00000000-0000-0000-0000-000000000000",
|
||||
"restrictions": {
|
||||
"minQuantity": 0,
|
||||
"maxQuantity": 0,
|
||||
"maxQuantity": 1,
|
||||
"freeQuantity": 0,
|
||||
"byDefault": 0
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user