mirror of
https://github.com/lukaszraczylo/filepuff-mcp.git
synced 2026-06-09 22:53:44 +00:00
Ho hum.
This commit is contained in:
Vendored
+129
@@ -0,0 +1,129 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
|
||||
interface ButtonProps {
|
||||
variant?: 'primary' | 'secondary';
|
||||
disabled?: boolean;
|
||||
onClick?: () => void;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* A reusable button component with Tailwind CSS styling
|
||||
*/
|
||||
export const Button: React.FC<ButtonProps> = ({
|
||||
variant = 'primary',
|
||||
disabled = false,
|
||||
onClick,
|
||||
children
|
||||
}) => {
|
||||
const baseClasses = 'font-bold py-2 px-4 rounded transition-colors duration-200';
|
||||
const variantClasses = {
|
||||
primary: 'bg-blue-500 hover:bg-blue-700 text-white',
|
||||
secondary: 'bg-gray-500 hover:bg-gray-700 text-white'
|
||||
};
|
||||
|
||||
return (
|
||||
<button
|
||||
className={`${baseClasses} ${variantClasses[variant]} ${disabled ? 'opacity-50 cursor-not-allowed' : ''}`}
|
||||
disabled={disabled}
|
||||
onClick={onClick}
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
interface TodoItem {
|
||||
id: number;
|
||||
text: string;
|
||||
completed: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Todo list component demonstrating React hooks and Tailwind
|
||||
*/
|
||||
export const TodoList: React.FC = () => {
|
||||
const [todos, setTodos] = useState<TodoItem[]>([
|
||||
{ id: 1, text: 'Learn React', completed: true },
|
||||
{ id: 2, text: 'Learn TypeScript', completed: true },
|
||||
{ id: 3, text: 'Build amazing apps', completed: false }
|
||||
]);
|
||||
const [inputValue, setInputValue] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
console.log('Todos updated:', todos);
|
||||
}, [todos]);
|
||||
|
||||
const addTodo = () => {
|
||||
if (inputValue.trim()) {
|
||||
const newTodo: TodoItem = {
|
||||
id: Date.now(),
|
||||
text: inputValue,
|
||||
completed: false
|
||||
};
|
||||
setTodos([...todos, newTodo]);
|
||||
setInputValue('');
|
||||
}
|
||||
};
|
||||
|
||||
const toggleTodo = (id: number) => {
|
||||
setTodos(todos.map(todo =>
|
||||
todo.id === id ? { ...todo, completed: !todo.completed } : todo
|
||||
));
|
||||
};
|
||||
|
||||
const deleteTodo = (id: number) => {
|
||||
setTodos(todos.filter(todo => todo.id !== id));
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="container mx-auto px-4 py-8 max-w-2xl">
|
||||
<h1 className="text-3xl font-bold text-gray-800 mb-6">
|
||||
My Todo List
|
||||
</h1>
|
||||
|
||||
<div className="flex gap-2 mb-6">
|
||||
<input
|
||||
type="text"
|
||||
value={inputValue}
|
||||
onChange={(e) => setInputValue(e.target.value)}
|
||||
onKeyPress={(e) => e.key === 'Enter' && addTodo()}
|
||||
placeholder="Add a new todo..."
|
||||
className="flex-1 px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
/>
|
||||
<Button onClick={addTodo}>Add</Button>
|
||||
</div>
|
||||
|
||||
<ul className="space-y-2">
|
||||
{todos.map(todo => (
|
||||
<li
|
||||
key={todo.id}
|
||||
className="flex items-center gap-3 p-4 bg-white rounded-lg shadow-sm hover:shadow-md transition-shadow"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={todo.completed}
|
||||
onChange={() => toggleTodo(todo.id)}
|
||||
className="w-5 h-5 text-blue-600 rounded focus:ring-2 focus:ring-blue-500"
|
||||
/>
|
||||
<span className={`flex-1 ${todo.completed ? 'line-through text-gray-400' : 'text-gray-700'}`}>
|
||||
{todo.text}
|
||||
</span>
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => deleteTodo(todo.id)}
|
||||
>
|
||||
Delete
|
||||
</Button>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
{todos.length === 0 && (
|
||||
<div className="text-center py-12 text-gray-400">
|
||||
No todos yet. Add one above!
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user