Practice 3 — React Review Aggregator Frontend

Build Interactive Product Review Interface with React

Practice
React
Frontend
Review Aggregator
Auteur
Affiliations

Université de Toulon

LIS UMR CNRS 7020

Date de publication

2025-10-11

Résumé

Course lectures and practices for JavaScript full‑stack web development with AI‑assisted workflows.

Practice Overview

Duration: 60 minutes
Prerequisites: React lecture completed, fullstack-minimal-app setup
Project: Multi-Source Product Review Aggregator frontend
Objective: Build React components for displaying and fetching product reviews

What You’ll Build (60 minutes)

Complete React frontend for the review aggregator project:

  • ProductHeader — Display product information
  • ReviewFetcher — Button to fetch reviews from “external sources”
  • ReviewStats — Statistics visualization (average rating, source breakdown)
  • ReviewList — Display list of reviews with filtering
  • ReviewCard — Individual review display component

Technologies: React hooks, Tailwind CSS, mock API integration
Foundation: Using fullstack-minimal-app/frontend as starting point


Part 1: Project Setup (5 min)

Step 1.1: Navigate to Frontend

# Make sure you're in the right place
cd fullstack-minimal-app/frontend

# Install dependencies if needed
npm install

# Start development server
npm run dev
# Opens http://localhost:5173

Step 1.2: Create Component Structure

# Create components for reviews
mkdir -p src/components/reviews
mkdir -p src/services

# Create component files
touch src/components/reviews/ProductHeader.jsx
touch src/components/reviews/ReviewFetcher.jsx
touch src/components/reviews/ReviewStats.jsx
touch src/components/reviews/ReviewList.jsx
touch src/components/reviews/ReviewCard.jsx

# Create mock API service
touch src/services/mockReviewAPI.js

Your structure should be:

frontend/src/
├── components/
│   ├── reviews/
│   │   ├── ProductHeader.jsx
│   │   ├── ReviewFetcher.jsx
│   │   ├── ReviewStats.jsx
│   │   ├── ReviewList.jsx
│   │   └── ReviewCard.jsx
│   ├── ProductList.jsx    # Already exists
│   └── ProductForm.jsx    # Already exists
├── services/
│   └── mockReviewAPI.js
├── App.jsx
└── main.jsx

Part 2: Mock API Service (10 min)

Exercise 2.1: Create Mock Review API

Use AI to generate the mock API service:

Prompt for AI:

Context: React frontend for Multi-Source Product Review Aggregator
Task: Create mockReviewAPI.js service that simulates backend API calls

Functions needed:
1. fetchProductReviews(productId) - Returns existing reviews for a product
2. triggerReviewFetch(productId) - Simulates fetching new reviews from external sources
3. getReviewStats(productId) - Returns aggregate statistics

Mock data:
- 15+ diverse reviews with fields: id, productId, source, author, rating, title, content, date
- Sources: "Amazon", "BestBuy", "Walmart"
- Ratings: 1-5 stars
- Realistic review content for a wireless headphones product

API simulation:
- Add delays (500ms-2s) to simulate network calls
- Return promises for async handling
- Include error simulation (10% chance)

Requirements:
- ES6 modules (export/import)
- JSDoc comments
- Realistic mock data
- Error handling simulation

Output: Complete mockReviewAPI.js file

Save the generated code to src/services/mockReviewAPI.js

Verify it works:

// Test in browser console
import { fetchProductReviews } from './services/mockReviewAPI.js';
fetchProductReviews('1').then(console.log);

Part 3: React Components (35 min)

Exercise 3.1: Create ReviewCard Component (8 min)

Prompt for AI:

Context: React component for displaying individual product review
Task: Create ReviewCard.jsx component

Props:
- review: {
    id: number,
    source: string ("Amazon" | "BestBuy" | "Walmart"),
    author: string,
    rating: number (1-5),
    title: string,
    content: string,
    date: string (ISO format)
  }

Features:
- Star rating display (★★★★☆ format)
- Source badge with colors (Amazon=orange, BestBuy=blue, Walmart=green)
- Author name and relative date ("3 days ago")
- Review title (bold)
- Review content (with read more/less for long text)
- Responsive card layout

Requirements:
- React functional component with hooks
- Tailwind CSS styling
- PropTypes validation
- Accessible (ARIA labels)
- Mobile-responsive

Output: Complete ReviewCard.jsx component

Test the component:

// In App.jsx temporarily
import ReviewCard from './components/reviews/ReviewCard';

const sampleReview = {
  id: 1,
  source: "Amazon",
  author: "John D.",
  rating: 5,
  title: "Excellent headphones!",
  content: "These wireless headphones exceeded my expectations...",
  date: "2025-10-01T10:30:00Z"
};

return <ReviewCard review={sampleReview} />;

Exercise 3.2: Create ReviewStats Component (8 min)

Prompt for AI:

Context: React component displaying aggregate review statistics
Task: Create ReviewStats.jsx component

Props:
- stats: {
    overallAverage: number (e.g., 4.2),
    totalReviews: number,
    sourceBreakdown: [
      { source: string, average: number, count: number }
    ],
    ratingHistogram: { 1: number, 2: number, 3: number, 4: number, 5: number }
  }
- loading: boolean (optional)

Features:
- Large overall average display (4.2★)
- Total review count
- Per-source breakdown (table or list)
- Rating histogram (horizontal bars)
- Loading skeleton when loading=true

Requirements:
- Tailwind CSS for styling
- No external chart libraries (use CSS for bars)
- PropTypes validation
- Loading state animation

Output: Complete ReviewStats.jsx component

Exercise 3.3: Create ReviewList Component (8 min)

Prompt for AI:

Context: React component for listing product reviews with filtering
Task: Create ReviewList.jsx component

Props:
- reviews: array of review objects
- loading: boolean
- onFilterChange: function

Features:
- Filter dropdown by source (All, Amazon, BestBuy, Walmart)
- Filter by rating (All, 5★, 4★+, 3★+, 2★+, 1★)
- Display filtered review count
- Map over reviews using ReviewCard component
- Empty state when no reviews
- Loading state with skeleton cards

State management:
- useState for sourceFilter and ratingFilter
- Filter reviews locally based on selected filters
- Call onFilterChange when filters change

Requirements:
- Import and use ReviewCard
- Tailwind CSS styling
- PropTypes validation

Output: Complete ReviewList.jsx component

Exercise 3.4: Create ReviewFetcher Component (8 min)

Prompt for AI:

Context: React component with button to fetch new reviews
Task: Create ReviewFetcher.jsx component

Props:
- productId: string
- onReviewsFetched: function (callback when new reviews are fetched)

Features:
- "Fetch Reviews" button (prominent styling)
- Loading state (button disabled, shows spinner)
- Success message after fetch ("Fetched X new reviews!")
- Error handling with retry button
- Progress indicator during fetch

Functionality:
- onClick calls triggerReviewFetch(productId) from mock API
- Handle loading, success, and error states
- Call onReviewsFetched with new reviews data
- Auto-clear messages after 3 seconds

Requirements:
- useState for loading, message, error states
- Import triggerReviewFetch from mock API
- Tailwind CSS styling
- PropTypes validation

Output: Complete ReviewFetcher.jsx component

Exercise 3.5: Create ProductHeader Component (3 min)

Simple component - can code manually or use AI:

// src/components/reviews/ProductHeader.jsx
import PropTypes from 'prop-types';

function ProductHeader({ productName, productImage, productPrice }) {
  return (
    <div className="bg-white rounded-lg shadow p-6 mb-6">
      <div className="flex items-center space-x-4">
        {productImage && (
          <img 
            src={productImage} 
            alt={productName}
            className="w-20 h-20 object-cover rounded"
          />
        )}
        <div>
          <h1 className="text-2xl font-bold text-gray-900">{productName}</h1>
          {productPrice && (
            <p className="text-xl text-green-600 font-semibold">${productPrice}</p>
          )}
        </div>
      </div>
    </div>
  );
}

ProductHeader.propTypes = {
  productName: PropTypes.string.isRequired,
  productImage: PropTypes.string,
  productPrice: PropTypes.number,
};

export default ProductHeader;

Part 4: Main Page Integration (8 min)

Exercise 4.1: Create Main ReviewAggregatorPage

Prompt for AI:

Context: Main React page component integrating all review components
Task: Create ReviewAggregatorPage.jsx component

Features:
- Main page layout with ProductHeader at top
- ReviewFetcher component with callback handling
- ReviewStats component showing aggregate statistics
- ReviewList component showing individual reviews
- State management for reviews, stats, loading states

State management:
- reviews: array (starts empty)
- stats: object (starts null)
- loading: boolean for initial load
- fetchingNew: boolean for fetch button

Lifecycle:
- useEffect on mount: load existing reviews and calculate stats
- onReviewsFetched callback: add new reviews, recalculate stats

Layout:
- Mobile: Stack all components vertically
- Desktop: Stats sidebar, reviews main content area

Props:
- productId: string (default "1" for demo)

Requirements:
- Import all review components
- Import mock API functions
- useState and useEffect hooks
- Tailwind CSS responsive layout
- PropTypes validation
- Error handling for API calls

Output: Complete ReviewAggregatorPage.jsx component

Exercise 4.2: Update App.jsx

Replace the content of App.jsx:

// src/App.jsx
import ReviewAggregatorPage from './components/reviews/ReviewAggregatorPage';

function App() {
  return (
    <div className="min-h-screen bg-gray-50">
      <ReviewAggregatorPage productId="1" />
    </div>
  );
}

export default App;

Part 5: Testing & Polish (2 min)

Test Complete Flow

  1. Initial Load:
    • Page loads with empty state
    • “Fetch Reviews” button is prominent
  2. Fetch Reviews:
    • Click fetch button
    • Loading state shows
    • After delay, reviews appear
    • Stats update with aggregated data
  3. Filtering:
    • Test source filter (All, Amazon, BestBuy, Walmart)
    • Test rating filter (All, 5★, 4★+, etc.)
    • Verify review count updates
  4. Responsive Design:
    • Test on mobile (375px)
    • Test on desktop (1200px+)
    • Components stack properly

Quick Fixes

If something doesn’t work:

// Check console for errors
// Verify imports are correct
// Check component props match PropTypes
// Test mock API functions individually

Part 6: Documentation & Reflection

Create README.md

# Review Aggregator Frontend

React frontend for Multi-Source Product Review Aggregator.

## Components

- **ReviewCard** - Individual review display
- **ReviewStats** - Aggregate statistics with charts
- **ReviewList** - Filtered list of reviews
- **ReviewFetcher** - Fetch new reviews button
- **ProductHeader** - Product information display

## Mock API

Located in `src/services/mockReviewAPI.js`
- Simulates backend endpoints
- Includes realistic delays
- 15+ sample reviews

## Features

✅ Fetch reviews on demand
✅ Display aggregate statistics  
✅ Filter by source and rating
✅ Responsive design
✅ Loading and error states
✅ Accessible components

## Next Steps

- Replace mock API with real backend endpoints
- Add pagination for large review sets
- Implement review submission form
- Add real-time updates

Reflection Questions

Consider these questions:

  1. React Patterns: How did you manage state across components?
  2. Component Design: Which components were easiest/hardest to build?
  3. AI Assistance: What worked well with AI prompts? What needed manual fixes?
  4. User Experience: How does the app feel to use? What would improve it?
  5. Code Organization: Is the component structure clear and maintainable?

Deliverables

Required files: - src/components/reviews/ReviewCard.jsx - src/components/reviews/ReviewStats.jsx - src/components/reviews/ReviewList.jsx - src/components/reviews/ReviewFetcher.jsx - src/components/reviews/ProductHeader.jsx - src/components/reviews/ReviewAggregatorPage.jsx - src/services/mockReviewAPI.js - README.md

Testing checklist: - [ ] All components render without errors - [ ] Fetch button loads new reviews - [ ] Filtering works correctly - [ ] Stats update after fetch - [ ] Responsive on mobile and desktop - [ ] Loading states display properly - [ ] Error handling works - [ ] No console warnings


Extension Challenges (Optional)

Challenge 1: Add Sorting

Add sorting options to ReviewList: - Sort by date (newest/oldest) - Sort by rating (highest/lowest) - Sort by source (alphabetical)

Challenge 2: Pagination

Implement pagination for reviews: - Show 10 reviews per page - Add page navigation - “Load more” button option

Challenge 4: Enhanced Stats

Improve the statistics display: - Add trend indicators (↑↓) - Show rating distribution chart - Add sentiment analysis indicators


Resources


Troubleshooting

Component not rendering: - Check console for errors - Verify all imports are correct - Ensure props match PropTypes

Mock API not working: - Check network tab in dev tools - Verify function exports/imports - Test functions individually in console

Styling issues: - Ensure Tailwind CSS is loaded - Check for typos in class names - Use browser dev tools to inspect styles

State not updating: - Don’t mutate state directly - Use functional updates for complex state - Check useEffect dependencies


Success Criteria

Excellent (A): - All components work flawlessly - Clean, readable code - Proper error handling - Responsive design - Good use of React patterns

Good (B): - Most components work - Minor bugs or styling issues - Basic error handling - Mostly responsive

Needs Work (C): - Components render but have issues - Poor error handling - Not responsive - Code quality issues


Next Practice Preview

Practice 4: Node.js Backend - Build Express.js REST API - Create the endpoints your React app will use - Handle data persistence - Integrate with external scraper service

The backend will replace your mock API and provide real data persistence!


🎉 Practice Complete!

Congratulations! You’ve built a complete React frontend with:

  • ✅ Interactive components with state management
  • ✅ Mock API integration with async data fetching
  • ✅ Responsive design with Tailwind CSS
  • ✅ Proper component architecture
  • ✅ Loading states and error handling
  • ✅ Filtering and statistics display

You’re ready for the backend! 🚀

Réutilisation