Admin for Laravel
Tags: laravel, php
Published: 2020-07-01 20:03:46

For laravel, there are many different packages for building internal applications. Laravel Nova, Backback, and many others. But for his internal administration application, I chose a lesser-known package called [Laravel Orchid](https://orchid.software/).

This package provides the concept of "Screens", this is when you explicitly determine what should be on one page at once. This approach is very different from what you saw before.
No need to worry about crud operations, or the mandatory use of eloquent models.

You in one class determine which methods can be called from the page, which tables, line graphs, etc. will be displayed. You do not have to create a model and its resources. The screen does not know where the data comes from, it can be: a database, API, or any other external sources. Therefore, it is more effective than packages rigidly based on simple operations, beyond which you cannot use their user interfaces

## Boring. Show me the code!

No problem, let's make an example of sending an `email` message to the user.


First, you need to create a screen to display the submission form, using the command:

```bash
php artisan orchid:screen EmailSenderScreen
```

A new file `EmailSenderScreen.php` will be created in the `app/Orchid/Screens` directory:

```php
namespace App\Orchid\Screens;

use Orchid\Screen\Screen;

class EmailSenderScreen extends Screen
{
    /**
     * Name and description properties are responsible for
     * what name will be displayed
     * on the user screen and in headlines.
     */
    public $name = 'EmailSenderScreen';
    public $description = 'EmailSenderScreen';

    /**
     * A method that defines all screen input data
     * is in it that database queries should be called,
     * API or any others (not necessarily explicit),
     * the result of which should be an array,
     * appeal to which his keys will be used.
     */
    public function query(): array
    {
        return [];
    }

    /**
     * Identifies control buttons and events.
     * which will have to happen by pressing
     */
    public function commandBar(): array
    {
        return [];
    }

    /**
     * Set of mappings
     * rows, tables, graphs,
     * modal windows, and their combinations
     */
    public function layout(): array
    {
        return [];
    }
}
```

The main difference of the screen from the controller is the structure defined in advance, which serves
only one-page defining data and events.

Like the controller, the screen needs to be registered in the route file,
Define it in the file for the admin panel `routes/platform.php`:

```php
use App\Orchid\Screens\EmailSenderScreen;

Route::screen('email', EmailSenderScreen::class)->name('platform.email');
```

After we have registered a new route, you can go to the browser at `/dashboard/email`,
to look at the empty screen, fill it with the elements.

Add a name and description:

```php
/**
 * Display header name.
 *
 * @var string
 */
public $name = 'Email sender';

/**
 * Display header description.
 *
 * @var string
 */
public $description = 'Tool that sends ad-hoc email messages.';
```

To display the input fields, we describe them in the `Layouts` method:

```php
use Orchid\Screen\Fields\Input;
use Orchid\Screen\Fields\Quill;
use Orchid\Screen\Fields\Relation;
use Orchid\Screen\Layout;

/**
 * Views.
 *
 * @return Layout[]
 */
public function layout(): array
{
    return [
        Layout::rows([
            Input::make('subject')
                ->title('Subject')
                ->required()
                ->placeholder('Message subject line')
                ->help('Enter the subject line for your message'),

            Relation::make('users.')
                ->title('Recipients')
                ->multiple()
                ->required()
                ->placeholder('Email addresses')
                ->help('Enter the users that you would like to send this message to.')
                ->fromModel(User::class,'name','email'),

            Quill::make('content')
                ->title('Content')
                ->required()
                ->placeholder('Insert text here ...')
                ->help('Add the content for the message that you would like to send.')

        ])
    ];
}
```

Now our page has some elements but does not produce any action.
to define them you need to create a new public method and specify a link to it in `commandBar`:

```php
namespace App\Orchid\Screens;

use App\User;
use Illuminate\Http\Request;
use Illuminate\Mail\Message;
use Illuminate\Support\Facades\Mail;
use Orchid\Screen\Fields\Input;
use Orchid\Screen\Fields\Quill;
use Orchid\Screen\Fields\Relation;
use Orchid\Screen\Layout;
use Orchid\Screen\Actions\Button;
use Orchid\Screen\Screen;
use Orchid\Support\Facades\Alert;

class EmailSenderScreen extends Screen
{
    /**
     * Display header name.
     *
     * @var string
     */
    public $name = 'Email sender';

    /**
     * Display header description.
     *
     * @var string
     */
    public $description = 'Tool that sends ad-hoc email messages.';

    /**
     * Query data.
     *
     * @return array
     */
    public function query(): array
    {
        return [];
    }

    /**
     * Button commands.
     *
     * @return Link[]
     */
    public function commandBar(): array
    {
        return [
            Button::make('Send Message')
                ->icon('icon-paper-plane')
                ->method('sendMessage')
        ];
    }

    /**
     * Views.
     *
     * @return Layout[]
     */
    public function layout(): array
    {
        return [
            Layout::rows([
                Input::make('subject')
                    ->title('Subject')
                    ->required()
                    ->placeholder('Message subject line')
                    ->help('Enter the subject line for your message'),

                Relation::make('users.')
                    ->title('Recipients')
                    ->multiple()
                    ->required()
                    ->placeholder('Email addresses')
                    ->help('Enter the users that you would like to send this message to.')
                    ->fromModel(User::class,'name','email'),

                Quill::make('content')
                    ->title('Content')
                    ->required()
                    ->placeholder('Insert text here ...')
                    ->help('Add the content for the message that you would like to send.')

            ])
        ];
    }

    /**
     * @param Request $request
     *
     * @return \Illuminate\Http\RedirectResponse
     */
    public function sendMessage(Request $request)
    {
        $request->validate([
            'subject' => 'required|min:6|max:50',
            'users'   => 'required',
            'content' => 'required|min:10'
        ]);

        Mail::raw($request->get('content'), function (Message $message) use ($request) {

            $message->subject($request->get('subject'));

            foreach ($request->get('users') as $email) {
                $message->to($email);
            }
        });


        Alert::info('Your email message has been sent successfully.');
        return back();
    }
}
```

After that, can to send email messages to addresses.

> **Note** that by default the `SMTP` driver enabled for sending mail,
You can change it in the `.env` file to `log` for verification.

Since our utility mixed up, we can dream up and imagine that our boss asked us to put the title of our messages like “Campaign news for July”, but be able to change it. To do this, add the key to the `query` method with the name of our element:

```php
/**
 * Query data.
 *
 * @return array
 */
public function query(): array
{
    return [
        'subject' => date('F').' Campaign News',
    ];
}
```

Now the field with the name `subject` automatically fits the value from the result.


This is a very simple example, but the development process will be identical in many aspects. I really like this approach, because you do not need to keep a lot of things in mind. Looking at one single class, it’s immediately clear what is happening on the page. If you are interested, then you can find more examples on the site [orchids.software](https://orchid.software/)