This graph shows how many times the word ______ has been mentioned throughout the history of the program.
que ha hecho un test a este nivel,
para mí no pasa la prueba técnica.
¡Pretísimo!
Pues hoy vamos a mirar pruebas técnicas.
Pruebas técnicas de programación
para que practiques tus habilidades de programación
con pruebas técnicas de empresas reales, ¿vale?
Que puedas utilizar el stack que prefieras y tal.
Porque habéis entregado, amigos,
habéis entregado la violera de 250 pruebas.
¿Pero qué salvajada es esta?
¡250 pruebas!
A ver, ya os voy a explicar una cosa.
Solo me ha dado tiempo a verme tres páginas.
Había 10 y solo me ha dado tiempo a ver tres.
Hoy yo ya he detectado,
porque viendo un poco el tema y eso,
he dicho, mira,
hoy vamos a estar revisando los errores más comunes.
Vamos a ver código, vamos a ver URLs y tal.
Vamos a ver cosas buenas también que la gente ha hecho,
que ha hecho mucho.
O sea, la verdad, estoy muy sorprendido
con el nivel de las soluciones que habéis hecho.
Es increíble, amigos.
Las 250 soluciones que habéis enviado.
O sea, de verdad, hay soluciones de muy alta calidad.
No sé si esta será.
Mira, mira, esta.
Somos Lapse Editorial.
O sea, este ha creado como si fuese realmente una editorial.
Aquí lo tenemos, de Dan Mondra.
Y fijaos, con un diseño súper bonito.
Me gusta mucho cómo se pone por encima cuando haces el hover.
¿Vale?
Y le das y te pone aquí el detalle.
Fijaos la animación.
Espectacular, ¿eh?
Súper, súper bonita.
Filosofía.
¿Vale?
Le puedes dar aquí para guardarlo.
¿Ves?
Y súper bien, súper bien.
La verdad, tremendo, ¿eh?
Tremendo.
Tremendo cómo lo ha hecho.
Aquí están, además, todos los contadores.
Le puedes dar a mis listas.
Y se mueve un poco la página.
La verdad, el diseño de esta de Dan Mondra, tremendo, ¿eh?
Yo me he quedado alucinando de, joder, la gente.
Pero, Dios mío, ¿cómo mueven las manitas?
Y, además, me gusta la idea de que se ha puesto en el pellejo de que ya es la editorial, ¿no?
Para la gente que no lo sepa.
Tenemos una página web que se llama pruebastécnicas.com.
Donde vamos a estar subiendo pruebas técnicas basadas en empresas reales.
Y aquí la primera que dijimos era la lista de lectura.
Implementar una pequeña aplicación de lista de libros utilizando el framework de frontend de tu elección.
Lo que tú quisieras, podrías utilizar aquí.
Y hay gente que utiliza React, Svelte, Vue, Angular.
Hay de todo.
De hecho, tengo algunos ejemplos de Angular y todo.
Y los vamos a ver, ¿vale?
El tema es que cuando le das clic, aquí tienes toda la prueba técnica con un posible diseño.
Que te explica cómo participar.
Cómo que está, de qué nivel es.
Es para Juniors.
El contexto de la prueba.
Los requisitos de la prueba.
Los consejos sobre el código.
Digo, desafíos adicionales.
Entrevista en el caso de que pasase.
Y luego referencias para continuar, ¿vale?
Y aquí teníamos el JSON con todos los libros.
Que esto, la verdad, que lo ha usado todo el mundo.
Hay gente que lo ha ampliado.
Hay gente que lo ha llevado a otro nivel y tal.
Así que un poquito de esto, ¿no?
Pues el caso es que habéis enviado 250.
250 pruebas.
No me ha dado tiempo a revisarlas todas.
Ya os digo que he revisado las tres primeras páginas donde me he estado mirando el código.
Están mirando ejemplos.
Y hoy vamos a hablar un poco de los errores más comunes que cometéis.
Vamos a mirar código.
Vamos a mirar semántica.
UX.
Cosas buenas.
Los test que habéis hecho.
CSS Modus.
Yo qué sé.
Pero primero que nada, os quiero dar a todos y a todas la enhorabuena.
Que está súper bien.
El nivel, ya os digo, que ha sido muy alto.
Este, por ejemplo, este es uno que os estaba enseñando ahora.
Que es de los últimos, donde la gente puede poner el libro leído, el libro no sé qué.
Y la verdad, con un montón de animaciones, muy bien integrado.
Me ha gustado bastante esta prueba.
Esta prueba está hecha con Bit, ¿vale?
Está hecha con React.
También el código muy chulo.
La verdad es que el código bastante, bastante, bastante bien.
Muy bien estructurado.
Muchos componentes.
De eso hablaremos, ¿vale?
De cuáles son los errores más típicos que habéis cometido a la hora de hacer las pruebas.
Mira, utilizando un montón de constantes.
Veis aquí, action, action no sé qué, action no sé cuánto.
Un montón de constantes a la hora de trabajar con esto.
Mira, aquí tenemos las constantes.
¿Vale?
Un montón de constantes.
Muy bien.
Un error muy común que he visto por ahí es el hecho de que utilizáis todavía muchos Magic Strings.
Y me sorprende, porque mira que soy muy pesado con eso.
O sea, no está bien.
No está bien porque al final, si cambia el string, vas a tener que reemplazarlo a todos los sitios.
Y aquí, además, os voy a decir una cosa.
Que gente que no tiene puñetera idea dice una chorrada como un templo muchas veces.
No te dejes llevar por esto, ¿vale?
Imagínate que tenemos aquí el filter, filter y all, ¿no?
Este.
Esto es un Magic String que se le llama.
Y os voy a explicar por qué es mala práctica la solución que mucha gente dice como si no fuese tan importante, ¿vale?
Imagínate que tú te pones filter, filter, igual o filter all, ¿no?
Y entonces tú estás aquí y dices cuando el index es, yo qué sé, y pones aquí, bueno, cuando el filter.
El filter selected es all, ¿vale?
Otra vez.
Aquí tenemos otra vez esto.
Otro Magic String.
¿Por qué se le llama Magic String?
Se le llama Magic String porque es una cadena de texto mágica.
Que no sabes a qué corresponde, no sabes de dónde sale, no sabes qué poder divino tiene que significa lo que significa, ¿no?
O sea, esta cadena de texto significa todos los filtros.
En lugar de hacer esto, lo que hay que hacer en su lugar sería tener más bien, pues, oye, tienes una carpeta que puede ser constantes y aquí podríamos tener, pues, filters, ¿vale?
Filters.js.
Y tú aquí haces Export Cons, All Filters.
Filters selected.
Y esto lo pones aquí una sola vez.
Y a partir de ahora, en todos los sitios, tú te vas a referir a este filtro, te vas a referir así.
¿Por qué?
Porque ahora, cuando cambie este filtro, ya sea que por lo que sea, imagínate que cambia, o everything, por lo que sea, ¿vale?
Ya lo tienes en un solo sitio.
Eso para empezar.
Pero a lo mejor no cambia nunca.
Y aunque no cambie nunca, también no hace falta que te acuerdes si es all, si es everything, si es all y te equivocas al ponerlo, ¿no?
O sea, el tema es tener una sola fuente de la verdad, de lo que significa eso, y quitar toda la magia y tenerlo en una constante.
Y entonces ya no es importante cuál es el valor que tienes, sino que lo importante es a lo que te refieres.
Hay gente que dice, esto es una tontería, porque si cambia all por everything, pues lo que hago es buscar all en todo mi proyecto y lo cambio.
Pues no, tío, no vayas de listo.
No es así.
Eso es una tontería lo que estás diciendo, ¿por qué?
Por dos motivos.
Lo primero, si tú buscas la palabra all en tu proyecto, no vas a saber cuál es el que tienes que cambiar y cuál es el que no tienes que cambiar.
Y vas a tener que ir discriminando y lo más fácil que te puede pasar es que te equivoques.
Pero si fíjate que este proyecto es enano y ya me están saliendo aquí un montón de alls, que ya no sé si son alls que son que debería cambiar o que no debería cambiar.
Bueno, pero entonces busco así y ya está.
Bueno, pues te pasa lo mismo.
Mira, aquí me sale el software.
Tú nunca sabes si esto va a ocurrir, ¿sabes?
O sea que hardcodear y luego decir eso que con un fine and replace se arregla es no tener ni puta idea de la vida.
Entonces, no diga chorrada.
No me enojo, pero que no hagáis caso de pensar que el fine and replace arregla esto porque no es verdad.
No es verdad.
Tú imagínate que por lo que sea el filter selected es text, por decir uno.
Y tú buscas aquí text y venga, ala, venga, ¿ahora qué?
Venga, fine and replace.
Te reto a que hagas el fine and replace.
No me enojo, casi se le revienta una vena a mi dulul.
Qué va, qué va.
Sí, no me habéis visto enfadado nunca.
No me habéis visto enfadado nunca de verdad.
En fin, que por eso puede ser una buena idea hacer esto, ¿vale?
¿Y por qué hablo de esto?
Hablo de esto porque justo cosas como esta, ¿no?
Pues está bastante bien porque aquí sí list IDs, books to be read, ¿ves?
Lo tiene aquí.
Esto tiene sentido y está súper, súper chulo.
Es un poco raro, esto sí que os digo, ¿eh?
Otro error muy común que he visto en vuestras pruebas técnicas y vuestras soluciones
es el hecho de confundir lo que son constantes con utilidades y servicios.
Es un poco raro.
Por ejemplo, veis aquí que pone constants y pone details of list.
Y entonces aquí tiene constantes y de repente, pues dice, bueno, pues voy a meter aquí una función que busca no sé qué.
Es un poco extraño.
O sea, hay que evitar cómo mezclar lo que son constantes a lo que son utilidades, servicios o lo que sea.
Esto es una cosa que habéis repetido mucho.
Lo he visto mucha gente.
Más cositas.
Bueno, aquí está muy bien esto que ha hecho con el contexto porque aquí, bueno, ha utilizado el mock, ¿vale?
Y aquí ha mapeado directamente esto.
A ver, esto está bien.
Básicamente, este proyecto está bastante bien en general.
Tiene el inter, está bastante bien estructurado.
Me gusta que está bastante bien componentizado.
Está muy bien el hecho de cómo exporta los iconos, que esto es una cosa que en general no habéis hecho bien.
Y ahora lo veremos, ¿vale?
Ah, muy bien el Ritmi también.
Otra cosa que os ha costado, ¿eh?
¿Veis aquí el Ritmi que ha hecho?
Mira, para una editorial sus libros son como los árboles a los pa...
O sea, muy bien este Ritmi, ¿eh?
Fijaos.
Es por eso que me tomé este proyecto en serio para desarrollar una web que disfruté basándome en la suposición que la editorial realmente...
O sea, muy bien.
Esto es un error muy común, muy común, que habéis cometido.
Si en el proyecto, en la prueba técnica, os está pidiendo que hagáis un Ritmi, lo hacéis.
Que lo ha hecho en ChatGPT.
Pero es que al menos lo ha hecho.
Da igual que lo haya hecho en ChatGPT.
Es que la gente no lo ha hecho.
O me ha dejado el Ritmi de NXDS.
Entonces, está bien porque al menos ha hecho esto, pero, pero, un error muy común que habéis cometido en el Ritmi, ¿vale?
En la prueba técnica, fijaos, en la prueba técnica que pusimos por aquí, había una cosita...
Mira, pensando en equipo.
Prepara tu proyecto pensando que cualquier persona de tu equipo puede tener que trabajar en el futuro.
¿Esto qué significa?
Significa que tenéis que explicar al menos cómo levantar el proyecto.
Son tres comandos.
Pues los comandos hay que ponerlos.
Oye, ¿cómo se levanta? ¿Cómo se testea?
¿Necesito algo en concreto?
Pues, está bien lo que ha hecho este chico.
La verdad es que el Ritmi está bastante mejor que muchos.
Pero, le ha faltado un poquito.
Oye, piensa también en el equipo.
Oye, ¿cómo levantarlo?
¿Cuáles son los scripts que tienes que utilizar?
Cualquier cosa, ahí, ese es el sitio donde hay que ponerlo, ¿vale?
De hecho, también tiene test.
Una cosa que también os ha costado, amigos.
Os ha costado.
A ver con este test.
Polémico.
Este test voy a darle un 7.
Un 7.
No está mal.
El test, ¿vale?
No está mal el test.
En la prueba técnica os pedía que teníais que hacer al menos un test.
Al menos uno.
Y aquí ha hecho al menos uno, ¿eh?
En el test no está mal, pero está probando un componente en concreto.
¿Vale?
Está probando ListBook.
Pero claro, la página es todo esto.
¿Qué le costaba renderizar toda la aplicación y ver si está ListBook y realmente hacer algo?
Porque aquí, fijaos que lo único que dice, should render the book in the list with its properties.
Bueno, pero dice render y ¿dónde están los expect?
O sea, no está esperando nada.
Solo está esperando que no pete el render.
Porque pensaba que había un expect.
Le vamos a dar un 3.5.
Le vamos a dar un 3.5, ¿vale?
¿Por qué?
Porque obviamente, obviamente aquí falta mucho, tío.
O sea, aquí te falta algún expect realmente ver si está funcionando.
Está viendo que renderice y que no pete.
Mira, vamos a ver el de Yes.0.15, ¿vale?
La prueba técnica que ha hecho muy bien el Linter.
Está bastante bien de código.
Muy bien los test.
Este hombre se ha tomado muy en serio el tema del testing.
De hecho, tiene muchos test.
Lo ha hecho con Vtest.
La verdad es que todo el tema de testing es...
Si tenéis dudas de cómo hacer testing, está muy bien porque hay un montón.
Está muy completo y a mí, sinceramente, me ha sorprendido bastante.
De que todos los componentes, veis, aquí tenéis el de filtros.test.
Y mira, aquí los está testeando.
El bug, pues también aquí tenéis todo testeado.
Otra cosa que me ha sorprendido para bien, porque, bueno, últimamente siempre lo hacemos todo con Tailwind.
Y me ha gustado lo que he visto.
Ha sido el tema de que ha utilizado CSS Modules.
Pero no solo ha utilizado CSS Modules, sino que realmente el CSS que estaba utilizando lo estaba haciendo súper bien.
Estaba utilizando scroll snap, estaba utilizando cosas así bastante modernillas.
La semántica del HTML también estaba bastante bien.
O sea, veis, con section header, el main, donde realmente tiene que ir el main, donde dentro está la lista de libros.
Cosas a mejorar.
Mira, en este caso, veis aquí constantes.
Aquí, veis, tendríamos aquí la constante, que sí, que aquí serían como los géneros.
Pero es un poco raro, no he entendido muy bien.
O sea, aquí tenía como una función autogenerada, o sea, que se autoinvocaba y tal.
O sea, esto era un poquito raro.
No he entendido muy bien por qué necesitaba esto.
Pero bueno, no sé si es por un tema de testing que le ayudaba.
Vamos a decirle a Jess alguna cosita.
Me ha dado bastante pena, porque viendo el código tenía pintaza.
Pero el problema es que cuando entras a la página, fíjate cómo se ve la página.
¡Se ve vacía!
Es muy importante.
Claro, tú puedes tener un montón de test, pero si la UX no invita a probar el producto, pues complicado, ¿vale?
Entonces, primero, que esto lo habéis hecho muchos.
El título.
El título es básico.
Empezad por el título, ¿vale?
Está vacío como tu corazón, ¿no, Armando?
Pues esto, al final, claro, tú entras aquí y mi primera sensación aquí fue como que no funcionaba.
Y no, es que resulta que están aquí los libros.
Le daría un poco la vuelta a esto.
O sea, los libros estos los pondría arriba.
Luego ha habido otro error, yo creo que de contenedores y tal, importante de la UX, es que fijaos que hay dos scrolls.
Os lo voy a enseñar, a ver si soy capaz.
Bueno, ahora no soy capaz.
Pero al menos en esta resolución hay dos scrolls, ¿veis?
Hay uno aquí y otro a nivel de toda la página.
Y queda muy raro.
Y luego los fallos de ortografía para una prueba técnica están prohibidos.
Están prohibidos.
Mezclar inglés con español y tal.
A ver, sé que es una chorrada, es una tontería, no pasa nada porque nosotros estamos aquí, jijijaja.
Pero para una prueba técnica donde cualquier cosa visual va a llamar mucho la atención, mezclar inglés con español, cosas así, ¿no?
Entonces, de código está muy bien esta prueba, pero hay que darle cañita también al BOE.
Muy bonita, esta de Facu Pérez, aunque es sencilla, pero es muy bonita.
Universo literario, sumérgete en las páginas de sabiduría y aventura.
Muy bien la presentación, minimalista, sencilla, sin complicaciones.
O sea, pim, pam, así lo dejamos.
¿Vale?
Añadir a la lista.
Y aquí, ¿veis?
Queda claro el remover.
Aquí en la lista de lectura se ha actualizado esto.
Podemos ir a la lista de lectura.
Aparecen aquí.
Lo podemos de nuevo otra vez, esta mezcla entre español e inglés.
No sé por qué.
Hay pequeños detalles.
Por ejemplo, esto no está bien centrado.
No sé, hay cositas raras.
Este 13 aquí junto al icono.
Pero bueno, estos son temas de UX que tampoco es tan grave.
Aquí el filtro, un error muy común que os he visto, que habéis cometido en las pruebas técnicas,
ha sido el filtro de páginas.
¿Vale?
Vamos a ver algunos ejemplos correctos o que a mí me han gustado.
Pero os ha costado mucho el de páginas.
¿Vale?
Por ejemplo, ¿qué significa este filtro?
Yo no lo entiendo, ¿sabes?
Pensándolo, me imagino es cualquier página que sea mayor de dos.
O sea, cualquier libro que tenga más de dos páginas.
Pero claro, como al principio además no funciona, queda raro, ¿verdad?
Entonces, yo creo que aquí se podría haber hecho diferente o indicar mejor esto, mínimo páginas,
que se entendiese mejor, ¿no?
O seleccionar rangos, por ejemplo.
Los rangos hubiera sido bastante interesante.
No ha terminado de encajar.
Mira, aquí en este caso está muy bien que le ha hecho la página de detalle.
Hay fallos de ortografía también por ahí y tal.
Título con acento, atrás.
Mira, yo sé que soy muy pesado con las faltas de ortografía y la gente me dirá, joder, qué pesado eres y tal.
Pero, pero, amigos, en una prueba técnica lo van a tener en cuenta, lo van a ver.
O sea, lo van a ver.
Lo van a ver y lo sé porque yo he estado revisando pruebas técnicas así.
Yo, personalmente, no soy una persona que le pone el foco porque, sinceramente, no me parece lo más importante.
Y dependiendo qué falta de ortografía, tampoco le da tanta importancia.
Pero es verdad que hay gente que cree que si tiene falta de ortografía significa que eres descuidado, que no te miras muy bien las cosas, ¿sabes?
Entonces, no cuesta nada al menos evitarlas.
Así que, por eso os diría, por ejemplo, tenéis en Visual Studio Code hay una extensión que os ve la falta de ortografía.
Así que echadle un vistazo.
Bueno, este proyecto, que ahora lo hemos visto visual, pero vamos a ver un poco el código.
Vamos a ver un tema, vale, vamos a ver un tema.
Si no me equivoco, este está hecho con React y con Radix, ¿vale?
Pero lo que os quiero enseñar es una cosa que habéis hecho muchos y os voy a decir, esto no está bien.
Y de hecho, voy a decir algo polémico, ¿vale?
Que ha hecho un test a este nivel, para mí no pasa la prueba técnica.
Si te están diciendo esto en los requerimientos, que tienes que tener un test en la prueba técnica, haz un test.
Hay gente que ha dicho, voy a hacer un test, pero voy a hacer el que me salga de la leche.
Claro, luego me decís, es que no sé por qué no me han pillado.
A ver, os voy a explicar por qué no se han pillado, ¿vale?
La prueba que estábamos viendo, este es el test que ha hecho.
Este test, con todo mi cariño, para Facu Pérez, que me ha gustado el proyecto en general, ¿vale?
Pero este test es muy flojo, muy flojo.
O sea, y hay peores, ¿eh?
Entiendo que testear un custom hook, pero fíjate que además es un custom hook que se está utilizando aquí,
solo que simplemente te devuelve el array de libros, que lo está llamando y solo está mirando que el array de libros sea mayor a cero.
O sea, no sirve para nada este test.
Este test es inútil.
Es que para eso no haber hecho ninguno.
Pero pensad que si es un requerimiento, un test, si os está pidiendo que hagas el test más importante que consideres,
claro, que le hagas este test, yo creo que no pasaría la prueba, ¿eh?
No significa que no vaya a pasar en otras pruebas técnicas.
Pero yo creo que objetivamente, o sea, no os quiero engañar y deciros que sí, hombre, que no pasa nada.
No, es que no se trata de eso.
La idea de la página esta de pruebas técnicas es que os vaya a dar, pues, directamente una opinión verdadera basada en cómo creo que se suelen mirar este tipo de pruebas.
Sobre todo con los requerimientos.
Lo que quiero es que si el día de mañana hacéis una prueba técnica, que os digan que sí.
Dandev MS.
Este es el proyectito.
Otra vez el error, ¿no?
Del title.
No es grave, pero es que nos cuesta nada.
Es un diseño sobrio, minimalista, normal, ¿vale?
Funcionando.
El add debug, peta, ya, mal.
Significa que el add debug no está testeado, o sea, que regulinchis.
El ritme no es tampoco lo que se pedía, ¿vale?
Además con errores de ortografía, pero esto no es el ritme que esperamos.
Que sí que he visto que tiene cosas bien, tiene cosas interesantes, también está hecho con bit, está hecho con react.
Muy bien el tema de componentizar.
Esto está muy bien porque no lo ha hecho todo el mundo.
O sea, hay gente que ha hecho ahí, en un componente lo ha hecho todo.
Pero le falta semántica.
O sea, una cosa que he encontrado es que todos son dips.
Dip, dip, dip, dip, dip, dip, dip, dip, dip, dip, dip, dip, dip, dip, dip todo el rato.
Pensad que una de las cosas que se pedía en la prueba.
Consejo sobre el código.
El HTML debe ser semántico y accesible.
Aquí tienes una imagen.
Esto puede ser un picture, article, main, section, nav, anchors que están vacíos, que no tienen ningún enlace a ningún sitio.
O sea, que temas de accesibilidad da problemas.
Demasiada falta de semántica, ¿vale?
Otro error muy común que he visto, ¿vale?
Y que esto es importante que lo revisemos, ¿vale?
El tema de sacar la lógica.
Contexto, claro.
Fijaos aquí la de lógica que tiene el contexto cuando una de las cosas que os dice en la prueba,
no sabemos si el framework que utilicemos ahora será el definitivo.
Pero querremos reutilizar el máximo de código disponible.
No lo habéis hecho, ¿vale?
En general, hay gente que sí.
Ya os digo que no me he dado tiempo a verlos todos.
Pero hay muchas veces que no habéis separado la lógica, pero nada.
Muchas veces lo que habéis pensado es, mira, es que esto, claro, este custom hook.
Y lo que habéis hecho es meterlo en componentes, a lo mejor como mucho en un custom hook.
Pero claro, no es lo que se pedía exactamente, ¿eh?
Mira, otro ejemplo de este es de Joaquín, pero que ha pasado lo mismo, ¿no?
Ha pasado que vamos en el test, o sea, todo tiene buena pinta,
y resulta que el test más importante es un helper de sendMessage que describe, dice,
tiene que ser una función.
La función tiene que petar si el primer parámetro no es un objeto.
Pero claro, ¿cómo va a ser el test más importante, amigo?
Es una pena porque este, por ejemplo, está bastante bien.
Además está hecho con TypeScript, está también semánticamente bien, bonito.
Y claro, el test es del palo.
No es el Happy Path ni siquiera.
Al final lo que es, es un test muy random.
Este de Álvaro, por ejemplo, otro proyecto que está bastante bien.
En este caso también bien con monetización, o sea, con interfaces, con TypeScript y tal.
Pero un error muy común que he visto que hacéis es el tema de no saber qué hacer con los iconos.
Mirad, vamos a mirar esto porque esto es bastante importante.
Esto lo habéis hecho mucha gente.
Yo no sé esto de dónde sacáis esta idea.
Si es que no os cuesta nada, no os cuesta nada el hecho de cambiar esto y arreglarlo y hacerlo bien.
En lugar de exportar los iconos que es un objeto, lo que podéis hacer es hacer un export const de cada icono.
Y ahora os explico por qué esto es mejor.
Export const, hacéis esto, que podéis poner xicon, yo que sé, podéis ponerle lo que queráis aquí, para que directamente libre icono.
Lo podéis hacer así.
¿Por qué esto es mejor que lo otro?
Claro, ¿qué pasa?
Lo otro lo que hace es que tú vas a tener que importar todos los iconos siempre aunque no los uses.
O sea, en cualquier página, si tú en una página importas los iconos from icons, estos si son, yo que sé, 10k, pues en todas las páginas que los utilices, pues los vas a tener.
En cambio, lo que consigues haciendo este library at icon, xicon, es que tú aquí solo estás importando estos dos iconos.
Y si imagínate que tienes 80 iconos, aquí solo pesan, estos a lo mejor solo pesan 100 bytes.
Así es como funcionaría el tree shaking, porque las cosas que no importas, el resto, no lo va a meter en el bundle o a nivel de páginas.
Si lo tenemos con una importación dinámica de cada una de las páginas con un lazy load.
Una cosa que podéis hacer, porque muchas veces la gente dice, bueno, es que lo quiero hacer así, porque así puedo hacer el icons.library.
Pero bueno, da igual, esto ya tiene autocomplete y si quieres le puedes cambiar a cada uno.
Aquí podrías poner super icon, le puedes cambiar el nombre.
Le pones library at icon as super icon y ya está.
Y ya no tienes problema.
Habéis hecho estos services, getbooks, ¿vale?
Aquí ha hecho un servicio, que está bien, ¿no?
Porque al menos ha separado un servicio en el que lo que está haciendo es devolver una interfaz de libros.
Que por cierto, las interfaces en TypeScript no está recomendado poner la i de interfaz.
Esto normalmente la gente que viene de backend lo hace, pero bueno, que no pasa nada si lo hacéis.
Yo lo digo como recomendación y ya está.
Voy a hacer una recomendación que también os puede servir en vuestro día a día en el mundo de la programación, ¿vale?
Y es interesante también porque está utilizando TypeScript y no se ha dado cuenta de este error.
De cara al futuro, ¿cuál es el problema que creéis que tiene?
¿Vale? Voy a poner aquí interface book y vamos a poner cualquier cosa.
Eso lo pueden usar. Ah, en archivos TypeScript, ¿vale?
¿Cuál es el problema que creéis que tiene este código para el futuro?
No está filtrando los libros, ¿vale? No es tanto los libros, ¿no?
¿Qué es lo que pasa?
Que aquí está importando, claro, de unos datos como moqueados, ¿no?
De un mock. Está moqueando esto y al moquearlo lo que está haciendo es devolverlo directamente.
Mapear. Bueno, podría ser mapear, que eso también es interesante.
Mapear para normalizar los datos de forma que si mañana vienen de otro sitio, pues no tenga que cambiar el contrato.
Y esa es la clave, amigos. El contrato.
¡Muy bien! ¡Muy bien! Lo ha dicho Juli Gudi.
Debería devolver una promesa.
Debería devolver una promesa porque cuando nosotros hacemos una función que tiene datos moqueados, ¿vale?
Tenemos que pensar en el futuro.
Porque el día de mañana este getbooks seguro que va a tener que ser asíncrona.
Porque va a tener que traerlo de una API, base de datos, de donde sea.
Y entonces alguien me dirá, bueno, pero qué chorrada, porque ahora no lo necesita.
Pero imaginad que vosotros lo desarrolláis todo así, con este getbooks y devolvéis esto así, ¿no?
El problema es que en todos los sitios que habéis utilizado el getbooks, confiando que va a ser síncrono,
vais a tener que adaptarlo después cuando venga la API.
¿Por qué? Cuando tengáis que utilizar aquí la API, va a devolver una promesa y la vais a liar.
Esto lo que significa es que vosotros habéis pensado en la implementación.
Pero vosotros siempre tenéis que pensar en esto así.
Vosotros cuando moqueáis algo, una función o lo que sea, lo que tenéis que pensar es en el contrato.
Y lo que tenéis que pensar en el contrato es, vale, export function va a ser una función que voy a hacer que sea asíncrona,
porque siempre va a ser asíncrona, no importa de dónde vengan los datos.
Y siempre me va a devolver entonces aquí una promesa con el contrato, ¿vale?
El contrato siempre va a ser lo mismo, independientemente de lo que haya aquí dentro.
Entonces aquí simplemente ya podéis hacer una async.
Si hacéis una async y esto ya devuelve una promesa, ya lo tendréis.
Y lo bueno de esto, independientemente, si ahora cambiáis un mock o esto de repente cambia un fetch,
barra API, barra bugs, ¿vale?
Y esto trae una respuesta.
Es indiferente, ya está.
O sea, puedes cambiar una línea por la otra, ¿entendéis?
¿Qué es un contrato?
A ver, un contrato es un contrato literalmente.
Y es, ¿qué es lo que esperas que una función reciba y devuelva?
Un contrato, para que te hagas a la idea, sería esto.
Sin saber cuál es la implementación, el contrato sería qué es lo que recibe aquí y qué es lo que devuelve la función.
Y el contrato es como el acuerdo al que hemos llegado a cómo funciona esa función.
Cómo funciona, sí, cuál es el funcionamiento de esa función.
Tanto los parámetros que le podemos pasar como lo que va a devolver.
Independientemente de qué es lo que tiene en el cuerpo de la función.
Eso no es importante.
Por ejemplo, aquí lo habéis hecho un montón.
Claro, habéis pensado, ah, son datos moqueados y tal.
Pero claro, es que imaginad que ahora cambia esto y este GetBooks.
Si nosotros buscamos el GetBooks, GetBooks, claro, venga.
UseState, GetBooks.
A tomar por culo.
O sea, ya solo por el hecho de cambiar una función, cambiarle el contrato, fijaos.
Este UseState con este GetBooks ya no funciona.
Este UseLibrary se va al carajo.
Y entonces ya hay una cascada de cosas que no funcionan.
TapBooks.
Pues mira, en este caso, mira, aquí tenemos separados los contratos.
Un poco, le pasa un poco lo mismo, ¿no?
Tiene, ya os digo que esto es, o sea, no va por Daft Books, va en general.
Y entiendo que mucha gente dirá, ya, pero como están moqueados.
Pero bueno, lo digo para que tengáis en cuenta.
¿Veis?
En este caso, pues otra vez lo mismo, todo síncrono.
Cuando podría hacerlo asíncrono, independientemente que sea asíncrono.
Para siempre tener el mismo contrato.
Pero bueno, está bien que aquí sí que realmente ha puesto en el mismo sitio, ha puesto todos los servicios o filtros y tal.
Y ha hecho muy bien el tema de los filtros, que era una de las cosas a revisar en el código, porque ha hecho el filtro una vez.
Datos moqueados son datos inventados.
Mosqueados no.
Datos moqueados lo que quiere decir son datos que creas tú, que simulas que vende una API.
Una cosa que está muy chula aquí es este filter que ha hecho.
¿Veis? Este filter de aquí.
Que lo que está haciendo es filtrarlo solo una vez, teniendo en cuenta los filtros.
Mucha gente lo que ha hecho es filtrar una y otra vez.
O sea, hacía el filter, luego el filter, luego otro filter.
¿Vale?
Muy bien el tema del estado global.
La verdad es que este proyecto estaba súper bien también.
Pero, de nuevo, fallos muy tontos, ¿eh?
Fallos de ortografía.
Fallos de ortografía.
Fallos de ortografía.
Aquí, is a by label.
Bueno, este no pasa nada.
Yo no le doy mucha importancia.
Pero, de nuevo, que tampoco cuesta mucho.
Y este es otro problema.
A ver, el test.
Si ya que no vais a hacer test, al menos quítate el test de ejemplo.
Index page as expected h1.
Ni siquiera funciona el test.
Teniendo en cuenta la de líneas de código que habéis hecho, además, súper bien presentadas, estilos.
Fijaos todo lo que habéis hecho.
¿Morir en la orilla de no hacer un test?
Os lo tenéis que pensar.
Maxi Calderón, una cosa que está chula, que quiero que veáis, es que al menos ha tenido en cuenta las rutas de error, que es una cosa que se agradece.
¿Ves?
Algo salió mal, intenta nuevamente, muy bien.
Pero, también le he visto los errores estos de las constantes.
¿Ves?
Aquí tiene las constantes.
Constantes.
Y fijaos que en constantes mete, no mete constante, mete métodos.
No tiene mucho sentido.
Un detalle importante que ha hecho es que ha tenido bastante en cuenta el SEO.
O sea, bien por él, tema Tite y tal.
Incluso ha hecho el robots.
Que eso es una cosa que me ha sorprendido.
Creo que es de los pocos que he visto.
A lo mejor estoy siendo muy estricto, ¿vale?
De las cosas y tal.
Pero, un error que no podéis cometer en pruebas técnicas porque da, da una, no sé, queda un poco raro.
Queda un poco raro, ¿vale?
Una cosa que siempre tenéis que evitar es dejar los archivos de demo y todo esto.
En este caso sí que ha hecho los test y súper bien porque al menos, al menos, es un test que va a la página y mira que realmente tiene una imagen y tal.
Podría haber hecho más cosas, la verdad, no le costaba nada añadir unas líneas más para ver si tiene título, si realmente la imagen que se está renderizando es la imagen correcta, lo que sea, ¿no?
Pero, al lado del test, te dejas un test de 300, ¿cuántas líneas tiene este test?
400, 500, 437 líneas que no son tuyas.
O sea, este es el test de demo.
¿Ves que lo pone aquí?
Test examples.
Evidad dejar cualquier cosa que sean ejemplos y cosas así.
De hecho, incluso el test bueno le ha puesto examples, ¿sabes?
Eso, o sea, hay que intentar pensar que es como si fuese para producción y estas cosas hay que mimarlas un poco, ¿verdad?
Este de Krishi107, que me ha gustado el diseño, está bonito, aquí bastante grande y tal.
Aquí tenemos explorar los archivos, mira, esta animación me ha gustado bastante, estaba chula la animación, así como para que supieras dónde iba, ¿sabes?
Es como decir, ah, va a la izquierda.
Y aquí no ha sido mi forma favorita porque, claro, es un poco raro, no puedes ver los que has, pero bueno, le doy cudos por haber intentado algo diferente, ¿sabes?
Y que se vea aquí claramente que ya los tienes en la lectura, aquí toda la información.
Aquí al menos, fijaos que aquí sí que ha hecho como un rango, cosa que no ha hecho todo el mundo.
Yo creo que el rango puede ser de la mejor forma de hacer esto de las páginas porque te queda más claro que es entre ese rango.
Muy bien, le voy a dar cudos por el CSS, que también me ha sorprendido.
Otro error común que hacéis mucho y esto lo he visto así de veces en pruebas técnicas.
Yo es una cosa que no le doy importancia, pero sí que hay una cosa que esto, hay gente que le molesta mucho cuando revisan las pruebas porque es una mala práctica, porque es horrible.
Entonces yo lo digo porque tampoco cuesta nada meterlo en el gitignore y ya está, ¿vale?
Dejar la carpeta disk nunca se tiene que enviar a GitHub, no hace falta porque las carpetas que se generan en la build nunca se tienen que subir, ¿vale?
Entonces las tenéis que poner en el gitignore.
Queda raro, no pasa nada, yo tampoco, yo no soy una persona que le dé mucha importancia, pero sí que es verdad que yo me he encontrado mucha gente que es que mira que se ha quedado la carpeta disk, esto no se tiene que hacer.
Y es verdad que a veces, si son muchos, muchos archivos, pues es un poco raro.
Este tiene un caso muy interesante porque os quiero enseñar qué es esto de aquí.
A ver, me encontré este useEffect, he visto algunas cosas que se podrían mejorar, por ejemplo aquí como los contadores de género que sean states, esto, hay muchas cosas, hay muchas capas aquí, ¿vale?
Hay muchas capas aquí y una de ellas es el hecho de, a ver, esto en realidad no debería ser un efecto, ¿vale?
Cualquier cosa que se pueda calcular a través del estado no se tiene que utilizar otro estado.
Vamos a ir paso a paso de cómo yo refactorizaría más o menos esto.
A ver si voy a poder importar useEffect.
Creo que no, que no estoy en un proyecto.
A ver, a ver, ¿dónde puedo traerme?
Programación a ciegas, mira, programación a ciegas.
Sí que tengo esto, ¿vale?
Vamos a poner aquí que esto es JSX y vamos a, ¿vale?
Esto por aquí, vamos a hacer esto un poco más pequeño para que lo veáis bien.
FilterBooks, vamos a pensar que esto es una función books, books y que le vienen los filterBooks ya, ¿vale?
Vamos a simplificarlo para que no sea tan difícil y tal.
Claro, y aquí además vamos a ir paso a paso de cómo lo haría yo.
O sea, no cómo lo haría de golpe porque si no es un poco raro.
UseState, ¿vale?
Claro, el problema es que ahora me dice que todo esto no lo utilizamos.
A ver, formateamos esto.
Y ahí, pues, son cosas que no utilizo.
Exportamos esto.
Export function.
Lo primero que yo haría viendo esto, viendo este filter, filter, filter.
A ver, ¿qué es lo que está haciendo aquí?
Lo que está haciendo aquí es como contar, es un contador, y lo que está haciendo es contar como todos los géneros.
Bueno, todos los géneros o al menos los géneros más importantes, ¿no?
Y dice, ah, pues fantasía tiene tanto.
Entonces, ¿ves?
Tiene contadores de género, pero ya tiene los filterBooks aquí y tiene un useEffect.
Esto es un error que cometemos mucho, incluso gente que tiene muchos años de experiencia, no pasa nada.
Lo primero que podemos hacer es decir, aquí el problema es que estamos haciendo cuatro, cuatro bucles.
Y como dice Rafael, lo haría en un solo bucle.
Podríais hacerlo con un reduce, pero tampoco pasa nada.
Mira, podéis hacer aquí un count, ¿vale?
Y directamente decir count, pues lo ponemos aquí.
Mira, lo bueno sería hacerlo esto con un group, que esto lo vamos a poder hacer, ¿vale?
Pero lo podéis hacer con un for each, con cada libro.
Y decir, vale, pues cada libro.
Hay diferentes formas de hacerlo, más fáciles, más difíciles.
Una que podéis hacer es, una vez que tenéis el libro, que en este caso, fijaos que aquí hace book.book.
Para evitar estas cosas, lo que podéis hacer es directamente aquí sacar el book.
Y así ya siempre os referís al book.
Y ahora decís, mira, vamos a sacar, sacamos el género del libro y ahora ya, pues el count, vamos a poner que es el género.
Podemos inicializarlo a cero.
Mira, lo voy a hacer, mira, esta sería la forma, la forma larga y luego os enseño la forma corta.
Lo malo es que se repite mucho.
Pero bueno, ya con esto, os quitáis todo esto.
¿Y ahora qué es lo que podéis hacer?
Pues a ver, lo que podéis hacer aquí, en lugar de tener todos estos contadores, solo tenéis uno.
Counter, setCounter, le podéis poner el useState con el objeto y tal.
Y al menos, pues mira, os lo habéis quitado, tenéis el count, aquí tenéis y ya está.
O sea, son como cuatro líneas de código mucho más cortos.
¿Cómo lo podéis hacer un poquito para no tener que repetir?
Porque fijaos que aquí repetís esto tres veces.
Tres veces en el mismo sitio.
Es como, what?
Si queréis hacer algo interesante, podéis hacer esto.
Esto lo que va a hacer es, si no existe, lo crea y le asigna cero.
¿Vale?
Y si ya existe, lo incrementamos en uno.
Que de hecho aquí ya podríamos hacer el más más.
Y ya está.
Sería un poco lo mismo, ¿eh?
En este caso, yo lo haría así.
Lo incrementaría primero.
Y además, esto ocurre solo en el caso de que no exista.
O sea, realmente ya es este check que estamos haciendo aquí abajo.
Este check es el mismo que estamos haciendo aquí.
O sea, que hay mucha gente que dice, no, es que estás haciendo dos veces lo mismo.
Pero no es verdad del todo.
Porque lo que está haciendo aquí, esta asignación no ocurre si no es necesaria.
Y ya está haciendo el check que es el mismo que estamos haciendo aquí.
Y este incremento sería el mismo que estaríamos haciendo aquí.
Bueno, que en este, por cierto, no estábamos haciendo correctamente esto, ¿no?
Porque esto tendría que ser exactamente...
Claro, esto sería más bien así.
A ver, cero no podría ser porque siempre asignamos en uno.
Entonces, ahí ya lo tendríamos, ¿no?
No, con el uno este no podría ser.
Es que si hacemos esto es un poco rollo.
Si hacemos esto y lo incrementamos en uno, ¿luego qué pasa aquí?
Cuando ya esté inicializado.
Pues que, claro, vas a tener que mirar si el count no sé qué, no sé cuánto.
Entonces, tú lo que haces es siempre inicializarlo en el caso de que no exista cero.
Y luego lo incrementas.
Entonces, esto solo ocurrirá una vez.
Solo ocurrirá en el caso de que no esté incrementado.
Aquí se supone que tendríamos que hacer el setCounterCount, ¿no?
Esto es lo que deberíamos hacer.
Esto es lo que hay que evitar, ¿no?
¿Por qué esto está mal?
Y esto es un error que muchas veces se hace en React y que hay que evitar.
¿Por qué?
Porque fijaos aquí que este estado es innecesario.
Lo que tenéis que tener aquí sería como createCountFromBooks, por ejemplo.
Que le pasen los bugs, esto lo haces aquí, esto lo copiamos, lo tienes aquí y directamente, oye, devuelves el count.
Y ya está.
Estos serían los bugs, ¿vale?
Y este useEffect lo quitas.
Quitamos un estado que es innecesario.
Y aquí ya puedes renderizar el count de lo que tú quieras.
Teníamos aquí constCount, ¿vale?
Esto es un cálculo, creo que conflito.
O sea que calculamos del state o del estado o las props actuales, ¿vale?
En el render lo hacemos porque si no estamos renderizando y luego volvemos a renderizar de forma totalmente innecesaria.
Y entonces aquí ya podríamos tener terror, pues count punto y aquí pues podemos acceder a terror, ¿vale?
Por ejemplo, y ya está, ya lo tendríamos.
En este caso lo puedes hacer como punto terror, aunque claro, dependiendo de cada uno lo tenemos que hacer de una forma diferente y ya lo tendrías.
Pero te quitas el useEffect, súper importante, ¿vale?
El hecho de evitar calcular, evitar calcular cosas que ya las tienes ahí, que no hace falta calcularlas.
En este caso ya lo ha hecho un par de veces.
Y finalmente, vale, vamos con John C.
Vamos con John C.
Que os voy a enseñar una cosa muy chula que ha hecho.
Es el test, ¿vale?
Ha hecho un test con cara y ojos.
Es una pena que ha dejado comentarios aquí.
Esto también, si puede ser, no lo hagáis.
Os voy a dar una recomendación.
Ya sé que os cuestan un montón los test, ¿vale?
Pero os voy a dar una recomendación para que no falléis con este tipo de cosas.
¿Veis aquí que los test localizan elementos?
Section, UL, L, no sé qué.
A ver, esto normalmente no es la mejor idea.
Porque es muy fácil que la estructura de tu página cambie.
Muy fácil.
O que añadas otra cosa y que entre por medio de esto y ya no entre lo que tenga que entrar y tal.
Entonces, en React Testing Library, Priority Selector.
¿Qué query es la que deberías utilizar?
La prioridad que deberías utilizar en tus tests a la hora de buscar, ¿no?
Mucha gente dice, ah, pues voy a utilizar el test ID.
El test ID es mejor que algunos de los que hemos visto, pero dentro de los mejores sería el peor, ¿vale?
Sería como lo último.
Lo primero que puedes intentar utilizar es el getByRoll, el getByLabelText, porque el texto normalmente no suele cambiar.
GetByPlayHolder, por texto.
Que el texto sí que he visto que lo utiliza y eso pues me parece súper bien.
Luego, Alt Text, Title y finalmente, si no puede ser, pues el test ID.
O sea, no está mal utilizar el test ID.
Lo que pasa es que si llenas toda tu página de test ID, al final también que un botón tenga un texto y tal puede ser parte del test.
En cambio, utilizar selectores es un poco más de aquella forma.
¿Ves?
Aquí sí que lo ha hecho chulo.
GetByRoll.
¿Veis que lo tenéis aquí?
GetByRoll.
El botón que es agregar a la lista.
Porque alguien dirá, ostras, pero el texto también puede cambiar.
El texto de un botón puede ser agregar a la lista, añadir a la lista, no puede cambiar.
Pero eso es lo interesante.
Porque ¿qué es lo que habéis aprendido hoy de los Magic Strings?
El tema es que imaginad si en lugar de esto, imaginad esto, ¿no?
Esto es un Magic String.
Imaginad que podéis hacer esto.
Import i18n from i18n, ¿no?
Y tenéis todas las traducciones.
Y aquí podéis hacer algo así.
18n.buttons.addToReadList.
Ahora, de magia, ya no importa cuando la traducción cambie.
No importa.
Porque lo que va a pasar es que este, claro, como ahora era un Magic String, ahora sí que tiene bichos.
¿Vale?
Pero si por lo que sea podéis utilizar traducciones, aunque ojo con esto.
Esto también es polémico, ¿eh?
Pero os voy a decir una cosa que os va a volar la cabeza.
Y el tema es, aunque solo tengáis un idioma, muchas veces es interesante que las traducciones funcionen...
O sea, que tengáis traducciones.
Yo, por ejemplo, en mis proyectos personales no lo hago, obviamente.
Pero si yo hiciese un proyecto profesional en una empresa de producto, en condiciones, aunque solo tuviese un idioma, seguramente le pondríamos internacionalización.
Y lo haríamos por dos motivos.
Lo primero es porque, obviamente, nunca sabes si vas a tener luego traducciones y tal.
Pero lo segundo y más importante es que tienes todos tus textos totalmente separados de tu UI, tanto componentes y tal.
Puede revisarlo un equipo totalmente separado que no tienen por qué ser desarrolladores, lo cual ayuda mucho.
Muchas veces, seguro que te ha pasado, que marketing te ha dicho, es que quiero que cambies este texto de la landing page.
¿Por qué?
Porque al final lo tiene que hacer una persona de desarrollo porque está tal.
Si al final eso puede estar totalmente externalizado y hay un montón de servicios, ya no digo de ponerlo en JSON, que eso sería lo mínimo.
Pero hay servicios en los que puedes tener como un CMS para hacerlo.
O sea, para mí es clave y súper importante tener traducciones separadas para un producto en condiciones en el mundo del desarrollo.
Ahí os lo dejo.
Sé que es polémico porque hay gente que dice, pero mucho trabajo y tal.
Y también nos puede ayudar justamente para este tipo de cosas.
Si al final podéis hacer esto, mucha gente a veces dice que, claro, esto lo que hace es que el test se arregla solo, pero también es que nunca debería romperse.
Porque este test, digamos que está dirigido, o sea, estás simulando un usuario.
Entonces, no es que estés cambiando la funcionalidad y por lo que sea, entonces deja de funcionar y lo arreglas.
Si no, lo que estamos haciendo es, el usuario en realidad le da igual el texto, ¿no?
Le da igual si es agregar a la lista, si es añadir a la lista, si es todo esto.
Lo importante es que ese botón sabe lo que hace.
Entonces, esta podría ser una forma y de hecho, en la empresa en la que yo estaba, utilizamos esto y, claro, funciona bastante guay.
Y ya te despreocupas de un montón de cosas.
Pero bueno, muy bien.
Dargul, prueba terminada.
Oye, con una cosa que también he visto, es que hay gente que no me ha puesto la URL.
Entonces, claro, si no me ponéis la URL, no puedo entrar al, ¿sabes?
No lo puedo desplegar, no lo veo.
O sea que, muy bien el diseño, bastante sencillo.
Oye, bastante bien el hecho de, fijaos, que con un detalle, solo poniendo un detalle de máximo, ya se entiende mejor.
Ya se entiende mejor qué quiere decir el filtro.
Con una palabra.
Pues, se agradece.
Muy bonito el diseño, simple, sencillo.
Me ha encantado este detallazo.
Esto es muy importante en temas de UX.
¿Eh?
Pero, ¿qué ha pasado?
No se han podido encontrar libros.
¿Por qué no pruebas a modificar los filtros?
La verdad, detallazo.
Estos son esos detalles que dices, ostras, me gusta.
Me gusta porque queda muy bien.
Está muy bien presentada la página.
Me ha gustado un montón.
Así que, felicidades.
Además, diseño benito.
Cumple la funcionalidad también de la sincronización.
¿Vale?
Sincronización.
También, ¿ves?
Lista de lectura.
Se sincroniza las pestañas.
O sea, ya hace más que Amazon.
Lo que más me ha gustado del de Darkwood, lo vamos a ver.
Y esto es, yo creo que Darkwood pasaría la prueba.
Yo creo que la pasaría.
Aunque podría mejorar la separación de la lógica.
Tiene muchísima lógica en los componentes.
Y justamente lo que se pedía también era la separación de lógica.
Pero una cosa que ha hecho, que mucha gente no ha hecho, no ha hecho muchos test, pero están bien.
O sea, fijaos.
App.
Renderizar dos tabs.
Una disponible y otra para esto.
Renderizar la lista de libros disponibles.
O sea, ha pensado como un usuario.
Mi usuario, cuando entre a mi página, ¿qué es lo que tiene que funcionar?
Y eso es súper importante.
Sí, a lo mejor es GPT Test.
Pero todos tienes, todos, Halifax, todos tenéis acceso a GPT.
Y de los que hemos visto hasta ahora, es el único, aparte de alguno que ha hecho end to end,
es el único que ha pensado como un usuario para testear la aplicación.
Es que muchas veces decís que nos vamos a quitar el trabajo de inteligencia artificial
y el trabajo nos lo va a quitar un programador que utilice la inteligencia artificial.
Está muy bien.
Además, bien utilizando roles, texto.
O sea, muy bien.
El tema de testing, súper, súper bien.
Y realmente tiene sentido y se ha hecho pasar por un usuario.
O sea, que eso es súper importante.
Si queréis saber cómo hacer test, pues mira, aquí tenéis un buen ejemplo de cómo se podría hacer.
Un error tan tonto, tan tonto.
Esto.
Esto está prohibido por las autoridades, ¿vale?
Esto está prohibido por las autoridades.
Vamos a ver, ¿eh?
Una cosa es que carguéis una fuente.
Dos.
Tres.
Cuatro.
Cinco.
Pero, tío.
¿Cuántas fuentes hay aquí?
¿Qué es esto?
Si solo la...
O sea, solo el archivo de cargar fuentes.
Solo el archivo de cargar las fuentes.
O sea, sin cargar las fuentes.
Ocupa 63K, tío.
Yo esto...
Yo no sé qué le ha pasado aquí.
Mira, está cargando Noto Sans y carga.
La de 100 y la de 300.
Noto Sans Italy.
La de 0, 100, 200, 300, 400, 500, 600, 700, 800.
La Inter, la Shipstead Grotesque, la Family Space Grotesque.
La Inter también.
La de 100, la de 200, la de 300.
¿Pero qué ha pasado aquí, tío?
Pero te has...
Te has acabado Google Fonts.
Te has traído...
Es que para eso hubieras hecho esto, tío.
Haces esto.
Y ya está.
Haces esto.
Te traes todas las fuentes.
Y tú ya las vas usando conforme te sale un poco del nabo.
O sea, tío.
Aquí se...
Creo que se te ha ido.
Y creo que esto muchas veces pasa.
Lo que tenéis que ir haciendo es seleccionar en concreto.
O sea, no seleccionarlas todas.
¿Ves?
No, no, no.
Add more styles.
No.
Seleccionáis una.
Yo qué sé.
Por la de 400 suele ser.
¿Vale?
400.
Y luego, pues, esta.
Vale.
Ya está.
Ya está.
Y luego, es mejor que utilicéis esto así que no meterlo directamente de CSS porque por
desgracia aquí va a bloquear todavía más.