Initial kanban board
This commit is contained in:
93
src/components/TaskCard.tsx
Normal file
93
src/components/TaskCard.tsx
Normal file
@@ -0,0 +1,93 @@
|
||||
import { useState } from 'react';
|
||||
import { useSortable } from '@dnd-kit/sortable';
|
||||
import { CSS } from '@dnd-kit/utilities';
|
||||
import type { Task } from '../types';
|
||||
|
||||
interface TaskCardProps {
|
||||
task: Task;
|
||||
isDragging?: boolean;
|
||||
onDelete?: () => void;
|
||||
onUpdate?: (updates: Partial<Task>) => void;
|
||||
}
|
||||
|
||||
export function TaskCard({ task, isDragging, onDelete, onUpdate }: TaskCardProps) {
|
||||
const [isEditing, setIsEditing] = useState(false);
|
||||
const [editTitle, setEditTitle] = useState(task.title);
|
||||
|
||||
const {
|
||||
attributes,
|
||||
listeners,
|
||||
setNodeRef,
|
||||
transform,
|
||||
transition,
|
||||
isDragging: isSortableDragging,
|
||||
} = useSortable({ id: task.id });
|
||||
|
||||
const style = {
|
||||
transform: CSS.Transform.toString(transform),
|
||||
transition,
|
||||
opacity: isSortableDragging ? 0.5 : 1,
|
||||
};
|
||||
|
||||
const handleSave = () => {
|
||||
if (editTitle.trim() && onUpdate) {
|
||||
onUpdate({ title: editTitle.trim() });
|
||||
}
|
||||
setIsEditing(false);
|
||||
};
|
||||
|
||||
if (isDragging) {
|
||||
return (
|
||||
<div className="task-card task-card-overlay">
|
||||
<p>{task.title}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={setNodeRef}
|
||||
style={style}
|
||||
className="task-card"
|
||||
{...attributes}
|
||||
{...listeners}
|
||||
>
|
||||
{isEditing ? (
|
||||
<div className="task-edit" onClick={(e) => e.stopPropagation()}>
|
||||
<input
|
||||
type="text"
|
||||
value={editTitle}
|
||||
onChange={(e) => setEditTitle(e.target.value)}
|
||||
onKeyDown={(e) => e.key === 'Enter' && handleSave()}
|
||||
autoFocus
|
||||
/>
|
||||
<button onClick={handleSave}>Save</button>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<p>{task.title}</p>
|
||||
<div className="task-actions">
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setIsEditing(true);
|
||||
}}
|
||||
title="Edit"
|
||||
>
|
||||
✏️
|
||||
</button>
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onDelete?.();
|
||||
}}
|
||||
title="Delete"
|
||||
>
|
||||
🗑️
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user