| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- import { useState } from 'react'
- import { Folder, MoreVertical, Pencil, Trash2, FolderInput } from 'lucide-react'
- import { WorkflowGroup } from '../api/workflowGroups'
- import { formatDistanceToNow } from 'date-fns'
- interface GroupCardProps {
- group: WorkflowGroup
- onClick: () => void
- onRename: () => void
- onMove: () => void
- onDelete: () => void
- }
- // Helper to safely format timestamps
- function safeFormatDistanceToNow(timestamp: number): string {
- if (!timestamp || timestamp < 0 || timestamp > 8640000000000000) {
- return 'unknown'
- }
- try {
- return formatDistanceToNow(timestamp, { addSuffix: true })
- } catch {
- return 'unknown'
- }
- }
- export function GroupCard({ group, onClick, onRename, onMove, onDelete }: GroupCardProps) {
- const [showMenu, setShowMenu] = useState(false)
- return (
- <div className="bg-white dark:bg-slate-800 rounded-xl border border-gray-200 dark:border-slate-700 p-4 hover:shadow-md transition-shadow">
- <div className="flex items-start justify-between mb-3">
- <button
- onClick={onClick}
- className="flex-1 flex items-start gap-3 text-left"
- >
- <div className="p-2 bg-amber-100 dark:bg-amber-900/30 rounded-lg">
- <Folder className="w-5 h-5 text-amber-600 dark:text-amber-400" />
- </div>
- <div className="flex-1 min-w-0">
- <h3 className="font-semibold text-gray-900 dark:text-gray-100 hover:text-primary-600 dark:hover:text-primary-400 truncate">
- {group.name}
- </h3>
- {group.description && (
- <p className="text-sm text-gray-500 dark:text-gray-400 mt-1 line-clamp-2">
- {group.description}
- </p>
- )}
- </div>
- </button>
- <div className="relative flex-shrink-0">
- <button
- onClick={(e) => {
- e.stopPropagation()
- setShowMenu(!showMenu)
- }}
- className="p-1 text-gray-400 dark:text-gray-500 hover:text-gray-600 dark:hover:text-gray-300 rounded"
- >
- <MoreVertical className="w-5 h-5" />
- </button>
- {showMenu && (
- <>
- <div
- className="fixed inset-0 z-10"
- onClick={() => setShowMenu(false)}
- />
- <div className="absolute right-0 mt-1 w-40 bg-white dark:bg-slate-800 rounded-lg shadow-lg border border-gray-200 dark:border-slate-700 z-20">
- <button
- onClick={(e) => {
- e.stopPropagation()
- onRename()
- setShowMenu(false)
- }}
- className="w-full px-4 py-2 text-left text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-slate-700 flex items-center gap-2"
- >
- <Pencil className="w-4 h-4" /> Rename
- </button>
- <button
- onClick={(e) => {
- e.stopPropagation()
- onMove()
- setShowMenu(false)
- }}
- className="w-full px-4 py-2 text-left text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-slate-700 flex items-center gap-2"
- >
- <FolderInput className="w-4 h-4" /> Move
- </button>
- <button
- onClick={(e) => {
- e.stopPropagation()
- onDelete()
- setShowMenu(false)
- }}
- className="w-full px-4 py-2 text-left text-sm text-red-600 dark:text-red-400 hover:bg-red-50 dark:hover:bg-red-900/30 flex items-center gap-2"
- >
- <Trash2 className="w-4 h-4" /> Delete
- </button>
- </div>
- </>
- )}
- </div>
- </div>
- <div className="flex items-center justify-end text-sm">
- <span className="text-gray-400 dark:text-gray-500">
- {safeFormatDistanceToNow(group.updatedAt)}
- </span>
- </div>
- </div>
- )
- }
|