Fix: Ensure all skills are tracked as files, not submodules

This commit is contained in:
sck_0
2026-01-14 18:48:48 +01:00
parent 7f46ed8ca1
commit 8bd204708b
1113 changed files with 82065 additions and 2 deletions

View File

@@ -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>
);
};

View File

@@ -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>
);
};

View File

@@ -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>
);
};

View File

@@ -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>
);
};

View File

@@ -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>
);
};