No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Curso Profesional de Next.js

Curso Profesional de Next.js

Oscar Barajas Tavares

Oscar Barajas Tavares

Conexión del modal para crear productos

19/31
Recursos

Aportes 16

Preguntas 2

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

o inicia sesión.

Honestamente ya me tiene harto que cada 2 minutos diga “elementos clave”. Ya me distrae, no me deja concentrarme.

Para colocar el icono de “+” en Add product utilice:

import { PlusIcon } from '@heroicons/react/solid';

Y dentro del button:

<PlusIcon className="-ml-1 mr-2 h-5 w-5" aria-hidden="true" />
Add Product

No me queda duda que Oscar es buen dev, pero en sus clases habla mucho, más de lo necesario y sinceramente hasta me llega abrumar jaja

La verdad estoy harto de la pronunciación desastrosa del inglés, además de que siempre dice lo mismo:
OBVIAMENTE
RECURSO
PERTINENTE
.
En todas las clases habla y habla y no dice nada importante, puro relleno.
Lo único que logra es desconcentrar y estirar el video innecesariamente.

Clase #19: Conexión del modal para crear productos 19/31 💬



 

Continuando con el proyecto: 🔨

 
Ya tenemos la estructura del dashboard, pero lo que se quiere es que al dar click en Products en el Menú de la Página entre a la dirección: /dashboard/products, así que en VSC, vamos a la ruta src/pages/dashboard y creamos el archivo products.js, dentro creamos la estructura de la función:

export default function produts() {
	return(
		<>
		
		</>
	);
}

 
Vamos al archivo index.js de la ruta src/pages/dashboard y cortamos todo lo referente a productos desde el primer <div> hasta el último </div> y lo pegamos dentro del return() de products.js
 
Luego vamos a la página de TailwindUI (enlace: aquí), en la parte del código <>Code al dar en “react” nos muestra el código del “Page Headings” que queremos, copiamos todos los import y pegamos en products.js al principio del archivo (borrar aquellos elementos que no se usaran o que se han eliminado).
 
También seleccionamos toda la parte del return de “Page Headings”, copiamos y lo pegamos encima de lo que pegamos proveniente del index.js
 
Ahí borramos todo lo que corresponde a la etiqueta <Menu></Menu>, de los 3 botones que tiene, borramos los botones de “Edit” y “View” y editamos el botón de “Publish” por Add Product.
 
Si queremos cambiar el icono que sale en el recuadro azul de “Add Product”, revisamos la página de Hero Icons (enlace: aquí) y escoger cual icono queremos colocar, también se puede revisar en la carpeta del proyecto en la ruta src/node_modules/@heroicons/react/solid y buscar el nombre del icono, en mi caso seleccioné el icono DocumentAddIcon, para ello se debe agregar primero el import:

import { DocumentAddIcon } from '@heroicons/react/solid';

 
Y en la etiqueta se cambió <CheckIcon /> por:

<DocumentAddIcon className="-ml-1 mr-2 h-5 w-5" aria-hidden="true" />

 
También se debe borrar todos los <div></div> relacionados con los títulos y etiquetas como: Back and Developer, Full Time, Remote, $120, Closing on January …
 
Se agregará un dialogo de forma que al dar click en el botón de “Add Product” aparezca una ventana emergente. Para ello, se utilizará el recurso del Modal.js de la ruta src/commons
 
En products.js agregamos el import del Modal:

import Modal from '@common/Modal';

 
Dentro de la función products() antes del return se agregan las constantes:

const [open, setOpen] = useState(false);
const [products, setProducts] = useState([]);

 
Dentro del return, en la parte del botón Add Product, dentro de la etiqueta <button > se agrega la acción que queremos que aparezca el dialogo:

onClick={() => setOpen(true)

 
La etiqueta de <Modal></Modal> la agregamos después del último </div> del return:

<Modal open={open} setOpen={setOpen}>
<h1>Cero estrés, you can do it!</h1>
</Modal>

 
Dato: el profesor agregó en el className del primer <div> un margen bottom de 2rem con el “mb-8” en el enlace (aquí) describen esas unidades.
 
Guardamos todo y ejecutamos en consola npm run dev, cuando entremos a la página de local, no entrar en “Log in”, si no directamente a Products del Panel superior, entra directamente al recuadro que creamos y debe aparecer la ventanita emergente cuando le das click al botón Add Product (dentro del botón el icono cambió al icono que se seleccionó de Hero Icons).

Elementos clave.

Saludos compañeros, si alguno tiene problemas para que se ejecute el Modal, en la versión de React 18 no corre el Headless UI y Dialog, pueden utilizar la versión 17 para continuar con el proyecto, para bajarlo a la versión anterior:
npm install [email protected] [email protected]

Si quieren pueden agregar un nuevo prop con el nombre del titulo para que quede así:

Lo que hice fue en el componente de Modal.js agregue la nueva prop “title”

export default function Modal({ open, setOpen, title, children }:any) {
	return(...
}

y Luego por allá en el medio del modal, donde está la x del boton de cerrar, agregué el title…

<div className="bg-gray-50 px-4 py-3 sm:px-6 sm:flex  justify-between">
	<Dialog.Title as="h2" className="text-lg font-medium leading-6 text-gray-900">
        	{title}
        </Dialog.Title>
        <XCircleIcon aria-hidden="true" onClick={() => setOpen(false)} />
</div> 

quite las clases que tenía el XCircleIcon para el ejemplo.

Luego ya solo queda asignarle el valor en el

<Modal title={"Add Product"} open={open} setOpen={setOpen}>
<h1>Hola Mundo</h1>
</Modal>

Al que le salga este error, solo cambia esto:

import { Modal } from '@common/Modal';

por esto:

import Modal from '@common/Modal';

Bueno… en el siguiente link, obviamente, de Tailwind UI… vas a poder encontrar, los elementos clave, para, obviamente, poder encontrar los recursos pertinentes, para, obviamente, desarrollar nuestro aplicativo.
https://tailwindui.com/components/application-ui/headings/page-headings

Para los que les aparezca este aviso

deben hacer lo siguiente

import { XCircleIcon } from '@heroicons/react/24/solid';

Si no les sale la interfaz como en el minuto 6:10 es por que quiza como yo, están usando la versión 1 de los iconos, y en esa versión no existe el MapPinIcon, se debe cambiar por un LocationMarkerIcon y ya con eso funciona. Claro al final se borra y no lo necesitamos pero pueden frustrarse un poco si no les sale al principio.

Miro algunos comentarios donde “puntualizan” algunos aspectos en los que no se hallan conformes con la forma de enseñar de Oscar.
Les invito a tomar otra perpectiva:
Estamos mirando a un desarrollador experimentado hacer su trabajo y como procesa los obstaculos.
Para muchos que estamos empezando resulta muy beneficioso.
Si puede mejorar en ser mucho mas directo, pero no resta mayor valor al curso en si.
Saludos

Codigo de la clase.

import { Fragment, useState } from 'react';
import { CheckIcon } from '@heroicons/react/solid';
import { PlusIcon } from '@heroicons/react/solid';
import Modal from '@common/Modal';

export default function products() {
  const [open, setOpen] = useState(false);
  const [products, setPorducts] = useState([]);
  return (
    <>
      <div className="lg:flex lg:items-center lg:justify-between mb-8">
        <div className="flex-1 min-w-0">
          <h2 className="text-2xl font-bold leading-7 text-gray-900 sm:text-3xl sm:truncate">List of product</h2>
        </div>
        <div className="mt-5 flex lg:mt-0 lg:ml-4">
          <span className="sm:ml-3">
            <button
              type="button"
              className="inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
              onClick={() => setOpen(true)}
            >
              <CheckIcon className="-ml-1 mr-2 h-5 w-5" aria-hidden="true" />
              <PlusIcon className="-ml-1 mr-2 h-5 w-5" aria-hidden="true" />
              add Product
            </button>
          </span>
        </div>
      </div>
      <div className="flex flex-col">
        <div className="-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
          <div className="py-2 align-middle inline-block min-w-full sm:px-6 lg:px-8">
            <div className="shadow overflow-hidden border-b border-gray-200 sm:rounded-lg">
              <table className="min-w-full divide-y divide-gray-200">
                <thead className="bg-gray-50">
                  <tr>
                    <th scope="col" className="px-6 py-3 text-left  text-xs font-medium text-gray-500 uppercase tracking-wider">
                      Name
                    </th>
                    <th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                      Category
                    </th>
                    <th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                      Price
                    </th>
                    <th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                      Id
                    </th>
                    <th scope="col" className="relative px-6 py-3">
                      <span className="sr-only">Edit</span>
                    </th>
                    <th scope="col" className="relative px-6 py-3">
                      <span className="sr-only">Delete</span>
                    </th>
                  </tr>
                </thead>
                <tbody className="bg-white divide-y divide-gray-200">
                  {products?.map((product) => (
                    <tr key={`Product-item-${product.id}`}>
                      <td className="px-6 py-4 whitespace-nowrap">
                        <div className="flex items-center">
                          <div className="flex-shrink-0 h-10 w-10">
                            <img className="h-10 w-10 rounded-full" src={product.images[0]} alt="" />
                          </div>
                          <div className="ml-4">
                            <div className="text-sm font-medium text-gray-900">{product.title}</div>
                          </div>
                        </div>
                      </td>
                      <td className="px-6 py-4 whitespace-nowrap">
                        <div className="text-sm text-gray-900">{product.category.name}</div>
                      </td>
                      <td className="px-6 py-4 whitespace-nowrap">
                        <span className="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">${product.price}</span>
                      </td>
                      <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{product.id}</td>
                      <td className="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
                        <a href="#" className="text-indigo-600 hover:text-indigo-900">
                          Edit
                        </a>
                      </td>
                      <td className="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
                        <a href="#" className="text-indigo-600 hover:text-indigo-900">
                          Delete
                        </a>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          </div>
        </div>
      </div>
      <Modal open={open} setOpen={setOpen}>
        <h1>Hola, mundo</h1>
      </Modal>
    </>
  );
}

aporte de la clase…