├── README.md ├── challenge-baby-name-picker ├── README.md ├── babyNamesData.json └── example-screenshots │ ├── finished.png │ ├── level-1.png │ ├── level-2.png │ ├── level-3.png │ └── level-4.png ├── challenge-counters ├── README.md └── images │ ├── counters-screenshot-advanced.png │ └── counters-screenshot-basic.png ├── challenge-countries ├── README.md └── countriesAll.json ├── challenge-country-capitals ├── README.md ├── capital-game-screenshot.png └── capitals.json ├── challenge-dice-roller ├── README.md └── example-screenshots │ ├── finished.png │ ├── level-1.png │ ├── level-2.png │ ├── level-3.png │ ├── level-4.png │ ├── level-5.png │ └── level-6.png ├── challenge-high-score-tables ├── README.md ├── example-screenshots │ ├── foo.txt │ └── react-high-score-tables-example-layout.png └── scores.js ├── challenge-image-carousel ├── README.md └── example-screenshots │ ├── example-level1.png │ └── example-level2.png ├── challenge-job-listing └── README.md ├── challenge-music-keyboard ├── README.md └── example-screenshots │ ├── example1.png │ └── example2.png ├── challenge-quiz ├── README.md └── question.json ├── challenge-sengen ├── README.md └── example-screenshots │ └── example1.png ├── challenge-tfl-lines ├── README.md └── example-screenshots │ ├── level-100-screenshot-1.png │ ├── level-100-screenshot-2.png │ ├── level-100-video.gif │ ├── level-200-screenshot-1.png │ ├── level-200-screenshot-2.png │ ├── level-200-video.gif │ ├── level-300-screenshot.png │ ├── level-300-video.gif │ ├── level-999-screenshot-1.png │ ├── level-999-screenshot-2.png │ └── level-999-video.gif ├── challenge-tv-show-info ├── README.md ├── example-level-1.png ├── example-level-2.png ├── example-level-3.png ├── github-instructions.md ├── season-layout-by-mussie.jpg ├── season-selector-mockup.png └── teaching_notes.md └── challenges-mars └── README.md /README.md: -------------------------------------------------------------------------------- 1 | # CodeYourFuture React Challenges 2 | 3 | A collection of introductory React challenges. 4 | 5 | There are also some larger projects at https://github.com/CodeYourFuture/group-projects#react-only-projects 6 | 7 | ## Contribution Guide 8 | Want to add a challenge? 9 | 10 | A good challenge consists of 11 | 12 | - A real world application for what the student is building 13 | - Uses real world data to make the application interesting 14 | - Has multiple levels that a student can complete 15 | - Is well definined 16 | - Is targetted at begineer developers 17 | 18 | Everyone is welcome to raise a Pull Request on this repository - please share with volunteers and/or students before merging. 19 | -------------------------------------------------------------------------------- /challenge-baby-name-picker/README.md: -------------------------------------------------------------------------------- 1 | # Challenge: "Baby Name Picker (React)" 2 | 3 | ![Example Screenshot from the finished challenge](./example-screenshots/finished.png) 4 | 5 | ## Challenge Overview 6 | 7 | Make a React app which shows some baby names and lets you pick your favourites. The names data is provided for you. 8 | 9 | ## Difficulty Level 10 | 11 | This is a beginner challenge. Level one can be completed by any student who has done week 1 of the CYF React module. 12 | 13 | The later levels are suitable from students who have completed at least week 2 of the CYF React module. 14 | 15 | ## Pre-requisites - what do I need to know to finish this challenge? 16 | 17 | (Level 1) 18 | 19 | - React `props` 20 | - The `array.map` method and its use in React JSX 21 | 22 | (Later levels) 23 | 24 | - Event handlers: onClick for buttons 25 | - Event handlers: onChange for input fields 26 | - The `useState` hook 27 | 28 | ## Getting Started 29 | 30 | **Don't** clone this repo. 31 | 32 | Make your own React app using `create-react-app`. See [(this guide)](https://docs.codeyourfuture.io/students/guides/creating-a-react-app) if you have forgotten how. 33 | 34 | Copy across the names file (or its contents) from this repo to your app, and then import from that file. 35 | 36 | Write a plain HTML prototype (e.g. on codepen). THEN, once you know the HTML you're attempting to create, work on the React version! This is not mandatory but it is recommended. 37 | 38 | ### The data: 39 | 40 | The data is available in the file [./babyNamesData.json](./babyNamesData.json). 41 | 42 | Copy across this file to your src/ directory, and then import it. 43 | 44 | ## GitHub & Hosting: 45 | 46 | Add your project in github and host it on Netlify. 47 | 48 | The github repo name should be exactly: 49 | `baby-names-react` 50 | 51 | The netlify site suffix should be `-baby-names` 52 | 53 | so... 54 | 55 | `cyf-YOURGITHUBUSERNAME-baby-names` 56 | 57 | # Level 1 Challenge 58 | 59 | * Write a react app which lists baby names from the given file. 60 | 61 | * It should display boys' and girls' names differently - your choice* 62 | 63 | * The names should be displayed in alphabetical order, ascending. 64 | 65 | * Your project should be on GitHub and Netlify with correct names (see Hosting, above). 66 | 67 | (*) Please, please feel free to break from the the "blue-for-boys/pink-for-girls" stereotyping and style it differently. The best creative solution will be included in this challenge document for subsequent cohorts to admire. 68 | 69 | ### Example Screenshot 70 | 71 | ![Level 1 Example Screenshot](./example-screenshots/level-1.png) 72 | 73 | # Level 2 challenge 74 | 75 | * Add a search bar. 76 | 77 | * When someone types into it, your app should update the displayed list of baby names to only show matches. 78 | 79 | * Matches should be case-insensitive. 80 | 81 | * When the search bar is clear, all names should be shown. 82 | 83 | ### Example Screenshot 84 | 85 | ![Level 2 Example Screenshot](./example-screenshots/level-2.png) 86 | 87 | # Level 3 challenge 88 | 89 | * Add "favourites". 90 | 91 | * When the user clicks a name from the main list, it should be moved to a "favourites" list, displayed separately. 92 | It should disappear from the main list! 93 | 94 | * When the user clicks a name from the _favourites_ list, it should be moved back to the main list. It should disappear from the favourites list! 95 | 96 | ### Example Screenshot 97 | 98 | ![Level 3 Example Screenshot](./example-screenshots/level-3.png) 99 | 100 | # Level 4 challenge 101 | 102 | Add "name gender" filter buttons. 103 | 104 | Add buttons that allow the user to only see boy or girl names (or all names). 105 | 106 | The buttons should operate as "radio" buttons - exactly one should be active at any time. 107 | 108 | The app should start by showing all names. 109 | 110 | The app should make it clear which filter is in effect. 111 | 112 | _How it works with search:_ 113 | 114 | If there is also a search term in effect, your app should apply any name gender filter to those search results. 115 | 116 | ### Example Screenshot 117 | 118 | ![Level 4 Example Screenshot](./example-screenshots/level-4.png) 119 | 120 | # Beyond - ideas for more work 121 | 122 | - Find a way to persist the favourites even after the browser tab is closed 123 | - Add the ability for the user to shuffle the list of names 124 | - Add the ability for the user to be presented with one or two randomly chosen names. 125 | - Find an attractive way to differentiate names by gender that doesn't use blue/pink stereotypes. 126 | - Add some suitably-themed sound effects for the UI. Josh W Comeau's [useSound hook](https://www.joshwcomeau.com/react/announcing-use-sound-react-hook/) can help here, as can [freesound.org](https://freesound.org/) 127 | 128 | ## Further resources 129 | 130 | # Credits 131 | 132 | This application idea, and look, were taken from [Simon Vrachliotis'](https://simonswiss.com/) app, found via [react.rocks](https://react.rocks/example/Baby_name_inspiration). 133 | -------------------------------------------------------------------------------- /challenge-baby-name-picker/babyNamesData.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 0, 4 | "name": "Zahra", 5 | "sex": "f" 6 | }, 7 | { 8 | "id": 1, 9 | "name": "Parsa", 10 | "sex": "m" 11 | }, 12 | { 13 | "id": 2, 14 | "name": "Avah", 15 | "sex": "f" 16 | }, 17 | { 18 | "id": 3, 19 | "name": "Lala", 20 | "sex": "f" 21 | }, 22 | { 23 | "id": 4, 24 | "name": "Jamshed", 25 | "sex": "m" 26 | }, 27 | { 28 | "id": 5, 29 | "name": "Yasir", 30 | "sex": "m" 31 | }, 32 | { 33 | "id": 6, 34 | "name": "Damiya", 35 | "sex": "f" 36 | }, 37 | { 38 | "id": 7, 39 | "name": "Abbas", 40 | "sex": "m" 41 | }, 42 | { 43 | "id": 8, 44 | "name": "Sahar", 45 | "sex": "f" 46 | }, 47 | { 48 | "id": 9, 49 | "name": "Neo", 50 | "sex": "m" 51 | }, 52 | { 53 | "id": 10, 54 | "name": "Damali", 55 | "sex": "f" 56 | }, 57 | { 58 | "id": 11, 59 | "name": "Olajuwon", 60 | "sex": "m" 61 | }, 62 | { 63 | "id": 12, 64 | "name": "Elinda", 65 | "sex": "f" 66 | }, 67 | { 68 | "id": 13, 69 | "name": "Emoni", 70 | "sex": "f" 71 | }, 72 | { 73 | "id": 14, 74 | "name": "Nabil", 75 | "sex": "m" 76 | }, 77 | { 78 | "id": 15, 79 | "name": "Kheri", 80 | "sex": "f" 81 | }, 82 | { 83 | "id": 16, 84 | "name": "Kidus", 85 | "sex": "m" 86 | }, 87 | { 88 | "id": 17, 89 | "name": "Aiyana", 90 | "sex": "f" 91 | }, 92 | { 93 | "id": 18, 94 | "name": "Ayana", 95 | "sex": "f" 96 | }, 97 | { 98 | "id": 19, 99 | "name": "Makoa", 100 | "sex": "m" 101 | }, 102 | { 103 | "id": 20, 104 | "name": "Cyrus", 105 | "sex": "m" 106 | }, 107 | { 108 | "id": 21, 109 | "name": "Mina", 110 | "sex": "f" 111 | }, 112 | { 113 | "id": 22, 114 | "name": "Zia", 115 | "sex": "f" 116 | }, 117 | { 118 | "id": 23, 119 | "name": "Roshan", 120 | "sex": "m" 121 | }, 122 | { 123 | "id": 24, 124 | "name": "Taja", 125 | "sex": "f" 126 | }, 127 | { 128 | "id": 25, 129 | "name": "Naveed", 130 | "sex": "m" 131 | }, 132 | { 133 | "id": 26, 134 | "name": "Suri", 135 | "sex": "f" 136 | }, 137 | { 138 | "id": 27, 139 | "name": "Farah", 140 | "sex": "f" 141 | }, 142 | { 143 | "id": 28, 144 | "name": "Shirin", 145 | "sex": "f" 146 | }, 147 | { 148 | "id": 29, 149 | "name": "Navid", 150 | "sex": "m" 151 | }, 152 | { 153 | "id": 30, 154 | "name": "Azra", 155 | "sex": "f" 156 | }, 157 | { 158 | "id": 31, 159 | "name": "Adonai", 160 | "sex": "m" 161 | }, 162 | { 163 | "id": 32, 164 | "name": "Livna", 165 | "sex": "f" 166 | }, 167 | { 168 | "id": 33, 169 | "name": "Sheran", 170 | "sex": "f" 171 | }, 172 | { 173 | "id": 34, 174 | "name": "Mayar", 175 | "sex": "f" 176 | }, 177 | { 178 | "id": 35, 179 | "name": "Magdalene", 180 | "sex": "f" 181 | }, 182 | { 183 | "id": 36, 184 | "name": "Areli", 185 | "sex": "f" 186 | }, 187 | { 188 | "id": 37, 189 | "name": "Or", 190 | "sex": "m" 191 | }, 192 | { 193 | "id": 38, 194 | "name": "Josiah", 195 | "sex": "m" 196 | }, 197 | { 198 | "id": 39, 199 | "name": "Zetta", 200 | "sex": "f" 201 | }, 202 | { 203 | "id": 40, 204 | "name": "Rohin", 205 | "sex": "m" 206 | }, 207 | { 208 | "id": 41, 209 | "name": "Vilas", 210 | "sex": "m" 211 | }, 212 | { 213 | "id": 42, 214 | "name": "Isha", 215 | "sex": "f" 216 | }, 217 | { 218 | "id": 43, 219 | "name": "Shlok", 220 | "sex": "m" 221 | }, 222 | { 223 | "id": 44, 224 | "name": "Setia", 225 | "sex": "f" 226 | }, 227 | { 228 | "id": 45, 229 | "name": "Surya", 230 | "sex": "m" 231 | }, 232 | { 233 | "id": 46, 234 | "name": "Arushi", 235 | "sex": "f" 236 | }, 237 | { 238 | "id": 47, 239 | "name": "Aditi", 240 | "sex": "f" 241 | }, 242 | { 243 | "id": 48, 244 | "name": "Rachana", 245 | "sex": "f" 246 | }, 247 | { 248 | "id": 49, 249 | "name": "Vadhir", 250 | "sex": "m" 251 | }, 252 | { 253 | "id": 50, 254 | "name": "Mohammad", 255 | "sex": "m" 256 | }, 257 | { 258 | "id": 51, 259 | "name": "Shaan", 260 | "sex": "m" 261 | }, 262 | { 263 | "id": 52, 264 | "name": "Arathi", 265 | "sex": "m" 266 | }, 267 | { 268 | "id": 53, 269 | "name": "Ashwin", 270 | "sex": "m" 271 | }, 272 | { 273 | "id": 54, 274 | "name": "Rudra", 275 | "sex": "m" 276 | }, 277 | { 278 | "id": 55, 279 | "name": "Loma", 280 | "sex": "f" 281 | }, 282 | { 283 | "id": 56, 284 | "name": "Patrick", 285 | "sex": "m" 286 | }, 287 | { 288 | "id": 57, 289 | "name": "Sriram", 290 | "sex": "m" 291 | }, 292 | { 293 | "id": 58, 294 | "name": "Aayan", 295 | "sex": "m" 296 | }, 297 | { 298 | "id": 59, 299 | "name": "Shakila", 300 | "sex": "f" 301 | }, 302 | { 303 | "id": 60, 304 | "name": "Iran", 305 | "sex": "m" 306 | }, 307 | { 308 | "id": 62, 309 | "name": "Dara", 310 | "sex": "f" 311 | }, 312 | { 313 | "id": 63, 314 | "name": "Jama", 315 | "sex": "f" 316 | }, 317 | { 318 | "id": 64, 319 | "name": "Yasmina", 320 | "sex": "f" 321 | }, 322 | { 323 | "id": 65, 324 | "name": "Mikah", 325 | "sex": "m" 326 | }, 327 | { 328 | "id": 66, 329 | "name": "Aram", 330 | "sex": "m" 331 | }, 332 | { 333 | "id": 67, 334 | "name": "Arash", 335 | "sex": "m" 336 | }, 337 | { 338 | "id": 69, 339 | "name": "Aashi", 340 | "sex": "f" 341 | }, 342 | { 343 | "id": 70, 344 | "name": "Zamir", 345 | "sex": "m" 346 | }, 347 | { 348 | "id": 71, 349 | "name": "Mostafa", 350 | "sex": "m" 351 | }, 352 | { 353 | "id": 72, 354 | "name": "Yasin", 355 | "sex": "m" 356 | }, 357 | { 358 | "id": 73, 359 | "name": "Zaki", 360 | "sex": "m" 361 | }, 362 | { 363 | "id": 74, 364 | "name": "Ammar", 365 | "sex": "m" 366 | }, 367 | { 368 | "id": 76, 369 | "name": "An", 370 | "sex": "f" 371 | }, 372 | { 373 | "id": 77, 374 | "name": "Shira", 375 | "sex": "f" 376 | }, 377 | { 378 | "id": 78, 379 | "name": "Yaron", 380 | "sex": "m" 381 | }, 382 | { 383 | "id": 79, 384 | "name": "Noam", 385 | "sex": "m" 386 | }, 387 | { 388 | "id": 80, 389 | "name": "Shalom", 390 | "sex": "f" 391 | }, 392 | { 393 | "id": 81, 394 | "name": "Ester", 395 | "sex": "f" 396 | }, 397 | { 398 | "id": 82, 399 | "name": "Aharon", 400 | "sex": "m" 401 | }, 402 | { 403 | "id": 83, 404 | "name": "Ahuva", 405 | "sex": "f" 406 | }, 407 | { 408 | "id": 84, 409 | "name": "Shomron", 410 | "sex": "m" 411 | }, 412 | { 413 | "id": 85, 414 | "name": "David", 415 | "sex": "m" 416 | }, 417 | { 418 | "id": 86, 419 | "name": "Michal", 420 | "sex": "m" 421 | }, 422 | { 423 | "id": 88, 424 | "name": "Ahmed", 425 | "sex": "m" 426 | }, 427 | { 428 | "id": 89, 429 | "name": "Abdul", 430 | "sex": "m" 431 | }, 432 | { 433 | "id": 90, 434 | "name": "Ahmad", 435 | "sex": "m" 436 | }, 437 | { 438 | "id": 91, 439 | "name": "Noor", 440 | "sex": "f" 441 | }, 442 | { 443 | "id": 92, 444 | "name": "Wira", 445 | "sex": "m" 446 | }, 447 | { 448 | "id": 93, 449 | "name": "Malik", 450 | "sex": "m" 451 | }, 452 | { 453 | "id": 96, 454 | "name": "Hakim", 455 | "sex": "m" 456 | }, 457 | { 458 | "id": 97, 459 | "name": "Samar", 460 | "sex": "m" 461 | }, 462 | { 463 | "id": 98, 464 | "name": "Raniya", 465 | "sex": "f" 466 | }, 467 | { 468 | "id": 99, 469 | "name": "Nader", 470 | "sex": "m" 471 | }, 472 | { 473 | "id": 100, 474 | "name": "Bahar", 475 | "sex": "f" 476 | }, 477 | { 478 | "id": 101, 479 | "name": "Gibran", 480 | "sex": "m" 481 | }, 482 | { 483 | "id": 102, 484 | "name": "Alysia", 485 | "sex": "f" 486 | }, 487 | { 488 | "id": 104, 489 | "name": "Nadiyya", 490 | "sex": "f" 491 | }, 492 | { 493 | "id": 105, 494 | "name": "Najah", 495 | "sex": "f" 496 | }, 497 | { 498 | "id": 106, 499 | "name": "Basil", 500 | "sex": "m" 501 | }, 502 | { 503 | "id": 107, 504 | "name": "Yasmin", 505 | "sex": "f" 506 | }, 507 | { 508 | "id": 109, 509 | "name": "Salma", 510 | "sex": "f" 511 | }, 512 | { 513 | "id": 111, 514 | "name": "Rahim", 515 | "sex": "m" 516 | }, 517 | { 518 | "id": 112, 519 | "name": "Ibrahim", 520 | "sex": "m" 521 | }, 522 | { 523 | "id": 113, 524 | "name": "Samira", 525 | "sex": "f" 526 | }, 527 | { 528 | "id": 114, 529 | "name": "Sabir", 530 | "sex": "m" 531 | }, 532 | { 533 | "id": 115, 534 | "name": "Suhana", 535 | "sex": "f" 536 | }, 537 | { 538 | "id": 116, 539 | "name": "Rasheed", 540 | "sex": "m" 541 | }, 542 | { 543 | "id": 117, 544 | "name": "Osman", 545 | "sex": "m" 546 | }, 547 | { 548 | "id": 118, 549 | "name": "Irania", 550 | "sex": "f" 551 | }, 552 | { 553 | "id": 120, 554 | "name": "Rasheen", 555 | "sex": "m" 556 | }, 557 | { 558 | "id": 121, 559 | "name": "Estie", 560 | "sex": "f" 561 | }, 562 | { 563 | "id": 122, 564 | "name": "Armaan", 565 | "sex": "m" 566 | }, 567 | { 568 | "id": 123, 569 | "name": "Lela", 570 | "sex": "f" 571 | }, 572 | { 573 | "id": 124, 574 | "name": "Malikah", 575 | "sex": "f" 576 | }, 577 | { 578 | "id": 125, 579 | "name": "Gulzar", 580 | "sex": "m" 581 | }, 582 | { 583 | "id": 126, 584 | "name": "Maryam", 585 | "sex": "f" 586 | }, 587 | { 588 | "id": 127, 589 | "name": "Adrian", 590 | "sex": "m" 591 | }, 592 | { 593 | "id": 128, 594 | "name": "Blenda", 595 | "sex": "f" 596 | }, 597 | { 598 | "id": 129, 599 | "name": "Kasandra", 600 | "sex": "f" 601 | }, 602 | { 603 | "id": 130, 604 | "name": "Hubert", 605 | "sex": "m" 606 | }, 607 | { 608 | "id": 131, 609 | "name": "Deniel", 610 | "sex": "m" 611 | }, 612 | { 613 | "id": 132, 614 | "name": "Konrad", 615 | "sex": "m" 616 | }, 617 | { 618 | "id": 133, 619 | "name": "Mateusz", 620 | "sex": "m" 621 | }, 622 | { 623 | "id": 134, 624 | "name": "Leon", 625 | "sex": "m" 626 | }, 627 | { 628 | "id": 135, 629 | "name": "Kamila", 630 | "sex": "f" 631 | }, 632 | { 633 | "id": 136, 634 | "name": "Albin", 635 | "sex": "m" 636 | }, 637 | { 638 | "id": 137, 639 | "name": "Cezar", 640 | "sex": "m" 641 | }, 642 | { 643 | "id": 138, 644 | "name": "Gabriel", 645 | "sex": "m" 646 | }, 647 | { 648 | "id": 139, 649 | "name": "Maria", 650 | "sex": "f" 651 | }, 652 | { 653 | "id": 141, 654 | "name": "Ina", 655 | "sex": "f" 656 | }, 657 | { 658 | "id": 142, 659 | "name": "Eduard", 660 | "sex": "m" 661 | }, 662 | { 663 | "id": 143, 664 | "name": "Claudia", 665 | "sex": "f" 666 | }, 667 | { 668 | "id": 144, 669 | "name": "Paul", 670 | "sex": "m" 671 | }, 672 | { 673 | "id": 145, 674 | "name": "Ileana", 675 | "sex": "f" 676 | }, 677 | { 678 | "id": 146, 679 | "name": "Lucian", 680 | "sex": "m" 681 | }, 682 | { 683 | "id": 147, 684 | "name": "Aida", 685 | "sex": "f" 686 | }, 687 | { 688 | "id": 149, 689 | "name": "Fatoumata", 690 | "sex": "f" 691 | }, 692 | { 693 | "id": 150, 694 | "name": "Fatou", 695 | "sex": "f" 696 | }, 697 | { 698 | "id": 151, 699 | "name": "Musa", 700 | "sex": "m" 701 | }, 702 | { 703 | "id": 152, 704 | "name": "Mariama", 705 | "sex": "f" 706 | }, 707 | { 708 | "id": 153, 709 | "name": "Oumar", 710 | "sex": "m" 711 | }, 712 | { 713 | "id": 154, 714 | "name": "Agata", 715 | "sex": "f" 716 | }, 717 | { 718 | "id": 156, 719 | "name": "Aminata", 720 | "sex": "f" 721 | }, 722 | { 723 | "id": 157, 724 | "name": "Asante", 725 | "sex": "f" 726 | }, 727 | { 728 | "id": 158, 729 | "name": "Zakiyah", 730 | "sex": "f" 731 | }, 732 | { 733 | "id": 159, 734 | "name": "Kwasi", 735 | "sex": "m" 736 | }, 737 | { 738 | "id": 160, 739 | "name": "Jina", 740 | "sex": "f" 741 | }, 742 | { 743 | "id": 163, 744 | "name": "Kwanza", 745 | "sex": "m" 746 | }, 747 | { 748 | "id": 164, 749 | "name": "Imani", 750 | "sex": "f" 751 | }, 752 | { 753 | "id": 165, 754 | "name": "Milly", 755 | "sex": "f" 756 | }, 757 | { 758 | "id": 166, 759 | "name": "Saskia", 760 | "sex": "f" 761 | }, 762 | { 763 | "id": 167, 764 | "name": "Lyuba", 765 | "sex": "f" 766 | }, 767 | { 768 | "id": 168, 769 | "name": "Laszlo", 770 | "sex": "m" 771 | }, 772 | { 773 | "id": 169, 774 | "name": "Nika", 775 | "sex": "f" 776 | }, 777 | { 778 | "id": 170, 779 | "name": "Yana", 780 | "sex": "f" 781 | }, 782 | { 783 | "id": 171, 784 | "name": "Vlasta", 785 | "sex": "f" 786 | }, 787 | { 788 | "id": 172, 789 | "name": "Ivan", 790 | "sex": "m" 791 | }, 792 | { 793 | "id": 173, 794 | "name": "Milana", 795 | "sex": "f" 796 | }, 797 | { 798 | "id": 174, 799 | "name": "Marica", 800 | "sex": "f" 801 | }, 802 | { 803 | "id": 175, 804 | "name": "Marko", 805 | "sex": "m" 806 | }, 807 | { 808 | "id": 176, 809 | "name": "Petra", 810 | "sex": "f" 811 | }, 812 | { 813 | "id": 177, 814 | "name": "Arica", 815 | "sex": "f" 816 | }, 817 | { 818 | "id": 178, 819 | "name": "Zainab", 820 | "sex": "f" 821 | }, 822 | { 823 | "id": 179, 824 | "name": "Attila", 825 | "sex": "f" 826 | }, 827 | { 828 | "id": 180, 829 | "name": "Eren", 830 | "sex": "f" 831 | }, 832 | { 833 | "id": 182, 834 | "name": "Demir", 835 | "sex": "m" 836 | }, 837 | { 838 | "id": 183, 839 | "name": "Angus", 840 | "sex": "m" 841 | }, 842 | { 843 | "id": 184, 844 | "name": "Temür", 845 | "sex": "m" 846 | }, 847 | { 848 | "id": 185, 849 | "name": "Sulaiman", 850 | "sex": "m" 851 | }, 852 | { 853 | "id": 186, 854 | "name": "Ozella", 855 | "sex": "f" 856 | } 857 | ] 858 | -------------------------------------------------------------------------------- /challenge-baby-name-picker/example-screenshots/finished.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-baby-name-picker/example-screenshots/finished.png -------------------------------------------------------------------------------- /challenge-baby-name-picker/example-screenshots/level-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-baby-name-picker/example-screenshots/level-1.png -------------------------------------------------------------------------------- /challenge-baby-name-picker/example-screenshots/level-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-baby-name-picker/example-screenshots/level-2.png -------------------------------------------------------------------------------- /challenge-baby-name-picker/example-screenshots/level-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-baby-name-picker/example-screenshots/level-3.png -------------------------------------------------------------------------------- /challenge-baby-name-picker/example-screenshots/level-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-baby-name-picker/example-screenshots/level-4.png -------------------------------------------------------------------------------- /challenge-counters/README.md: -------------------------------------------------------------------------------- 1 | # Challenge: Lunch Order Counters 2 | 3 | ## Challenge Overview 4 | 5 | Make a React app which assists you in taking an order for lunch for a large group. 6 | 7 | It should provide multiple counters for different options (vegetarian, halal, vegan, etc). 8 | 9 | ### Try a live demo 10 | 11 | [Try the live demo here](https://cyf-counters-react.netlify.com/). 12 | 13 | ### Example Screenshot 14 | 15 | ![Example Screenshot](./images/counters-screenshot-basic.png) 16 | 17 | ## What you need to know before starting: 18 | 19 | This challenge is suitable if you have successfully completed the homework of CYF React Week 2. 20 | 21 | # Try to figure the rest out by yourself 22 | 23 | If you want a harder challenge, don't read the rest of this document but try to build the app by yourself. 24 | 25 | # Suggested approach 26 | 27 | Here's one approach you might take to building this app. 28 | 29 | ## Task: Create a new React app 30 | 31 | Create a new empty React app for this challenge. 32 | 33 | The tool can take a while to run, so continue with the next task while it's running... 34 | 35 | ## Task: Design your layout _on paper_ 36 | 37 | Design your layout on paper. Keep it very simple - this is a React challenge, not a CSS challenge. 38 | 39 | Use a layout that will be ok on a phone (but don't do responsive design). 40 | 41 | Keep this drawing around for reference later. 42 | 43 | ## Task: Convert your layout to JSX (HTML) 44 | 45 | Make a prototype which just shows two or three example counters. _Don't_ worry about the JSON yet. 46 | 47 | You can do this all within your `App.js`, or you can immediately build some React Component(s). 48 | 49 | ## Task: Make a component to represent a counter 50 | 51 | Make a single counter which has a title given to it and which increments its count when clicked. 52 | 53 | ## Task: Use this component repeatedly 54 | 55 | Reuse your component for each meal option you want to present. 56 | 57 | ## Task: Host your app 58 | 59 | Host your app and prove it works by viewing it on your phone! 60 | 61 | ## Task: Host your app 62 | 63 | Host your app and prove it works by viewing it on your phone! 64 | 65 | We recommend you use Netlify. [Instructions are here](https://gist.github.com/nbogie/bf58a391fab6884f77a6adec66047181). 66 | 67 | (You can instead use Heroku to host, or github pages, or codesandbox.io, or glitch.com...) 68 | 69 | ## Advanced challenges: total, and reset 70 | 71 | ![Example Screenshot](./images/counters-screenshot-advanced.png) 72 | 73 | See more detail below... 74 | 75 | ### Advanced Challenge: Add a reset button 76 | 77 | Add a reset button which will set all counts back to zero. 78 | 79 | ### Advanced Challenge: Add a total 80 | 81 | Add a live total of meals selected. 82 | -------------------------------------------------------------------------------- /challenge-counters/images/counters-screenshot-advanced.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-counters/images/counters-screenshot-advanced.png -------------------------------------------------------------------------------- /challenge-counters/images/counters-screenshot-basic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-counters/images/counters-screenshot-basic.png -------------------------------------------------------------------------------- /challenge-countries/README.md: -------------------------------------------------------------------------------- 1 | # Challenge: "Frontend Mentor's REST Countries API with color theme switcher (React)" 2 | 3 | This excellent challenge was created by, and lives at [frontendmentor.io](https://www.frontendmentor.io/challenges/rest-countries-api-with-color-theme-switcher-5cacc469fec04111f7b848ca). 4 | 5 | In *this* document we will simply break down that challenge into approachable levels, and give extra tips for getting started. 6 | 7 | ## Challenge Overview 8 | 9 | Your *eventual* challenge is to make a React app integrate with the REST Countries API to fetch country data and display it like in the designs provided by [frontendmentor.io](https://www.frontendmentor.io/challenges/rest-countries-api-with-color-theme-switcher-5cacc469fec04111f7b848ca). 10 | 11 | However, in the earlier levels you will be given a file containing with the downloaded countries data, so that you do not have to fetch it from the API. 12 | 13 | ## Pre-requisites - what do I need to know to finish this challenge? 14 | 15 | Level 1 - React week 1: 16 | 17 | - React `props` 18 | - The `array.map` method and its use in React JSX 19 | - Lots of CSS (flexbox recommended) 20 | 21 | Later levels - React week 2: 22 | 23 | - Event handlers: `onClick` for buttons 24 | - Event handlers: `onChange` for input fields and `select` elements 25 | - `useState`: The React State hook 26 | - `useEffect`: The React Effect hook, and how to use it with `fetch`. 27 | 28 | ## Getting Started 29 | 30 | * **Don't** clone this repo. 31 | * Read Level 1 below, but don't start 32 | * Carefully read [the brief in the frontend mentor challenge](https://www.frontendmentor.io/challenges/rest-countries-api-with-color-theme-switcher-5cacc469fec04111f7b848ca) 33 | * Sign in to frontendmentor.io and download and expand the starter pack 34 | * Read the instructions and guidance in that pack. 35 | * Read Level 1 below, again! It tells you what you can ignore! 36 | * Make your own React app using `create-react-app`. See [(this guide)](https://docs.codeyourfuture.io/students/guides/creating-a-react-app) if you have forgotten how. 37 | * Copy the [./countriesAll.json](./countriesAll.json) data file into your `src/` directory, and then import it. 38 | * Put your project on GitHub (see below) 39 | * Host it on Netlify (see below) 40 | * Write a plain HTML prototype (e.g. on codepen) with some copy-pasted country "cards". THEN, once you are confident about the HTML you need to create... 41 | * Start to code the React app! 42 | 43 | ### The data: 44 | 45 | * The data you will need is available in the file [./countriesAll.json](./countriesAll.json). This is a list of all countries, obtained from `https://restcountries.eu/rest/v2/all` 46 | * Read "Getting Started" for what to do with this file. 47 | * In *later* levels you will make your app fetch the data directly from the API as described in the frontendmentor challenge. 48 | 49 | ## GitHub & Hosting: 50 | 51 | Add your project in github and host it on Netlify. 52 | 53 | 54 | | site: | correct name | 55 | | ------------- | ----------------------------------------------- | 56 | | GitHub repo | `countries-react` | 57 | | Netlify site | `cyf-YOURGITHUBUSERNAME-countries-react` | 58 | 59 | 60 | 61 | # Level 1 Challenge 62 | 63 | * Write a react app to present the list of countries as shown in the frontend mentor challenge. 64 | * Get as close as possible to the presentation. 65 | * Format the population correctly 66 | * Ignore the search box 67 | * Ignore the region select 68 | * Ignore the colour theme selector 69 | * Ignore the requirement to allow "clicking into" specific countries. Just show the main list. 70 | * Publish your project on GitHub and Netlify with the correct names (see Hosting, above). 71 | 72 | # Level 2 challenge 73 | 74 | * Add the search box 75 | * When the search box has text in it, your app should update the displayed list of countries to only show matches 76 | * Accept matches of the string in the country name **AND** matches in the capital's name 77 | * Matches should be case-insensitive. 78 | * When the search bar is clear, all countries should be shown. 79 | 80 | # Level 3 challenge 81 | 82 | * Add the "region select" menu 83 | * When this is changed, only show the countries which: 84 | * have the chosen region, AND 85 | * match the search box term (if there is one) 86 | * When a region is not selected (i.e. the menu is set to "Filter by region") then countries should NOT be filtered by region and only the search rules should apply. 87 | 88 | # Level 4 challenge 89 | 90 | * Allow users to click on a country and view that country's full details, as shown in the frontendmentor challenge. 91 | * Make sure to allow clicking on bordering countries to visit these neighbours 92 | * Don't forget the "back" button 93 | 94 | # Level 5 challenge 95 | * Implement the colour scheme picker 96 | 97 | # Beyond - ideas for more work 98 | 99 | - easy: Add a "random country" button 100 | - Advanced: Make a quiz where a country card is shown and 5 random capitals - the user must correctly guess the correct capital. 101 | - use a separate component to develop this without affecting your main app 102 | - Advanced: Make a game where two countries are named and the user tries to navigate from one country to another via their bordering countries in the fewest possible steps. 103 | - record "favourite" countries 104 | - Find a way to persist these even after the browser tab is closed 105 | - See the existing [CYF Group project: Countries](https://github.com/CodeYourFuture/group-project-countries) for more ideas 106 | 107 | 108 | # Credits 109 | 110 | This is a presentation (and further structuring) of a free challenge made available [here](https://www.frontendmentor.io/challenges/rest-countries-api-with-color-theme-switcher-5cacc469fec04111f7b848ca) by [Frontend Mentor](https://www.frontendmentor.io/). Code Your Future are grateful for that excellent resource! 111 | -------------------------------------------------------------------------------- /challenge-country-capitals/README.md: -------------------------------------------------------------------------------- 1 | # Challenge: make a country-capital guessing game 2 | 3 | ## Example layout 4 | 5 | ![screenshot](capital-game-screenshot.png) 6 | 7 | Load the json, `capitals.json` 8 | 9 | Make a react app which: 10 | 11 | - randomly chooses a country from the list of capitals, 12 | - presents 5 possible capitals to choose from (one being correct), 13 | - tells you if you guess correctly or not. 14 | 15 | # Additional challenges 16 | 17 | - Add scoring or counting of your winning streak. 18 | 19 | - Add a timer? 20 | 21 | # Data source: 22 | 23 | Combined and cleaned from http://country.io/data/ 24 | -------------------------------------------------------------------------------- /challenge-country-capitals/capital-game-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-country-capitals/capital-game-screenshot.png -------------------------------------------------------------------------------- /challenge-country-capitals/capitals.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "name": "Afghanistan", "capital": "Kabul" }, 3 | { "name": "Aland Islands", "capital": "Mariehamn" }, 4 | { "name": "Albania", "capital": "Tirana" }, 5 | { "name": "Algeria", "capital": "Algiers" }, 6 | { "name": "American Samoa", "capital": "Pago Pago" }, 7 | { "name": "Andorra", "capital": "Andorra la Vella" }, 8 | { "name": "Angola", "capital": "Luanda" }, 9 | { "name": "Anguilla", "capital": "The Valley" }, 10 | { "name": "Antigua and Barbuda", "capital": "St. John's" }, 11 | { "name": "Argentina", "capital": "Buenos Aires" }, 12 | { "name": "Armenia", "capital": "Yerevan" }, 13 | { "name": "Aruba", "capital": "Oranjestad" }, 14 | { "name": "Australia", "capital": "Canberra" }, 15 | { "name": "Austria", "capital": "Vienna" }, 16 | { "name": "Azerbaijan", "capital": "Baku" }, 17 | { "name": "Bahamas", "capital": "Nassau" }, 18 | { "name": "Bahrain", "capital": "Manama" }, 19 | { "name": "Bangladesh", "capital": "Dhaka" }, 20 | { "name": "Barbados", "capital": "Bridgetown" }, 21 | { "name": "Belarus", "capital": "Minsk" }, 22 | { "name": "Belgium", "capital": "Brussels" }, 23 | { "name": "Belize", "capital": "Belmopan" }, 24 | { "name": "Benin", "capital": "Porto-Novo" }, 25 | { "name": "Bermuda", "capital": "Hamilton" }, 26 | { "name": "Bhutan", "capital": "Thimphu" }, 27 | { "name": "Bolivia", "capital": "Sucre" }, 28 | { "name": "Bosnia and Herzegovina", "capital": "Sarajevo" }, 29 | { "name": "Botswana", "capital": "Gaborone" }, 30 | { "name": "Brazil", "capital": "Brasilia" }, 31 | { "name": "British Indian Ocean Territory", "capital": "Diego Garcia" }, 32 | { "name": "British Virgin Islands", "capital": "Road Town" }, 33 | { "name": "Brunei", "capital": "Bandar Seri Begawan" }, 34 | { "name": "Bulgaria", "capital": "Sofia" }, 35 | { "name": "Burkina Faso", "capital": "Ouagadougou" }, 36 | { "name": "Burundi", "capital": "Bujumbura" }, 37 | { "name": "Cambodia", "capital": "Phnom Penh" }, 38 | { "name": "Cameroon", "capital": "Yaounde" }, 39 | { "name": "Canada", "capital": "Ottawa" }, 40 | { "name": "Cape Verde", "capital": "Praia" }, 41 | { "name": "Cayman Islands", "capital": "George Town" }, 42 | { "name": "Central African Republic", "capital": "Bangui" }, 43 | { "name": "Chad", "capital": "N'Djamena" }, 44 | { "name": "Chile", "capital": "Santiago" }, 45 | { "name": "China", "capital": "Beijing" }, 46 | { "name": "Christmas Island", "capital": "Flying Fish Cove" }, 47 | { "name": "Cocos Islands", "capital": "West Island" }, 48 | { "name": "Colombia", "capital": "Bogota" }, 49 | { "name": "Comoros", "capital": "Moroni" }, 50 | { "name": "Cook Islands", "capital": "Avarua" }, 51 | { "name": "Costa Rica", "capital": "San Jose" }, 52 | { "name": "Croatia", "capital": "Zagreb" }, 53 | { "name": "Cuba", "capital": "Havana" }, 54 | { "name": "Curacao", "capital": " Willemstad" }, 55 | { "name": "Cyprus", "capital": "Nicosia" }, 56 | { "name": "Czech Republic", "capital": "Prague" }, 57 | { "name": "Democratic Republic of the Congo", "capital": "Kinshasa" }, 58 | { "name": "Denmark", "capital": "Copenhagen" }, 59 | { "name": "Djibouti", "capital": "Djibouti" }, 60 | { "name": "Dominica", "capital": "Roseau" }, 61 | { "name": "Dominican Republic", "capital": "Santo Domingo" }, 62 | { "name": "East Timor", "capital": "Dili" }, 63 | { "name": "Ecuador", "capital": "Quito" }, 64 | { "name": "Egypt", "capital": "Cairo" }, 65 | { "name": "El Salvador", "capital": "San Salvador" }, 66 | { "name": "Equatorial Guinea", "capital": "Malabo" }, 67 | { "name": "Eritrea", "capital": "Asmara" }, 68 | { "name": "Estonia", "capital": "Tallinn" }, 69 | { "name": "Ethiopia", "capital": "Addis Ababa" }, 70 | { "name": "Falkland Islands", "capital": "Stanley" }, 71 | { "name": "Faroe Islands", "capital": "Torshavn" }, 72 | { "name": "Fiji", "capital": "Suva" }, 73 | { "name": "Finland", "capital": "Helsinki" }, 74 | { "name": "France", "capital": "Paris" }, 75 | { "name": "French Guiana", "capital": "Cayenne" }, 76 | { "name": "French Polynesia", "capital": "Papeete" }, 77 | { "name": "French Southern Territories", "capital": "Port-aux-Francais" }, 78 | { "name": "Gabon", "capital": "Libreville" }, 79 | { "name": "Gambia", "capital": "Banjul" }, 80 | { "name": "Georgia", "capital": "Tbilisi" }, 81 | { "name": "Germany", "capital": "Berlin" }, 82 | { "name": "Ghana", "capital": "Accra" }, 83 | { "name": "Gibraltar", "capital": "Gibraltar" }, 84 | { "name": "Greece", "capital": "Athens" }, 85 | { "name": "Greenland", "capital": "Nuuk" }, 86 | { "name": "Grenada", "capital": "St. George's" }, 87 | { "name": "Guadeloupe", "capital": "Basse-Terre" }, 88 | { "name": "Guam", "capital": "Hagatna" }, 89 | { "name": "Guatemala", "capital": "Guatemala City" }, 90 | { "name": "Guernsey", "capital": "St Peter Port" }, 91 | { "name": "Guinea-Bissau", "capital": "Bissau" }, 92 | { "name": "Guinea", "capital": "Conakry" }, 93 | { "name": "Guyana", "capital": "Georgetown" }, 94 | { "name": "Haiti", "capital": "Port-au-Prince" }, 95 | { "name": "Honduras", "capital": "Tegucigalpa" }, 96 | { "name": "Hong Kong", "capital": "Hong Kong" }, 97 | { "name": "Hungary", "capital": "Budapest" }, 98 | { "name": "Iceland", "capital": "Reykjavik" }, 99 | { "name": "India", "capital": "New Delhi" }, 100 | { "name": "Indonesia", "capital": "Jakarta" }, 101 | { "name": "Iran", "capital": "Tehran" }, 102 | { "name": "Iraq", "capital": "Baghdad" }, 103 | { "name": "Ireland", "capital": "Dublin" }, 104 | { "name": "Isle of Man", "capital": "Douglas, Isle of Man" }, 105 | { "name": "Israel", "capital": "Jerusalem" }, 106 | { "name": "Italy", "capital": "Rome" }, 107 | { "name": "Ivory Coast", "capital": "Yamoussoukro" }, 108 | { "name": "Jamaica", "capital": "Kingston" }, 109 | { "name": "Japan", "capital": "Tokyo" }, 110 | { "name": "Jersey", "capital": "Saint Helier" }, 111 | { "name": "Jordan", "capital": "Amman" }, 112 | { "name": "Kazakhstan", "capital": "Astana" }, 113 | { "name": "Kenya", "capital": "Nairobi" }, 114 | { "name": "Kiribati", "capital": "Tarawa" }, 115 | { "name": "Kosovo", "capital": "Pristina" }, 116 | { "name": "Kuwait", "capital": "Kuwait City" }, 117 | { "name": "Kyrgyzstan", "capital": "Bishkek" }, 118 | { "name": "Laos", "capital": "Vientiane" }, 119 | { "name": "Latvia", "capital": "Riga" }, 120 | { "name": "Lebanon", "capital": "Beirut" }, 121 | { "name": "Lesotho", "capital": "Maseru" }, 122 | { "name": "Liberia", "capital": "Monrovia" }, 123 | { "name": "Libya", "capital": "Tripolis" }, 124 | { "name": "Liechtenstein", "capital": "Vaduz" }, 125 | { "name": "Lithuania", "capital": "Vilnius" }, 126 | { "name": "Luxembourg", "capital": "Luxembourg" }, 127 | { "name": "Macao", "capital": "Macao" }, 128 | { "name": "Macedonia", "capital": "Skopje" }, 129 | { "name": "Madagascar", "capital": "Antananarivo" }, 130 | { "name": "Malawi", "capital": "Lilongwe" }, 131 | { "name": "Malaysia", "capital": "Kuala Lumpur" }, 132 | { "name": "Maldives", "capital": "Male" }, 133 | { "name": "Mali", "capital": "Bamako" }, 134 | { "name": "Malta", "capital": "Valletta" }, 135 | { "name": "Marshall Islands", "capital": "Majuro" }, 136 | { "name": "Martinique", "capital": "Fort-de-France" }, 137 | { "name": "Mauritania", "capital": "Nouakchott" }, 138 | { "name": "Mauritius", "capital": "Port Louis" }, 139 | { "name": "Mayotte", "capital": "Mamoudzou" }, 140 | { "name": "Mexico", "capital": "Mexico City" }, 141 | { "name": "Micronesia", "capital": "Palikir" }, 142 | { "name": "Moldova", "capital": "Chisinau" }, 143 | { "name": "Monaco", "capital": "Monaco" }, 144 | { "name": "Mongolia", "capital": "Ulan Bator" }, 145 | { "name": "Montenegro", "capital": "Podgorica" }, 146 | { "name": "Montserrat", "capital": "Plymouth" }, 147 | { "name": "Morocco", "capital": "Rabat" }, 148 | { "name": "Mozambique", "capital": "Maputo" }, 149 | { "name": "Myanmar", "capital": "Nay Pyi Taw" }, 150 | { "name": "Namibia", "capital": "Windhoek" }, 151 | { "name": "Nauru", "capital": "Yaren" }, 152 | { "name": "Nepal", "capital": "Kathmandu" }, 153 | { "name": "Netherlands", "capital": "Amsterdam" }, 154 | { "name": "New Caledonia", "capital": "Noumea" }, 155 | { "name": "New Zealand", "capital": "Wellington" }, 156 | { "name": "Nicaragua", "capital": "Managua" }, 157 | { "name": "Niger", "capital": "Niamey" }, 158 | { "name": "Nigeria", "capital": "Abuja" }, 159 | { "name": "Niue", "capital": "Alofi" }, 160 | { "name": "Norfolk Island", "capital": "Kingston" }, 161 | { "name": "North Korea", "capital": "Pyongyang" }, 162 | { "name": "Northern Mariana Islands", "capital": "Saipan" }, 163 | { "name": "Norway", "capital": "Oslo" }, 164 | { "name": "Oman", "capital": "Muscat" }, 165 | { "name": "Pakistan", "capital": "Islamabad" }, 166 | { "name": "Palau", "capital": "Melekeok" }, 167 | { "name": "Palestinian Territory", "capital": "East Jerusalem" }, 168 | { "name": "Panama", "capital": "Panama City" }, 169 | { "name": "Papua New Guinea", "capital": "Port Moresby" }, 170 | { "name": "Paraguay", "capital": "Asuncion" }, 171 | { "name": "Peru", "capital": "Lima" }, 172 | { "name": "Philippines", "capital": "Manila" }, 173 | { "name": "Pitcairn", "capital": "Adamstown" }, 174 | { "name": "Poland", "capital": "Warsaw" }, 175 | { "name": "Portugal", "capital": "Lisbon" }, 176 | { "name": "Puerto Rico", "capital": "San Juan" }, 177 | { "name": "Qatar", "capital": "Doha" }, 178 | { "name": "Republic of the Congo", "capital": "Brazzaville" }, 179 | { "name": "Reunion", "capital": "Saint-Denis" }, 180 | { "name": "Romania", "capital": "Bucharest" }, 181 | { "name": "Russia", "capital": "Moscow" }, 182 | { "name": "Rwanda", "capital": "Kigali" }, 183 | { "name": "Saint Barthelemy", "capital": "Gustavia" }, 184 | { "name": "Saint Helena", "capital": "Jamestown" }, 185 | { "name": "Saint Kitts and Nevis", "capital": "Basseterre" }, 186 | { "name": "Saint Lucia", "capital": "Castries" }, 187 | { "name": "Saint Martin", "capital": "Marigot" }, 188 | { "name": "Saint Pierre and Miquelon", "capital": "Saint-Pierre" }, 189 | { "name": "Saint Vincent and the Grenadines", "capital": "Kingstown" }, 190 | { "name": "Samoa", "capital": "Apia" }, 191 | { "name": "San Marino", "capital": "San Marino" }, 192 | { "name": "Sao Tome and Principe", "capital": "Sao Tome" }, 193 | { "name": "Saudi Arabia", "capital": "Riyadh" }, 194 | { "name": "Senegal", "capital": "Dakar" }, 195 | { "name": "Serbia", "capital": "Belgrade" }, 196 | { "name": "Seychelles", "capital": "Victoria" }, 197 | { "name": "Sierra Leone", "capital": "Freetown" }, 198 | { "name": "Singapore", "capital": "Singapur" }, 199 | { "name": "Sint Maarten", "capital": "Philipsburg" }, 200 | { "name": "Slovakia", "capital": "Bratislava" }, 201 | { "name": "Slovenia", "capital": "Ljubljana" }, 202 | { "name": "Solomon Islands", "capital": "Honiara" }, 203 | { "name": "Somalia", "capital": "Mogadishu" }, 204 | { "name": "South Africa", "capital": "Pretoria" }, 205 | { 206 | "name": "South Georgia and the South Sandwich Islands", 207 | "capital": "Grytviken" 208 | }, 209 | { "name": "South Korea", "capital": "Seoul" }, 210 | { "name": "South Sudan", "capital": "Juba" }, 211 | { "name": "Spain", "capital": "Madrid" }, 212 | { "name": "Sri Lanka", "capital": "Colombo" }, 213 | { "name": "Sudan", "capital": "Khartoum" }, 214 | { "name": "Suriname", "capital": "Paramaribo" }, 215 | { "name": "Svalbard and Jan Mayen", "capital": "Longyearbyen" }, 216 | { "name": "Swaziland", "capital": "Mbabane" }, 217 | { "name": "Sweden", "capital": "Stockholm" }, 218 | { "name": "Switzerland", "capital": "Berne" }, 219 | { "name": "Syria", "capital": "Damascus" }, 220 | { "name": "Taiwan", "capital": "Taipei" }, 221 | { "name": "Tajikistan", "capital": "Dushanbe" }, 222 | { "name": "Tanzania", "capital": "Dodoma" }, 223 | { "name": "Thailand", "capital": "Bangkok" }, 224 | { "name": "Togo", "capital": "Lome" }, 225 | { "name": "Tonga", "capital": "Nuku'alofa" }, 226 | { "name": "Trinidad and Tobago", "capital": "Port of Spain" }, 227 | { "name": "Tunisia", "capital": "Tunis" }, 228 | { "name": "Turkey", "capital": "Ankara" }, 229 | { "name": "Turkmenistan", "capital": "Ashgabat" }, 230 | { "name": "Turks and Caicos Islands", "capital": "Cockburn Town" }, 231 | { "name": "Tuvalu", "capital": "Funafuti" }, 232 | { "name": "U.S. Virgin Islands", "capital": "Charlotte Amalie" }, 233 | { "name": "Uganda", "capital": "Kampala" }, 234 | { "name": "Ukraine", "capital": "Kiev" }, 235 | { "name": "United Arab Emirates", "capital": "Abu Dhabi" }, 236 | { "name": "United Kingdom", "capital": "London" }, 237 | { "name": "United States", "capital": "Washington" }, 238 | { "name": "Uruguay", "capital": "Montevideo" }, 239 | { "name": "Uzbekistan", "capital": "Tashkent" }, 240 | { "name": "Vanuatu", "capital": "Port Vila" }, 241 | { "name": "Vatican", "capital": "Vatican City" }, 242 | { "name": "Venezuela", "capital": "Caracas" }, 243 | { "name": "Vietnam", "capital": "Hanoi" }, 244 | { "name": "Wallis and Futuna", "capital": "Mata Utu" }, 245 | { "name": "Western Sahara", "capital": "El-Aaiun" }, 246 | { "name": "Yemen", "capital": "Sanaa" }, 247 | { "name": "Zambia", "capital": "Lusaka" }, 248 | { "name": "Zimbabwe", "capital": "Harare" } 249 | ] 250 | -------------------------------------------------------------------------------- /challenge-dice-roller/README.md: -------------------------------------------------------------------------------- 1 | # Challenge: "Dice Roller (React)" 2 | 3 | ![Example Screenshot from the finished challenge](./example-screenshots/finished.png) 4 | 5 | ## Challenge Overview 6 | 7 | Make a React app which generates random dice roll results for you, based on the number and type of dice. 8 | 9 | For example, a request for "3d20" would "roll" three dice each with twenty faces, and return their total. 10 | 11 | This challenge is for fans of games such as Dungeons and Dragons, where these dice combinations are used frequently. It's probably not very interesting if you've never played those games, however, here's [a short video introducing the various kinds of dice](https://www.youtube.com/watch?v=qQq_WsPFiDs&t=1m59s) in case you are curious. 12 | 13 | ## Difficulty Level 14 | 15 | Suitable for those who have finished week 2 of the React module. 16 | 17 | ## Pre-requisites - what do I need to know to finish this challenge? 18 | 19 | To complete levels 1 to 4, you will need knowledge of: 20 | 21 | - React component creation 22 | - Parameterising components with `props` 23 | - Tracking state (e.g. with useState) 24 | - Event handlers: for buttons and input text fields 25 | 26 | ## Getting Started 27 | 28 | **Don't** clone this repo. 29 | 30 | Make your own React app using `create-react-app`. See [(this guide)](https://docs.codeyourfuture.io/students/guides/creating-a-react-app) if you have forgotten how. 31 | 32 | ## GitHub & Hosting: 33 | 34 | Add your project in github and host it on Netlify. 35 | 36 | The github repo name should be exactly: 37 | `dice-react` 38 | 39 | The netlify site suffix should be `-dice` 40 | 41 | so... 42 | 43 | `cyf-YOURGITHUBUSERNAME-dice` 44 | 45 | # Level 1 Challenge 46 | 47 | - Write a react app which simulates the results of dice rolls of two six-sided dice. 48 | 49 | - It should have a single component called `DieRoller` or similar. (A "die" is the english singular term for dice). 50 | 51 | - It should have a "roll" button to generate a new result. 52 | 53 | - The generated total of the two dice should be displayed each time. 54 | 55 | - Your project should be on GitHub and Netlify with correct names (see Hosting, above). 56 | 57 | Tip: 58 | 59 | Try to keep everything to do with the dice roll neatly inside of a component (Why? Eventually you will need to make and configure many instances of this component). 60 | 61 | ### Example Screenshot 62 | 63 | ![Level 1 Example Screenshot](./example-screenshots/level-1.png) 64 | 65 | # Level 2 challenge 66 | 67 | - Add a numeric input field to allow the user to control _how many_ dice are being rolled. 68 | 69 | - Update your calculation to account for the correct number of dice. 70 | 71 | ### Example Screenshot 72 | 73 | ![Level 2 Example Screenshot](./example-screenshots/level-2.png) 74 | 75 | # Level 3 challenge 76 | 77 | - Instead of always rolling a _six_-sided dice, have your component receive a prop, `numberOfFaces`, from its parent. 78 | 79 | - Update your calculation to use the value of this prop. Example: if `numberOfFaces` is 20, and your user has chosen to roll 5 dice, you will generate the roll for 5 dice which each have 20 sides. (In this case the number will be between 5 and 100.) 80 | 81 | - In the parent component, instantiate seven of your `DieRoller` components, each with a different number of faces, following this list: 82 | 83 | - 4, 6, 8, 10, 100, 12, 20 84 | 85 | - Make it look however you want. There is no dictated layout or styling for this challenge. 86 | 87 | ### Example Screenshot 88 | 89 | ![Level 3 Example Screenshot](./example-screenshots/level-3.png) 90 | 91 | This is just an example. 92 | 93 | You are encouraged to lay your app out creatively - it is a tool used in a game, after all! 94 | 95 | # Level 4 challenge 96 | 97 | - Add a single "log" textarea which will keep a history of your dice rolls. 98 | 99 | - Each time a DieRoller makes a roll it should add a line to the _top_ of the log. 100 | 101 | - This "log" textarea will be rendered by your parent component, **not** by any DieRoller. 102 | 103 | ### Example Screenshot 104 | 105 | ![Level 4 Example Screenshot](./example-screenshots/level-4.png) 106 | 107 | # Level 5 challenge 108 | 109 | - Add a "modifier" to each DieRoller. This is a numeric input the user can change, which gets added to the total dice roll. 110 | 111 | - Modifier can be positive or negative. 112 | 113 | - The total result of any roll should never be less than 1. If the total of a roll once added to its modifier would be less than 1, the result should be 1. 114 | 115 | ### Example Screenshot 116 | 117 | ![Level 5 Example Screenshot](./example-screenshots/level-5.png) 118 | 119 | # Level 6 challenge 120 | 121 | - If a DieRoller result has been adjusted to 1 from lower than 1, make the result look different so the user can see it has been adjusted. 122 | 123 | - To do this, use a CSS class, and also suitable explanation in a title/tooltip hover. 124 | 125 | ### Example Screenshot 126 | 127 | ![Level 6 Example Screenshot](./example-screenshots/level-6.png) 128 | 129 | # Level 7 challenge 130 | 131 | - Add error handling so that no change is made to the number of sides, or the modifier, if the user enters whitespace in that field. 132 | 133 | - If a field is blank, non-numeric, or otherwise unsuitable, it should revert to a previous value. 134 | 135 | - Ensure the user can enter all sensible values, _including_ setting the modifier _back_ to zero. 136 | 137 | # You are finished! 138 | 139 | Congratulations! 140 | 141 | Now... are your sure your code is as readable as possible? 142 | 143 | # Beyond - ideas for more work 144 | 145 | - Easy: display an image in each DieRoller, showing the type of dice in use. [Example](https://www.wizards.com/dnd/dice/dice.htm) 146 | 147 | - Intermediate: use a chart library to make a chart of the distribution of results of 1000 simulated rolls. 148 | 149 | - Advanced: Add a reset button in the parent. 150 | 151 | - Very advanced: Add some CSS (or 3d) animation of the dice. [3d example](http://a.teall.info/dice/). 152 | 153 | - Very advanced: Allow free-text expressions to be written, such as `1d20 + 2d4 + 2`. 154 | 155 | ## Further resources 156 | 157 | - [Dice notation](https://en.wikipedia.org/wiki/Dice_notation) - only for the curious. It won't help you in this challenge. 158 | - [Dice 101 - an intro video about dice in the DnD game](https://www.youtube.com/watch?v=qQq_WsPFiDs&t=1m59s) 159 | 160 | # Credits 161 | 162 | Background image in some screenshots is by [Alperen Yazgı on Unsplash](https://unsplash.com/photos/QuP5RL_E5oE). 163 | -------------------------------------------------------------------------------- /challenge-dice-roller/example-screenshots/finished.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-dice-roller/example-screenshots/finished.png -------------------------------------------------------------------------------- /challenge-dice-roller/example-screenshots/level-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-dice-roller/example-screenshots/level-1.png -------------------------------------------------------------------------------- /challenge-dice-roller/example-screenshots/level-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-dice-roller/example-screenshots/level-2.png -------------------------------------------------------------------------------- /challenge-dice-roller/example-screenshots/level-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-dice-roller/example-screenshots/level-3.png -------------------------------------------------------------------------------- /challenge-dice-roller/example-screenshots/level-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-dice-roller/example-screenshots/level-4.png -------------------------------------------------------------------------------- /challenge-dice-roller/example-screenshots/level-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-dice-roller/example-screenshots/level-5.png -------------------------------------------------------------------------------- /challenge-dice-roller/example-screenshots/level-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-dice-roller/example-screenshots/level-6.png -------------------------------------------------------------------------------- /challenge-high-score-tables/README.md: -------------------------------------------------------------------------------- 1 | # Challenge: "High Score Tables (React)" 2 | 3 | ## Challenge Overview 4 | 5 | Make a React app which lists some high score tables. The scores data is provided for you. 6 | 7 | ## Difficulty Level 8 | 9 | This is a beginner challenge. Level 1 can be completed by students who have completed week 1 of the CYF React module. 10 | 11 | ## Pre-reqs 12 | 13 | - react `props` 14 | - `array.map` method as used in React JSX 15 | 16 | To finish level 4 17 | 18 | - event handling (handle a button click) 19 | - Keeping state with the state hook (`useState`) 20 | 21 | ### Example Screenshot 22 | 23 | Level 1 challenge screenshot example. 24 | 25 | ![Example Screenshot](./example-screenshots/react-high-score-tables-example-layout.png) 26 | 27 | # Level 1 Challenge 28 | 29 | * Write a React app which displays high score tables for the given data. 30 | 31 | * Each country must have its own High Score table displayed. 32 | 33 | * Your app must be hosted on Netlify (see "Hosting" below). 34 | 35 | * You must make AT LEAST: 36 | - `HighScoreTable` - a table with a country name and a list of player-scores for that country. 37 | - `PlayerScore` - component responsible for displaying a single score by one player (e.g. as one line of the table) (e.g. `Neill 2000`) 38 | 39 | ### Getting Started 40 | 41 | **Don't** clone this repo. 42 | 43 | Make your own React app using `create-react-app`. See [(this guide)](https://docs.codeyourfuture.io/students/guides/creating-a-react-app) if you have forgotten how. 44 | 45 | Copy across the score file (or the score file's contents) from this repo to your app, and then import from that file. 46 | 47 | Write a plain HTML prototype first for two or three countries (e.g. on codepen). THEN, once you know the HTML you're attempting to create, work on the React version! This is not mandatory but it is recommended. 48 | 49 | ### The data: 50 | 51 | The data is available in the file [./scores.js](./scores.js). Here is [a raw version of it](https://raw.githubusercontent.com/codeyourfuture/cyf-react-challenges/master/challenge-high-score-tables/scores.js), suitable for saving. 52 | 53 | You can copy this array of data into your App.js or you can import it. 54 | 55 | ## Hosting: 56 | 57 | Add your project in github and host it on Netlify. 58 | 59 | The github repo name should be: 60 | `high-scores-react` 61 | 62 | The netlify site suffix should be `-scores` 63 | 64 | so... 65 | 66 | `cyf-YOURGITHUBUSERNAME-scores` 67 | 68 | # Level 2 69 | 70 | - Present the High Score Tables sorted alphabetically by country name 71 | 72 | # Level 3 73 | 74 | - Within each individual table, show the highest scores first - i.e. sort the scores numerically, descending. 75 | 76 | # Level 4 - advanced (needs content from React week 2) 77 | - Add a _single_ button at the top of the page which toggles the sort order of every high-score-table between ascending and descending by scores. This will require some study about event handlers and the use of a "State hook". 78 | 79 | # Level 5 - advanced 80 | 81 | - Add a "world-wide" table, shown first, which shows the sorted high scores from EVERYONE, regardless of country. 82 | 83 | # Bonus 84 | - Add your own country and scores! 85 | - Add some old-skool videogame icons or animations 86 | -------------------------------------------------------------------------------- /challenge-high-score-tables/example-screenshots/foo.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /challenge-high-score-tables/example-screenshots/react-high-score-tables-example-layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-high-score-tables/example-screenshots/react-high-score-tables-example-layout.png -------------------------------------------------------------------------------- /challenge-high-score-tables/scores.js: -------------------------------------------------------------------------------- 1 | let allCountryScores = [ 2 | { 3 | name: "Ethiopia", 4 | scores: [ {n: "Sub", s: 9990}, {n: "lucy", s: "4134234"}, {n: "DWH", s: 9999}, {n: "Hanif", s: 999999999} ] 5 | }, 6 | { 7 | name: "Scotland", 8 | scores: [ {n: "groundkeeper willie", s: 4000}, {n: "Neill", s: 999999}, {n: "braveheart", s: -200}] 9 | },{ 10 | name: "England", 11 | scores: [ {n: "Jonny", s: 202020}, {n: "Chris", s: 202021}] 12 | },{ 13 | name: "Brazil", 14 | scores: [ {n: "Mozart", s: 999}] 15 | }, 16 | { 17 | name: "Colombia", 18 | scores: [ {n: "Maria", s: 6000}, {n: "Melanie", s: "99999999"}, {n: "Ali", s: 5000}] 19 | }, 20 | { 21 | name: "Turkey", 22 | scores: [ {n: "selim", s: 900 }, {n: "mahmut", s: 1000 }, {n: "morat", s: 999 } ] 23 | }, 24 | { 25 | name: "Iran", 26 | scores: [ {n: "arosha", s: 5550 }, {n: "zahra", s: 3000 }, {n: "nader", s: 2000 }, {n: "Bani", s: 1999 } ] 27 | }, 28 | { 29 | name: "Bangladesh", 30 | scores: [ {n: "rahman", s: 700200}, {n: "rayhan", s: 18238123}, {n: "ali", s: 5400000} ] 31 | }, 32 | ]; 33 | 34 | export default allCountryScores; 35 | -------------------------------------------------------------------------------- /challenge-image-carousel/README.md: -------------------------------------------------------------------------------- 1 | # Challenge: "Image Carousel" (React) 2 | 3 | ## Challenge Overview 4 | 5 | Make a React app which allows the user to navigate a set of images (first manually, then with an auto-playing slideshow). 6 | 7 | ### Try a live demo: 8 | 9 | [Try this live demo!](https://cyf-image-carousel.netlify.com/) 10 | 11 | ### Example Screenshot 12 | 13 | Level 1 challenge screenshot example. 14 | 15 | ![Example Screenshot](./example-screenshots/example-level1.png) 16 | 17 | ## Difficulty Level 18 | 19 | * Level 1 is an intermediate challenge. 20 | * Level 2's auto-play functionality is advanced if you have learned React hooks. 21 | 22 | # Level 1 Challenge 23 | 24 | Make forward and back buttons to move _manually_ in that direction through a list of at least 4 images. 25 | 26 | (e.g. When the user presses forward once, the display should move ONCE to the next image.) 27 | 28 | You can use any images. 29 | 30 | You can store the images within your app or you can use links to images hosted elsewhere ("hotlinking"). 31 | 32 | [Unsplash](https://unsplash.com/) is a good source of images for this challenge. 33 | 34 | # Level 2 Challenge 35 | 36 | Make auto-forward and auto-back buttons to _automatically_ move in that direction through the list of images. 37 | 38 | Here's a screenshot example from a completed level 2 challenge. 39 | 40 | Warning: This quite hard to do using React Hooks. See [here](https://overreacted.io/making-setinterval-declarative-with-react-hooks/) for an explantion! 41 | 42 | ![Example Screenshot](./example-screenshots/example-level2.png) 43 | 44 | # Try to finish the rest by yourself 45 | 46 | If you want a harder challenge, don't read the rest of this document but instead try to build the app by yourself. 47 | 48 | If you want hints, then you will find some below. 49 | 50 | # Suggested approach 51 | 52 | Here's one approach you might take to building this app. 53 | 54 | ## Task: Create a new React app 55 | 56 | Create a new empty React app for this challenge. 57 | 58 | The tool can take a while to run, so continue with the next task while it's running... 59 | 60 | ## Task: Design your layout _on paper_ 61 | 62 | Design your layout on paper. Keep it very simple - this is a React challenge, not a CSS challenge. 63 | 64 | Use a layout that will be ok on a phone (but _don't_ spend time on responsive design). 65 | 66 | Keep this drawing around for reference later. 67 | 68 | ## Task: Convert your layout to HTML 69 | 70 | Convert the drawing to HTML (on codepen or elsewhere) and check the buttons appear correctly. 71 | 72 | _DON'T_ add any CSS or extra markup to make it look good just now. That will only make it more difficult for you to think about your app during development. 73 | 74 | ## Task: Convert your HTML to JSX within your React app 75 | 76 | Now make components which will generate the planned HTML from the previous task. 77 | 78 | ## Task: Make the buttons work 79 | 80 | Make your buttons work to navigate forwards and backwards, manually. 81 | 82 | ## Task: Host your app 83 | 84 | Host your app and prove it works by viewing it on your phone! 85 | 86 | We recommend you use Netlify. [Instructions are here](https://gist.github.com/nbogie/bf58a391fab6884f77a6adec66047181). 87 | 88 | (You can instead use Heroku to host, or github pages, or codesandbox.io, or glitch.com...) 89 | 90 | ## Task: more buttons - automated slideshow 91 | 92 | Add the following buttons: 93 | 94 | - auto-forward 95 | - stop 96 | - auto-backwards 97 | 98 | These should allow automatic navigation through the images, say every 5 seconds. 99 | 100 | ## Task: host again. 101 | 102 | Host again. 103 | 104 | ## Create a repo on github for your code 105 | * Create a new repo on github 106 | * Add this github repo as a remote for your existing local image-carousel repo. 107 | 108 | *STOP!* You CANNOT simply copy-paste and run this command! You'll have to change the user and repo in the following to match your own. 109 | 110 | ```git remote add origin https://github.com/user/repo.git``` 111 | 112 | ```git push -u origin master``` 113 | 114 | ## End of basic challenge! 115 | 116 | Congratulations, you've finished the basics! 117 | 118 | - Send the URL of your hosted app to your team on Slack. 119 | - Make sure you can access it and play with it on a smartphone! 120 | - Celebrate! 121 | 122 | ## Optional: Add UI for delay time 123 | 124 | Add UI so that the user can specify how long to wait between images. 125 | 126 | ## Advanced Challenge: make it look good 127 | 128 | - Now is a good time to make it look good with CSS, colour, typography, images, and creativity. Maybe you could ask someone to collaborate with you on those aspects. 129 | 130 | ## Further resources 131 | -------------------------------------------------------------------------------- /challenge-image-carousel/example-screenshots/example-level1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-image-carousel/example-screenshots/example-level1.png -------------------------------------------------------------------------------- /challenge-image-carousel/example-screenshots/example-level2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-image-carousel/example-screenshots/example-level2.png -------------------------------------------------------------------------------- /challenge-job-listing/README.md: -------------------------------------------------------------------------------- 1 | # Job Listing with Filtering 2 | 3 | Complete the Frontend Mentor challenge "Job Listings with Filtering", with the rule changes below: 4 | 5 | https://www.frontendmentor.io/challenges/job-listings-with-filtering-ivstIPCt 6 | 7 | You will have to refer to the "brief" on that web page AND download the "starter" zip file and explore its contents. 8 | 9 | ## Rule changes and additions 10 | 11 | - Use React! 12 | - Ignore "Option 1" from the challenge document. 13 | - Load the jobs data file as mentioned in "Option 2". 14 | - DO NOT implement any filtering functionality at this point. 15 | - Build only the desktop version - do not worry about responsive design at this point 16 | - Name your GitHub repo exactly: `job-listings-react` 17 | - Host on Netlify as usual 18 | - Your Netlify site name must be in this format: cyf-USERNAME-jobs(.netlify.app) 19 | - You may work in teams of maximum 2 people if you wish. 20 | - This is also a CSS practice exercise, not only React. Your result should be laid out correctly. 21 | 22 | ## More Notes 23 | 24 | - You do NOT need to buy anything to do this challenge. (The frontendmentor website also offers a "sketch file" for sale - you can ignore this.) 25 | - You will need to log in to frontendmentor.io with github and download the "starter" file. 26 | - There is no starting project repo provided by CYF for this challenge - you will make your own. 27 | 28 | ## Optional Extra 29 | 30 | ### Give feedback on the challenge 31 | 32 | The author of the challenge (and the "countries" one) is interested in your feedback. 33 | 34 | If you want to, take notes on anything in the challenge statement that you find unclear, and anything that you particularly enjoy in the challenge. 35 | 36 | This feedback will help them improve this and other challenges for other students. 37 | 38 | ## Submission: 39 | 40 | Please add links here to your deployed site and your repo, and submit, when you have finished this task. 41 | -------------------------------------------------------------------------------- /challenge-music-keyboard/README.md: -------------------------------------------------------------------------------- 1 | # Challenge: "Musical Keyboard" with React and Tone.js 2 | 3 | ## Challenge Overview 4 | 5 | You must make a React app which presents a very simple musical keyboard made of buttons. When a button is pressed, the correct musical note sounds. 6 | 7 | ### Try a live demo: 8 | 9 | [Try this live demo!](https://cyf-tones-react.netlify.com/) 10 | 11 | ### Example Screenshot 12 | 13 | ![Example Screenshot](./example-screenshots/example2.png) 14 | 15 | ## What you need to know before starting: 16 | 17 | This challenge is suitable if you have successfully completed the homework of CYF React Week 1. 18 | 19 | You _will_ need to know... 20 | 21 | - how to create a React app 22 | - how to create a component in React 23 | - how to pass props 24 | - how to populate components from an array 25 | - how to handle events (button clicks) 26 | 27 | In addition, you'll learn... 28 | 29 | - How to install a library (in this case, tone.js) 30 | - How to make synthesised sound with the tone.js library. This is one of many ways to make sound in a web app. 31 | 32 | # Task: Install the "tone.js" library 33 | 34 | - If you haven't created your app yet, use `create-react-app` to create the skeleton of the app. 35 | - Check the app works, by running `npm start` from your app's root directory. 36 | - **Use the following command to install the tones library: 37 | `npm install tone`** 38 | - Check the app STILL works, with `npm start` 39 | 40 | ### Optional - Advanced: 41 | 42 | - Look in `package.json`, and compare it with `package.json` for another React app you have. What do you notice? 43 | 44 | # Look at the first tone.js example 45 | 46 | - Look at the first example from the [tone.js documentation](https://tonejs.github.io/). 47 | - Load and experiment with [this JSFiddle of that example](https://jsfiddle.net/enz0/f0b2u7ct/) 48 | - Try to understand the two lines of js code in the example. 49 | 50 | # Try to finish the rest by yourself 51 | 52 | If you want a harder challenge, don't read the rest of this document but instead try to build the app by yourself. 53 | 54 | If you want hints, then you will find some below. 55 | 56 | # More help: A suggested approach 57 | 58 | Here's one approach you might take to building this app. 59 | 60 | ## Task: Create a new React app 61 | 62 | Create a new empty React app for this challenge. 63 | 64 | The tool can take a while to run, so continue with the next task while it's running... 65 | 66 | ## Task: Design your layout _on paper_ 67 | 68 | Design your layout on paper. Keep it very simple - this is a React challenge, not a CSS challenge. 69 | 70 | If you know the layout of a piano keyboard, I suggest you ignore the black notes for now, to keep things simpler. 71 | 72 | Use a layout that will be ok on a phone (but _don't_ spend time on responsive design). 73 | 74 | Keep this drawing around for reference later. You can take a photo of it and keep it in your repo, for example. 75 | 76 | ## Task: Convert your layout to HTML (e.g. on CodePen) 77 | 78 | Convert the drawing to HTML (on codepen or elsewhere) and check the buttons appear correctly. 79 | _DON'T_ add any CSS or extra markup to make it look good just now. That will only make it more difficult for you to think about your app during development. 80 | 81 | At this stage, buttons will not work - that's OK. 82 | 83 | At this stage you will have lots of repeated HTML - the same for each button. 84 | 85 | ## Task: Convert your HTML to JSX within your React app 86 | 87 | Now make a React component to represent your musical keyboard. 88 | 89 | It should generate the HTML for your buttons. 90 | 91 | You can do this all first within your `App.js`, or you can build some other components: 92 | * perhaps a component for a Keyboard 93 | * perhaps a component for a single Key, which you then use many times. 94 | 95 | ## Task: Get the buttons working very simply 96 | 97 | - Write code which calls `console.log` when the "musical keyboard" buttons are clicked. 98 | 99 | ## Task: Get the audio working 100 | 101 | - Add code which uses tone.js to make sounds when buttons are pressed. Keep it _very_ simple. 102 | 103 | If you need a hint, [use the first example in the docs, here.](https://tonejs.github.io/) 104 | 105 | ## Task: Host your app 106 | 107 | Host your app and prove it works by viewing it on your phone! 108 | 109 | We recommend you use Netlify: 110 | 111 | Site name: `cyf-GITHUBUSERNAME-tones` 112 | Repo name: `tones-react` 113 | 114 | ## End of basic challenge! 115 | 116 | Congratulations, you've finished the basics! 117 | 118 | - Send the URL of your hosted app to your team on Slack. 119 | - Make sure you can access it and play with it on a smartphone! 120 | - Celebrate! 121 | 122 | ## Advanced Challenge: make it change scale. 123 | 124 | If you know a little about music scales (or don't mind reading), you might want to make your keyboard play only notes from a certain scale. 125 | 126 | Here's the names of the notes in a C pentatonic scale, for example: `C4 D4 E4 G4 A4 C5 D5 E5 G5 A5 C6` 127 | 128 | - Change your app to use minor scale, a blues or bebop scale, or another scale. 129 | 130 | ## Advanced Challenge: support multiple scales 131 | 132 | - Add to the interface so that the user can choose what scale they want. 133 | 134 | ## Advanced Challenge: add controls to change the sound 135 | 136 | - Add to the interface so that the user can modify the sound synthesis parameters. 137 | 138 | ## Advanced Challenge: make it look good 139 | 140 | - Now is a good time to make it look good with CSS, colour, typography, images, and creativity. Or maybe you could ask someone to collaborate with you and do those aspects. 141 | 142 | ## Further resources 143 | 144 | - https://musiclab.chromeexperiments.com/Oscillators/ 145 | -------------------------------------------------------------------------------- /challenge-music-keyboard/example-screenshots/example1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-music-keyboard/example-screenshots/example1.png -------------------------------------------------------------------------------- /challenge-music-keyboard/example-screenshots/example2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-music-keyboard/example-screenshots/example2.png -------------------------------------------------------------------------------- /challenge-quiz/README.md: -------------------------------------------------------------------------------- 1 | # Challenge: Trivia Quiz 2 | 3 | ![example](https://i.ibb.co/Byyss7c/Screenshot-2020-07-02-at-20-00-51.png) 4 | 5 | ## Introduction 6 | 7 | Welcome to the React Quiz challenge! This is what we need to build: 8 | 9 | ### [>>> Click here for Game Demo <<<](https://csb-qmydz-9dm8xvx98.vercel.app/) 10 | 11 | You will require a strong understanding of React+Hooks to complete this challenge. 12 | 13 | ## The rules 14 | 15 | Every player has 3 lives: The logic and rules are simple. When the player loads the app: 16 | 17 | 1. We fetch a question and display it. 18 | 2. The player guesses the answer. 19 | 3. If the player is right, they get a point 🥇. If wrong, they lose a life 🖤. 20 | 4. We fetch a new question and repeat. 21 | 22 | When the player makes a wrong guess and has no remaining lives, it's game over and the player will be shown their final score. (My best score is 9). 23 | 24 | ## Challenge 25 | 26 | 1. Easy part: Recreate the game demo above. 27 | 28 | If you are looking to work out how to approach the problem, do this without checking the "Steps" section below. If you're more trying to practice React implementation than design, feel free to read the Steps section for guidance. 29 | 30 | 2. Hard part: The goal here is not to add features, the goal is to write the code for the game above in the **cleanest way possible**. That means: 31 | 32 | - [ ] No errors or warnings in the console 33 | - [ ] Variable/function/component names must make sense and be properly spelled 34 | - [ ] No unused or commented-out code 35 | - [ ] A code structure that you understand and can clearly explain. 36 | 37 | Once the demo is working you are only **half finished**, you must go back and refactor the code to remove anything unnecessary and fix anything confusing. 38 | 39 | Completing the challenge is not enough, this should be the cleanest code you have ever written. 40 | 41 | ## Things that will help 42 | 43 | ### The API 44 | 45 | ```js 46 | const api = `https://opentdb.com/api.php?amount=1&difficulty=easy&encode=url3986`; 47 | ``` 48 | 49 | Fetch data from here 👆👆👆. This is the Open Trivia Database, they have thousands of questions. The documentation for this api is [here](https://opentdb.com/api_config.php). Fetching from the url above will return one single question (inside an array). 50 | 51 | ### Encoding 52 | 53 | When you fetch from the api, you will notice that all strings returned all look like this: 54 | 55 | ``` 56 | ## A%20slug%E2%80%99s%20blood%20is%20green. 57 | ``` 58 | 59 | What's going on here? This is a _[url encoded string](https://en.wikipedia.org/wiki/Percent-encoding)_. We don't want to display our strings like that to our players. Javascript has a way to convert a string like this to a normal string, using the function below. You might find this useful. 60 | 61 | ```js 62 | const decoded = decodeURIComponent("A%20slug%E2%80%99s%20blood%20is%20green"); 63 | console.log(decoded); 64 | // A slug's blood is green 65 | ``` 66 | 67 | ### Shuffle 68 | 69 | You may need to shuffle an array at some point (the game must show the possible answers in a random order). There are many ways to do a random shuffle, here is one: 70 | 71 | ```js 72 | const unshuffled = [1, 2, 3]; 73 | const shuffled = unshuffled.sort(() => Math.random() - 0.5); 74 | console.log(shuffled); 75 | // [2, 1, 3] 76 | ``` 77 | 78 | ### React Guidelines 79 | 80 | You do not necessarily need to use useEffect to complete this challenge but it may be cleaner to do so. 81 | 82 | You do not need to use multiple components to complete this challenge but it may be cleaner to do so. 83 | 84 | ### Styling & CSS 85 | 86 | This challenge is all about clean code so there are no extra points for styling. (If you decide to include syling anyway, your CSS must be every bit as beautiful and clean as your javascript code!). 87 | 88 | ## Advanced challenge 89 | 90 | When this was sent to the top-secret Code Your Future QA team for testing they noticed a serious bug. I will include their report below. 91 | 92 | ``` 93 | From: Quality Assurance Team 94 | Subject: Quiz demo bug CRITICAL!! 95 | 96 | We have noticed that if a player clicks a correct answer 97 | two times VERY QUICKLY they can get an extra point. 98 | 99 | We have noticed some players using this to cheat, this 100 | bug must be fixed urgently!! CHEATING IS NOT ACCEPTABLE! 101 | ``` 102 | 103 | If you can fix the bug they will very pleased. Good luck. 104 | 105 | ## Steps 106 | 107 | Ignore this section if you'd like to work out the steps yourself, these are just a suggestion to help out if you need. 108 | 109 | 1. Get a single question working, without fetch. We've provided one example question in the question.json file, which you can import. It has the same structure as the API returns. Your app should tell the user "You got the answer right" or "You got the answer wrong". 110 | 2. Implement the "lives" logic. If they get the question wrong, they lose a life. Show them how many lives they have left. Instead of telling the user right/wrong, tell them "You got the answer right" or "You got the answer wrong, you have (number) lives remaining: try again", or "You ran out of lives". 111 | 3. Switch your implementation to fetch questions using the API, rather than from the JSON file. 112 | 4. Implement the "score" logic. Count how many questions they got right, and show them, both as they play, and when they die. 113 | 5. Make sure your code is perfect! 114 | -------------------------------------------------------------------------------- /challenge-quiz/question.json: -------------------------------------------------------------------------------- 1 | {"response_code":0,"results":[{"category":"Art","type":"multiple","difficulty":"easy","question":"Who%20painted%20%22Swans%20Reflecting%20Elephants%22%2C%20%22Sleep%22%2C%20and%20%22The%20Persistence%20of%20Memory%22%3F","correct_answer":"Salvador%20Dali","incorrect_answers":["Jackson%20Pollock","Vincent%20van%20Gogh","Edgar%20Degas"]}]} -------------------------------------------------------------------------------- /challenge-sengen/README.md: -------------------------------------------------------------------------------- 1 | # Challenge: "Sentence Generator" (React) 2 | 3 | ## Challenge Overview 4 | 5 | Make a React app which presents a different randomly generated sentence each time it is loaded. 6 | 7 | ### Try a live demo: 8 | 9 | [Try this live demo!](https://cyf-sengen-simple.netlify.com/) 10 | 11 | Make sure you understand what's happening at a conceptual level. Each word-slot in the sentence template is picking a word randomly from an appropriate list. E.g. from a list of nouns. 12 | 13 | ### Example Screenshot 14 | 15 | ![Example Screenshot](./example-screenshots/example1.png) 16 | 17 | I have added a "regenerate" button, but alternatively, the user can simply reload the page for that. 18 | 19 | ## What you need to know before starting: 20 | 21 | This challenge is suitable if you have successfully completed the homework of CYF React Week 1. 22 | 23 | You _will_ need to know... 24 | 25 | - how to create a React app 26 | - how to create a component in React 27 | - how to pass props 28 | 29 | It will be helpful to know: 30 | 31 | - how to populate components from an array 32 | 33 | You DO NOT need to know about: 34 | 35 | - state 36 | - fetching JSON from an API 37 | - promises 38 | 39 | # Task: ... 40 | 41 | # Try to finish the rest by yourself 42 | 43 | If you want a harder challenge, don't read the rest of this document but instead try to build the app by yourself. 44 | 45 | If you want hints, then you will find some below. 46 | 47 | # Suggested approach 48 | 49 | Here's one approach you might take to building this app. 50 | 51 | ## Task: Create a new React app 52 | 53 | Create a new empty React app for this challenge. 54 | 55 | The tool can take a while to run, so continue with the next task while it's running... 56 | 57 | ## Task: Design your layout _on paper_ 58 | 59 | Design your layout on paper. Keep it very simple - this is a React challenge, not a CSS challenge. 60 | 61 | Use a layout that will be ok on a phone (but _don't_ spend time on responsive design). 62 | 63 | Keep this drawing around for reference later. 64 | 65 | ## Task: Convert your layout to JSX (HTML) 66 | 67 | Convert the drawing to HTML (on codepen or elsewhere) and check the buttons appear correctly. 68 | _DON'T_ add any CSS or extra markup to make it look good just now. That will only make it more difficult for you to think about your app during development. 69 | 70 | ## Task: Convert your HTML to JSX within your React app 71 | 72 | Now make a component to represent your sentence. It should generate the HTML. You can do this all first within your `App.js`, or you can build a React Component. 73 | 74 | ## Task: Have words picked at random from lists 75 | 76 | Try to write the javascript yourself to pick one word from a list of words, at random. 77 | 78 | If you have a lot of trouble, [here is a function you can use](https://gist.github.com/nbogie/05332f6c8834f6b57a08d8ea1edd911b) 79 | 80 | ## Task: Host your app 81 | 82 | Host your app and prove it works by viewing it on your phone! 83 | 84 | We recommend you use Netlify. [Instructions are here](https://gist.github.com/nbogie/bf58a391fab6884f77a6adec66047181). 85 | 86 | (You can instead use Heroku to host, or github pages, or codesandbox.io, or glitch.com...) 87 | 88 | ## End of basic challenge! 89 | 90 | Congratulations, you've finished the basics! 91 | 92 | - Send the URL of your hosted app to your team on Slack. 93 | - Make sure you can access it and play with it on a smartphone! 94 | - Celebrate! 95 | 96 | ## Advanced Challenge: make it look good 97 | 98 | - Now is a good time to make it look good with CSS, colour, typography, images, and creativity. Maybe you could ask someone to collaborate with you on those aspects. 99 | 100 | ## Advanced Challenges 101 | 102 | * Allow any word to be clicked, to change *only* that word. 103 | * Allow "like" and saving of favourite sentences 104 | * Add different template sentences 105 | 106 | ## Further resources 107 | -------------------------------------------------------------------------------- /challenge-sengen/example-screenshots/example1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-sengen/example-screenshots/example1.png -------------------------------------------------------------------------------- /challenge-tfl-lines/README.md: -------------------------------------------------------------------------------- 1 | # Challenge: "Transport for London (TfL) Line Information" 2 | 3 | ![TfL Line Information app](example-screenshots/level-300-screenshot.png) 4 | 5 | ## Challenge overview 6 | 7 | Make a React app that shows Transport for London (TfL) data from their API about tubes, buses, trains, etc. 8 | 9 | ## Difficulty level 10 | 11 | This is a more advanced challenge. Level 100 can be completed by any student has done Week 2 of the CYF React module. Level 200 can be completed by anyone who has done Week 3 of the CYF React module. 12 | 13 | ## Pre-requisites - what do I need to know to finish this challenge? 14 | 15 | Level 100: 16 | 17 | - `useState` Hook 18 | - `useEffect` Hook to fetch data on load (with empty dependencies array) 19 | - The `array.map` method and its use in React JSX 20 | 21 | Later levels: 22 | 23 | - `useEffect` dependencies array (the second argument) 24 | 25 | ## Getting started 26 | 27 | **Don't** clone this repo. 28 | 29 | Make your own React app using `create-react-app`. See [this guide](https://docs.codeyourfuture.io/students/guides/creating-a-react-app) if you have forgotten how. 30 | 31 | Write a plain HTML prototype (e.g. on CodePen). THEN, once you know the HTML you're attempting to create, work on the React version! This is not mandatory but it is recommended. 32 | 33 | ### Fetching data 34 | 35 | Data for this project will need to be fetched from the TfL API. [Here is a link to their documentation](https://api.tfl.gov.uk/swagger/ui/index.html). 36 | 37 | There will be more detail in the challenge levels below. 38 | 39 | ## GitHub & Hosting: 40 | 41 | Add your project to GitHub and host it on Netlify. 42 | 43 | The GitHub repo name should be exactly: `tfl-lines-react`. 44 | 45 | The Netlify site suffix should be `-tfl-lines`, so something like... 46 | 47 | ``` 48 | cyf-YOUR_GITHUB_USERNAME-tfl-lines 49 | ``` 50 | 51 | ## Level 100 challenge 52 | 53 | Write a React app that shows a selector for the different modes of transport available from TfL (for example bus, tube, rail). 54 | 55 | - The app should fetch data from `https://api.tfl.gov.uk/Line/Meta/Modes` **when the page loads**. The documentation for this API is available [here](https://api.tfl.gov.uk/swagger/ui/index.html?url=/swagger/docs/v1#!/Line/Line_MetaModes) 56 | 57 | - Using this data, the app should show a `` is selected, it should show that `modeName` on screen 60 | 61 | - Your project should be on GitHub and Netlify with correct names (see GitHub & Hosting section above) 62 | 63 | ### Example screenshots 64 | 65 | Mode selector: 66 | 67 | ![Level 100 mode selector](example-screenshots/level-100-screenshot-1.png) 68 | 69 | Selected mode: 70 | 71 | ![Level 100 selected mode shown](example-screenshots/level-100-screenshot-2.png) 72 | 73 | [CLICK HERE TO SEE A VIDEO](example-screenshots/level-100-video.gif) 74 | 75 | ## Level 200 challenge 76 | 77 | Show another selector for the different lines available for the selected mode of transport. So for example, if tube is selected, the second selector shows all of the tube lines. 78 | 79 | - The app should fetch data from `https://api.tfl.gov.uk/Line/Mode/${SELECTED_MODE_OF_TRANSPORT}` **when a mode of transport is selected**. The documentation for this API is available [here](https://api.tfl.gov.uk/swagger/ui/index.html?url=/swagger/docs/v1#!/Line/Line_GetByMode) 80 | 81 | - Using this data, the app should show second `` is selected, it should show that `id` on screen 84 | 85 | ### Example screenshots 86 | 87 | Line selector: 88 | 89 | ![Level 200 line selector](example-screenshots/level-200-screenshot-1.png) 90 | 91 | Selected line: 92 | 93 | ![Level 200 selected line shown](example-screenshots/level-200-screenshot-2.png) 94 | 95 | [CLICK HERE TO SEE A VIDEO](example-screenshots/level-200-video.gif) 96 | 97 | ## Level 300 challenge 98 | 99 | Show the start and end locations for the selected line. So for example, if the Victoria line is selected, display Walthamstow Central Underground Station and Brixton Underground Station. 100 | 101 | - The app should fetch data from `https://api.tfl.gov.uk/Line/${SELECTED_LINE}/Route` **when a line is selected**. The documentation for this API is available [here](https://api.tfl.gov.uk/swagger/ui/index.html?url=/swagger/docs/v1#!/Line/Line_LineRoutesByIds). 102 | 103 | - Using this data, the app show the `originationName` (start of the line) and `destinationName` (end of the line) from the **first** item in the `routeSections` array. 104 | 105 | ### Example screenshots 106 | 107 | ![Level 300](example-screenshots/level-300-screenshot.png) 108 | 109 | [CLICK HERE TO SEE A VIDEO](example-screenshots/level-300-video.gif) 110 | 111 | ## Level 999 challenge 112 | 113 | This challenge is **OPTIONAL**! 114 | 115 | Here are some additional ideas for improving your app: 116 | 117 | - If a mode of transport is **changed** reset the line selector and the line start/end so that they do not show out-of-date information (see video below) 118 | 119 | - Improve the styling. Try to make it match the screenshots as closely as possible. Or, even better, try to improve the design with your own ideas 120 | 121 | - Install the [aXe Browser Extension](https://www.deque.com/axe/axe-for-web/) in your browser. 122 | - This extension allows you to test for [*accessibility* problems](https://developer.mozilla.org/en-US/docs/Learn/Accessibility/What_is_accessibility) in your application. It adds a new tab inside your Dev Tools called axe. Navigate to this tab, then click Analyze 123 | - Try to solve any accessibility problems it tells you about. It may be useful to enable the Highlight mode so that you can see more easily which element are causing the problem. The Learn more link is also a useful resource 124 | 125 | ### Example screenshots 126 | 127 | Resetting the line selector and line start/end: 128 | 129 | [CLICK HERE TO SEE A VIDEO](example-screenshots/level-999-video.gif) 130 | 131 | Running the aXe extension: 132 | 133 | ![aXe extension analyze button](example-screenshots/level-999-screenshot-1.png) 134 | 135 | aXe extension results: 136 | 137 | ![aXe extention results](example-screenshots/level-999-screenshot-2.png) 138 | 139 | ## Credits 140 | 141 | Inspired by Ahmad Ali's original TfL exercise. 142 | -------------------------------------------------------------------------------- /challenge-tfl-lines/example-screenshots/level-100-screenshot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-tfl-lines/example-screenshots/level-100-screenshot-1.png -------------------------------------------------------------------------------- /challenge-tfl-lines/example-screenshots/level-100-screenshot-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-tfl-lines/example-screenshots/level-100-screenshot-2.png -------------------------------------------------------------------------------- /challenge-tfl-lines/example-screenshots/level-100-video.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-tfl-lines/example-screenshots/level-100-video.gif -------------------------------------------------------------------------------- /challenge-tfl-lines/example-screenshots/level-200-screenshot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-tfl-lines/example-screenshots/level-200-screenshot-1.png -------------------------------------------------------------------------------- /challenge-tfl-lines/example-screenshots/level-200-screenshot-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-tfl-lines/example-screenshots/level-200-screenshot-2.png -------------------------------------------------------------------------------- /challenge-tfl-lines/example-screenshots/level-200-video.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-tfl-lines/example-screenshots/level-200-video.gif -------------------------------------------------------------------------------- /challenge-tfl-lines/example-screenshots/level-300-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-tfl-lines/example-screenshots/level-300-screenshot.png -------------------------------------------------------------------------------- /challenge-tfl-lines/example-screenshots/level-300-video.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-tfl-lines/example-screenshots/level-300-video.gif -------------------------------------------------------------------------------- /challenge-tfl-lines/example-screenshots/level-999-screenshot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-tfl-lines/example-screenshots/level-999-screenshot-1.png -------------------------------------------------------------------------------- /challenge-tfl-lines/example-screenshots/level-999-screenshot-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-tfl-lines/example-screenshots/level-999-screenshot-2.png -------------------------------------------------------------------------------- /challenge-tfl-lines/example-screenshots/level-999-video.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-tfl-lines/example-screenshots/level-999-video.gif -------------------------------------------------------------------------------- /challenge-tv-show-info/README.md: -------------------------------------------------------------------------------- 1 | # Challenge: TV Show Episode List 2 | 3 | Note: This is a challenge, **not** a tutorial. It is a chance to put into practice what you've studied. 4 | 5 | ## Challenge Overview 6 | 7 | You must make a React app which shows all of the episode summaries of a tv show such as "Game Of Thrones", in one long list. 8 | 9 | (If you are interested in doing this challenge in vanilla JS see end of this document.) 10 | 11 | ### Example Screenshot 12 | 13 | ![Example Screenshot](./example-level-1.png) 14 | 15 | ## What you need to know before starting: 16 | 17 | This challenge is suitable if you have successfully completed the homework of CYF React Week 1. 18 | 19 | You _will_ need to know... 20 | 21 | - how to create a react app 22 | - how to load a static json file 23 | - how to create a component in react 24 | - how to pass props 25 | - how to populate components from an array 26 | 27 | You DON'T need to know about: 28 | 29 | - state 30 | - fetching JSON from an API 31 | 32 | ## Task: Download and save a JSON file 33 | 34 | Your app should read the information _locally_ from a static JSON file. Download one of the following JSON files and save it. 35 | 36 | - [Breaking Bad](http://api.tvmaze.com/shows/169/episodes) 37 | - [Game of Thrones](http://api.tvmaze.com/shows/82/episodes) 38 | - [Lost](http://api.tvmaze.com/shows/123/episodes) 39 | - [Sherlock](http://api.tvmaze.com/shows/335/episodes) 40 | - [Star Trek TNG](http://api.tvmaze.com/shows/491/episodes) 41 | - [The Daily Show](http://api.tvmaze.com/shows/3928/episodes) 42 | - [The Simpsons](http://api.tvmaze.com/shows/83/episodes) 43 | - [The Sopranos](http://api.tvmaze.com/shows/527/episodes) 44 | - [The Walking Dead](http://api.tvmaze.com/shows/73/episodes) 45 | - [The Wire](http://www.tvmaze.com/shows/179/the-wire) 46 | - [The X-Files](http://api.tvmaze.com/shows/430/episodes) 47 | - [True Blood](http://api.tvmaze.com/shows/22/episodes) 48 | 49 | Save it in your app in a new directory `src/data/`. E.g. `src/data/sherlock.json` 50 | 51 | # Try to figure the rest out by yourself 52 | 53 | If you want a harder challenge, don't read the rest of this document but try to build the app by yourself. 54 | 55 | # Suggested approach 56 | 57 | Here's one approach you might take to building this app. 58 | 59 | ## Task: Investigate the JSON 60 | 61 | Look at the JSON. 62 | Ask yourself the following questions and more - these will help you when you come to use the JSON in your app: 63 | 64 | - Does it contain an array or an object, at the top level? 65 | 66 | - If you think it contains an object at top level, what are the properties of the object? 67 | - If you think it contains an array at top level, how many elements are there in that array? 68 | 69 | - What properties will you need from each episode? 70 | - What are their names? 71 | - Are they nested within other properties? 72 | 73 | ## Task: Create a new React app 74 | 75 | Create a new empty React app for this challenge. 76 | 77 | The tool can take a while to run, so continue with the next task while it's running... 78 | 79 | ## Task: Design your layout _on paper_ 80 | 81 | Design your layout on paper. Keep it very simple - this is a React challenge, not a CSS challenge. 82 | 83 | Use a layout that will be ok on a phone (but don't do responsive design). 84 | 85 | Keep this drawing around for reference later. 86 | 87 | ## Task: Convert your layout to HTML (really, JSX) 88 | 89 | Make a prototype which just shows detail from one or two example episodes. _Don't_ worry about the JSON yet. 90 | 91 | If you're still new to React, you can do this all all within your `App.js`, with no other components. 92 | 93 | ## Split your HTML across separate React components 94 | 95 | If you haven't already, now is a good time to "decompose" your HTML into separate sections. 96 | 97 | Go back to your paper layout and circle and name each section that will be a separate component. 98 | 99 | ## Task: Read in the JSON 100 | 101 | Make your app load the JSON that you previously saved in a local file. Extract the first episode and use it to populate an `Episode` component. 102 | 103 | ## Task: Make the whole list of episodes 104 | 105 | Loop over the JSON to make a whole list of `Episode` components. 106 | 107 | Note: If your app crashes at this point, _DO NOT_ edit the JSON - instead, look at the error messages and fix your code to prevent those errors from happening. 108 | 109 | ## Task: Host your app 110 | 111 | Host your app and prove it works by viewing it on your phone! 112 | 113 | We recommend you use Netlify. [Instructions are here](https://gist.github.com/nbogie/bf58a391fab6884f77a6adec66047181). 114 | 115 | You can instead use Heroku to host, or github pages, or codesandbox.io, or glitch.com 116 | 117 | ## End of basic challenge! 118 | 119 | Congratulations, you've finished the basics! 120 | 121 | - Send the URL of your hosted app to your team on Slack. 122 | - Make sure you can access the site on a smartphone. 123 | - Celebrate! 124 | 125 | 126 | ## Optional Challenge: store your code on github 127 | 128 | Put your code in a github repo. This way: 129 | * employers can see it, 130 | * mentors can code-review it 131 | * you'll have a backup! 132 | 133 | Instructions on how to do this are [here](./github-instructions.md) 134 | 135 | ## Advanced Challenge: make an episode selector 136 | 137 | ### Example screenshot with episode selector 138 | 139 | ![Example Screenshot](./example-level-2.png) 140 | 141 | Modify your app to show only one episode, which your user can choose using a `select` input. 142 | 143 | Make the selector that lists the episode numbers (E1S1) and titles, and allows you to choose one. 144 | 145 | When you choose one from the selector, have the single shown episode update accordingly. 146 | 147 | ## Advanced Challenge: download the JSON live from the API 148 | 149 | This requires you have learned about fetch (e.g. in React week 3). 150 | 151 | Change your React app so that instead of using static data in a local file, it gets the data from the API just before it shows the page. 152 | 153 | _Be careful_ when developing this. By default, every time you make a small change to your app it will be restarted and the JSON will be downloaded _again_. These frequent http requests may lead to the API banning your IP address from further requests, or throttling for some time. 154 | 155 | ## Advanced Challenge: Add the ability to choose show 156 | 157 | ### Example screenshot with show selector 158 | 159 | ![Example Screenshot](./example-level-3.png) 160 | 161 | Add the ability for the user to pick which _show_ is being presented. e.g. Allow them to change from "Game of Thrones" to "Star Trek", or to discover new shows! 162 | 163 | Note: This will require use of fetch and a basic use of promises. 164 | 165 | Make sure you have a backup of your code for your _working_ version, before you attempt this advanced version, so you always have something to show. 166 | 167 | ## Extra CSS Challenge: Student-suggested 168 | 169 | This is a React challenge, but if you really want more practice, how about implementing this season-selector layout, suggested by Mussie (thanks Mussie!) There's interesting JS and React work to be done there, too! 170 | 171 | 172 | ![Season Selector Layout](./season-selector-mockup.png) 173 | 174 | ## Vanilla JS version of this challenge 175 | 176 | There is now [a more detailed version of this challenge in the CYF syllabus](https://github.com/CodeYourFuture/syllabus/tree/master/js-core-3/tv-show-dom-project). That version is for vanilla JavaScript, not React. You might find it useful even if you are working in React. 177 | -------------------------------------------------------------------------------- /challenge-tv-show-info/example-level-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-tv-show-info/example-level-1.png -------------------------------------------------------------------------------- /challenge-tv-show-info/example-level-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-tv-show-info/example-level-2.png -------------------------------------------------------------------------------- /challenge-tv-show-info/example-level-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-tv-show-info/example-level-3.png -------------------------------------------------------------------------------- /challenge-tv-show-info/github-instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions: Hosting your tv-info react app on github 2 | 3 | Here are instructions for hosting your tv-info React app on github. 4 | 5 | Why would you want to do this? 6 | * Potential employers can see an example of your code 7 | * You have a more permanent backup of your code 8 | * You get practice using github 9 | * You can ask for code reviews 10 | 11 | When you started with `create-react-app`, that command also made a git repository locally for your project. 12 | We will: 13 | * ensure your work is committed to that local repo, 14 | * create an empty repo on github to act as a "remote" for the local one, 15 | * push the changes from the local repo to the github "remote" 16 | 17 | ## Step-by-step 18 | 19 | * Open a terminal 20 | * `cd` into the correct directory for your react tv-info project 21 | * Add and commit all changes to git, locally, using git add and git commit 22 | * Open github.com in a browser (ensure you are logged in) 23 | * In the top-right click the plus (+) sign 24 | * Choose "new repository" 25 | * Add a suitable name for the repository. e.g. `tv-info-react` or `game-of-thrones-react` 26 | * Don't change anything else 27 | * Click `create repository` at the bottom of the form 28 | * Find the section entitled "...or push an existing repository from the command line" 29 | * Copy the FULL `git remote add origin` command from that section 30 | * Paste it into terminal, and ensure it runs with no errors 31 | * Run the second command: `git push -u origin master` 32 | * Reload your github page and explore to ensure your most recent code is there. 33 | 34 | ### Optional 1: link to your deployed project from your new github repo. 35 | 36 | It is a good idea to link from your github repo to your deployed react app. 37 | * Click on "No description, website, or topics provided." 38 | * When the form expands, edit the "website" field to have a link to your deployed project on netlify (e.g. https://elaminwk.netlify.com/) 39 | 40 | ### Optional 2: link to your source on github from the footer of your react app 41 | 42 | * In your React app, add or edit the app's Footer component to include a link back to your new github repo so that people can look at your source code. 43 | -------------------------------------------------------------------------------- /challenge-tv-show-info/season-layout-by-mussie.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-tv-show-info/season-layout-by-mussie.jpg -------------------------------------------------------------------------------- /challenge-tv-show-info/season-selector-mockup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeYourFuture/cyf-react-challenges/d183ea156b11c1680f76c117450860734ef5007d/challenge-tv-show-info/season-selector-mockup.png -------------------------------------------------------------------------------- /challenge-tv-show-info/teaching_notes.md: -------------------------------------------------------------------------------- 1 | # incremental steps for pre-react version of this challenge 2 | 3 | **pre-coding - looking at the data** 4 | * looking at one episode of the JSON, 5 | * identifying and extracting key elements of the data: episode name, img url, summary. "What properties will you need from each episode?" What are their names? Are they nested within other properties? 6 | 7 | **pure JS coding** 8 | * extracting key elements of the data from ONE episode JSON (episode name, summary, img url, etc) 9 | * presenting in plain text on the (node) console 10 | * coding necessary manipulations of those key elements, presenting to console 11 | * e.g. truncating summary to 100 chars 12 | * e.g. making a fixed-width episode tag like `S01E03` from `{..., seasonNumber: 1, episode: 3 }` 13 | * e.g. optional: clean-up of p tags in summary. 14 | * (if teaching testing: writing tests for these examples) 15 | * (optional) code some manipulations of the JSON: [Here are some in this repl: TVEpisodesStart](https://repl.it/@NeillBogie/TVEpisodesStart) 16 | * getNamesOfFirstEpisodes(epis) 17 | * getNumberedEpisode(epis, sNum, eNum) 18 | * getSeasonLengths(epis) //(advanced) 19 | *... 20 | 21 | **pre-coding - looking again at the data** 22 | * Does it contain an array or an object, at the top level? 23 | * If you think it contains an object at top level, what are the properties of the object? 24 | * If you think it contains an array at top level, how many elements are there in that array? 25 | 26 | **back to pure JS coding** 27 | * looping over the array of episodes, printing to console 28 | * filtering the episode list by a string's occurence in episode summaries 29 | * (based of necessity on a hard-coded value) 30 | * finding and reporting ONE episode based on a find for season and episode numbers 31 | 32 | **on paper** 33 | * **page layout design** (use a whiteboard app (or marvel, etc?) if remote) 34 | 35 | **html + vanilla JS coding** 36 | 37 | * **static** JSON file - **ONE episode** 38 | * **static** JSON file - **LOOP through all episodes** 39 | * **fetch of the JSON from API** 40 | 41 | ** using input fields - no change to API use** 42 | * add a search input and array.filter the episodes (based on string occurrence in summary) 43 | * episode selector drop-down ("s01e08: The Pointy End") (with scroll/jump to place in list) 44 | * defensive coding: 45 | * defend against null `episode.image` (e.g. The Simpsons) 46 | * defend against null `episode.summary` (e.g. The Voice) 47 | 48 | **responsive design** 49 | 50 | **more advanced** 51 | * single-episode version: fetching ONE resource, based on the selector 52 | * season selector, using multiple resources from the API 53 | 54 | # things to avoid 55 | 56 | * Don't have tens of resources being loaded that overwhelm exploration (e.g. in network tab) 57 | * Don't have the project source consist of tens or hundreds of files. index.html, style.css, script.js, and maybe an image. 58 | * Don't have students first trying to visualise what their programmatically created html page will LOOK like while they're staring at a page of code full of `document.createElement()` and `elem.appendChild()`. Have them build a prototype page first (e.g. in codepen) so they know exactly the page structure they're trying to create, down to the individual tag and class. 59 | * don't try to describe the challenge in text where a screenshot would do 60 | * don't give a working live version for students to play with without obfuscating the sources - some will copy-paste. Instead, use screenshots (and a video of any interaction). 61 | * Don't give the project an expiry date as a portfolio item. Use a long-lived API with data which will likely continue (e.g. based on visualisation of PRs that will be deleted). 62 | * Consider making permanently available the student's prototype version with static data as portfolio item when they want to do crucial demos without worrying about the API being available, etc. 63 | * Don't use APIs that are going to rate-limit the students through the likely repeated calling during development. 64 | 65 | 66 | # incremental steps for the react version 67 | 68 | TODO, but most of the above still applies. 69 | 70 | 71 | -------------------------------------------------------------------------------- /challenges-mars/README.md: -------------------------------------------------------------------------------- 1 | # Challenge: Who's on Mars? 2 | 3 | ## Overview 4 | 5 | NASA has sent three rovers to Mars: Spirit, Opportunity, and Curiosity. These rovers move around Mars taking pictures (among other things). 6 | 7 | Unfortunately, rovers eventually stop sending back pictures. Some of the rovers stopped sending back pictures already.😥 8 | 9 | ## Difficulty Level 10 | 11 | This is a advanced challenge. Level one can be completed by any student who has done week 3 of the CYF React module. 12 | 13 | ## API 14 | 15 | [This page gives details about NASA’s APIs](https://api.nasa.gov/). You should be ok to use DEMO_KEY as your API key for experimenting, but you may need to register for your own API key. Make sure not to check your API key into git. 16 | 17 | You should use the `Mars Rover Photos` API to get data. 18 | 19 | Make sure you read the website carefully before starting. 20 | 21 | You can use this API to get a list of the Rovers: 22 | 23 | e.g. https://api.nasa.gov/mars-photos/api/v1/rovers/?api_key=DEMO_KEY 24 | 25 | You can then use this api to get information about the rover 26 | 27 | e.g. https://api.nasa.gov/mars-photos/api/v1/rovers/curiosity?api_key=DEMO_KEY 28 | 29 | You can then use this API to get photos from that rover: 30 | 31 | e.g. https://api.nasa.gov/mars-photos/api/v1/rovers/curiosity/photos?sol=1000&api_key=DEMO_KEY 32 | 33 | _Note: Earth dates and Mars dates (“sols”) are slightly different. For the UI of this website, we always want to use Earth dates._ 34 | 35 | ## Getting Started 36 | 37 | **Don't** clone this repo. 38 | 39 | Make your own React app using `create-react-app`. See [(this guide)](https://docs.codeyourfuture.io/students/guides/creating-a-react-app) if you have forgotten how. 40 | 41 | Write a plain HTML prototype (e.g. on codepen). THEN, once you know the HTML you're attempting to create, work on the React version! This is not mandatory but it is recommended. 42 | 43 | ## Levels 44 | 45 | ### Level 100 46 | 47 | Your goal is to make a website which is a bit like a timeline or calendar. 48 | 49 | Create an overview page. 50 | 51 | Show when each of the rovers arrived on Mars, and make it clear when they overlapped. 52 | 53 | Use some nice visualisation to show this overlap. 54 | 55 | ### Level 200 56 | 57 | Improve your Overview page by also showing when each rover stopped sending back pictures. 58 | 59 | For any date I want, I should easily be able to tell “How many rovers were sending back pictures this day?” 60 | 61 | ### Level 300 62 | 63 | Per-date page - if the user clicks on a date on your overview page, you should show one picture of Mars taken by each rover which took a picture on that day. You should decide which camera tends to take the best “overview” photo. 64 | 65 | ### Level 400 66 | 67 | Per-date per-rover page - if the user clicks on the rover name from the per-date page, you should show all pictures (but not more than 25) taken by that rover on that day. 68 | 69 | ### Level 500 70 | 71 | Improve your per-date per-rover page to show up to 100 pictures. 72 | --------------------------------------------------------------------------------