All files / src/pages/admin FlyerReviewPage.tsx

100% Statements 20/20
95.23% Branches 20/21
100% Functions 4/4
100% Lines 20/20

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93                  1x 11x 11x 11x   11x 6x 6x 6x 6x 6x 3x 1x   2x     3x 3x 3x   5x       6x     11x                                                                       3x                                      
// src/pages/admin/FlyerReviewPage.tsx
import React, { useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
import { getFlyersForReview } from '../../services/apiClient';
import { logger } from '../../services/logger.client';
import type { Flyer } from '../../types';
import { LoadingSpinner } from '../../components/LoadingSpinner';
import { format } from 'date-fns';
 
export const FlyerReviewPage: React.FC = () => {
  const [flyers, setFlyers] = useState<Flyer[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
 
  useEffect(() => {
    const fetchFlyers = async () => {
      setIsLoading(true);
      setError(null);
      try {
        const response = await getFlyersForReview();
        if (!response.ok) {
          throw new Error((await response.json()).message || 'Failed to fetch flyers for review.');
        }
        setFlyers(await response.json());
      } catch (err) {
        const errorMessage =
          err instanceof Error ? err.message : 'An unknown error occurred while fetching data.';
        logger.error({ err }, 'Failed to fetch flyers for review');
        setError(errorMessage);
      } finally {
        setIsLoading(false);
      }
    };
 
    fetchFlyers();
  }, []);
 
  return (
    <div className="max-w-7xl mx-auto py-8 px-4">
      <div className="mb-8">
        <Link to="/admin" className="text-brand-primary hover:underline">
          &larr; Back to Admin Dashboard
        </Link>
        <h1 className="text-3xl font-bold text-gray-800 dark:text-white mt-2">
          Flyer Review Queue
        </h1>
        <p className="text-gray-500 dark:text-gray-400">
          Review flyers that were processed with low confidence by the AI.
        </p>
      </div>
 
      {isLoading && (
        <div
          role="status"
          aria-label="Loading flyers for review"
          className="flex justify-center items-center h-64"
        >
          <LoadingSpinner />
        </div>
      )}
      {error && (
        <div className="text-red-500 bg-red-100 dark:bg-red-900/20 p-4 rounded-lg">{error}</div>
      )}
 
      {!isLoading && !error && (
        <div className="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 overflow-hidden">
          <ul className="divide-y divide-gray-200 dark:divide-gray-700">
            {flyers.length === 0 ? (
              <li className="p-6 text-center text-gray-500">
                The review queue is empty. Great job!
              </li>
            ) : (
              flyers.map((flyer) => (
                <li key={flyer.flyer_id} className="p-4 hover:bg-gray-50 dark:hover:bg-gray-700/50">
                  <Link to={`/flyers/${flyer.flyer_id}`} className="flex items-center space-x-4">
                    <img src={flyer.icon_url || undefined} alt={flyer.store?.name || 'Unknown Store'} className="w-12 h-12 rounded-md object-cover" />
                    <div className="flex-1">
                      <p className="font-semibold text-gray-800 dark:text-white">{flyer.store?.name || 'Unknown Store'}</p>
                      <p className="text-sm text-gray-500 dark:text-gray-400">{flyer.file_name}</p>
                    </div>
                    <div className="text-right text-sm text-gray-500 dark:text-gray-400">
                      <p>Uploaded: {format(new Date(flyer.created_at), 'MMM d, yyyy')}</p>
                    </div>
                  </Link>
                </li>
              ))
            )}
          </ul>
        </div>
      )}
    </div>
  );
};