vkashti / app / admin / deals / DealsList.tsx
DealsList.tsx
Raw
'use client';

import { useEffect, useState } from 'react';
import { FiTag } from 'react-icons/fi';
import { useDeals } from './DealsProvider';
import { Deal } from '@/types/types';

// Helper function to format currency
const formatCurrency = (value: number): string => {
  return new Intl.NumberFormat('bg-BG', {
    style: 'currency',
    currency: 'BGN',
    minimumFractionDigits: 0,
    maximumFractionDigits: 2
  }).format(value);
};

// Inline deal card component to avoid import issues
function DealCard({ deal }: { deal: Deal }) {
  const { openEditDialog, getDealTags, tags } = useDeals();
  const [dealTags, setDealTags] = useState<number[]>([]);
  const [isLoadingTags, setIsLoadingTags] = useState(true);

  useEffect(() => {
    const loadTags = async () => {
      setIsLoadingTags(true);
      try {
        const tagIds = await getDealTags(deal.id);
        setDealTags(tagIds);
      } catch (error) {
        console.error('Error loading deal tags:', error);
      } finally {
        setIsLoadingTags(false);
      }
    };

    loadTags();
  }, [deal.id, getDealTags]);

  const handleCardClick = () => {
    openEditDialog(deal);
  };

  return (
    <div 
      className="card bg-white shadow-md hover:shadow-lg transition-shadow duration-300 overflow-hidden cursor-pointer relative h-36"
      onClick={handleCardClick}
    >
      <div className="card-body p-4">
        <h3 className="card-title text-lg font-bold truncate">{deal.title}</h3>
        
        {/* Price positioned in top right corner */}
        <div className="absolute top-2 right-2">
          {deal.is_for_business && (
            <div className="badge badge-outline badge-warning mr-2">Business</div>
          )}
          <div className="badge badge-outline badge-info flex items-center gap-1">
            {deal.regular_price ? (
              <>
                <span className="text-xs line-through opacity-70">{formatCurrency(deal.regular_price)}</span>
                <span>{formatCurrency(deal.price)}</span>
              </>
            ) : (
              formatCurrency(deal.price)
            )}
          </div>
        </div>
        
        {/* Tags display */}
        {!isLoadingTags && dealTags.length > 0 && (
          <div className="mt-2 flex flex-wrap gap-1">
            {dealTags.map(tagId => {
              const tag = tags.find(t => t.id === tagId);
              return tag ? (
                <div key={tag.id} className="badge badge-outline badge-sm flex items-center gap-1">
                  <FiTag className="w-3 h-3" />
                  <span>{tag.name}</span>
                </div>
              ) : null;
            })}
          </div>
        )}
        
        <div className="mt-auto">
          <p className="text-xs text-gray-500">For: {deal.for_who}</p>
          <p className="text-xs text-gray-500">
            Group size: {deal.min_group_size} - {deal.max_group_size} people
          </p>
        </div>
      </div>
    </div>
  );
}

export default function DealsList() {
  const { deals, isLoading } = useDeals();

  if (isLoading) {
    return (
      <div className="flex justify-center items-center h-40">
        <div className="loading loading-spinner loading-lg"></div>
      </div>
    );
  }

  if (deals.length === 0) {
    return (
      <div className="flex flex-col justify-center items-center h-40 text-center p-6 border-2 border-dashed border-gray-300 rounded-lg">
        <h3 className="text-xl font-medium text-gray-500">No deals found</h3>
        <p className="text-gray-400 mt-2">
          Add a new deal using the + button above
        </p>
      </div>
    );
  }

  return (
    <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
      {deals.map(deal => (
        <DealCard key={deal.id} deal={deal} />
      ))}
    </div>
  );
}