
Nous avons dans le précédent article mis en place la gestion de notre catalogue. Nous allons à présent coder le paramétrage de la boutique pour préciser nom, adresse, téléphone, compte bancaire, modes de paiement... Tout un tas de renseignements indispensables qui peuvent évoluer au fil du temps : changement d'adresse, de banque, de paiements autorisés, d'informations livrées en page d'accueil...
Vous pouvez trouver le code dans ce dépôt Github.
TinyMCE
Pour renseigner le contenu des informations variables de la boutique (et plus tard le contenu des pages), on va avoir besoin d'un éditeur performant. On va s'en sortir élégamment parce que MaryUI intègre TinyMCE dans un composant. Il existe deux façons de l'utiliser :
- créer un compte sur le site de TinyMCE et obtenir une clé, il suffit ensuite de charger l'éditeur à partir d'un CDN
- charger les fichiers et héberger le SDK sur son propre serveur (licence GPL2+)
La première option est plus simple à mettre en place, mais le plan gratuit est limité à 1000 chargements mensuels de l'éditeur. La seconde option est plus longue à mettre en place, mais vous n'avez aucune limitation de chargement. On va donc choisir la seconde possibilité. Évidemment, les mises à jour dans ce cas ne seront pas automatiques, contrairement à la première option.
Télécharger et copiez tous les fichiers ici :
Il faut ensuite configurer l'éditeur en fonction de nos besoins. En particulier les commandes à prévoir dans la barre d'outils et les plugins utiles. Il y a plusieurs façons pour le faire, le plus logique me semble d'utiliser un fichier de configuration :
Avec ce code :
<?php
return [
'config' => [
'language' => env('APP_TINYMCE_LOCALE', 'en_US'),
'plugins' => 'fullscreen',
'toolbar' => 'undo redo style | fontfamily fontsize | alignleft aligncenter alignright alignjustify | bullist numlist | copy cut paste pastetext | hr | link image quicktable | fullscreen',
'toolbar_sticky' => true,
'min_height' => 50,
'license_key' => 'gpl',
'valid_elements' => '*[*]',
],
];
On voit que la locale pour le langage est récupéré dans le fichier .env, on l'ajoute dans ce fichier :
APP_TINYMCE_LOCALE=fr_FR
Mais pour que ça fonctionne, il faut aussi charger les traductions, vous trouvez les gratuites sur cette page. Chargez le français et mettez le fichier ici :
On prévoit le plugin "full screen" pour avoir l'éditeur en plein écran au besoin.
Dans notre layout admin, on doit charger la librairie :
<head>
...
<script src="{{ asset('storage/scripts/tinymce.min.js') }}" referrerpolicy="origin"></script>
</head>
Un composant pour la boutique
On crée le composant pour la gestion des paramètres de la boutique :
php artisan make:volt admin/parameters/store --class
Avec un code un peu chargé :
<?php
use Livewire\Volt\Component;
use Livewire\Attributes\{Layout, Title};
use App\Models\Shop;
use Mary\Traits\Toast;
new
#[Title('Store')]
#[Layout('components.layouts.admin')]
class extends Component
{
use Toast;
public Shop $shop;
public string $name;
public string $address;
public string $email;
public string $phone;
public string $facebook;
public string $holder;
public string $bank;
public string $bank_address;
public string $bic;
public string $iban;
public string $home;
public string $home_infos;
public string $home_shipping;
public bool $invoice;
public bool $billing;
public bool $card;
public bool $transfer;
public bool $check;
public bool $mandat;
public function mount(): void
{
$this->shop = Shop::firstOrFail();
$this->fill($this->shop);
}
public function save(): void
{
$data = $this->validate([
'name' => 'required|string|max:255',
'address' => 'required|string|max:255',
'holder' => 'required|string|max:255',
'email' => 'required|string|email|max:255',
'bic' => 'required|regex:/^[a-z]{6}[0-9a-z]{2}([0-9a-z]{3})?\z/i',
'iban' => 'required|regex:/^[a-zA-Z]{2}[0-9]{2}[a-zA-Z0-9]{4,}$/',
'bank' => 'required|string|max:255',
'bank_address' => 'required|string|max:255',
'phone' => 'required|regex:/^[+]?[(]?[0-9]{3}[)]?[-\s.]?[0-9]{3}[-\s.]?[0-9]{4,6}$/|max:25',
'facebook' => 'required|url|regex:/^(https?:\/\/)?(www\.)?facebook\.com\/.+/i|max:255',
'home' => 'required|string|max:16777215',
'home_infos' => 'required|string|max:16777215',
'home_shipping'=> 'required|string|max:16777215',
'invoice' => 'required|boolean',
'card' => 'required|boolean',
'transfer' => 'required|boolean',
'check' => 'required|boolean',
'mandat' => 'required|boolean',
]);
$this->shop->update($data);
$this->success(__('Store updated with success.'));
}
}; ?>
<div>
<x-header title="{{ __('Store') }}" 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 shadow separator progress-indicator >
<x-form wire:submit="save">
<x-card title="{{ __('Identity') }}" shadow separator >
<div class="space-y-2">
<x-input label="{{ __('Name') }}" wire:model="name" required />
<x-input label="{{ __('Address') }}" wire:model="address" required />
<x-input label="{{ __('Email') }}" wire:model="email" required />
<x-input label="{{ __('Phone') }}" wire:model="phone" required />
<x-input label="{{ __('Facebook') }}" wire:model="facebook" required />
</div>
</x-card>
<x-card title="{{ __('Bank') }}" shadow separator >
<div class="space-y-2">
<x-input label="{{ __('Holder') }}" wire:model="holder" required />
<x-input label="{{ __('Name') }}" wire:model="bank" required />
<x-input label="{{ __('Address') }}" wire:model="bank_address" required />
<x-input label="{{ __('BIC') }}" wire:model="bic" required />
<x-input label="{{ __('IBAN') }}" wire:model="iban" required />
</div>
</x-card>
<x-card title="{{ __('Home') }}" shadow separator >
<div class="space-y-2">
<x-editor wire:model="home" label="{{ __('Title') }}" :config="config('tinymce.config')" folder="photos" />
<x-editor wire:model="home_infos" label="{{ __('General informations') }}" :config="config('tinymce.config')" folder="photos" />
<x-editor wire:model="home_shipping" label="{{ __('Shipping costs') }}" :config="config('tinymce.config')" folder="photos" />
</div>
</x-card>
<x-card title="{{ __('Billing') }}" shadow separator >
<x-checkbox label="{{ __('Activation of billing') }}" wire:model="invoice" />
</x-card>
<x-card title="{{ __('Accepted payment methods') }}" shadow separator >
<div class="space-y-4">
<x-checkbox label="{{ __('Credit card') }}" wire:model="card" />
<x-checkbox label="{{ __('Bank transfer') }}" wire:model="transfer" />
<x-checkbox label="{{ __('Check') }}" wire:model="check" />
<x-checkbox label="{{ __('Administrative mandate') }}" wire:model="mandat" />
</div>
</x-card>
<x-slot:actions>
<x-button
label="{{ __('Save') }}"
icon="o-paper-airplane"
spinner="save"
type="submit"
class="btn-primary" />
</x-slot:actions>
</x-form>
</x-card>
</div>
On a encore besoin de traductions :
"Edit a product": "Modification d'un produit",
"Store": "Boutique",
"Phone": "Téléphone",
"Bank": "Banque",
"Holder": "Titulaire",
"Accepted payment methods": "Moyens de paiement acceptés",
"Store updated with success.": "Boutique mise à jour avec succès.",
"Shipping costs": "Frais de livraison",
"Title": "Titre",
"Activation of billing": "Activation de la facturation",
Dans la validation également :
'holder' => 'titulaire',
'bank_address' => 'adresse de la banque',
Une route pour atteindre le composant :
Route::middleware(IsAdmin::class)->prefix('admin')->group(function ()
{
...
Volt::route('/store', 'admin.parameters.store')->name('admin.parameters.store');
Et on complète la barre de navigation latérale :
<x-menu-sub title="{{ __('Settings') }}" icon="s-cog-8-tooth">
<x-menu-item title="{{ __('Store') }}" icon="c-building-storefront" link="{{ route('admin.parameters.store') }}" />
</x-menu-sub>
Une petite traduction :
"Store": "Boutique",
Dans la partie supérieure, on a l'identité de la boutique :
Puis les informations bancaires :
Suivent les informations livrées sur la page d'accueil (boostées par TinyMCE) :
Et enfin l'activation de la facturation et des différents modes de paiement :
Conclusion
On peut désormais modifier tous les paramètres de la boutique à partir de l'administration. Dans le prochain article, on continuera le paramétrage.
Par bestmomo
Aucun commentaire