├── .gitignore
├── README.md
├── app.js
├── components
├── PokeApp.js
├── PokeAvatar.js
├── PokeChat.js
├── PokeMessage.js
├── PokeRow.js
└── PokeTable.js
├── db-api
├── index.js
└── pokemons.js
├── index.html
├── index.js
├── package.json
└── public
└── app.css
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | build.js
3 | .DS_Store
4 | public/app.js
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Pokechat #PlatziReactJS
2 |
3 | ## Instrucciones
4 |
5 | ```
6 | npm install
7 | npm run build
8 | npm start
9 | ```
10 |
11 | Aquí encontrarás el código que se crea durante el [curso de #PlatziReactJS](https://platzi.com/clases/react-js/) por [Sacha Lifszyc](http://twitter.com/slifszyc).
12 |
--------------------------------------------------------------------------------
/app.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Module dependencies
3 | */
4 |
5 | import React from 'react';
6 | import PokeApp from './components/PokeApp';
7 |
8 |
9 | React.render(
10 | ,
11 | document.getElementById('container')
12 | );
--------------------------------------------------------------------------------
/components/PokeApp.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Module dependencies
3 | */
4 |
5 | import React from 'react';
6 | import PokeTable from './PokeTable';
7 | import PokeChat from './PokeChat';
8 | import uid from 'uid';
9 | import $ from 'jquery';
10 | import io from 'socket.io-client';
11 |
12 | export default class PokeApp extends React.Component {
13 | constructor(props) {
14 | super(props);
15 | this.state = { messages: [], pokemons: [] };
16 | this.onGrowl = this.onGrowl.bind(this);
17 | this.user = uid(10);
18 | }
19 |
20 | componentWillMount() {
21 | $.get('/pokemons', (pokemons) => {
22 | this.setState({ pokemons: pokemons });
23 | });
24 | this.socket = io('http://localhost:3000');
25 | this.socket.on('message', (message) => {
26 | if (message.user !== this.user) {
27 | this.newMessage(message);
28 | }
29 | });
30 | }
31 |
32 | onGrowl(name) {
33 | let text = `${name}, ${name}!`;
34 | let message = { id: uid(), text: text, user: this.user };
35 | this.newMessage(message);
36 | this.socket.emit('message', message);
37 | }
38 |
39 | newMessage(message) {
40 | this.state.messages.push(message);
41 | let messages = this.state.messages;
42 | this.setState({ messages: messages });
43 | }
44 |
45 | render() {
46 | if (this.state.pokemons.length) {
47 | return
51 | } else {
52 | return Cargando...
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/components/PokeAvatar.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Module dependencies
3 | */
4 |
5 | import React from 'react';
6 |
7 | export default class PokeAvatar extends React.Component {
8 | render() {
9 | var url = `http://veekun.com/dex/media/pokemon/main-sprites/x-y/${this.props.number}.png`;
10 | return
11 |

12 |
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/components/PokeChat.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Module dependencies
3 | */
4 |
5 | import React from 'react/addons';
6 | import PokeMessage from './PokeMessage';
7 |
8 | const { CSSTransitionGroup } = React.addons;
9 |
10 | export default class PokeChat extends React.Component {
11 | render() {
12 | return
13 |
14 | {
15 | this.props.messages.map((message) => {
16 | return
17 | })
18 | }
19 |
20 |
21 | }
22 | }
23 |
24 | PokeChat.defaultProps = { messages: [] };
--------------------------------------------------------------------------------
/components/PokeMessage.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Module dependencies
3 | */
4 |
5 | import React from 'react';
6 |
7 | export default class PokeMessage extends React.Component {
8 | render() {
9 | return {this.props.message.text}
10 | }
11 | }
--------------------------------------------------------------------------------
/components/PokeRow.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Module dependencies
3 | */
4 |
5 | import React from 'react';
6 | import PokeAvatar from './PokeAvatar';
7 |
8 | export default class PokeRow extends React.Component {
9 | onClick(ev) {
10 | this.props.growl(this.props.name)
11 | }
12 |
13 | render() {
14 | return
15 |
16 | {this.props.name}
17 |
18 | }
19 | }
--------------------------------------------------------------------------------
/components/PokeTable.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Module dependencies
3 | */
4 |
5 | import React from 'react';
6 | import PokeRow from './PokeRow';
7 |
8 | export default class PokeTable extends React.Component {
9 | render() {
10 | return
11 | {
12 | this.props.pokemons.map((pokemon) => {
13 | return
18 | })
19 | }
20 |
21 | }
22 | }
--------------------------------------------------------------------------------
/db-api/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Module dependencies
3 | */
4 |
5 | import pokemons from './pokemons';
6 |
7 | export default {
8 | pokemons: {
9 | find: function(callback) {
10 | setTimeout(() => {
11 | callback(pokemons);
12 | }, 3000);
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/db-api/pokemons.js:
--------------------------------------------------------------------------------
1 | export default [
2 | {
3 | number: 1,
4 | name: "bulbasaur"
5 | },
6 | {
7 | number: 2,
8 | name: "ivysaur"
9 | },
10 | {
11 | number: 3,
12 | name: "venusaur"
13 | },
14 | {
15 | number: 4,
16 | name: "charmander"
17 | },
18 | {
19 | number: 5,
20 | name: "charmeleon"
21 | },
22 | {
23 | number: 6,
24 | name: "charizard"
25 | },
26 | {
27 | number: 7,
28 | name: "squirtle"
29 | },
30 | {
31 | number: 8,
32 | name: "wartortle"
33 | },
34 | {
35 | number: 9,
36 | name: "blastoise"
37 | },
38 | {
39 | number: 10,
40 | name: "caterpie"
41 | },
42 | {
43 | number: 11,
44 | name: "metapod"
45 | },
46 | {
47 | number: 12,
48 | name: "butterfree"
49 | },
50 | {
51 | number: 13,
52 | name: "weedle"
53 | },
54 | {
55 | number: 14,
56 | name: "kakuna"
57 | },
58 | {
59 | number: 15,
60 | name: "beedrill"
61 | },
62 | {
63 | number: 16,
64 | name: "pidgey"
65 | },
66 | {
67 | number: 17,
68 | name: "pidgeotto"
69 | },
70 | {
71 | number: 18,
72 | name: "pidgeot"
73 | },
74 | {
75 | number: 19,
76 | name: "rattata"
77 | },
78 | {
79 | number: 20,
80 | name: "raticate"
81 | },
82 | {
83 | number: 21,
84 | name: "spearow"
85 | },
86 | {
87 | number: 22,
88 | name: "fearow"
89 | },
90 | {
91 | number: 23,
92 | name: "ekans"
93 | },
94 | {
95 | number: 24,
96 | name: "arbok"
97 | },
98 | {
99 | number: 25,
100 | name: "pikachu"
101 | },
102 | {
103 | number: 26,
104 | name: "raichu"
105 | },
106 | {
107 | number: 27,
108 | name: "sandshrew"
109 | },
110 | {
111 | number: 28,
112 | name: "sandslash"
113 | },
114 | {
115 | number: 29,
116 | name: "nidoran-f"
117 | },
118 | {
119 | number: 30,
120 | name: "nidorina"
121 | },
122 | {
123 | number: 31,
124 | name: "nidoqueen"
125 | },
126 | {
127 | number: 32,
128 | name: "nidoran-m"
129 | },
130 | {
131 | number: 33,
132 | name: "nidorino"
133 | },
134 | {
135 | number: 34,
136 | name: "nidoking"
137 | },
138 | {
139 | number: 35,
140 | name: "clefairy"
141 | },
142 | {
143 | number: 36,
144 | name: "clefable"
145 | },
146 | {
147 | number: 37,
148 | name: "vulpix"
149 | },
150 | {
151 | number: 38,
152 | name: "ninetales"
153 | },
154 | {
155 | number: 39,
156 | name: "jigglypuff"
157 | },
158 | {
159 | number: 40,
160 | name: "wigglytuff"
161 | },
162 | {
163 | number: 41,
164 | name: "zubat"
165 | },
166 | {
167 | number: 42,
168 | name: "golbat"
169 | },
170 | {
171 | number: 43,
172 | name: "oddish"
173 | },
174 | {
175 | number: 44,
176 | name: "gloom"
177 | },
178 | {
179 | number: 45,
180 | name: "vileplume"
181 | },
182 | {
183 | number: 46,
184 | name: "paras"
185 | },
186 | {
187 | number: 47,
188 | name: "parasect"
189 | },
190 | {
191 | number: 48,
192 | name: "venonat"
193 | },
194 | {
195 | number: 49,
196 | name: "venomoth"
197 | },
198 | {
199 | number: 50,
200 | name: "diglett"
201 | },
202 | {
203 | number: 51,
204 | name: "dugtrio"
205 | },
206 | {
207 | number: 52,
208 | name: "meowth"
209 | },
210 | {
211 | number: 53,
212 | name: "persian"
213 | },
214 | {
215 | number: 54,
216 | name: "psyduck"
217 | },
218 | {
219 | number: 55,
220 | name: "golduck"
221 | },
222 | {
223 | number: 56,
224 | name: "mankey"
225 | },
226 | {
227 | number: 57,
228 | name: "primeape"
229 | },
230 | {
231 | number: 58,
232 | name: "growlithe"
233 | },
234 | {
235 | number: 59,
236 | name: "arcanine"
237 | },
238 | {
239 | number: 60,
240 | name: "poliwag"
241 | },
242 | {
243 | number: 61,
244 | name: "poliwhirl"
245 | },
246 | {
247 | number: 62,
248 | name: "poliwrath"
249 | },
250 | {
251 | number: 63,
252 | name: "abra"
253 | },
254 | {
255 | number: 64,
256 | name: "kadabra"
257 | },
258 | {
259 | number: 65,
260 | name: "alakazam"
261 | },
262 | {
263 | number: 66,
264 | name: "machop"
265 | },
266 | {
267 | number: 67,
268 | name: "machoke"
269 | },
270 | {
271 | number: 68,
272 | name: "machamp"
273 | },
274 | {
275 | number: 69,
276 | name: "bellsprout"
277 | },
278 | {
279 | number: 70,
280 | name: "weepinbell"
281 | },
282 | {
283 | number: 71,
284 | name: "victreebel"
285 | },
286 | {
287 | number: 72,
288 | name: "tentacool"
289 | },
290 | {
291 | number: 73,
292 | name: "tentacruel"
293 | },
294 | {
295 | number: 74,
296 | name: "geodude"
297 | },
298 | {
299 | number: 75,
300 | name: "graveler"
301 | },
302 | {
303 | number: 76,
304 | name: "golem"
305 | },
306 | {
307 | number: 77,
308 | name: "ponyta"
309 | },
310 | {
311 | number: 78,
312 | name: "rapidash"
313 | },
314 | {
315 | number: 79,
316 | name: "slowpoke"
317 | },
318 | {
319 | number: 80,
320 | name: "slowbro"
321 | },
322 | {
323 | number: 81,
324 | name: "magnemite"
325 | },
326 | {
327 | number: 82,
328 | name: "magneton"
329 | },
330 | {
331 | number: 83,
332 | name: "farfetchd"
333 | },
334 | {
335 | number: 84,
336 | name: "doduo"
337 | },
338 | {
339 | number: 85,
340 | name: "dodrio"
341 | },
342 | {
343 | number: 86,
344 | name: "seel"
345 | },
346 | {
347 | number: 87,
348 | name: "dewgong"
349 | },
350 | {
351 | number: 88,
352 | name: "grimer"
353 | },
354 | {
355 | number: 89,
356 | name: "muk"
357 | },
358 | {
359 | number: 90,
360 | name: "shellder"
361 | },
362 | {
363 | number: 91,
364 | name: "cloyster"
365 | },
366 | {
367 | number: 92,
368 | name: "gastly"
369 | },
370 | {
371 | number: 93,
372 | name: "haunter"
373 | },
374 | {
375 | number: 94,
376 | name: "gengar"
377 | },
378 | {
379 | number: 95,
380 | name: "onix"
381 | },
382 | {
383 | number: 96,
384 | name: "drowzee"
385 | },
386 | {
387 | number: 97,
388 | name: "hypno"
389 | },
390 | {
391 | number: 98,
392 | name: "krabby"
393 | },
394 | {
395 | number: 99,
396 | name: "kingler"
397 | },
398 | {
399 | number: 100,
400 | name: "voltorb"
401 | },
402 | {
403 | number: 101,
404 | name: "electrode"
405 | },
406 | {
407 | number: 102,
408 | name: "exeggcute"
409 | },
410 | {
411 | number: 103,
412 | name: "exeggutor"
413 | },
414 | {
415 | number: 104,
416 | name: "cubone"
417 | },
418 | {
419 | number: 105,
420 | name: "marowak"
421 | },
422 | {
423 | number: 106,
424 | name: "hitmonlee"
425 | },
426 | {
427 | number: 107,
428 | name: "hitmonchan"
429 | },
430 | {
431 | number: 108,
432 | name: "lickitung"
433 | },
434 | {
435 | number: 109,
436 | name: "koffing"
437 | },
438 | {
439 | number: 110,
440 | name: "weezing"
441 | },
442 | {
443 | number: 111,
444 | name: "rhyhorn"
445 | },
446 | {
447 | number: 112,
448 | name: "rhydon"
449 | },
450 | {
451 | number: 113,
452 | name: "chansey"
453 | },
454 | {
455 | number: 114,
456 | name: "tangela"
457 | },
458 | {
459 | number: 115,
460 | name: "kangaskhan"
461 | },
462 | {
463 | number: 116,
464 | name: "horsea"
465 | },
466 | {
467 | number: 117,
468 | name: "seadra"
469 | },
470 | {
471 | number: 118,
472 | name: "goldeen"
473 | },
474 | {
475 | number: 119,
476 | name: "seaking"
477 | },
478 | {
479 | number: 120,
480 | name: "staryu"
481 | },
482 | {
483 | number: 121,
484 | name: "starmie"
485 | },
486 | {
487 | number: 122,
488 | name: "mr-mime"
489 | },
490 | {
491 | number: 123,
492 | name: "scyther"
493 | },
494 | {
495 | number: 124,
496 | name: "jynx"
497 | },
498 | {
499 | number: 125,
500 | name: "electabuzz"
501 | },
502 | {
503 | number: 126,
504 | name: "magmar"
505 | },
506 | {
507 | number: 127,
508 | name: "pinsir"
509 | },
510 | {
511 | number: 128,
512 | name: "tauros"
513 | },
514 | {
515 | number: 129,
516 | name: "magikarp"
517 | },
518 | {
519 | number: 130,
520 | name: "gyarados"
521 | },
522 | {
523 | number: 131,
524 | name: "lapras"
525 | },
526 | {
527 | number: 132,
528 | name: "ditto"
529 | },
530 | {
531 | number: 133,
532 | name: "eevee"
533 | },
534 | {
535 | number: 134,
536 | name: "vaporeon"
537 | },
538 | {
539 | number: 135,
540 | name: "jolteon"
541 | },
542 | {
543 | number: 136,
544 | name: "flareon"
545 | },
546 | {
547 | number: 137,
548 | name: "porygon"
549 | },
550 | {
551 | number: 138,
552 | name: "omanyte"
553 | },
554 | {
555 | number: 139,
556 | name: "omastar"
557 | },
558 | {
559 | number: 140,
560 | name: "kabuto"
561 | },
562 | {
563 | number: 141,
564 | name: "kabutops"
565 | },
566 | {
567 | number: 142,
568 | name: "aerodactyl"
569 | },
570 | {
571 | number: 143,
572 | name: "snorlax"
573 | },
574 | {
575 | number: 144,
576 | name: "articuno"
577 | },
578 | {
579 | number: 145,
580 | name: "zapdos"
581 | },
582 | {
583 | number: 146,
584 | name: "moltres"
585 | },
586 | {
587 | number: 147,
588 | name: "dratini"
589 | },
590 | {
591 | number: 148,
592 | name: "dragonair"
593 | },
594 | {
595 | number: 149,
596 | name: "dragonite"
597 | },
598 | {
599 | number: 150,
600 | name: "mewtwo"
601 | },
602 | {
603 | number: 151,
604 | name: "mew"
605 | }
606 | ];
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Curso Platzi - React.js
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Module dependencies
3 | */
4 |
5 | import express from 'express';
6 | import http from 'http';
7 | import engine from 'socket.io';
8 | import dbapi from './db-api';
9 |
10 | const port = 3000;
11 | const app = express();
12 |
13 | // Configurar la ruta de archivos estáticos
14 | app.use('/', express.static(__dirname + '/public'));
15 |
16 | app.get('/pokemons', (req, res) => {
17 | dbapi.pokemons.find((pokemons) => {
18 | res.json(pokemons);
19 | })
20 | });
21 |
22 | app.get('/', (req, res) => {
23 | res.sendFile(__dirname + '/index.html');
24 | })
25 |
26 | let server = http.createServer(app).listen(port, () => {
27 | console.log(`El servidor está escuchando en el puerto ${port}`);
28 | });
29 |
30 | const io = engine.listen(server);
31 |
32 | io.on('connection', (socket) => {
33 | socket.on('message', (msg) => {
34 | io.emit('message', msg);
35 | })
36 | })
37 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "pokechat",
3 | "dependencies": {
4 | "babel": "^5.5.8",
5 | "babelify": "^6.1.2",
6 | "browserify": "^10.2.4",
7 | "express": "^4.12.4",
8 | "jquery": "^2.1.4",
9 | "react": "^0.13.3",
10 | "socket.io": "^1.3.5",
11 | "socket.io-client": "^1.3.5",
12 | "uid": "0.0.2"
13 | },
14 | "scripts": {
15 | "build": "browserify app.js > public/app.js -t babelify",
16 | "start": "babel-node index.js"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/public/app.css:
--------------------------------------------------------------------------------
1 | /* http://meyerweb.com/eric/tools/css/reset/
2 | v2.0 | 20110126
3 | License: none (public domain)
4 | */
5 |
6 | html, body, div, span, applet, object, iframe,
7 | h1, h2, h3, h4, h5, h6, p, blockquote, pre,
8 | a, abbr, acronym, address, big, cite, code,
9 | del, dfn, em, img, ins, kbd, q, s, samp,
10 | small, strike, strong, sub, sup, tt, var,
11 | b, u, i, center,
12 | dl, dt, dd, ol, ul, li,
13 | fieldset, form, label, legend,
14 | table, caption, tbody, tfoot, thead, tr, th, td,
15 | article, aside, canvas, details, embed,
16 | figure, figcaption, footer, header, hgroup,
17 | menu, nav, output, ruby, section, summary,
18 | time, mark, audio, video {
19 | margin: 0;
20 | padding: 0;
21 | border: 0;
22 | font-size: 100%;
23 | font: inherit;
24 | vertical-align: baseline;
25 | }
26 | /* HTML5 display-role reset for older browsers */
27 | article, aside, details, figcaption, figure,
28 | footer, header, hgroup, menu, nav, section {
29 | display: block;
30 | }
31 | body {
32 | line-height: 1;
33 | }
34 | ol, ul {
35 | list-style: none;
36 | }
37 | blockquote, q {
38 | quotes: none;
39 | }
40 | blockquote:before, blockquote:after,
41 | q:before, q:after {
42 | content: '';
43 | content: none;
44 | }
45 | table {
46 | border-collapse: collapse;
47 | border-spacing: 0;
48 | }
49 |
50 | .pokeapp {
51 | width: 100%;
52 | overflow: hidden;
53 | }
54 |
55 | .poketable {
56 | width: 30%;
57 | float: left;
58 | height: 100%;
59 | overflow: scroll;
60 | }
61 |
62 | .pokerow {
63 | background-color: lightblue;
64 | border: 1px solid black;
65 | width: 100%;
66 | height: 80px;
67 | line-height: 80px;
68 | }
69 |
70 | .avatar-container {
71 | width: 120px;
72 | display: inline-block;
73 | text-align: center;
74 | }
75 |
76 | .avatar {
77 | vertical-align: middle;
78 | max-height: 75px;
79 | max-width: 100px;
80 | }
81 |
82 | .pokechat {
83 | width: 70%;
84 | float: right;
85 | height: 100%;
86 | overflow: scroll;
87 | }
88 |
89 | .message-animation-enter {
90 | opacity: 0;
91 | transition: opacity .5s ease-in;
92 | }
93 |
94 | .message-animation-enter.message-animation-enter-active {
95 | opacity: 1;
96 | }
97 |
--------------------------------------------------------------------------------