Case Study 1: A Python Developer Builds a React Dashboard

Background

Priya Krishnamurthy had been a Python backend developer for six years. She built data pipelines, REST APIs, and machine learning models at a mid-size analytics company. Her tools of choice were FastAPI, pandas, and PostgreSQL. She had never written a React component, rarely touched CSS beyond changing a font color, and considered JavaScript a language she encountered only when debugging browser console errors.

Then her team's frontend developer left for another company, and the team needed a dashboard -- urgently. The sales team had been using spreadsheets to track pipeline metrics, and the VP of Sales wanted a real-time dashboard before the next board meeting, three weeks away. The backend API already existed; Priya had built it herself. What was missing was the frontend.

"I can build the API endpoints you need in a day," Priya told her manager. "But I have never built a React app."

"Use AI," her manager suggested. "Half the team is using it for code generation. You already know the data model. You just need to put it on a screen."

Priya was skeptical. But with no alternative and a hard deadline, she opened Claude and began.

The Challenge

The dashboard needed to display:

  • KPI cards showing total revenue, number of deals, win rate, and average deal size
  • A bar chart showing revenue by sales representative
  • A line chart showing monthly revenue trends over the past 12 months
  • A data table listing all active deals with sorting and filtering
  • A date range picker to filter all visualizations
  • Authentication to restrict access to sales team members

The backend API was already built with FastAPI and returned JSON. Priya had full documentation for every endpoint.

Phase 1: Project Setup (Day 1)

Priya started with a high-level prompt:

I am a Python developer who has never used React. I need to build a
sales dashboard. I already have a FastAPI backend with these endpoints:

- GET /api/metrics?start_date=YYYY-MM-DD&end_date=YYYY-MM-DD
  Returns: { total_revenue, deal_count, win_rate, avg_deal_size }
- GET /api/revenue/by-rep?start_date=...&end_date=...
  Returns: [{ rep_name, revenue }]
- GET /api/revenue/monthly?months=12
  Returns: [{ month, revenue }]
- GET /api/deals?status=active&sort=value&order=desc
  Returns: [{ id, title, value, rep_name, stage, close_date }]

Walk me through setting up a React project and building this dashboard.
Start with the project setup and a basic layout. Explain things as if
I only know Python.

The AI walked her through installing Node.js, creating a Vite project, and explained the project structure by comparing it to a Python package layout. It drew parallels she understood immediately: package.json was like requirements.txt, npm install was like pip install, and npm run dev was like python -m flask run.

Within an hour, Priya had a running React app showing "Hello, World!" in her browser. She committed the boilerplate to Git, just as she would with any Python project.

Phase 2: Layout and Navigation (Day 2)

Priya asked the AI to create the main layout:

Create a dashboard layout with:
- A sidebar on the left with the company logo and navigation links:
  Dashboard, Deals, Settings
- A header bar at the top showing the current page title and a user
  avatar placeholder
- A main content area where pages will render

Use Tailwind CSS. The sidebar should be dark blue (#1e3a5f).
The content area should be light gray (#f8fafc).
Make it responsive: sidebar collapses to icons on screens under 1024px.

I am using React Router for navigation. Show me how to set that up too.
Compare it to Flask's URL routing so I understand the concept.

The AI produced a Layout.jsx component and set up React Router, explaining that React Router was conceptually similar to Flask's @app.route() decorators -- each route mapped a URL path to a component, just as Flask routes mapped URLs to handler functions.

Priya noticed something important during review: the AI had used className instead of class, and onClick instead of onclick. She asked why, and the AI explained the JSX differences from HTML. This five-minute conversation saved her hours of debugging later.

Lesson Learned: Asking "why" about unfamiliar syntax is never a waste of time. Each explanation builds your mental model and helps you spot errors in future AI output.

Phase 3: KPI Cards and Data Fetching (Days 3-5)

The KPI cards were Priya's first real React component. She started with a specific prompt:

Create a KPICard React component that displays a single metric.

Props:
- title (string): e.g., "Total Revenue"
- value (string or number): e.g., "$1,234,567"
- change (number): percentage change, e.g., 12.5 or -3.2
- icon (string): icon name or emoji
- loading (boolean): show skeleton when true

The card should:
- Show a green up arrow and text for positive change
- Show a red down arrow and text for negative change
- Show a loading skeleton (pulsing gray rectangle) when loading is true
- Have a white background, rounded corners, subtle shadow
- Use Tailwind CSS

Then create a Dashboard page that:
- Fetches data from /api/metrics using useEffect and useState
- Displays 4 KPICard components in a responsive grid
  (4 columns on desktop, 2 on tablet, 1 on mobile)
- Formats the revenue as USD currency
- Formats win_rate as percentage
- Shows loading state while data fetches
- Shows error state if fetch fails

This prompt produced working code on the first attempt. Priya was surprised -- and a little suspicious. She inspected the code carefully, noting several patterns:

  1. The useEffect hook with an empty dependency array ran once on mount, similar to Python's __init__ method.
  2. The useState hook managed three pieces of state: data, loading, and error -- the same pattern she used in her FastAPI error handling.
  3. The Intl.NumberFormat API formatted currency, which she had never seen but immediately understood.

She tested with her actual API. The data appeared. The cards looked professional. She spent 20 minutes adjusting Tailwind classes to match the company's design system, which she did by describing changes to the AI: "Make the shadow more subtle" and "Use the company blue #2563eb for the icon background."

Phase 4: Charts (Days 6-9)

Charts were the trickiest part. Priya initially asked the AI to build charts with pure CSS and SVG, as the chapter recommended. The bar chart worked well, but the line chart was complex. After two iterations, she asked:

The SVG line chart is getting complicated. Should I use a charting
library instead? If so, which one works best with React? I want
something simple -- I do not need 3D charts or animations, just clean
bar and line charts.

The AI recommended Recharts for its simplicity and React integration. It provided installation instructions and a comparison: "Recharts components work like other React components -- you pass data as props and configure appearance with properties, similar to how you would configure a matplotlib plot in Python."

import { BarChart, Bar, XAxis, YAxis, Tooltip, ResponsiveContainer } from "recharts";

function RevenueByRepChart({ data }) {
    return (
        <ResponsiveContainer width="100%" height={400}>
            <BarChart data={data}>
                <XAxis dataKey="rep_name" />
                <YAxis tickFormatter={(v) => `$${(v / 1000).toFixed(0)}k`} />
                 `$${v.toLocaleString()}`} />
                <Bar dataKey="revenue" fill="#2563eb" radius={[4, 4, 0, 0]} />
            </BarChart>
        </ResponsiveContainer>
    );
}

Priya recognized the pattern immediately. The Recharts API was declarative, just like building a figure in matplotlib. Pass the data, configure the axes, add a tooltip. She had both charts working within two days.

Phase 5: The Data Table (Days 10-12)

The deals table was the most complex component. Priya needed sorting, filtering, and pagination -- features she had built many times in backend code but never in a browser.

Create a DealsTable component that displays a list of deals from
/api/deals. The table should have:

Columns: Deal Title, Value ($), Rep Name, Stage, Close Date
Features:
- Click column headers to sort (ascending/descending toggle)
- Search bar filters by deal title (debounced, 300ms delay)
- Dropdown filter for Stage (All, Prospecting, Negotiation, Closing, Won)
- Pagination: 15 items per page with Previous/Next buttons and page info
- Row click navigates to deal detail page

The data comes from the API with query parameters:
GET /api/deals?sort=value&order=desc&stage=negotiation&search=acme&page=1&limit=15

So pagination and sorting should be server-side, not client-side.
Show loading state when fetching. Handle errors gracefully.

This prompt was Priya's most detailed and produced a nearly complete implementation. She found one issue: the debounce implementation used setTimeout directly, which caused stale closures. She described the symptom to the AI ("the search works but sometimes shows results for a previous query"), and the AI identified the race condition and fixed it with an AbortController pattern.

Lesson Learned: When something does not work as expected, describe the behavior you observe rather than guessing at the cause. AI is remarkably good at diagnosing issues from behavioral descriptions, just as you might describe symptoms to a doctor rather than self-diagnosing.

Phase 6: Date Range Filter and Integration (Days 13-15)

The final feature was the date range picker that filtered all dashboard data. Priya learned about React Context here, because the date range needed to affect every component on the page:

I need a date range picker at the top of the dashboard. When the user
changes the date range, ALL components (KPI cards, charts, deals table)
should refetch their data with the new date range.

What is the best way to share this state across all components?
Compare it to a Python approach so I understand the trade-offs.

The AI explained React Context as analogous to Python's dependency injection -- a way to provide shared resources to components without passing them explicitly through every level. It created a DateRangeContext provider and showed Priya how each component could consume the date range with useContext.

Phase 7: Polish and Deployment (Days 16-18)

With all features working, Priya used AI for the final polish:

Review the entire dashboard for:
1. Loading states -- every data-dependent component should show a
   skeleton or spinner while loading
2. Error states -- every fetch should have error handling with a
   retry button
3. Empty states -- what does the deals table show when no deals
   match the filters?
4. Accessibility -- check all interactive elements for keyboard
   access and screen reader support
5. Mobile responsiveness -- test all breakpoints

The AI identified three missing error boundaries, two components without loading states, and five accessibility issues (missing aria-label attributes on icon-only buttons, a chart with no text alternative, and a table without proper header scoping).

Priya deployed to Vercel, which took ten minutes -- most of it spent creating an account. The build command was npm run build, and Vercel handled everything else.

Results

Priya delivered the dashboard two days ahead of the three-week deadline. The VP of Sales used it in the board meeting and received compliments on its clarity and design.

By the numbers: - 18 working days from zero React knowledge to deployed dashboard - 47 AI prompts for code generation (she logged them all) - 12 components built, including layout, KPI cards, charts, table, and date picker - 3 major iterations on the data table (the most complex component) - 0 prior React experience - Lighthouse scores: Performance 92, Accessibility 96, Best Practices 100, SEO 89

Key Takeaways

  1. Domain knowledge transfers. Priya's understanding of data models, API design, and application architecture was more valuable than JavaScript syntax knowledge. She knew what data to display and how to structure it -- the AI handled the syntax.

  2. Detailed prompts prevent rework. Her most successful generations came from prompts that specified props, behavior, styling, and edge cases upfront. Vague prompts required multiple rounds of iteration.

  3. Ask "why" constantly. Every time Priya encountered unfamiliar JavaScript or React patterns, she asked the AI to explain them in Python terms. This built her mental model and made her increasingly effective at reviewing code.

  4. Backend experience helps with frontend data flow. Understanding HTTP requests, JSON parsing, error handling, and pagination from the backend perspective made frontend API integration intuitive.

  5. Ship, then polish. Getting a working version early created momentum. The polish phase (loading states, error handling, accessibility) was faster because the core functionality was already solid.

  6. Track your prompts. Priya's prompt log became documentation for the project. When she needed to modify the dashboard later, she could trace each component back to the prompt that created it and iterate from there.