Using reactPrime library in DataView components how update dynamic values (react hook)? - reactjs

how I can update price value when update quantity value automatically ??
page design
interface ui
print values on the console:
print values on the console:
This sentence needs to be modified
{quantity[initQ] == 1 ? data.price : initP[initQ]}
i use setState to save multiple values
export default function Contaner({ setPressed, getPressed }) {
const [products, setProducts] = useState([]);
const [layout, setLayout] = useState('list');
let initQ = 1;
const [initP,setInitP] = useState({ [initQ]: 1 }) ;
const [quantity, setQuantity] = useState({ [initQ]: 1 });
function checkQuantity(e, data) {
if (e.value <= data.quantity) {
initQ = data.name;
setQuantity({ ...quantity, [data.name]: e.value});
setInitP( { ...quantity, [data.name]: data.price * e.value});
console.log(initP );
setCart(current => [...current, data.name]);
}
else {
showError();
}
}
const renderListItem = (data) => {
return (
<div style={{ display: "flex" }}>
<button className="button_color" onClick={() => removeItem(data)}>
<i className="pi pi-trash"></i>
</button>
<h6>{quantity[initQ] == 1 ? data.price : initP[initQ] }</h6>
<InputNumber id="stacked" showButtons min={1} value={quantity[initQ]}
onValueChange={(e) => checkQuantity(e, data)} />
<InputText disabled={true} value={"₪ " + data.price} />
<h6>{data.name}</h6>
</div>
);
}
const itemTemplate = (product, layout) => {
if (!product) {
return <></>;
}
if (layout === 'list') {
return renderListItem(product);
}
}
return(
<DataView value={products} layout={layout} itemTemplate={itemTemplate} rows={1} />
);
}

Related

react typescript jotai Property 'placement' does not exist on type 'NotAnArrayType<unknown>'

I'm trying to convert an an app from javascript to typescript and I'm having issues. I'm new to typescript and Jotai. I'm getting the error in the Attribute function on attribute?placement. It's like it doesn't recognize that it is an array of strings. Can someone please help me decipher what I'm doing wrong.
import { splitAtom } from "jotai/utils";
import { focusAtom } from 'jotai-optics';
import { atom, useAtom, useAtomValue } from "jotai";
import cat from '../cat.json';
import { Key, useMemo } from "react";
import { Switch } from "#chakra-ui/react";
const catAtom = atom(cat);
const partsAtom = focusAtom(catAtom, (optic) => optic.prop("parts"));
const partsAtomAtoms = splitAtom(partsAtom);
const useAttributesAtom = (partAtom:any) => {
return useMemo(
() => focusAtom(partAtom, (optic:any) => optic.prop("attributes")),
[partAtom]
);
};
const useAttributeAtom = (attributesAtom:any, index:number) => {
// const { attributesAtom, index } = props;
return useMemo(() => {
return focusAtom(attributesAtom, (optic) => optic.at(index));
}, [attributesAtom, index]);
};
const Attribute = (attributesAtom:any, index:number) => {
// const { attributesAtom, index } = props;
const attributeAtom = useAttributeAtom(attributesAtom, index);
const [attribute, setAttribute] = useAtom(attributeAtom);
return (
<div style={{ display: "flex" }}>
<label>
<span style={{ marginRight: "16px" }}>{attribute?.placement}</span>
<Switch
onChange={(checked) =>
setAttribute((prevAttribute: any) => ({
...prevAttribute,
injured: checked
}))
}
checked={attribute?.injured}
/>
</label>
</div>
);
};
const Part = (partAtom:any) => {
const [part] = useAtom(partAtom) as typeof partAtom;
const attributesAtom = useAttributesAtom(partAtom);
const attributes = useAtomValue(attributesAtom) as typeof partAtom;
return (
<div>
<h3>{part.type}</h3>
{attributes.map((attribute: { placement: Key | null | undefined; }, index:
number) => {
return (
<Attribute
key={attribute.placement}
attributesAtom={attributesAtom}
index={index}
/>
);
})}
</div>
);
};
const PetParts = () => {
const [partsAtoms] = useAtom(partsAtomAtoms);
return (
<div>
<h2>Body Injury Details</h2>
{partsAtoms.map((partAtom) => {
return <Part key={`${partAtom}`} partAtom={partAtom} />;
})}
</div>
);
};
export default PetParts;

PayPal Checkout not showing correct total amount in react app

Good morning. I am trying to integrate PayPal check out in my React app. Everything works fine except that the Paypal Checkout amount is not showing the same as the total cart amount. Checkout amount is fixed at $0.01 and not changing as cart amount changes. Please what could i be doing wrong ??? This is the code
#cart.js code
import React, { useContext, useState, useEffect } from "react";
import { GlobalState } from "../../../GlobalState";
import axios from "axios";
import PayPalButton from "./PaypalButton";
function Cart() {
const state = useContext(GlobalState);
const [cart, setCart] = state.userAPI.cart;
const [token] = state.token;
const [total, setTotal] = useState(0);
useEffect(() => {
const getTotal = () => {
const total = cart.reduce((prev, item) => {
return prev + item.price * item.quantity;
}, 0);
setTotal(total);
};
getTotal();
}, [cart]);
const addToCart = async () => {
await axios.patch(
"/user/addcart",
{ cart },
{
headers: { Authorization: token },
}
);
};
const increment = (id) => {
cart.forEach((item) => {
if (item._id === id) {
item.quantity += 1;
}
});
setCart([...cart]);
addToCart();
};
const decrement = (id) => {
cart.forEach((item) => {
if (item._id === id) {
item.quantity === 1 ? (item.quantity = 1) : (item.quantity -= 1);
}
});
setCart([...cart]);
addToCart();
};
const removeProduct = (id) => {
if (window.confirm("Do you want to delete this product?")) {
cart.forEach((item, index) => {
if (item._id === id) {
cart.splice(index, 1);
}
});
setCart([...cart]);
addToCart();
}
};
const tranSuccess = async (payment) => {
console.log(payment);
};
if (cart.length === 0)
return (
<h2 style={{ textAlign: "center", fontSize: "5rem" }}>Cart Empty</h2>
);
return (
<div>
{cart.map((product) => (
<div className="detail cart" key={product._id}>
<img src={product.images.url} alt="" />
<div className="box-detail">
<h2>{product.title}</h2>
<h3>${product.price * product.quantity}</h3>
<p>{product.description}</p>
<p>{product.content}</p>
<div className="amount">
<button onClick={() => decrement(product._id)}> - </button>
<span>{product.quantity}</span>
<button onClick={() => increment(product._id)}> + </button>
</div>
<div className="delete" onClick={() => removeProduct(product._id)}>
X
</div>
</div>
</div>
))}
<div className="total">
<h3>Total: $ {total}</h3>
<PayPalButton total={total} tranSuccess={tranSuccess} />
</div>
</div>
);
}
export default Cart;
PayPal button code
import React from "react";
import { PayPalScriptProvider, PayPalButtons } from "#paypal/react-paypal-js";
export default class PayPalButton extends React.Component {
render() {
const onSuccess = (payment) => {
console.log("The payment was succeeded!", payment);
this.props.tranSuccess(payment);
};
const onCancel = (data) => {
console.log("The payment was cancelled!", data);
};
const onError = (err) => {
console.log("Error!", err);
};
let env = "sandbox"; // you can set here to 'production' for production
let total = this.props.total;
let currency = "USD";
const client = {
sandbox:
"ARhnfWu_QrcGQa-PdvaY1RVriEmqGiSkfEWf-plauZQpQN_gyxaLjH9RXOhdQw7fxxxxxxxxxxxx",
production: "YOUR-PRODUCTION-APP-ID",
};
let style = {
size: "small",
color: "blue",
shape: "rect",
label: "checkout",
tagline: false,
};
return (
<PayPalScriptProvider
options={{
"client-id": "ARhnfWu_QrcGQa-PdvaY1RVriEmqGiSkfEWf-plauZQpQN_gyxaLjH9RXOhdQw7fxxxxxxxxxxxx",
}}
>
<PayPalButtons
env={env}
client={client}
commit={true}
total={total}
currency={currency}
onError={onError}
onSuccess={onSuccess}
onCancel={onCancel}
style={style}
/>
</PayPalScriptProvider>
);
}
}
I don't see a createOrder function anywhere. You need one, and it needs to invoke actions.order.create() with a JSON object that uses your total to set the amount.
See examples in the react-paypal-js storybook.

Options not showing when using custom input in React-Bootstrap-TypeAhead

I am using React-Bootstrap-TypeAhead's latest version in my React project. The main goal is to display the options menu when the user types. The menu is displayed when using the default input component but once I use the render input method for customization the options menu stops showing:
working example
import React, { useState } from 'react';
import { AsyncTypeahead } from 'react-bootstrap-typeahead';
/* example-start */
const BasicExample = ({ key, label }) => {
const [singleSelections, setSingleSelections] = useState([]);
const [multiSelections, setMultiSelections] = useState([]);
const [query, setQuery] = useState('');
const [isLoading, setIsLoading] = useState(false);
const [options, setOptions] = useState([]);
const PER_PAGE = 50;
const SEARCH_URI = 'https://api.github.com/search/users';
function makeAndHandleRequest(query, page = 1) {
return fetch(`${SEARCH_URI}?q=${query}+in:login&page=${page}&per_page=50`)
.then((resp) => resp.json())
.then(({ items, total_count }) => {
/* eslint-disable-line camelcase */
const options = items.map((i) => ({
avatar_url: i.avatar_url,
id: i.id,
login: i.login,
}));
return { options, total_count };
})
.catch((err) => console.log(err));
}
const _handleInputChange = (query) => {
setQuery(query);
};
const _handlePagination = (e, shownResults) => {
const { query } = this.state;
const cachedQuery = this._cache[query];
// Don't make another request if:
// - the cached results exceed the shown results
// - we've already fetched all possible results
if (cachedQuery.options.length > shownResults || cachedQuery.options.length === cachedQuery.total_count) {
return;
}
setIsLoading(true);
const page = cachedQuery.page + 1;
makeAndHandleRequest(query, page).then((resp) => {
const options = cachedQuery.options.concat(resp.options);
// this._cache[query] = { ...cachedQuery, options, page };
setIsLoading(false);
setOptions(options);
});
};
const _handleSearch = (query) => {
setIsLoading(true);
makeAndHandleRequest(query).then((resp) => {
setIsLoading(true);
setOptions(resp?.options || []);
});
};
return (
<>
<AsyncTypeahead
{...{ query, isLoading, options }}
id="async-pagination-example"
labelKey="login"
maxResults={PER_PAGE - 1}
minLength={2}
onInputChange={_handleInputChange}
onPaginate={_handlePagination}
onSearch={_handleSearch}
renderInput={({ inputRef, referenceElementRef, ...inputProps }) => (
<div className="form-group h-64">
<label>Job Category</label>
<div className="input-group">
<input
type="text"
{...inputProps}
ref={(input) => {
inputRef(input);
// referenceElementRef(input);
}}
className="form-control"
placeholder=""
/>
</div>
</div>
)}
paginate
placeholder="Search for a Github user..."
renderMenuItemChildren={(option) => (
<div key={option.id}>
<img
alt={option.login}
src={option.avatar_url}
style={{
height: '24px',
marginRight: '10px',
width: '24px',
}}
/>
<span>{option.login}</span>
</div>
)}
useCache={false}
/>
</>
);
};
/* example-end */
export default BasicExample;
The reason you're not seeing any results rendered is that _handleInputChange is triggering a re-render and resetting the debounced onSearch handler before it can fire.
You can wrap _handleSearch with useCallback to fix that:
const _handleSearch = useCallback((query) => {
setIsLoading(true);
makeAndHandleRequest(query).then((resp) => {
setIsLoading(false);
setOptions(resp?.options || []);
});
}, []);

Radio buttons not toggling, checked or highlighted

import React, { useState, useEffect, Fragment } from "react";
import Button from "../../../Resources/Forms/Button";
import Switch from "../../../Resources/Forms/Switch";
import { POST } from "../../../Utils/api";
import Radio from "../../../Resources/Forms/Radio";
import withAppData from "../../../HOC/withAppData";
const InventorySettings = (props) => {
const [state, setState] = useState({});
const [isSaving, setIsSaving] = useState();
const [isStockRequestChecked, setIsStockRequestChecked] = useState(false);
const getStatus = id => {
return props.context.isSettingsActivated(id) ? 1 : 0;
};
const setBusinessSettings = async () => {
const defaultSettings = [
{ state: "enableStockRequest", id: 53 },
{ state: "connectWarehousePickStock", id: 52 },
{ state: "approveRequestOtp", id: 51 },
{ state: "approveRequestManually", id: 50 }
];
for (const setting of defaultSettings) {
await setState({ [setting.state]: getStatus(setting.id) });
}
};
function chooseApprovalMethod(methodType) {
const currentValue = state[methodType];
setState({[methodType]
: currentValue === 1 ? 0: 1})
}
async function saveApprovalMethod() {
setIsSaving(true)
const approvalSettings = [{text:"approvalRequestManually", id: 51}, {text:"approveRequestOtp", id: 50}]
for(const el of approvalSettings) {
const currentValue = state[el.text];
const data = {
settingId: el.id,
status: currentValue
}
await POST(`Common/AddBusinessSetting`, data);
}
setIsSaving(false);
props.context.getBusinessSettings();
}
const updateBasicSettings = async (id, key) => {
setState({ [key]: !state[key] ? 1 : 0 });
const data = {
SettingId: id,
Status: state[key],
};
await POST(`Common/AddBusinessSetting`, data);
props.context.getBusinessSettings();
};
useEffect(() => {
setBusinessSettings();
}, []);
return (
<Fragment>
<div className="basic-settings-section">
<Switch
label={"Connect Warehouse Stock to pick stock"}
light={true}
checked={state && state.connectWarehousePickStock === 1}
onChange={() => updateBasicSettings(52, "connectWarehousePickStock")}
></Switch>
</div>
<div className="basic-settings-section">
<Switch
label={"Stock Request"}
light={true}
checked={isStockRequestChecked}
onChange={() => setIsStockRequestChecked(!isStockRequestChecked)}
></Switch>
{isStockRequestChecked && (
<div className="basic-settings-plan-generate">
<div
className="form__label"
style={{ padding: "2px", marginBottom: "20px" }}
>
<p>Please choose an approval method</p>
</div>
<Radio
label={"Manual Approval"}
name="approval"
value="50"
id="50"
checked={state && state.approveRequestManually === 1}
// onChange={() => (chooseApprovalMethod)}
/>
<Radio
label={"OTP Approval"}
name="approval"
value="51"
id="51"
checked={state && state.approveRequestOtp === 1}
// onChange={() => (chooseApprovalMethod)}
/>
<div className="password-settings-btn"
// onClick={props.context.showToast}
>
<Button
type={"outline"}
size={"medium"}
text={"Save"}
disabled={!state.approveRequestOtp && !state.approveRequestManually}
withMargin={false}
loading={isSaving}
onClick={saveApprovalMethod}
></Button>
</div>
</div>
)}
</div>
</Fragment>
);
}
export default withAppData(InventorySettings);
I added the chooseApprovalMethod function to the radio buttons but still I wasn't getting it well. So I had to call there state using state.text is equal to 1. Please help me out I don't think I know what I'm doing anymore.
Please above are my code, the radio buttons aren't checking or highlighting, so I want them to be checked when clicked on, and I want there ids to be saved when clicking on the save button.
So please guys help me out, as I don't understand it anymore.

React parsing function inside component as React Element

I have a React component which is trying to render another component that has function inside it as a child. When I try to render that component it returns an [Object]. I am trying to find another way to render that child component.
Right now, I tried to render it with React.createElement(), yet it also returned an object. I am using react-beautiful-dnd library to use Drag and Drop feature. This library has Droppable component and it takes a function inside which has two parameters, provided, snapshot.
Since it takes a function, when I try to render Droppable component, it returns an object instead of react element.
DroppableContent.js
const DroppableContent = ({ droppedBlank, label, id }) => (
<Droppable droppableId={id || _.uniqueId('droppable_')}>
{(provided, snapshot) => (
<span ref={provided.innerRef} style={{ display: 'inline' }} {...provided.droppableProps}>
{/* blank placeholder */}
<span className={droppedBlank ? styles.dropped : styles.placeholder}
style={{ backgroundColor: !droppedBlank && snapshot.isDraggingOver ? '#88d2ee' : '#fff' }}
>
{droppedBlank ? <BlankItem label={label} index={id} /> : null}
</span>
</span>
)}
</Droppable>
);
DragAndDrop.js where I call QuestionPreview component.
import React from 'react';
import PropTypes from 'prop-types';
import { withTranslation } from 'react-i18next';
import { DragDropContext, Droppable } from 'react-beautiful-dnd';
import _ from 'lodash';
import * as questionStyles from '../Questions.less';
import BlankList from './BlankList';
import BlankItem from './BlankItem';
import QuestionPreview from './QuestionPreview';
const DragAndDrop = ({
question, onAnswer, answer, hideTitle, className, t, readOnly,
}) => {
const handleDragEnd = (result) => {
const { destination, source, draggableId } = result;
if (!destination) {
return;
}
if (destination.droppableId === source.droppableId && destination.index === source.index) {
return;
}
const destinationId = destination.droppableId;
const sourceId = draggableId;
const blank = {
textIndex: destinationId,
id: sourceId,
// answer: _.find(questionBlanks, b => b.id === sourceId).answer,
};
let updatedBlanks;
if (destinationId === 'answerBlanks') {
updatedBlanks = _.filter(answer.blanks, item => item.id !== blank.id);
} else {
updatedBlanks = _.filter(answer.blanks, item => item.textIndex !== blank.textIndex);
updatedBlanks.push(blank);
}
onAnswer(question, { blanks: updatedBlanks });
};
const blankLabels = currentLabels => _.filter(currentLabels, l => !_.includes(_.map(answer.blanks, ab => ab.id), l.id)).map((label, index) => (
<BlankItem key={label.id} label={label} index={index} />
));
const blankItems = currentBlanks => _.map(currentBlanks, (currentBlank, index) => (
<BlankItem key={currentBlank.id} label={currentBlank} index={index} readOnly />
));
const { text } = question;
const shuffledLabels = question.labels && _.shuffle(question.labels);
// filtering answers from blank items so that whenever we drag an item to a blank,
// answer will be removed.
const filteredLabels = shuffledLabels && blankLabels(shuffledLabels);
const filteredBlanks = blankItems(question.blanks);
return (
<DragDropContext onDragEnd={handleDragEnd}>
<div>
<p style={{ fontWeight: 600 }}>
{t('defaultDndText', { numberOfBlanks: question.blanks.length })}
</p>
<Droppable droppableId="answerBlanks">
{provided => (
<div>
<BlankList innerRef={provided.innerRef} {...provided.droppableProps}>
{readOnly ? filteredBlanks : filteredLabels}
</BlankList>
</div>
)}
</Droppable>
{!hideTitle && (
<QuestionPreview blanks={_.filter(question.blanks, blank => blank.textIndex < 100)}
labels={question.labels}
selectedBlanks={answer.blanks}
text={text}
className={[questionStyles.title, className].join(' ')}
/>
)}
</div>
</DragDropContext>
);
};
DragAndDrop.propTypes = {
question: PropTypes.shape({
text: PropTypes.string,
}).isRequired,
answer: PropTypes.shape({
blanks: PropTypes.arrayOf(PropTypes.shape({})),
}),
readOnly: PropTypes.bool,
disabled: PropTypes.bool,
hideTitle: PropTypes.bool,
onAnswer: PropTypes.func,
className: PropTypes.string,
};
DragAndDrop.defaultProps = {
onAnswer: () => {},
disabled: false,
hideTitle: false,
className: '',
answer: { blanks: [] },
readOnly: false,
};
export default withTranslation('question')(DragAndDrop);
QuestionPreview.js where I try to render DroppableContent component.
const QuestionPreview = ({
text, labels, selectedBlanks, readOnly,
}) => {
const readOnlyContent = (id) => {
const droppedBlank = selectedBlanks && _.find(selectedBlanks, blank => blank.textIndex === id);
const label = droppedBlank && _.find(labels, l => l.id === droppedBlank.id);
return (
<span className={droppedBlank ? styles.dropped : styles.placeholder}>
{droppedBlank && <BlankItem label={label} readOnly />}
</span>
);
};
const splittedText = splitTextWithBlanks(text);
const blankIndices = getBlankIndices(text);
const getContentId = index => blankIndices[index];
const tempArray = [];
const html = () => {
_.map(splittedText, (element, index) => {
const contentId = getContentId(index);
const droppedBlank = selectedBlanks && _.find(selectedBlanks, blank => blank.textIndex === contentId);
const label = droppedBlank && _.find(labels, l => l.id === droppedBlank.id);
const blankContent = readOnly ? readOnlyContent(contentId) : <DroppableContent id={contentId} droppedBlank={droppedBlank} label={label} />;
const htmlContent = <span dangerouslySetInnerHTML={{ __html: toHTML(element) }} />;
tempArray.push(htmlContent);
if (index !== splittedText.length - 1) {
tempArray[index] = tempArray[index] + blankContent;
}
});
return tempArray;
};
const createdElement = React.createElement('div', null, html());
return createdElement;
};
This does not return any error but what I want to achieve is that combining htmlContent variable with blankContent. When I do that, it does render blankContent as an Object. In the end, I just want to find a way to parse Droppable component.
You might have error in the following line
const blankContent = readOnly ? readOnlyContent : <DroppableContent id={contentId} droppedBlank={droppedBlank} label={label} />;
You are passing reference of readOnlyContent, May be you want to call
readOnlyContent (contentId) .BTW your code is complex and hard to maintain/read. try to refactor it
Edit 1 Try this QuestionPreview.js
const QuestionPreview = ({
text, labels, selectedBlanks, readOnly,
}) => {
const readOnlyContent = (id) => {
const droppedBlank = selectedBlanks && _.find(selectedBlanks, blank =>
blank.textIndex === id);
const label = droppedBlank && _.find(labels, l => l.id ===
droppedBlank.id);
return (
<span className={droppedBlank ? styles.dropped : styles.placeholder}>
{droppedBlank && <BlankItem label={label} readOnly />}
</span>
);
};
const splittedText = splitTextWithBlanks(text);
const blankIndices = getBlankIndices(text);
const getContentId = index => blankIndices[index];
const tempArray = [];
const html = () => {
return _.map(splittedText, (element, index) => {
const contentId = getContentId(index);
const droppedBlank = selectedBlanks && _.find(selectedBlanks, blank =>
blank.textIndex === contentId);
const label = droppedBlank && _.find(labels, l => l.id ===
droppedBlank.id);
const blankContent = readOnly ? readOnlyContent(contentId) :
<DroppableContent id={contentId} droppedBlank={droppedBlank} label=
{label}
/>;
let htmlContent = <span dangerouslySetInnerHTML={{ __html:
toHTML(element) }} />;
if (index !== splittedText.length - 1) {
return (
<Fragment>
{htmlContent}
{blankContent}
</Fragment>
)
}
return htmlContent
});
};
return (
{html()}
)
};

Resources