diff --git a/README.md b/README.md
index b58e0af83..2861c925f 100644
--- a/README.md
+++ b/README.md
@@ -39,8 +39,3 @@ Instead, it will copy all the configuration files and the transitive dependencie
You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
-## Learn More
-
-You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
-
-To learn React, check out the [React documentation](https://reactjs.org/).
diff --git a/package.json b/package.json
index d9a0e2130..789fe5b17 100644
--- a/package.json
+++ b/package.json
@@ -12,7 +12,7 @@
"@types/react-dom": "^17.0.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
- "react-router-dom": "^5.3.0",
+ "react-router-dom": "^6.7.0",
"react-scripts": "4.0.3",
"typescript": "^4.1.2",
"web-vitals": "^1.0.1"
diff --git a/public/coffee-mug.png b/public/coffee-mug.png
new file mode 100644
index 000000000..c19c2088d
Binary files /dev/null and b/public/coffee-mug.png differ
diff --git a/src/02-component-patterns/assets/no-image.jpg b/src/02-component-patterns/assets/no-image.jpg
new file mode 100644
index 000000000..ae122b097
Binary files /dev/null and b/src/02-component-patterns/assets/no-image.jpg differ
diff --git a/src/02-component-patterns/components/ProductButtons.tsx b/src/02-component-patterns/components/ProductButtons.tsx
new file mode 100644
index 000000000..abfde3f78
--- /dev/null
+++ b/src/02-component-patterns/components/ProductButtons.tsx
@@ -0,0 +1,20 @@
+import { useContext } from "react";
+
+import { ProductCardContext } from "./ProductCard";
+import { ProductCardButtons } from "../interfaces/interfaces";
+
+import styles from "../styles/styles.module.css";
+
+export const ProductButtons = () => {
+ const { counter, increaseBy }: ProductCardButtons = useContext(ProductCardContext);
+
+ return (
+
+
+
+
{counter}
+
+
+
+ )
+};
\ No newline at end of file
diff --git a/src/02-component-patterns/components/ProductCard.tsx b/src/02-component-patterns/components/ProductCard.tsx
new file mode 100644
index 000000000..e938e6ddf
--- /dev/null
+++ b/src/02-component-patterns/components/ProductCard.tsx
@@ -0,0 +1,36 @@
+import { createContext } from "react";
+
+import { IProductCardContext, IProductCardProps } from "../interfaces/interfaces";
+// import { ProductButtons, ProductImage, ProductTitle } from "./";
+
+import useProducts from "../hooks/useProducts";
+
+import styles from "../styles/styles.module.css";
+
+export const ProductCardContext = createContext({} as IProductCardContext);
+
+export const ProductCard = ({ product, children }: IProductCardProps) => {
+ const { counter, increaseBy } = useProducts();
+
+ return (
+
+
+ {children}
+
+
+ )
+};
+
+/*
+ Se puede asignar componentes a otro componente de este modo
+ cuando los componentes a añadir se encuentran en el mismo archivo.
+*/
+
+// ProductCard.Title = ProductTitle;
+// ProductCard.Image = ProductImage;
+// ProductCard.Buttons = ProductButtons;
diff --git a/src/02-component-patterns/components/ProductImage.tsx b/src/02-component-patterns/components/ProductImage.tsx
new file mode 100644
index 000000000..ff8bb02bf
--- /dev/null
+++ b/src/02-component-patterns/components/ProductImage.tsx
@@ -0,0 +1,23 @@
+import { useContext } from "react";
+
+import styles from "../styles/styles.module.css";
+import noImage from "../assets/no-image.jpg";
+import { ProductCardContext } from "./ProductCard";
+
+export const ProductImage = ({ image = "" }) => {
+ let imgToShow: string;
+
+ const { product } = useContext(ProductCardContext);
+
+ if (image) {
+ imgToShow = image
+ } else if (product.img) {
+ imgToShow = product.img
+ } else {
+ imgToShow = noImage
+ }
+
+ return (
+
+ )
+};
diff --git a/src/02-component-patterns/components/ProductTitle.tsx b/src/02-component-patterns/components/ProductTitle.tsx
new file mode 100644
index 000000000..820c74618
--- /dev/null
+++ b/src/02-component-patterns/components/ProductTitle.tsx
@@ -0,0 +1,15 @@
+import { useContext } from "react";
+
+import { ProductCardContext } from "./ProductCard";
+
+import styles from "../styles/styles.module.css";
+
+export const ProductTitle = ({ title }: { title?: string }) => {
+ const { product } = useContext(ProductCardContext);
+
+ return (
+
+ { title ? title : product.title }
+
+ )
+};
\ No newline at end of file
diff --git a/src/02-component-patterns/components/index.ts b/src/02-component-patterns/components/index.ts
new file mode 100644
index 000000000..6ad896f3b
--- /dev/null
+++ b/src/02-component-patterns/components/index.ts
@@ -0,0 +1,18 @@
+import { ProductButtons } from "./ProductButtons";
+import { ProductCard as ProductCardHOC} from "./ProductCard";
+import { ProductImage } from "./ProductImage";
+import { ProductTitle } from "./ProductTitle";
+
+import { IProductCardHOC } from "../interfaces/interfaces";
+
+export { ProductImage } from "./ProductImage";
+export { ProductTitle } from "./ProductTitle";
+export { ProductButtons } from "./ProductButtons";
+
+export const ProductCard: IProductCardHOC = Object.assign( ProductCardHOC, {
+ Image: ProductImage,
+ Title: ProductTitle,
+ Buttons: ProductButtons
+});
+
+
diff --git a/src/02-component-patterns/hooks/useProducts.tsx b/src/02-component-patterns/hooks/useProducts.tsx
new file mode 100644
index 000000000..0785d8e90
--- /dev/null
+++ b/src/02-component-patterns/hooks/useProducts.tsx
@@ -0,0 +1,14 @@
+import { useState } from 'react'
+
+const useProducts = () => {
+
+ const [counter, setCounter] = useState(0)
+
+ const increaseBy = (value: number) => {
+ setCounter(prev => Math.max(prev + value, 0));
+ }
+
+ return { counter, increaseBy }
+}
+
+export default useProducts
\ No newline at end of file
diff --git a/src/02-component-patterns/interfaces/interfaces.ts b/src/02-component-patterns/interfaces/interfaces.ts
new file mode 100644
index 000000000..c4110c489
--- /dev/null
+++ b/src/02-component-patterns/interfaces/interfaces.ts
@@ -0,0 +1,30 @@
+import { ReactElement } from "react";
+
+export interface IProductCardContext {
+ product: Product;
+ counter: number;
+ increaseBy: (value: number) => void;
+}
+
+export interface IProductCardProps {
+ product: Product;
+ children?: ReactElement | ReactElement[];
+}
+
+interface Product {
+ id: number;
+ title?: string;
+ img?: string;
+}
+
+export interface ProductCardButtons {
+ counter: number;
+ increaseBy: (value: number) => void;
+}
+
+export interface IProductCardHOC {
+ ({ product, children }: IProductCardProps): JSX.Element;
+ Image: ({ image }: { image?: string }) => JSX.Element;
+ Title: ({ title }: { title?: string }) => JSX.Element;
+ Buttons: () => JSX.Element;
+}
diff --git a/src/02-component-patterns/pages/About.tsx b/src/02-component-patterns/pages/About.tsx
new file mode 100644
index 000000000..611fd846f
--- /dev/null
+++ b/src/02-component-patterns/pages/About.tsx
@@ -0,0 +1,7 @@
+const About = () => {
+ return (
+
About Page
+ )
+}
+
+export default About;
\ No newline at end of file
diff --git a/src/02-component-patterns/pages/Home.tsx b/src/02-component-patterns/pages/Home.tsx
new file mode 100644
index 000000000..34837a699
--- /dev/null
+++ b/src/02-component-patterns/pages/Home.tsx
@@ -0,0 +1,7 @@
+const Home = () => {
+ return (
+