> For the complete documentation index, see [llms.txt](https://helpdocs.quickadminpanel.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://helpdocs.quickadminpanel.com/livewire+tailwind-version/quickadminpanel-livewire+tailwind-version.md).

# QuickAdminPanel: Livewire+Tailwind Version

In April 2021, we released a separate QuickAdminPanel version that generates the code with Livewire and Tailwind, using the modern TALL stack.

![](/files/-MYiK1_Dj2bYxvV6jOFA)

{% hint style="info" %}
**Notice**: this version is available only for the **Yearly Plan** customers.
{% endhint %}

Here are a few screenshots of a [simple adminpanel](https://github.com/LaravelDaily/QuickAdminPanel-Livewire-Tailwind-Example), fully generated without writing a single line of code:

![Login form page](/files/-MYiHbgkI03ci-7FrcE9)

![Simple Datatable Example](/files/-MYiHen9IqrDHs2QxanT)

![Simple Form Example](/files/-MYiHipXVXOJ975u5dnG)

For the design, we're using a theme [Notus JS by Creative Tim](https://www.creative-tim.com/product/notus-js).&#x20;

## Structure of Generated Code

We believe that Laravel Livewire is really powerful for dynamic elements on the pages, so every inner page in our adminpanel is a Livewire component that you can customize however you want.

So, the main project structure is good old Laravel with Routes and Blade, and inside of each **resources/views/admin/xxxxx.blade.php** you will find a line similar to this:

```
<div class="card-body">
    @livewire('transaction.create')
</div>
```

It means that there are three separate Livewire components for each CRUD:

* Create Page;
* Edit Page;
* Index Page.

Typical code of Livewire component:

**app/Http/Livewire/Transaction/Index.php**

```
<?php

namespace App\Http\Livewire\Transaction;

use App\Http\Livewire\WithConfirmation;
use App\Http\Livewire\WithSorting;
use App\Models\Transaction;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Gate;
use Livewire\Component;
use Livewire\WithPagination;

class Index extends Component
{
    use WithPagination;
    use WithSorting;
    use WithConfirmation;

    public int $perPage;

    public array $orderable;

    public string $search = '';

    public array $selected = [];

    public array $paginationOptions;

    protected $queryString = [
        'search' => [
            'except' => '',
        ],
        'sortBy' => [
            'except' => 'id',
        ],
        'sortDirection' => [
            'except' => 'desc',
        ],
    ];

    public function getSelectedCountProperty()
    {
        return count($this->selected);
    }

    public function updatingSearch()
    {
        $this->resetPage();
    }

    public function updatingPerPage()
    {
        $this->resetPage();
    }

    public function resetSelected()
    {
        $this->selected = [];
    }

    public function mount()
    {
        $this->sortBy            = 'id';
        $this->sortDirection     = 'desc';
        $this->perPage           = 100;
        $this->paginationOptions = config('project.pagination.options');
        $this->orderable         = (new Transaction())->orderable;
    }

    public function render()
    {
        $query = Transaction::advancedFilter([
            's'               => $this->search ?: null,
            'order_column'    => $this->sortBy,
            'order_direction' => $this->sortDirection,
        ]);

        $transactions = $query->paginate($this->perPage);

        return view('livewire.transaction.index', compact('query', 'transactions', 'transactions'));
    }

    public function deleteSelected()
    {
        abort_if(Gate::denies('transaction_delete'), Response::HTTP_FORBIDDEN, '403 Forbidden');

        Transaction::whereIn('id', $this->selected)->delete();

        $this->resetSelected();
    }

    public function delete(Transaction $transaction)
    {
        abort_if(Gate::denies('transaction_delete'), Response::HTTP_FORBIDDEN, '403 Forbidden');

        $transaction->delete();
    }
}
```

For Datatables, we don't use any external packages, as we believe it's not needed in this case - all the pagination/filtering/sorting could happen directly in the component, using the power of some reusable Traits.

For Roles/Permissions, we use the core Laravel Gate functionality, without any external packages. You can read more about it [here](https://helpdocs.quickadminpanel.com/create-panel/roles-permissions).

You can look at the full code of this example adminpanel [in this public repository](https://github.com/LaravelDaily/QuickAdminPanel-Livewire-Tailwind-Example).
