-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathScriptCard.tsx
More file actions
16 lines (16 loc) · 3.32 KB
/
Copy pathScriptCard.tsx
File metadata and controls
16 lines (16 loc) · 3.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import React, { useState } from 'react';
import { Check, Clock, Copy, Download, Edit3, FileCode, Folder, Tag, Trash2 } from 'lucide-react';
import { handleCopy } from './fileHelpers';
import { Script } from './types';
interface Props { script: Script; onEdit:(id:string)=>void; onView:(id:string)=>void; onDownload:(s:Script)=>void; onDelete:(id:string)=>void; }
export const ScriptCard: React.FC<Props> = ({ script, onEdit, onView, onDownload, onDelete }) => {
const [copied,setCopied]=useState(false); const files=script.files || []; const lines=files.reduce((n,f)=>n+(f.content?f.content.split('\n').length:0),0); const chars=files.reduce((n,f)=>n+f.content.length,0);
const copy=async(e:React.MouseEvent)=>{e.stopPropagation();if(await handleCopy(script.content)){setCopied(true);setTimeout(()=>setCopied(false),1200)}};
return <article role="button" tabIndex={0} onClick={()=>onView(script.id)} onKeyDown={e=>{if(e.key==='Enter'||e.key===' '){e.preventDefault();onView(script.id)}}} className="group bg-[var(--bg-card)] border border-[var(--border-color)] rounded-2xl p-4 hover:border-red-400 hover:shadow-lg transition flex flex-col min-h-48 cursor-pointer" aria-label={`Buka ${script.name}`}>
<div className="flex items-start justify-between gap-2"><div className="min-w-0"><div className="flex items-center gap-2"><FileCode className="w-4 h-4 text-red-600 shrink-0"/><h3 className="font-bold truncate">{script.name}</h3></div>{script.folder&&<div className="text-[10px] text-[var(--text-muted)] flex items-center gap-1 mt-1"><Folder className="w-3 h-3"/>{script.folder}</div>}</div><span className="text-[10px] font-bold bg-[var(--bg-hover)] px-2 py-1 rounded-lg">v{script.version}</span></div>
<p className="text-xs text-[var(--text-muted)] mt-3 line-clamp-2">{script.description||'Tanpa deskripsi.'}</p>
<div className="flex flex-wrap gap-1 mt-3">{(script.tags||[]).slice(0,4).map(t=><span key={t} className="text-[9px] px-1.5 py-0.5 rounded bg-blue-50 text-blue-600 flex items-center gap-1"><Tag className="w-2 h-2"/>{t}</span>)}</div>
<div className="mt-auto pt-4 text-[10px] text-[var(--text-muted)] flex items-center gap-2"><strong className="uppercase">{script.language}</strong><span>• {files.length} file</span><span>• {lines.toLocaleString('id-ID')} baris</span><span>• {chars.toLocaleString('id-ID')} karakter</span></div>
<div className="pt-3 mt-2 border-t border-[var(--border-color)] flex items-center justify-between"><span className="text-[10px] text-[var(--text-muted)] flex items-center gap-1"><Clock className="w-3 h-3"/>{new Date(script.updatedAt).toLocaleDateString('id-ID')}</span><div className="flex gap-1"><button onClick={copy} className="p-1.5 rounded-lg hover:bg-[var(--bg-hover)]" title="Salin">{copied?<Check className="w-3.5 h-3.5 text-green-500"/>:<Copy className="w-3.5 h-3.5"/>}</button><button onClick={e=>{e.stopPropagation();onDownload(script)}} className="p-1.5 rounded-lg hover:bg-[var(--bg-hover)]" title="Unduh"><Download className="w-3.5 h-3.5"/></button><button onClick={e=>{e.stopPropagation();onEdit(script.id)}} className="p-1.5 rounded-lg hover:bg-[var(--bg-hover)]" title="Edit"><Edit3 className="w-3.5 h-3.5"/></button><button onClick={e=>{e.stopPropagation();onDelete(script.id)}} className="p-1.5 rounded-lg hover:bg-red-50 text-red-500" title="Hapus"><Trash2 className="w-3.5 h-3.5"/></button></div></div>
</article>;
};