Initial commit: snapAna 截图智能整理工具
包含 FastAPI 后端、React 前端、队列/OCR/标签/待办等完整功能。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
import { Star } from "lucide-react";
|
||||
import type { ScreenshotBrief } from "@/types";
|
||||
import { StatusBadge } from "./StatusBadge";
|
||||
|
||||
interface Props {
|
||||
shot: ScreenshotBrief;
|
||||
onOpen: (id: number) => void;
|
||||
onToggleFav?: (shot: ScreenshotBrief) => void;
|
||||
}
|
||||
|
||||
export function Card({ shot, onOpen, onToggleFav }: Props) {
|
||||
const date = new Date(shot.captured_at).toLocaleString("zh-CN", {
|
||||
hour12: false,
|
||||
});
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={() => onOpen(shot.id)}
|
||||
className="card-hover group relative flex w-full flex-col overflow-hidden rounded-xl border border-slate-800 bg-slate-900/40 text-left"
|
||||
>
|
||||
<div className="relative aspect-[4/3] w-full overflow-hidden bg-slate-800">
|
||||
{shot.thumb_url ? (
|
||||
<img
|
||||
src={shot.thumb_url}
|
||||
alt=""
|
||||
loading="lazy"
|
||||
className="h-full w-full object-cover transition group-hover:scale-[1.02]"
|
||||
/>
|
||||
) : (
|
||||
<div className="flex h-full w-full items-center justify-center text-xs text-slate-500">
|
||||
无缩略图
|
||||
</div>
|
||||
)}
|
||||
{shot.category && (
|
||||
<span
|
||||
className="absolute left-2 top-2 inline-flex items-center rounded-full bg-black/55 px-2 py-0.5 text-[10px] text-white backdrop-blur"
|
||||
style={{
|
||||
borderLeft: `3px solid ${shot.category.color ?? "#6366f1"}`,
|
||||
}}
|
||||
>
|
||||
{shot.category.name}
|
||||
</span>
|
||||
)}
|
||||
<button
|
||||
className={`absolute right-2 top-2 rounded-full p-1.5 transition ${
|
||||
shot.is_favorite
|
||||
? "bg-amber-400/90 text-slate-900"
|
||||
: "bg-black/40 text-slate-300 opacity-0 group-hover:opacity-100"
|
||||
}`}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onToggleFav?.(shot);
|
||||
}}
|
||||
aria-label="收藏"
|
||||
>
|
||||
<Star size={14} fill={shot.is_favorite ? "currentColor" : "none"} />
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex flex-1 flex-col gap-1 px-3 py-2">
|
||||
<div className="line-clamp-2 text-sm font-medium text-slate-100">
|
||||
{shot.ai_title || "(未生成标题)"}
|
||||
</div>
|
||||
<div className="mt-auto flex items-center justify-between text-[11px] text-slate-500">
|
||||
<span>{date}</span>
|
||||
<StatusBadge status={shot.ai_status} />
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user