Build an AI-Powered Todo List with Laravel 11, Livewire 3, and OpenAI

Abu Sayed
5 min readSep 26, 2024

--

Learn how to create a dynamic, AI-enhanced Todo List application using Laravel 11, Livewire 3, and OpenAI. Perfect for beginners and intermediate developers looking to integrate AI into web applications.

Laravel 11, Livewire 3, and OpenAI: Building an AI-Enhanced Todo List
Laravel 11, Livewire 3, and OpenAI: Building an AI-Enhanced Todo List

Hey there, future AI-powered web developers! 👋 Today, we’re going to take our Laravel and Livewire skills to the next level by integrating OpenAI’s powerful language model into our Todo List application. We’ll create a smart todo list that can understand natural language, suggest task improvements, and even generate new tasks based on your existing ones. Excited? Let’s dive in!

Prerequisites

Before we start, make sure you have:

  • PHP 8.2 or higher installed
  • Composer installed
  • Node.js and NPM installed
  • Basic knowledge of Laravel and Livewire
  • An OpenAI API key (sign up at https://openai.com/ if you haven’t already)

Step 1: Setting Up the Project

Let’s start by creating a new Laravel project and installing Livewire:

composer create-project laravel/laravel ai-todo-list
cd ai-todo-list
composer require livewire/livewire

Next, let’s install the OpenAI PHP client:

composer require openai-php/client

Step 2: Configure OpenAI API Key

Add your OpenAI API key to the .env file:

OPENAI_API_KEY=your_api_key_here

Step 3: Create the Task Model and Migration

Let’s create our Task model and migration:

php artisan make:model Task -m

Edit the migration file (database/migrations/xxxx_xx_xx_create_tasks_table.php):

public function up()
{
Schema::create('tasks', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('description')->nullable();
$table->boolean('is_completed')->default(false);
$table->timestamps();
});
}

Run the migration:

php artisan migrate

Step 4: Create the Livewire Component

Create a Livewire component for our AI-enhanced Todo list:

php artisan make:livewire AiTodoList

Edit the app/Http/Livewire/AiTodoList.php file:

<?php
namespace App\Http\Livewire;use Livewire\Component;
use App\Models\Task;
use OpenAI\Client;
class AiTodoList extends Component
{
public $tasks;
public $newTaskTitle = '';
public $newTaskDescription = '';
public $editingTaskId;
public $editingTaskTitle;
public $editingTaskDescription;
public $aiSuggestion = '';
protected $rules = [
'newTaskTitle' => 'required|min:3',
'newTaskDescription' => 'nullable',
];
public function mount()
{
$this->tasks = Task::all();
}
public function render()
{
return view('livewire.ai-todo-list');
}
public function addTask()
{
$this->validate();
Task::create([
'title' => $this->newTaskTitle,
'description' => $this->newTaskDescription,
]);
$this->newTaskTitle = '';
$this->newTaskDescription = '';
$this->tasks = Task::all();
}
public function toggleComplete($taskId)
{
$task = Task::find($taskId);
$task->is_completed = !$task->is_completed;
$task->save();
$this->tasks = Task::all();
}
public function editTask($taskId)
{
$this->editingTaskId = $taskId;
$task = Task::find($taskId);
$this->editingTaskTitle = $task->title;
$this->editingTaskDescription = $task->description;
}
public function updateTask()
{
$this->validate([
'editingTaskTitle' => 'required|min:3',
'editingTaskDescription' => 'nullable',
]);
$task = Task::find($this->editingTaskId);
$task->title = $this->editingTaskTitle;
$task->description = $this->editingTaskDescription;
$task->save();
$this->editingTaskId = null;
$this->tasks = Task::all();
}
public function deleteTask($taskId)
{
Task::destroy($taskId);
$this->tasks = Task::all();
}
public function getAiSuggestion()
{
$client = OpenAI::client(env('OPENAI_API_KEY'));
$existingTasks = $this->tasks->pluck('title')->implode(', '); $response = $client->chat()->create([
'model' => 'gpt-3.5-turbo',
'messages' => [
['role' => 'system', 'content' => 'You are a helpful assistant that suggests tasks based on existing ones.'],
['role' => 'user', 'content' => "Based on these existing tasks: $existingTasks, suggest a new relevant task."],
],
]);
$this->aiSuggestion = $response->choices[0]->message->content;
}
public function improveTaskDescription($taskId)
{
$task = Task::find($taskId);

$client = OpenAI::client(env('OPENAI_API_KEY'));
$response = $client->chat()->create([
'model' => 'gpt-3.5-turbo',
'messages' => [
['role' => 'system', 'content' => 'You are a helpful assistant that improves task descriptions.'],
['role' => 'user', 'content' => "Improve this task description: {$task->description}"],
],
]);
$task->description = $response->choices[0]->message->content;
$task->save();
$this->tasks = Task::all();
}
}

Step 5: Create the Livewire Component View

Edit the resources/views/livewire/ai-todo-list.blade.php file:

<div>
<h1 class="text-3xl font-bold mb-4">AI-Enhanced Todo List</h1>
    <form wire:submit.prevent="addTask" class="mb-4">
<input type="text" wire:model="newTaskTitle" placeholder="Add a new task" class="border p-2 mr-2">
<textarea wire:model="newTaskDescription" placeholder="Task description (optional)" class="border p-2 mr-2"></textarea>
<button type="submit" class="bg-blue-500 text-white px-4 py-2 rounded">Add</button>
</form>
<button wire:click="getAiSuggestion" class="bg-green-500 text-white px-4 py-2 rounded mb-4">Get AI Suggestion</button> @if($aiSuggestion)
<div class="bg-yellow-100 p-4 mb-4 rounded">
<h3 class="font-bold">AI Suggestion:</h3>
<p>{{ $aiSuggestion }}</p>
</div>
@endif
<ul>
@foreach($tasks as $task)
<li class="mb-4 p-4 border rounded">
@if($editingTaskId === $task->id)
<input type="text" wire:model="editingTaskTitle" class="border p-2 mb-2 w-full">
<textarea wire:model="editingTaskDescription" class="border p-2 mb-2 w-full"></textarea>
<button wire:click="updateTask" class="bg-blue-500 text-white px-4 py-2 rounded mr-2">Save</button>
@else
<h3 class="font-bold {{ $task->is_completed ? 'line-through' : '' }}">{{ $task->title }}</h3>
<p>{{ $task->description }}</p>
<div class="mt-2">
<button wire:click="toggleComplete({{ $task->id }})" class="bg-green-500 text-white px-4 py-2 rounded mr-2">
{{ $task->is_completed ? 'Undo' : 'Complete' }}
</button>
<button wire:click="editTask({{ $task->id }})" class="bg-yellow-500 text-white px-4 py-2 rounded mr-2">Edit</button>
<button wire:click="deleteTask({{ $task->id }})" class="bg-red-500 text-white px-4 py-2 rounded mr-2">Delete</button>
<button wire:click="improveTaskDescription({{ $task->id }})" class="bg-purple-500 text-white px-4 py-2 rounded">Improve Description</button>
</div>
@endif
</li>
@endforeach
</ul>
</div>

Step 6: Update the Route

Edit the routes/web.php file to use our new Livewire component:

use App\Http\Livewire\AiTodoList;
Route::get('/', AiTodoList::class);

Step 7: Add Tailwind CSS (Optional)

For better styling, let’s add Tailwind CSS:

npm install -D tailwindcss@latest postcss@latest autoprefixer@latest
npx tailwindcss init -p

Update the tailwind.config.js file:

module.exports = {
content: [
"./resources/**/*.blade.php",
"./resources/**/*.js",
"./resources/**/*.vue",
],
theme: {
extend: {},
},
plugins: [],
}

Create a new CSS file at resources/css/app.css:

@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';

Update your resources/views/welcome.blade.php to include the compiled CSS:

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>AI-Enhanced Todo List</title>
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
@livewireStyles
</head>
<body class="antialiased">
<div class="container mx-auto mt-8">
@livewire('ai-todo-list')
</div>
    @livewireScripts
</body>
</html>

Compile the assets:

npm run dev

Conclusion

Congratulations! You’ve just built an AI-enhanced Todo List application using Laravel 11, Livewire 3, and OpenAI. This app demonstrates how to:

  • Create, read, update, and delete tasks using Livewire
  • Use OpenAI to generate task suggestions based on existing tasks
  • Improve task descriptions using AI

This is just the beginning of what you can do with AI in web applications. You could expand this further by:

  • Using AI to categorize tasks automatically
  • Generating entire task lists based on a project description
  • Analyzing task completion patterns and suggesting productivity improvements

Remember, when working with AI, always review the generated content to ensure it meets your needs and standards. Happy coding, and enjoy your new AI-powered productivity tool! 🚀🤖📝

--

--

Abu Sayed
Abu Sayed

Written by Abu Sayed

Bangladeshi Full Stack Web Dev, Sys Admin & DevOps Engineer. Skills: Data analysis, SQL, Unity, C#. Python, PHP & Laravel. Me on: bd.linkedin.com/in/imabusayed

No responses yet