As you can see in the react code, I am trying to reduce the quantity, but I struggle to do it in react. what I want is if click button then quantity should be reduced 1 by 1.
I don't understand what should I do here.
const ManageInventory = () => {
const [products, setProducts] = useProducts();
const handleDelevery = id => {
const handleDelivery = event => { event.preventDefault();
const deliveryInventoryItem = inventoryItem.quantity(quantity-1);
}
const handleDelete = id => {
const proceed = window.confirm('Are Your Sure?');
if(proceed){
const url =`http://localhost:5000/product/${id}`;
fetch(url, {
method: 'DELETE'
})
.then(res => res.json())
.then(data => {
console.log(data);
const remaining = products.filter(product => product._id !==id);
setProducts(remaining);
})
}
}
return (
<div className=''>
<h2 className='product-title'>All Products {products.length} </h2>
<div>
</div>
<div>
<Table striped bordered hover variant="dark">
<thead>
<tr>
<th>Image</th>
<th>Prodct Name</th>
<th>Price</th>
<th>Quantity</th>
<th>Supplier</th>
<th colSpan={2}>Edit</th>
</tr>
</thead>
<tbody>
{
products.map(product => <tr
key={product._id}
product={product}>
<td><img src={product.img} alt="" /> </td>
<td>{product.name}</td>
<td> {product.price}</td>
<td>{product.quantity}</td>
<td>{product.supplier}</td>
<td><button className='manage-btn' onClick={()=> handleDelete(product._id)}>Delete</button></td>
<td><button className='manage-btn' onClick={()=> handleDelevery()}>Delivered</button></td>
</tr>
)
}
</tbody>
</Table>
</div>
<button className='add-product-link'><Link to='/addproduct'>Add Product</Link></button>
</div>
);
};
Related
I have list components:
import React,{useState,useEffect} from 'react'
import { Link } from 'react-router-dom'
import UserService from '../services/UserService'
const UserList = () => {
const [users,setUsers] = useState([])
useEffect(() => {
UserService.findAll().then((response)=>{
setUsers(response.data)
}).catch(error=>{
console.log(error)
})
},[users])
const [selectedUserId, setSelectedUserId] = useState();
const handleRowClick = (id) => {
setSelectedUserId(id);
}
return (
<div className='container'>
<h2 className='text-center'>Users</h2>
<div>
<table className='table table-bordered table-stripped'>
<thead>
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
<th>Password</th>
</thead>
<tbody>
{
users.map(
user =>
<tr key={user.id} onClick={() => handleRowClick(user.id)} style={{backgroundColor: selectedUserId === user.id ? "lightblue" : ""}}>
<td>{user.firstName}</td>
<td>{user.lastName}</td>
<td>{user.email}</td>
<td>{user.password}</td>
</tr>
)
}
</tbody>
</table>
</div>
<Link className="btn btn-primary mx-2" to={"/users/save"} state='Create' >New</Link>
<Link className="btn btn-primary mx-2" to={'/update/'+selectedUserId} state='Update'> Edit</Link>
<Link className="btn btn-primary mx-2" to={"/update/"+selectedUserId} state='Delete' >Delete</Link>
</div>
)
}
export default UserList;
//<Link className="btn btn-primary mx-2" to={"/users/save"} onClick={() => setData('Create')} >New</Link>
It shows UserList twice:
I thought because of the React Strict Mode but it wasn't.
Why is my table showing twice? How can I fix this?
import React from 'react'
import './user.css'
const User = ({ id, email, name, onDelete }) => {
const handleDelete = () => {
onDelete(id);
}
return (
<table className='table'>
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>edit</th>
<th>delete</th>
</tr>
</thead>
<tbody>
<tr>
<td>{name}</td>
<td>{email}</td>
<td>
<button>edit</button>
<button onClick={handleDelete}>delete</button>
</td>
</tr>
</tbody>
</table>
)
}
export default User
You're creating a new table for every user. That's why your headers are duplicated. You only need a new row for every user instead of an entire table for each user.
I'd separate the UserTable and the UserRow.
// UserTable.jsx
import React from 'react'
import './user.css'
import './UserRow'
const UserTable = ({ users, onDelete }) => {
return (
<table className='table'>
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>edit</th>
<th>delete</th>
</tr>
</thead>
<tbody>
{users.map(user => {
<UserRow key={user.id} userId={user.id} userName={user.name} email {user.email} onDelete={onDelete} />onDelete={onDelete} />
})
}
</tbody>
</table>
)
}
export default UserTable
// UserRow.jsx
import React from 'react'
import './user.css'
const UserRow = ({ userId, email, userName, onDelete }) => {
const handleDelete = () => {
onDelete(userId);
}
return (
<tr>
<td>{userName}</td>
<td>{email}</td>
<td>
<button>edit</button>
<button onClick={handleDelete}>delete</button>
</td>
</tr>
)
}
export default UserRow
I need a function to filter by name, The data comes from my Laravel API, I wanted to make a filter on the screen to search for the account name. I am new to React.
import Table from "react-bootstrap/Table";
import axios from "axios";
import { Link } from "react-router-dom";
import { useState, useEffect } from "react";
import Form from "react-bootstrap/Form";
import Button from "react-bootstrap/Button";
const endpoint = "http://localhost:8000/api";
const AccountShow = () => {
const [accounts, setAccounts] = useState([]);
useEffect(() => {
getAllAccounts();
}, []);
const getAllAccounts = async () => {
const response = await axios.get(`${endpoint}/accounts`);
setAccounts(response.data);
};
const deleteAccount = async (id) => {
await axios.delete(`${endpoint}/account/${id}`);
getAllAccounts();
};
return (
<div className="d-grid gap-2">
<div className="row">
<div className="col-8">
<Form className="d-flex m-1">
<Form.Control
type="search"
placeholder="Filtro"
className="me-2"
aria-label="Search"
/>
<Button variant="outline-secondary">Search</Button>
</Form>
</div>
<div className="col-4">
<Link
to="/account/create"
className="col-11 btn btn-outline-primary m-1 "
>
Create
</Link>
</div>
</div>
<Table hover className="">
<thead>
<tr>
<th scope="col">#</th>
<th className="col-2" scope="col">
Nome
</th>
<th className="col-2" scope="col">
Razão Social
</th>
<th scope="col">Status da Conta</th>
<th scope="col">Setor</th>
<th scope="col">Segmento Atuacao</th>
<th scope="col">Natureza Juridica</th>
<th scope="col">Capital</th>
<th scope="col">Funcionarios</th>
<th className="text-center" scope="col">
Ações
</th>
</tr>
</thead>
<tbody>
{accounts.map((account) => (
<tr key={account.id}>
<th>{account.id}</th>
<td>{account.nome}</td>
<td>{account.razaoSocial}</td>
<td>{account.statusConta}</td>
<td>{account.setor}</td>
<td>{account.segmentoAtuacao}</td>
<td>{account.naturezaJuridica}</td>
<td>{account.capital}</td>
<td>{account.funcionarios}</td>
<td className="text-center">
<Link
to={`edit/${account.id}`}
className="btn btn-outline-warning"
>
Editar
</Link>
<button
onClick={() => deleteAccount(account.id)}
className="btn btn-outline-danger m-1"
>
Deletar
</button>
</td>
</tr>
))}
</tbody>
</Table>
</div>
);
};
export default AccountShow;
This is a correct way to filter.
import Table from "react-bootstrap/Table";
import axios from "axios";
import { Link } from "react-router-dom";
import { useState, useEffect } from "react";
import Form from "react-bootstrap/Form";
import Button from "react-bootstrap/Button";
const endpoint = "http://localhost:8000/api";
const AccountShow = () => {
const searchQuery = useState("");
const [accounts, setAccounts] = useState([]);
const [accountToShow, setAccountsToShow] = useState([]);
useEffect(() => {
setAccountsToShow(accounts.filter((account) => /*filter by a specific parameter here depending on what you want to filter it by; by the account.nome field?*/ account.nome.includes(searchQuery)));
}, [accounts, searchQuery]);
useEffect(() => {
getAllAccounts();
}, []);
const getAllAccounts = async () => {
const response = await axios.get(`${endpoint}/accounts`);
setAccounts(response.data);
};
const deleteAccount = async (id) => {
await axios.delete(`${endpoint}/account/${id}`);
getAllAccounts();
};
return (
<div className="d-grid gap-2">
<div className="row">
<div className="col-8">
<Form className="d-flex m-1">
<Form.Control
onChange={({target}) => setSearchQuery(target.value)}
value={searchQuery}
type="search"
placeholder="Filtro"
className="me-2"
aria-label="Search"
/>
<Button variant="outline-secondary">Search</Button>
</Form>
</div>
<div className="col-4">
<Link
to="/account/create"
className="col-11 btn btn-outline-primary m-1 "
>
Create
</Link>
</div>
</div>
<Table hover className="">
<thead>
<tr>
<th scope="col">#</th>
<th className="col-2" scope="col">
Nome
</th>
<th className="col-2" scope="col">
Razão Social
</th>
<th scope="col">Status da Conta</th>
<th scope="col">Setor</th>
<th scope="col">Segmento Atuacao</th>
<th scope="col">Natureza Juridica</th>
<th scope="col">Capital</th>
<th scope="col">Funcionarios</th>
<th className="text-center" scope="col">
Ações
</th>
</tr>
</thead>
<tbody>
{accountsToShow.map((account) => (
<tr key={account.id}>
<th>{account.id}</th>
<td>{account.nome}</td>
<td>{account.razaoSocial}</td>
<td>{account.statusConta}</td>
<td>{account.setor}</td>
<td>{account.segmentoAtuacao}</td>
<td>{account.naturezaJuridica}</td>
<td>{account.capital}</td>
<td>{account.funcionarios}</td>
<td className="text-center">
<Link
to={`edit/${account.id}`}
className="btn btn-outline-warning"
>
Editar
</Link>
<button
onClick={() => deleteAccount(account.id)}
className="btn btn-outline-danger m-1"
>
Deletar
</button>
</td>
</tr>
))}
</tbody>
</Table>
</div>
);
};
export default AccountShow;
You can filter data using
useMemo()
const [accounts, setAccounts] = useState([]);
const [query, setQuery] = useState('');
const filterData = useMemo(() => {
if (accounts && accounts?.length > 0) {
return accounts.filter(item =>
item?.name
.toLocaleLowerCase('en')
.includes(query.trim().toLocaleLowerCase('en')),
);
}
}, [accounts, query]);
you can set query using textbox change event
Hope you guys are fine.
I have the next code for dynamically show the quantity of each selected product
import React, { useState, useEffect } from 'react';
import db from '../firebase';
//const Swal = window.Swal;
const NewSale = () => {
const [products, setProducts] = useState([]);
const [selectedProducts, setSelectedProducts] = useState([]);
useEffect(() => {
if(products.length === 0){
db.collection('products').get().then((querySnapshot) => {
const docs = [];
querySnapshot.forEach((doc) => {
docs.push({
id: doc.id,
...doc.data()
});
});
docs.sort((a, b)=> a.name.localeCompare(b.name));
setProducts(docs);
});
}
});
const handleSelectChange = (e) => {
const value = e.target.value;
if(value){
const selectedProduct = products.filter(item => item.id === value)[0];
setSelectedProducts(selectedProducts => [...selectedProducts, {
id: value,
name: selectedProduct.name,
quantity: 1
}]);
}
}
const handleRangeChange = (target, index) => {
const currentValue = parseInt(target.value);
let currentArrayValue = selectedProducts;
currentArrayValue[index].quantity = currentValue;
setSelectedProducts(currentArrayValue);
}
const handleCancelButton = () => {
setSelectedProducts([]);
}
return (
<React.Fragment>
<div className='container'>
<h1 className='display-3 text-center'>New Sale</h1>
<div className='row'>
<div className='col'>
<div className='mb-3'>
<label htmlFor='product' className='form-label fs-3'>Service</label>
<select id='product' onChange={handleSelectChange} className='form-select form-select-lg' multiple aria-label='multiple select service'>
{products.length !== 0?
products.map(item => <option key={item.id} value={item.id}>{item.name}</option>) : <option>No product registered</option>
}
</select>
</div>
</div>
</div>
<div className='row mt-4'>
<div className='col'>
<table className='table caption-top'>
<caption>Sell List</caption>
<thead>
<tr>
<th scope='col'>#</th>
<th scope='col'>Product</th>
<th scope='col'>Quantity</th>
</tr>
</thead>
<tbody>
{selectedProducts.length !== 0?
selectedProducts.map((item, index) => (
<tr key={index}>
<th scope='row'>{(index + 1)}</th>
<td>{item.name}</td>
<td>
<label htmlFor={`customRange-${index}`} className='form-label'>{item.quantity} Units</label>
<input
type='range'
className='form-range'
value={item.quantity}
onChange={({target}) => handleRangeChange(target, index)}
min='1'
max='100'
step='1'
id={`customRange-${index}`}/>
</td>
</tr>
)) :
<tr>
<th className='text-center' colSpan='3'>Nothing selected!</th>
</tr>
}
</tbody>
</table>
</div>
</div>
<div className='row mt-2'>
<div className='col'>
<button className='btn btn-success'>Save</button>
</div>
<div className='col'>
<button className='btn btn-warning' onClick={handleCancelButton}>Cancel</button>
</div>
</div>
</div>
</React.Fragment>
)
};
export default NewSale;
The code shows this... I do not know if I'm allowed to do this kind of operations because I'm adding events every time I select a product so, I'm not sure this is the best way to do it.
And the problem is that I'm getting this unexpected result,
What I want to do is show the current Quantity for each selected item,
Thanks!!
I am new with programing and I want to use if ternario, but it doesn't work. I have two functions and I create a third function to show one of them or the other. It is an application in ReactJS. Below is the code:
import { Table } from "react-bootstrap";
import { Link } from "react-router-dom";
import { useCartContext } from "../../Context/CartContext";
const emptyCart = () => {
return(
<>
<div>
<h3>The Cart is empty</h3>
<p>
Return to home to see our products
</p>
<Link to='/' ><button className="btn btn-info"> Home </button></Link>
</div>
</>
);
};
const CartFunction = () => {
const { list, totalPrice } = useCartContext();
return (
<Table striped hover>
<thead>
<tr>
<th>Product</th>
<th>Title</th>
<th>Quantity</th>
<th>Price</th>
</tr>
</thead>
<tbody>
{list.map((varietal) => (
<tr key={varietal.id}>
<td>
<img
src={varietal.pictureUrl}
alt='img'
style={{ width: "82px" }}
/>
</td>
<td>{varietal.title}</td>
<td>{varietal.count}</td>
<td>${varietal.price}</td>
</tr>
))}
</tbody>
<thead>
<tr>
<td colSpan="3">Total</td>
<td>${totalPrice()}</td>
</tr>
</thead>
</Table>
);
};
const CartComponent = () => {
const { list } = useCartContext();
return (
<>
{list.length !== 0 ? <CartFunction /> : <emptyCart />}
</>
);
};
export default CartComponent;
Visual Code it says that emptyCard has a value but it is never used. If there is someone that could help me I would appreciate it. Cheers