diff --git a/package-lock.json b/package-lock.json index 9b67e2b..0007d8f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@testing-library/user-event": "^13.5.0", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-scripts": "5.0.1", + "react-scripts": "^5.0.1", "web-vitals": "^2.1.4" } }, diff --git a/package.json b/package.json index f6f7903..3ae4ff4 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "@testing-library/user-event": "^13.5.0", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-scripts": "5.0.1", + "react-scripts": "^5.0.1", "web-vitals": "^2.1.4" }, "scripts": { diff --git a/src/App.js b/src/App.js index 3784575..2162979 100644 --- a/src/App.js +++ b/src/App.js @@ -1,23 +1,14 @@ -import logo from './logo.svg'; + import './App.css'; +import ProductsPage from './components/ProductsPage'; + + + function App() { return (
-
- logo -

- Edit src/App.js and save to reload. -

- - Learn React - -
+
); } diff --git a/src/Product.css b/src/Product.css new file mode 100644 index 0000000..4e28e3f --- /dev/null +++ b/src/Product.css @@ -0,0 +1,28 @@ +/* ProductRow.css */ + +.product-row { + color: black; + } + + .product-row.out-of-stock { + color: red; + } + + /* ProductTable.css */ + + .product-table { + width: 100%; + border-collapse: collapse; + } + + .product-table th, + .product-table td { + border: 1px solid #dddddd; + padding: 8px; + text-align: left; + } + + .product-table th { + background-color: #f2f2f2; + } + \ No newline at end of file diff --git a/src/components/ProductRow.js b/src/components/ProductRow.js new file mode 100644 index 0000000..3428d9a --- /dev/null +++ b/src/components/ProductRow.js @@ -0,0 +1,18 @@ + + +import React from 'react'; +import "../Product.css"; + +function ProductRow({ product }) { + const rowClassName = product.inStock ? 'product-row' : 'product-row out-of-stock'; + + + return ( + + {product.name} + {product.price} + + ); +} + +export default ProductRow; diff --git a/src/components/ProductTable.js b/src/components/ProductTable.js new file mode 100644 index 0000000..cc68001 --- /dev/null +++ b/src/components/ProductTable.js @@ -0,0 +1,27 @@ + + +import React from 'react'; +import ProductRow from './ProductRow'; +import "../Product.css"; + +function ProductTable({ products }) { + return ( +
+ + + + + + + + + {products.map((product, index) => ( + + ))} + +
NamePrice
+
+ ); +} + +export default ProductTable; diff --git a/src/components/ProductsPage.js b/src/components/ProductsPage.js new file mode 100644 index 0000000..c52668b --- /dev/null +++ b/src/components/ProductsPage.js @@ -0,0 +1,45 @@ + + +import React, { useState } from 'react'; +import jsonData from '../data.json'; +import SearchBar from './SearchBar'; +import ProductTable from './ProductTable'; + +function ProductsPage() { + const [products, setProducts] = useState(jsonData); + const [filteredProducts, setFilteredProducts] = useState(jsonData); + const [showOnlyInStock, setShowOnlyInStock] = useState(false); + + + const handleSearch = (searchTerm) => { + const filtered = products.filter(product => + product.name.toLowerCase().includes(searchTerm.toLowerCase()) + ); + setFilteredProducts(filtered); + }; + + const handleCheckboxChange = (e) => { + setShowOnlyInStock(e.target.checked); + if (e.target.checked) { + const filtered = products.filter(product => product.inStock); + setFilteredProducts(filtered); + } else { + setFilteredProducts(products); + } + }; + + + + + + + return ( +
+

Store

+ + +
+ ); +} + +export default ProductsPage; diff --git a/src/components/SearchBar.js b/src/components/SearchBar.js new file mode 100644 index 0000000..b1d9b8b --- /dev/null +++ b/src/components/SearchBar.js @@ -0,0 +1,17 @@ + + +import React from 'react'; + +function SearchBar({ handleSearch,handleCheckboxChange }) { + return ( +
+ handleSearch(e.target.value)} /> + +
+ ); +} + +export default SearchBar;