DEV Community

Alexandr
Alexandr

Posted on

Admin for Laravel

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.

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:

php artisan orchid:screen EmailSenderScreen
Enter fullscreen mode Exit fullscreen mode

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

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 [];
    }
}
Enter fullscreen mode Exit fullscreen mode

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:

use App\Orchid\Screens\EmailSenderScreen;

Route::screen('email', EmailSenderScreen::class)->name('platform.email');
Enter fullscreen mode Exit fullscreen mode

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:

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

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

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

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.')

        ])
    ];
}
Enter fullscreen mode Exit fullscreen mode

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:

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();
    }
}
Enter fullscreen mode Exit fullscreen mode

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:

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

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

Top comments (0)