Rewrite of ESH-Media v1 with separated main/renderer/shared architecture (vite-plugin-electron, React 18, react-router-dom). Includes NeDB storage, electron-store config, proxy manager with FoxyProxy/uBlock extensions, custom server-checked updater, NSIS installer. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
53 lines
1.4 KiB
TypeScript
53 lines
1.4 KiB
TypeScript
import React from 'react';
|
|
import { Bookmark } from '../../shared/types';
|
|
import '../styles/BookmarkCard.css';
|
|
|
|
interface BookmarkCardProps {
|
|
bookmark: Bookmark;
|
|
onOpen: () => void;
|
|
onDelete: () => void;
|
|
}
|
|
|
|
const BookmarkCard: React.FC<BookmarkCardProps> = ({
|
|
bookmark,
|
|
onOpen,
|
|
onDelete,
|
|
}) => {
|
|
const handleDelete = (e: React.MouseEvent) => {
|
|
e.stopPropagation();
|
|
if (confirm(`Удалить закладку "${bookmark.title}"?`)) {
|
|
onDelete();
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="bookmark-card" onClick={onOpen}>
|
|
{bookmark.image && (
|
|
<img
|
|
src={bookmark.image}
|
|
alt={bookmark.title}
|
|
className="bookmark-image"
|
|
onError={(e) => {
|
|
(e.target as HTMLImageElement).style.display = 'none';
|
|
}}
|
|
/>
|
|
)}
|
|
<div className="bookmark-info">
|
|
<h3 className="bookmark-title">{bookmark.title}</h3>
|
|
<p className="bookmark-site">{bookmark.siteName}</p>
|
|
{bookmark.metadata?.year && (
|
|
<p className="bookmark-year">{bookmark.metadata.year}</p>
|
|
)}
|
|
{bookmark.metadata?.description && (
|
|
<p className="bookmark-description">{bookmark.metadata.description}</p>
|
|
)}
|
|
</div>
|
|
<button className="delete-button" onClick={handleDelete}>
|
|
✕
|
|
</button>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default BookmarkCard;
|