
Nous avons déjà bien avancé le paramétrage de notre boutique. Dans le présent article, nous allons nous occuper des pays. Selon la destination d'expédition des commandes, on n'aura pas le même taux de TVA à appliquer. Par exemple, la TVA est à 20% au sein de l'Union européenne, mais à zéro dans un pays comme la Suisse. La gestion des pays sera très simple parce qu'on a peu de données à manipuler.
Vous pouvez trouver le code dans ce dépôt Github.
Un formulaire pour les pays
On va avoir un formulaire commun pour la création et la modification d'un pays. On ajoute une vue partielle pour ce formulaire :
Avec un code léger :
<x-form wire:submit="save">
<x-input
label="{{ __('Name') }}"
wire:model="name"
required
placeholder="{{ __('Enter name') }}"
/>
<x-input
type="text"
wire:model="tax"
label="{{ __('VAT') }}"
required
placeholder="{{ __('Enter VAT (e.g., 0.2)') }}"
/>
<x-slot:actions>
<x-button
label="{{ __('Save') }}"
icon="o-paper-airplane"
spinner="save"
type="submit"
class="btn-primary"
/>
</x-slot:actions>
</x-form>
On ajoute les deux traductions :
"Enter name": "Entrez le nom",
"Enter VAT (e.g., 0.2)": "Entrez la TVA (par exemple, 0.2)",
Le tableau des pays
Un composant pour le tableau
Il nous faut un composant Volt pour afficher le tableau et le formulaire de création d'un pays :
php artisan make:volt admin/parameters/countries/index --class
Avec ce code :
<?php
use Livewire\Volt\Component;
use Livewire\Attributes\{Layout, Title};
use App\Models\{ Country, Range };
use Mary\Traits\Toast;
use Livewire\WithPagination;
new
#[Title('Countries')]
#[Layout('components.layouts.admin')]
class extends Component
{
use Toast, WithPagination;
public string $name;
public string $tax;
public array $sortBy = ['column' => 'name', 'direction' => 'asc'];
public function headers(): array
{
return [['key' => 'name', 'label' => __('Name')], ['key' => 'tax', 'label' => __('VAT')]];
}
public function save(): void
{
$data = $this->validate([
'name' => 'required|string|max:100|unique:countries,name',
'tax' => 'required|numeric|between:0,0.4',
]);
$country = Country::create($data);
$ranges = Range::all();
foreach($ranges as $range) {
$range->countries()->attach($country, ['price' => 0]);
}
$this->success(__('Country created successfully.'));
}
public function deleteCountry(Country $country): void
{
$country->delete();
$this->success(__('Country deleted successfully.'));
}
public function with(): array
{
return [
'countries' => Country::orderBy(...array_values($this->sortBy))->paginate(10),
'headers' => $this->headers(),
];
}
}; ?>
<div>
<x-header title="{{ __('Countries') }}" 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>
<x-table striped :headers="$headers" :rows="$countries" :sort-by="$sortBy" link="/admin/countries/{id}/edit" with-pagination >
@scope('actions', $country)
<x-popover>
<x-slot:trigger>
<x-button icon="o-trash" wire:click="deleteCountry({{ $country->id }})"
wire:confirm="{{ __('Are you sure to delete this country?') }}" 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>
<x-card title="{!! __('Create a new country') !!}">
@include('livewire.admin.parameters.countries.form')
</x-card>
</div>
Pour la validation, on a besoin d'une traduction dans fr.validation :
'tax' => 'TVA',
On ajoute quelques traductions :
"Create a new country": "Création d'un nouveau pays",
"Country created successfully.": "Pays créé avec succès.",
"Are you sure to delete this country?": "Voulez-vous vraiment supprimer ce pays ?",
"Country deleted successfully.": "Pays supprimé avec succès.",
"Countries": "Pays",
La route
On ajoute une route pour l'atteindre :
Volt::route('/countries', 'admin.parameters.countries.index')->name('admin.parameters.countries.index');
La navigation
On ajoute un lien dans la barre latérale de l'administration :
<x-menu-item title="{{ __('Countries') }}" icon="c-map-pin" link="{{ route('admin.parameters.countries.index') }}" />
Et on a notre tableau avec le formulaire de création intégré :
Vérifiez que la validation fonctionne :
Et que vous pouvez bien créer et supprimer un pays.
La modification d'un pays
On crée le composant pour la modification d'un pays :
php artisan make:volt admin/parameters/countries/edit --class
Avec aussi un code simple :
<?php
use Livewire\Volt\Component;
use Livewire\Attributes\{Layout, Title};
use App\Models\{ Country, Range };
use Mary\Traits\Toast;
new #[Title('Dashboard')] #[Layout('components.layouts.admin')] class extends Component
{
use Toast;
public Country $country;
public string $name;
public string $tax;
public function mount(Country $country): void
{
$this->country = $country;
$this->fill($this->country);
}
public function save(): void
{
$data = $this->validate([
'name' => 'required|string|max:100',
'tax' => 'required|numeric|between:0,0.4',
]);
$this->country->update($data);
$this->success(__('Country updated successfully.'), redirectTo: '/admin/countries');
}
}; ?>
<div>
<x-header title="{{ __('Countries') }}" 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="{!! __('Edit a country') !!}">
@include('livewire.admin.parameters.countries.form')
</x-card>
</div>
Quelques traductions :
"Edit a country": "Modification d'un pays",
"Country updated successfully.": "Pays mis à jour avec succès.",
On ajoute la route :
Volt::route('/countries/{country}/edit', 'admin.parameters.countries.edit')->name('admin.parameters.countries.edit');
On a le même formulaire que pour la création, mais renseigné avec les données du pays sélectionné :
Conclusion
On en a fini avec la gestion des pays. Dans la prochaine étape, on s'occupera des pages d'information de la boutique.
Par bestmomo
Aucun commentaire