diff --git a/curriculum/phase1-foundations/02-github/exercises/exercises3.md b/curriculum/phase1-foundations/02-github/exercises/exercises3.md index 127bb47..e5008c6 100644 --- a/curriculum/phase1-foundations/02-github/exercises/exercises3.md +++ b/curriculum/phase1-foundations/02-github/exercises/exercises3.md @@ -15,8 +15,8 @@ Practice resolving a merge conflict. 2. Stage and commit the file: ```bash - git add . - git commit -m "Changed hello.txt" + git add hello.txt + git commit -m "Update hello.txt" ``` 3. Merge your new branch you made on Exercise 2 into your current(main) branch: @@ -27,6 +27,7 @@ Practice resolving a merge conflict. > This will create a **merge conflict**, since both your main branch and your new branch edited the same file `hello.txt` differently. +4. Resolve the merge conflict. Edit the file so that both changes are kept: 4. Resolve the merge conflict. Edit the file so that both changes are kept: ```bash @@ -35,6 +36,7 @@ Practice resolving a merge conflict. I love ``` +5. Stage and commit the resolved file: 5. Stage and commit the resolved file: ```bash @@ -42,6 +44,7 @@ Practice resolving a merge conflict. git commit -m "Resolve merge conflict in hello.txt" ``` +6. Push the updated branch to your GitHub fork: 6. Push the updated branch to your GitHub fork: ```bash diff --git a/curriculum/phase3-frameworks/07-hooks-vercel/README.md b/curriculum/phase3-frameworks/07-hooks-vercel/README.md index 440d94b..0ccfbf2 100644 --- a/curriculum/phase3-frameworks/07-hooks-vercel/README.md +++ b/curriculum/phase3-frameworks/07-hooks-vercel/README.md @@ -1,7 +1,6 @@ -# ๐Ÿง  01 - Workshop Title Here +# ๐Ÿง  07 - React Hooks & Deployment - -> TLDR; A quick overview of the topic and what students will learn in this session. +> TLDR; A hands-on workshop mastering React fundamentals: Components, Props, Hooks (useState + useEffect), and Deployment with Vercel. ## ๐Ÿ“š Table of Contents @@ -17,9 +16,11 @@ ## ๐Ÿ” Topic Overview In this session, we'll cover: -* Brief summary of the workshop topic. -* Why this topic is important -* Real-world examples. +* **CSR vs. SSR:** Understanding when to use `"use client"` in Next.js. +* **Components & Props:** The DRY principle (Don't Repeat Yourself) and passing data top-down. +* **State Management:** Using `useState` to make apps interactive ("Memory"). +* **Side Effects:** Using `useEffect` for data persistence and browser interactions ("Senses"). +* **Deployment:** Taking your app live to the world using Vercel. ๐ŸŒ ## ๐Ÿ“ฆ Project Setup @@ -33,51 +34,85 @@ Before we begin: * Navigate to the folder where you cloned your forked repo. 3. **Pull the changes to your local machine** - ```bash git checkout main git pull origin main ``` 4. **Navigate to the lesson folder** - ```bash - cd curriculum/[lesson-phase]/[lesson-name] + cd curriculum/phase3-frameworks/07-hooks-vercel ``` -4. **Install dependencies (if any)** - +5. **Install dependencies (if any)** ```bash npm install ``` -5. **Start the dev server (if applicable)** - +6. **Start the dev server** ```bash npm run dev ``` ## ๐Ÿ“„ Code Walkthrough -Use this section to explain important code blocks: +We will refer to these patterns throughout the workshop. -```tsx -// Example code -const HelloWorld = () => { - return

Hello World ๐ŸŒ

; -}; +### 1. Components & Props +Instead of hardcoding HTML, we pass data into flexible components. +```jsx +// โŒ Bad (Hardcoded) +
Desmond - Teacher
+ +// โœ… Good (Reusable) +function UserCard({ name, role }) { + return
{name} - {role}
; +} +// Usage: +``` + +### 2. useState +Variables reset on refresh. State remembers data between renders. +```jsx +const [count, setCount] = useState(0); + +// โŒ Wrong: count = 5; +// โœ… Correct: setCount(5); +``` + +### 3. Callback Function +Data flows down. Functions flow down so children can change parent state. +```jsx +// Parent passes the "Key" (handleDelete) to the Child + +``` + +### 4. useEffect +Run code after the screen updates (e.g., saving data, console log). +```jsx +useEffect(() => { + document.title = `Count: ${count}`; +}, [count]); // Run whenever 'count' changes ``` ## ๐Ÿงช Exercises - -* ๐Ÿ Starter Exercise: ... -* ๐Ÿ”ง Modify This Component: ... -* ๐Ÿง  Thought Question: ... +> For more details please check `exercises` folder. + +### ๐Ÿ Exercise 1: Dynamic User Cards +* **Goal:** Stop copy-pasting code! Refactor the hardcoded `UserCard` component to be reusable. +### ๐Ÿ”ง Exercise 2: The Interactive Counter (State & Events) +* **Goal:** Build a counter that actually remembers its value. + +### ๐Ÿš€ Exercise 3: The Notes App (Final Build) +* **Goal:** Build a notes app that can add notes and persist them to localStorage. + +### ๐ŸŒ Exercise 4: Deployment +* **Goal:** Publish your app to the live web. + ## ๐Ÿ› ๏ธ Pushing Your Work - Once you're done with the exercises and your changes are complete, make sure to push your updates: ```bash git add . @@ -85,39 +120,15 @@ git commit -m "Complete workshop exercises" git push origin main ``` - ## ๐Ÿ“ Bonus Resources - -* [MDN Docs](https://developer.mozilla.org/) -* [React Docs](https://react.dev/) -* [Tailwind Docs](https://tailwindcss.com/) +* [React Developer Tools (Chrome Extension)](https://chromewebstore.google.com/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi) - Allows you to inspect components and see State/Props changing in real-time. +* [Lucide React Icons](https://lucide.dev/icons/) - The standard icon library for Next.js (perfect for your Delete/Edit buttons). +* [React Cheatsheet](https://devhints.io/react) - Quick syntax reference for Hooks, Props, and Lifecycle. ## ๐Ÿ™Œ Contributors - | Name | Role | GitHub | | ------------ | ------------------- | -------------------------------------------------- | -| Your Name | Speaker 1 | [@yourgithub](https://github.com/yourgithub) | -| Your Name | Speaker 2 | [@yourgithub](https://github.com/yourgithub) | -| Your Name | Activity Creator 1 | [@yourgithub](https://github.com/yourgithub) | -| Your Name | Activity Creator 2 | [@yourgithub](https://github.com/yourgithub) | -| Your Name | Reviewer 1 | [@yourgithub](https://github.com/yourgithub) | -| Your Name | Reviewer 2 | [@yourgithub](https://github.com/yourgithub) | - - -## ๐Ÿ“Œ Heading Format Guide (for consistency) - -Use these emoji-based headers for every section: - -```md -## ๐Ÿง  Title โ€“ For lesson title -## ๐Ÿ“š Title โ€“ For table of contents -## ๐Ÿ” Title โ€“ For explanation -## ๐Ÿ“ฆ Title โ€“ For tools or dependencies and setup - -## ๐Ÿ“„ Title โ€“ For code breakdown -## ๐Ÿงช Title โ€“ For exercises -## ๐Ÿ“ Title โ€“ For documentation-related things - -## ๐Ÿ™Œ Title โ€“ For contributors -``` \ No newline at end of file +| Desmond | Speaker & Activity Creator 1 | [@desraymondz](https://github.com/desraymondz) | +| Michelle Chan | Speaker & Activity Creator 2 | [@Chelle007](https://github.com/Chelle007) | +| Yan Mei | Reviewer | [@yxnmei](https://github.com/yxnmei) | diff --git a/curriculum/phase3-frameworks/07-hooks-vercel/exercises/exercise1/exercise1.md b/curriculum/phase3-frameworks/07-hooks-vercel/exercises/exercise1/exercise1.md new file mode 100644 index 0000000..6baec9d --- /dev/null +++ b/curriculum/phase3-frameworks/07-hooks-vercel/exercises/exercise1/exercise1.md @@ -0,0 +1,10 @@ +# ๐Ÿงช Exercise 1: Reusable Components + +## Goal +Stop copy-pasting code! Refactor the hardcoded `UserCard` component to be reusable. + +## Steps + +1. Modify `UserCard` to accept `name` and `role` as props. + +2. In `App.js`, render **3 distinct users** (e.g., Teacher, Student, Developer) reusing that single component. diff --git a/curriculum/phase3-frameworks/07-hooks-vercel/exercises/exercise1/starter/App.jsx b/curriculum/phase3-frameworks/07-hooks-vercel/exercises/exercise1/starter/App.jsx new file mode 100644 index 0000000..a6532d3 --- /dev/null +++ b/curriculum/phase3-frameworks/07-hooks-vercel/exercises/exercise1/starter/App.jsx @@ -0,0 +1,8 @@ +export default function App() { + return ( +
+ + +
+ ); + } \ No newline at end of file diff --git a/curriculum/phase3-frameworks/07-hooks-vercel/exercises/exercise1/starter/UserCard.jsx b/curriculum/phase3-frameworks/07-hooks-vercel/exercises/exercise1/starter/UserCard.jsx new file mode 100644 index 0000000..d2aeecd --- /dev/null +++ b/curriculum/phase3-frameworks/07-hooks-vercel/exercises/exercise1/starter/UserCard.jsx @@ -0,0 +1,8 @@ +export default function UserCard() { + return ( +
+

Name: Desmond

+

Role: Teacher ๐Ÿ‘จโ€๐Ÿซ

+
+ ); + } \ No newline at end of file diff --git a/curriculum/phase3-frameworks/07-hooks-vercel/exercises/exercise2/exercise2.md b/curriculum/phase3-frameworks/07-hooks-vercel/exercises/exercise2/exercise2.md new file mode 100644 index 0000000..b27bb8b --- /dev/null +++ b/curriculum/phase3-frameworks/07-hooks-vercel/exercises/exercise2/exercise2.md @@ -0,0 +1,18 @@ +# ๐Ÿงช Exercise 2: The Interactive Counter (State & Events) + +## Goal +Build a counter that actually remembers its value. + +## Steps + +1. Change `count` variable into a state using `useState`. + +2. Create a separate `ResetButton` component. Pass a **callback function** down to it so that clicking it resets the parent's count to 0. + +3. Use `useEffect` to update the browser's document title whenever the count changes. Import `useEffect` from React and add this effect to your `Counter` component: + + ```jsx + useEffect(() => { + document.title = `Count: ${count}`; + }, [count]); + ``` \ No newline at end of file diff --git a/curriculum/phase3-frameworks/07-hooks-vercel/exercises/exercise2/starter/App.jsx b/curriculum/phase3-frameworks/07-hooks-vercel/exercises/exercise2/starter/App.jsx new file mode 100644 index 0000000..4482812 --- /dev/null +++ b/curriculum/phase3-frameworks/07-hooks-vercel/exercises/exercise2/starter/App.jsx @@ -0,0 +1,7 @@ +export default function App() { + return ( +
+ +
+ ); + } \ No newline at end of file diff --git a/curriculum/phase3-frameworks/07-hooks-vercel/exercises/exercise2/starter/Counter.jsx b/curriculum/phase3-frameworks/07-hooks-vercel/exercises/exercise2/starter/Counter.jsx new file mode 100644 index 0000000..7952322 --- /dev/null +++ b/curriculum/phase3-frameworks/07-hooks-vercel/exercises/exercise2/starter/Counter.jsx @@ -0,0 +1,21 @@ +'use client'; + +export default function Counter() { + // Normal variable (React doesn't watch this) + let count = 0; + + const handleAdd = () => { + count = count + 1; + console.log("Variable updated to:", count); + // โŒ The screen will NOT update! + }; + + return ( +
+

Count: {count}

+ +
+ ); + } \ No newline at end of file diff --git a/curriculum/phase3-frameworks/07-hooks-vercel/exercises/exercise2/starter/ResetButton.jsx b/curriculum/phase3-frameworks/07-hooks-vercel/exercises/exercise2/starter/ResetButton.jsx new file mode 100644 index 0000000..96c972f --- /dev/null +++ b/curriculum/phase3-frameworks/07-hooks-vercel/exercises/exercise2/starter/ResetButton.jsx @@ -0,0 +1,10 @@ +export default function ResetButton() { + return ( + // โŒ CRASH! + // Error: 'setCount' is not defined. + // The Child says: "I don't know what 'setCount' is! It's not in my house." + + ); + } \ No newline at end of file diff --git a/curriculum/phase3-frameworks/07-hooks-vercel/exercises/exercise3/exercise3.md b/curriculum/phase3-frameworks/07-hooks-vercel/exercises/exercise3/exercise3.md new file mode 100644 index 0000000..9526f1b --- /dev/null +++ b/curriculum/phase3-frameworks/07-hooks-vercel/exercises/exercise3/exercise3.md @@ -0,0 +1,112 @@ +# ๐Ÿงช Exercise 3: The Notes App (Final Build) + +## Goal +Build a fully functional application that allows users to **Add**, **Edit**, and **Delete** notes. + +## Steps + +### 0. Setup +Open your `app/page.jsx` file. Since we are using Hooks, the very first line **MUST** be: + +```jsx +"use client"; +import { useState, useEffect } from "react"; +``` + +### 1. Create the State (The Memory) ๐Ÿง  +We need two pieces of memory: +1. **`input`**: To remember what the user is typing *right now*. +2. **`notes`**: An array (list) to store *all* the saved notes. + +```jsx +export default function NotesApp() { + const [input, setInput] = useState(""); + const [notes, setNotes] = useState([]); + + // ... rest of code +``` + +### 2. Handle Inputs & Adding Notes โž• +Let's create the function to add a note. +* **Logic:** We take the current `notes` array, add the new `input` to the end, and then clear the input box. + +```jsx + const addNote = () => { + // Spread operator (...) keeps old notes and adds new one + setNotes([...notes, input]); + setInput(""); // Clear the box + }; +``` + +Now, connect this to your **JSX (Your UI)**: + +```jsx + return ( +
+

๐Ÿ“ My Notes App

+ +
+ setInput(e.target.value)} // Update state on type + className="border p-2 w-full rounded" + placeholder="Type a note..." + /> + +
+ + {/* List will go here later */} +
+ ); +} +``` + +### 3. Display the Notes (Rendering) ๐ŸŽจ +Use the `.map()` function to loop through the `notes` array and turn raw data into UI elements. + +Add this inside your `return`, below the input section: + +```jsx +
    + {notes.map((note, index) => ( +
  • + {note} + {/* Buttons will go here */} +
  • + ))} +
+``` + +### 4. Delete & Edit Functionality ๐Ÿ—‘๏ธ โœ๏ธ +Let's add the logic to remove or modify items. +* **Delete:** Keep everything *except* the one we clicked. +* **Edit:** A simple trick! Remove the note from the list and put the text *back* into the input box so you can fix it. + +```jsx + const deleteNote = (indexToDelete) => { + // Fill in yourself + }; + + const editNote = (indexToEdit) => { + // Fill in yourself + }; +``` + +Update your list (`
  • `) to include these buttons: + +```jsx +
    + + +
    +``` diff --git a/curriculum/phase3-frameworks/07-hooks-vercel/exercises/exercise4/exercise4.md b/curriculum/phase3-frameworks/07-hooks-vercel/exercises/exercise4/exercise4.md new file mode 100644 index 0000000..9283536 --- /dev/null +++ b/curriculum/phase3-frameworks/07-hooks-vercel/exercises/exercise4/exercise4.md @@ -0,0 +1,16 @@ +# ๐Ÿงช Exercise 4: Deployment + +## Goal +Publish your app to the live web. + +## Steps + +1. Commit and Push your latest code to GitHub ๐Ÿ™. + +2. Go to **Vercel** โ†’ **Add New Project**. + +3. Import your specific repository. + +4. Click **Deploy** and wait for the magic โœจ. + +5. Paste your live link in the chat! diff --git a/curriculum/phase3-frameworks/07-hooks-vercel/final/index.html b/curriculum/phase3-frameworks/07-hooks-vercel/final/index.html deleted file mode 100644 index e69de29..0000000 diff --git a/curriculum/phase3-frameworks/07-hooks-vercel/starter/index.html b/curriculum/phase3-frameworks/07-hooks-vercel/starter/index.html deleted file mode 100644 index e69de29..0000000