Build an Event Management App with Laravel and Twilio SendGrid
Build an Event Management App with Laravel and Twilio SendGrid
Event management platforms are quite common in today's interconnected world.
They serve as the backbone for organizing gatherings, from intimate workshops to grand conferences, providing a seamless bridge between hosts and attendees. Such platforms not only streamline the planning process but also enhance the overall event experience through efficient management and communication tools.
In this tutorial, I'll show you how to build "EventVoyage", an event management application using Laravel and Twilio SendGrid.
Prerequisites
To complete the tutorial you will need the following:
- A Twilio account (either free or paid). If you are new to Twilio, click here to create a free account
- A SendGrid account (either free or paid). If you are new to SendGrid, click here to create a free account. You also need to have an email address with a verified Sender Identity
- A basic understanding of and experience with PHP and Laravel
- Docker Desktop (or Docker Engine)
Application overview
Before we begin building the application, I want to give you a broad overview of the application's user flow.
The EventVoyage application is a minimal viable product (MVP) designed to demonstrate the intricacies of event management and participation; offering a streamlined user experience for both event organizers and attendees.
Once logged in, event organizers are welcomed into their dashboard, a central hub where they can view, create, and manage their events. The process of creating an event is intuitive, requiring organizers to input details such as the event's title, description, date, time, and location.
Upon the creation or editing of an event, Twilio SendGrid steps in to send email notifications, confirming actions taken by the organizers and informing attendees of any updates.
Attendees, on the other hand, are presented with a curated list of upcoming and past events, allowing them to explore and register for events with ease. Each registration triggers an automatic email confirmation, ensuring attendees are well-informed and their participation is recorded. Attendees also benefit from the ability to manage their registrations, including the option to unregister from events.
Email notifications, which would be powered by Twilio SendGrid, play a pivotal role throughout the user journey. They serve as a reliable communication channel between organizers and attendees. Both groups have access to interactive dashboards tailored to their needs, displaying relevant information such as upcoming events, past events, and registration statuses.
Build the app
Set up the Laravel application
The first thing we need to do is to create a new Laravel application. To create the project, named EventVoyage, open your terminal and run the following command:
This command downloads and runs a script to set up your Laravel project and integrates Laravel Sail; a light-weight command-line interface for interacting with Docker, to build a local development environment with all of the services and dependencies which the application needs.
At the end of the process, you'll be asked the following:
Once completed, navigate into your project directory:
To start your Docker containers, including all the services e.g., MySQL and Redis, execute the following command:
Finally, open another terminal in your project directory. There, run the initial database migrations to populate the database with the default tables from Laravel by running the following command in a new terminal tab or session:
Once the application's started, you can access the application in your web browser at http://localhost.
Set up authentication with Laravel Breeze
Next, we will give your application a head-start by installing Laravel Breeze, a simple implementation of authentication features, such as login, registration, email verification, and password reset.
To install Breeze, execute the following commands:
After installing Breeze, compile the frontend assets with:
If you refresh your Laravel application in the browser, you should now see a Register link at the top-right. Follow that link to see the registration form provided by Laravel Breeze.
Then, register a new account and log in.
Set up Twilio SendGrid
To integrate Twilio SendGrid into the application, first, sign in to your SendGrid account and obtain your API key. To obtain your API key, navigate to Settings > API Keys. Once there, click on the "Create API Key" button in the top right corner of the page. Give the new API key a name, accept the default permission of “Full Access”, then click “Create & View”.
Then, update your .env file with the following details:
After that, replace <your_sendgrid_api_key_here>
with your newly generated API key, and < your_email@example.com>
with your Single Sender Verified email address. This configuration tells Laravel to use SendGrid as the mail driver, and sets the default from address and name for your emails.
Create and update events
Now you'll work on the core feature that enables users to create events.
Add models, migrations, and controllers
To allow users to create events, you will need to create models, migrations, and controllers. You can create a model, migration, and resource controller for the events with the following command:
Executing this command generates three essential files:
- Firstly, app/Models/Event.php is created as the Eloquent model, which serves as the ORM (Object-Relational Mapping) component, linking the event data structure to the application's database.
- Secondly, a database migration file ending with _create_events_table.php is created within the database/migrations directory. This migration outlines the schema for the event table in the database, specifying how it should be constructed. Lastly, app/Http/Controllers/EventController.php is the HTTP controller. This controller is responsible for handling incoming requests related to events and generating the appropriate responses, thereby bridging the gap between the user interface and the database operations.
In addition to the event resources we just generated, let's create a registration resource. This will handle all the registration logistics between a user and an event. Run the following command to create the resource:
In the updated up()
method, several fields were defined in the events table to store event details. These include a primary key id
, a user_id
as a foreign key linked to the users table with cascading delete functionality, and fields for the title
, description
, date
, time
, and location
of the event. Additionally, Laravel's timestamps()
method automatically adds created_at
and updated_at
columns to track when each event was created and last updated.
Similarly, update the up()
method of the migration file ending with _create_registration_table.php with the following:
This structures the registrations table to track user registrations for events. The setup includes an id
as the primary key, and two foreign keys: user_id
and event_id
.
The user_id
links the registration to a specific user, and event_id
associates it with a particular event, both employing constraints for referential integrity and cascading deletes to remove registrations if a user or event is deleted. The inclusion of timestamps()
automatically adds created_at
and updated_at
columns, allowing the application to record when a registration is created or modified.
Run the migration again to update the database with these changes:
Set up the relationship
Now, you need to establish a relationship between an event and a user, and a relationship between a registration and an event. Update app\Models\Event.php with the following properties and methods:
Then, add the following properties and methods to the app\Models\Registration.php file:
After that, add the following properties and methods to the app\Models\User.php file.
After that, add the following import:
In the Event
model, you have introduced methods to not only protect all attributes from mass assignment via the $guarded
property, but also to establish a one-to-many relationship with the Registration
model. This is achieved through the registrations()
method, indicating that an event can have multiple registrations.
Additionally, the isUserRegistered()
method utilizes this relationship to check if a specific user has registered for the event, enhancing the model's functionality. The $casts
property is set to ensure the date attribute is correctly cast to a Date
instance, facilitating easier date manipulation.
In the Registration
model, similar protection against mass assignment is provided. The model defines relationships back to the User
and Event
models, signifying that each registration is linked to a single user and a single event. These relationships are important for navigating between users, their registrations, and the events they are interested in.
Lastly, the User
model outlines the user's connections to events and registrations. Through the events()
method, a one-to-many relationship is established, showing that a user can create multiple events. The registrations method further connects a user to their event registrations.
Add the routing configuration
To configure URLs for your controller, leverage the resource controller, utilizing the Route::resource()
statement to define a comprehensive set of routes that follow a conventional URL structure.
You can secure these routes with two pieces of middleware:
- The
auth
middleware, which restricts access to authenticated users - The
verified
middleware, which further limits access to users who have verified their accounts.
For the registration route, you will need to apply the only()
method alongside the Route::resource()
statement. This method allows you to explicitly define which controller actions are accessible, as you would only be needing the store()
and destroy()
methods here.At the end of the routes/web.php file, add the following to set up the routes:
Ensure you also include the necessary (below) use statements for
EventController and
RegistrationController` at the beginning of the file:
This setup maps the controller actions to specific routes, ensuring a structured and secure way to handle event and registration management within the application.
Create Mailables
You now need to create Mailable classes that will allow users to send emails, by running the following command:
This generates an EventCreated
mailable class with a corresponding Markdown template. Open this file, app\Mail\EventCreated.php, and update the content()
method with the following:
This method constructs and returns a Content
object for an email, utilizing a Markdown template with specific event details, such as title, date, location, and event ID. Ensure you also include the necessary use
statement for the Event
model at the top of the file, and pass a protected
instance of the Event
model in the constructor, as shown in the code below:
Secondly, generate a similar Mailable class for emails sent when an event is updated, by running the following command:
Then, in app\Mail\EventUpdated.php update the content()
method:
Then, import the Event
model, and create an Event
instance in the constructor
This creates a dependency between the Event
model and the EventUpdated
mailable class.
Finally, generate a Mailable class for when a user registers for an event:
Then, in app\Mail\EventRegistered.php, update the content()
method, with the following:
Finally, pass the Event
model into the constructor of the EventRegistered
Mailable class. This creates a dependency between the Event
model and the EventRegistered
mailable class.
Add the EventController's methods
Before updating the Markdown templates that were generated, you're first going to build out the controller methods. To handle displaying an event, in app/Http/Controllers/EventController.php import the following files:
Then update the stub index()
method with the following:
The method retrieves and categorizes events into two groups: upcoming events, which are those scheduled for today or in the future, and past events, which are those that have already occurred.
The method utilizes the Carbon library to compare event dates against the current date, ensuring accurate categorization. Then, it passes these categorized events to the yet to be created events.index
view.
Next, handle displaying the form for creating an event by updating the stub create()
method with the following:
This returns the yet to be created view for creating an event.
Next, handle the logic that saves an event in the database. Update the stub store()
method with the following:
- validates the incoming request data for creating an event
- creates the event associated with the current user
- attempts to send an email notification about the event creation
- logs any email sending failures
- and finally redirects to the events index page.
To display a single event, update the show()
method with the following:
This method displays a specific event by returning the events.show
view with the event data passed to it.
Next, add the method that displays a form for editing an event. Your edit()
method should look like this:
This method checks if the currently authenticated user is the creator of the specified event. If so, it returns the view to edit the event. If the user is not authorized, it redirects them to the yet to be created events index page with an error message indicating the lack of authorization.
Finally, to update an event, enter the following for the update()
method:
This method updates an event after validating the current user's authorization and the request data. It sends an email notification about the event update to the event creator and all registered users. If email sending fails, it logs the error and returns an error message. Then, it redirects to the event's detail page with a success message.
Add the RegistrationController's methods
Now, you need to create the logistics of users registering and unregistering for an event. First, make sure the following files are imported on the top of app/Http/Controllers/RegisterController.php:
Next, update the store()
method with the following:
This method handles the registration process for an event. It first checks if the currently authenticated user is already registered for the specified event to prevent duplicate registrations. If not already registered, it proceeds to create a new registration record linking the user to the event.
After successfully registering, it attempts to send an email notification to the user confirming their registration. If the email sending process fails, it logs the error and returns an error message. Then, the method concludes by returning a success message indicating the successful registration.
Finally update the destroy()
method with the following:
This method facilitates the cancellation of an event registration. It locates the registration by its ID and checks if the currently authenticated user is the one who made the registration. If the user is not the registrant, it returns an error message indicating the lack of permission to cancel. If the check passes, it deletes the registration from the database and returns a success message confirming the cancellation.
Implement the dashboard
Now, you need to build out the functionality that lists events created and attended by a user. Run the following command to generate a dashboard controller:
Then, replace the content of this controller (app/Http/Controllers/DashboardController.php) with the following:
The dashboard method retrieves all events created by the authenticated user and passes them to the dashboard view. The attending method fetches events the user is registered to attend, separating them into upcoming and past events based on the current date. Both sets of data are then passed to the attending view. This allows users to view their own events and the events they are attending, organized by date.
Given these new methods, you need to update the routes\web.php file. First, include the dashboard controller at the top of the file
Then, replace the default dashboard route with routes to the DashboardController
classes:
The routes are protected by two middleware classes: auth
and verified
, meaning that only authenticated and email-verified users can access this route.
Create the application's views
Now, you should create the application's views. The views are typically located in the resources\views directory. To speed up development, Tailwind CSS was used for styling on all views.
Create the homepage view
First, create the homepage. In the welcome.blade.php file, replace the content with the following:
The main content section promotes the event management features of the application, including a call-to-action button for creating events, and showcases various event categories with icons.
Additional sections highlight customer testimonials and display contact information. The footer contains copyright information and links to terms of service and privacy policies, providing necessary legal and navigational links for users.
At the top, there is a header with a logo and navigation links that change based on user authentication status, offering links to login, register, or access the dashboard. Here is what the homepage will look like:
Create the dashboard view
The dashboard showcases events created by the currently logged in user. Replace the content of dashboard.blade.php with the following:
The dashboard displays the user's events within a clean, responsive layout using the <x-app-layout>
component. It features a container with padding and a maximum width for centering. Inside, a card with a white background and shadow effect contains a header titled "My Events."
The user's events are rendered in a responsive grid, transitioning to two columns on medium screens, and three on large. Each event card links to its detailed view, showing the event's title, formatted date, and location. If no events exist, a fallback message is displayed, ensuring graceful degradation of the UI.
Next, you should create a view that lists the events the user is attending. Still in the resources\views directory, create a file named attending.blade.php and paste the following into the file:
This view allows users to toggle between upcoming and past events the user registered for. It displays the events in a grid layout, showing details like the event title, date, time, and location. If there are no events to display, a message indicates that. JavaScript is used to control the visibility of the sections, allowing users to switch between upcoming and past events by clicking the respective buttons.
Create the event view
Now, you need to create views that handle creating an event, editing an event, showing an event and listing upcoming and past events. For creating an event, in the directory resources\views create a directory named events. In this directory, create a file named create.blade.php, and paste the following into the file:
This template renders a form that allows users to create a new event. The form includes input fields for the event's title, description, date, time, and location, each marked as required.
Upon submission, the form data is sent via a POST request to the events.store
route. The template also checks for validation errors for each field and displays any error messages below the corresponding input.
Next, create a file edit.blade.php in the same directory, and enter the following:
This Blade template renders a form for editing an existing event. It pre-fills the form fields with the current event data, allowing the user to update the event's title, description, date, time, and location. The form uses the HTTP PUT method and sends the updated data to the events.update route with the event's ID. Validation errors for each field are displayed below the respective input.
Next, create a file show.blade.php in the same directory and enter the following:
This Blade template displays detailed information about an event, including its title, description, date, time, and location. It also provides conditional controls based on the authenticated user's relationship to the event.
If the authenticated user is the event's creator, an " Edit" button is displayed, allowing them to navigate to the event's edit page. If the user is registered for the event, an " Unregister" button appears, enabling them to cancel their registration. If the user is not registered, a " Register" button is shown, allowing them to sign up for the event.
Finally, create a file index.blade.php in the same directory and enter the following:
This template presents a dynamic event listing page with flash messaging for user feedback. At the top, a header labeled "Events" introduces the page, accompanied by two buttons that allow users to toggle between viewing upcoming and past events. Below, any flash messages from event creation attempts, whether successful or failed, are displayed prominently to provide immediate feedback to the user.
The event data is rendered in a responsive grid format, where each event's title, date, time, and location are displayed, and each event links to its detail page. The @forelse
directive is used to handle cases where there are no events to display.
The JavaScript code attached to the buttons enables the toggling functionality between upcoming and past event sections, ensuring only the relevant events are shown based on the user's selection.
Add view navigation
Next, add links to the navigation menu provided by Laravel Breeze by updating the navigation section in resources\views\layouts\navigation.blade.php file:
For mobile screens:
Now, update the navigation items for creating an event:
For mobile screens:
An authenticated user would now see the following links on the navigation pane:
Create the notification mails template
When you generated the mailable classes, the corresponding views were also created. You can find these at the resources\views\mail\events directory. You should update these files with information relevant to their purpose. Replace the content of the created.blade.php file with the following:
This Blade template is used to generate an email notification informing the recipient that a new event has been created. It dynamically inserts the event's title, date, and location into the email body. The template also includes a button that links to the event's page, using the event ID to construct the URL. The email is concluded with a signature that includes the application's name.
Next, replace the content of the registered.blade.php file with the following:
This Blade template generates an email notification confirming the recipient's registration for an event. It displays the event's title, date, and location, and includes a button linking to the event's page, constructed using the event ID. The email ends with a signature featuring the application's name.
Finally, replace the content of the updated.blade.php file with the following:
This Blade template is used to create an email notification informing the recipient that an event has been updated. It displays the event's updated title, date, and location, and includes a button linking to the event's page, allowing the recipient to view the updated details. The email concludes with a signature that includes the application's name.
Congratulations, you’ve finished coding the app!
Test your work
It's time to test that the app works properly. In your browser, visit http://localhost. Click on Register on the navigation bar and create an account. You will be redirected to the dashboard, which is currently empty. Click Create Event on the navigation bar, where you will see the form for creating a new event:
Enter the details of an event and click the Create Event button to submit the form. This redirects you to the events page which will look similar to this after creating several events:
Click on an event to view details of that event. Here you can register for the event or edit the event if you are the creator:
Click on Register. You should receive an email confirming your registration for the event:
You would also receive similar emails when you create or update an event.
That's how to build an event management app with Laravel and Twilio SendGrid
In this tutorial, you successfully built a simple event management application with Laravel, integrating Twilio SendGrid for seamless email delivery. By following the steps, you’ve gained hands-on experience with setting up email notifications and managing events efficiently. To continue improving your app, consider exploring Twilio SendGrid’s advanced features like email analytics and templates.
You can find the full source code of this app here.
Caleb Oki is a Senior Software Developer with extensive experience in building robust applications using Laravel, TypeScript, and Vue. He has a passion for teaching and has created backend development courses, sharing his expertise with students and professionals alike. Connect with him on Linkedin or via email at caleboki@gmail.com.
Related Posts
Related Resources
Twilio Docs
From APIs to SDKs to sample apps
API reference documentation, SDKs, helper libraries, quickstarts, and tutorials for your language and platform.
Resource Center
The latest ebooks, industry reports, and webinars
Learn from customer engagement experts to improve your own communication.
Ahoy
Twilio's developer community hub
Best practices, code samples, and inspiration to build communications and digital engagement experiences.