CROP
ProjectsParts Services

Media Coverage API - Frontend Integration Package

Version: 1.0.0 Last Updated: 2025-11-17 Package for: CROP Admin Frontend Team

Media Coverage API - Frontend Integration Package

Version: 1.0.0 Last Updated: 2025-11-17 Package for: CROP Admin Frontend Team


Overview

This documentation package provides everything needed for the CROP admin frontend team to integrate the Media Coverage API into their dashboard. The API provides real-time analytics on media enrichment status across the parts catalog.


What's Included

1. Integration Guide

File: FRONTEND_MEDIA_INTEGRATION.md

Complete technical integration guide covering:

  • Quick start and installation
  • TypeScript type definitions
  • React hooks with React Query
  • Component examples (dashboard, charts, tables)
  • Error handling patterns
  • Caching strategies
  • Performance optimization tips
  • Troubleshooting guide

Who should read this: Frontend developers implementing the API integration

2. TypeScript SDK

File: media-coverage-client.ts

Production-ready TypeScript client library:

  • Type-safe API methods
  • Built-in error handling
  • Request timeout management
  • Batch fetch operations
  • Health check utilities
  • Singleton pattern support

How to use:

import { MediaCoverageClient } from '@/lib/media-coverage-client';

const client = new MediaCoverageClient({
  baseUrl: 'http://localhost:3005',
  debug: true
});

const coverage = await client.getCoverage({ environment: 'prod' });

3. Example Dashboard

File: examples/media-dashboard-example.tsx

Full-featured React component (~500 lines) demonstrating:

  • Statistics overview cards
  • Interactive Recharts visualizations
  • Searchable and sortable table
  • CSV export functionality
  • Environment switcher
  • Cache refresh
  • Comprehensive error handling
  • Responsive design

How to use: Copy and adapt components for your admin dashboard

4. Design Reference

File: FRONTEND_DESIGN_REFERENCE.md

UI/UX guidelines and specifications:

  • Layout structure and grid system
  • Component library with specs
  • Color palette (Tailwind-compatible)
  • Typography scale
  • Chart configurations
  • Responsive breakpoints
  • Accessibility requirements (WCAG 2.1 AA)
  • Animation guidelines

Who should read this: UI/UX designers and frontend developers


Quick Start

Step 1: Install Dependencies

# Using npm
npm install @tanstack/react-query recharts react-csv axios

# Using yarn
yarn add @tanstack/react-query recharts react-csv axios

# Using bun
bun add @tanstack/react-query recharts react-csv axios

Step 2: Configure API Client

// src/config/api.ts
export const API_BASE_URL = import.meta.env.VITE_API_URL || 'http://localhost:3005';

Step 3: Set Up React Query

// src/main.tsx
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      staleTime: 5 * 60 * 1000, // 5 minutes
      retry: 2,
    },
  },
});

function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <MediaDashboard />
    </QueryClientProvider>
  );
}

Step 4: Create Your First Component

// src/components/MediaDashboard.tsx
import { useQuery } from '@tanstack/react-query';

function MediaDashboard() {
  const { data, isLoading, error } = useQuery({
    queryKey: ['media-coverage'],
    queryFn: async () => {
      const response = await fetch('http://localhost:3005/api/health/media/coverage');
      return response.json();
    },
  });

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error loading data</div>;

  return (
    <div>
      <h1>Total Parts: {data.data.summary.totalParts}</h1>
      <p>360° Coverage: {data.data.images.view360.with360.percentage}%</p>
    </div>
  );
}

API Endpoints

Base URL

http://localhost:3005  (development)
https://api.crop.com   (production - TBD)

Available Endpoints

EndpointMethodPurposeCache
/api/health/media/coverageGETOverall statistics5 min
/api/health/media/distributionGETImage type breakdown15 min
/api/health/media/gapsGETParts needing enrichment10 min
/api/health/media/cache/statsGETCache metricsReal-time
/api/health/media/cache/invalidatePOSTClear cacheN/A

Query Parameters

All endpoints support:

  • environment: 'prod' | 'dev' | 'stage' (default: 'prod')
  • nocache: '1' | 'true' to bypass cache (default: false)

Gaps endpoint also supports:

  • minQuality: Minimum quality score 0-100 (default: 60)
  • limit: Max results 1-1000 (default: 100)

Key Features to Implement

1. Dashboard Overview

Priority: High

Display key metrics:

  • Total parts count
  • 360° view coverage (count + percentage)
  • Gallery images coverage (count + avg per part)
  • Documents coverage (count + avg per part)
  • Quality correlation (360° impact on quality scores)

Components needed:

  • StatCard component (4x grid)
  • Quality impact card (gradient background, 3-column stats)

2. Distribution Charts

Priority: High

Visualize media type distribution:

  • Pie chart showing "No media", "Gallery only", "360° only", "Both"
  • Bar chart comparing coverage percentages
  • Most common category highlight

Components needed:

  • PieChart (Recharts)
  • BarChart (Recharts)
  • Chart legend and tooltips

3. Media Gaps Table

Priority: High

List parts needing media enrichment:

  • Searchable by part number or title
  • Filterable by minimum quality score
  • Sortable by all columns
  • Shows missing media types (badges)
  • Export to CSV functionality
  • Link to part edit page

Components needed:

  • DataTable with search and sort
  • Filter controls
  • CSV export button
  • Badge components for missing media

4. Environment Switcher

Priority: Medium

Toggle between environments:

  • Production (default)
  • Development
  • Staging

Refreshes all data when switched.

5. Cache Management

Priority: Low

Admin features:

  • Refresh button to invalidate cache
  • Cache status indicator (show if data is cached)
  • Cache statistics debug panel (optional)

Response Types Reference

Coverage Summary Response

{
  success: true,
  data: {
    summary: {
      totalParts: 3740,
      analyzedAt: "2025-11-17T10:30:00Z",
      environment: "prod",
      collection: "parts_prod"
    },
    images: {
      gallery: {
        withGallery: { count: 297, percentage: 7.9 },
        withoutGallery: { count: 3443, percentage: 92.1 },
        averageGallerySize: 2.4,
        maxGallerySize: 85
      },
      view360: {
        with360: { count: 2517, percentage: 67.3 },
        without360: { count: 1223, percentage: 32.7 }
      },
      withAnyMedia: { count: 2680, percentage: 71.7 },
      withBothTypes: { count: 134, percentage: 3.6 },
      withNoMedia: { count: 1060, percentage: 28.3 }
    },
    documents: {
      overall: { count: 450, percentage: 12.0 },
      byType: [
        { type: "manual", coverage: { count: 320, percentage: 8.6 } },
        { type: "spec_sheet", coverage: { count: 130, percentage: 3.5 } }
      ],
      averagePerPart: 0.4,
      maxPerPart: 5
    },
    qualityCorrelation: {
      with360Score: 85.2,
      without360Score: 72.3,
      scoreDifference: 12.9
    }
  },
  meta: {
    environment: "prod",
    fromCache: true,
    timestamp: "2025-11-17T10:30:00Z"
  }
}

Media Gaps Response

{
  success: true,
  data: {
    summary: {
      totalGaps: 1223,
      minQualityThreshold: 60,
      limit: 100
    },
    parts: [
      {
        _id: "507f1f77bcf86cd799439011",
        partNumber: "NH-123456",
        title: "Hydraulic Pump Assembly",
        media: {
          galleryCount: 0,
          has360: false,
          pdfCount: 0
        },
        qualityScore: 75,
        missingMedia: ["gallery", "360_view", "pdfs"]
      }
      // ... more parts
    ],
    gapBreakdown: {
      missingGallery: 980,
      missing360: 850,
      missingPdfs: 1100,
      missingAll: 620
    }
  },
  meta: {
    environment: "prod",
    minQuality: 60,
    limit: 100,
    fromCache: false,
    timestamp: "2025-11-17T10:30:00Z"
  }
}

Implementation Roadmap

Phase 1: Core Dashboard (Week 1)

  • Set up React Query
  • Create API client hooks
  • Implement overview stat cards
  • Add environment switcher
  • Basic error handling

Phase 2: Data Visualization (Week 2)

  • Integrate Recharts
  • Create pie chart for distribution
  • Create bar chart for breakdown
  • Add tooltips and legends
  • Make charts responsive

Phase 3: Gaps Table (Week 2-3)

  • Create table component
  • Add search functionality
  • Implement column sorting
  • Add quality score filters
  • CSV export feature
  • Link to part edit page

Phase 4: Polish & Performance (Week 3)

  • Responsive design for tablet/mobile
  • Loading skeletons
  • Error boundaries
  • Cache refresh button
  • Accessibility audit
  • Performance optimization

Phase 5: Advanced Features (Week 4+)

  • Dashboard customization (hide/show cards)
  • Saved filter presets
  • Historical trend charts
  • Email alerts for low coverage
  • Bulk part selection for enrichment

Testing Guide

Unit Tests

// Example test for useMediaCoverage hook
import { renderHook, waitFor } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { useMediaCoverage } from './useMediaApi';

test('should fetch media coverage', async () => {
  const queryClient = new QueryClient();
  const wrapper = ({ children }) => (
    <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
  );

  const { result } = renderHook(() => useMediaCoverage('prod'), { wrapper });

  await waitFor(() => expect(result.current.isSuccess).toBe(true));

  expect(result.current.data?.data.summary.totalParts).toBeGreaterThan(0);
});

Integration Tests

// Example test for MediaDashboard component
import { render, screen } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { MediaDashboard } from './MediaDashboard';

test('should display total parts count', async () => {
  const queryClient = new QueryClient();

  render(
    <QueryClientProvider client={queryClient}>
      <MediaDashboard />
    </QueryClientProvider>
  );

  const totalParts = await screen.findByText(/Total Parts/i);
  expect(totalParts).toBeInTheDocument();
});

E2E Tests (Playwright)

test('should export gaps to CSV', async ({ page }) => {
  await page.goto('http://localhost:3000/media-dashboard');

  const downloadPromise = page.waitForEvent('download');
  await page.click('text=Export CSV');
  const download = await downloadPromise;

  expect(download.suggestedFilename()).toContain('media-gaps');
});

Troubleshooting

Common Issues

1. CORS Errors

Problem: Access to fetch at 'http://localhost:3005' from origin 'http://localhost:3000' has been blocked by CORS

Solution: Configure Vite proxy

// vite.config.ts
export default defineConfig({
  server: {
    proxy: {
      '/api': 'http://localhost:3005'
    }
  }
});

2. Stale Data

Problem: Dashboard shows old data even after updates

Solution: Use nocache parameter or invalidate queries

// Force fresh data
const { data } = useMediaCoverage('prod', true); // nocache = true

// Or invalidate manually
queryClient.invalidateQueries(['media-coverage']);

3. Slow Initial Load

Problem: First request takes 400-500ms

Solution: This is expected - cache is warming up. Show loading state:

if (isLoading) {
  return <LoadingSpinner message="Loading initial data (may take a moment)..." />;
}

4. Chart Not Rendering

Problem: Recharts pie chart doesn't show up

Solution: Ensure ResponsiveContainer has explicit height

<ResponsiveContainer width="100%" height={400}>
  <PieChart>...</PieChart>
</ResponsiveContainer>

Performance Considerations

Caching Strategy

  • Server-side: 5-15 minute TTL (configured per endpoint)
  • Client-side: React Query caches for 5 minutes (staleTime)
  • Total: Data can be up to 10 minutes old (5 min server + 5 min client)

Optimization Tips

  1. Lazy load charts: Use React.lazy() for chart components
  2. Virtualize table: Use react-window for 1000+ rows
  3. Debounce search: Wait 300ms after user stops typing
  4. Prefetch data: On hover, prefetch next environment
  5. Bundle splitting: Separate charts into async chunks

Expected Load Times

  • Cold start: 400-500ms (first request)
  • Cached: 20-50ms (subsequent requests)
  • Table rendering: <100ms (100 rows)
  • Chart rendering: 200-300ms (initial paint)

Support & Resources

Documentation

  • Integration Guide: FRONTEND_MEDIA_INTEGRATION.md
  • Design Reference: FRONTEND_DESIGN_REFERENCE.md
  • TypeScript SDK: media-coverage-client.ts
  • Example Dashboard: examples/media-dashboard-example.tsx

API Documentation

External Resources

Contact

  • Backend Team: [email/slack]
  • Frontend Lead: [email/slack]
  • Design Team: [email/slack]

Changelog

v1.0.0 (2025-11-17)

  • Initial release
  • Complete integration guide
  • TypeScript SDK client
  • Example dashboard component
  • Design reference guide
  • Testing examples
  • Troubleshooting guide

Next Steps

  1. Review Documentation: Read through FRONTEND_MEDIA_INTEGRATION.md
  2. Run Example: Copy media-dashboard-example.tsx and test locally
  3. Design Review: Share FRONTEND_DESIGN_REFERENCE.md with design team
  4. Spike Task: Create technical spike to estimate effort
  5. Implementation: Follow phased roadmap above
  6. QA Testing: Test all endpoints and error scenarios
  7. Production Deploy: Coordinate with backend team for prod API access

Feedback

This is a living document. If you find issues, need clarifications, or have suggestions for improvement, please:

  1. Create a Linear ticket with label Frontend Integration
  2. Tag backend team for API questions
  3. Update this documentation with your learnings

Happy coding!

On this page