1+ // #20 PETICIONES HTPP
2+ /*
3+ * EJERCICIO:
4+ * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza
5+ * una petición a la web que tú quieras, verifica que dicha petición
6+ * fue exitosa y muestra por consola el contenido de la web.
7+ *
8+ * DIFICULTAD EXTRA (opcional):
9+ * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por
10+ * terminal al que le puedas solicitar información de un Pokémon concreto
11+ * utilizando su nombre o número.
12+ * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon
13+ * - Muestra el nombre de su cadena de evoluciones
14+ * - Muestra los juegos en los que aparece
15+ * - Controla posibles errores
16+ */
17+ // I use GPT for reference information.
18+
19+ let log = console . log ;
20+
21+ window . addEventListener ( 'load' , ( ) => {
22+ const body = document . querySelector ( 'body' ) ;
23+ const title = document . createElement ( 'h1' ) ;
24+
25+ body . style . setProperty ( 'background' , '#000' ) ;
26+ body . style . setProperty ( 'text-align' , 'center' ) ;
27+
28+ title . textContent = 'Retosparaprogramadores #20.' ;
29+ title . style . setProperty ( 'font-size' , '3.5vmax' ) ;
30+ title . style . setProperty ( 'color' , '#fff' ) ;
31+ title . style . setProperty ( 'line-height' , '34vh' ) ;
32+
33+ body . appendChild ( title ) ;
34+ log ( 'Retosparaprogramadores #20' ) ;
35+
36+ /* LoremIpsum Paragraph Maker Visual Modal */
37+
38+ let modal = document . createElement ( 'div' ) ;
39+ modal . style . setProperty ( 'position' , 'relative' ) ;
40+ modal . style . setProperty ( 'top' , '50%' ) ;
41+ modal . style . setProperty ( 'left' , '50%' ) ;
42+ modal . style . setProperty ( 'transform' , 'translate(-50%, -20%)' ) ;
43+ modal . style . setProperty ( 'background' , 'rgba(0,0,0,0.2)' ) ;
44+ modal . style . setProperty ( 'width' , '400px' ) ;
45+ modal . style . setProperty ( 'min-height' , '200px' ) ;
46+ // modal.style.setProperty('display', 'none');
47+ document . body . appendChild ( modal ) ;
48+
49+ let loremIpsumContainer = document . createElement ( 'div' ) ;
50+ loremIpsumContainer . style . setProperty ( 'font-family' , 'sans-serif' ) ;
51+ loremIpsumContainer . style . setProperty ( 'margin' , '1rem' ) ;
52+ modal . appendChild ( loremIpsumContainer ) ;
53+
54+ let label = document . createElement ( 'label' ) ;
55+ label . style . setProperty ( 'padding' , '10px' ) ;
56+ label . style . setProperty ( 'color' , '#fff' ) ;
57+ label . setAttribute ( 'for' , 'paragraphsCount' ) ;
58+ let strong = document . createElement ( 'strong' ) ;
59+ strong . textContent = 'How many Paragraphs?' ;
60+ loremIpsumContainer . appendChild ( label ) ;
61+ label . appendChild ( strong ) ;
62+
63+ let input = document . createElement ( 'input' ) ;
64+ input . setAttribute ( 'type' , 'number' )
65+ input . style . setProperty ( 'width' , '4rem' ) ;
66+ input . setAttribute ( 'min' , '0' ) ;
67+ input . classList . add ( 'paragraphsCount' ) ;
68+ loremIpsumContainer . appendChild ( input ) ;
69+
70+ let button = document . createElement ( 'button' ) ;
71+ button . style . setProperty ( 'background' , '#ff8c00' ) ;
72+ button . style . setProperty ( 'color' , '#f6f6f6' ) ;
73+ button . style . setProperty ( 'padding' , '5px' ) ;
74+ button . style . setProperty ( 'border-radius' , '15px' ) ;
75+ button . style . setProperty ( 'text-align' , 'center' ) ;
76+ button . style . setProperty ( 'margin-left' , '10px' ) ;
77+ button . textContent = 'Generate' ;
78+ button . classList . add ( 'getLoremIpsum' ) ;
79+ loremIpsumContainer . appendChild ( button ) ;
80+
81+ let result = document . createElement ( 'div' ) ;
82+ result . style . setProperty ( 'margin-top' , '1rem' )
83+ result . style . setProperty ( 'padding' , '1rem' ) ;
84+ result . style . setProperty ( 'border' , '1px dashed black' ) ;
85+ result . style . setProperty ( 'font-size' , '.75rem' ) ;
86+ result . style . setProperty ( 'position' , 'absolute' ) ;
87+ result . style . setProperty ( 'left' , '-25%' ) ;
88+ result . style . setProperty ( 'width' , '58vw' ) ;
89+ result . style . setProperty ( 'display' , 'none' ) ;
90+ result . classList . add ( 'result' ) ;
91+ loremIpsumContainer . appendChild ( result ) ;
92+ } ) ;
93+
94+
95+ /* LoremIpsum Paragraph Maker Funcionality */
96+
97+ function getLoremIpsum ( numberOfParagraphs ) {
98+ fetch ( `https://baconipsum.com/api/?type=meat-and-filler¶s=${ numberOfParagraphs } ` )
99+ . then ( response => response . json ( ) )
100+ . then ( loremIpsumTextArray => {
101+ updateResult ( loremIpsumTextArray ) ;
102+ } )
103+ . catch ( error => {
104+ showError ( error ) ;
105+ } ) ;
106+ } ;
107+
108+ function updateResult ( textArray ) {
109+ const resultElement = document . querySelector ( '.result' ) ;
110+ resultElement . classList . add ( 'show' ) ;
111+ resultElement . style . setProperty ( 'display' , '' ) ;
112+ resultElement . innerHTML = '' ;
113+ resultElement . innerHTML = textArray
114+ . map ( paragraph => `<p>${ paragraph } </p>` )
115+ . join ( '' ) ;
116+ addCopyButton ( textArray . join ( '' ) ) ;
117+
118+ // Apply styles to the paragraphs immediately
119+ const p_elements = document . querySelectorAll ( '.result p' ) ;
120+ p_elements . forEach ( p => {
121+ p . style . setProperty ( 'color' , '#fff' ) ;
122+ p . style . setProperty ( 'line-height' , '16px' ) ;
123+ p . style . setProperty ( 'text-align' , 'justify' ) ;
124+ } ) ;
125+ }
126+
127+ function showError ( error ) {
128+ const resultElement = document . querySelector ( '.result' ) ;
129+ resultElement . innerHTML = '' ;
130+ resultElement . innerHTML = `<p class="error">${ error . message } </p>`
131+ }
132+
133+ function addCopyButton ( text ) {
134+ const resultElement = document . querySelector ( '.result' ) ;
135+ const copyBtn = document . createElement ( 'button' ) ;
136+
137+ copyBtn . textContent = 'Copy' ;
138+ copyBtn . classList . add ( 'copy' ) ;
139+ copyBtn . onclick = ( ) => {
140+ navigator . clipboard . writeText ( text ) ;
141+ copyBtn . textContent = 'Copied!' ;
142+ setTimeout ( ( ) => {
143+ copyBtn . textContent = 'Copy' ;
144+ } , 2000 ) ;
145+ }
146+
147+ resultElement . appendChild ( copyBtn ) ;
148+
149+ setTimeout ( ( ) => getPokemon ( id = prompt ( 'Please type a number id to get the pokemon data' ) ) , 2000 )
150+ }
151+
152+ setTimeout ( ( ) => {
153+ const getLoremIpsumElement = document . querySelector ( '.getLoremIpsum' ) ;
154+ const paragraphsCountElement = document . querySelector ( '.paragraphsCount' ) ;
155+
156+ getLoremIpsumElement . addEventListener ( 'click' , ( ) => {
157+ getLoremIpsum ( parseInt ( paragraphsCountElement . value ) ) ;
158+ paragraphsCountElement . value = '' ;
159+
160+ } )
161+ } , 1000 ) ;
162+
163+
164+ // Extra Dificulty Exercise
165+
166+ let pokemon ;
167+ function getPokemon ( id ) {
168+ fetch ( `https://pokeapi.co/api/v2/pokemon/${ id } ` )
169+ . then ( ( response ) => response . json ( ) )
170+ . then ( ( data ) => {
171+ log ( data ) ;
172+ ;
173+ pokemon = {
174+ name : `Name: ${ data . name } ` ,
175+ id : `Id: ${ data . id } ` ,
176+ weight : `Weight: ${ data . weight } ` ,
177+ height : `Height: ${ data . height } ` ,
178+ type : `Type: ${ data . types . map ( t => t . type . name ) . join ( ', ' ) } ` ,
179+ games : `Games: ${ data . game_indices . map ( g => g . version . name ) . join ( ', ' ) } ` ,
180+ }
181+ log ( pokemon ) ;
182+
183+ let modal1 = document . createElement ( 'div' ) ;
184+ modal1 . style . setProperty ( 'position' , 'relative' ) ;
185+ modal1 . style . setProperty ( 'top' , '50%' ) ;
186+ modal1 . style . setProperty ( 'color' , '#fff' ) ;
187+ modal1 . style . setProperty ( 'left' , '50%' ) ;
188+ modal1 . style . setProperty ( 'transform' , 'translate(-50%, -72%)' ) ;
189+ modal1 . style . setProperty ( 'background' , 'rgba(0,0,0,0.9)' ) ;
190+ modal1 . style . setProperty ( 'width' , '100vw' ) ;
191+ modal1 . style . setProperty ( 'height' , '100vh' ) ;
192+ modal1 . style . setProperty ( 'display' , 'flex' ) ;
193+ modal1 . style . setProperty ( 'justify-content' , 'center' ) ;
194+ modal1 . style . setProperty ( 'align-items' , 'center' ) ;
195+ let modal2 = document . createElement ( 'div' ) ;
196+ modal2 . style . setProperty ( 'width' , '80vw' ) ;
197+ modal2 . style . setProperty ( 'height' , '100vh' ) ;
198+ modal2 . style . setProperty ( 'display' , 'flex' ) ;
199+ modal2 . style . setProperty ( 'justify-content' , 'space-arround' ) ;
200+ modal2 . style . setProperty ( 'align-items' , 'flex-start' ) ;
201+ modal2 . style . setProperty ( 'flex-direction' , 'column' ) ;
202+ let h1 = document . createElement ( 'h1' ) ;
203+ h1 . textContent = `POKEMON` ;
204+ h1 . style . setProperty ( 'align-self' , 'center' ) ;
205+ h1 . style . setProperty ( 'font-family' , 'cursive' ) ;
206+ modal2 . appendChild ( h1 ) ;
207+ modal1 . appendChild ( modal2 ) ;
208+ document . body . appendChild ( modal1 ) ;
209+
210+ for ( let key in pokemon ) {
211+ let p = document . createElement ( 'p' ) ;
212+ p . textContent = `${ pokemon [ key ] } ` ;
213+ p . style . setProperty ( 'color' , 'yellow' ) ;
214+ p . style . setProperty ( 'font-size' , '2vw' ) ;
215+ p . style . setProperty ( 'font-weight' , '600' ) ;
216+ p . style . setProperty ( 'font-family' , 'cursive' ) ;
217+ p . style . setProperty ( 'text-align' , 'justify' ) ;
218+ modal2 . appendChild ( p ) ;
219+ }
220+
221+ // Function to remove the modal
222+ const removeModal = ( ) => {
223+ modal1 . remove ( ) ;
224+ document . removeEventListener ( 'keydown' , handleKeyDown ) ; // Clean up the event listener
225+ } ;
226+
227+ // Add event listener to remove the modal when clicked
228+ modal2 . addEventListener ( 'click' , removeModal ) ;
229+
230+ // Function to handle keydown events
231+ const handleKeyDown = ( event ) => {
232+ if ( event . key === "Escape" ) { // Check if the pressed key is "Escape"
233+ removeModal ( ) ; // Call the function to remove the modal
234+ }
235+ } ;
236+
237+ // Add event listener for keydown events
238+ document . addEventListener ( 'keydown' , handleKeyDown ) ;
239+ } )
240+ . catch ( ( error ) => console . error ( 'Error fetching Pokémon:' , error ) ) ;
241+ }
242+
243+ //Note: is easy use a external css file an just add classes rather than adding prperty by property.
244+ /* By using CSS classes, your JavaScript code becomes cleaner and easier to manage, while your styles are centralized in a dedicated CSS file. This approach is generally recommended for larger projects or when working in teams. */
0 commit comments