+
+
+
+
+
+ Categories
+
+
+ Cart
+
+
+ {shopCart.length}
+
+
+
+
+
+
+
+
+
+
+
+ {cartProducts && cartProducts.length}{' '}
+ {cartProducts.length > 1 || cartProducts.length === 0 ? ' products' : ' product'}{' '}
+ found
+
+
+
+
+
+ {cartProducts &&
+ cartProducts.map((product, index) => {
+ if (index <= amountLoaded) {
+ return (
+
+
+
+
+
+
+ {product.category.name}
+ {product.product.name}
+
+
+
+ {product.product.price}
+
+
+
+
+ removeProductFromCart(index)}
+ >
+
+
+
+
+ );
+ }
+ })}
+
+
+
+
+
+ £{total.toFixed(2)}
+
+
+
+ Checkout
+
+
+
+
+ );
+};
+
+export default CartProducts;
diff --git a/03_source/mobile/src/pages/DemoEcommerceExample/pages/CategoryProducts.module.css b/03_source/mobile/src/pages/DemoEcommerceExample/pages/CategoryProducts.module.css
new file mode 100644
index 0000000..e42a0b1
--- /dev/null
+++ b/03_source/mobile/src/pages/DemoEcommerceExample/pages/CategoryProducts.module.css
@@ -0,0 +1,10 @@
+.categoryPage ion-toolbar {
+
+ --border-style: none;
+}
+
+.search {
+
+ --background: rgb(240, 240, 240);
+ --color: black;
+}
\ No newline at end of file
diff --git a/03_source/mobile/src/pages/DemoEcommerceExample/pages/CategoryProducts.tsx b/03_source/mobile/src/pages/DemoEcommerceExample/pages/CategoryProducts.tsx
new file mode 100644
index 0000000..ccbd65a
--- /dev/null
+++ b/03_source/mobile/src/pages/DemoEcommerceExample/pages/CategoryProducts.tsx
@@ -0,0 +1,134 @@
+import {
+ IonBadge,
+ IonButton,
+ IonButtons,
+ IonCol,
+ IonContent,
+ IonGrid,
+ IonHeader,
+ IonIcon,
+ IonInfiniteScroll,
+ IonInfiniteScrollContent,
+ IonNote,
+ IonPage,
+ IonRow,
+ IonSearchbar,
+ IonTitle,
+ IonToolbar,
+} from '@ionic/react';
+import { cart, chevronBackOutline, searchOutline } from 'ionicons/icons';
+import { useEffect, useRef, useState } from 'react';
+import { useParams } from 'react-router';
+import ProductCard from '../components/ProductCard';
+
+import { CartStore } from '../data/CartStore';
+import { ProductStore } from '../data/ProductStore';
+
+import styles from './CategoryProducts.module.css';
+
+const CategoryProducts = () => {
+ const params = useParams();
+ const cartRef = useRef();
+ const products = ProductStore.useState((s) => s.products);
+ const shopCart = CartStore.useState((s) => s.product_ids);
+ const [category, setCategory] = useState({});
+ const [searchResults, setsearchResults] = useState([]);
+ const [amountLoaded, setAmountLoaded] = useState(6);
+
+ useEffect(() => {
+ const categorySlug = params.slug;
+ const tempCategory = products.filter((p) => p.slug === categorySlug)[0];
+ setCategory(tempCategory);
+ setsearchResults(tempCategory.products);
+ }, [params.slug]);
+
+ const fetchMore = async (e) => {
+ // Increment the amount loaded by 6 for the next iteration
+ setAmountLoaded((prevAmount) => prevAmount + 6);
+ e.target.complete();
+ };
+
+ const search = async (e) => {
+ const searchVal = e.target.value;
+
+ if (searchVal !== '') {
+ const tempResults = category.products.filter((p) =>
+ p.name.toLowerCase().includes(searchVal.toLowerCase())
+ );
+ setsearchResults(tempResults);
+ } else {
+ setsearchResults(category.products);
+ }
+ };
+
+ return (
+