import React from 'react'; import { UserAvatar } from '../ui/UserAvatar'; import { Avatar } from '../leads/leadUi'; import { CollapsibleText, ProbabilityBar, STAGE_COLORS, StageBadge, formatDate, formatDays, relativeDays, } from './opportunityUi'; import { contactFullName, formatEuro, opportunityVolume, type Opportunity, } from '../../types'; interface OpportunityGridProps { opportunities: Opportunity[]; onEdit: (opportunity: Opportunity) => void; onDelete: (opportunity: Opportunity) => void; /** Kopie fuer einen anderen Berater anlegen. */ onCopy: (opportunity: Opportunity) => void; } const Metric: React.FC<{ label: string; value: string; className?: string }> = ({ label, value, className = '', }) => (

{label}

{value}

); export const OpportunityGrid: React.FC = ({ opportunities, onEdit, onDelete, onCopy, }) => (
{opportunities.map((opportunity) => { const color = STAGE_COLORS[opportunity.stage]; const interaction = relativeDays(opportunity.last_interaction_at); return (
onEdit(opportunity)} role="button" tabIndex={0} onKeyDown={(event) => { if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); onEdit(opportunity); } }} className="group flex cursor-pointer flex-col gap-3 overflow-hidden rounded-2xl border border-ink-200 bg-surface p-4 shadow-card transition hover:border-brand-300 hover:shadow-lift" > {/* Kopf */}

{opportunity.title}

{opportunity.company || 'Ohne Firma'}

{/* Fuer wen das Projekt laeuft - hervorgehoben, weil es die Kachel sonst nicht hergibt. */} {opportunity.consultant && (

{opportunity.consultant}

)}
{/* Sichtbar, nicht erst beim Ueberfahren: ein Knopf, den man nur findet, wenn man ihn schon kennt, ist keiner. */}
{opportunity.tags.slice(0, 2).map((tag) => ( {tag} ))} {opportunity.tags.length > 2 && ( +{opportunity.tags.length - 2} )}
{/* Projektdaten */}
{/* Festpreisprojekte haben keinen Tagessatz - dann zaehlt der Preis. */} {opportunity.fixed_price !== null ? ( ) : ( )}
{/* Letzte Interaktion */}

Letzte Interaktion

{formatDate(opportunity.last_interaction_at)} {interaction && ({interaction})}

{opportunity.last_interaction_note && (

{opportunity.last_interaction_note}

)}
{opportunity.next_step && (

{opportunity.next_step}

)} {/* Ansprechpartner und Zustaendigkeit */}
{opportunity.contacts.length === 0 ? ( Kein Ansprechpartner ) : ( <> {opportunity.contacts.slice(0, 3).map((contact) => ( ))} {opportunity.contacts.length > 3 ? ( +{opportunity.contacts.length - 3} ) : ( opportunity.contacts.length === 1 && ( {contactFullName(opportunity.contacts[0])} ) )} )}
{opportunity.owner_id !== null && ( )}
); })}
);