├── .github └── workflows │ └── block27E.yaml ├── .gitignore ├── README.md ├── git_commands.md ├── pizza.md ├── reacto ├── find_max_value.js ├── hashing_one.js ├── merge_sort.js ├── react_traverse.js ├── recursion_one.js └── tree_one.js ├── unit_1 ├── block_10 │ ├── 11-23 │ │ ├── flexbox.css │ │ ├── flexbox.html │ │ ├── grid.css │ │ ├── grid.html │ │ ├── layout.css │ │ ├── layout.html │ │ ├── z-index.css │ │ └── z-index.html │ └── 11-25 │ │ └── index.html ├── block_2 │ ├── index.html │ └── style.css ├── block_5 │ ├── sample.html │ ├── script.js │ └── squirtle_gang.jpg ├── block_6 │ ├── index.html │ └── style.css ├── block_7 │ ├── colors.css │ ├── colors.js │ ├── data_types.js │ ├── index.html │ ├── logical_operators.js │ └── variables.js └── block_9 │ ├── about.html │ ├── contact.html │ ├── index.html │ ├── script.js │ └── styles.css ├── unit_2 ├── block_13 │ ├── functions.js │ └── index.js ├── block_14 │ ├── for_loops.js │ └── while_loops.js ├── block_15 │ ├── demo.js │ ├── json.js │ └── review.js ├── block_16 │ ├── array_methods.js │ └── block_15_review.js ├── block_17 │ └── classes.js ├── block_19 │ ├── demo.html │ ├── stocks.css │ └── stocks.js ├── block_20 │ ├── index.html │ ├── script.js │ └── styles.css ├── block_20A │ ├── modules_1 │ │ ├── log.js │ │ ├── package-lock.json │ │ ├── package.json │ │ └── sum.js │ ├── modules_2 │ │ ├── dom.test.js │ │ ├── gobble.js │ │ ├── gobble.test.js │ │ ├── index.html │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── render.js │ │ └── sum.js │ └── stretch.js ├── block_21 │ ├── index.html │ └── script.js ├── block_22 │ ├── async_review.js │ ├── block_21_api_review.js │ └── demo │ │ ├── index.html │ │ ├── main.js │ │ └── styles.css ├── block_23 │ ├── review_1.html │ └── review_1.js ├── review_1 │ ├── arrow_functions.js │ ├── assignment.js │ ├── for_loops.js │ ├── for_loops_for_lists.js │ ├── functions.js │ ├── minesweeper.js │ └── object_looping.js ├── review_2 │ ├── freelancer_forum │ │ ├── forum.css │ │ ├── forum.html │ │ └── forum.js │ └── stretch.js └── review_3 │ ├── index.html │ ├── script.js │ └── styles.css ├── unit_3 ├── block_24 │ └── jsx_intro.js ├── block_26 │ └── hooks │ │ ├── .gitignore │ │ ├── README.md │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── public │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── logo192.png │ │ ├── logo512.png │ │ ├── manifest.json │ │ └── robots.txt │ │ └── src │ │ ├── App.css │ │ ├── App.js │ │ ├── App.test.js │ │ ├── components │ │ └── Beer.js │ │ ├── index.css │ │ ├── index.js │ │ ├── logo.svg │ │ ├── reportWebVitals.js │ │ └── setupTests.js ├── block_27 │ └── forms-jwt │ │ ├── .gitignore │ │ ├── README.md │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── public │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── logo192.png │ │ ├── logo512.png │ │ ├── manifest.json │ │ └── robots.txt │ │ └── src │ │ ├── App.css │ │ ├── App.js │ │ ├── App.test.js │ │ ├── Components │ │ ├── Login.js │ │ └── SignUp.js │ │ ├── index.css │ │ ├── index.js │ │ ├── logo.svg │ │ ├── reportWebVitals.js │ │ └── setupTests.js ├── block_27B │ ├── README.md │ ├── immutability-example │ │ ├── .eslintrc.cjs │ │ ├── .gitignore │ │ ├── README.md │ │ ├── index.html │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── public │ │ │ └── vite.svg │ │ ├── src │ │ │ ├── App.jsx │ │ │ ├── Example.jsx │ │ │ └── main.jsx │ │ └── vite.config.js │ ├── pokemon-example │ │ ├── README.md │ │ ├── index.html │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── public │ │ │ └── vite.svg │ │ ├── src │ │ │ ├── App.jsx │ │ │ ├── main.jsx │ │ │ └── mockData.js │ │ └── vite.config.js │ ├── prop-drilling-example │ │ └── App.jsx │ └── redux-example │ │ ├── .eslintrc.cjs │ │ ├── .gitignore │ │ ├── README.md │ │ ├── index.html │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── public │ │ └── vite.svg │ │ ├── src │ │ ├── App.jsx │ │ ├── app │ │ │ └── store.js │ │ ├── features │ │ │ └── counter │ │ │ │ └── counterSlice.js │ │ └── main.jsx │ │ └── vite.config.js └── review_1 │ ├── .gitignore │ ├── README.md │ ├── package-lock.json │ ├── package.json │ ├── public │ ├── favicon.ico │ ├── index.html │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt │ └── src │ ├── App.css │ ├── App.js │ ├── App.test.js │ ├── components │ ├── AddTodo.js │ └── ListItem.js │ ├── index.css │ ├── index.js │ ├── logo.svg │ ├── reportWebVitals.js │ ├── setupTests.js │ └── utils │ └── dummyData.js ├── unit_4 ├── block_31 │ ├── index.html │ ├── package-lock.json │ ├── package.json │ ├── server.js │ ├── students.html │ └── topics.md ├── block_33 │ ├── .env │ ├── package-lock.json │ ├── package.json │ ├── server.js │ └── topics.md ├── block_34 │ ├── .gitignore │ ├── commands.md │ ├── package-lock.json │ ├── package.json │ ├── prisma │ │ ├── migrations │ │ │ ├── 20240212234016_init │ │ │ │ └── migration.sql │ │ │ └── migration_lock.toml │ │ └── schema.prisma │ ├── server.js │ └── tsconfig.json └── block_34B │ ├── .env │ ├── github.html │ ├── package-lock.json │ ├── package.json │ └── server.js └── unix_commands.md /.github/workflows/block27E.yaml: -------------------------------------------------------------------------------- 1 | name: My Workflow 2 | on: [push] 3 | jobs: 4 | greet: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - name: Print a message 8 | run: echo "Hello, world!" 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | node_modules 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 2310-FSA-ET-WEB-PT-SF 2 | 3 | This is our class repository. As class goes on, video links to lectures, code from lectures, and any helpful material will be placed here. 4 | 5 | ## Recordings 6 | 7 | | Topic | Date | Link | 8 | | --------------------------------------- | :------: | :---------------------------------------: | 9 | | Syllabus | 10.2.23 | [Recording](https://youtu.be/qZD5EhHtseg) | 10 | | CLI | 10.5.23 | [Recording](https://youtu.be/S-ubWKYYrHg) | 11 | | Intro to Frontend Development | 10.11.23 | [Recording](https://youtu.be/rizgPX4mnYI) | 12 | | Intro to Javascript | 10.16.23 | [Recording](https://youtu.be/25iJeH93iwk) | 13 | | Dev Work | 10.19.23 | [Recording](https://youtu.be/uv5w95MJlas) | 14 | | Github & Git | 10.26.23 | [Recording](https://youtu.be/UK3ZFEYVq-k) | 15 | | Statements, Conditionals, and Functions | 10.30.23 | [Recording](https://youtu.be/K7QdBewUQxQ) | 16 | | Loops and Arrays | 11.1.23 | [Recording](https://youtu.be/33sGihIi6Ww) | 17 | | Objects | 11.2.23 | [Recording](https://youtu.be/PmXbiZSkVI0) | 18 | | Array Methods | 11.6.23 | [Recording](https://youtu.be/s4yy9mY2XNc) | 19 | | Classes | 11.8.23 | [Recording](https://youtu.be/OFxGkeZFLBM) | 20 | | Testing | 11.9.23 | [Recording](https://youtu.be/92DmVRz9sxU) | 21 | | Review 1 | 11.13.23 | [Recording](https://youtu.be/VFbBaP9oSsA) | 22 | | DOM | 11.15.23 | [Recording](https://youtu.be/DsAkrl12AIs) | 23 | | Events | 11.20.23 | [Recording](https://youtu.be/k69veKtTgMw) | 24 | | Modules/Writing JavaScript Tests | 11.22.23 | [Recording]() | 25 | | Async Await | 11.27.23 | [Recording](https://youtu.be/yOf8refPuh4) | 26 | | Review 2 (DOM, APIS) | 12.04.23 | [Recording](https://youtu.be/VMoZb6-RzFk?si=OIdK3KFs3iySta9K) | 27 | | Fetching Data and useEffect | 12.18.23 | [Recording](https://youtu.be/x76YR84UnNo) | 28 | | Prisma | 02.12.24 | [Recording](https://youtu.be/0hkqpO2hpyc) | 29 | 30 | ## Schedule 31 | 32 | | Week | Date | Lesson | 33 | | :--: | -------- | --------------------------------------------------------------- | 34 | | 1 | 10/2/23 | Block 1: Orientation | 35 | | | 10/4/23 | Block 2: My First Website | 36 | | | 10/5/23 | Block 3: Command Line Interface | 37 | | 2 | 10/9/23 | Block 4: Development Environments | 38 | | | 10/11/23 | Block 5: Intro to Frontend Development | 39 | | | 10/12/23 | Block 6: More Frontend Development | 40 | | 3 | 10/16/23 | Block 7: JavaScript Fundamentals | 41 | | | 10/18/23 | Block 8: Development Team Dynamics | 42 | | | 10/19/23 | Block 9: Career Simulation - Building a Personal Website Pt I | 43 | | 4 | 10/23/23 | \-----Career Simulation Work Day | 44 | | | 10/25/23 | Block 10: Expanded CSS & HTML | 45 | | | 10/26/23 | Block 11: Working in a Development Team | 46 | | 5 | 10/30/23 | Block 12: Career Simulation - Building a Personal Website Pt II | 47 | | | 11/1/23 | \-----Career Simulation Work Day | 48 | | | 11/2/23 | Block 13: Conditionals & Comparisons | 49 | | 6 | 11/6/23 | Block 14: Loops & Arrays | 50 | | | 11/8/23 | Block 15: Objects and Methods | 51 | | | 11/9/23 | Block 16: Functions | 52 | | 7 | 11/13/23 | Block 17: Functions and Scope | 53 | | | 11/15/23 | Block 18: Testing | 54 | | | 11/16/23 | Block 19: JavaScript Review | 55 | | 8 | 11/20/23 | Block 20: Document Object Model | 56 | | | 11/22/23 | Block 20A: Writing Frontend Tests | 57 | | | 11/23/23 | Thanksgiving | 58 | | 9 | 11/27/23 | Block 21: ES6 Modules and the Prototype Chain | 59 | | | 11/29/23 | Block 22: Async/Await | 60 | | | 11/30/23 | Block 23A: Career Simulation | 61 | | 10 | 12/4/23 | \-----Career Simulation / Career Preparation Work Day | 62 | | | 12/6/23 | \-----Career Simulation / Career Preparation Work Day | 63 | | | 12/7/23 | \-----Career Simulation / Career Preparation Work Day | 64 | | 11 | 12/11/23 | Block 24A: Functional Programming | 65 | | | 12/13/23 | Block 24: Intro to React | 66 | | | 12/14/23 | Block 25: State and Props | 67 | | 12 | 12/18/23 | Block 26: Data Fetching and More React Hooks | 68 | | | 12/20/23 | Block 27: Forms in React | 69 | | | 12/21/23 | Block 27A: React Third Party Libraries (optional) | 70 | | 13 | 01/01/24 | Last Day of Christmas Break | 71 | | | 01/03/24 | Block 27B: Expanded React | 72 | | | 01/05/24 | Block 27C: Expanded React II | 73 | | 14 | 01/08/24 | Block 27D: Writing Tests for Frontend and React | 74 | | | 01/07/24 | Block 27E: Continuous Integration (optional) | 75 | | | 01/08/24 | Block 28: React Router | 76 | | 15 | 01/15/24 | Martin Luther King Jr. Day | 77 | | | 01/17/24 | Block 29: Puppy Bowl React | 78 | | | 01/18/24 | Block 30: Career Simulation / Career Preparation | 79 | | 16 | 01/22/24 | Block 31: Backend Fundamentals | 80 | | | 01/24/24 | Block 32: SQL | 81 | | | 01/25/24 | Block 33: API Routes | 82 | | 17 | 01/29/24 | Block 34: Career Simulation - Juicebox | 83 | | | 01/31/24 | \-----Career Simulation Work Day | 84 | | | 02/01/24 | Block 34A: Database abstractions | 85 | | 18 | 02/05/24 | Block 34B: Advanced API, back-end subjects | 86 | | | 02/07/24 | Block 34 E: Writing Backend Tests | 87 | | | 02/08/24 | Block 34F: Career Simulation Pt 2 | 88 | | 19 | 02/12/24 | \-----Career Simulation Work Day | 89 | | | 02/14/24 | Capstone/ Project Work | 90 | | | 02/15/24 | Capstone/ Project Work | 91 | | 20 | 02/19/24 | Capstone/ Project Work | 92 | | | 02/21/24 | Capstone/ Project Work | 93 | | | 02/22/24 | Capstone/ Project Work | 94 | | 21 | 02/26/24 | Capstone/ Project Work | 95 | | | 02/28/24 | Capstone/ Project Work | 96 | | | 02/29/24 | Capstone/ Project Work | 97 | | 22 | 03/04/24 | Capstone/ Project Work | 98 | | | 03/06/24 | Capstone/ Project Work | 99 | | | 03/07/24 | Capstone/ Project Work | 100 | | 23 | 03/11/24 | Capstone/ Project Work | 101 | | | 03/13/24 | Capstone/ Project Work | 102 | | | 03/14/24 | Capstone/ Project Work | 103 | | 24 | 03/18/24 | Capstone/ Project Work | 104 | | | 03/20/24 | Capstone/ Project Work | 105 | | | 03/21/24 | Capstone/ Project Work | 106 | | 25 | 03/25/24 | Capstone/ Project Work | 107 | | | 03/27/24 | Capstone/ Project Work | 108 | | | 03/28/24 | Block 48: Algos | 109 | | 26 | 04/01/24 | Block 49: Algos | 110 | | | 04/03/24 | Block 50: Algos | 111 | | | 04/04/24 | Block 51: Algos | 112 | | 27 | 04/08/24 | Block 52: Algos | 113 | | | 04/10/24 | Self-Directed Learning Plan | 114 | | | 04/11/24 | Self-Directed Learning Plan | 115 | | 28 | 04/15/24 | Self-Directed Learning Plan | 116 | | | 04/17/24 | Self-Directed Learning Plan | 117 | | | 04/18/24 | Graduation | 118 | -------------------------------------------------------------------------------- /git_commands.md: -------------------------------------------------------------------------------- 1 | # Git Commands 2 | 3 | git add: starting tracking a file 4 | 5 | git commit: adds a commit message to file(s) 6 | 7 | git push: pushes the commited files to git 8 | 9 | git status: shows the status of file(s) 10 | -------------------------------------------------------------------------------- /pizza.md: -------------------------------------------------------------------------------- 1 | Aguilar, Luis : 0 2 | Alcaraz, Javier : 0 3 | Badell, Roy : 0 4 | Bobadilla, Monica : 0 5 | Brown, Matthew : 3 6 | Carouthers, Stephen : 4 7 | Charles, Marc : 1 8 | Choi, Jennie : 0 9 | cooper, marcus : 0 10 | Daniels, Vanessa : 0 11 | Davila, Jonathan : 1 12 | Disylvestro, Angel : 1 13 | Fang, Zi : 2 14 | Fuller, John : 0 15 | Garcia, Jason : 1 16 | Gomez, Eduardo : 1 17 | Gonzalez, Alexis : 2 18 | Haynes, Ethan : 0 19 | Hernandez, Tony : 0 20 | herrera, mario jr : 0 21 | Hinson, Jon : 2 22 | Johnson, Troy : 0 23 | Jones, Monica : 0 24 | Julio, Isaias : 0 25 | Kiguli, Jude : 0 26 | King, Andrew : 0 27 | landrum, timothy : 0 28 | Lee, Mo : 1 29 | Lott, Clayton : 0 30 | Martinez, Victor : 5 31 | Maynard, Khiry : 0 32 | Mekmueangthong, Santiparp : 2 33 | Mullai, Midhat : 0 34 | Munoz, Jordan : 1 35 | noel, marquez : 2 36 | Nugent, Christopher : 1 37 | Peterson, Hisashi : 0 38 | Regmi, Sarvesh : 3 39 | Richards, Keevin : 0 40 | Rivera, Moises : 0 41 | Shogan, Gregory : 0 42 | Strickland, Felton : 0 43 | Stroupe, David : 1 44 | Tavarez, Lilianne : 0 45 | Theiss, Ernest : 1 46 | Vargas, Katie : 0 47 | Williams, Portia : 0 48 | -------------------------------------------------------------------------------- /reacto/find_max_value.js: -------------------------------------------------------------------------------- 1 | // Prompt 2 | /* 3 | Add a method to BinaryTree called "locateMaxValue". Given the below class, the method should find the max value in the current tree. 4 | 5 | Add a method to BinaryTree called "locateMinValue". Given the below class, the method should find the min value in the current tree. 6 | 7 | Add a method to BinaryTree called "accumulateTree". This method should return the tree as an array in ANY order. Essentially converting the tree to an array and disregarding any semblance of order. 8 | */ 9 | 10 | class BinaryTree { 11 | value = null; 12 | 13 | left = null; 14 | 15 | right = null; 16 | 17 | constructor(value) { 18 | this.value = value; 19 | } 20 | 21 | insert = (value) => { 22 | if (value < this.value) { 23 | if (!this.left) { 24 | const createdNode = new BinaryTree(value); 25 | this.left = createdNode; 26 | 27 | return createdNode; 28 | } else { 29 | return this.left.insert(value); 30 | } 31 | } else { 32 | if (!this.right) { 33 | const createdNode = new BinaryTree(value); 34 | this.right = createdNode; 35 | 36 | return createdNode; 37 | } else { 38 | return this.right.insert(value); 39 | } 40 | } 41 | } 42 | 43 | retrieve = (value) => { 44 | if (this.value === value) { 45 | return this.value; 46 | } else if (value < this.value) { 47 | if (!this.left) { 48 | return null; 49 | } else { 50 | return this.left.retrieve(value); 51 | } 52 | } else { 53 | if (!this.right) { 54 | return null; 55 | } else { 56 | return this.right.retrieve(value); 57 | } 58 | } 59 | } 60 | } 61 | 62 | // Solution 63 | // I'm writing this as standalone functions to save space. These should actually be written as methods on the class. 64 | 65 | function locateMaxValue() { 66 | if (this.right) { 67 | return this.right.locateMaxValue(); 68 | } else { 69 | return this.value; 70 | } 71 | } 72 | 73 | function locateMinValue() { 74 | if (this.left) { 75 | return this.left.locateMinValue(); 76 | } else { 77 | return this.value; 78 | } 79 | } 80 | 81 | const values = []; 82 | 83 | function accumulateTree(child) { 84 | 85 | } 86 | -------------------------------------------------------------------------------- /reacto/hashing_one.js: -------------------------------------------------------------------------------- 1 | // Prompt 2 | // Write a function "hasDuplicates" that uses a hash table to detect if it has seen a value before. The hash table should operate in O(1) time. The complexity of the overall problem should be O(n). 3 | 4 | const hasDuplicates = (nums) => { 5 | // TODO 6 | } 7 | 8 | console.log(hasDuplicates([1, 2, 3, 4, 5])); // => false 9 | console.log(hasDuplicates([6, 7, 8, 9, 6])); // => true 10 | 11 | // Solution 12 | // DO NOT PASTE TO INTERVIEWEE 13 | 14 | const hasDuplicatesSolution = (nums) => { 15 | // Create Hash Table 16 | const collection = {}; 17 | 18 | // Don't get caught up on this - a standard for loop is fine as well. Whatever their flavor for iteration is works! 19 | for (let num of nums) { 20 | // Check the hash table for a collision. 21 | if (collection[num]) { 22 | // If there is a collision, return true. 23 | return true; 24 | } 25 | 26 | // Otherwise, add it to the hash table. 27 | collection[num] = true; 28 | } 29 | 30 | // If no collision occurred, there are no duplicates. 31 | return false; 32 | } 33 | 34 | // Stretch Goal (If Interviewee Gets It) 35 | // Lets take that same function, and allow it to work across function calls. So if I call it with (1, 2, 3) in one call, and (3, 4, 5) in another call, it will correctly identify the second call (3, 4, 5) as having a duplicate (3) because 3 was in both the first arguments (1, 2, 3) and the second (3, 4, 5). 36 | const cacheHasSeenDuplicates = (nums) => { 37 | // TODO 38 | } 39 | 40 | console.log(cacheHasSeenDuplicates([1, 2, 3])); // => false 41 | console.log(cacheHasSeenDuplicates([3, 4, 5])); // => true 42 | 43 | // Stretch Goal Solution 44 | // DO NOT PASTE TO INTERVIEWEE 45 | // Almost the exact same, but you must dig deep in your javascript well to remember closure, which gives functions their own memory store. 46 | const createCacheHasSeenDuplicates = () => { 47 | // Create the hash table in the upper scope (the closure). So that it is accessible to the returned function in perpetuity. 48 | const duplicatesTable = {}; 49 | 50 | return (nums) => { 51 | for (let num of nums) { 52 | // Check the hash table for a collision. 53 | if (duplicatesTable[num]) { 54 | // If there is a collision, return true. 55 | return true; 56 | } 57 | 58 | // Otherwise, add it to the hash table. 59 | duplicatesTable[num] = true; 60 | } 61 | 62 | // If no collision occurred, there are no duplicates. 63 | return false; 64 | }; 65 | } 66 | 67 | const cacheHasSeenDuplicatesSolution = createCacheHasSeenDuplicates(); 68 | -------------------------------------------------------------------------------- /reacto/merge_sort.js: -------------------------------------------------------------------------------- 1 | const merge = (left, right) => { 2 | const sortedArr = []; 3 | 4 | while (left.length && right.length) { 5 | if (left[0] <= right[0]) { 6 | sortedArr.push(left.shift()); 7 | } else { 8 | sortedArr.push(right.shift()); 9 | } 10 | } 11 | 12 | const combinedArr = [...sortedArr, ...left, ...right]; 13 | 14 | console.log('Combined: ', combinedArr); 15 | 16 | return combinedArr; 17 | }; 18 | 19 | // MS [3, 2, 4, 1] 20 | // MS [3, 2] 21 | // MS [3] 22 | // MS [2] 23 | // M ([3], [2]) => [2, 3] 24 | // MS [4, 1] 25 | // MS [4] 26 | // MS [1] 27 | // M ([4], [1]) => [1, 4] 28 | // M ([2, 3], [1, 4]) => [1, 2, 3, 4] 29 | const mergeSort = (listOfNumbers) => { 30 | if (listOfNumbers.length < 2) { 31 | return listOfNumbers; 32 | } 33 | 34 | const halfPoint = Math.round(listOfNumbers.length / 2); 35 | 36 | const left = listOfNumbers.splice(0, halfPoint); 37 | const right = listOfNumbers; 38 | 39 | console.log('Left: ', left, 'Right: ', right); 40 | 41 | return merge(mergeSort(left), mergeSort(right)); 42 | }; 43 | 44 | const generateArray = (size) => { 45 | return new Array(size).fill('').map(() => { 46 | return Math.round(Math.random() * 1000); 47 | }); 48 | }; 49 | 50 | console.log('Final Result: ', mergeSort(generateArray(25))); 51 | -------------------------------------------------------------------------------- /reacto/react_traverse.js: -------------------------------------------------------------------------------- 1 | class BinaryTree { 2 | value = null; 3 | 4 | left = null; 5 | 6 | right = null; 7 | 8 | constructor(value) { 9 | this.value = value; 10 | } 11 | 12 | insert = (value) => { 13 | if (value < this.value) { 14 | if (!this.left) { 15 | const createdNode = new BinaryTree(value); 16 | this.left = createdNode; 17 | 18 | return createdNode; 19 | } else { 20 | return this.left.insert(value); 21 | } 22 | } else { 23 | if (!this.right) { 24 | const createdNode = new BinaryTree(value); 25 | this.right = createdNode; 26 | 27 | return createdNode; 28 | } else { 29 | return this.right.insert(value); 30 | } 31 | } 32 | } 33 | 34 | retrieve = (value) => { 35 | if (this.value === value) { 36 | return this.value; 37 | } else if (value < this.value) { 38 | if (!this.left) { 39 | return null; 40 | } else { 41 | return this.left.retrieve(value); 42 | } 43 | } else { 44 | if (!this.right) { 45 | return null; 46 | } else { 47 | return this.right.retrieve(value); 48 | } 49 | } 50 | } 51 | 52 | breadthSearch = () => { 53 | const breadthArray = []; 54 | const childrenToProcess = []; 55 | 56 | breadthArray.push(this.value); 57 | 58 | if (this.left) { 59 | childrenToProcess.push(this.left); 60 | } 61 | 62 | if (this.right) { 63 | childrenToProcess.push(this.right); 64 | } 65 | 66 | while (childrenToProcess.length) { 67 | const nextChild = childrenToProcess.shift(); 68 | 69 | breadthArray.push(nextChild.value); 70 | 71 | if (nextChild.left) { 72 | childrenToProcess.push(nextChild.left); 73 | } 74 | 75 | if (nextChild.right) { 76 | childrenToProcess.push(nextChild.right); 77 | } 78 | } 79 | 80 | return breadthArray; 81 | } 82 | 83 | recursiveSearch = (type, searchFunc) => { 84 | if (type === 'pre') { 85 | searchFunc(this.value); 86 | } 87 | 88 | this.left?.recursiveSearch(type, searchFunc); 89 | 90 | if (type === 'in') { 91 | searchFunc(this.value); 92 | } 93 | 94 | this.right?.recursiveSearch(type, searchFunc); 95 | 96 | if (type === 'post') { 97 | searchFunc(this.value); 98 | } 99 | } 100 | } 101 | 102 | /* 103 | 5 104 | 3 7 105 | 2 4 8 106 | */ 107 | 108 | const root = new BinaryTree(5); 109 | root.insert(3); 110 | root.insert(7); 111 | root.insert(2); 112 | root.insert(4); 113 | root.insert(8); 114 | 115 | console.log('Breadth', root.breadthSearch()); 116 | 117 | // Pre-Order, Post-Order, In-Order 118 | 119 | const preArray = []; 120 | const postArray = []; 121 | const inArray = []; 122 | 123 | root.recursiveSearch('pre', (val) => { 124 | preArray.push(val); 125 | }); 126 | 127 | root.recursiveSearch('post', (val) => { 128 | postArray.push(val); 129 | }); 130 | 131 | root.recursiveSearch('in', (val) => { 132 | inArray.push(val); 133 | }); 134 | 135 | console.log('Pre', preArray); 136 | console.log('Post', postArray); 137 | console.log('In', inArray); 138 | -------------------------------------------------------------------------------- /reacto/recursion_one.js: -------------------------------------------------------------------------------- 1 | // Prompt 2 | // Write a function "reverseString" that takes a string as input, and returns that string reversed. You MUST use recursion for your answer. Any form of looping (including built-ins like .forEach) are forbidden for your solution. 3 | 4 | // hello 5 | // ello 6 | // llo 7 | // lo 8 | // o 9 | // '' 10 | // '' 11 | 12 | const reverseString = (inputString) => { 13 | console.log('Going Down: ', inputString); 14 | 15 | // Base Case - Where do we stop calling ourselves again? 16 | if (inputString.length === 0) { 17 | return ''; 18 | } 19 | // Recursive Case - When do we call ourselves again? 20 | const restOfCharactersReversed = reverseString(inputString.substring(1, inputString.length)); 21 | console.log('Result of Reversal While Coming Up: ', restOfCharactersReversed); 22 | 23 | // Return - How do we create the value over time? 24 | return restOfCharactersReversed + inputString[0]; 25 | } 26 | 27 | console.log(reverseString('hello')); // => olleh 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | // Solution 41 | // const reverseString = (inputString) => { 42 | // // Base Case: Return nothing if there are no characters left. 43 | // if (inputString.length === 0) { 44 | // return ''; 45 | // } 46 | // 47 | // // Recursive Case: Reverse every character in the string besides for the first one. 48 | // const restOfStringReversed = reverseString( 49 | // inputString.substring(1, inputString.length), 50 | // ); 51 | // 52 | // // Because, we will append whatever the "first" character was at this level to the end of the rest of the string reversed. 53 | // return restOfStringReversed + inputString.charAt(0); 54 | // }; 55 | // 56 | // console.log(reverseString('hello')); // => olleh 57 | -------------------------------------------------------------------------------- /reacto/tree_one.js: -------------------------------------------------------------------------------- 1 | // Trees 2 | 3 | // Guess what Im number Im thinking? 4 | // The number is between 0 and 100 5 | 6 | // 10 7 | // 50 8 | // 76 9 | // 60 10 | // 68 11 | // 64 12 | // 61 13 | // 62 14 | 15 | // They tell you lower or higher at every interval allowing super fast search lookups for particular data 16 | 17 | // 30 18 | 19 | // 50 20 | // 25 21 | // 37 22 | // 31 23 | // 28 24 | // 29 25 | // 30 26 | 27 | class BinaryTree { 28 | value = null; 29 | 30 | left = null; 31 | 32 | right = null; 33 | 34 | constructor(value) { 35 | this.value = value; 36 | } 37 | 38 | insert = (value) => { 39 | if (value < this.value) { 40 | if (!this.left) { 41 | const createdNode = new BinaryTree(value); 42 | this.left = createdNode; 43 | 44 | return createdNode; 45 | } else { 46 | return this.left.insert(value); 47 | } 48 | } else { 49 | if (!this.right) { 50 | const createdNode = new BinaryTree(value); 51 | this.right = createdNode; 52 | 53 | return createdNode; 54 | } else { 55 | return this.right.insert(value); 56 | } 57 | } 58 | } 59 | 60 | retrieve = (value) => { 61 | console.log('Searching Into Node with Value: ', this.value); 62 | 63 | if (this.value === value) { 64 | return this.value; 65 | } else if (value < this.value) { 66 | if (!this.left) { 67 | return null; 68 | } else { 69 | return this.left.retrieve(value); 70 | } 71 | } else { 72 | if (!this.right) { 73 | return null; 74 | } else { 75 | return this.right.retrieve(value); 76 | } 77 | } 78 | } 79 | } 80 | 81 | const generateNumbers = (size) => { 82 | const uniqueNumbers = new Set( 83 | new Array(size).fill('').map(() => { 84 | return Math.round(Math.random() * 100000); 85 | }), 86 | ); 87 | 88 | return Array.from(uniqueNumbers); 89 | }; 90 | 91 | const allNums = generateNumbers(1000000); 92 | 93 | const root = new BinaryTree(allNums.shift()); 94 | 95 | allNums.forEach((num) => root.insert(num)); 96 | 97 | root.retrieve(321); 98 | -------------------------------------------------------------------------------- /unit_1/block_10/11-23/flexbox.css: -------------------------------------------------------------------------------- 1 | .container { 2 | display: flex; 3 | flex-direction: row; 4 | background-color: orange; 5 | flex-wrap: wrap; 6 | } 7 | 8 | .box1, .box2 { 9 | flex: 50%; 10 | } 11 | 12 | .box3 { 13 | background-color: red; 14 | flex: 30%; 15 | } 16 | 17 | .box4 { 18 | flex: 70%; 19 | background-color: blue; 20 | } 21 | 22 | @media screen and (min-width: 390px) { 23 | .container { 24 | flex-direction: column; 25 | } 26 | } 27 | 28 | @media screen and (min-width: 500px) and (max-width: 800px) { 29 | .container { 30 | flex-direction: column; 31 | } 32 | } 33 | 34 | @media screen and (min-width: 1020px) { 35 | .container { 36 | flex-direction: column; 37 | } 38 | } -------------------------------------------------------------------------------- /unit_1/block_10/11-23/flexbox.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 22 |
23 |
1
24 |
2
25 |
3
26 |
4
27 |
28 | 29 | -------------------------------------------------------------------------------- /unit_1/block_10/11-23/grid.css: -------------------------------------------------------------------------------- 1 | .container { 2 | display: grid; 3 | grid-template-rows: repeat(2, 1fr); 4 | grid-template-columns: repeat(3, 1fr); 5 | grid-template-areas: 6 | "box1 box1 box1" 7 | "box3 box4 box2"; 8 | } 9 | 10 | .box1 { 11 | grid-area: box1; 12 | background-color: red; 13 | } 14 | 15 | .box2 { 16 | grid-area: box2; 17 | background-color: green; 18 | } 19 | 20 | .box3 { 21 | grid-area: box3; 22 | background-color: orange; 23 | } 24 | 25 | .box4 { 26 | grid-area: box4; 27 | background-color: cyan; 28 | } 29 | -------------------------------------------------------------------------------- /unit_1/block_10/11-23/grid.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 |
11 |
1
12 |
2
13 |
3
14 |
4
15 | 20 | 21 |
22 | 23 | -------------------------------------------------------------------------------- /unit_1/block_10/11-23/layout.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | margin: 0; 3 | height: 100%; 4 | } 5 | 6 | main { 7 | display: flex; 8 | flex-wrap: wrap; 9 | height: 100%; 10 | } 11 | 12 | .header, .footer { 13 | background-color: gray; 14 | flex: 100%; 15 | display: flex; 16 | align-items: center; 17 | justify-content: center; 18 | margin-bottom: 30px; 19 | } 20 | 21 | .sidebar-1, .article, .sidebar-2 { 22 | flex: calc(100% / 3 - 10px); 23 | background-color: gray; 24 | margin-right: 10px; 25 | margin-bottom: 30px; 26 | } 27 | -------------------------------------------------------------------------------- /unit_1/block_10/11-23/layout.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 |
11 |
Header
12 | 13 |
Article
14 | 15 | 16 |
17 | 18 | 19 | -------------------------------------------------------------------------------- /unit_1/block_10/11-23/z-index.css: -------------------------------------------------------------------------------- 1 | .box1 { 2 | background-color: red; 3 | height: 200px; 4 | width: 200px; 5 | z-index: 2; 6 | position: relative; 7 | } 8 | 9 | .box2 { 10 | background-color: yellow; 11 | height: 200px; 12 | width: 200px; 13 | position: relative; 14 | left: 50px; 15 | bottom: 50px; 16 | z-index: 1; 17 | } -------------------------------------------------------------------------------- /unit_1/block_10/11-23/z-index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 |
11 |
box1
12 |
box2
13 |
14 | 15 | -------------------------------------------------------------------------------- /unit_1/block_10/11-25/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Grid / Flexbox Demo 8 | 9 | 10 |
11 |
header
12 |
hero
13 |
content
14 | 15 | 16 |
17 | 18 | -------------------------------------------------------------------------------- /unit_1/block_2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Coding 6 | 29 | 30 | 31 | 32 |

My first websites

33 |
34 |

Taylor Swift

35 | 37 | 39 | 41 |
42 | 43 |

this is another text about my website

44 | Hi I'm a inline element 45 | 46 | 47 | -------------------------------------------------------------------------------- /unit_1/block_2/style.css: -------------------------------------------------------------------------------- 1 | img { 2 | width: 200px; 3 | height: 200px; 4 | } -------------------------------------------------------------------------------- /unit_1/block_5/sample.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Introduction to Frontend Development 4 | 5 | 6 | 7 | 11 |
12 |

Eliots HTML Tutorial Site

13 |
14 |
15 |
16 |

Introduction to Frontend Development

17 |

18 | Today we are focused on the parent-child relationship of HTML elements, the meaning of "semantic" in regards to elements, and of course, on HTML itself and some of its useful tags. 19 |

20 |
21 |
22 |

Element Structure

23 |

24 | HTML elements consist of greater than and less than symbols (<, >) with a tag name inbetween. 25 |

26 |
27 |
28 |

Javascript Magic

29 | 30 | 35 |
36 |
37 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /unit_1/block_5/script.js: -------------------------------------------------------------------------------- 1 | function changeColor() { 2 | const p = document.getElementById('html_element_p'); 3 | 4 | p.style.color = 'purple'; 5 | p.style['font-size'] = '64px'; 6 | } 7 | -------------------------------------------------------------------------------- /unit_1/block_5/squirtle_gang.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FullstackAcademy/2310-fsa-et-web-pt-sf-class-repo/a5f1225dc309f78bcbc2ef1e4d3d67065736e25a/unit_1/block_5/squirtle_gang.jpg -------------------------------------------------------------------------------- /unit_1/block_6/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 14 | 15 | 16 | 17 | 18 | 19 |

Grocery List

20 | 25 | 26 |

Things to learn

27 |
    28 |
  1. 29 | HTML 30 |
  2. 31 |
  3. 32 |
  4. hi
  5. 33 |
  6. hi
  7. 34 | 35 |
  8. JavaScript
  9. 36 |
37 | 38 |

Drinks

39 |
40 |
Coffee
41 |
- black hot drink
42 |
Milk
43 |
- white cold drink
44 |
45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
First NameLast NameEmail
JohnDoeJohnDoe@gmail.com
SallyDoeSallyDoe@gmail.com
64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /unit_1/block_6/style.css: -------------------------------------------------------------------------------- 1 | table { 2 | border: 10px solid red; 3 | } 4 | 5 | /* id */ 6 | #coffee, .item { 7 | color: brown; 8 | } 9 | /* class */ 10 | 11 | .item { 12 | font-size: 50px; 13 | } 14 | -------------------------------------------------------------------------------- /unit_1/block_7/colors.css: -------------------------------------------------------------------------------- 1 | #colors { 2 | display: flex; 3 | flex-direction: row; 4 | flex-wrap: wrap; 5 | } 6 | 7 | .color_div { 8 | width: 100px; 9 | height: 100px; 10 | border-radius: 50%; 11 | border: solid 1px black; 12 | margin: 10px; 13 | } 14 | -------------------------------------------------------------------------------- /unit_1/block_7/colors.js: -------------------------------------------------------------------------------- 1 | // I want to select the div with id "colors" 2 | const colorsDiv = document.getElementById('colors'); 3 | // I need to describe my favorite colors 4 | const favoriteColors = ['purple', 'green', 'gold', 'black', 'gray', 'yellow', 'orange']; 5 | // for every color 6 | for (let i = 0; i < favoriteColors.length; ++i) { 7 | // I then want to create a new div 8 | const colorDiv = document.createElement('div'); 9 | // I am then going to apply some styling to have that div show a color that i really like 10 | colorDiv.className = 'color_div'; 11 | colorDiv.style['background-color'] = favoriteColors[i]; 12 | // I am then going to attach that div to the colors div from earlier 13 | colorsDiv.appendChild(colorDiv); 14 | } 15 | -------------------------------------------------------------------------------- /unit_1/block_7/data_types.js: -------------------------------------------------------------------------------- 1 | // Static Types and Dynamic Types 2 | 3 | // The JS Types 4 | // Booleans 5 | // Numbers 6 | // Strings 7 | // Objects (more on this later, this is a huge category) 8 | // undefined 9 | // null 10 | 11 | // Boolean 12 | // Absence of, or presence of. 13 | // True or False 14 | // 1 or 0 15 | 16 | const aBoolean = true; 17 | const aBoolean2 = false; 18 | 19 | const eliotIsTheBestTeacher = true; 20 | const eliot_is_the_best_teacher = true; 21 | 22 | // Numbers 23 | // console.log('The max number in JS: ', Number.MAX_SAFE_INTEGER); 24 | 25 | const aNumber = 100.672; 26 | 27 | // Operations: Things we can do to data types based on what they are. 28 | // Addition, subtraction, multiplication, exponentiation, division, logarithms, etc etc 29 | 30 | console.log('Addition: ', 2 + 2); 31 | console.log('Subtraction: ', 2 - 2); 32 | console.log('Division: ', 2 / 2); 33 | console.log('Multiplication: ', 2 * 2); 34 | console.log('Exponentiation: ', 2 ** 2); 35 | console.log('Advanced, Logs: ', Math.log2(4)); 36 | console.log('Using Variables: ', aNumber * 2); 37 | 38 | // Strings 39 | // A collection of (sometimes) human readable text. Text is composed of composite parts. Characters are put together to form a string. 40 | 41 | const aString = 'Eliot Szwajkowski'; 42 | const aStudent = "Victor Martinez"; 43 | // Template Literals 44 | const aTeacherAge = 35; 45 | const aTeacher = `Ryan Riley Puzon 46 | 47 | is so cool 48 | 49 | and his age is ${aTeacherAge} 50 | `; 51 | 52 | // Operations 53 | // Concatenation 54 | // Putting two strings together 55 | const anotherStudent = "Jon" + ` ` + 'Hinson'; 56 | 57 | // Coercion 58 | 59 | console.log(1 + 1); // 2 60 | console.log('Eliot ' + 'Szwajkowski'); // 'Eliot Szwajkowski' 61 | console.log(1 + '1'); // '11' 😡 62 | console.log(1 + '1' - 1); // '10' 😵 63 | 64 | // Avoid coercion at all costs. 65 | 66 | // Objects 67 | 68 | // Array - an array is a list of any other datatypes. An array is a subtype of objects. 69 | // Dictionary - a collection of keyed values. 70 | const aDict = { 71 | name: 'EliotSzwajkowski', 72 | age: Infinity, 73 | pets: 2, 74 | }; 75 | 76 | // undefined 77 | // Undefined means we forgot to assign a value to something. 78 | let coolThing; 79 | 80 | // null 81 | // null is an intentional value meaning "nothing". It is often used to notate a variable as not having been given its value yet. 82 | let otherCoolThing = null; 83 | 84 | // NaN 85 | NaN 86 | // A symbol for a number we cant represent 87 | console.log('Are you a not a number?', isNaN(NaN)); 88 | 89 | // typeof 90 | 91 | console.log('TypeOf', typeof NaN); 92 | -------------------------------------------------------------------------------- /unit_1/block_7/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 |

My Favorite Colors

12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /unit_1/block_7/logical_operators.js: -------------------------------------------------------------------------------- 1 | // Logical Operators 2 | 3 | // AND 4 | // Uses &&, only true if both sides are true 5 | console.log('true && true', true && true); 6 | 7 | // OR 8 | // Uses ||, only true if one or both sides is true 9 | console.log('true || false', true || false); 10 | 11 | // NOT 12 | // Uses !, this inverts the value after it 13 | console.log('!false', !false); 14 | 15 | // Coercion 16 | // Show some cases of coercion 17 | 18 | // Truthiness vs Falsiness 19 | // Six Falsy Values 20 | 0 21 | '' 22 | null 23 | undefined 24 | NaN 25 | false 26 | 27 | // Comparison 28 | // !== not equal 29 | // === equal 30 | 31 | // "loose" versions 32 | // != 33 | // == 34 | -------------------------------------------------------------------------------- /unit_1/block_7/variables.js: -------------------------------------------------------------------------------- 1 | let variableTwo = 'This is the let variable.'; 2 | const variableThree = 'This is the const variable'; 3 | 4 | variableTwo = 'This is still the let variable, but somewhat different.'; 5 | -------------------------------------------------------------------------------- /unit_1/block_9/about.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | About 8 | 9 | 10 | 15 | 16 |

Michell Brito

17 |

Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature 18 | from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, 19 | looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of 20 | the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 21 | of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise 22 | on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit 23 | amet..", comes from a line in section 1.10.32.

24 | 25 | -------------------------------------------------------------------------------- /unit_1/block_9/contact.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 15 |
16 | 17 | 18 | 19 | 20 |
21 | 22 | -------------------------------------------------------------------------------- /unit_1/block_9/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Homepage 8 | 9 | 10 | 11 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /unit_1/block_9/script.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FullstackAcademy/2310-fsa-et-web-pt-sf-class-repo/a5f1225dc309f78bcbc2ef1e4d3d67065736e25a/unit_1/block_9/script.js -------------------------------------------------------------------------------- /unit_1/block_9/styles.css: -------------------------------------------------------------------------------- 1 | #homepage-nav a { 2 | color: green; 3 | } 4 | 5 | #about-nav a { 6 | color: yellow; 7 | } 8 | 9 | #contact-nav a { 10 | color: red; 11 | } -------------------------------------------------------------------------------- /unit_2/block_13/functions.js: -------------------------------------------------------------------------------- 1 | // no parmameter, no return 2 | function greetUser(){ 3 | console.log('hi michell'); 4 | console.log('how was your day?'); 5 | } 6 | 7 | // greetUser(); 8 | 9 | // calls function to execute 10 | 11 | 12 | // parameter, with return 13 | 14 | // globl = not nested within another variable 15 | function math (num1,num2){ 16 | // local variable 17 | function addTwoNums(num1, num2) { 18 | return num1 + num2; 19 | } 20 | console.log(addTwoNums(num1, num2)); 21 | } 22 | // math(10, 5); 23 | // math(100, 20); 24 | function subtract(num1,num2){ 25 | return num1-num2; 26 | } 27 | 28 | 29 | // var currentAge = subtract(2023,1995); 30 | // console.log('my current age is: ' + currentAge) 31 | 32 | console.log('my current age is: ' + subtract(2023, 1995)) 33 | 34 | // For this question in the competency check: 35 | 36 | // let value = 21; 37 | 38 | if (value < 0) { 39 | console.log("value is negative"); 40 | } else if (value === 20) { 41 | console.log("value is assigned the number 20"); 42 | } else if (value > 0) { 43 | console.log("value is positive"); 44 | } else { 45 | console.log("value is assigned the number 0"); 46 | // return; 47 | } 48 | 49 | -------------------------------------------------------------------------------- /unit_2/block_13/index.js: -------------------------------------------------------------------------------- 1 | // Booleans 2 | 3 | // true 4 | // false 5 | 6 | // 0 - 1 7 | 8 | // "Truthy" "Falsy" 9 | 10 | // Remember the 6 falsy values 11 | 0 12 | '' 13 | NaN 14 | false 15 | undefined 16 | null 17 | 18 | console.log('-----------------------------\n'); 19 | 20 | // Everything else is truthy 21 | 22 | // const doesUserLikeOranges = prompt('Do you like oranges?'); 23 | const doesUserLikeOranges = 'yes'; 24 | 25 | // if ( 26 | // doesUserLikeOranges === 'yes' 27 | // || doesUserLikeOranges === 'bet' 28 | // || doesUserLikeOranges === 'yea' 29 | // || doesUserLikeOranges === 'ya' 30 | // ) { 31 | // console.log('🍊'); 32 | // } else { 33 | // console.log('It prevents scurvy, you should like oranges you idiot.'); 34 | // } 35 | 36 | // Varying inputs change the output you receive from a piece of code 37 | 38 | // Functions 39 | // A function is a reusable chunk of code that can take "arguments" that alter its behavior. 40 | // DRY 41 | // If you find yourself writing the same code twice, youre doing it wrong 42 | // Write code once, make it work for lots of different situations 43 | 44 | function checkIfCanDrinkAlcohol(birthYear) { 45 | if (birthYear > 2023) { 46 | throw new Error("You can't be born in the future."); 47 | } else if (2023 - birthYear >= 21) { 48 | return true; 49 | } else { 50 | return false; 51 | } 52 | } 53 | 54 | // console.log(checkIfCanDrinkAlcohol(2025)); 55 | // console.log(checkIfCanDrinkAlcohol(2005)); 56 | // console.log(checkIfCanDrinkAlcohol(1999)); 57 | // console.log(checkIfCanDrinkAlcohol(1998)); 58 | // console.log(checkIfCanDrinkAlcohol(2012)); 59 | // console.log(checkIfCanDrinkAlcohol(1964)); 60 | // console.log(checkIfCanDrinkAlcohol(1776)); 61 | // console.log(checkIfCanDrinkAlcohol(2001)); 62 | 63 | function addTwoNumbers(numberOne, numberTwo) { 64 | return numberOne + numberTwo; 65 | } 66 | 67 | // console.log(addTwoNumbers(2, 2)); 68 | // console.log(addTwoNumbers(3, 7)); 69 | 70 | function randomNumber() { 71 | const randPercentage = Math.round(Math.random() * 100); 72 | 73 | return randPercentage; 74 | } 75 | 76 | console.log(randomNumber()); 77 | 78 | console.log('\n-----------------------------\n'); 79 | -------------------------------------------------------------------------------- /unit_2/block_14/for_loops.js: -------------------------------------------------------------------------------- 1 | // arrays are index 2 | // ex: roy is index 0, andrew is index 5; 3 | let names = ['Roy', "Jennie", "Alexis", "Ryan", "Matt", "Andrew" ]; 4 | 5 | console.log(names.length) 6 | 7 | for(let i = 0; i < names.length; i++){ 8 | if (names[i] === "Ryan"){ 9 | names.splice(i,1); 10 | } 11 | } 12 | 13 | for (let i = names.length - 1; i >= 0; i = i - 2) { 14 | console.log(names[i]); 15 | } 16 | 17 | -------------------------------------------------------------------------------- /unit_2/block_14/while_loops.js: -------------------------------------------------------------------------------- 1 | let age = 1; 2 | 3 | while (age <= 21){ 4 | if (age < 21){ 5 | console.log('you cant drink'); 6 | } else { 7 | console.log('nice! you can drink'); 8 | } 9 | age++; 10 | } -------------------------------------------------------------------------------- /unit_2/block_15/demo.js: -------------------------------------------------------------------------------- 1 | const fruit = { 2 | name: "banana", 3 | color: ["green", "yellow", "brown"], 4 | sugar: 14, 5 | isAvailable: true, 6 | }; 7 | 8 | const shoe = { 9 | brand: "converse", 10 | hasLaces: true, 11 | hasVelcro: false, 12 | color: "green", 13 | price: 50, 14 | activityType: "basketball", 15 | }; 16 | 17 | // console.log(shoe.color); 18 | // console.log(shoe["color"]); 19 | // console.log(shoe.brand); 20 | // console.log(shoe["brand"]); 21 | // console.log(shoe.lincoln); 22 | 23 | const car = { 24 | color: "blue", 25 | brand: "honda", 26 | trim: "sport", 27 | }; 28 | console.log(car.color); 29 | car.weight = "1577kg"; 30 | car.color = "red"; 31 | 32 | car.trim = null; 33 | console.table(car); 34 | 35 | // let property = "color"; 36 | // console.log(car[property]); 37 | // console.log(car["color"]); 38 | 39 | // property = "brand"; 40 | // console.log(car[property]); 41 | 42 | for (const key in car) { 43 | console.log(car[key]); 44 | } 45 | 46 | // console.log(Object.keys(shoe)); 47 | // console.log(Object.values(shoe)); 48 | 49 | // console.log(Object.values(fruit)); 50 | // let array = Object.values(fruit); 51 | 52 | // console.log(array[1][0]); 53 | console.log(car); 54 | console.log(typeof car); 55 | -------------------------------------------------------------------------------- /unit_2/block_15/json.js: -------------------------------------------------------------------------------- 1 | // ********************** 2 | //DEMO JSON (parsing and printing) 3 | // ********************** 4 | // ********************** 5 | // Learning Objectives 6 | // - JSON methods (parse and stringify) 7 | // ********************** 8 | 9 | const obj = { name: "John", age: 30, car: null }; 10 | 11 | const str = JSON.stringify(obj, null, 2); 12 | console.log(str); 13 | console.log(typeof str, "\n"); 14 | 15 | const obj2 = JSON.parse('{"name": "John", "age": 30, "car": null}'); 16 | 17 | console.log("This becomes an object:", obj2); 18 | console.log(typeof obj2); 19 | -------------------------------------------------------------------------------- /unit_2/block_15/review.js: -------------------------------------------------------------------------------- 1 | // functions 2 | function add(num1, num2) { 3 | console.log(num1 + num2); 4 | } 5 | // add(2, 3); 6 | ​ 7 | function favoriteDog(name) { 8 | console.log(`My favorite dog is ${name}!`); 9 | // console.log("My favorite dog is " + name + "!"); 10 | } 11 | // favoriteDog("Logan"); 12 | // favoriteDog("Chase"); 13 | // favoriteDog("Lincoln"); 14 | ​ 15 | // for loops 16 | const dogs = ["Logan", "Chase", "Lincoln"]; 17 | // console.log(dogs[0]); 18 | // console.log(dogs[1]); 19 | // console.log(dogs[2]); 20 | ​ 21 | for (let i = 0; i < dogs.length; i++) { 22 | console.log(dogs[i]); 23 | } 24 | ​ 25 | // const i = "eagles"; 26 | // console.log(i); 27 | ​ 28 | // i = "phillies"; 29 | // console.log(i); 30 | -------------------------------------------------------------------------------- /unit_2/block_16/array_methods.js: -------------------------------------------------------------------------------- 1 | const fruitsArray = ['🍇', '🍈', '🍉', '🍊', '🍋', '🍌']; 2 | 3 | const fruitsObject = { 4 | grape: { emoji: '🍇', price: 3.79, color: 'purple' }, 5 | melon: { emoji: '🍈', price: 3.19, color: 'green' }, 6 | watermelon: { emoji: '🍉', price: 4.19, color: 'green and pink' }, 7 | tangerine: { emoji: '🍊', price: 3.97, color: 'orange' }, 8 | lemon: { emoji: '🍋', price: 3.99, color: 'yellow' }, 9 | banana: { emoji: '🍌', price: 2.02, color: 'yellow' }, 10 | }; 11 | 12 | // forEach 13 | 14 | // old way of looping 15 | // for(let i = 0; i < fruitsArray.length; i++){ 16 | // console.log(fruitsArray[i]); 17 | // } 18 | 19 | // fat arrow function (callback) 20 | fruitsArray.forEach((fruit, index) => console.log(`${fruit}: ${index}`)); 21 | 22 | 23 | // fruitsArray.forEach(function(fruit){ 24 | // console.log(fruit) 25 | // }) 26 | 27 | // map 28 | const fruits = Object.values(fruitsObject); 29 | const fruitNames = Object.keys(fruitsObject); 30 | const fruitPrices = fruits.map((fruit) => fruit.price); 31 | // console.log(fruitPrices); 32 | 33 | // reduce 34 | const groceryTotal = fruitPrices.reduce((sum, currentPrice) => sum + currentPrice, 0); 35 | // console.log(groceryTotal) 36 | // rounds up a number 37 | // console.log(Math.floor(groceryTotal)) 38 | 39 | // filter 40 | // const yellowFruits = fruitsArray.filter((fruit) => fruit === '🍋' || fruit === '🍌' ) 41 | const yellowFruits = fruits.filter((fruit) => fruit.color === 'yellow').map((fruit) => fruit.emoji); 42 | // console.log(yellowFruits); 43 | 44 | // find 45 | const grapeFruit = fruitsArray.find((fruit) => fruit === '🍇' ); 46 | // console.log(grapeFruit); 47 | 48 | // slice 49 | const threeFruits = fruitsArray.slice(0,3); 50 | // console.log(threeFruits); -------------------------------------------------------------------------------- /unit_2/block_16/block_15_review.js: -------------------------------------------------------------------------------- 1 | // removing white space 2 | const num = '10 '; 3 | console.log(num.trim() === '10'); 4 | 5 | 6 | -------------------------------------------------------------------------------- /unit_2/block_17/classes.js: -------------------------------------------------------------------------------- 1 | // regular object 2 | const michell = { 3 | firstName: 'michell', 4 | lastName: 'brito', 5 | getFirstName: function () { 6 | return 'michell'; 7 | } 8 | } 9 | 10 | // console.log(michell.getFirstName()) 11 | 12 | // function with parm 13 | function getFirstName(name) { 14 | console.log(name); 15 | } 16 | 17 | // getFirstName('michell') 18 | // getFirstName('Daniel') 19 | // getFirstName('Keevin') 20 | 21 | class Student { 22 | // setting up parms within a class 23 | constructor(firstName, lastName) { 24 | this.firstName = firstName; 25 | this.lastName = lastName; 26 | } 27 | 28 | // creating functions witin a class 29 | getFirstName() { 30 | return this.firstName; 31 | } 32 | 33 | getLastName() { 34 | return this.lastName; 35 | } 36 | 37 | setLastName(name) { 38 | this.lastName = name; 39 | } 40 | } 41 | 42 | const matt = new Student('Matt', "Brown"); 43 | 44 | // // calling the keys from our class 45 | console.log(matt.lastName); 46 | console.log(matt.firstName); 47 | 48 | // // calling function defined from our class 49 | console.log(matt.getFirstName()); 50 | 51 | 52 | const sally = new Student('Sally', "Doe"); 53 | // changing the initial value passed to a class 54 | console.log(sally.getLastName()); 55 | sally.setLastName('Gomez'); 56 | console.log(sally.getLastName()); 57 | 58 | -------------------------------------------------------------------------------- /unit_2/block_19/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Bad Stock Market 4 | 5 | 6 | 7 | 8 |
9 |

Our Stocks!

10 |
11 |
12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /unit_2/block_19/stocks.css: -------------------------------------------------------------------------------- 1 | .stock_container { 2 | display: flex; 3 | flex-direction: column; 4 | } 5 | 6 | .stock_ticker { 7 | background-color: yellow; 8 | font-weight: bold; 9 | transition: background-color 250ms linear; 10 | display: flex; 11 | flex-direction: row; 12 | justify-content: space-evenly; 13 | align-items: center; 14 | padding: 0.2em; 15 | border: solid 1px black; 16 | font-family: "Comic Sans MS"; 17 | } 18 | 19 | .gains { 20 | background-color: lawngreen; 21 | } 22 | 23 | .losses { 24 | background-color: red; 25 | } 26 | -------------------------------------------------------------------------------- /unit_2/block_19/stocks.js: -------------------------------------------------------------------------------- 1 | const stockContainer = document.querySelector('#stock_container'); 2 | 3 | const stocks = [ 4 | { 5 | name: 'GME', 6 | price: 420, 7 | }, 8 | { 9 | name: 'AMZ', 10 | price: 20, 11 | }, 12 | { 13 | name: 'MSFT', 14 | price: 111, 15 | }, 16 | ]; 17 | 18 | function createStock(stock) { 19 | const stockTicker = document.createElement('div'); 20 | stockTicker.classList.add('stock_ticker'); 21 | 22 | const tickerName = document.createElement('span'); 23 | tickerName.textContent = stock.name; 24 | const tickerSplitter = document.createElement('span'); 25 | tickerSplitter.textContent = '|'; 26 | const tickerPrice = document.createElement('price'); 27 | tickerPrice.textContent = stock.price; 28 | 29 | stockTicker.append(tickerName, tickerSplitter, tickerPrice); 30 | 31 | setInterval(function() { 32 | const randomAmount = Math.random() * (stock.price * .05); 33 | const isGain = Math.random() >= .5; 34 | 35 | if (isGain) { 36 | stock.price += randomAmount; 37 | tickerPrice.textContent = stock.price.toFixed(2); 38 | stockTicker.classList.add('gains'); 39 | stockTicker.classList.remove('losses'); 40 | } else { 41 | stock.price -= randomAmount; 42 | tickerPrice.textContent = stock.price.toFixed(2); 43 | stockTicker.classList.add('losses'); 44 | stockTicker.classList.remove('gains'); 45 | } 46 | }, 1000); 47 | 48 | return stockTicker; 49 | } 50 | 51 | function createAllStocks(allStocks) { 52 | let tickers = []; 53 | 54 | for (let i = 0; i < allStocks.length; ++i) { 55 | const currentStock = allStocks[i]; 56 | 57 | tickers.push(createStock(currentStock)); 58 | } 59 | 60 | return tickers; 61 | } 62 | 63 | // Render Loop 64 | // One function called "render", that will rebuild the entire page. 65 | stockContainer.append(...createAllStocks(stocks)); 66 | -------------------------------------------------------------------------------- /unit_2/block_20/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Events 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 |
19 | 20 |
21 | 22 |
23 | 24 | 25 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /unit_2/block_20/script.js: -------------------------------------------------------------------------------- 1 | function sayName() { 2 | alert('Hi Michell'); 3 | } 4 | 5 | // event lister using js 6 | document.getElementById('hoverBtn').addEventListener('mouseover', sayName) 7 | 8 | const sayNameBtn = document.createElement('button'); 9 | sayNameBtn.innerText = "Click Me"; 10 | sayNameBtn.addEventListener('click', sayName); 11 | sayNameBtn.setAttribute('class', 'btn'); 12 | sayNameBtn.setAttribute('id', 'clickBtn'); 13 | 14 | document.querySelector('body').append(sayNameBtn) 15 | 16 | document.querySelector('#form').addEventListener('submit', function (e) { 17 | e.preventDefault(); 18 | const firstName = document.getElementById('firstName').value; 19 | const lastName = document.getElementById('lastName').value; 20 | console.log(firstName, lastName) 21 | }); -------------------------------------------------------------------------------- /unit_2/block_20/styles.css: -------------------------------------------------------------------------------- 1 | .btn { 2 | background-color: red; 3 | border-radius: 50px; 4 | } 5 | 6 | #clickBtn { 7 | color: orange; 8 | } -------------------------------------------------------------------------------- /unit_2/block_20A/modules_1/log.js: -------------------------------------------------------------------------------- 1 | import chalk from 'chalk'; 2 | import sum from './sum.js'; 3 | 4 | console.log(chalk.yellow('Sum: '), chalk.red(sum(2, 2))); 5 | -------------------------------------------------------------------------------- /unit_2/block_20A/modules_1/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "modules_1", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "modules_1", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "chalk": "^5.3.0" 13 | } 14 | }, 15 | "node_modules/chalk": { 16 | "version": "5.3.0", 17 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", 18 | "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", 19 | "engines": { 20 | "node": "^12.17.0 || ^14.13 || >=16.0.0" 21 | }, 22 | "funding": { 23 | "url": "https://github.com/chalk/chalk?sponsor=1" 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /unit_2/block_20A/modules_1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "modules_1", 3 | "version": "1.0.0", 4 | "type": "module", 5 | "description": "", 6 | "main": "log.js", 7 | "scripts": { 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "chalk": "^5.3.0" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /unit_2/block_20A/modules_1/sum.js: -------------------------------------------------------------------------------- 1 | const sum = (a, b) => { 2 | return a + b; 3 | } 4 | 5 | export default sum; 6 | -------------------------------------------------------------------------------- /unit_2/block_20A/modules_2/dom.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | const { getByText } = require('@testing-library/dom'); 5 | const sum = require('./sum.js'); 6 | 7 | function domReset() { 8 | document.body.innerHTML = ` 9 |
10 | `; 11 | } 12 | 13 | describe('Document Testing', () => { 14 | beforeEach(domReset); 15 | 16 | test('Sum correctly adds numbers for insertion on page.', () => { 17 | document.getElementById('app'); 18 | 19 | app.textContent = sum(4, 4); 20 | 21 | expect(getByText(document, '6')).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /unit_2/block_20A/modules_2/gobble.js: -------------------------------------------------------------------------------- 1 | const gobble = (howManyGobbles) => { 2 | return `${new Array(2 ** howManyGobbles).fill('Gobble').join(' ')}!`; 3 | }; 4 | 5 | module.exports = gobble; 6 | -------------------------------------------------------------------------------- /unit_2/block_20A/modules_2/gobble.test.js: -------------------------------------------------------------------------------- 1 | const gobble = require('./gobble.js'); 2 | 3 | test('Returns an appropriate number of gobbles when given 0 as an argument.', () => { 4 | expect(gobble(0)).toEqual('Gobble!'); 5 | }); 6 | 7 | test('Returns an appropriate number of gobbles when given 4 as an argument.', () => { 8 | expect(gobble(4)).toEqual('Gobble Gobble Gobble Gobble Gobble Gobble Gobble Gobble Gobble Gobble Gobble Gobble Gobble Gobble Gobble Gobble!'); 9 | }); 10 | -------------------------------------------------------------------------------- /unit_2/block_20A/modules_2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | -------------------------------------------------------------------------------- /unit_2/block_20A/modules_2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "modules_2", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "jest" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "@testing-library/dom": "^9.3.3", 14 | "jest": "^29.7.0", 15 | "jest-environment-jsdom": "^29.7.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /unit_2/block_20A/modules_2/render.js: -------------------------------------------------------------------------------- 1 | const sum = require('./sum.js'); 2 | 3 | const appDiv = document.getElementById('app'); 4 | 5 | appDiv.textContent = sum(2, 2); 6 | -------------------------------------------------------------------------------- /unit_2/block_20A/modules_2/sum.js: -------------------------------------------------------------------------------- 1 | const sum = (a, b) => { 2 | return a + b; 3 | }; 4 | 5 | module.exports = sum; 6 | -------------------------------------------------------------------------------- /unit_2/block_20A/stretch.js: -------------------------------------------------------------------------------- 1 | // Write a function "gobbler" that takes a number, and it writes 2 ^ number "Gobble"s into a string, ending with an exclamation mark. 2 | 3 | function gobbler(howManyGobbles) { 4 | const gobbleCount = 2 ** howManyGobbles; 5 | 6 | let gobbleString = ''; 7 | 8 | for (let i = 0; i < gobbleCount; ++i) { 9 | gobbleString += 'Gobble '; 10 | } 11 | 12 | gobbleString = gobbleString.slice(0, -1); 13 | 14 | return gobbleString + '!'; 15 | } 16 | 17 | const result = gobbler(0); 18 | 19 | console.log(result); // => "Gobble!" 20 | 21 | const result2 = gobbler(4); 22 | 23 | console.log(result2); // => "Gobble Gobble Gobble Gobble Gobble Gobble Gobble Gobble Gobble Gobble Gobble Gobble Gobble Gobble Gobble Gobble!" 24 | -------------------------------------------------------------------------------- /unit_2/block_21/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Async / Await 8 | 9 | 10 | 11 |

Async / Await

12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /unit_2/block_21/script.js: -------------------------------------------------------------------------------- 1 | async function getRecipies() { 2 | try { 3 | const response = await fetch('https://fsa-crud-2aa9294fe819.herokuapp.com/api/2310-FSA-ET-WEB-PT-SF/recipes'); 4 | const recipes = await response.json(); 5 | for (let i = 0; i < recipes.data.length; i++) { 6 | console.log(recipes) 7 | const recipeElm = document.createElement('p'); 8 | recipeElm.innerText = recipes.data[i].name; 9 | document.querySelector('body').append(recipeElm); 10 | } 11 | } catch (err) { 12 | console.log(err); 13 | document.querySelector('body').append('error please try again later'); 14 | } 15 | } 16 | 17 | async function addRecipie() { 18 | try { 19 | const response = await fetch('https://fsa-crud-2aa9294fe819.herokuapp.com/api/2310-FSA-ET-WEB-PT-SF/recipes', { 20 | method: 'POST', 21 | body: JSON.stringify({ 22 | name: "michell cheese burger", 23 | imageUrl: "https://contenthub.kraftheinz.com/api/public/content/91c0242dbc2e479886547f52f0cb0812?v=04b07367", 24 | description: "michell famous cheese burger" 25 | }), 26 | headers: { 27 | 'Content-Type': 'application/json' 28 | } 29 | }); 30 | } catch (err) { 31 | console.log(err); 32 | } 33 | } 34 | 35 | async function deleteBurger(id) { 36 | try { 37 | await fetch(`https://fsa-crud-2aa9294fe819.herokuapp.com/api/2310-FSA-ET-WEB-PT-SF/recipes/${id}`, { 38 | method: 'DELETE', 39 | }); 40 | } catch (err) { 41 | console.log(err); 42 | } 43 | } 44 | 45 | async function updateRecipie(id) { 46 | try { 47 | const response = await fetch(`https://fsa-crud-2aa9294fe819.herokuapp.com/api/2310-FSA-ET-WEB-PT-SF/recipes/${id}`, { 48 | method: 'PUT', 49 | body: JSON.stringify({ 50 | name: "Fresh cheese", 51 | }), 52 | headers: { 53 | 'Content-Type': 'application/json' 54 | } 55 | }); 56 | } catch (err) { 57 | console.log(err); 58 | } 59 | } 60 | 61 | document.getElementById('dataBtn').addEventListener('click', getRecipies); 62 | document.getElementById('postBtn').addEventListener('click', addRecipie); 63 | document.getElementById('deleteBtn').addEventListener('click', async function(){ 64 | await deleteBurger(570); 65 | }); 66 | document.getElementById('updateBtn').addEventListener('click', async function(){ 67 | await updateRecipie(571); 68 | }); -------------------------------------------------------------------------------- /unit_2/block_22/async_review.js: -------------------------------------------------------------------------------- 1 | // Asynchronicity 2 | // Some things take lots of time. You have to do something that is going to run for a long time, and you want to do other stuff while that is happening. 3 | // Uncertainty - We can't trust external sources to behave as expected. 4 | // There are almost infinite reasons something might not work as expected. 5 | 6 | // fetch - requesting data from some other site 7 | 8 | // We declared that this function is asynchronous in its declaration. 9 | // const fetchGoogle = async () => { 10 | // // Inside an async function, we said "wait on this thing". 11 | // const response = await fetch('http://www.google.com'); 12 | // 13 | // const html = await response.body.getReader().read(); 14 | // 15 | // console.log('Response Body: ', html.value.toString()); 16 | // }; 17 | 18 | // fetchGoogle(); 19 | 20 | // async function fetchGoogleDec() { 21 | // await fetch('http://www.google.com'); 22 | // } 23 | 24 | const delay = (time, reject = false) => { 25 | return new Promise((res, rej) => { 26 | setTimeout(() => { 27 | if (reject) { 28 | rej(new Error(`The delay timed out!`)); 29 | } 30 | res(); 31 | }, time); 32 | }); 33 | } 34 | 35 | 36 | const sayThingsInOrder = async () => { 37 | try { 38 | // HAPPY PATH 39 | console.log('Hello!'); 40 | await delay(1000, true); 41 | console.log(`Its so nice to see you!`); 42 | } catch (e) { 43 | // BAD PATH 44 | console.error(e); 45 | console.log(`I'm having a bad day.`); 46 | } finally { 47 | // BUDDHIST PATH 48 | console.log('Goodbye!') 49 | } 50 | }; 51 | 52 | sayThingsInOrder(); 53 | // NOTE: This runs before the rest of the function is over! Async Await only applies inside of the async function itself. 54 | // console.log('Is it over yet?'); 55 | -------------------------------------------------------------------------------- /unit_2/block_22/block_21_api_review.js: -------------------------------------------------------------------------------- 1 | const BASE_URL = 'https://fsa-crud-2aa9294fe819.herokuapp.com/api'; 2 | const COHORT = '/2310-fsa-et-web-pt-sf'; 3 | 4 | const CLASS_URL = `${BASE_URL}${COHORT}`; 5 | 6 | const getRecipes = async () => { 7 | try { 8 | const response = await fetch(`${CLASS_URL}/recipes`); 9 | const json = await response.json(); 10 | 11 | return json; 12 | } catch (e) { 13 | console.log('Failed to get recipes.'); 14 | console.error(e); 15 | 16 | return { 17 | success: false, 18 | error: e, 19 | data: [], 20 | }; 21 | } 22 | }; 23 | 24 | const getRSVPS = async () => { 25 | try { 26 | const response = await fetch(`${CLASS_URL}/rsvps`); 27 | const json = await response.json(); 28 | 29 | return json; 30 | } catch (e) { 31 | console.log('Failed to get RSVPs.'); 32 | console.error(e); 33 | 34 | return { 35 | success: false, 36 | error: e, 37 | data: [], 38 | }; 39 | } 40 | }; 41 | 42 | const runApp = async () => { 43 | const rsvps = await getRSVPS(); 44 | 45 | console.log('RSVPs', rsvps); 46 | }; 47 | 48 | runApp(); 49 | -------------------------------------------------------------------------------- /unit_2/block_22/demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Hash Routing 6 | 7 | 8 |
9 | 10 | 11 | -------------------------------------------------------------------------------- /unit_2/block_22/demo/main.js: -------------------------------------------------------------------------------- 1 | let app = document.getElementById('app'); 2 | 3 | const state = { 4 | resource: '', 5 | resourceId: null, 6 | allRecipes: [], 7 | }; 8 | 9 | const BASE_URL = 'https://fsa-crud-2aa9294fe819.herokuapp.com/api'; 10 | const COHORT = '/2310-fsa-et-web-pt-sf'; 11 | 12 | const CLASS_URL = `${BASE_URL}${COHORT}`; 13 | 14 | const getAllRecipes = async () => { 15 | try { 16 | const response = await fetch(`${CLASS_URL}/recipes`); 17 | const json = await response.json(); 18 | 19 | return json.data; 20 | } catch (e) { 21 | console.log('Failed to get recipes.'); 22 | console.error(e); 23 | 24 | return { 25 | success: false, 26 | error: e, 27 | data: [], 28 | }; 29 | } 30 | }; 31 | 32 | const fetchResource = async () => { 33 | try { 34 | const response = await fetch(`${CLASS_URL}/${state.resource}/${state.resourceId}`); 35 | const json = await response.json(); 36 | 37 | return json.data; 38 | } catch (e) { 39 | console.log(`Failed to get ${state.resource} ${state.resourceId}.`); 40 | console.error(e); 41 | 42 | return null; 43 | } 44 | } 45 | 46 | const clearDOM = () => { 47 | // NOTE: Wipe the application clean. 48 | document.body.removeChild(app); 49 | 50 | const newApp = document.createElement('div'); 51 | newApp.id = 'app'; 52 | 53 | document.body.appendChild(newApp); 54 | 55 | app = newApp; 56 | }; 57 | 58 | const createHeader = (text, size = 1) => { 59 | const header = document.createElement(`h${size}`); 60 | 61 | header.innerText = text; 62 | 63 | return header; 64 | } 65 | 66 | const createRecipeList = (recipes) => { 67 | const list = document.createElement('div'); 68 | list.classList.add('card_list'); 69 | 70 | const cards = recipes.map((recipe) => { 71 | const card = document.createElement('div'); 72 | card.classList.add('card'); 73 | 74 | const cardTitle = createHeader(recipe.name, 4); 75 | 76 | card.appendChild(cardTitle); 77 | 78 | const cardImage = document.createElement('img'); 79 | cardImage.src = recipe.imageUrl; 80 | cardImage.classList.add('card_image'); 81 | 82 | card.appendChild(cardImage); 83 | 84 | const cardDescription = document.createElement('p'); 85 | cardDescription.innerText = recipe.description; 86 | 87 | card.appendChild(cardDescription); 88 | 89 | const cardButton = document.createElement('button'); 90 | cardButton.innerText = `Go To ${recipe.name} Recipe!`; 91 | cardButton.onclick = () => { 92 | window.location.hash = `/recipes/${recipe.id}`; 93 | }; 94 | 95 | card.appendChild(cardButton); 96 | 97 | return card; 98 | }); 99 | 100 | list.append(...cards); 101 | 102 | return list; 103 | }; 104 | 105 | const createCodeBlock = (text) => { 106 | const code = document.createElement('code'); 107 | 108 | code.innerText = text; 109 | 110 | return code; 111 | } 112 | 113 | const render = () => { 114 | clearDOM(); 115 | 116 | app.appendChild(createHeader(`Resource: ${state.resource}`)); 117 | app.appendChild(createHeader(`Resource ID: ${state.resourceId}`, 2)); 118 | 119 | const selectedResourceContainer = document.createElement('div'); 120 | 121 | app.appendChild(selectedResourceContainer); 122 | 123 | if (state.resource && state.resourceId) { 124 | fetchResource() 125 | .then((data) => { 126 | selectedResourceContainer.appendChild(createCodeBlock(JSON.stringify(data, null, 2))); 127 | }); 128 | } 129 | 130 | app.appendChild(document.createElement('hr')); 131 | 132 | app.appendChild(createHeader('All Recipes')); 133 | app.appendChild(createRecipeList(state.allRecipes)); 134 | }; 135 | 136 | const manageHash = () => { 137 | state.allRecipes = recipes; 138 | 139 | const path = decodeURIComponent(window.location.hash.slice(1)); 140 | 141 | const parts = path.split('/'); 142 | 143 | // /recipes/123 144 | // squirtle yolo yahtzee 145 | const resource = parts[1]; 146 | 147 | state.resource = resource; 148 | 149 | const resourceId = parts[2]; 150 | 151 | state.resourceId = resourceId; 152 | } 153 | 154 | window.addEventListener('hashchange', () => { 155 | manageHash(); 156 | 157 | render(); 158 | }); 159 | 160 | const startApp = async () => { 161 | const recipes = await getAllRecipes(); 162 | 163 | manageHash(); 164 | 165 | render(); 166 | }; 167 | 168 | startApp(); 169 | -------------------------------------------------------------------------------- /unit_2/block_22/demo/styles.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | width: 100vw; 4 | height: 100vh; 5 | max-width: 100vw; 6 | max-height: 100vh; 7 | overflow: hidden; 8 | } 9 | 10 | .card { 11 | display: flex; 12 | flex-direction: column; 13 | align-items: center; 14 | max-height: 500px; 15 | max-width: 300px; 16 | border: solid 3px black; 17 | overflow: hidden; 18 | padding: 0.5em; 19 | margin: 1em; 20 | box-sizing: border-box; 21 | } 22 | 23 | .card_list { 24 | display: flex; 25 | flex-wrap: wrap; 26 | width: 100%; 27 | overflow-y: auto; 28 | } 29 | 30 | .card_image { 31 | width: 100%; 32 | } 33 | 34 | #app { 35 | overflow-y: auto; 36 | max-width: 100%; 37 | max-height: 100%; 38 | } 39 | -------------------------------------------------------------------------------- /unit_2/block_23/review_1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | -------------------------------------------------------------------------------- /unit_2/block_23/review_1.js: -------------------------------------------------------------------------------- 1 | // .map 2 | 3 | // Array is an object 4 | 5 | // const someArray = []; 6 | // 7 | // console.log(typeof someArray); 8 | 9 | // const anObjectWithAMethod = { 10 | // hello: () => { 11 | // console.log('Hello!'); 12 | // }, 13 | // }; 14 | // 15 | // anObjectWithAMethod.hello(); 16 | 17 | // Map is an array method that looks at every element in an array, and gives you a chance to return a new value based on that element. Each new value you return is placed in the same index you are inspecting in a brand new array. 18 | 19 | const someOtherArray = [1, 2, 3, 4, 5]; 20 | 21 | function mapper(elem) { 22 | return elem * 2; 23 | } 24 | 25 | const newArray = someOtherArray.map(mapper); 26 | 27 | // console.log(newArray); 28 | 29 | function myMap(array, cb) { 30 | const newArray = []; 31 | 32 | for (let i = 0; i < array.length; ++i) { 33 | const elem = array[i]; 34 | 35 | const newElem = cb(elem); 36 | 37 | newArray.push(newElem); 38 | } 39 | 40 | return newArray; 41 | } 42 | 43 | const otherNewArray = myMap(someOtherArray, mapper); 44 | 45 | // console.log('New 1', newArray); 46 | // console.log('New 2', otherNewArray); 47 | 48 | // Buttons 49 | 50 | // const state = { 51 | // count: 0, 52 | // }; 53 | // 54 | // const app = document.getElementById('app'); 55 | // 56 | // const button = document.createElement('button'); 57 | // button.textContent = 'Increment'; 58 | // const countText = document.createElement('h2'); 59 | // countText.textContent = state.count; 60 | 61 | // Way 1: Event Listeners 62 | // button.addEventListener('click', function() { 63 | // alert('Hello World!'); 64 | // }); 65 | 66 | // Way 2: assign a handler 67 | // button.onclick = function() { 68 | // ++state.count; 69 | // countText.textContent = state.count; 70 | // } 71 | // 72 | // app.appendChild(button); 73 | // app.appendChild(countText); 74 | 75 | // render 76 | 77 | // Document That Displays Stuff -> User Interacts with the Document -> Something Changes from that Interaction -> Document Displays That Change -> 78 | 79 | // HTML Skeleton -> User Does Something that Uses Javascript (INTERACTION) -> Javascript Changes Data Somewhere (STATE CHANGE) -> Redraw the HTML/CSS (RENDER STATE) -> 80 | 81 | let app = document.getElementById('app'); 82 | 83 | // INITIAL STATE 84 | const state = { 85 | name: '', 86 | names: [], 87 | }; 88 | 89 | const clearDOM = () => { 90 | document.body.removeChild(app); 91 | 92 | const newApp = document.createElement('div'); 93 | newApp.id = 'app'; 94 | app = newApp; 95 | 96 | document.body.append(newApp); 97 | } 98 | 99 | const render = () => { 100 | clearDOM(); 101 | 102 | const nameInput = document.createElement('input'); 103 | 104 | nameInput.addEventListener('change', (event) => { 105 | state.name = event.target.value; 106 | }); 107 | 108 | const submitName = document.createElement('button'); 109 | submitName.textContent = 'Add Name'; 110 | 111 | submitName.addEventListener('click', () => { 112 | state.names.push(state.name); 113 | state.name = ''; 114 | nameInput.value = state.name; 115 | render(); 116 | }); 117 | 118 | const pageBreak = document.createElement('hr'); 119 | 120 | const nameHeaders = state.names.map((name) => { 121 | const nameHeader = document.createElement('h3'); 122 | nameHeader.textContent = name; 123 | 124 | return nameHeader; 125 | }); 126 | 127 | app.append(nameInput, submitName, pageBreak, ...nameHeaders); 128 | } 129 | 130 | render(); 131 | -------------------------------------------------------------------------------- /unit_2/review_1/arrow_functions.js: -------------------------------------------------------------------------------- 1 | function addTwoNumbers(numOne, numTwo) { 2 | return numOne + numTwo; 3 | } 4 | 5 | const result = addTwoNumbers(7, 3); 6 | 7 | console.log(result); 8 | 9 | const addTwoNumbersArrow = (numOne, numTwo) => { 10 | return numOne + numTwo; 11 | } 12 | 13 | // Implicit Returns 14 | // Will return whatever is after the arrow if a curly brace is not there. 15 | /* 16 | const addTwoNumbersArrow = (numOne, numTwo) => return numOne + numTwo; 17 | */ 18 | 19 | const resultArrow = addTwoNumbersArrow(50, 49); 20 | 21 | console.log(resultArrow); 22 | 23 | const sayHelloToName = name => `Hello ${name}!`; 24 | 25 | console.log(sayHelloToName('Clayton')); 26 | -------------------------------------------------------------------------------- /unit_2/review_1/assignment.js: -------------------------------------------------------------------------------- 1 | let name = 'Eliot'; 2 | let lastName = ' Szwajkowski'; 3 | 4 | // Longform 5 | // name = name + lastName; 6 | // Shorthand 7 | name += lastName; 8 | 9 | count = 1; 10 | 11 | // Longform 12 | // count = count - 1; 13 | // Shorthand 14 | count -= 1; 15 | 16 | console.log('Name', name); 17 | console.log('Count', count); 18 | -------------------------------------------------------------------------------- /unit_2/review_1/for_loops.js: -------------------------------------------------------------------------------- 1 | // For Loops 2 | // Alexis says, helps a programmer do less manual work and repeat a task multiple times 3 | // Marcus says, Repeat a set of instructions multiple times 4 | 5 | // Some task 6 | // Do that task a lot 7 | 8 | // const someArray = [1, 2, 3, 4, 5]; 9 | 10 | // For loops are often thought of as being for lists, but they can do all sorts of stuff. 11 | 12 | // let lotsOfHellos = ''; 13 | // 14 | // for (let i = 0; i < 100; i++) { 15 | // // someArray[i] 16 | // 17 | // lotsOfHellos += 'Hello!'; 18 | // } 19 | // 20 | // console.log(lotsOfHellos); 21 | 22 | // const someStupidArray = []; 23 | // 24 | // for (let i = 0; i <= someStupidArray.length; i++) { 25 | // someStupidArray.push('Snowing'); 26 | // } 27 | // 28 | // console.log(someStupidArray.length); 29 | 30 | // let myName = 'Eliot Szwajkowski'; 31 | // 32 | // while (myName.length) { 33 | // console.log(myName[0]); 34 | // myName = myName.slice(1); 35 | // } 36 | 37 | // When should I use a while loops versus a for loop? 38 | // Always use a for loop 39 | // .while should only be used when the condition to end the repetition involves "emptying" some sort of object 40 | 41 | // The fluidity of the arguments to for loops is vast! 42 | // The only rule is that you initialize a value, you have a way for the for loop to end, and that you update the value to get closer to ending the loop. 43 | 44 | for (let name = ''; name.length <= 12; name += 'ALEXIS') { 45 | console.log(name); 46 | } 47 | 48 | // Quintessentially the same 49 | // const items = [1, 2, 3, 4, 5]; 50 | // 51 | // for (let item of items) { 52 | // 53 | // } 54 | // 55 | // items.forEach((item) => { 56 | // 57 | // }); 58 | -------------------------------------------------------------------------------- /unit_2/review_1/for_loops_for_lists.js: -------------------------------------------------------------------------------- 1 | // Lists and For Loops 2 | 3 | const aListOfNames = ['David', 'Andrew', 'Stephen', 'Victor', 'Marquez']; 4 | 5 | // Tell me how many of the names are 6 or more characters. 6 | 7 | function checkLengthOfName(list, maxCharacterCount) { 8 | let count = 0; 9 | 10 | for (let i = 0; i < aListOfNames.length; ++i) { 11 | const aName = aListOfNames[i]; 12 | 13 | if (aName.length >= maxCharacterCount) { 14 | ++count; 15 | } 16 | } 17 | 18 | return count; 19 | } 20 | 21 | console.log(checkLengthOfName(aListOfNames, 3)); 22 | -------------------------------------------------------------------------------- /unit_2/review_1/functions.js: -------------------------------------------------------------------------------- 1 | // function addTwoNumbers(a, b) { 2 | // 3 | // } 4 | 5 | // I want you to add 3 + 7 and log it out 6 | // console.log(3 + 7); 7 | 8 | // I want you to add 6 + 7 and log it out 9 | // I want you to add 1 + 7 and log it out 10 | // I want you to add 2 + 7 and log it out 11 | // I want you to add 3 + 7 and log it out 12 | // I want you to add 0 + 7 and log it out 13 | // I want you to add 1 + 5 and log it out 14 | // I want you to add 4 + 6 and log it out 15 | // I want you to add 4 + 5 and log it out 16 | // console.log(3 + 7); 17 | // console.log(3 + 7); 18 | // console.log(3 + 7); 19 | // console.log(3 + 7); 20 | 21 | // Functions are intended to avoid this problem - we write code that works ONCE - but can be given different inputs to produce differing outputs by a consistent ruleset. 22 | 23 | const checkIfStringOrNumber = (aValue) => { 24 | return typeof aValue === 'string' || typeof aValue === 'number'; 25 | } 26 | 27 | // DRY - DONT REPEAT YOURSELF 28 | function addTwoNumbers(a, b) { 29 | if (checkIfStringOrNumber(a) && checkIfStringOrNumber(b)) { 30 | let realA = typeof a === 'string' ? parseInt(a) : a; 31 | let realB = typeof b === 'string' ? parseInt(b) : b; 32 | 33 | return realA + realB; 34 | } else { 35 | throw new Error(`Invalid arguments supplied. Arguments may only be strings or numbers.`); 36 | } 37 | } 38 | 39 | console.log(addTwoNumbers(2, 2)); 40 | 41 | // Hey, we have a client sending us strings instead of numbers, can you still add them? 42 | 43 | console.log(addTwoNumbers('2', '2')); 44 | 45 | // A client just sent us an array as an argument 46 | 47 | console.log(addTwoNumbers('2', ['elephant'])); 48 | -------------------------------------------------------------------------------- /unit_2/review_1/minesweeper.js: -------------------------------------------------------------------------------- 1 | /* 2 | [ 3 | [o o o o o] 4 | [o o o o o] 5 | [o o o o o] 6 | [o x o o o] 7 | [o o o o o] 8 | ] 9 | */ 10 | 11 | const createMinesweeperBoard = (height, width) => { 12 | const grid = []; 13 | 14 | for (let y = 0; y < height; ++y) { 15 | const row = []; 16 | 17 | for (let x = 0; x < width; ++x) { 18 | row.push('o'); 19 | } 20 | 21 | grid.push(row); 22 | } 23 | 24 | const randY = Math.floor(Math.random() * height); 25 | const randX = Math.floor(Math.random() * width); 26 | 27 | grid[randY][randX] = 'x'; 28 | 29 | return grid; 30 | } 31 | 32 | const minefield = createMinesweeperBoard(5, 5); 33 | 34 | console.log(minefield); 35 | 36 | // I am going to create a board of any size, with the 'o's in every position but 1. Return to me the x, y coordinates of the mine so that my troops dont hit it. 37 | 38 | function findMine(field) { 39 | for (let y = 0; y < field.length; ++y) { 40 | const row = field[y]; 41 | 42 | for (let x = 0; x < row.length; ++x) { 43 | const cell = row[x]; 44 | 45 | if (cell === 'x') { 46 | return [x, y]; 47 | } 48 | } 49 | } 50 | 51 | return 'Mine not found.'; 52 | } 53 | 54 | console.log(findMine(minefield)); 55 | -------------------------------------------------------------------------------- /unit_2/review_1/object_looping.js: -------------------------------------------------------------------------------- 1 | // Nested Object 2 | // Dictionary 3 | // An object keyed with strings. 4 | const questions = { 5 | onlyOdds: { 6 | difficulty: 2, 7 | }, 8 | crazyCaps: { 9 | difficulty: 4, 10 | }, 11 | }; 12 | 13 | for (let key in questions) { 14 | console.log(key); 15 | 16 | const value = questions[key]; 17 | 18 | console.log(value); 19 | } 20 | 21 | const keys = Object.keys(questions); 22 | console.log('Keys', keys); 23 | 24 | // for (let i = 0; i < keys.length; ++i) { 25 | // const key = keys[i]; 26 | // const value = questions[key]; 27 | // 28 | // console.log(`${key}: ${JSON.stringify(value, null, 2)}`); 29 | // } 30 | 31 | const values = Object.values(questions); 32 | console.log('Values', values); 33 | 34 | const entries = Object.entries(questions); 35 | console.log('Entries', entries); 36 | 37 | questions.mySlice = { 38 | difficulty: 3, 39 | }; 40 | 41 | questions['my-slice'] = { 42 | difficulty: 3, 43 | }; 44 | -------------------------------------------------------------------------------- /unit_2/review_2/freelancer_forum/forum.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | background-color: #2e2e31; 4 | color: whitesmoke; 5 | font-family: "Comic Sans MS"; 6 | } 7 | 8 | td { 9 | padding: 0 1em; 10 | text-align: center; 11 | } 12 | 13 | th { 14 | color: greenyellow; 15 | } 16 | 17 | main { 18 | width: 100vw; 19 | height: 100vh; 20 | overflow: hidden; 21 | display: flex; 22 | flex-direction: column; 23 | justify-content: flex-start; 24 | align-items: center; 25 | } 26 | 27 | #table_div { 28 | display: flex; 29 | flex-direction: column; 30 | align-items: center; 31 | overflow-y: scroll; 32 | flex-grow: 1; 33 | width: 100%; 34 | } 35 | 36 | #meta_div { 37 | display: flex; 38 | flex-direction: column; 39 | align-items: center; 40 | width: 60%; 41 | text-align: center; 42 | } 43 | 44 | #forum_container { 45 | max-height: 100%; 46 | width: 100%; 47 | display: flex; 48 | flex-direction: column; 49 | justify-content: flex-start; 50 | align-items: center; 51 | } 52 | -------------------------------------------------------------------------------- /unit_2/review_2/freelancer_forum/forum.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Freelancer Forum 4 | 5 | 6 | 7 | 8 |
9 |
10 |
11 |

Freelancer Forum

12 | Average Price 13 |
14 |

Available Freelancers

15 |
16 | 17 |
18 |
19 |
20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /unit_2/review_2/freelancer_forum/forum.js: -------------------------------------------------------------------------------- 1 | const state = { 2 | averagePrice: 50, 3 | freelancers: [ 4 | { 5 | name: 'Alice', 6 | occupation: 'Writer', 7 | price: 30, 8 | }, 9 | { 10 | name: 'Bob', 11 | occupation: 'Teacher', 12 | price: 50, 13 | }, 14 | { 15 | name: 'Carol', 16 | occupation: 'Programmer', 17 | price: 70, 18 | }, 19 | ], 20 | } 21 | 22 | // I update an average to display. 23 | function updateAveragePrice() { 24 | let total = 0; 25 | 26 | for (let i = 0; i < state.freelancers.length; ++i) { 27 | const currentFreelancer = state.freelancers[i]; 28 | 29 | total += currentFreelancer.price; 30 | } 31 | 32 | state.averagePrice = Math.round(total / state.freelancers.length); 33 | } 34 | 35 | function addFreelancerRow(freelancer) { 36 | state.freelancers.push(freelancer); 37 | } 38 | 39 | // You want functions that can create the different elements on your page. 40 | // I only create rows in this website. 41 | function createFreelancerTableRow(freelancer) { 42 | const tr = document.createElement('tr'); 43 | 44 | const nameData = document.createElement('td'); 45 | const occupationData = document.createElement('td'); 46 | const priceData = document.createElement('td'); 47 | 48 | nameData.textContent = freelancer.name; 49 | occupationData.textContent = freelancer.occupation; 50 | priceData.textContent = freelancer.price; 51 | 52 | tr.append(nameData, occupationData, priceData); 53 | 54 | return tr; 55 | } 56 | 57 | function createTableHeaders() { 58 | const tr = document.createElement('tr'); 59 | 60 | const nameData = document.createElement('th'); 61 | const occupationData = document.createElement('th'); 62 | const priceData = document.createElement('th'); 63 | 64 | nameData.textContent = 'Name'; 65 | occupationData.textContent = 'Occupation'; 66 | priceData.textContent = 'Starting Price'; 67 | 68 | tr.append(nameData, occupationData, priceData); 69 | 70 | return tr; 71 | } 72 | 73 | function clearTable() { 74 | const table = document.getElementById('freelancer_table'); 75 | 76 | while(table.childNodes.length) { 77 | table.removeChild(table.childNodes[0]); 78 | } 79 | } 80 | 81 | function render() { 82 | clearTable(); 83 | 84 | const table = document.getElementById('freelancer_table'); 85 | 86 | table.appendChild(createTableHeaders()); 87 | 88 | for (let i = 0; i < state.freelancers.length; ++i) { 89 | const currentFreelancer = state.freelancers[i]; 90 | 91 | const row = createFreelancerTableRow(currentFreelancer); 92 | 93 | table.appendChild(row); 94 | } 95 | 96 | updateAveragePrice(); 97 | 98 | const priceText = document.getElementById('average_price_text'); 99 | 100 | priceText.textContent = `The average starting price among our ${state.freelancers.length} freelancers is $${state.averagePrice}.`; 101 | } 102 | 103 | render(); 104 | 105 | const randomNames = ['Matt', 'Monica', 'Zi', 'Roy']; 106 | const randomJobs = ['IT', 'Chic-Fil-A', 'Construction', 'Lumberjack']; 107 | 108 | function createRandomFreelancer() { 109 | const randomName = randomNames[Math.floor(Math.random() * randomNames.length)]; 110 | const randomJob = randomJobs[Math.floor(Math.random() * randomJobs.length)]; 111 | 112 | const randomPrice = Math.round(Math.random() * 150); 113 | 114 | const freelancer = { 115 | name: randomName, 116 | occupation: randomJob, 117 | price: randomPrice, 118 | }; 119 | 120 | return freelancer; 121 | } 122 | 123 | let renderCount = 0; 124 | 125 | // Interval Logic 126 | let intervalID = setInterval(function() { 127 | if (renderCount > 250) { 128 | clearInterval(intervalID); 129 | } 130 | 131 | const newFreelancer = createRandomFreelancer(); 132 | addFreelancerRow(newFreelancer); 133 | 134 | render(); 135 | 136 | ++renderCount; 137 | }, 1000); 138 | -------------------------------------------------------------------------------- /unit_2/review_2/stretch.js: -------------------------------------------------------------------------------- 1 | // Write a function "writeObj" that takes an array, and writes every even index as a key, with the following odd index as its value to an object that it returns. 2 | 3 | const arrOfTrainersAndPokemon = ['Ash', 'Pikachu', 'Gary', 'Pidgey', 'Misty', 'Starmie']; 4 | 5 | function writeObj(arr) { 6 | const trainerObj = {}; 7 | 8 | for (let i = 0; i < arr.length; i += 2) { 9 | const key = arr[i] // 0 - 2 - 4 10 | const value = arr[i + 1] // 1 - 3 - 5 11 | 12 | trainerObj[key] = value; 13 | } 14 | 15 | return trainerObj; 16 | } 17 | 18 | const result = writeObj(arrOfTrainersAndPokemon); 19 | 20 | console.log(result); 21 | 22 | // => { 'Ash': 'Pikachu', 'Gary': 'Pidgey', 'Misty': 'Starmie' } 23 | -------------------------------------------------------------------------------- /unit_2/review_3/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 |
13 |
14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /unit_2/review_3/script.js: -------------------------------------------------------------------------------- 1 | const state = { 2 | dogs: [] 3 | } 4 | 5 | function card(imgSrc, header, subHeader) { 6 | const cardDiv = document.createElement('div'); 7 | cardDiv.classList.add('card'); 8 | 9 | const cardImg = document.createElement('img'); 10 | cardImg.setAttribute('src', imgSrc); 11 | cardImg.classList.add('card-img'); 12 | 13 | const cardHeader = document.createElement('p'); 14 | cardHeader.innerText = header; 15 | 16 | const cardSubheader = document.createElement('p'); 17 | cardSubheader.innerText = subHeader; 18 | 19 | cardDiv.append(cardImg); 20 | cardDiv.append(cardHeader); 21 | cardDiv.append(cardSubheader); 22 | return cardDiv; 23 | } 24 | 25 | async function getPuppyData() { 26 | try { 27 | const response = await fetch("https://dog.ceo/api/breeds/image/random"); 28 | const result = await response.json(); 29 | state.dogs.push(await result.message); 30 | } catch (error) { 31 | console.error("Error:", error); 32 | } 33 | } 34 | 35 | async function displayCards(){ 36 | for (let i = 0; i < 10; i++) { 37 | const dogCard = card(state.dogs[i], `dog: ${i + 1}`, 'aduioahsodiasoidhasoidhoasid'); 38 | document.getElementById('content-container').append(dogCard); 39 | } 40 | } 41 | 42 | function clearCards(){ 43 | document.getElementById('content-container').innerText = "

Cleared

"; 44 | // document.getElementById('content-container').classList.add('hide') 45 | } 46 | 47 | displayCards(); 48 | 49 | setTimeout(function () { 50 | clearCards(); 51 | }, 10000); 52 | 53 | -------------------------------------------------------------------------------- /unit_2/review_3/styles.css: -------------------------------------------------------------------------------- 1 | #content-container { 2 | display: flex; 3 | gap: 30px; 4 | flex-wrap: wrap; 5 | } 6 | 7 | .card { 8 | height: 400px; 9 | width: 300px; 10 | background-color: gray; 11 | padding: 10px; 12 | border-radius: 4px; 13 | } 14 | 15 | .card-img { 16 | height: 300px; 17 | width: 300px; 18 | border-radius: 4px; 19 | } 20 | 21 | .hide { 22 | display: none; 23 | } -------------------------------------------------------------------------------- /unit_3/block_24/jsx_intro.js: -------------------------------------------------------------------------------- 1 | const MyButton = () => { 2 | return ; 3 | } 4 | -------------------------------------------------------------------------------- /unit_3/block_26/hooks/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /unit_3/block_26/hooks/README.md: -------------------------------------------------------------------------------- 1 | # Getting Started with Create React App 2 | 3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 4 | 5 | ## Available Scripts 6 | 7 | In the project directory, you can run: 8 | 9 | ### `npm start` 10 | 11 | Runs the app in the development mode.\ 12 | Open [http://localhost:3000](http://localhost:3000) to view it in your browser. 13 | 14 | The page will reload when you make changes.\ 15 | You may also see any lint errors in the console. 16 | 17 | ### `npm test` 18 | 19 | Launches the test runner in the interactive watch mode.\ 20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 21 | 22 | ### `npm run build` 23 | 24 | Builds the app for production to the `build` folder.\ 25 | It correctly bundles React in production mode and optimizes the build for the best performance. 26 | 27 | The build is minified and the filenames include the hashes.\ 28 | Your app is ready to be deployed! 29 | 30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 31 | 32 | ### `npm run eject` 33 | 34 | **Note: this is a one-way operation. Once you `eject`, you can't go back!** 35 | 36 | If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 37 | 38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own. 39 | 40 | You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it. 41 | 42 | ## Learn More 43 | 44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 45 | 46 | To learn React, check out the [React documentation](https://reactjs.org/). 47 | 48 | ### Code Splitting 49 | 50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting) 51 | 52 | ### Analyzing the Bundle Size 53 | 54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size) 55 | 56 | ### Making a Progressive Web App 57 | 58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app) 59 | 60 | ### Advanced Configuration 61 | 62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration) 63 | 64 | ### Deployment 65 | 66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment) 67 | 68 | ### `npm run build` fails to minify 69 | 70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify) 71 | -------------------------------------------------------------------------------- /unit_3/block_26/hooks/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "forms", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.17.0", 7 | "@testing-library/react": "^13.4.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "react": "^18.2.0", 10 | "react-dom": "^18.2.0", 11 | "react-scripts": "5.0.1", 12 | "web-vitals": "^2.1.4" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "eslintConfig": { 21 | "extends": [ 22 | "react-app", 23 | "react-app/jest" 24 | ] 25 | }, 26 | "browserslist": { 27 | "production": [ 28 | ">0.2%", 29 | "not dead", 30 | "not op_mini all" 31 | ], 32 | "development": [ 33 | "last 1 chrome version", 34 | "last 1 firefox version", 35 | "last 1 safari version" 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /unit_3/block_26/hooks/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FullstackAcademy/2310-fsa-et-web-pt-sf-class-repo/a5f1225dc309f78bcbc2ef1e4d3d67065736e25a/unit_3/block_26/hooks/public/favicon.ico -------------------------------------------------------------------------------- /unit_3/block_26/hooks/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /unit_3/block_26/hooks/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FullstackAcademy/2310-fsa-et-web-pt-sf-class-repo/a5f1225dc309f78bcbc2ef1e4d3d67065736e25a/unit_3/block_26/hooks/public/logo192.png -------------------------------------------------------------------------------- /unit_3/block_26/hooks/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FullstackAcademy/2310-fsa-et-web-pt-sf-class-repo/a5f1225dc309f78bcbc2ef1e4d3d67065736e25a/unit_3/block_26/hooks/public/logo512.png -------------------------------------------------------------------------------- /unit_3/block_26/hooks/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /unit_3/block_26/hooks/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /unit_3/block_26/hooks/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /unit_3/block_26/hooks/src/App.js: -------------------------------------------------------------------------------- 1 | import logo from './logo.svg'; 2 | import { useState, useEffect } from 'react'; 3 | import './App.css'; 4 | import Beer from './components/Beer'; 5 | 6 | function App() { 7 | const [beers, setBeers] = useState([]); 8 | 9 | useEffect(()=> { 10 | async function getBeers() { 11 | const response = await fetch('https://api.punkapi.com/v2/beers'); 12 | const data = await response.json(); 13 | setBeers(data); 14 | } 15 | getBeers(); 16 | },[]) 17 | 18 | return ( 19 |
20 | {beers.map((beer) => 21 | 22 | )} 23 |
24 | ); 25 | } 26 | 27 | export default App; 28 | -------------------------------------------------------------------------------- /unit_3/block_26/hooks/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /unit_3/block_26/hooks/src/components/Beer.js: -------------------------------------------------------------------------------- 1 | // function Beer(props) { 2 | // return ( 3 | //
4 | //

{props.title}

5 | //

{props.desc}

6 | //
7 | // ); 8 | // } 9 | 10 | function Beer({ title, desc}) { 11 | return ( 12 |
13 |

{title}

14 |

{desc}

15 |
16 | ); 17 | } 18 | 19 | export default Beer; 20 | -------------------------------------------------------------------------------- /unit_3/block_26/hooks/src/index.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FullstackAcademy/2310-fsa-et-web-pt-sf-class-repo/a5f1225dc309f78bcbc2ef1e4d3d67065736e25a/unit_3/block_26/hooks/src/index.css -------------------------------------------------------------------------------- /unit_3/block_26/hooks/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | const root = ReactDOM.createRoot(document.getElementById('root')); 8 | root.render( 9 | 10 | 11 | 12 | ); 13 | 14 | // If you want to start measuring performance in your app, pass a function 15 | // to log results (for example: reportWebVitals(console.log)) 16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 17 | reportWebVitals(); 18 | -------------------------------------------------------------------------------- /unit_3/block_26/hooks/src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /unit_3/block_26/hooks/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /unit_3/block_26/hooks/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /unit_3/block_27/forms-jwt/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /unit_3/block_27/forms-jwt/README.md: -------------------------------------------------------------------------------- 1 | # Getting Started with Create React App 2 | 3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 4 | 5 | ## Available Scripts 6 | 7 | In the project directory, you can run: 8 | 9 | ### `npm start` 10 | 11 | Runs the app in the development mode.\ 12 | Open [http://localhost:3000](http://localhost:3000) to view it in your browser. 13 | 14 | The page will reload when you make changes.\ 15 | You may also see any lint errors in the console. 16 | 17 | ### `npm test` 18 | 19 | Launches the test runner in the interactive watch mode.\ 20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 21 | 22 | ### `npm run build` 23 | 24 | Builds the app for production to the `build` folder.\ 25 | It correctly bundles React in production mode and optimizes the build for the best performance. 26 | 27 | The build is minified and the filenames include the hashes.\ 28 | Your app is ready to be deployed! 29 | 30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 31 | 32 | ### `npm run eject` 33 | 34 | **Note: this is a one-way operation. Once you `eject`, you can't go back!** 35 | 36 | If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 37 | 38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own. 39 | 40 | You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it. 41 | 42 | ## Learn More 43 | 44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 45 | 46 | To learn React, check out the [React documentation](https://reactjs.org/). 47 | 48 | ### Code Splitting 49 | 50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting) 51 | 52 | ### Analyzing the Bundle Size 53 | 54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size) 55 | 56 | ### Making a Progressive Web App 57 | 58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app) 59 | 60 | ### Advanced Configuration 61 | 62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration) 63 | 64 | ### Deployment 65 | 66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment) 67 | 68 | ### `npm run build` fails to minify 69 | 70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify) 71 | -------------------------------------------------------------------------------- /unit_3/block_27/forms-jwt/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "forms-jwt", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.17.0", 7 | "@testing-library/react": "^13.4.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "react": "^18.2.0", 10 | "react-dom": "^18.2.0", 11 | "react-scripts": "5.0.1", 12 | "web-vitals": "^2.1.4" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "eslintConfig": { 21 | "extends": [ 22 | "react-app", 23 | "react-app/jest" 24 | ] 25 | }, 26 | "browserslist": { 27 | "production": [ 28 | ">0.2%", 29 | "not dead", 30 | "not op_mini all" 31 | ], 32 | "development": [ 33 | "last 1 chrome version", 34 | "last 1 firefox version", 35 | "last 1 safari version" 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /unit_3/block_27/forms-jwt/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FullstackAcademy/2310-fsa-et-web-pt-sf-class-repo/a5f1225dc309f78bcbc2ef1e4d3d67065736e25a/unit_3/block_27/forms-jwt/public/favicon.ico -------------------------------------------------------------------------------- /unit_3/block_27/forms-jwt/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /unit_3/block_27/forms-jwt/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FullstackAcademy/2310-fsa-et-web-pt-sf-class-repo/a5f1225dc309f78bcbc2ef1e4d3d67065736e25a/unit_3/block_27/forms-jwt/public/logo192.png -------------------------------------------------------------------------------- /unit_3/block_27/forms-jwt/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FullstackAcademy/2310-fsa-et-web-pt-sf-class-repo/a5f1225dc309f78bcbc2ef1e4d3d67065736e25a/unit_3/block_27/forms-jwt/public/logo512.png -------------------------------------------------------------------------------- /unit_3/block_27/forms-jwt/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /unit_3/block_27/forms-jwt/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /unit_3/block_27/forms-jwt/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /unit_3/block_27/forms-jwt/src/App.js: -------------------------------------------------------------------------------- 1 | import logo from './logo.svg'; 2 | import './App.css'; 3 | import { useState } from 'react'; 4 | import SignUp from './Components/SignUp'; 5 | import Login from './Components/Login'; 6 | function App() { 7 | const [token, setToken] = useState('') 8 | 9 | return ( 10 | <> 11 | {token} 12 | 13 | 14 | 15 | ); 16 | } 17 | 18 | export default App; 19 | -------------------------------------------------------------------------------- /unit_3/block_27/forms-jwt/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /unit_3/block_27/forms-jwt/src/Components/Login.js: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | 3 | function Login({ token }) { 4 | const [username, setUsername] = useState(''); 5 | const [iat, setIAT] = useState(''); 6 | async function handleLogin() { 7 | const response = await fetch('https://fsa-jwt-practice.herokuapp.com/authenticate', 8 | { 9 | method: "GET", 10 | headers: { 11 | "Content-Type": "application/json", 12 | "Authorization": `Bearer ${token}` 13 | } 14 | }) 15 | const { data } = await response.json(); 16 | console.log(data) 17 | setUsername(data.username); 18 | setIAT(data.iat); 19 | } 20 | 21 | return ( 22 |
23 | 24 |

Username: {username}

25 |

IAM: {iat}

26 |
27 | ); 28 | } 29 | 30 | export default Login; 31 | -------------------------------------------------------------------------------- /unit_3/block_27/forms-jwt/src/Components/SignUp.js: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | function SignUp({ setToken }) { 3 | const [username, setUsername] = useState('') 4 | const [password, setPassword] = useState('') 5 | 6 | async function handleFormSubmit(e) { 7 | e.preventDefault(); 8 | const response = await fetch('https://fsa-jwt-practice.herokuapp.com/signup', 9 | { 10 | method: "POST", 11 | headers: { 12 | "Content-Type": "application/json" 13 | }, 14 | body: JSON.stringify({ 15 | username: username, 16 | password: password 17 | }) 18 | }) 19 | const data = await response.json(); 20 | setToken(data.token); 21 | } 22 | 23 | return ( 24 |
handleFormSubmit(e)}> 25 | setUsername(e.target.value)} /> 26 | setPassword(e.target.value)} /> 27 | 28 |
29 | ); 30 | } 31 | 32 | export default SignUp; 33 | -------------------------------------------------------------------------------- /unit_3/block_27/forms-jwt/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /unit_3/block_27/forms-jwt/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | const root = ReactDOM.createRoot(document.getElementById('root')); 8 | root.render( 9 | 10 | 11 | 12 | ); 13 | 14 | // If you want to start measuring performance in your app, pass a function 15 | // to log results (for example: reportWebVitals(console.log)) 16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 17 | reportWebVitals(); 18 | -------------------------------------------------------------------------------- /unit_3/block_27/forms-jwt/src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /unit_3/block_27/forms-jwt/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /unit_3/block_27/forms-jwt/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /unit_3/block_27B/README.md: -------------------------------------------------------------------------------- 1 | Quick Review of React 2 | 3 | useState 4 | 5 | in a counter component 6 | const [count, setCount] = useState(0); 7 | this is where we keep dynamic pieces of data within our component 8 | 9 | 10 | Props pass data from one component to another 11 | 12 | useEffect uses a conditional based on which states have updated or changed 13 | we call a function based on those states changed 14 | 15 | When does a component rerender? 16 | When the state or props change the parent component and its children will also rerender 17 | -------------------------------------------------------------------------------- /unit_3/block_27B/immutability-example/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { browser: true, es2020: true }, 4 | extends: [ 5 | 'eslint:recommended', 6 | 'plugin:react/recommended', 7 | 'plugin:react/jsx-runtime', 8 | 'plugin:react-hooks/recommended', 9 | ], 10 | ignorePatterns: ['dist', '.eslintrc.cjs'], 11 | parserOptions: { ecmaVersion: 'latest', sourceType: 'module' }, 12 | settings: { react: { version: '18.2' } }, 13 | plugins: ['react-refresh'], 14 | rules: { 15 | 'react-refresh/only-export-components': [ 16 | 'warn', 17 | { allowConstantExport: true }, 18 | ], 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /unit_3/block_27B/immutability-example/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /unit_3/block_27B/immutability-example/README.md: -------------------------------------------------------------------------------- 1 | # React + Vite 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. 4 | 5 | Currently, two official plugins are available: 6 | 7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh 8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 9 | -------------------------------------------------------------------------------- /unit_3/block_27B/immutability-example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /unit_3/block_27B/immutability-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "immutability-example", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "react": "^18.2.0", 14 | "react-dom": "^18.2.0" 15 | }, 16 | "devDependencies": { 17 | "@types/react": "^18.2.43", 18 | "@types/react-dom": "^18.2.17", 19 | "@vitejs/plugin-react": "^4.2.1", 20 | "eslint": "^8.55.0", 21 | "eslint-plugin-react": "^7.33.2", 22 | "eslint-plugin-react-hooks": "^4.6.0", 23 | "eslint-plugin-react-refresh": "^0.4.5", 24 | "vite": "^5.0.8" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /unit_3/block_27B/immutability-example/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /unit_3/block_27B/immutability-example/src/App.jsx: -------------------------------------------------------------------------------- 1 | import { useState } from 'react' 2 | 3 | function App() { 4 | const [names, setNames] = useState(["Thomas The Train", "Jeremy Lin", "Casper"]); 5 | const [name, setName] = useState(""); 6 | 7 | return ( 8 | <> 9 |
{ 10 | // to grab the name inside of names 11 | // push the name into the array of names 12 | event.preventDefault(); 13 | //immutability 14 | //names values and expect it to be reflected within the state 15 | //we need to set the state to a new object/array 16 | const newArray = [...names, name]; 17 | setNames(newArray); 18 | }}> 19 | 23 | 24 |
25 | { 26 | names.map((name) => { 27 | return
{name}
28 | }) 29 | } 30 | 31 | 32 | ) 33 | } 34 | 35 | export default App 36 | -------------------------------------------------------------------------------- /unit_3/block_27B/immutability-example/src/Example.jsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FullstackAcademy/2310-fsa-et-web-pt-sf-class-repo/a5f1225dc309f78bcbc2ef1e4d3d67065736e25a/unit_3/block_27B/immutability-example/src/Example.jsx -------------------------------------------------------------------------------- /unit_3/block_27B/immutability-example/src/main.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App.jsx' 4 | 5 | ReactDOM.createRoot(document.getElementById('root')).render( 6 | 7 | 8 | , 9 | ) 10 | -------------------------------------------------------------------------------- /unit_3/block_27B/immutability-example/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | -------------------------------------------------------------------------------- /unit_3/block_27B/pokemon-example/README.md: -------------------------------------------------------------------------------- 1 | # React + Vite 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. 4 | 5 | Currently, two official plugins are available: 6 | 7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh 8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 9 | -------------------------------------------------------------------------------- /unit_3/block_27B/pokemon-example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /unit_3/block_27B/pokemon-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "material-ui-class", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "@emotion/react": "^11.11.3", 14 | "@emotion/styled": "^11.11.0", 15 | "@mui/icons-material": "^5.15.3", 16 | "@mui/material": "^5.15.3", 17 | "react": "^18.2.0", 18 | "react-dom": "^18.2.0" 19 | }, 20 | "devDependencies": { 21 | "@types/react": "^18.2.43", 22 | "@types/react-dom": "^18.2.17", 23 | "@vitejs/plugin-react": "^4.2.1", 24 | "eslint": "^8.55.0", 25 | "eslint-plugin-react": "^7.33.2", 26 | "eslint-plugin-react-hooks": "^4.6.0", 27 | "eslint-plugin-react-refresh": "^0.4.5", 28 | "vite": "^5.0.8" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /unit_3/block_27B/pokemon-example/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /unit_3/block_27B/pokemon-example/src/App.jsx: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from 'react'; 2 | 3 | function App() { 4 | const [pokemon, setPokemon] = useState(null); 5 | const [isLoading, setIsLoading] = useState(false); 6 | 7 | const handlePokemon = async () => { 8 | setIsLoading(true); 9 | const res = await fetch("https://pokeapi.co/api/v2/pokemon/1"); 10 | const data = await res.json(); 11 | console.log(data); 12 | setPokemon(data); 13 | }; 14 | 15 | useEffect(() => { 16 | handlePokemon(); 17 | }, []); 18 | 19 | //this concept appears often when we fetching/async functions 20 | // 21 | 22 | //guard clause 23 | if (isLoading) { 24 | return (
25 | waiting for pokemon 26 |
) 27 | } 28 | 29 | return ( 30 |
31 |

{pokemon.name}

32 | 33 |
34 | ) 35 | } 36 | 37 | export default App 38 | -------------------------------------------------------------------------------- /unit_3/block_27B/pokemon-example/src/main.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App.jsx' 4 | 5 | ReactDOM.createRoot(document.getElementById('root')).render( 6 | 7 | 8 | , 9 | ) 10 | -------------------------------------------------------------------------------- /unit_3/block_27B/pokemon-example/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | -------------------------------------------------------------------------------- /unit_3/block_27B/prop-drilling-example/App.jsx: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | 3 | function ContactRow({ contact }) { 4 | return ( 5 | 6 | {contact.name} 7 | {contact.email} 8 | {contact.phone} 9 | 10 | ); 11 | } 12 | 13 | function ContactList({ contacts }) { 14 | 15 | return ( 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | {error ? ( 29 | {error} 30 | ) : ( 31 | contacts.map((contact) => { 32 | return ( 33 | 37 | ); 38 | }) 39 | )} 40 | 41 |
Contact List
NamePhoneEmail
42 | ); 43 | } 44 | 45 | function App() { 46 | const [contacts, setContacts] = useState([]); 47 | 48 | return ( 49 |
50 | 53 |
54 | ); 55 | } 56 | -------------------------------------------------------------------------------- /unit_3/block_27B/redux-example/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { browser: true, es2020: true }, 4 | extends: [ 5 | 'eslint:recommended', 6 | 'plugin:react/recommended', 7 | 'plugin:react/jsx-runtime', 8 | 'plugin:react-hooks/recommended', 9 | ], 10 | ignorePatterns: ['dist', '.eslintrc.cjs'], 11 | parserOptions: { ecmaVersion: 'latest', sourceType: 'module' }, 12 | settings: { react: { version: '18.2' } }, 13 | plugins: ['react-refresh'], 14 | rules: { 15 | 'react-refresh/only-export-components': [ 16 | 'warn', 17 | { allowConstantExport: true }, 18 | ], 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /unit_3/block_27B/redux-example/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /unit_3/block_27B/redux-example/README.md: -------------------------------------------------------------------------------- 1 | # React + Vite 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. 4 | 5 | Currently, two official plugins are available: 6 | 7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh 8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 9 | -------------------------------------------------------------------------------- /unit_3/block_27B/redux-example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /unit_3/block_27B/redux-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "redux-example", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "@reduxjs/toolkit": "^2.0.1", 14 | "react": "^18.2.0", 15 | "react-dom": "^18.2.0", 16 | "react-redux": "^9.0.4" 17 | }, 18 | "devDependencies": { 19 | "@types/react": "^18.2.43", 20 | "@types/react-dom": "^18.2.17", 21 | "@vitejs/plugin-react": "^4.2.1", 22 | "eslint": "^8.55.0", 23 | "eslint-plugin-react": "^7.33.2", 24 | "eslint-plugin-react-hooks": "^4.6.0", 25 | "eslint-plugin-react-refresh": "^0.4.5", 26 | "vite": "^5.0.8" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /unit_3/block_27B/redux-example/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /unit_3/block_27B/redux-example/src/App.jsx: -------------------------------------------------------------------------------- 1 | import { useDispatch, useSelector } from "react-redux" 2 | import { increment, decrement, reset } from "./features/counter/counterSlice" 3 | 4 | function App() { 5 | const dispatch = useDispatch(); 6 | const count = useSelector((state) => state.counter.count) 7 | 8 | return ( 9 |
10 |

Counter Example

11 |
Count: {count}
12 | 13 | 14 | 15 |
16 | ) 17 | } 18 | 19 | export default App 20 | -------------------------------------------------------------------------------- /unit_3/block_27B/redux-example/src/app/store.js: -------------------------------------------------------------------------------- 1 | import { configureStore } from "@reduxjs/toolkit"; 2 | import counterReducer from '../features/counter/counterSlice'; 3 | 4 | const store = configureStore({ 5 | reducer: { 6 | counter: counterReducer 7 | } 8 | }); 9 | 10 | export default store; 11 | -------------------------------------------------------------------------------- /unit_3/block_27B/redux-example/src/features/counter/counterSlice.js: -------------------------------------------------------------------------------- 1 | import { createSlice } from "@reduxjs/toolkit"; 2 | 3 | const initialState = { 4 | count: 0 5 | } 6 | 7 | const counterSlice = createSlice({ 8 | name: "counter", 9 | initialState, 10 | reducers: { 11 | //type of actions that are related to this specific feature 12 | increment: (state) => { 13 | state.count++; 14 | }, 15 | decrement: (state) => { 16 | if (state.count === 0) return; 17 | state.count--; 18 | }, 19 | reset: (state) => { 20 | state.count = 0; 21 | } 22 | } 23 | }) 24 | 25 | export const { increment, decrement, reset } = counterSlice.actions; 26 | 27 | export default counterSlice.reducer; 28 | -------------------------------------------------------------------------------- /unit_3/block_27B/redux-example/src/main.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App.jsx' 4 | import { Provider } from 'react-redux' 5 | import store from './app/store.js' 6 | 7 | ReactDOM.createRoot(document.getElementById('root')).render( 8 | 9 | 10 | 11 | 12 | , 13 | ) 14 | -------------------------------------------------------------------------------- /unit_3/block_27B/redux-example/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | -------------------------------------------------------------------------------- /unit_3/review_1/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /unit_3/review_1/README.md: -------------------------------------------------------------------------------- 1 | # Getting Started with Create React App 2 | 3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 4 | 5 | ## Available Scripts 6 | 7 | In the project directory, you can run: 8 | 9 | ### `npm start` 10 | 11 | Runs the app in the development mode.\ 12 | Open [http://localhost:3000](http://localhost:3000) to view it in your browser. 13 | 14 | The page will reload when you make changes.\ 15 | You may also see any lint errors in the console. 16 | 17 | ### `npm test` 18 | 19 | Launches the test runner in the interactive watch mode.\ 20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 21 | 22 | ### `npm run build` 23 | 24 | Builds the app for production to the `build` folder.\ 25 | It correctly bundles React in production mode and optimizes the build for the best performance. 26 | 27 | The build is minified and the filenames include the hashes.\ 28 | Your app is ready to be deployed! 29 | 30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 31 | 32 | ### `npm run eject` 33 | 34 | **Note: this is a one-way operation. Once you `eject`, you can't go back!** 35 | 36 | If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 37 | 38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own. 39 | 40 | You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it. 41 | 42 | ## Learn More 43 | 44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 45 | 46 | To learn React, check out the [React documentation](https://reactjs.org/). 47 | 48 | ### Code Splitting 49 | 50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting) 51 | 52 | ### Analyzing the Bundle Size 53 | 54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size) 55 | 56 | ### Making a Progressive Web App 57 | 58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app) 59 | 60 | ### Advanced Configuration 61 | 62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration) 63 | 64 | ### Deployment 65 | 66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment) 67 | 68 | ### `npm run build` fails to minify 69 | 70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify) 71 | -------------------------------------------------------------------------------- /unit_3/review_1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "review_1", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.17.0", 7 | "@testing-library/react": "^13.4.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "bootstrap": "^5.3.2", 10 | "react": "^18.2.0", 11 | "react-bootstrap": "^2.9.2", 12 | "react-dom": "^18.2.0", 13 | "react-scripts": "5.0.1", 14 | "web-vitals": "^2.1.4" 15 | }, 16 | "scripts": { 17 | "start": "react-scripts start", 18 | "build": "react-scripts build", 19 | "test": "react-scripts test", 20 | "eject": "react-scripts eject" 21 | }, 22 | "eslintConfig": { 23 | "extends": [ 24 | "react-app", 25 | "react-app/jest" 26 | ] 27 | }, 28 | "browserslist": { 29 | "production": [ 30 | ">0.2%", 31 | "not dead", 32 | "not op_mini all" 33 | ], 34 | "development": [ 35 | "last 1 chrome version", 36 | "last 1 firefox version", 37 | "last 1 safari version" 38 | ] 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /unit_3/review_1/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FullstackAcademy/2310-fsa-et-web-pt-sf-class-repo/a5f1225dc309f78bcbc2ef1e4d3d67065736e25a/unit_3/review_1/public/favicon.ico -------------------------------------------------------------------------------- /unit_3/review_1/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /unit_3/review_1/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FullstackAcademy/2310-fsa-et-web-pt-sf-class-repo/a5f1225dc309f78bcbc2ef1e4d3d67065736e25a/unit_3/review_1/public/logo192.png -------------------------------------------------------------------------------- /unit_3/review_1/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FullstackAcademy/2310-fsa-et-web-pt-sf-class-repo/a5f1225dc309f78bcbc2ef1e4d3d67065736e25a/unit_3/review_1/public/logo512.png -------------------------------------------------------------------------------- /unit_3/review_1/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /unit_3/review_1/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /unit_3/review_1/src/App.css: -------------------------------------------------------------------------------- 1 | .todo-container { 2 | background-color: beige; 3 | height: 100vh; 4 | width: 100vw; 5 | display: flex; 6 | flex-direction: column; 7 | align-items: center; 8 | } 9 | 10 | .addTodo-container { 11 | display: flex; 12 | flex-direction: column; 13 | width: 400px; 14 | gap: 10px; 15 | } 16 | 17 | .listItem-container { 18 | display: flex; 19 | background-color: white; 20 | width: 500px; 21 | justify-content: space-between; 22 | align-items: center; 23 | padding: 10px; 24 | border-radius: 10px; 25 | margin-top: 10px; 26 | } 27 | 28 | .completed { 29 | text-decoration: line-through; 30 | } -------------------------------------------------------------------------------- /unit_3/review_1/src/App.js: -------------------------------------------------------------------------------- 1 | import './App.css'; 2 | import { useState } from 'react'; 3 | import AddTodo from './components/AddTodo'; 4 | import ListItem from './components/ListItem'; 5 | import { notes } from './utils/dummyData'; 6 | function App() { 7 | const [todos, setTodos] = useState(notes); 8 | return ( 9 |
10 |

Todo List

11 | 12 |
13 | {todos.map((note) => 14 | 18 | )} 19 |
20 |
21 | ); 22 | } 23 | 24 | export default App; 25 | -------------------------------------------------------------------------------- /unit_3/review_1/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /unit_3/review_1/src/components/AddTodo.js: -------------------------------------------------------------------------------- 1 | import Button from 'react-bootstrap/Button'; 2 | import { useState } from 'react'; 3 | 4 | function AddTodo({ setTodos, todos }) { 5 | const [todo, setTodo] = useState(''); 6 | function handleAddTodo() { 7 | const updatedTodos = [...todos]; 8 | updatedTodos.push(todo); 9 | setTodos(updatedTodos); 10 | setTodo(''); 11 | } 12 | return ( 13 |
14 |

Add Todo

15 | setTodo(e.target.value)} type='text' placeholder='Add a new todo' value={todo} /> 16 | 17 |
18 | ) 19 | } 20 | 21 | export default AddTodo; 22 | -------------------------------------------------------------------------------- /unit_3/review_1/src/components/ListItem.js: -------------------------------------------------------------------------------- 1 | import Button from 'react-bootstrap/Button'; 2 | import { useState } from 'react'; 3 | 4 | function ListItem({ note, setTodos, todos }) { 5 | const [isCompleted, setIsCompleted] = useState(false); 6 | function handleDelete() { 7 | const updatedTodos = todos.filter((todo) => todo !== note); 8 | setTodos(updatedTodos); 9 | } 10 | return ( 11 |
12 |

{note}

13 |
14 | 15 | 16 |
17 |
18 | ) 19 | } 20 | 21 | export default ListItem; 22 | -------------------------------------------------------------------------------- /unit_3/review_1/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /unit_3/review_1/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | import 'bootstrap/dist/css/bootstrap.min.css'; 7 | const root = ReactDOM.createRoot(document.getElementById('root')); 8 | root.render( 9 | 10 | 11 | 12 | ); 13 | 14 | // If you want to start measuring performance in your app, pass a function 15 | // to log results (for example: reportWebVitals(console.log)) 16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 17 | reportWebVitals(); 18 | -------------------------------------------------------------------------------- /unit_3/review_1/src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /unit_3/review_1/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /unit_3/review_1/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /unit_3/review_1/src/utils/dummyData.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | notes: ['This is a sample todo', '2nd todo', 'do something new', 'next todo'], 3 | } -------------------------------------------------------------------------------- /unit_4/block_31/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | HomePage 7 | 8 | 9 |

Welcome to our homepage

10 | 11 | -------------------------------------------------------------------------------- /unit_4/block_31/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "unit_4", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "nodemon server.js" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "express": "^4.18.2", 14 | "nodemon": "^3.0.3" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /unit_4/block_31/server.js: -------------------------------------------------------------------------------- 1 | const express = require('express') 2 | const path = require('path'); 3 | const app = express() 4 | const port = 8080; 5 | const students = ['Midhat', "Matt", "Stephen", "Andrew", "Troy", "michell"]; 6 | 7 | app.get('/', function(req,res){ 8 | res.sendFile(path.join(__dirname, '/index.html')); 9 | }) 10 | 11 | app.get('/students', function(req,res){ 12 | console.log(req.query.student); 13 | res.sendFile(path.join(__dirname, '/students.html')); 14 | }) 15 | 16 | app.get('/api/names', function (req, res) { 17 | res.json(students) 18 | }) 19 | 20 | app.post('/api/name/:studentName', function (req, res) { 21 | const studentName = req.params.studentName; 22 | students.push(studentName); 23 | return res.sendStatus(200); 24 | }) 25 | 26 | app.put('/api/update/:oldName/:newName', function (req, res) { 27 | const oldName = req.params.oldName; 28 | const newName = req.params.newName; 29 | const oldNameIndex = students.indexOf(oldName); 30 | students[oldNameIndex] = newName; 31 | return res.sendStatus(200); 32 | }) 33 | 34 | app.delete('/api/remove/student', function (req, res) { 35 | students.pop(); 36 | return res.sendStatus(200); 37 | }) 38 | 39 | app.listen(port) -------------------------------------------------------------------------------- /unit_4/block_31/students.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Students 7 | 8 | 9 |

Students

10 | 11 | 12 | 21 | 22 | -------------------------------------------------------------------------------- /unit_4/block_31/topics.md: -------------------------------------------------------------------------------- 1 | # Block 31 Topics 2 | 3 | - Node.js - enables us to run javascript code without a browser 4 | - Express.js - npm package that allows developer to create a server 5 | - CRUD (Create Read Update Delete) 6 | - API Routes (res.json) 7 | - HTML Routes (res.sendFile) 8 | - HTTP Methods 9 | - GET 10 | - POST 11 | - PUT 12 | - PATCH 13 | - DELETE 14 | - URL params (req.params) 15 | - Query params (req.query) 16 | -------------------------------------------------------------------------------- /unit_4/block_33/.env: -------------------------------------------------------------------------------- 1 | USER=michell 2 | HOST=localhost 3 | DATABASE=block_33 4 | PASSWORD="" -------------------------------------------------------------------------------- /unit_4/block_33/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "block_33", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "server.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node server.js" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "bcrypt": "^5.1.1", 14 | "dotenv": "^16.4.1", 15 | "express": "^4.18.2", 16 | "jsonwebtoken": "^9.0.2", 17 | "pg": "^8.11.3" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /unit_4/block_33/server.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const { Pool } = require('pg'); 3 | const jwt = require('jsonwebtoken'); 4 | const bcrypt = require('bcrypt'); 5 | require('dotenv').config() 6 | const app = express(); 7 | const port = 3000; 8 | 9 | const pool = new Pool({ 10 | user: process.env.USER, 11 | host: process.env.HOST, 12 | database: process.env.DATABASE, 13 | password: process.env.PASSWORD, 14 | port: 5432, 15 | }); 16 | 17 | app.use(express.json()); 18 | 19 | app.post('/register', async (req, res) => { 20 | const { username, password } = req.body; 21 | try { 22 | if (!username || !password) { 23 | return res.status(401).json({ error: 'Missing credentials' }); 24 | } 25 | const salt = await bcrypt.genSalt(10); 26 | const hashedPassword = await bcrypt.hash(password, salt); 27 | 28 | const newUser = await pool.query('INSERT INTO users (username, password_hash) VALUES ($1, $2) RETURNING *', [username, hashedPassword]); 29 | 30 | res.status(201).json({ user: newUser.rows[0] }); 31 | } catch (error) { 32 | console.log(error.message) 33 | res.status(500).send(error.message); 34 | } 35 | }); 36 | 37 | app.post('/login', async (req, res) => { 38 | const { username, password } = req.body; 39 | try { 40 | const userResult = await pool.query('SELECT * FROM users WHERE username = $1', [username]); 41 | 42 | if (userResult.rows.length === 0) { 43 | return res.status(401).json({ error: 'Invalid credentials' }); 44 | } 45 | 46 | const user = userResult.rows[0]; 47 | 48 | const passwordMatch = await bcrypt.compare(password, user.password_hash); 49 | 50 | if (!passwordMatch) { 51 | return res.status(401).json({ error: 'Invalid credentials' }); 52 | } 53 | 54 | const token = jwt.sign({ user_id: user.user_id }, 'your_jwt_secret', { expiresIn: '1h' }); 55 | 56 | res.json({ token }); 57 | } catch (error) { 58 | res.status(500).send('Internal Server Error'); 59 | } 60 | }); 61 | 62 | app.post('/api/breed', async (req, res) => { 63 | try { 64 | const { breed, numOfLegs } = req.body; 65 | await pool.query('INSERT INTO ANIMALS (breed, numOfLegs) VALUES ($1, $2)', [breed, numOfLegs]); 66 | res.status(200).send('breed created!'); 67 | } catch (err) { 68 | res.status(500).send(err); 69 | } 70 | }); 71 | 72 | app.get('/api/breeds', async (req, res) => { 73 | try { 74 | const animals = await pool.query('SELECT * FROM ANIMALS'); 75 | res.status(200).send(animals.rows); 76 | } catch (err) { 77 | res.status(500).send(err); 78 | } 79 | }); 80 | 81 | app.delete('/api/breed/:breed', async (req, res) => { 82 | try { 83 | await pool.query('DELETE FROM ANIMALS WHERE breed = $1', [req.params.breed]); 84 | res.status(200).send(`${req.params.breed} was deleted!`); 85 | } catch (err) { 86 | res.status(500).send(err); 87 | } 88 | }); 89 | 90 | app.patch('/api/breed', async (req, res) => { 91 | const { id, newValue } = req.body 92 | try { 93 | await pool.query('UPDATE ANIMALS SET breed = $1 WHERE breed = $2', [newValue, id]); 94 | res.status(200).send(`${id} was updated!`); 95 | } catch (err) { 96 | res.status(500).send(err); 97 | } 98 | }); 99 | 100 | app.listen(port, () => { 101 | console.log(`Server is running on - http://localhost:${port}`); 102 | }); 103 | -------------------------------------------------------------------------------- /unit_4/block_33/topics.md: -------------------------------------------------------------------------------- 1 | # Block 33 Topics 2 | 3 | - PK, FK 4 | - Tables 5 | - Queries (SELECT, INSERT, DELETE, UPDATE) 6 | - Joins 7 | -------------------------------------------------------------------------------- /unit_4/block_34/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | # Keep environment variables out of version control 3 | .env 4 | -------------------------------------------------------------------------------- /unit_4/block_34/commands.md: -------------------------------------------------------------------------------- 1 | 1. npm install prisma typescript ts-node @types/node --save-dev 2 | 2. npx tsc --init 3 | 3. npx prisma 4 | 4. npx prisma init 5 | 5. npx prisma migrate dev --name init 6 | 6. npm install @prisma/client 7 | 8 | https://www.prisma.io/docs/getting-started/setup-prisma/start-from-scratch/relational-databases-typescript-postgresql -------------------------------------------------------------------------------- /unit_4/block_34/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "block_34", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "@types/node": "^20.11.17", 13 | "prisma": "^5.9.1", 14 | "ts-node": "^10.9.2", 15 | "typescript": "^5.3.3" 16 | }, 17 | "dependencies": { 18 | "@prisma/client": "^5.9.1", 19 | "dotenv": "^16.4.3", 20 | "express": "^4.18.2" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /unit_4/block_34/prisma/migrations/20240212234016_init/migration.sql: -------------------------------------------------------------------------------- 1 | -- CreateTable 2 | CREATE TABLE "User" ( 3 | "id" SERIAL NOT NULL, 4 | "email" TEXT NOT NULL, 5 | "name" TEXT, 6 | 7 | CONSTRAINT "User_pkey" PRIMARY KEY ("id") 8 | ); 9 | 10 | -- CreateTable 11 | CREATE TABLE "Post" ( 12 | "id" SERIAL NOT NULL, 13 | "title" TEXT NOT NULL, 14 | "content" TEXT, 15 | "published" BOOLEAN NOT NULL DEFAULT false, 16 | "authorId" INTEGER NOT NULL, 17 | 18 | CONSTRAINT "Post_pkey" PRIMARY KEY ("id") 19 | ); 20 | 21 | -- CreateIndex 22 | CREATE UNIQUE INDEX "User_email_key" ON "User"("email"); 23 | 24 | -- AddForeignKey 25 | ALTER TABLE "Post" ADD CONSTRAINT "Post_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; 26 | -------------------------------------------------------------------------------- /unit_4/block_34/prisma/migrations/migration_lock.toml: -------------------------------------------------------------------------------- 1 | # Please do not edit this file manually 2 | # It should be added in your version-control system (i.e. Git) 3 | provider = "postgresql" -------------------------------------------------------------------------------- /unit_4/block_34/prisma/schema.prisma: -------------------------------------------------------------------------------- 1 | // This is your Prisma schema file, 2 | // learn more about it in the docs: https://pris.ly/d/prisma-schema 3 | 4 | generator client { 5 | provider = "prisma-client-js" 6 | } 7 | 8 | datasource db { 9 | provider = "postgresql" 10 | url = "postgresql://michell:@localhost:5432/block_34?schema=public" 11 | } 12 | 13 | model User { 14 | id Int @id @default(autoincrement()) 15 | email String @unique 16 | name String? 17 | posts Post[] 18 | } 19 | 20 | model Post { 21 | id Int @id @default(autoincrement()) 22 | title String 23 | content String? 24 | published Boolean @default(false) 25 | author User @relation(fields: [authorId], references: [id]) 26 | authorId Int 27 | } -------------------------------------------------------------------------------- /unit_4/block_34/server.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | require("dotenv").config(); 3 | const app = express(); 4 | const port = 3000; 5 | const { PrismaClient } = require("@prisma/client"); 6 | const prisma = new PrismaClient(); 7 | 8 | app.use(express.json()); 9 | 10 | app.post("/api/register", async (req, res) => { 11 | try { 12 | await prisma.user.create({ 13 | data: req.body, 14 | }); 15 | res.status(201).send("user created"); 16 | } catch (error) { 17 | console.log(error.message); 18 | res.status(500).send(error.message); 19 | } 20 | }); 21 | 22 | app.get("/api/users", async (req, res) => { 23 | try { 24 | const users = await prisma.user.findMany(); 25 | res.status(201).json(users); 26 | } catch (error) { 27 | console.log(error.message); 28 | res.status(500).send(error.message); 29 | } 30 | }); 31 | 32 | app.listen(port, () => { 33 | console.log(`Server is running on - http://localhost:${port}`); 34 | }); 35 | -------------------------------------------------------------------------------- /unit_4/block_34/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ 9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ 10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 | 13 | /* Language and Environment */ 14 | "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 16 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 17 | // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ 18 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ 20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ 22 | // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ 23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 25 | // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ 26 | 27 | /* Modules */ 28 | "module": "commonjs", /* Specify what module code is generated. */ 29 | // "rootDir": "./", /* Specify the root folder within your source files. */ 30 | // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ 31 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 32 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 33 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 34 | // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ 35 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 36 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 37 | // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ 38 | // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ 39 | // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ 40 | // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ 41 | // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ 42 | // "resolveJsonModule": true, /* Enable importing .json files. */ 43 | // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ 44 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ 45 | 46 | /* JavaScript Support */ 47 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ 48 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 49 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ 50 | 51 | /* Emit */ 52 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 53 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 54 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 55 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 56 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 57 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ 58 | // "outDir": "./", /* Specify an output folder for all emitted files. */ 59 | // "removeComments": true, /* Disable emitting comments. */ 60 | // "noEmit": true, /* Disable emitting files from a compilation. */ 61 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 62 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ 63 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 64 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 65 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 66 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 67 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 68 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 69 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ 70 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ 71 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 72 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ 73 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 74 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 75 | 76 | /* Interop Constraints */ 77 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 78 | // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ 79 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 80 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ 81 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 82 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 83 | 84 | /* Type Checking */ 85 | "strict": true, /* Enable all strict type-checking options. */ 86 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ 87 | // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ 88 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 89 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ 90 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 91 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ 92 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ 93 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 94 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ 95 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ 96 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 97 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 98 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 99 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ 100 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 101 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ 102 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 103 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 104 | 105 | /* Completeness */ 106 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 107 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /unit_4/block_34B/.env: -------------------------------------------------------------------------------- 1 | GITHUB_CLIENT_ID=Iv1.dc4454df770a8026 2 | GITHUB_CLIENT_SECRET=f1908d85917bfbb3aeafb4f4459ed8fe31c32768 3 | -------------------------------------------------------------------------------- /unit_4/block_34B/github.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /unit_4/block_34B/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "block_34b", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "axios": "^1.6.7", 13 | "dotenv": "^16.4.4", 14 | "express": "^4.18.2", 15 | "octokit": "^3.1.2" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /unit_4/block_34B/server.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config(); 2 | const express = require('express'); 3 | const axios = require('axios'); 4 | const { Octokit } = require('octokit'); 5 | const app = express(); 6 | 7 | const CLIENT_ID = process.env.GITHUB_CLIENT_ID; 8 | const CLIENT_SECRET = process.env.GITHUB_CLIENT_SECRET; 9 | 10 | app.get('/', (req, res) => { 11 | res.send('Login with GitHub'); 12 | }); 13 | 14 | app.get('/login', (req, res) => { 15 | const redirectUri = `https://github.com/login/oauth/authorize?client_id=${CLIENT_ID}`; 16 | res.redirect(redirectUri); 17 | }); 18 | 19 | app.get('/auth/github/callback', async (req, res) => { 20 | const code = req.query.code; 21 | try { 22 | const response = await axios.post('https://github.com/login/oauth/access_token', { 23 | client_id: CLIENT_ID, 24 | client_secret: CLIENT_SECRET, 25 | code: code 26 | }, { headers: { accept: 'application/json' } }); 27 | 28 | const accessToken = response.data.access_token; 29 | res.send('You are logged in!'); 30 | } catch (error) { 31 | console.error('Error during authentication:', error); 32 | res.send('Authentication failed'); 33 | } 34 | }); 35 | 36 | app.listen(3000, () => { 37 | console.log('Server started on http://localhost:3000'); 38 | }); 39 | -------------------------------------------------------------------------------- /unix_commands.md: -------------------------------------------------------------------------------- 1 | Some common unix commands: 2 | 3 | ls: list all files and directories 4 | cd: change working directory 5 | cat: print output of file 6 | pwd: list current path of current working directory 7 | nano: edit file in nano editor 8 | touch: create empty file 9 | ssh-add: adds ssh key 10 | --------------------------------------------------------------------------------