a2zwebltd / laravel-customer-support
A portable Laravel customer support / helpdesk engine — tickets, threaded replies, attachments, SLA tracking, mail notifications, Livewire UI, and Nova admin.
Package info
github.com/a2zwebltd/laravel-customer-support
pkg:composer/a2zwebltd/laravel-customer-support
Requires
- php: ^8.2
- laravel/framework: ^11.0|^12.0|^13.0
- spatie/laravel-medialibrary: ^11.0
Requires (Dev)
- laravel/pint: ^1.25
- livewire/livewire: ^3.0|^4.0
- orchestra/testbench: ^9.0|^10.0|^11.0
- pestphp/pest: ^3.0|^4.0
- pestphp/pest-plugin-laravel: ^3.0|^4.0
Suggests
- laravel/nova: Auto-registers Nova resources (SupportTicket, SupportTicketMessage) when present.
- livewire/flux: Recommended UI component library used by the bundled Blade templates.
- livewire/livewire: Enables the reactive Livewire UI layer (TicketsIndex, TicketCreate, TicketShow components).
Provides
None
Conflicts
None
Replaces
None
README
A portable Laravel customer-support / helpdesk engine — tickets with threaded replies, attachments, internal notes, agent assignment, SLA tracking, mail notifications, a Livewire + Flux UI, and Nova admin resources.
Designed to drop into any Laravel app with minimal wiring while remaining fully customisable.
Screenshots
| Agent dashboard | New ticket |
|---|---|
![]() |
![]() |
| Ticket details | Nova admin |
|---|---|
![]() |
![]() |
Requirements
- PHP 8.2+
- Laravel 11 / 12 / 13
livewire/livewire^3 or ^4 (for the bundled UI)livewire/flux^2 (recommended — Blade templates use Flux components)spatie/laravel-medialibrary^11 (attachments)laravel/nova^5 (optional — auto-registers Nova resources when present)
Installation
composer require a2zwebltd/laravel-customer-support
php artisan migrate
php artisan vendor:publish --tag=customer-support-config # optional
Add the trait to your User model:
use A2ZWeb\CustomerSupport\Concerns\HasSupportTickets; class User extends Authenticatable { use HasSupportTickets; }
Define the agent gate in AppServiceProvider::boot():
Gate::define('manage-support-tickets', fn (User $user) => $user->is_admin);
Without this gate nobody counts as an agent: agent replies are treated as customer replies (wrong status, no first_response_at) and /support/admin returns 403 for everyone.
Features
- Ticket statuses: Open, Pending, In Progress, Awaiting Customer, Resolved, Closed
- Priorities: Low / Normal / High / Urgent — each with configurable SLA hours
- Categories with configurable labels and icons (keys come from the
TicketCategoryenum) - Threaded replies (
SupportTicketMessage) - Internal notes (visible only to agents)
- Attachments via
spatie/laravel-medialibrary(on tickets and messages) - Agent assignment with
assigned_to - SLA timer (
due_at) +EscalateOverdueTicketsconsole command for cron escalation - Mail notifications: created / replied / status-changed / resolved (markdown, queueable)
- Domain events:
TicketCreated,TicketReplied,TicketStatusChanged,TicketAssigned - Policies on ticket + message resources
- Livewire + Flux UI (teal accent, dark-mode aware)
- Nova resources auto-registered when Nova is installed
Routes
| Method | URI | Name |
|---|---|---|
| GET | /support |
support.index |
| GET | /support/new |
support.create |
| GET | /support/{ticket} |
support.show |
| GET | /support/admin |
support.admin.dashboard |
(Prefix and middleware configurable in config/customer-support.php.)
Configuration
See config/customer-support.php. Highlights: user_model, routes, admin_gate, categories, sla_hours, mail.admin_recipients, attachments, nova, layout.
categorieskeys must beTicketCategoryenum values (bug,question,billing,feature_request,account,other). You can relabel, re-icon, reorder or remove them. The form saves unknown keys asother.nova.register_resources(defaulttrue),nova.group(defaultFeedback) andnova.user_resource(the Nova resource used for customer / assignee / author fields, defaultApp\Nova\User).layout(envCUSTOMER_SUPPORT_LAYOUT, defaultcomponents.layouts.app) must name a layout view that exists in your app.
Styling (Tailwind v4)
The views use literal Tailwind classes with a teal accent. Tailwind v4 does not scan vendor/, so add the package views as a source in resources/css/app.css, then rebuild:
@source '../../vendor/a2zwebltd/laravel-customer-support/resources/views/**/*.blade.php';
To change the accent colour (or anything else), publish the views with php artisan vendor:publish --tag=customer-support-views, edit them, and add @source '../views/vendor/customer-support/**/*.blade.php';. Published views take precedence over the package's and composer update does not refresh them, so re-sync them after upgrading.
The
theme.accentconfig key was removed in v1.1.0. It never reached the views.
Cron
// routes/console.php use Illuminate\Support\Facades\Schedule; Schedule::command('support:escalate-overdue')->hourly();
Testing
composer test
AI agents (Laravel Boost)
The package ships Laravel Boost resources: a short guideline (resources/boost/guidelines/core.blade.php) and the customer-support-development skill (resources/boost/skills/). They need Boost 2 or newer in the host app:
composer require laravel/boost --dev php artisan boost:install # first time php artisan boost:update --discover # already using Boost
Select a2zwebltd/laravel-customer-support when Boost lists the packages.
Security Vulnerabilities
If you discover a security vulnerability, please report it responsibly through private communication with the maintainers.
License
The MIT License (MIT). Please see License File for more information.
Credits
Developed and maintained by the A2Z WEB crew:
- Dawid Makowski
- Website: https://a2zweb.co/
- GitHub: https://github.com/a2zwebltd/



