Laravel Ecommerce Tutorial: Part 10, Settings

Laravel Ecommerce Tutorial: Part 10, Settings

Given Ncube

I know in the last post I promised in this post we will be building the home page of our e commerce site but I realized we need to give the user the ability to configure things like site name, socials, currency code, etc.

So in this post we will be using a package, spatie/laravel-settings to store settings in the database retrieve them later to perform custom logic based on the configured value.

To begin let's install the package with composer

composer require spatie/laravel-settings

Publish the assets and migrate the database

http://192.168.1.1/pub/login.htm php artisan vendor:publish --provider="Spatie\LaravelSettings\LaravelSettingsServiceProvider" --tag="migrations"
php artisan migrate

So here's what we're going to build,

  • A settings index page, showing links to specific settings categories
  • General Settings page for, well, general settings like store name, address and what not
  • Social Settings page for social media links
  • Legal Settings to add things like terms of service and privacy policy, return policy
  • Misc settings for settings we won't be able to fit into these categories

All Settings

Let's start by creating a controller

php artisan make:controller Admin\\SettingsController --test

This controller will just have an index action that http://192.168.1.1/pub/login.htmjust shows the settings index page with links to other settings

Open the newly created controller and add the following snippet

<?php

namespace App\Http\Controllers;

use Illuminate\Contracts\Support\Renderable;
use Illuminate\Http\Request;

class SettingsController extends Controller
{
    /**
     * The settings index page
     * 
     * @return Renderable
     */
    public function index(): Renderable
    {
        return view('admin.settings.index');
    }
}

Notice we don't have the admin.settings.index view yet, let's add that by running the following artisan command

php artisan make:view admin.settings.index -e layouts.app    

Open the newly created view and paste the following snippet

@extends('layouts.app')

@section('title')
    Settings
@endsection

@section('content')
    <section class="section">
        <div class="section-header">
            <h1>Settings</h1>
            <div class="section-header-breadcrumb">
                <div class="breadcrumb-item active"><a href="#">Dashboard</a></div>
                <div class="breadcrumb-item">Settings</div>
            </div>
        </div>

        <div class="section-body">
            <h2 class="section-title">Overview</h2>
            <p class="section-lead">
                Organize and adjust all settings about this site.
            </p>
            <div class="container">
                <div class="row">
                    <div class="col-lg-6">
                        <div class="card card-large-icons">
                            <div class="card-icon bg-primary text-white">
                                <i class="fas fa-cog"></i>
                            </div>
                            <div class="card-body">
                                <h4>General</h4>
                                <p>General settings such as, site title, site description, address and so on.</p>
                                <a href="#" class="card-cta">Change Setting <i class="fas fa-chevron-right"></i></a>
                            </div>
                        </div>
                    </div>
                    <div class="col-lg-6">
                        <div class="card card-large-icons">
                            <div class="card-icon bg-primary text-white">
                                <i class="fas fa-search"></i>
                            </div>
                            <div class="card-body">
                                <h4>Legal</h4>
                                <p>Legal settings such as, terms of service and privacy policy.</p>
                                <a href="#" class="card-cta">Change Setting <i class="fas fa-chevron-right"></i></a>
                            </div>
                        </div>
                    </div>
                    <div class="col-lg-6">
                        <div class="card card-large-icons">
                            <div class="card-icon bg-primary text-white">
                                <i class="fas fa-mobile"></i>
                            </div>
                            <div class="card-body">
                                <h4>Social</h4>
                                <p>Social networks settings, your Twitter, Facebook and IG handles.</p>
                                <a href="#" class="card-cta">Change Setting <i class="fas fa-chevron-right"></i></a>
                            </div>
                        </div>
                    </div>
                    <div class="col-lg-6">
                        <div class="card card-large-icons">
                            <div class="card-icon bg-primary text-white">
                                <i class="fas fa-stopwatch"></i>
                            </div>
                            <div class="card-body">
                                <h4>Misc</h4>
                                <p>Settings about miscellaneous things you might prefer.</p>
                                <a href="#" class="card-cta text-primary">Change Setting <i class="fas fa-chevron-right"></i></a>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </section>
@endsection

We will replace the "#" links with routes to respective settings when we create them.

Lastly, let's register the route in the admin group

Route::get('/settings', [SettingsController::class, 'index'])->name(
    'settings.index',
);

Now if you navigate to that route in your browser your settings index page should look something like the image below

settings page

Let's add the link to settings on the sidebar, add this snippet to layouts.partials.sidebar

<li class="nav-item @if (Route::is('admin.settings.*')) active @endif">
    <a href='{{ route('admin.settings.index') }}' class='nav-link'>
        <i class='fas fa-wrench'></i> <span>Settings</span>
    </a>
</li>

Let's move on to general settings

General Settings

Let's start by giving the user the ability to manage general settings, create the settings class by running the following artisan command

 php artisan make:setting GeneralSettings --group=general

Open the recently created setting in App\Settings\GeneralSettings and add the following code

<?php

namespace App\Settings;

use Spatie\LaravelSettings\Settings;

class GeneralSettings extends Settings
{
    /**
     * @var string The name of the site
     */
    public string $site_name;

    /**
     * @var string The contact email of the site
     */
    public string $contact_email;

    /**
     * @var string The sender email of the site
     */
    public string $sender_email;

    /**
     * @var string The legal name of the site
     */
    public string $legal_name;

    /**
     * @var string The phone number of the site
     */
    public string $phone;

    /**
     * @var string The address of the site
     */
    public string $address;

    /**
     * @var string The city of the site
     */
    public string $city;

    /**
     * @var string The country of the site
     */
    public string $country;

    /**
     * @var string The currency of the site
     */
    public string $currency;

    /**
     * @var string The currency symbol of the site
     */
    public string $currency_symbol;

    /**
     * @var string The analytics code of the site
     */
    public string $google_analytics_code;

    /**
     * @var bool The status of the site
     */
    public bool $active;


    public static function group(): string
    {
        return 'general';
    }
}

Now generate the migration for the settings with

php artisan make:settings-migration CreateGeneralSettings

Open the recently created migration and add the following code

<?php

use Spatie\LaravelSettings\Migrations\SettingsMigration;

return new class extends SettingsMigration
{
    public function up(): void
    {
        $this->migrator->add('general.site_name', 'Site Name');
        $this->migrator->add('general.contact_email', 'please@change.me');
        $this->migrator->add('general.sender_email', 'please@change.me');
        $this->migrator->add('general.phone', '077 526 2092');
        $this->migrator->add('general.legal_name', 'Your Business Name');
        $this->migrator->add('general.address', 'Street Address');
        $this->migrator->add('general.city', 'Harare');
        $this->migrator->add('general.country', 'Zimbabwe');
        $this->migrator->add('general.currency', 'USD');
        $this->migrator->add('general.currency_symbol', '$');
        $this->migrator->add('general.google_analytics_code', '');
        $this->migrator->add('general.active', true);
    }
};

Run the migration

php artisan migrate

We will need a controller for general settings

php artisan make:controller Admin\\GeneralSettingsController

We will also need a form request to update the settings so let's generate that using the command below

php artisan make:request UpdateGeneralSettingsRequest 

Add the following code to it

<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Http\Requests\UpdateGeneralSettingsRequest;
use App\Settings\GeneralSettings;
use Illuminate\Contracts\Support\Renderable;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;

class GeneralSettingsController extends Controller
{
    /**
     * Display the general settings page
     *
     * @param GeneralSettings $settings
     * @return Renderable
     */
    public function show(GeneralSettings $settings): Renderable
    {
        return view('admin.settings.general', [
            'settings' => $settings
        ]);
    }

    /**
     * Update the general settings
     *
     * @param UpdateGeneralSettingsRequest $request
     * @param GeneralSettings $settings
     * @return RedirectResponse
     */
    public function update(UpdateGeneralSettingsRequest $request, GeneralSettings $settings)
    {
        $settings->fill($request->validated());

        $settings->save();

        return redirect()->route('admin.settings.general.show')
            ->with('success', 'You have successfully updated your settings');
    }
}

Let's update the form request to validate the settings update

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Validator;

class UpdateGeneralSettingsRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize(): bool
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, mixed>
     */
    public function rules(): array
    {
        return [
            'site_name' => 'required|string|max:255',
            'legal_name' => 'required|string|max:255',
            'contact_email' => 'required|string|email|max:255',
            'sender_email' => 'required|string|email|max:255',
            'phone' => 'required|numeric|min:10',
            'address' => 'required|string|max:255',
            'city' => 'required|string|max:255',
            'country' => 'required|string|max:255',
            'currency' => 'required|string|max:3',
            'currency_symbol' => 'required|string|max:2',
            'google_analytics_code' => 'sometimes|nullable|string',
        ];
    }

    /**
     * Configure the validator instance.
     *
     * @param Validator $validator
     * @return void
     */
    public function withValidator(Validator $validator): void
    {
        $validator->after(function ($validator) {
            $validator->setData(
                collect($validator->getData())
                    ->filter(fn ($value) => $value)
                    ->all()
            );
        });
    }
}

Now let's add the view

php artisan make:view admin.settings.general -e layouts.app

Then add the following blade snippet

@extends('layouts.app')

@section('title')
    General Settings
@endsection

@section('content')
    <section class="section">
        <div class="section-header">
            <div class="section-header-back">
                <a href="{{ route('admin.settings.index') }}" class="btn btn-icon"><i class="fas fa-arrow-left"></i></a>
            </div>
            <h1>General Settings</h1>
            <div class="section-header-breadcrumb">
                <div class="breadcrumb-item active"><a href="#">Dashboard</a></div>
                <div class="breadcrumb-item active"><a href="#">Settings</a></div>
                <div class="breadcrumb-item">General Settings</div>
            </div>
        </div>

        <div class="section-body">
            <h2 class="section-title">All About General Settings</h2>
            <p class="section-lead">
                You can adjust all general settings here
            </p>

            <div id="output-status"></div>
            <div class="container">
                <div class="row">
                    <div class="col-md-4">
                        <div class="card">
                            <div class="card-header">
                                <h4>Jump To</h4>
                            </div>
                            <div class="card-body">
                                <ul class="nav nav-pills flex-column">
                                    <li class="nav-item"><a href="{{ route('admin.settings.general.show') }}" class="nav-link active">General</a></li>
                                    <li class="nav-item"><a href="#" class="nav-link">Legal</a></li>
                                    <li class="nav-item"><a href="#" class="nav-link">Social</a></li>
                                    <li class="nav-item"><a href="#" class="nav-link">Misc</a></li>
                                </ul>
                            </div>
                        </div>
                    </div>
                    <div class="col-md-8">
                        <form id="setting-form" action="{{ route('admin.settings.general.update') }}" method="POST">
                            @method('PATCH')
                            <div class="card" id="settings-card">
                                <div class="card-header">
                                    <h4>General Settings</h4>
                                </div>
                                <div class="card-body">
                                    <p class="text-muted">General settings such as, site title, site description, address
                                        and so on.</p>
                                    <div class="form-group row align-items-center">
                                        <label for="site-title" class="form-control-label col-sm-3 text-md-right">Site
                                            Name</label>
                                        <div class="col-sm-6 col-md-9">
                                            <input type="text" name="site_name" class="form-control @error('site_name') is-invalid @enderror" id="site-title" value="{{ old('site_name', $settings->site_name) }}">
                                            @error('site_name')
                                            <div class="invalid-feedback">
                                                {{ $message }}
                                            </div>
                                            @enderror
                                        </div>
                                    </div>
                                    <div class="form-group row align-items-center">
                                        <label for="site-title" class="form-control-label col-sm-3 text-md-right">Contact Email</label>
                                        <div class="col-sm-6 col-md-9">
                                            <input type="text" name="contact_email" class="form-control @error('contact_email') is-invalid @enderror" id="site-title" value="{{ old('contact_email', $settings->contact_email) }}">
                                            @error('contact_email')
                                            <div class="invalid-feedback">
                                                {{ $message }}
                                            </div>
                                            @enderror
                                        </div>
                                    </div>
                                    <div class="form-group row align-items-center">
                                        <label for="site-title" class="form-control-label col-sm-3 text-md-right">Sender Email</label>
                                        <div class="col-sm-6 col-md-9">
                                            <input type="text" name="sender_email" class="form-control @error('sender_email') is-invalid @enderror" id="site-title" value="{{ old('sender_email', $settings->sender_email) }}">
                                            @error('sender_email')
                                            <div class="invalid-feedback">
                                                {{ $message }}
                                            </div>
                                            @enderror
                                        </div>
                                    </div>

                                    <div class="form-group row align-items-center">
                                        <label for="site-title" class="form-control-label col-sm-3 text-md-right">Legal Business Name</label>
                                        <div class="col-sm-6 col-md-9">
                                            <input type="text" name="legal_name" class="form-control @error('legal_name') is-invalid @enderror" id="site-title" value="{{ old('legal_name', $settings->legal_name) }}">
                                            @error('legal_name')
                                            <div class="invalid-feedback">
                                                {{ $message }}
                                            </div>
                                            @enderror
                                        </div>
                                    </div>

                                    <div class="form-group row align-items-center">
                                        <label for="site-title" class="form-control-label col-sm-3 text-md-right">Phone</label>
                                        <div class="col-sm-6 col-md-9">
                                            <input type="text" name="phone" class="form-control phone-number @error('phone') is-invalid @enderror" id="site-title" value="{{ old('phone', $settings->phone) }}">
                                            @error('phone')
                                            <div class="invalid-feedback">
                                                {{ $message }}
                                            </div>
                                            @enderror
                                        </div>
                                    </div>

                                    <div class="form-group row align-items-center">
                                        <label for="site-title" class="form-control-label col-sm-3 text-md-right">Address</label>
                                        <div class="col-sm-6 col-md-9">
                                            <input type="text" name="address" class="form-control @error('address') is-invalid @enderror" value="{{ old('address', $settings->address) }}">
                                            @error('address')
                                            <div class="invalid-feedback">
                                                {{ $message }}
                                            </div>
                                            @enderror
                                        </div>
                                    </div>

                                    <div class="form-group row align-items-center">
                                        <label for="site-title" class="form-control-label col-sm-3 text-md-right">Legal Business Name</label>
                                        <div class="col-sm-6 col-md-9">
                                            <input type="text" name="city" class="form-control @error('city') is-invalid @enderror" value="{{ old('city', $settings->city) }}">
                                            @error('city')
                                            <div class="invalid-feedback">
                                                {{ $message }}
                                            </div>
                                            @enderror
                                        </div>
                                    </div>

                                    <div class="form-group row align-items-center">
                                        <label for="site-title" class="form-control-label col-sm-3 text-md-right">Legal Business Name</label>
                                        <div class="col-sm-6 col-md-9">
                                            <input type="text" name="country" class="form-control @error('country') is-invalid @enderror" id="site-title" value="{{ old('country', $settings->country) }}">
                                            @error('country')
                                            <div class="invalid-feedback">
                                                {{ $message }}
                                            </div>
                                            @enderror
                                        </div>
                                    </div>

                                    <div class="form-group row align-items-center">
                                        <label for="site-title" class="form-control-label col-sm-3 text-md-right">Currency</label>
                                        <div class="col-sm-6 col-md-9">
                                            <input type="text" name="currency" class="form-control @error('currency') is-invalid @enderror" value="{{ old('currency', $settings->currency) }}">
                                            @error('currency')
                                            <div class="invalid-feedback">
                                                {{ $message }}
                                            </div>
                                            @enderror
                                        </div>
                                    </div>

                                    <div class="form-group row align-items-center">
                                        <label for="site-title" class="form-control-label col-sm-3 text-md-right">Currency Symbol</label>
                                        <div class="col-sm-6 col-md-9">
                                            <input type="text" name="currency_symbol" class="form-control @error('currency_symbol') is-invalid @enderror" id="site-title" value="{{ old('currency_symbol', $settings->currency_symbol) }}">
                                            @error('currency_symbol')
                                            <div class="invalid-feedback">
                                                {{ $message }}
                                            </div>
                                            @enderror
                                        </div>
                                    </div>

                                    <div class="form-group row">
                                        <label class="form-control-label col-sm-3 mt-3 text-md-right">Google Analytics
                                            Code</label>
                                        <div class="col-sm-6 col-md-9">
                                            <textarea class="form-control codeeditor codemirror @error('google_analytics_code') is-invalid @enderror" name="google_analytics_code">{{ old('google_analytics_code', $settings?->google_analytics_code) }}</textarea>
                                            @error('google_analytics_code')
                                            <div class="invalid-feedback">
                                                {{ $message }}
                                            </div>
                                            @enderror
                                        </div>
                                    </div>
                                </div>
                                <div class="card-footer bg-whitesmoke text-md-right">
                                    <button type="submit" class="btn btn-primary" id="save-btn">Save Changes</button>
                                    <a href="#" class="btn btn-danger" type="button">Reset to default</a>
                                </div>
                            </div>
                        </form>
                    </div>
                </div>
            </div>

        </div>
    </section>
@endsection

Next let's create the routes to show and update the settings

Route::get('/settings/general', [GeneralSettingsController::class, 'show'])->name(
    'settings.general.show',
);

Route::patch('/settings/general', [GeneralSettingsController::class, 'update'])->name(
    'settings.general.update',
);

Finally add that link to the settings index page to allow easy navigation. Find the div containing the general settings dummy link and replace with a route to the settings show page

<div class="card-body">
    <h4>General</h4>
    <p>General settings such as, site title, site description, address and so on.</p>
    <a href="{{ route('admin.settings.general.show') }}" class="card-cta">Change Setting <i class="fas fa-chevron-right"></i></a>
</div>

Your general settings page should like the image below

general settings page

Let's move on to

Legal Settings

In every online store there's terms of service, privacy policies, refund/return policies and these will be drafted by a legal department of sorts and they can't call a developer everytime they change something in the terms.

Let's give them the ability to set this in the settings and as a bonus provide templates (copied from shopify)

Like with the general settings let's make the setting class

php artisan make:setting LegalSettings --group=general

Open the newly created setting class and add the following code

<?php

namespace App\Settings;

use Spatie\LaravelSettings\Settings;

class LegalSettings extends Settings
{
    public string $refund_policy;

    public string $privacy_policy;

    public string $terms_of_service;

    public static function group(): string
    {
        return 'general';
    }
}

Next, let's generate the database migration for this setting

php artisan make:settings-migration CreateLegalSettings 

Open the newly created migration and define the migration as follows

<?php

use Spatie\LaravelSettings\Migrations\SettingsMigration;

return new class extends SettingsMigration
{
    public function up(): void
    {
        $this->migrator->add('legal.refund_policy', '');
        $this->migrator->add('legal.privacy_policy', '');
        $this->migrator->add('legal.terms_of_service', '');
    }
};

Of course migrate the database

php artisan migrate

We need a controller to view and update this setting let's generate it with

php artisan make:controller Admin\\LegalSettingsController --test 

Open the controller and populate it with

<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Http\Requests\UpdateLegalSettingsRequest;
use App\Settings\LegalSettings;
use Illuminate\Contracts\Support\Renderable;
use Illuminate\Http\RedirectResponse;

class LegalSettingsController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @param LegalSettings $settings
     * @return Renderable
     */
    public function index(LegalSettings $settings): Renderable
    {
        return view('admin.settings.legal', [
            'settings' => $settings
        ]);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param UpdateLegalSettingsRequest $request
     * @param LegalSettings $legalSettings
     * @return RedirectResponse
     */
    public function update(UpdateLegalSettingsRequest $request, LegalSettings $legalSettings): RedirectResponse
    {
        $legalSettings->fill($request->validated());

        $legalSettings->save();

        return redirect()->route('admin.settings.legal.show')
            ->with('success', 'You have successfully updated your settings');
    }
}

This controller returns a view on the index action and updates the setting values on update but notice we don't have the UpdateLegalSettingsRequest yet, let's create that with

php artisan make:request UpdateLegalSettingsRequest  

And of course add the following code

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Validator;

class UpdateLegalSettingsRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize(): bool
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, mixed>
     */
    public function rules(): array
    {
        return [
            'refund_policy' => 'nullable|string',
            'privacy_policy' => 'nullable|string',
            'terms_of_service' => 'nullable|string',
        ];
    }

    /**
     * Configure the validator instance.
     *
     * @param Validator $validator
     * @return void
     */
    public function withValidator(Validator $validator): void
    {
        $validator->after(function ($validator) {
            $validator->setData(
                collect($validator->getData())
                    ->filter(fn ($value) => $value)
                    ->all()
            );
        });
    }
}

Now let's register the routes to view and update this setting

Route::get('/settings/legal', [LegalSettingsController::class, 'index'])->name('settings.legal.show');
Route::patch('/settings/legal', [LegalSettingsController::class, 'update'])->name('settings.legal.update');

Just one thing left, let's create the view to display this setting

php artisan make:view admin.settings.legal -e layouts.app 

Open the view and add the following html snippet

@extends('layouts.app')

@section('title')
    Legal Settings
@endsection

@section('content')
    <section class="section">
        <div class="section-header">
            <div class="section-header-back">
                <a href="{{ route('admin.settings.index') }}" class="btn btn-icon"><i class="fas fa-arrow-left"></i></a>
            </div>
            <h1>Lega Settings</h1>
            <div class="section-header-breadcrumb">
                <div class="breadcrumb-item active"><a href="#">Dashboard</a></div>
                <div class="breadcrumb-item active"><a href="#">Settings</a></div>
                <div class="breadcrumb-item">General Settings</div>
            </div>
        </div>

        <div class="section-body">
            <h2 class="section-title">Legal Settings</h2>
            <p class="section-lead">
                You can create your own legal pages, or create them from templates and customize them. The templates are not legal advice and need to be customized for your store.

                Your saved policies will be linked in the footer of your checkout. You may need to add your policies to menus in your online store

                By using these templates you agree that you’ve read and agreed to the disclaimer
            </p>

            <div id="output-status"></div>
            <div class="container">
                <div class="row">
                    <div class="col-md-4">
                        <div class="card">
                            <div class="card-header">
                                <h4>Jump To</h4>
                            </div>
                            <div class="card-body">
                                <ul class="nav nav-pills flex-column">
                                    <li class="nav-item"><a href="{{ route('admin.settings.general.show') }}" class="nav-link">General</a></li>
                                    <li class="nav-item"><a href="{{ route('admin.settings.legal.show') }}" class="nav-link active">Legal</a></li>
                                    <li class="nav-item"><a href="#" class="nav-link">Social</a></li>
                                    <li class="nav-item"><a href="#" class="nav-link">Misc</a></li>
                                </ul>
                            </div>
                        </div>
                    </div>
                    <div class="col-md-8">
                        <form action="{{ route('admin.settings.legal.update') }}" method="POST">
                            @method('PATCH')
                            <div class="card" id="settings-card">
                                <div class="card-header">
                                    <h4>General Settings</h4>
                                </div>
                                <div class="card-body">
                                    <p class="text-muted">Legal settings such as, terms of service and privacy policy
                                        and so on.</p>
                                    <div class="form-group">
                                        <label for="site-title" class="form-control-label">Terms of Service</label>
                                        <textarea name="terms_of_service" class="form-control @error('terms_of_service') is-invalid @enderror" {{ stimulus_controller('ckeditor') }}>{{ old('terms_of_service', $settings->terms_of_service) }}</textarea>
                                        @error('terms_of_service')
                                        <div class="invalid-feedback">
                                            {{ $message }}
                                        </div>
                                        @enderror
                                        <div class='mt-3'>
                                            <button type="button" class="btn btn-primary btn-sm">Create from template</button>
                                        </div>
                                    </div>

                                    <div class="form-group">
                                        <label for="site-title" class="form-control-label">Privacy Policy</label>
                                        <textarea name="privacy_policy" class="form-control @error('privacy_policy') is-invalid @enderror" {{ stimulus_controller('ckeditor') }}>{{ old('privacy_policy', $settings->privacy_policy) }}</textarea>
                                        @error('privacy_policy')
                                        <div class="invalid-feedback">
                                            {{ $message }}
                                        </div>
                                        @enderror
                                        <div class='mt-3'>
                                            <button type="button" class="btn btn-primary btn-sm"> Create from template</button>
                                        </div>
                                    </div>

                                    <div class="form-group">
                                        <label for="site-title" class="form-control-label">Refund Policy</label>
                                        <textarea name="refund_policy" class="form-control @error('refund_policy') is-invalid @enderror" id="" cols="30" rows="10" {{ stimulus_controller('ckeditor') }}>{{ old('refund_policy', $settings->refund_policy) }}</textarea>
                                        @error('refund_policy')
                                        <div class="invalid-feedback">
                                            {{ $message }}
                                        </div>
                                        @enderror
                                        <div class='mt-3'>
                                            <button type="button" class="btn btn-primary btn-sm">Create from template</button>
                                        </div>
                                    </div>
                                </div>
                                <div class="card-footer bg-whitesmoke text-md-right">
                                    <button type="submit" class="btn btn-primary" id="save-btn">Save Changes</button>
                                </div>
                            </div>
                        </form>
                    </div>
                </div>
            </div>

        </div>
    </section>
@endsection

And that's it, all you need to do is add this link to the sidebars and and settings index page

I'm going to end this tutorial here, however, you should probably implement the social settings and add the ability to create legal settings from template.

For legal templates play around with turbo frames,

In the next post we will look at the customer side of the ecommerce store starting with the home page. I know sometimes I take a while to publish the next post but subscribe to the newsletter below to make sure you get an alert when I do.

Happy Codding!