Desarrollando un clon de instagram en React II - Desarrollando los Nav
Tags: react, instagram, clon, javascript
Published: 2023-01-31 18:45:05

Comenzamos con el post número dos de nuestra pequeña aventura.

En este post veremos como desarrollar el `<NavbarBottom>` y el `<NavbarTop>`.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yacqm5edd3hpruinsyvc.png)

Antes de nada, necesitamos los iconos para los distintos botones de la aplicación.

Estos los podemos sacar de la aplicación web de instagram, son SVGs, por lo que copiaremos el svg, crearemos un archivo svg por cada elemento dentro de la carpeta `assets`, (más adelante manejaremos mejor los ficheros) e insertaremos el código.

Os dejaré por aquí los SVG de los distintos iconos para que los tengais.

Home:

```svg
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24" width="24" height="24">
<path d="M22 23h-6.001a1 1 0 0 1-1-1v-5.455a2.997 2.997 0 1 0-5.993 0V22a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V11.543a1.002 1.002 0 0 1 .31-.724l10-9.543a1.001 1.001 0 0 1 1.38 0l10 9.543a1.002 1.002 0 0 1 .31.724V22a1 1 0 0 1-1 1Z"></path></svg>
```

Search:

```svg
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24" width="24" height="24"><path d="M19 10.5A8.5 8.5 0 1 1 10.5 2a8.5 8.5 0 0 1 8.5 8.5Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"></path><line fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" x1="16.511" x2="22" y1="16.511" y2="22"></line></svg>
```

Reels:

```svg
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24" width="24" height="24">
<line fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="2" x1="2.049" x2="21.95" y1="7.002" y2="7.002"></line><line fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" x1="13.504" x2="16.362" y1="2.001" y2="7.002"></line><line fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" x1="7.207" x2="10.002" y1="2.11" y2="7.002"></line><path d="M2 12.001v3.449c0 2.849.698 4.006 1.606 4.945.94.908 2.098 1.607 4.946 1.607h6.896c2.848 0 4.006-.699 4.946-1.607.908-.939 1.606-2.096 1.606-4.945V8.552c0-2.848-.698-4.006-1.606-4.945C19.454 2.699 18.296 2 15.448 2H8.552c-2.848 0-4.006.699-4.946 1.607C2.698 4.546 2 5.704 2 8.552Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"></path><path d="M9.763 17.664a.908.908 0 0 1-.454-.787V11.63a.909.909 0 0 1 1.364-.788l4.545 2.624a.909.909 0 0 1 0 1.575l-4.545 2.624a.91.91 0 0 1-.91 0Z" fill-rule="evenodd"></path></svg>
```

Messages:

```svg
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24" width="24" height="24"><path d="M22.91 2.388a.69.69 0 0 0-.597-.347l-20.625.002a.687.687 0 0 0-.482 1.178L7.26 9.16a.686.686 0 0 0 .778.128l7.612-3.657a.723.723 0 0 1 .937.248.688.688 0 0 1-.225.932l-7.144 4.52a.69.69 0 0 0-.3.743l2.102 8.692a.687.687 0 0 0 .566.518.655.655 0 0 0 .103.008.686.686 0 0 0 .59-.337L22.903 3.08a.688.688 0 0 0 .007-.692" fill-rule="evenodd"></path></svg>
```

Y por último, para la foto de perfil, podeis utilizar la imagen que queráis.


Ahora que ya tenemos las imagenes, vamos con el desarrollo del componente:

Para comenzar, creamos una carpeta en la raíz, que llamaremos `components`. En esta carpeta, guardaremos todos los componentes generales, que se utilizan en varias páginas, de acuerdo con la arquitectura que vamos a utilizar, Clean Architecture.

Dentro de `components`, vamos a crear otra carpeta que llamaremos `NavbarBottom`, y dentro de ella, vamos a crear el fichero jsx y el css.

`NavbarBottom.jsx` y `NavbarBottom.css`.


Para el desarrollo de los componentes, utilizaremos arrow functions.

Asi que comenzamos el inicio del componente con el siguiente código:

```javascript
const NavbarBottom = () => {
  return (
    <footer>
    </footer>
  );
};

export default NavbarBottom;
```

El próximo paso será insertar las imagenes, que posteriormente serán botones, pero por ahora, insertaremos las cinco imagenes dentro del footer e importaremos los svg que guardamos antes en la carpeta `assets`. Además, pondre una constante llamada `URL_IMAGE_PROFILE_ICON` en la que guardaré la url de la imagen de perfil.

Ya que estamos, importaremos `NavbarBottom.css`, que hemos creado antes, para estilar luego el navbar.

```javascript
import "./NavbarBottom.css";
import home from "../../assets/home.svg";
import search from "../../assets/search.svg";
import reels from "../../assets/reels.svg";
import messages from "../../assets/messages.svg";

const URL_IMAGE_PROFILE_ICON =
  "https://img.freepik.com/free-photo/portrait-happy-young-woman-looking-camera_23-2147892777.jpg?w=2000";

const NavbarBottom = () => {
  return (
    <footer>
      <img src={home} />
      <img src={search} />
      <img src={reels} />
      <img src={messages} />
      <img src={URL_IMAGE_PROFILE_ICON} id="profile_icon" />
    </footer>
  );
};

export default NavbarBottom;

```

En este momento, tenemos el componente listo, solo quedaría darle los estilos.

Para ello, comenzamos con el footer, vamos a comenzar con la posición. En instagram, este menú esta en la parte de abajo de la app, y su comportamiento es flotante, siempre está aunque se haga scroll.

Asi que, vamos a darle el siguiente estilo:

```css
footer {
    width: 100%;
    position: sticky;
    bottom: 0;
    z-index: 5;
    background-color: white;
}
```

Lo siguiente a incorporar a nuestro footer, es `flex`, para que los iconos se alineen, y justificaremos el contenido para que ocupe todo el contenedor, respetando los margenes, esto lo realizaremos con `space-around`.

Añadiremos también un padding, para dejar el contenido espaciado, y pondremos en gris el border de arriba, para simular exactamente la estetica de instagram.

```css
footer {
    display: flex;
    width: 100%;
    justify-content: space-around;
    position: sticky;
    left: 0;
    bottom: 0;
    z-index: 5;
    padding: 10px 0 10px 0;
    border-top: 0.3px solid rgb(213, 213, 213);
    background-color: white;
}
```
Por último, estilaremos la imagen de perfil, para darle un tamaño de 24px y que sea rendondeada.

Para ello, daremos un id a la imagen, en este caso, #profile_icon.

```css
footer #profile_icon {
    width: 24px;
    height: 24px;
    border-radius: 100%;
}
```

Con esto, tenemos nuestro componente listo!


Ahora, seguimos con el componente `<NavbarTop>`, que tiene un aspecto muy parecido al otro componente.

Para comenzar, dentro de la carpeta `components`, vamos a crear una nueva carpeta con el nombre `NavbarTop`.

Una vez creada, crearemos los ficheros `NavbarTop.jsx` y `NavbarTop.css`.

Este componente es bastante sencillo, contiene el logo de Instagram a la izquierda, y luego a la derecha, el botón de añadir historia, el botón para ver las interacciones que han tenido contigo y por último, el botón para ver los mensajes directos.

Comenzamos abriendo el archivo `NavbarTop.jsx` y creamos la función junto con el import del archivo `NavbarTop.css`, y exportamos la función.

```javascript
import "./NavbarTop.css";

const NavbarTop = () => {
  return (
  );
};

export default NavbarTop;
```

Lo siguiente será importar los iconos que vamos a utilizar, y que hemos mencionado más arriba.

```javascript
import "./NavbarTop.css";
import logo from "../../assets/logo.svg";
import heart from "../../assets/heart.svg";
import messages from "../../assets/messages.svg";
import add from "../../assets/add.svg";

const NavbarTop = () => {
  return (
  );
};

export default NavbarTop;
```

Ahora que tenemos todos lo necesario, vamos a plantear como realizar el componente.

Crearemos un nav con el logo, y después, crearemos un div con un id `right_buttoms` en el que insertaremos los botones de la derecha.

¿Por que creamos un div para los botones de la derecha?
Por que de esta manera, podemos poner el contenedor padre con flex, justificar el contenido con `justify-content: space-between`, y queda el logo a la izquierda del todo, y el div con los botones a la derecha del todo.

Ya el siguiente paso sería poner un `display: flex` al div `right_buttons` y tendríamos la estructura creada.

El nav le daremos un `position: sticky` para que se quede fijo arriba, tal y como tiene el comportamiento en Instagram y daremos un padding por arriba y por abajo de 10px con `padding: 10px 0 10px 0`.

Con estas instrucciones, el componente quedaría así:

```javascript
import "./NavbarTop.css";
import logo from "../../assets/logo.svg";
import heart from "../../assets/heart.svg";
import messages from "../../assets/messages.svg";
import add from "../../assets/add.svg";
const NavbarTop = () => {
  return (
    <nav>
      <img src={logo} id="navbar--logo" />
      <div id="right_buttons">
        <img src={add} />
        <img src={heart} />
        <img src={messages} />
      </div>
    </nav>
  );
};

export default NavbarTop;
```

Se ha añadido un id al tag img del logo, para poder añadir un `margin-left: 10px`, y que quede exactamente como en instagram.

Ahora, veamos como quedó el css con las instrucciones de arriba.

```css
nav {
    width: 100%;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 10px 0 10px 0;
    position: sticky;
    top: 0;
    background-color: white;
}

nav #right_buttons {
    display: flex;
}

nav #right_buttons img {
    padding: 0 10px 0 10px;
}

#navbar--logo {
    margin-left: 10px;
}
```

Hemos añadido a los distintos botones de la derecha, un padding para que no estuvieran juntos.

De este modo, hemos creado los dos navs principales de nuestro clon de instagram.


Espero que os haya gustado la segunda entrada del post, y para el próximo post, crearemos las rutas de la aplicación con `react-router-dom`, para ir colocando los componentes en las distintas páginas.

El enlace al repositorio os lo dejo por aquí, podeis aportar cualquier cambio mediante pull request.

[Repositorio clone-instagram-react](https://github.com/robertomsen/clone-instagram-react)