# Thinking in Aurora

### Step 1: Define the JSON API and Mockup

Assuming we have a JSON API returning product data like this:

```json
jsonCopy code[
  { "category": "Fruits", "price": "$1", "stocked": true, "name": "Apple" },
  { "category": "Fruits", "price": "$1", "stocked": true, "name": "Dragonfruit" },
  { "category": "Fruits", "price": "$2", "stocked": false, "name": "Passionfruit" },
  { "category": "Vegetables", "price": "$2", "stocked": true, "name": "Spinach" },
  { "category": "Vegetables", "price": "$4", "stocked": false, "name": "Pumpkin" },
  { "category": "Vegetables", "price": "$1", "stocked": true, "name": "Peas" }
]
```

And a mockup representing the UI:

\[Mockup Image]

### Step 2: Break Down the UI into Components

We'll identify the following components based on the mockup:

1. `FilterableProductTable`: Main container for the app.
2. `SearchBar`: Component to receive user input for searching.
3. `ProductTable`: Component to display and filter the product list.
4. `ProductCategoryRow`: Component to display category headings.
5. `ProductRow`: Component to display individual product rows.

### Step 3: Build a Static Version

We'll start by building a static version of the app without interactivity. We'll focus on reusability and passing data through props.

```python
pythonCopy code# Define ProductCategoryRow component
component ProductCategoryRow:
    def __init__(self, category):
        self.category = category
    
    def render(self):
        return f"<tr><th colspan='2'>{self.category}</th></tr>"

# Define ProductRow component
component ProductRow:
    def __init__(self, product):
        self.product = product
    
    def render(self):
        name = f"<span style='color: red'>{self.product['name']}</span>" if not self.product['stocked'] else self.product['name']
        return f"<tr><td>{name}</td><td>{self.product['price']}</td></tr>"

# Define ProductTable component
component ProductTable:
    def __init__(self, products):
        self.products = products
    
    def render(self):
        rows = []
        last_category = None
        
        for product in self.products:
            if product['category'] != last_category:
                rows.append(ProductCategoryRow(product['category']).render())
                last_category = product['category']
            rows.append(ProductRow(product).render())
        
        return "<table>" + "".join(rows) + "</table>"

# Define FilterableProductTable component
component FilterableProductTable:
    def __init__(self, products):
        self.products = products
    
    def render(self):
        return f"<div><SearchBar/><ProductTable products={self.products}/></div>"
```

### Step 4: Manage State

Identify the minimal but complete representation of UI state. In this case, it includes the search text and the value of the checkbox.

```python
pythonCopy code# Define FilterableProductTable component with state
component FilterableProductTable:
    def __init__(self, products):
        self.products = products
        self.state = {
            'filterText': '',
            'inStockOnly': False
        }
    
    def render(self):
        return f"""
            <div>
                <SearchBar 
                    filterText={self.state['filterText']} 
                    inStockOnly={self.state['inStockOnly']} 
                    onFilterTextChange={self.handleFilterTextChange}
                    onInStockOnlyChange={self.handleInStockOnlyChange} 
                />
                <ProductTable 
                    products={self.products} 
                    filterText={self.state['filterText']} 
                    inStockOnly={self.state['inStockOnly']} 
                />
            </div>
        """

    # Define event handlers for updating state
    def handleFilterTextChange(self, new_filter_text):
        self.state['filterText'] = new_filter_text
    
    def handleInStockOnlyChange(self, new_value):
        self.state['inStockOnly'] = new_value
```

### Step 5: Add Interactivity

Now, add inverse data flow to update the state based on user input.

```python
pythonCopy code# Define SearchBar component
component SearchBar:
    def __init__(self, filterText='', inStockOnly=False, onFilterTextChange=None, onInStockOnlyChange=None):
        self.filterText = filterText
        self.inStockOnly = inStockOnly
        self.onFilterTextChange = onFilterTextChange
        self.onInStockOnlyChange = onInStockOnlyChange
    
    def render(self):
        return f"""
            <form>
                <input 
                    type='text' 
                    value='{self.filterText}' 
                    placeholder='Search...'
                    onchange='{self.handleFilterTextChange}' 
                />
                <label>
                    <input 
                        type='checkbox' 
                        checked='{self.inStockOnly}' 
                        onchange='{self.handleInStockOnlyChange}' 
                    />
                    Only show products in stock
                </label>
            </form>
        """
    
    # Define event handlers for updating state
    def handleFilterTextChange(self, event):
        self.onFilterTextChange(event.target.value)
    
    def handleInStockOnlyChange(self, event):
        self.onInStockOnlyChange(event.target.checked)
```

Now, you have a fully functional searchable product data table in Aurora! You can further enhance this implementation with styling and additional features as needed. Happy coding! 🚀


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://1dvlpr-sorganization.gitbook.io/aurora/thinking-in-aurora.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
