66 lines
3.3 KiB
TypeScript
66 lines
3.3 KiB
TypeScript
import React from 'react';
|
|
import type { Flyer } from '../types';
|
|
import { DocumentTextIcon } from './icons/DocumentTextIcon';
|
|
|
|
const formatShortDate = (dateString: string | null | undefined): string | null => {
|
|
if (!dateString) return null;
|
|
// Dates from DB are YYYY-MM-DD, which can be interpreted as UTC midnight by new Date().
|
|
// Appending T00:00:00 ensures it's not shifted by local timezone.
|
|
try {
|
|
return new Date(`${dateString}T00:00:00`).toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
|
|
interface FlyerListProps {
|
|
flyers: Flyer[];
|
|
onFlyerSelect: (flyer: Flyer) => void;
|
|
selectedFlyerId: number | null;
|
|
}
|
|
|
|
export const FlyerList: React.FC<FlyerListProps> = ({ flyers, onFlyerSelect, selectedFlyerId }) => {
|
|
return (
|
|
<div className="bg-white dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-700">
|
|
<h3 className="text-lg font-bold text-gray-800 dark:text-white p-4 border-b border-gray-200 dark:border-gray-700">
|
|
Processed Flyers
|
|
</h3>
|
|
{flyers.length > 0 ? (
|
|
<ul className="divide-y divide-gray-200 dark:divide-gray-700 max-h-96 overflow-y-auto">
|
|
{flyers.map(flyer => {
|
|
const from = formatShortDate(flyer.valid_from);
|
|
const to = formatShortDate(flyer.valid_to);
|
|
const dateRange = from && to ? (from === to ? from : `${from} - ${to}`) : from || to;
|
|
|
|
return (
|
|
<li
|
|
key={flyer.id}
|
|
onClick={() => onFlyerSelect(flyer)}
|
|
className={`p-4 flex items-center space-x-3 cursor-pointer transition-colors duration-200 ${selectedFlyerId === flyer.id ? 'bg-brand-light dark:bg-brand-dark/30' : 'hover:bg-gray-50 dark:hover:bg-gray-800'}`}
|
|
>
|
|
<DocumentTextIcon className="w-6 h-6 text-brand-primary flex-shrink-0" />
|
|
<div className="flex-grow min-w-0">
|
|
<p className="text-sm font-semibold text-gray-900 dark:text-white truncate" title={flyer.store?.name || 'Unknown Store'}>
|
|
{flyer.store?.name || 'Unknown Store'}
|
|
</p>
|
|
<p className="text-sm text-gray-600 dark:text-gray-400 truncate" title={flyer.file_name}>
|
|
{flyer.file_name}
|
|
</p>
|
|
<p className="text-xs text-gray-500 dark:text-gray-400 mt-1">
|
|
{`Processed: ${new Date(flyer.created_at).toLocaleDateString()}`}
|
|
{dateRange && ` • Valid: ${dateRange}`}
|
|
</p>
|
|
</div>
|
|
</li>
|
|
);
|
|
})}
|
|
</ul>
|
|
) : (
|
|
<p className="p-4 text-sm text-gray-500 dark:text-gray-400">
|
|
No flyers have been processed yet. Upload one to get started.
|
|
</p>
|
|
)}
|
|
</div>
|
|
);
|
|
}; |