Debuggler LogoDebuggler
All challenges
The Missing Search ResultsLists / TablesInstantSearch.js
import { useState, useEffect } from "react";

// Mock database
const DB = Array.from({ length: 25 }, (_, i) => ({ id: i + 1, name: `Transaction #${1000 + i}`, amount: (Math.random() * 100).toFixed(2) }));
// Add a specific one for testing search
DB.push({ id: 99, name: "Special Refund 99", amount: "5.00" });

async function fetchPage(page, search) {
  await new Promise(r => setTimeout(r, 300));
  const filtered = DB.filter(item => item.name.toLowerCase().includes(search.toLowerCase()));
  const start = (page - 1) * 5;
  return {
    items: filtered.slice(start, start + 5),
    totalPages: Math.ceil(filtered.length / 5) || 1
  };
}

export default function App() {
  const [page, setPage] = useState(1);
  const [search, setSearch] = useState("");
  const [data, setData] = useState({ items: [], totalPages: 1 });
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const b = document.body;
    b.style.background = "#fafafa"; b.style.margin = "0";
    return () => { b.style.background = ""; b.style.margin = ""; };
  }, []);

  useEffect(() => {
    setLoading(true);
    let active = true;
    fetchPage(page, search).then((res) => {
      if (active) {
        setData(res);
        setLoading(false);
      }
    });
    return () => { active = false; };
  }, [page, search]);

  return (
    <div style={styles.page}>
      <div style={styles.card}>
        <h1 style={styles.h1}>Transactions</h1>
        
        <input 
          data-testid="search-input"
          value={search}
          // BUG: changing search does not reset page to 1.
          // If you are on page 3 and search for an item that only has 1 page of results,
          // the query asks for page 3 of that search result, which is empty.
          onChange={(e) => setSearch(e.target.value)}
          placeholder="Search by name..."
          style={styles.input}
        />

        <div style={styles.tableContainer}>
          {loading ? (
            <div data-testid="loading" style={styles.loading}>Loading...</div>
          ) : data.items.length === 0 ? (
             <div data-testid="empty-state" style={styles.empty}>0 items found</div>
          ) : (
            <table style={styles.table}>
              <tbody>
                {data.items.map(item => (
                  <tr key={item.id} data-testid="table-row">
                    <td style={styles.tdName}>{item.name}</td>
                    <td style={styles.tdAmount}>${item.amount}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          )}
        </div>

        <div style={styles.pagination}>
          <button data-testid="prev-btn" disabled={page === 1} onClick={() => setPage(p => p - 1)} style={styles.btn}>Prev</button>
          <span data-testid="page-indicator" style={styles.pageText}>Page {page} of {data.totalPages}</span>
          <button data-testid="next-btn" disabled={page >= data.totalPages} onClick={() => setPage(p => p + 1)} style={styles.btn}>Next</button>
        </div>
      </div>
    </div>
  );
}

const styles = {
  page: { display: "flex", justifyContent: "center", padding: "40px 20px", fontFamily: "system-ui, sans-serif" },
  card: { background: "#fff", borderRadius: 12, padding: "24px", width: "100%", maxWidth: 480, boxShadow: "0 4px 6px -1px rgba(0,0,0,0.1)" },
  h1: { margin: "0 0 16px", fontSize: 20, fontWeight: 600, color: "#111827" },
  input: { width: "100%", boxSizing: "border-box", padding: "10px", borderRadius: 6, border: "1px solid #D1D5DB", marginBottom: 16 },
  tableContainer: { minHeight: 220, border: "1px solid #E5E7EB", borderRadius: 8, overflow: "hidden" },
  loading: { padding: 32, textAlign: "center", color: "#6B7280" },
  empty: { padding: 32, textAlign: "center", color: "#6B7280" },
  table: { width: "100%", borderCollapse: "collapse" },
  tdName: { padding: "12px 16px", borderBottom: "1px solid #E5E7EB", fontSize: 14, color: "#374151" },
  tdAmount: { padding: "12px 16px", borderBottom: "1px solid #E5E7EB", fontSize: 14, color: "#111827", textAlign: "right", fontWeight: 500 },
  pagination: { display: "flex", justifyContent: "space-between", alignItems: "center", marginTop: 16 },
  btn: { padding: "6px 12px", borderRadius: 6, border: "1px solid #D1D5DB", background: "#fff", cursor: "pointer", fontSize: 14 },
  pageText: { fontSize: 14, color: "#6B7280" }
};

Navigate to page 3, then search for 'Special'. The list goes blank because it's asking for page 3 of the new search results. Fix the search so it resets the page.

After you fix it

  • Typing in the search bar should reset the page index back to 1.
  • Searching for 'Special' while on page 3 should display the result.

Click "Run checks" to verify your solution.