All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Wrap 7 list-item/card components with React.memo to prevent unnecessary re-renders when parent components update but props remain unchanged: - TaskItem (task lists) - EventCard (calendar views) - EntryCard (knowledge base) - WorkspaceCard (workspace list) - TeamCard (team list) - DomainItem (domain list) - ConnectionCard (federation connections) All are pure components rendered inside .map() loops that depend solely on their props for rendering output. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
61 lines
1.8 KiB
TypeScript
61 lines
1.8 KiB
TypeScript
"use client";
|
|
|
|
import React from "react";
|
|
import type { Domain } from "@mosaic/shared";
|
|
|
|
interface DomainItemProps {
|
|
domain: Domain;
|
|
onEdit?: (domain: Domain) => void;
|
|
onDelete?: (domain: Domain) => void;
|
|
}
|
|
|
|
export const DomainItem = React.memo(function DomainItem({
|
|
domain,
|
|
onEdit,
|
|
onDelete,
|
|
}: DomainItemProps): React.ReactElement {
|
|
return (
|
|
<div className="border rounded-lg p-4 hover:shadow-md transition-shadow">
|
|
<div className="flex items-start justify-between">
|
|
<div className="flex-1">
|
|
<div className="flex items-center gap-2 mb-2">
|
|
{domain.icon && <span className="text-2xl">{domain.icon}</span>}
|
|
{domain.color && (
|
|
<div className="w-4 h-4 rounded-full" style={{ backgroundColor: domain.color }} />
|
|
)}
|
|
<h3 className="font-semibold text-lg">{domain.name}</h3>
|
|
</div>
|
|
{domain.description && <p className="text-sm text-gray-600">{domain.description}</p>}
|
|
<div className="mt-2">
|
|
<span className="text-xs text-gray-500 font-mono">{domain.slug}</span>
|
|
</div>
|
|
</div>
|
|
<div className="flex gap-2 ml-4">
|
|
{onEdit && (
|
|
<button
|
|
onClick={() => {
|
|
onEdit(domain);
|
|
}}
|
|
className="text-sm px-3 py-1 border rounded hover:bg-gray-50"
|
|
aria-label={`Edit ${domain.name}`}
|
|
>
|
|
Edit
|
|
</button>
|
|
)}
|
|
{onDelete && (
|
|
<button
|
|
onClick={() => {
|
|
onDelete(domain);
|
|
}}
|
|
className="text-sm px-3 py-1 border border-red-300 text-red-600 rounded hover:bg-red-50"
|
|
aria-label={`Delete ${domain.name}`}
|
|
>
|
|
Delete
|
|
</button>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
});
|