turash/bugulma/frontend/components/organization/OrganizationCard.tsx
2025-12-15 10:06:41 +01:00

145 lines
5.3 KiB
TypeScript

import React from 'react';
import { useNavigate } from 'react-router-dom';
// No longer needs SECTORS - uses getTranslatedSectorName directly
import { useTranslation } from '@/hooks/useI18n.tsx';
import { getTranslatedSectorName } from '@/lib/sector-mapper.ts';
import { getOrganizationSubtypeLabel } from '@/schemas/organizationSubtype.ts';
import type { Organization } from '@/types.ts';
import { Briefcase, MapPin, Building2 } from 'lucide-react';
import Badge from '@/components/ui/Badge.tsx';
import Button from '@/components/ui/Button.tsx';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/Card.tsx';
import VerifiedBadge from '@/components/ui/VerifiedBadge.tsx';
interface OrganizationCardProps {
organization: Organization;
showDetails?: boolean;
onClick?: (organization: Organization) => void;
}
const OrganizationCard = ({ organization, showDetails = true, onClick }: OrganizationCardProps) => {
const { t } = useTranslation();
const navigate = useNavigate();
// Sector display handled by getTranslatedSectorName
const handleCardClick = () => {
if (onClick) {
onClick(organization);
} else {
navigate(`/organization/${organization.ID}`);
}
};
const handleViewDetails = (e: React.MouseEvent) => {
e.stopPropagation();
navigate(`/organization/${organization.ID}`);
};
return (
<Card
className="hover:shadow-lg transition-all duration-200 cursor-pointer group"
onClick={handleCardClick}
>
<CardHeader className="pb-3">
<div className="flex items-start justify-between">
<div className="flex items-center gap-3">
<div className="w-12 h-12 rounded-lg bg-muted flex items-center justify-center shrink-0 overflow-hidden">
{organization.LogoURL ? (
<img
src={organization.LogoURL}
alt={organization.Name}
className="w-full h-full object-cover"
loading="lazy"
/>
) : (
<Building2 className="h-6 w-6 text-muted-foreground" />
)}
</div>
<div className="min-w-0 flex-1">
<CardTitle className="text-lg group-hover:text-primary transition-colors truncate">
{organization.Name}
</CardTitle>
<div className="flex items-center gap-2 mt-1">
<Badge variant="outline" className="text-xs">
{getOrganizationSubtypeLabel(organization.Subtype)}
</Badge>
{organization.Verified && <VerifiedBadge />}
</div>
</div>
</div>
</div>
</CardHeader>
<CardContent className="pt-0">
<div className="space-y-3">
{/* Sector and Location */}
<div className="flex items-center justify-between text-sm">
<div className="flex items-center gap-1">
<Briefcase className="h-4 text-current text-muted-foreground w-4" />
<span className="text-muted-foreground">
{getTranslatedSectorName(organization.Sector)}
</span>
</div>
{organization.Address && (
<div className="flex items-center gap-1">
<MapPin className="h-4 text-current text-muted-foreground w-4" />
<span className="text-muted-foreground truncate max-w-32">
{organization.Address}
</span>
</div>
)}
</div>
{/* Description */}
{organization.Description && showDetails && (
<p className="text-sm text-muted-foreground line-clamp-2">{organization.Description}</p>
)}
{/* Key Stats */}
{showDetails && (
<div className="grid grid-cols-3 gap-2 pt-2 border-t">
<div className="text-center">
<div className="text-lg font-semibold text-primary">
{organization.ResourceFlows?.length || 0}
</div>
<div className="text-xs text-muted-foreground">
{t('organizationCard.resourceFlows')}
</div>
</div>
<div className="text-center">
<div className="text-lg font-semibold text-success">
{organization.Matches?.length || 0}
</div>
<div className="text-xs text-muted-foreground">{t('organizationCard.matches')}</div>
</div>
<div className="text-center">
<div className="text-lg font-semibold text-warning">
{organization.Proposals?.length || 0}
</div>
<div className="text-xs text-muted-foreground">
{t('organizationCard.proposals')}
</div>
</div>
</div>
)}
{/* Action Button */}
<div className="pt-2">
<Button
variant="outline"
size="sm"
onClick={handleViewDetails}
className="w-full group-hover:bg-primary group-hover:text-primary-foreground transition-colors"
>
{t('organizationCard.viewDetails')}
</Button>
</div>
</div>
</CardContent>
</Card>
);
};
export default React.memo(OrganizationCard);