DEV Community

syauqi fuadi
syauqi fuadi

Posted on • Edited on

Create Task manager using react typescript

Hey there! Let's create a simple but good-looking React app using some modern tools. We'll make a task management app that's actually useful and looks decent. No boring stuff - let's jump right in!

Setting Up the Project

First, let's create our project. Open your terminal and run:

npm create vite@latest my-task-app -- --template react-ts
cd my-task-app
Enter fullscreen mode Exit fullscreen mode

Now, let's add Tailwind CSS for styling:

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
Enter fullscreen mode Exit fullscreen mode

Quick Configuration

Update your tailwind.config.js:

export default {
  content: [
    "./index.html",
    "./src/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
Enter fullscreen mode Exit fullscreen mode

Add Tailwind to your src/index.css:

@tailwind base;
@tailwind components;
@tailwind utilities;
Enter fullscreen mode Exit fullscreen mode

Let's Build Something Cool

We'll create a task manager with the ability to add, complete, and delete tasks. First, let's define our task type in src/types.ts:

export interface Task {
  id: number;
  text: string;
  completed: boolean;
}
Enter fullscreen mode Exit fullscreen mode

Now, let's create our main app in src/App.tsx:

import { useState } from 'react'
import { Task } from './types'

function App() {
  const [tasks, setTasks] = useState<Task[]>([])
  const [newTask, setNewTask] = useState('')

  const addTask = () => {
    if (!newTask.trim()) return

    setTasks([
      ...tasks,
      {
        id: Date.now(),
        text: newTask,
        completed: false
      }
    ])
    setNewTask('')
  }

  const toggleTask = (id: number) => {
    setTasks(tasks.map(task => 
      task.id === id ? { ...task, completed: !task.completed } : task
    ))
  }

  const deleteTask = (id: number) => {
    setTasks(tasks.filter(task => task.id !== id))
  }

  return (
    <div className="min-h-screen bg-gray-100 py-8">
      <div className="max-w-md mx-auto bg-white rounded-lg shadow-md p-6">
        <h1 className="text-2xl font-bold text-center mb-6">Task Manager</h1>

        <div className="flex mb-4">
          <input
            type="text"
            value={newTask}
            onChange={(e) => setNewTask(e.target.value)}
            className="flex-1 p-2 border rounded-l-lg focus:outline-none focus:border-blue-500"
            placeholder="Add a new task..."
          />
          <button
            onClick={addTask}
            className="bg-blue-500 text-white px-4 rounded-r-lg hover:bg-blue-600"
          >
            Add
          </button>
        </div>

        <div className="space-y-2">
          {tasks.map((task) => (
            <div
              key={task.id}
              className="flex items-center p-3 bg-gray-50 rounded-lg"
            >
              <label className="flex items-center flex-1 cursor-pointer">
                <input
                  type="checkbox"
                  checked={task.completed}
                  onChange={() => toggleTask(task.id)}
                  className="mr-3 h-4 w-4 cursor-pointer accent-blue-500"
                />
                <span
                  className={`flex-1 ${
                    task.completed ? "line-through text-gray-500" : ""
                  }`}
                >
                  {task.text}
                </span>
              </label>
              <button
                onClick={() => deleteTask(task.id)}
                className="text-red-500 hover:text-red-700"
              >
                Delete
              </button>
            </div>
          ))}
        </div>
      </div>
    </div>
  )
}

export default App
Enter fullscreen mode Exit fullscreen mode

Running the App

Start the development server:

npm run dev
Enter fullscreen mode Exit fullscreen mode

That's it! You now have a functional task manager with a clean, modern look. Here's what we've built:

  • A responsive layout with a centered card design
  • Input field with a connected add button
  • Task list with completion toggling and deletion
  • Clean animations and hover states
  • TypeScript for type safety
  • Modern styling with Tailwind CSS

Making It Even Better

Want to take it further? Here are some quick improvements you could add:

  1. Add local storage to persist tasks:
// Add and update to App.tsx
// Initialize state with a function that checks localStorage
  const [tasks, setTasks] = useState<Task[]>(() => {
    const savedTasks = localStorage.getItem('tasks')
    return savedTasks ? JSON.parse(savedTasks) : []
  })
  const [newTask, setNewTask] = useState('')

  // Only need one useEffect to handle updates
  useEffect(() => {
    localStorage.setItem('tasks', JSON.stringify(tasks))
  }, [tasks])

  // Rest of your code remains the same
Enter fullscreen mode Exit fullscreen mode
  1. Add keyboard support:
// Add to input element
onKeyPress={(e) => {
  if (e.key === 'Enter') addTask()
}}
Enter fullscreen mode Exit fullscreen mode

That's all! You now have a modern React app that's actually useful and looks good. The best part? It's built with modern tools and best practices, but keeps things simple and maintainable.

Want to experiment? Try adding categories, due dates, or priority levels to make it even more useful!

Remember: Good code doesn't have to be complicated. Keep it simple, readable, and functional! 🚀

Top comments (0)