All files / src/pages MyDealsPage.tsx

100% Statements 8/8
100% Branches 7/7
100% Functions 2/2
100% Lines 8/8

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                    1x 6x   6x 1x     5x 3x                               2x                                 2x                                                                
// src/pages/MyDealsPage.tsx
import React from 'react';
import { AlertCircle, Tag, Store, Calendar } from 'lucide-react';
import { useBestSalePricesQuery } from '../hooks/queries/useBestSalePricesQuery';
 
/**
 * Page displaying the best deals for the user's watched items.
 *
 * Uses TanStack Query for data fetching (ADR-0005 Phase 6).
 */
const MyDealsPage: React.FC = () => {
  const { data: deals = [], isLoading, error } = useBestSalePricesQuery();
 
  if (isLoading) {
    return <div className="text-center p-8">Loading your deals...</div>;
  }
 
  if (error) {
    return (
      <div
        className="bg-red-100 border-l-4 border-red-500 text-red-700 p-4 rounded-md shadow-md max-w-2xl mx-auto"
        role="alert"
      >
        <div className="flex items-center">
          <AlertCircle className="h-6 w-6 mr-3" />
          <div>
            <p className="font-bold">Error</p>
            <p>{error.message}</p>
          </div>
        </div>
      </div>
    );
  }
 
  return (
    <div className="max-w-4xl mx-auto p-4 sm:p-6 lg:p-8">
      <h1 className="text-3xl font-bold text-gray-900 dark:text-white mb-6">
        My Watched Item Deals
      </h1>
      {deals.length === 0 ? (
        <div className="text-center bg-gray-100 dark:bg-gray-800 p-8 rounded-lg shadow-sm">
          <p className="text-lg text-gray-600 dark:text-gray-400">
            No deals found for your watched items right now.
          </p>
          <p className="text-sm text-gray-500 mt-2">
            Try adding more items to your watchlist or check back after new flyers are uploaded!
          </p>
        </div>
      ) : (
        <ul className="space-y-4">
          {deals.map((deal) => (
            <li
              key={`${deal.master_item_id}-${deal.flyer_id}`}
              className="bg-white dark:bg-gray-800 rounded-lg shadow-md p-4 transition hover:shadow-lg"
            >
              <div className="flex flex-col sm:flex-row justify-between items-start sm:items-center">
                <h2 className="text-xl font-semibold text-gray-800 dark:text-gray-100 mb-2 sm:mb-0">
                  {deal.item_name}
                </h2>
                <div className="flex items-center bg-green-100 dark:bg-green-900 text-green-800 dark:text-green-200 text-lg font-bold px-3 py-1 rounded-full">
                  <Tag className="h-5 w-5 mr-2" />
                  <span>${(deal.best_price_in_cents / 100).toFixed(2)}</span>
                </div>
              </div>
              <div className="mt-3 text-sm text-gray-600 dark:text-gray-400 flex flex-col sm:flex-row sm:items-center sm:space-x-6 space-y-2 sm:space-y-0">
                <div className="flex items-center">
                  <Store className="h-4 w-4 mr-2 text-gray-500" />
                  <span>{deal.store.name}</span>
                </div>
                <div className="flex items-center">
                  <Calendar className="h-4 w-4 mr-2 text-gray-500" />
                  <span>Valid until: {new Date(deal.valid_to).toLocaleDateString()}</span>
                </div>
              </div>
            </li>
          ))}
        </ul>
      )}
    </div>
  );
};
 
export default MyDealsPage;