Add popover for cart summary with options data

Signed-off-by: Egor Savkin <es@m-labs.hk>
This commit is contained in:
Egor Savkin 2023-08-22 12:41:32 +08:00
parent 288a0cc74c
commit 23c7508358
3 changed files with 72 additions and 13 deletions

View File

@ -261,6 +261,29 @@ button {
width: 20px; width: 20px;
padding-bottom: 3px; padding-bottom: 3px;
} }
.alert-info {
padding-bottom: 0;
}
}
.overlayVariant {
min-width: 100px;
height: 150px;
overflow-y: scroll;
position: absolute;
display: flex;
align-items: start;
justify-content: center;
text-align: left;
background-color: white;
color: black;
flex-direction: column;
cursor: pointer;
p {
font-size: .875rem;
margin: 0;
}
} }
thead, tbody, tfoot { thead, tbody, tfoot {

View File

@ -6,9 +6,7 @@ import { createRoot } from "react-dom/client";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd"; import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
import { CustomizeButton } from "./shop_components.jsx"; import { CustomizeButton, CustomizeData } from "./shop_components.jsx";import { OverlayTrigger } from "react-bootstrap";
import { OverlayTrigger } from "react-bootstrap";
const data = window.shop_data; const data = window.shop_data;
const itemsUnfoldedList = Array.from(data.columns.backlog.categories.map(groupId => groupId.itemIds).flat()); const itemsUnfoldedList = Array.from(data.columns.backlog.categories.map(groupId => groupId.itemIds).flat());
@ -1422,7 +1420,7 @@ class OrderSumary extends React.PureComponent {
<tbody> <tbody>
{summary.map((item, index) => { {summary.map((item, index) => {
let alert, warning, options; let alert, warning, options, options_data;
if (itemsData[index] && itemsData[index].warnings) { if (itemsData[index] && itemsData[index].warnings) {
alert = itemsData[index]; alert = itemsData[index];
@ -1432,6 +1430,7 @@ class OrderSumary extends React.PureComponent {
} }
} }
options = itemsData[index] && itemsData[index].options; options = itemsData[index] && itemsData[index].options;
options_data = itemsData[index] && itemsData[index].options_data;
return ( return (
<tr key={item.id} <tr key={item.id}
@ -1459,12 +1458,8 @@ class OrderSumary extends React.PureComponent {
className="alert-warning" className="alert-warning"
src={`/images/${warning.icon}`} src={`/images/${warning.icon}`}
/> />
) : ( options ? ) : ( (options && options_data) ?
(<img ( <CustomizeData id={item.id + "options"} data={options_data} /> ) : null
style={{'marginLeft': '10px'}}
className="alert-info"
src="/images/shop/icon-customize.svg"
/>) : null
)} )}
{(!warning && !options) && ( {(!warning && !options) && (
@ -1831,7 +1826,6 @@ class Shop extends React.PureComponent {
}; };
const clonedCart = Array.from(this.state.columns.cart.items); const clonedCart = Array.from(this.state.columns.cart.items);
const clonedCartData = Array.from(this.state.columns.cart.itemsData); const clonedCartData = Array.from(this.state.columns.cart.itemsData);
console.log(clonedCartData);
for (const i in clonedCart) { for (const i in clonedCart) {
const item = clonedCart[i]; const item = clonedCart[i];
const item_data = clonedCartData[i]; const item_data = clonedCartData[i];

View File

@ -2,11 +2,12 @@
import React, {Component} from "react"; import React, {Component} from "react";
import jsonLogic from 'json-logic-js'; import jsonLogic from 'json-logic-js';
import { useState } from 'react'; import {useState} from 'react';
// https://stackoverflow.com/a/70511311 // https://stackoverflow.com/a/70511311
const trueTypeOf = (obj) => Object.prototype.toString.call(obj).slice(8, -1).toLowerCase(); const trueTypeOf = (obj) => Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
class Radio extends Component { class Radio extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
@ -276,7 +277,8 @@ export function CustomizeButton({options, data, target, id, big}) {
return ( return (
<div> <div>
<img className="alert-info" src={show ? "/images/shop/icon-close.svg" : "/images/shop/icon-customize.svg"} onClick={handleClick} /> <img className="alert-info" src={show ? "/images/shop/icon-close.svg" : "/images/shop/icon-customize.svg"}
onClick={handleClick}/>
<div style={{'display': show ? 'flex' : 'none'}} className={div_classes}> <div style={{'display': show ? 'flex' : 'none'}} className={div_classes}>
<ProcessOptions <ProcessOptions
options={options} options={options}
@ -289,3 +291,43 @@ export function CustomizeButton({options, data, target, id, big}) {
</div> </div>
); );
} }
export function CustomizeData({id, data}) {
const [show, setShow] = useState(false);
const [position, setPosition] = useState({x: 0, y: 0});
const handleClick = (event) => {
setPosition({x: event.clientX, y: event.clientY});
setShow(!show);
};
const stringify = (value) => {
let value_type = trueTypeOf(value);
if (value_type === "string") {
return value;
} else if (value_type === "object") {
if (value.checked === false) {
return "off";
} else if (value.checked === true && value.text) {
return value.text;
}
}
return JSON.stringify(value);
}
return (
<div>
<img className="alert-info" src={show ? "/images/shop/icon-close.svg" : "/images/shop/icon-customize.svg"}
onClick={handleClick}/>
<div style={{'display': show ? 'flex' : 'none', 'top': position.y - 170, 'left': position.x - 66}}
className="overlayVariant card border rounded">
<div className="card-body">
{Array.from(Object.entries(data).map(([key, value], _) => {
return (<p className="card-text" key={id + key}><i>{key}</i>: {stringify(value)}</p>);
}))}
</div>
</div>
</div>
);
}