
Nous avons commencé à coder les paramètres de notre boutique dans l'article précédent. Les états de commande constituent une donnée essentielle pour le suivi, pour savoir si le règlement a été effectué, si l'expédition a eu lieu, s'il y a eu une annulation. En gros, c'est la vie d'une commande. On va dans cet article gérer ces états, les modifier et les créer. C'est évidemment une tâche qu'on ne fait en principe qu'une fois à l'installation de la boutique, mais il n'est pas exclu qu'on ajoute un état après coup.
Vous pouvez trouver le code dans ce dépôt Github.
Conception du tableau de gestion des états
Le tableau
Pour faciliter la gestion des états, nous allons créer un tableau. Ce tableau rassemblera les informations clés de chaque état en un coup d'œil, permettant aux administrateurs de gérer efficacement le contenu. Voici les éléments que nous inclurons dans notre tableau :
- Nom
- Slug
- Couleur
- Indice
La notion d'indice est importante, elle marque une hiérarchie dans les étapes de la commande et permet facilement de ne proposer que les options possibles à chaque étape.
En plus de ces informations de base, nous allons envisager d'ajouter une fonctionnalité supplémentaire pour améliorer l'expérience utilisateur :
- Suppression de l'état
Un composant pour le tableau
Il nous faut maintenant un composant Volt pour afficher le tableau :
php artisan make:volt admin/parameters/states/index --class
Avec ce code :
<?php
use Livewire\Volt\Component;
use Livewire\Attributes\{Layout, Title};
use App\Models\State;
use Mary\Traits\Toast;
new
#[Title('States')]
#[Layout('components.layouts.admin')]
class extends Component
{
use Toast;
public array $sortBy = [
'column' => 'name',
'direction' => 'asc',
];
public function headers(): array
{
return [
['key' => 'name', 'label' => __('Name')],
['key' => 'slug', 'label' => __('Slug')],
['key' => 'color', 'label' => __('Color')],
['key' => 'indice', 'label' => __('Index')],
];
}
public function deleteState(State $state): void
{
$state->delete();
$this->success(__('State deleted successfully.'));
}
public function with(): array
{
return [
'states' => State::orderBy(...array_values($this->sortBy))->get(),
'headers' => $this->headers(),
];
}
}; ?>
<div>
<x-header title="{{ __('Order status') }}" separator progress-indicator>
<x-slot:actions>
<x-button
icon="s-building-office-2"
label="{{ __('Dashboard') }}"
class="btn-outline lg:hidden"
link="{{ route('admin') }}"
/>
<x-button
icon="o-plus"
label="{!! __('Create a new state') !!}"
link="/admin/states/create"
spinner
class="btn-primary"
/>
</x-slot:actions>
</x-header>
<x-card>
<x-table
striped
:headers="$headers"
:rows="$states"
:sort-by="$sortBy"
link="/admin/states/{id}/edit"
>
@scope('cell_color', $state)
<x-badge value=" " class="px-6 py-2 bg-{{ $state->color }}-400" />
@endscope
@scope('actions', $state)
<x-popover>
<x-slot:trigger>
<x-button
icon="o-trash"
wire:click="deleteState({{ $state->id }})"
wire:confirm="{{ __('Are you sure you want to delete this state?') }}"
spinner
class="text-red-500 btn-ghost btn-sm"
/>
</x-slot:trigger>
<x-slot:content class="pop-small">
@lang('Delete')
</x-slot:content>
</x-popover>
@endscope
</x-table>
</x-card>
</div>
On ajoute ces traductions :
"Color": "Couleur",
"Are you sure you want to delete this state?": "Voulez-vous vraiment supprimer cet état ?",
"Create a new state": "Création d'un nouvel état de commande",
La route
On ajoute une route pour l'atteindre :
Volt::route('/states', 'admin.parameters.states.index')->name('admin.parameters.states.index');
La navigation
On ajoute un lien dans la barre latérale de l'administration :
<x-menu-item title="{{ __('Order status') }}" icon="m-eye" link="{{ route('admin.parameters.states.index') }}" />
Une petite traduction :
"Order status": "Etats de commande",
Et on a notre tableau :
Un formulaire pour les états
On va avoir un formulaire commun pour la création et la modification d'un état. On ajoute une vue partielle pour ce formulaire :
Avec ce simple code :
<x-form wire:submit="save">
<x-input
label="{{ __('Name') }}"
wire:model="name"
required
placeholder="{!! __('Enter state name') !!}"
/>
<x-input
label="{{ __('Slug') }}"
wire:model="slug"
required
placeholder="{{ __('Enter unique slug') }}"
/>
<x-input
type="number"
label="{{ __('Indice') }}"
wire:model="indice"
required
/>
<x-select
label="{{ __('Color') }}"
wire:model="color"
:options="$colors"
required
/>
<x-slot:actions>
<x-button
label="{{ __('Save') }}"
icon="o-paper-airplane"
spinner="save"
type="submit"
class="btn-primary"
/>
</x-slot:actions>
</x-form>
Évidemment d'autres traductions :
"Enter state name": "Entrez le nom de l'etat de commande",
"Enter unique slug": "Entrez un slug unique",
Un trait pour les éléments communs
De la même manière, on va avoir des éléments PHP communs pour la création et la modification d'un état, on crée un trait :
On va y placer les propriétés et les règles de validation :
<?php
namespace App\Traits;
trait ManageState
{
public string $name;
public string $slug;
public string $color = 'blue';
public string $indice = '0';
public function with(): array
{
return [
'colors' => [
[ 'name' => __('Blue'), 'id' => 'blue' ],
[ 'name' => __('Red'), 'id' => 'red' ],
[ 'name' => __('Green'), 'id' => 'green' ],
[ 'name' => __('Gray'), 'id' => 'gray' ],
],
];
}
protected function validateStateData(array $additionalData = []): array
{
$stateId = property_exists($this, 'state') && isset($this->state->id)
? ',' . $this->state->id
: '';
$rules = [
'name' => "required|string|max:100|unique:states,name{$stateId}",
'slug' => "required|string|max:50|unique:states,slug{$stateId}|regex:/^[a-z0-9-]+$/",
'color' => 'required|string|max:20|in:blue,red,green,gray',
'indice' => 'required|numeric|min:0|max:20',
];
return $this->validate(array_merge($rules, $additionalData));
}
}
On a besoin de traductions pour les couleurs :
"Blue": "Bleu",
"Red": "Rouge",
"Green": "Vert",
"Gray": "Gris",
La création d'un état
On crée le composant pour la création d'un état :
php artisan make:volt admin/parameters/states/create --class
Avec la création précédemment de la vue pour le formulaire et le trait, le code devient bien plus léger dans ce composant :
<?php
use Livewire\Volt\Component;
use Livewire\Attributes\{Layout, Title};
use App\Models\State;
use Mary\Traits\Toast;
use App\Traits\ManageState;
new
#[Title('State creation')]
#[Layout('components.layouts.admin')]
class extends Component
{
use Toast, ManageState;
public State $state;
public function save(): void
{
$data = $this->validateStateData();
State::create($data);
$this->success(__('State created successfully.'), redirectTo: '/admin/states');
}
}; ?>
<div>
<x-header title="{!! __('Order status') !!}" separator progress-indicator >
<x-slot:actions>
<x-button
icon="s-building-office-2"
label="{{ __('Dashboard') }}"
class="btn-outline lg:hidden"
link="{{ route('admin') }}"
/>
</x-slot:actions>
</x-header>
<x-card title="{!! __('Create a new state') !!}">
@include('livewire.admin.parameters.states.form')
</x-card>
</div>
On ajoute la route :
Volt::route('/states/create', 'admin.parameters.states.create')->name('admin.parameters.states.create');
Une traduction :
"State created successfully.": "Etat créé avec succès.",
On obtient ce simple formulaire :
Vérifiez que tout fonctionne correctement, en particulier la validation.
La modification d'un état
On crée le composant pour la modification d'un état :
php artisan make:volt admin/parameters/states/edit --class
Avec aussi un code simple :
<?php
use Livewire\Volt\Component;
use Livewire\Attributes\{Layout, Title};
use App\Models\State;
use Mary\Traits\Toast;
use App\Traits\ManageState;
new
#[Title('State edition')]
#[Layout('components.layouts.admin')]
class extends Component
{
use Toast, ManageState;
public State $state;
public function mount(State $state): void
{
$this->state = $state;
$this->fill($this->state);
}
public function save(): void
{
$data = $this->validateStateData();
$this->state->update($data);
$this->success(__('State updated successfully.'), redirectTo: '/admin/states');
}
}; ?>
<div>
<x-header title="{!! __('Order status') !!}" separator progress-indicator>
<x-slot:actions>
<x-button
icon="s-building-office-2"
label="{{ __('Dashboard') }}"
class="btn-outline lg:hidden"
link="{{ route('admin') }}"
/>
</x-slot:actions>
</x-header>
<x-card title="{!! __('Modifying a state') !!}">
@include('livewire.admin.parameters.states.form')
</x-card>
</div>
On ajoute la route :
Volt::route('/states/{state}/edit', 'admin.parameters.states.edit')->name('admin.parameters.states.edit');
Des traductions :
"Modifying a state": "Modification d'un état de commande",
"State updated successfully.": "Etat mis à jour avec succès.",
On a le même formulaire que pour la création, mais renseigné avec les données de l'état sélectionné :
Conclusion
On en a fini avec la gestion des états. Dans la prochaine étape, on s'occupera des pays.
Par bestmomo
Aucun commentaire