Implement Timer using React - reactjs

import React from 'react';
import { nanoid } from 'nanoid';
import Confetti from 'react-confetti';
import { useStopwatch } from 'react-timer-hook';
import Die from './components/Die';
import './style.css';
import Timer from './components/Timer';
import Rolls from './components/rolls';
function App() {
const { seconds, minutes, hours, isRunning, start, pause, reset } =
useStopwatch({ autoStart: true });
const [dice, setDice] = React.useState(allNewDice());
const [tenzies, setTenzies] = React.useState(false);
const [time, setTime] = React.useState({});
const [hasStarted, setHasStarted] = React.useState(() => false);
const [bestTime, setBestTime] = React.useState(() =>
localStorage.getItem('best-time')
? JSON.parse(localStorage.getItem('best-time'))
: ''
);
React.useEffect(() => {
setTime({ seconds: seconds, minutes: minutes, hours: hours });
}, [seconds, minutes, hours]);
React.useEffect(() => {
const firstValue = dice[0].value;
const allHeld = dice.every((die) => die.isHeld === true);
const allEqual = dice.every((die) => die.value === firstValue);
if (allEqual && allHeld) {
setTenzies(true);
//if (time < bestTime || !bestTime) {
// setBestTime(time);
// localStorage.setItem('best-time', time);
//}
}
}, [dice]);
function generateNewDie() {
return { value: Math.ceil(Math.random() * 6), isHeld: false, id: nanoid() };
}
function allNewDice() {
const newDice = [];
for (let i = 0; i < 10; i++) {
newDice.push(generateNewDie());
}
return newDice;
}
function rollDice() {
if (!tenzies) {
setDice((oldDice) =>
oldDice.map((die) => {
return die.isHeld === true ? die : generateNewDie();
})
);
} else {
setTenzies(false);
setDice(allNewDice());
}
}
function holdDice(id) {
setDice((oldDice) =>
oldDice.map((die) => {
return die.id === id ? { ...die, isHeld: !die.isHeld } : die;
})
);
}
const diceElements = dice.map((die) => (
<Die
key={die.id}
value={die.value}
isHeld={die.isHeld}
holdDice={() => holdDice(die.id)}
/>
));
return (
<main>
{tenzies && <Confetti />}
<h1 className="title">Tenzies</h1>
<p className="instructions">
Roll until all dice are the same. Click each die to freeze it at its
current value between rolls.
</p>
<div className="dice-container">{diceElements}</div>
<div className="row">
<div className="total-timer">
<Timer best={true} timer={time} />
<Timer timer={time} />
</div>
<button type="button" className="roll-dice" onClick={rollDice}>
{tenzies ? 'New Game' : 'Roll'}
</button>
<div className="total-rolls">
<Rolls best={true} />
<Rolls />
</div>
</div>
</main>
);
}
export default App;
Is it a good practice having Effect Hook render my page every second of the timer??
Timer
export default function Timer(props) {
const styles = {
color: props.best ? '#59e391' : 'white',
};
return (
<div className="timer" style={styles}>
{props.best ? <span>Best Time : </span> : <span>Your Time : </span>}
<span className="digits">
{props.timer.hours ? props.timer.hours : '00'}
</span>
<span>:</span>
<span className="digits">
{props.timer.minutes ? props.timer.minutes : '00'}
</span>
<span>:</span>
<span className="digits">
{props.timer.seconds ? props.timer.seconds : '00'}
</span>
</div>
);
}

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.

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.

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

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} />
);
}

How to add a class to an image by click?

How to add a class to an image if the flag is done: true? As I have not tried, the class is added to all images, and not to those with true...
import React, { useState } from "react";
import "./styles.css";
export default function App() {
const [avatarArr, setAvatarArr] = useState({
avatar: [
{
id: 1,
url: "https://starwars-visualguide.com/assets/img/characters/1.jpg"
},
{
id: 2,
url: "https://starwars-visualguide.com/assets/img/characters/2.jpg"
},
{
id: 3,
url: "https://starwars-visualguide.com/assets/img/characters/3.jpg"
}
]
});
const [classUser, setClassUser] = useState(null);
const [selectUser, setSelectUser] = useState(false);
const onAddClass = id => {
if (avatarArr.avatar.find(items => items.id === id)) {
const index = avatarArr.avatar.findIndex(items => items.id === id);
setAvatarArr([
...avatarArr.slice(0, index),
...avatarArr.slice(index + 1)
]);
} else {
setAvatarArr([...avatarArr, { done: true }]);
setSelectUser(avatarArr.avatar.map(items => items.done));
if (selectUser) {
setClassUser("active__user");
}
}
};
const blockCreate = () => {
return avatarArr.avatar.map(items => {
return (
<div key={items.id}>
<img
src={items.url}
alt="avatar"
width="150px"
onClick={() => onAddClass(items.done, items.id)}
className={selectUser ? classUser : null}
/>
</div>
);
});
};
return (
<div className="App">
<div>{blockCreate()}</div>
</div>
);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
I'm trying to set true on click, to tell the user that the avatar that was clicked on is selected, and add some kind of styling class.
And if you click a second time, then true - becomes false, in short - the choice
Are you looking like this
export default function App() {
const [avatarArr, setAvatarArr] = useState({
avatar: [
{
id: 1,
url: "https://starwars-visualguide.com/assets/img/characters/1.jpg"
},
{
id: 2,
url: "https://starwars-visualguide.com/assets/img/characters/2.jpg"
},
{
id: 3,
url: "https://starwars-visualguide.com/assets/img/characters/3.jpg"
}
]
});
const [selectUser, setSelectUser] = useState(false);
const onAddClass = item => {
setSelectUser(item);
};
const blockCreate = () => {
return avatarArr.avatar.map(items => {
return (
<div key={items.id}>
<img
src={items.url}
alt="avatar"
width="150px"
onClick={() => onAddClass(items)}
className={selectUser.id === items.id ? "myClass" : ""}
/>
</div>
);
});
};
return (
<div className="App">
<div>{blockCreate()}</div>
</div>
);
}
Live working demo https://codesandbox.io/s/vigilant-almeida-169zj

Resources