Fix: Ensure all skills are tracked as files, not submodules
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
interface ConfirmDialogProps {
|
||||
isOpen: boolean;
|
||||
message: string;
|
||||
onConfirm: () => void;
|
||||
onCancel: () => void;
|
||||
}
|
||||
|
||||
export const ConfirmDialog = ({ isOpen, message, onConfirm, onCancel }: ConfirmDialogProps) => {
|
||||
if (!isOpen) return null;
|
||||
|
||||
return (
|
||||
<div className="dialog-overlay">
|
||||
<div className="dialog-content">
|
||||
<p className="dialog-message">{message}</p>
|
||||
<div className="dialog-buttons">
|
||||
<button onClick={onCancel} className="cancel-button">
|
||||
Cancel
|
||||
</button>
|
||||
<button onClick={onConfirm} className="confirm-button">
|
||||
Confirm
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
export const EmptyState = () => {
|
||||
return (
|
||||
<div className="empty-state">
|
||||
<p className="empty-message">No todos yet!</p>
|
||||
<p className="empty-hint">Add your first todo above to get started.</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,43 @@
|
||||
import { useState, FormEvent } from 'react';
|
||||
|
||||
interface TodoFormProps {
|
||||
onAddTodo: (title: string) => Promise<void>;
|
||||
}
|
||||
|
||||
export const TodoForm = ({ onAddTodo }: TodoFormProps) => {
|
||||
const [title, setTitle] = useState('');
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
const handleSubmit = async (e: FormEvent) => {
|
||||
e.preventDefault();
|
||||
|
||||
const trimmedTitle = title.trim();
|
||||
if (!trimmedTitle) return;
|
||||
|
||||
try {
|
||||
setIsSubmitting(true);
|
||||
await onAddTodo(trimmedTitle);
|
||||
setTitle('');
|
||||
} catch (err) {
|
||||
console.error('Failed to add todo:', err);
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit} className="todo-form">
|
||||
<input
|
||||
type="text"
|
||||
value={title}
|
||||
onChange={(e) => setTitle(e.target.value)}
|
||||
placeholder="Add a new todo..."
|
||||
disabled={isSubmitting}
|
||||
className="todo-input"
|
||||
/>
|
||||
<button type="submit" disabled={isSubmitting || !title.trim()} className="add-button">
|
||||
{isSubmitting ? 'Adding...' : 'Add Todo'}
|
||||
</button>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,36 @@
|
||||
import { Todo } from '../api/todos';
|
||||
|
||||
interface TodoItemProps {
|
||||
todo: Todo;
|
||||
onToggle: (id: number) => Promise<void>;
|
||||
onDelete: (id: number) => Promise<void>;
|
||||
}
|
||||
|
||||
export const TodoItem = ({ todo, onToggle, onDelete }: TodoItemProps) => {
|
||||
const handleToggle = () => {
|
||||
onToggle(todo.id);
|
||||
};
|
||||
|
||||
const handleDelete = () => {
|
||||
onDelete(todo.id);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="todo-item">
|
||||
<div className="todo-content">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={todo.completed}
|
||||
onChange={handleToggle}
|
||||
className="todo-checkbox"
|
||||
/>
|
||||
<span className={todo.completed ? 'todo-title completed' : 'todo-title'}>
|
||||
{todo.title}
|
||||
</span>
|
||||
</div>
|
||||
<button onClick={handleDelete} className="delete-button">
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,27 @@
|
||||
import { Todo } from '../api/todos';
|
||||
import { TodoItem } from './TodoItem';
|
||||
|
||||
interface TodoListProps {
|
||||
todos: Todo[];
|
||||
onToggle: (id: number) => Promise<void>;
|
||||
onDelete: (id: number) => Promise<void>;
|
||||
}
|
||||
|
||||
export const TodoList = ({ todos, onToggle, onDelete }: TodoListProps) => {
|
||||
if (todos.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="todo-list">
|
||||
{todos.map(todo => (
|
||||
<TodoItem
|
||||
key={todo.id}
|
||||
todo={todo}
|
||||
onToggle={onToggle}
|
||||
onDelete={onDelete}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user