Created
October 2, 2025 17:16
-
-
Save dimasusername/7c3a7d711e531c6b1260215cf2cde66d to your computer and use it in GitHub Desktop.
Sonnet 4.5 One-Shot ToDo with `create to-do app in react with vite`
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { useState } from 'react'; | |
| import { Trash2, Plus, Check } from 'lucide-react'; | |
| export default function TodoApp() { | |
| const [todos, setTodos] = useState([]); | |
| const [input, setInput] = useState(''); | |
| const addTodo = () => { | |
| if (input.trim()) { | |
| setTodos([...todos, { id: Date.now(), text: input, completed: false }]); | |
| setInput(''); | |
| } | |
| }; | |
| const handleKeyPress = (e) => { | |
| if (e.key === 'Enter') { | |
| addTodo(); | |
| } | |
| }; | |
| const toggleTodo = (id) => { | |
| setTodos(todos.map(todo => | |
| todo.id === id ? { ...todo, completed: !todo.completed } : todo | |
| )); | |
| }; | |
| const deleteTodo = (id) => { | |
| setTodos(todos.filter(todo => todo.id !== id)); | |
| }; | |
| const remaining = todos.filter(t => !t.completed).length; | |
| return ( | |
| <div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100 flex items-center justify-center p-4"> | |
| <div className="bg-white rounded-2xl shadow-xl w-full max-w-md p-6"> | |
| <h1 className="text-3xl font-bold text-gray-800 mb-6 text-center">My Tasks</h1> | |
| <div className="mb-6"> | |
| <div className="flex gap-2"> | |
| <input | |
| type="text" | |
| value={input} | |
| onChange={(e) => setInput(e.target.value)} | |
| onKeyPress={handleKeyPress} | |
| placeholder="Add a new task..." | |
| className="flex-1 px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent" | |
| /> | |
| <button | |
| onClick={addTodo} | |
| className="bg-indigo-500 hover:bg-indigo-600 text-white px-4 py-3 rounded-lg transition-colors flex items-center gap-2" | |
| > | |
| <Plus size={20} /> | |
| </button> | |
| </div> | |
| </div> | |
| <div className="space-y-2 mb-4"> | |
| {todos.length === 0 ? ( | |
| <p className="text-center text-gray-400 py-8">No tasks yet. Add one above!</p> | |
| ) : ( | |
| todos.map(todo => ( | |
| <div | |
| key={todo.id} | |
| className="flex items-center gap-3 p-3 bg-gray-50 rounded-lg hover:bg-gray-100 transition-colors" | |
| > | |
| <button | |
| onClick={() => toggleTodo(todo.id)} | |
| className={`flex-shrink-0 w-6 h-6 rounded-md border-2 flex items-center justify-center transition-all ${ | |
| todo.completed | |
| ? 'bg-indigo-500 border-indigo-500' | |
| : 'border-gray-300 hover:border-indigo-400' | |
| }`} | |
| > | |
| {todo.completed && <Check size={16} className="text-white" />} | |
| </button> | |
| <span | |
| className={`flex-1 ${ | |
| todo.completed | |
| ? 'line-through text-gray-400' | |
| : 'text-gray-700' | |
| }`} | |
| > | |
| {todo.text} | |
| </span> | |
| <button | |
| onClick={() => deleteTodo(todo.id)} | |
| className="text-red-500 hover:text-red-700 transition-colors" | |
| > | |
| <Trash2 size={18} /> | |
| </button> | |
| </div> | |
| )) | |
| )} | |
| </div> | |
| {todos.length > 0 && ( | |
| <div className="text-center text-sm text-gray-600 pt-4 border-t border-gray-200"> | |
| {remaining} {remaining === 1 ? 'task' : 'tasks'} remaining | |
| </div> | |
| )} | |
| </div> | |
| </div> | |
| ); | |
| } |
Author
dimasusername
commented
Oct 2, 2025
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment