# React Fundamentals — Interactive Workshop Scenarios
# Build components with useState, lists, and useEffect.

scenarios:
  - id: counter-component
    title: "Build a Counter with useState"
    difficulty: beginner
    xp: 25
    setup:
      - "mkdir -p counter && cd counter && npm init -y && npm install react react-dom"
    files:
      - name: Counter.jsx
        content: |
          import React from "react";

          export default function Counter() {
            return (
              <div>
                <p>Count: 0</p>
                <button>Increment</button>
              </div>
            );
          }
        language: javascript
        readonly: false
    task: "Add state for the count using useState. Initialize it to 0. Make the Increment button update the count when clicked. Display the current count in the paragraph."
    validations:
      - label: "Counter uses useState and increments"
        check: file-changed
        pattern: "useState|setCount|onClick"
    hints:
      - "Import useState: import { useState } from 'react';"
      - "Add state: const [count, setCount] = useState(0);"
      - "The button needs onClick={() => setCount(count + 1)} and the paragraph should show {count}."
    agent_prompts:
      on_start: "Right now the count is hardcoded as 0. What would need to change for the number to update when the user clicks?"

  - id: todo-list
    title: "Build a Todo List with State Management"
    difficulty: intermediate
    xp: 35
    setup:
      - "mkdir -p todo-list && cd todo-list && npm init -y && npm install react react-dom"
    files:
      - name: TodoApp.jsx
        content: |
          import React, { useState } from "react";

          export default function TodoApp() {
            const [todos, setTodos] = useState([]);
            const [input, setInput] = useState("");

            return (
              <div>
                <input
                  value={input}
                  onChange={(e) => setInput(e.target.value)}
                  placeholder="Add a todo"
                />
                <button>Add</button>
                <ul>
                  {/* Todo items will go here */}
                </ul>
              </div>
            );
          }
        language: javascript
        readonly: false
    task: "Implement add (append new todo on Add click), remove (delete a todo by id or index), and toggle (mark todo complete/incomplete). Each todo should have id, text, and done. Display todos with checkboxes and a way to remove each."
    validations:
      - label: "Todo add, remove, and toggle implemented"
        check: file-changed
        pattern: "setTodos|add|toggle|remove"
    hints:
      - "Use a unique id for each todo — Date.now() or crypto.randomUUID() works."
      - "To add: setTodos([...todos, { id, text: input, done: false }]) then clear input."
      - "To toggle: map over todos and flip done for the matching id. To remove: filter out by id."
    agent_prompts:
      on_start: "You have an array of todos and an input. What happens when the user clicks Add? What shape should each todo item have?"

  - id: api-fetch
    title: "Fetch Data with useEffect"
    difficulty: intermediate
    xp: 35
    setup:
      - "mkdir -p api-fetch && cd api-fetch && npm init -y && npm install react react-dom"
    files:
      - name: UserList.jsx
        content: |
          import React, { useState, useEffect } from "react";

          export default function UserList() {
            return (
              <div>
                <h2>Users</h2>
                <p>Loading...</p>
              </div>
            );
          }
        language: javascript
        readonly: false
    task: "Fetch users from https://jsonplaceholder.typicode.com/users using useEffect. Store them in state. Show a loading state while fetching, an error message if the request fails, and render the list of user names when successful."
    validations:
      - label: "useEffect fetch with loading and error states"
        check: file-changed
        pattern: "useEffect|fetch|loading|error"
    hints:
      - "useEffect(() => { fetch(url).then(...) }, []) — empty deps = run once on mount."
      - "Use state for users, loading, and error. Set loading true before fetch, false after."
      - "fetch().then(res => res.json()).then(data => setUsers(data)).catch(err => setError(err.message))."
    agent_prompts:
      on_start: "The data comes from a server. When does that request need to run? What should the UI show before the data arrives?"
