├── .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
48 | 49 | 50 |
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 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 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 | --------------------------------------------------------------------------------