138 lines
5.6 KiB
TypeScript
138 lines
5.6 KiB
TypeScript
import { ReactNode } from 'react';
|
|
import Switch from '../form/switch/Switch';
|
|
import Button from '../ui/button/Button';
|
|
import Badge from '../ui/badge/Badge';
|
|
import { Site } from '../../services/api';
|
|
|
|
interface SiteCardProps {
|
|
site: Site;
|
|
icon: ReactNode;
|
|
onToggle: (siteId: number, enabled: boolean) => void;
|
|
onSettings: (site: Site) => void;
|
|
onDetails: (site: Site) => void;
|
|
isToggling?: boolean;
|
|
}
|
|
|
|
export default function SiteCard({
|
|
site,
|
|
icon,
|
|
onToggle,
|
|
onSettings,
|
|
onDetails,
|
|
isToggling = false,
|
|
}: SiteCardProps) {
|
|
const handleToggle = (enabled: boolean) => {
|
|
onToggle(site.id, enabled);
|
|
};
|
|
|
|
const getStatusColor = () => {
|
|
if (site.is_active) {
|
|
return 'bg-green-500 dark:bg-green-600';
|
|
}
|
|
return 'bg-gray-400 dark:bg-gray-500';
|
|
};
|
|
|
|
const getStatusText = () => {
|
|
if (site.is_active) {
|
|
return { text: 'Active', color: 'text-green-600 dark:text-green-400', bold: true };
|
|
}
|
|
return { text: 'Inactive', color: 'text-gray-400 dark:text-gray-500', bold: false };
|
|
};
|
|
|
|
const statusText = getStatusText();
|
|
|
|
return (
|
|
<article className="rounded-2xl border border-gray-200 bg-white dark:border-gray-800 dark:bg-white/3">
|
|
<div className="relative p-5 pb-9">
|
|
<div className="mb-5 inline-flex h-10 w-10 items-center justify-center">
|
|
{icon}
|
|
</div>
|
|
<h3 className="mb-3 text-lg font-semibold text-gray-800 dark:text-white/90">
|
|
{site.name}
|
|
</h3>
|
|
<p className="max-w-xs text-sm text-gray-500 dark:text-gray-400 mb-2">
|
|
{site.description || 'No description'}
|
|
</p>
|
|
{site.domain && (
|
|
<p className="text-xs text-gray-400 dark:text-gray-500 mb-2">
|
|
{site.domain}
|
|
</p>
|
|
)}
|
|
<div className="flex items-center gap-2 mb-2 flex-wrap">
|
|
{site.industry_name && (
|
|
<Badge variant="light" color="info" className="text-xs">
|
|
{site.industry_name}
|
|
</Badge>
|
|
)}
|
|
<Badge variant="light" color="info" className="text-xs">
|
|
{site.active_sectors_count} / 5 Sectors
|
|
</Badge>
|
|
{site.status && (
|
|
<Badge variant="light" color={site.status === 'active' ? 'success' : 'dark'} className="text-xs">
|
|
{site.status}
|
|
</Badge>
|
|
)}
|
|
</div>
|
|
{/* Status Text and Circle - Same row */}
|
|
<div className="absolute top-5 right-5 flex items-center gap-2">
|
|
<span className={`text-sm ${statusText.color} ${statusText.bold ? 'font-bold' : ''} transition-colors duration-200`}>
|
|
{statusText.text}
|
|
</span>
|
|
<div
|
|
className={`w-[25px] h-[25px] rounded-full ${getStatusColor()} transition-colors duration-200`}
|
|
title={site.is_active ? 'Active site' : 'Inactive site'}
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div className="flex items-center justify-between border-t border-gray-200 p-5 dark:border-gray-800">
|
|
<div className="flex gap-3">
|
|
<Button
|
|
variant="outline"
|
|
size="md"
|
|
onClick={() => onSettings(site)}
|
|
className="shadow-theme-xs inline-flex h-11 w-11 items-center justify-center rounded-lg border border-gray-300 text-gray-700 dark:border-gray-700 dark:text-gray-400"
|
|
>
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 20 20"
|
|
fill="none"
|
|
>
|
|
<path
|
|
d="M5.64615 4.59906C5.05459 4.25752 4.29808 4.46015 3.95654 5.05171L2.69321 7.23986C2.35175 7.83128 2.5544 8.58754 3.14582 8.92899C3.97016 9.40493 3.97017 10.5948 3.14583 11.0707C2.55441 11.4122 2.35178 12.1684 2.69323 12.7598L3.95657 14.948C4.2981 15.5395 5.05461 15.7422 5.64617 15.4006C6.4706 14.9247 7.50129 15.5196 7.50129 16.4715C7.50129 17.1545 8.05496 17.7082 8.73794 17.7082H11.2649C11.9478 17.7082 12.5013 17.1545 12.5013 16.4717C12.5013 15.5201 13.5315 14.9251 14.3556 15.401C14.9469 15.7423 15.7029 15.5397 16.0443 14.9485L17.3079 12.7598C17.6494 12.1684 17.4467 11.4121 16.8553 11.0707C16.031 10.5948 16.031 9.40494 16.8554 8.92902C17.4468 8.58757 17.6494 7.83133 17.3079 7.23992L16.0443 5.05123C15.7029 4.45996 14.9469 4.25737 14.3556 4.59874C13.5315 5.07456 12.5013 4.47961 12.5013 3.52798C12.5013 2.84515 11.9477 2.2915 11.2649 2.2915L8.73795 2.2915C8.05496 2.2915 7.50129 2.84518 7.50129 3.52816C7.50129 4.48015 6.47059 5.07505 5.64615 4.59906Z"
|
|
stroke="currentColor"
|
|
strokeWidth="1.5"
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
/>
|
|
<path
|
|
d="M12.5714 9.99977C12.5714 11.4196 11.4204 12.5706 10.0005 12.5706C8.58069 12.5706 7.42969 11.4196 7.42969 9.99977C7.42969 8.57994 8.58069 7.42894 10.0005 7.42894C11.4204 7.42894 12.5714 8.57994 12.5714 9.99977Z"
|
|
stroke="currentColor"
|
|
strokeWidth="1.5"
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
/>
|
|
</svg>
|
|
</Button>
|
|
<Button
|
|
variant="outline"
|
|
size="md"
|
|
onClick={() => onDetails(site)}
|
|
className="shadow-theme-xs inline-flex h-11 items-center justify-center rounded-lg border border-gray-300 px-4 py-3 text-sm font-medium text-gray-700 dark:border-gray-700 dark:text-gray-400"
|
|
>
|
|
Details
|
|
</Button>
|
|
</div>
|
|
<Switch
|
|
label=""
|
|
checked={site.is_active}
|
|
disabled={isToggling}
|
|
onChange={handleToggle}
|
|
/>
|
|
</div>
|
|
</article>
|
|
);
|
|
}
|
|
|