| 289 | }; |
| 290 | |
| 291 | export const EntityItem = ({ |
| 292 | href, |
| 293 | title, |
| 294 | subtitle, |
| 295 | image, |
| 296 | actions, |
| 297 | onRemove, |
| 298 | isRemoving, |
| 299 | className, |
| 300 | }: EntityItemProps) => { |
| 301 | const handleRemove = async (e: React.MouseEvent) => { |
| 302 | e.preventDefault(); |
| 303 | e.stopPropagation(); |
| 304 | |
| 305 | if (isRemoving) { |
| 306 | return; |
| 307 | } |
| 308 | |
| 309 | if (onRemove) { |
| 310 | await onRemove(); |
| 311 | } |
| 312 | } |
| 313 | |
| 314 | return ( |
| 315 | <Link href={href} prefetch> |
| 316 | <Card |
| 317 | className={cn( |
| 318 | "p-4 shadow-none hover:shadow cursor-pointer", |
| 319 | isRemoving && "opacity-50 cursor-not-allowed", |
| 320 | className, |
| 321 | )} |
| 322 | > |
| 323 | <CardContent className="flex flex-row items-center justify-between p-0"> |
| 324 | <div className="flex items-center gap-3"> |
| 325 | {image} |
| 326 | <div> |
| 327 | <CardTitle className="text-base font-medium"> |
| 328 | {title} |
| 329 | </CardTitle> |
| 330 | {!!subtitle && ( |
| 331 | <CardDescription className="text-xs"> |
| 332 | {subtitle} |
| 333 | </CardDescription> |
| 334 | )} |
| 335 | </div> |
| 336 | </div> |
| 337 | {(actions || onRemove) && ( |
| 338 | <div className="flex gap-x-4 items-center"> |
| 339 | {actions} |
| 340 | {onRemove && ( |
| 341 | <DropdownMenu> |
| 342 | <DropdownMenuTrigger asChild> |
| 343 | <Button |
| 344 | size="icon" |
| 345 | variant="ghost" |
| 346 | onClick={(e) => e.stopPropagation()} |
| 347 | > |
| 348 | <MoreVerticalIcon className="size-4" /> |