sed -n '1380,1665p' specs/03-ADMIN-UI.md

### 11.1 General Settings

**Route:** `GET /admin/settings`

**Livewire component:** `App\Livewire\Admin\Settings\General`

**Blade view:** `resources/views/livewire/admin/settings/general.blade.php`

#### Component Requirements

| Property | Type | Purpose |
|----------|------|---------|
| `storeName` | `string` | Store display name |
| `storeHandle` | `string` | Store handle (read-only or with warning) |
| `defaultCurrency` | `string` | Currency code (e.g., "EUR") |
| `defaultLocale` | `string` | Locale code (e.g., "en") |
| `timezone` | `string` | Timezone string |

| Action | Behavior |
|--------|----------|
| `save()` | Validates and saves store settings |

#### Layout

Two-column layout per section: left side has section label and description, right side has form fields.

**Store details section:**
- Left: Heading "Store details" + description "Basic information about your store."
- Right: Store name input, Store handle input (disabled, with description: "The store handle cannot be changed after creation.")

Separator between sections.

**Defaults section:**
- Left: Heading "Defaults" + description "Currency, language, and timezone settings."
- Right:
  - Default currency: Select (EUR/USD/GBP and more)
  - Default locale: Select (English/German/French and more)
  - Timezone: Select (populated from PHP timezone list)

Save button at the bottom (primary variant, right-aligned).

### 11.2 Domains Settings

Domains is a tab within the Settings page (`/admin/settings`), not a separate route. The Settings page has tabs: General, Domains, Shipping, Taxes, Checkout, Notifications.

**Livewire component:** `App\Livewire\Admin\Settings\Domains`

**Blade view:** `resources/views/livewire/admin/settings/domains.blade.php`

#### Component Requirements

| Property | Type | Purpose |
|----------|------|---------|
| `domains` | `Collection` | Store domains |
| `newHostname` | `string` | Hostname for new domain |
| `newType` | `string` | Type for new domain: `storefront`, `admin`, `api` |

| Action | Behavior |
|--------|----------|
| `addDomain()` | Creates a new domain record |
| `removeDomain(int $domainId)` | Removes a domain |
| `setPrimary(int $domainId)` | Sets domain as primary |

#### Layout

- Heading "Domains"
- Table of existing domains:

| Column | Content |
|--------|---------|
| Hostname | Domain hostname |
| Type | Flux badge: storefront/admin/api |
| Primary | Flux badge (green) "Primary" if `is_primary` |
| TLS | Flux badge showing TLS mode |
| Actions | "Set Primary" button, "Delete" button |

- "Add domain" button opens a modal

#### Add Domain Modal

| Property | Value |
|----------|-------|
| Modal name | `add-domain` |
| Max width | md |
| Heading | "Add domain" |

**Form fields:**
- Hostname input (placeholder: "shop.example.com")
- Type select: Storefront, Admin, API
- Cancel button (ghost) and "Add domain" button (primary)

### 11.3 Shipping Settings

**Route:** `GET /admin/settings/shipping`

**Livewire component:** `App\Livewire\Admin\Settings\Shipping`

**Blade view:** `resources/views/livewire/admin/settings/shipping.blade.php`

#### Component Requirements

| Property | Type | Purpose |
|----------|------|---------|
| `zones` | `Collection` | Shipping zones with rates |
| `editingZone` | `?ShippingZone` | Zone being edited |
| `zoneName` | `string` | Name for zone form |
| `zoneCountries` | `array` | Selected countries for zone |
| `editingRate` | `?ShippingRate` | Rate being edited |
| `rateName` | `string` | Rate name |
| `rateType` | `string` | `flat`, `weight`, `price`, `carrier` |
| `rateConfig` | `array` | Rate configuration (depends on type) |
| `rateActive` | `bool` | Whether rate is active |
| `testAddress` | `array` | Address fields for test tool |
| `testResult` | `?array` | Result of test address lookup |

| Action | Behavior |
|--------|----------|
| `openZoneModal(?ShippingZone $zone)` | Opens zone create/edit modal |
| `saveZone()` | Saves shipping zone |
| `deleteZone(int $zoneId)` | Deletes a shipping zone |
| `openRateModal(int $zoneId, ?ShippingRate $rate)` | Opens rate create/edit modal |
| `saveRate()` | Saves shipping rate |
| `deleteRate(int $rateId)` | Deletes a rate |
| `testShippingAddress()` | Tests which zone/rate matches a given address |

#### Layout Wireframe

```
+==================================================================+
| Shipping                                         [+ Add zone]    |
+==================================================================+
|                                                                   |
| +--------------------------------------------------------------+ |
| | ZONE: Domestic                            [Edit] [Delete]    | |
| | Countries: US, CA                                             | |
| |                                                               | |
| | Name      | Type    | Config           | Active | Actions    | |
| |-----------|---------|------------------|--------|------------|  |
| | Standard …1745 chars truncated…ut (placeholder: "Domestic, Europe, International...")
- Countries: scrollable checklist of all available countries with checkboxes
- Cancel button (ghost) and "Save zone" button (primary)

#### Rate Modal

| Property | Value |
|----------|-------|
| Modal name | `rate-form` |
| Max width | md |
| Heading | "Edit shipping rate" or "Add shipping rate" (dynamic) |

**Form fields:**
- Rate name input (placeholder: "Standard, Express...")
- Rate type select: Flat rate, Weight-based, Price-based, Carrier-calculated
- Dynamic config fields based on rate type:
  - **Flat:** Price input
  - **Weight-based:** Min weight (g) input, Max weight (g) input, Price input
  - **Price-based:** Min order amount input, Max order amount input, Price input
  - **Carrier:** Info callout: "Carrier-calculated rates require a carrier integration to be configured."
- Active toggle switch with "Active" text label
- Cancel button (ghost) and "Save rate" button (primary)

#### Test Shipping Address Tool

A card section at the bottom of the page:
- Heading "Test shipping address"
- Description: "Enter an address to see which shipping zone and rates match."
- 2-column grid of fields: Country (select), State/Region (input), City (input), ZIP/Postal code (input)
- "Test" button
- Result area (shown after test):
  - If matched: "Matched zone: [zone name]" and list of available rates with prices
  - If no match: Warning callout "No shipping zone matches this address."

### 11.4 Tax Settings

**Route:** `GET /admin/settings/taxes`

**Livewire component:** `App\Livewire\Admin\Settings\Taxes`

**Blade view:** `resources/views/livewire/admin/settings/taxes.blade.php`

#### Component Requirements

| Property | Type | Purpose |
|----------|------|---------|
| `mode` | `string` | `manual` or `provider` |
| `pricesIncludeTax` | `bool` | Whether prices include tax |
| `provider` | `string` | Provider name (e.g., `stripe_tax`) |
| `providerApiKey` | `string` | API key for tax provider |
| `manualRates` | `array` | Array of `{zone_name, rate_percentage}` |

| Action | Behavior |
|--------|----------|
| `save()` | Saves tax settings |
| `addManualRate()` | Adds a new empty rate row |
| `removeManualRate(int $index)` | Removes a manual rate |

#### Layout Wireframe

```
+==================================================================+
| TAXES                                                             |
+==================================================================+
| MODE SELECTION                                                    |
|  ( ) Manual tax rates - Define tax rates per zone manually       |
|  (o) Tax provider - Use an automated tax calculation service     |
+==================================================================+
| MANUAL RATES TABLE (shown when mode = "manual")                  |
| Zone name       | Rate (%)    |                                   |
|-----------------|-------------|                                   |
| [EU           ] | [19.00    ] | [trash]                          |
| [US-CA        ] | [7.25     ] | [trash]                          |
| [+ Add rate]                                                      |
+==================================================================+
| PROVIDER CONFIG (shown when mode = "provider")                   |
|  Provider: [Stripe Tax v]                                        |
|  API key:  [*************]                                       |
+==================================================================+
| [separator]                                                       |
| TAX-INCLUSIVE TOGGLE                                              |
|  [switch: ON]  Prices include tax                                |
|  Description: When enabled, the listed price includes tax.       |
|  Tax is calculated backwards from the price.                      |
+==================================================================+
| [Save]                                                            |
+==================================================================+
```

**Mode selection:** Two radio buttons - "Manual tax rates" (description: "Define tax rates per zone manually") and "Tax provider" (description: "Use an automated tax calculation service"). Live-bound.

**Manual rates table:** Shown when mode = "manual". Inline-editable table with columns: Zone name (text input), Rate % (number input with step 0.01). Each row has a trash button. "Add rate" ghost button with plus icon.

**Provider config:** Shown when mode = "provider". Provider select (Stripe Tax / None) and API key password input.

**Tax-inclusive toggle:** Toggle switch with "Prices include tax" label and description text explaining the behavior.

Save button at the bottom.

---

## 12. Themes Management

### 12.1 Themes List

**Route:** `GET /admin/themes`

**Livewire component:** `App\Livewire\Admin\Themes\Index`

**Blade view:** `resources/views/livewire/admin/themes/index.blade.php`

#### Component Requirements


Output:
Chunk ID: 2d6e6f
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 2937
Output:
### 11.1 General Settings

**Route:** `GET /admin/settings`

**Livewire component:** `App\Livewire\Admin\Settings\General`

**Blade view:** `resources/views/livewire/admin/settings/general.blade.php`

#### Component Requirements

| Property | Type | Purpose |
|----------|------|---------|
| `storeName` | `string` | Store display name |
| `storeHandle` | `string` | Store handle (read-only or with warning) |
| `defaultCurrency` | `string` | Currency code (e.g., "EUR") |
| `defaultLocale` | `string` | Locale code (e.g., "en") |
| `timezone` | `string` | Timezone string |

| Action | Behavior |
|--------|----------|
| `save()` | Validates and saves store settings |

#### Layout

Two-column layout per section: left side has section label and description, right side has form fields.

**Store details section:**
- Left: Heading "Store details" + description "Basic information about your store."
- Right: Store name input, Store handle input (disabled, with description: "The store handle cannot be changed after creation.")

Separator between sections.

**Defaults section:**
- Left: Heading "Defaults" + description "Currency, language, and timezone settings."
- Right:
  - Default currency: Select (EUR/USD/GBP and more)
  - Default locale: Select (English/German/French and more)
  - Timezone: Select (populated from PHP timezone list)

Save button at the bottom (primary variant, right-aligned).

### 11.2 Domains Settings

Domains is a tab within the Settings page (`/admin/settings`), not a separate route. The Settings page has tabs: General, Domains, Shipping, Taxes, Checkout, Notifications.

**Livewire component:** `App\Livewire\Admin\Settings\Domains`

**Blade view:** `resources/views/livewire/admin/settings/domains.blade.php`

#### Component Requirements

| Property | Type | Purpose |
|----------|------|---------|
| `domains` | `Collection` | Store domains |
| `newHostname` | `string` | Hostname for new domain |
| `newType` | `string` | Type for new domain: `storefront`, `admin`, `api` |

| Action | Behavior |
|--------|----------|
| `addDomain()` | Creates a new domain record |
| `removeDomain(int $domainId)` | Removes a domain |
| `setPrimary(int $domainId)` | Sets domain as primary |

#### Layout

- Heading "Domains"
- Table of existing domains:

| Column | Content |
|--------|---------|
| Hostname | Domain hostname |
| Type | Flux badge: storefront/admin/api |
| Primary | Flux badge (green) "Primary" if `is_primary` |
| TLS | Flux badge showing TLS mode |
| Actions | "Set Primary" button, "Delete" button |

- "Add domain" button opens a modal

#### Add Domain Modal

| Property | Value |
|----------|-------|
| Modal name | `add-domain` |
| Max width | md |
| Heading | "Add domain" |

**Form fields:**
- Hostname input (placeholder: "shop.example.com")
- Type select: Storefront, Admin, API
- Cancel button (ghost) and "Add domain" button (primary)

### 11.3 Shipping Settings

**Route:** `GET /admin/settings/shipping`

**Livewire component:** `App\Livewire\Admin\Settings\Shipping`

**Blade view:** `resources/views/livewire/admin/settings/shipping.blade.php`

#### Component Requirements

| Property | Type | Purpose |
|----------|------|---------|
| `zones` | `Collection` | Shipping zones with rates |
| `editingZone` | `?ShippingZone` | Zone being edited |
| `zoneName` | `string` | Name for zone form |
| `zoneCountries` | `array` | Selected countries for zone |
| `editingRate` | `?ShippingRate` | Rate being edited |
| `rateName` | `string` | Rate name |
| `rateType` | `string` | `flat`, `weight`, `price`, `carrier` |
| `rateConfig` | `array` | Rate configuration (depends on type) |
| `rateActive` | `bool` | Whether rate is active |
| `testAddress` | `array` | Address fields for test tool |
| `testResult` | `?array` | Result of test address lookup |

| Action | Behavior |
|--------|----------|
| `openZoneModal(?ShippingZone $zone)` | Opens zone create/edit modal |
| `saveZone()` | Saves shipping zone |
| `deleteZone(int $zoneId)` | Deletes a shipping zone |
| `openRateModal(int $zoneId, ?ShippingRate $rate)` | Opens rate create/edit modal |
| `saveRate()` | Saves shipping rate |
| `deleteRate(int $rateId)` | Deletes a rate |
| `testShippingAddress()` | Tests which zone/rate matches a given address |

#### Layout Wireframe

```
+==================================================================+
| Shipping                                         [+ Add zone]    |
+==================================================================+
|                                                                   |
| +--------------------------------------------------------------+ |
| | ZONE: Domestic                            [Edit] [Delete]    | |
| | Countries: US, CA                                             | |
| |                                                               | |
| | Name      | Type    | Config           | Active | Actions    | |
| |-----------|---------|------------------|--------|------------|  |
| | Standard  | flat    | $5.00            | [on]   | [Ed] [Del]| |
| | Express   | flat    | $15.00           | [on]   | [Ed] [Del]| |
| | [+ Add rate]                                                  | |
| +--------------------------------------------------------------+ |
|                                                                   |
| +--------------------------------------------------------------+ |
| | ZONE: Europe                              [Edit] [Delete]    | |
| | Countries: DE, FR, GB, ...                                    | |
| | (rates table...)                                              | |
| +--------------------------------------------------------------+ |
|                                                                   |
| TEST SHIPPING ADDRESS                                             |
| Country: [v]  State: [    ]  City: [    ]  ZIP: [    ]           |
| [Test]                                                            |
| Result: Matched zone: Domestic                                    |
|         Standard - $5.00 / Express - $15.00                      |
+==================================================================+
```

Each zone is displayed as a card with:
- Zone name heading and Edit/Delete buttons in the header
- Countries list as muted text
- Rates table inside the zone card with columns: Name, Type (as badge), Config summary, Active (toggle switch), Actions (Edit/Delete buttons)
- "Add rate" button at the bottom of each zone card

"Add zone" button at the top of the page.

#### Zone Modal

| Property | Value |
|----------|-------|
| Modal name | `zone-form` |
| Max width | md |
| Heading | "Edit shipping zone" or "Add shipping zone" (dynamic) |

**Form fields:**
- Zone name input (placeholder: "Domestic, Europe, International...")
- Countries: scrollable checklist of all available countries with checkboxes
- Cancel button (ghost) and "Save zone" button (primary)

#### Rate Modal

| Property | Value |
|----------|-------|
| Modal name | `rate-form` |
| Max width | md |
| Heading | "Edit shipping rate" or "Add shipping rate" (dynamic) |

**Form fields:**
- Rate name input (placeholder: "Standard, Express...")
- Rate type select: Flat rate, Weight-based, Price-based, Carrier-calculated
- Dynamic config fields based on rate type:
  - **Flat:** Price input
  - **Weight-based:** Min weight (g) input, Max weight (g) input, Price input
  - **Price-based:** Min order amount input, Max order amount input, Price input
  - **Carrier:** Info callout: "Carrier-calculated rates require a carrier integration to be configured."
- Active toggle switch with "Active" text label
- Cancel button (ghost) and "Save rate" button (primary)

#### Test Shipping Address Tool

A card section at the bottom of the page:
- Heading "Test shipping address"
- Description: "Enter an address to see which shipping zone and rates match."
- 2-column grid of fields: Country (select), State/Region (input), City (input), ZIP/Postal code (input)
- "Test" button
- Result area (shown after test):
  - If matched: "Matched zone: [zone name]" and list of available rates with prices
  - If no match: Warning callout "No shipping zone matches this address."

### 11.4 Tax Settings

**Route:** `GET /admin/settings/taxes`

**Livewire component:** `App\Livewire\Admin\Settings\Taxes`

**Blade view:** `resources/views/livewire/admin/settings/taxes.blade.php`

#### Component Requirements

| Property | Type | Purpose |
|----------|------|---------|
| `mode` | `string` | `manual` or `provider` |
| `pricesIncludeTax` | `bool` | Whether prices include tax |
| `provider` | `string` | Provider name (e.g., `stripe_tax`) |
| `providerApiKey` | `string` | API key for tax provider |
| `manualRates` | `array` | Array of `{zone_name, rate_percentage}` |

| Action | Behavior |
|--------|----------|
| `save()` | Saves tax settings |
| `addManualRate()` | Adds a new empty rate row |
| `removeManualRate(int $index)` | Removes a manual rate |

#### Layout Wireframe

```
+==================================================================+
| TAXES                                                             |
+==================================================================+
| MODE SELECTION                                                    |
|  ( ) Manual tax rates - Define tax rates per zone manually       |
|  (o) Tax provider - Use an automated tax calculation service     |
+==================================================================+
| MANUAL RATES TABLE (shown when mode = "manual")                  |
| Zone name       | Rate (%)    |                                   |
|-----------------|-------------|                                   |
| [EU           ] | [19.00    ] | [trash]                          |
| [US-CA        ] | [7.25     ] | [trash]                          |
| [+ Add rate]                                                      |
+==================================================================+
| PROVIDER CONFIG (shown when mode = "provider")                   |
|  Provider: [Stripe Tax v]                                        |
|  API key:  [*************]                                       |
+==================================================================+
| [separator]                                                       |
| TAX-INCLUSIVE TOGGLE                                              |
|  [switch: ON]  Prices include tax                                |
|  Description: When enabled, the listed price includes tax.       |
|  Tax is calculated backwards from the price.                      |
+==================================================================+
| [Save]                                                            |
+==================================================================+
```

**Mode selection:** Two radio buttons - "Manual tax rates" (description: "Define tax rates per zone manually") and "Tax provider" (description: "Use an automated tax calculation service"). Live-bound.

**Manual rates table:** Shown when mode = "manual". Inline-editable table with columns: Zone name (text input), Rate % (number input with step 0.01). Each row has a trash button. "Add rate" ghost button with plus icon.

**Provider config:** Shown when mode = "provider". Provider select (Stripe Tax / None) and API key password input.

**Tax-inclusive toggle:** Toggle switch with "Prices include tax" label and description text explaining the behavior.

Save button at the bottom.

---

## 12. Themes Management

### 12.1 Themes List

**Route:** `GET /admin/themes`

**Livewire component:** `App\Livewire\Admin\Themes\Index`

**Blade view:** `resources/views/livewire/admin/themes/index.blade.php`

#### Component Requirements


Output:
Chunk ID: 88b39a
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1885
Output:
<?php

namespace App\Livewire\Admin\Settings;

use App\Enums\StoreDomainType;
use App\Models\Store;
use App\Models\StoreDomain;
use App\Models\StoreSettings;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Support\Collection;
use Illuminate\Validation\Rule;
use Livewire\Attributes\Locked;
use Livewire\Component;

class Index extends Component
{
    use AuthorizesRequests;

    #[Locked]
    public int $storeId;

    public string $storeName = '';

    public string $storeHandle = '';

    public string $defaultCurrency = 'EUR';

    public string $defaultLocale = 'en';

    public string $timezone = 'UTC';

    public bool $announcementEnabled = false;

    public string $announcementText = '';

    public bool $guestCheckoutEnabled = true;

    public string $newHostname = '';

    public string $newType = 'storefront';

    public function mount(): void
    {
        $store = $this->store();

        $this->authorize('update', $store);

        $settings = $this->storeSettings($store)->settings_json ?? [];

        $this->storeId = $store->getKey();
        $this->storeName = $store->name;
        $this->storeHandle = $store->handle;
        $this->defaultCurrency = $store->default_currency;
        $this->defaultLocale = $store->default_locale;
        $this->timezone = $store->timezone;
        $this->announcementEnabled = (bool) data_get($settings, 'announcement.enabled', false);
        $this->announcementText = (string) data_get($settings, 'announcement.text', '');
        $this->guestCheckoutEnabled = (bool) data_get($settings, 'checkout.guest_checkout_enabled', true);
    }

    public function save(): void
    {
        $store = $this->scopedStore();

        $this->authorize('update', $store);

        $validated = $this->validate([
            'storeName' => ['required', 'string', 'max:255'],
            'defaultCurrency' => ['required', Rule::in($this->currencyOptions())],
            'defaultLocale' => ['required', Rule::in(array_keys($this->localeOptions()))],
            'timezone' => ['required', Rule::in(timezone_identifiers_list())],
            'announcementEnabled' => ['boolean'],
            'announcementText' => ['nullable', 'string', 'max:255'],
            'guestCheckoutEnabled' => ['boolean'],
        ]);

        $store->forceFill([
            'name' => $validated['storeName'],
            'default_currency' => $validated['defaultCurrency'],
            'default_locale' => $validated['defaultLocale'],
            'timezone' => $validated['timezone'],
        ])->save();

        $settings = $this->storeSettings($store);
        $settings->forceFill([
            'settings_json' => array_replace_recursive($settings->settings_json ?? [], [
                'announcement' => [
                    'enabled' => $this->announcementEnabled,
                    'text' => $this->announcementText,
                ],
                'checkout' => [
                    'guest_checkout_enabled' => $this->guestCheckoutEnabled,
                ],
            ]),
            'updated_at' => now(),
        ])->save();

        session()->flash('status', 'Settings saved');
        $this->dispatch('toast', type: 'success', message: __('Settings saved'));
    }

    public function addDomain(): void
    {
        $store = $this->scopedStore();

        $this->authorize('update', $store);

        $validated = $this->validate([
            'newHostname' => [
                'required',
                'string',
                'max:255',
                'regex:/^[a-z0-9.-]+$/i',
                Rule::unique('store_domains', 'hostname'),
            ],
            'newType' => ['required', Rule::in(array_column(StoreDomainType::cases(), 'value'))],
        ], [], [
            'newHostname' => 'hostname',
            'newType' => 'domain type',
        ]);

        StoreDomain::query()->create([
            'store_id' => $store->getKey(),
            'hostname' => mb_strtolower(trim($validated['newHostname'])),
            'type' => StoreDomainType::from($validated['newType']),
            'is_primary' => $this->domains()->isEmpty(),
            'tls_mode' => 'managed',
        ]);

        $this->reset('newHostname');

        session()->flash('status', 'Domain added');
        $this->dispatch('toast', type: 'success', message: __('Domain added'));
    }

    public function setPrimary(int $domainId): void
    {
        $store = $this->scopedStore();

        $this->authorize('update', $store);

        $domain = $this->domain($domainId);

        StoreDomain::query()
            ->where('store_id', $store->getKey())
            ->update(['is_primary' => false]);

        $domain->forceFill(['is_primary' => true])->save();

        session()->flash('status', 'Primary domain updated');
    }

    public function removeDomain(int $domainId): void
    {
        $store = $this->scopedStore();

        $this->authorize('update', $store);

        $domain = $this->domain($domainId);
        $wasPrimary = $domain->is_primary;

        $domain->delete();

        if ($wasPrimary) {
            StoreDomain::query()
                ->where('store_id', $store->getKey())
                ->orderBy('id')
                ->first()
                ?->forceFill(['is_primary' => true])
                ->save();
        }

        session()->flash('status', 'Domain removed');
    }

    /**
     * @return Collection<int, StoreDomain>
     */
    public function domains(): Collection
    {
        return StoreDomain::query()
            ->where('store_id', $this->storeId)
            ->orderByDesc('is_primary')
            ->orderBy('hostname')
            ->get();
    }

    /**
     * @return array<string, string>
     */
    public function localeOptions(): array
    {
        return [
            'en' => 'English',
            'de' => 'German',
            'fr' => 'French',
        ];
    }

    /**
     * @return list<string>
     */
    public function currencyOptions(): array
    {
        return ['EUR', 'USD', 'GBP', 'CHF'];
    }

    /**
     * @return list<string>
     */
    public function timezoneOptions(): array
    {
        return collect(timezone_identifiers_list())
            ->filter(fn (string $timezone): bool => str_starts_with($timezone, 'Europe/') || str_starts_with($timezone, 'America/'))
            ->values()
            ->all();
    }

    public function render(): mixed
    {
        return view('livewire.admin.settings.index', [
            'domains' => $this->domains(),
            'currencyOptions' => $this->currencyOptions(),
            'localeOptions' => $this->localeOptions(),
            'timezoneOptions' => $this->timezoneOptions(),
        ])->layout('layouts.app', [
            'title' => __('Settings'),
        ]);
    }

    private function store(): Store
    {
        $store = app('current_store');

        abort_unless($store instanceof Store, 404);

        return $store;
    }

    private function scopedStore(): Store
    {
        return Store::query()->whereKey($this->storeId)->firstOrFail();
    }

    private function storeSettings(Store $store): StoreSettings
    {
        return StoreSettings::query()->firstOrCreate(
            ['store_id' => $store->getKey()],
            ['settings_json' => []],
        );
    }

    private function domain(int $domainId): StoreDomain
    {
        return StoreDomain::query()
            ->where('store_id', $this->storeId)
            ->whereKey($domainId)
            ->firstOrFail();
    }
}


/bin/zsh
-lc
sed -n '1,240p' routes/web.php

<?php

use App\Http\Middleware\EnsureUserEmailIsVerified;
use App\Livewire\Admin\Analytics\Index as AdminAnalyticsIndex;
use App\Livewire\Admin\Apps\Index as AdminAppsIndex;
use App\Livewire\Admin\Apps\Show as AdminAppShow;
use App\Livewire\Admin\Auth\Login as AdminLogin;
use App\Livewire\Admin\Collections\Form as AdminCollectionForm;
use App\Livewire\Admin\Collections\Index as AdminCollectionsIndex;
use App\Livewire\Admin\Customers\Index as AdminCustomersIndex;
use App\Livewire\Admin\Customers\Show as AdminCustomerShow;
use App\Livewire\Admin\Dashboard as AdminDashboard;
use App\Livewire\Admin\Developers\Index as AdminDevelopersIndex;
use App\Livewire\Admin\Discounts\Form as AdminDiscountForm;
use App\Livewire\Admin\Discounts\Index as AdminDiscountsIndex;
use App\Livewire\Admin\Inventory\Index as AdminInventoryIndex;
use App\Livewire\Admin\Navigation\Index as AdminNavigationIndex;
use App\Livewire\Admin\Orders\Index as AdminOrdersIndex;
use App\Livewire\Admin\Orders\Show as AdminOrderShow;
use App\Livewire\Admin\Pages\Form as AdminPageForm;
use App\Livewire\Admin\Pages\Index as AdminPagesIndex;
use App\Livewire\Admin\Products\Form as AdminProductForm;
use App\Livewire\Admin\Products\Index as AdminProductsIndex;
use App\Livewire\Admin\Search\Settings as AdminSearchSettings;
use App\Livewire\Admin\Settings\Index as AdminSettingsIndex;
use App\Livewire\Admin\Settings\Shipping as AdminSettingsShipping;
use App\Livewire\Admin\Settings\Taxes as AdminSettingsTaxes;
use App\Livewire\Admin\Themes\Editor as AdminThemeEditor;
use App\Livewire\Admin\Themes\Index as AdminThemesIndex;
use App\Livewire\Storefront\Account\Auth\ForgotPassword as CustomerForgotPassword;
use App\Livewire\Storefront\Account\Auth\Login as CustomerLogin;
use App\Livewire\Storefront\Account\Auth\Register as CustomerRegister;
use App\Livewire\Storefront\Account\Auth\ResetPassword as CustomerResetPassword;
use App\Livewire\Storefront\Account\Orders\Index as CustomerOrdersIndex;
use App\Livewire\Storefront\Account\Orders\Show as CustomerOrderShow;
use App\Livewire\Storefront\Cart\Show as StorefrontCartShow;
use App\Livewire\Storefront\Checkout\Confirmation as StorefrontCheckoutConfirmation;
use App\Livewire\Storefront\Checkout\Show as StorefrontCheckoutShow;
use App\Livewire\Storefront\Collections\Index as StorefrontCollectionsIndex;
use App\Livewire\Storefront\Collections\Show as StorefrontCollectionShow;
use App\Livewire\Storefront\Home as StorefrontHome;
use App\Livewire\Storefront\Pages\Show as StorefrontPageShow;
use App\Livewire\Storefront\Products\Show as StorefrontProductShow;
use App\Livewire\Storefront\Search\Index as StorefrontSearchIndex;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;

Route::middleware(['storefront'])->group(function (): void {
    Route::livewire('/', StorefrontHome::class)->name('home');
    Route::livewire('collections', StorefrontCollectionsIndex::class)->name('collections.index');
    Route::livewire('collections/{handle}', StorefrontCollectionShow::class)->name('collections.show');
    Route::livewire('products/{handle}', StorefrontProductShow::class)->name('products.show');
    Route::livewire('cart', StorefrontCartShow::class)->name('cart.show');
    Route::livewire('checkout', StorefrontCheckoutShow::class)->name('checkout.show');
    Route::livewire('checkout/confirmation/{order}', StorefrontCheckoutConfirmation::class)->name('checkout.confirmation');
    Route::livewire('search', StorefrontSearchIndex::class)->name('search.index');
    Route::livewire('pages/{handle}', StorefrontPageShow::class)->name('pages.show');
});

Route::livewire('admin/login', AdminLogin::class)
    ->middleware('guest')
    ->name('admin.login');

Route::post('admin/logout', function () {
    Auth::guard('web')->logout();

    request()->session()->invalidate();
    request()->session()->regenerateToken();

    return redirect()->route('admin.login');
})->middleware('auth')->name('admin.logout');

Route::middleware(['auth', EnsureUserEmailIsVerified::class, 'admin'])->prefix('admin')->name('admin.')->group(function (): void {
    Route::livewire('/', AdminDashboard::class)->name('dashboard');
    Route::livewire('analytics', AdminAnalyticsIndex::class)->name('analytics.index');
    Route::livewire('apps', AdminAppsIndex::class)->name('apps.index');
    Route::livewire('apps/{installation}', AdminAppShow::class)->name('apps.show');
    Route::livewire('developers', AdminDevelopersIndex::class)->name('developers.index');
    Route::livewire('products', AdminProductsIndex::class)->name('products.index');
    Route::livewire('products/create', AdminProductForm::class)->name('products.create');
    Route::livewire('products/{product}/edit', AdminProductForm::class)->name('products.edit');
    Route::livewire('inventory', AdminInventoryIndex::class)->name('inventory.index');
    Route::livewire('orders', AdminOrdersIndex::class)->name('orders.index');
    Route::livewire('orders/{order}', AdminOrderShow::class)->name('orders.show');
    Route::livewire('customers', AdminCustomersIndex::class)->name('customers.index');
    Route::livewire('customers/{customer}', AdminCustomerShow::class)->name('customers.show');
    Route::livewire('discounts', AdminDiscountsIndex::class)->name('discounts.index');
    Route::livewire('discounts/create', AdminDiscountForm::class)->name('discounts.create');
    Route::livewire('discounts/{discount}/edit', AdminDiscountForm::class)->name('discounts.edit');
    Route::livewire('pages', AdminPagesIndex::class)->name('pages.index');
    Route::livewire('pages/create', AdminPageForm::class)->name('pages.create');
    Route::livewire('pages/{page}/edit', AdminPageForm::class)->name('pages.edit');
    Route::livewire('navigation', AdminNavigationIndex::class)->name('navigation.index');
    Route::livewire('themes', AdminThemesIndex::class)->name('themes.index');
    Route::livewire('themes/{theme}/editor', AdminThemeEditor::class)->name('themes.editor');
    Route::livewire('settings', AdminSettingsIndex::class)->name('settings.index');
    Route::livewire('settings/shipping', AdminSettingsShipping::class)->name('settings.shipping');
    Route::livewire('settings/taxes', AdminSettingsTaxes::class)->name('settings.taxes');
    Route::livewire('search/settings', AdminSearchSettings::class)->name('search.settings');
    Route::livewire('collections', AdminCollectionsIndex::class)->name('collections.index');
    Route::livewire('collections/create', AdminCollectionForm::class)->name('collections.create');
    Route::livewire('collections/{collection}/edit', AdminCollectionForm::class)->name('collections.edit');
});

Route::middleware(['storefront'])->group(function (): void {
    Route::livewire('account/login', CustomerLogin::class)
        ->middleware('guest:customer')
        ->name('account.login');

    Route::livewire('account/register', CustomerRegister::class)
        ->middleware('guest:customer')
        ->name('account.register');

    Route::livewire('account/forgot-password', CustomerForgotPassword::class)
        ->middleware('guest:customer')
        ->name('account.password.request');

    Route::livewire('account/reset-password/{token}', CustomerResetPassword::class)
        ->middleware('guest:customer')
        ->name('account.password.reset');

    Route::livewire('account', CustomerOrdersIndex::class)
        ->middleware('auth:customer')
        ->name('account.dashboard');

    Route::livewire('account/orders/{order}', CustomerOrderShow::class)
        ->middleware('auth:customer')
        ->name('account.orders.show');
});

Route::redirect('dashboard', 'admin')
    ->middleware(['auth', 'verified'])
    ->name('dashboard');

require __DIR__.'/settings.php';


sed -n '1,340p' resources/views/livewire/admin/settings/index.blade.php

index.blade.php

            <flux:heading size="xl">Settings</flux:heading>
            <flux:text class="mt-1">Store defaults, checkout preferences, and domains.</flux:text>

            <flux:button :href="route('admin.settings.index')" wire:navigate variant="primary">General</flux:button>
            <flux:button :href="route('admin.settings.shipping')" wire:navigate variant="filled">Shipping</flux:button>
            <flux:button :href="route('admin.settings.taxes')" wire:navigate variant="filled">Taxes</flux:button>

    @if (session('status'))
        <flux:callout color="green" icon="check-circle">{{ session('status') }}</flux:callout>
    @endif

    <form wire:submit="save" class="space-y-6">

                    <flux:heading size="lg">Store details</flux:heading>
                    <flux:text class="mt-1">Basic storefront identity.</flux:text>

                    <flux:input wire:model="storeName" label="Store name" />
                    <flux:input wire:model="storeHandle" label="Store handle" disabled />
                    <flux:error name="storeName" />

            <flux:separator />

                    <flux:heading size="lg">Defaults</flux:heading>
                    <flux:text class="mt-1">Currency, language, and timezone.</flux:text>

                    <flux:select wire:model="defaultCurrency" label="Default currency">
                        @foreach ($currencyOptions as $currency)
                            <flux:select.option value="{{ $currency }}">{{ $currency }}</flux:select.option>
                        @endforeach
                    </flux:select>

                    <flux:select wire:model="defaultLocale" label="Default locale">
                        @foreach ($localeOptions as $locale => $label)
                            <flux:select.option value="{{ $locale }}">{{ $label }}</flux:select.option>
                        @endforeach
                    </flux:select>

                    <flux:select wire:model="timezone" label="Timezone">
                        @foreach ($timezoneOptions as $timezoneOption)
                            <flux:select.option value="{{ $timezoneOption }}">{{ $timezoneOption }}</flux:select.option>
                        @endforeach
                    </flux:select>

            <flux:separator />

                    <flux:heading size="lg">Checkout</flux:heading>
                    <flux:text class="mt-1">Customer-facing storefront defaults.</flux:text>

                    <flux:switch wire:model="announcementEnabled" label="Announcement bar" align="left" />
                    <flux:input wire:model="announcementText" label="Announcement text" />
                    <flux:checkbox wire:model="guestCheckoutEnabled" label="Guest checkout enabled" />

                <flux:button type="submit" variant="primary" wire:loading.attr="disabled">
                    Save settings
                    Saving...
                </flux:button>

    </form>

                <flux:heading size="lg">Domains</flux:heading>
                <flux:text class="mt-1">Hostnames connected to this store.</flux:text>

                <flux:input wire:model="newHostname" label="Hostname" placeholder="shop.example.com" />
                <flux:select wire:model="newType" label="Type">
                    <flux:select.option value="storefront">Storefront</flux:select.option>
                    <flux:select.option value="admin">Admin</flux:select.option>
                    <flux:select.option value="api">API</flux:select.option>
                </flux:select>

                    <flux:button type="button" wire:click="addDomain" variant="primary" icon="plus">Add</flux:button>

                        Hostname
                        Type
                        Primary
                        TLS
                        Actions

                    @foreach ($domains as $domain)

getKey() }}">
                            {{ $domain->hostname }}
                            <flux:badge>{{ Str::headline($domain->type->value) }}</flux:badge>

                                @if ($domain->is_primary)
                                    <flux:badge color="green">Primary</flux:badge>
                                @else
                                    -
                                @endif

                            {{ Str::headline($domain->tls_mode) }}

                                    @unless ($domain->is_primary)
                                        <flux:button type="button" size="sm" variant="filled" wire:click="setPrimary({{ $domain->getKey() }})">Set primary</flux:button>
                                    @endunless
                                    <flux:button type="button" size="sm" variant="danger" wire:click="removeDomain({{ $domain->getKey() }})">Delete</flux:button>

                    @endforeach


Output:
Chunk ID: 663d50
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1888
Output:

            <flux:heading size="xl">Settings</flux:heading>
            <flux:text class="mt-1">Store defaults, checkout preferences, and domains.</flux:text>

            <flux:button :href="route('admin.settings.index')" wire:navigate variant="primary">General</flux:button>
            <flux:button :href="route('admin.settings.shipping')" wire:navigate variant="filled">Shipping</flux:button>
            <flux:button :href="route('admin.settings.taxes')" wire:navigate variant="filled">Taxes</flux:button>

    @if (session('status'))
        <flux:callout color="green" icon="check-circle">{{ session('status') }}</flux:callout>
    @endif

    <form wire:submit="save" class="space-y-6">

                    <flux:heading size="lg">Store details</flux:heading>
                    <flux:text class="mt-1">Basic storefront identity.</flux:text>

                    <flux:input wire:model="storeName" label="Store name" />
                    <flux:input wire:model="storeHandle" label="Store handle" disabled />
                    <flux:error name="storeName" />

            <flux:separator />

                    <flux:heading size="lg">Defaults</flux:heading>
                    <flux:text class="mt-1">Currency, language, and timezone.</flux:text>

                    <flux:select wire:model="defaultCurrency" label="Default currency">
                        @foreach ($currencyOptions as $currency)
                            <flux:select.option value="{{ $currency }}">{{ $currency }}</flux:select.option>
                        @endforeach
                    </flux:select>

                    <flux:select wire:model="defaultLocale" label="Default locale">
                        @foreach ($localeOptions as $locale => $label)
                            <flux:select.option value="{{ $locale }}">{{ $label }}</flux:select.option>
                        @endforeach
                    </flux:select>

                    <flux:select wire:model="timezone" label="Timezone">
                        @foreach ($timezoneOptions as $timezoneOption)
                            <flux:select.option value="{{ $timezoneOption }}">{{ $timezoneOption }}</flux:select.option>
                        @endforeach
                    </flux:select>

            <flux:separator />

                    <flux:heading size="lg">Checkout</flux:heading>
                    <flux:text class="mt-1">Customer-facing storefront defaults.</flux:text>

                    <flux:switch wire:model="announcementEnabled" label="Announcement bar" align="left" />
                    <flux:input wire:model="announcementText" label="Announcement text" />
                    <flux:checkbox wire:model="guestCheckoutEnabled" label="Guest checkout enabled" />

                <flux:button type="submit" variant="primary" wire:loading.attr="disabled">
                    Save settings
                    Saving...
                </flux:button>

    </form>

                <flux:heading size="lg">Domains</flux:heading>
                <flux:text class="mt-1">Hostnames connected to this store.</flux:text>

                <flux:input wire:model="newHostname" label="Hostname" placeholder="shop.example.com" />
                <flux:select wire:model="newType" label="Type">
                    <flux:select.option value="storefront">Storefront</flux:select.option>
                    <flux:select.option value="admin">Admin</flux:select.option>
                    <flux:select.option value="api">API</flux:select.option>
                </flux:select>

                    <flux:button type="button" wire:click="addDomain" variant="primary" icon="plus">Add</flux:button>

                        Hostname
                        Type
                        Primary
                        TLS
                        Actions

                    @foreach ($domains as $domain)

getKey() }}">
                            {{ $domain->hostname }}
                            <flux:badge>{{ Str::headline($domain->type->value) }}</flux:badge>

                                @if ($domain->is_primary)
                                    <flux:badge color="green">Primary</flux:badge>
                                @else
                                    -
                                @endif

                            {{ Str::headline($domain->tls_mode) }}

                                    @unless ($domain->is_primary)
                                        <flux:button type="button" size="sm" variant="filled" wire:click="setPrimary({{ $domain->getKey() }})">Set primary</flux:button>
                                    @endunless
                                    <flux:button type="button" size="sm" variant="danger" wire:click="removeDomain({{ $domain->getKey() }})">Delete</flux:button>

                    @endforeach


Output:
Chunk ID: ea3c20
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1937
Output:
<?php

use App\Http\Middleware\EnsureUserEmailIsVerified;
use App\Livewire\Admin\Analytics\Index as AdminAnalyticsIndex;
use App\Livewire\Admin\Apps\Index as AdminAppsIndex;
use App\Livewire\Admin\Apps\Show as AdminAppShow;
use App\Livewire\Admin\Auth\Login as AdminLogin;
use App\Livewire\Admin\Collections\Form as AdminCollectionForm;
use App\Livewire\Admin\Collections\Index as AdminCollectionsIndex;
use App\Livewire\Admin\Customers\Index as AdminCustomersIndex;
use App\Livewire\Admin\Customers\Show as AdminCustomerShow;
use App\Livewire\Admin\Dashboard as AdminDashboard;
use App\Livewire\Admin\Developers\Index as AdminDevelopersIndex;
use App\Livewire\Admin\Discounts\Form as AdminDiscountForm;
use App\Livewire\Admin\Discounts\Index as AdminDiscountsIndex;
use App\Livewire\Admin\Inventory\Index as AdminInventoryIndex;
use App\Livewire\Admin\Navigation\Index as AdminNavigationIndex;
use App\Livewire\Admin\Orders\Index as AdminOrdersIndex;
use App\Livewire\Admin\Orders\Show as AdminOrderShow;
use App\Livewire\Admin\Pages\Form as AdminPageForm;
use App\Livewire\Admin\Pages\Index as AdminPagesIndex;
use App\Livewire\Admin\Products\Form as AdminProductForm;
use App\Livewire\Admin\Products\Index as AdminProductsIndex;
use App\Livewire\Admin\Search\Settings as AdminSearchSettings;
use App\Livewire\Admin\Settings\Index as AdminSettingsIndex;
use App\Livewire\Admin\Settings\Shipping as AdminSettingsShipping;
use App\Livewire\Admin\Settings\Taxes as AdminSettingsTaxes;
use App\Livewire\Admin\Themes\Editor as AdminThemeEditor;
use App\Livewire\Admin\Themes\Index as AdminThemesIndex;
use App\Livewire\Storefront\Account\Auth\ForgotPassword as CustomerForgotPassword;
use App\Livewire\Storefront\Account\Auth\Login as CustomerLogin;
use App\Livewire\Storefront\Account\Auth\Register as CustomerRegister;
use App\Livewire\Storefront\Account\Auth\ResetPassword as CustomerResetPassword;
use App\Livewire\Storefront\Account\Orders\Index as CustomerOrdersIndex;
use App\Livewire\Storefront\Account\Orders\Show as CustomerOrderShow;
use App\Livewire\Storefront\Cart\Show as StorefrontCartShow;
use App\Livewire\Storefront\Checkout\Confirmation as StorefrontCheckoutConfirmation;
use App\Livewire\Storefront\Checkout\Show as StorefrontCheckoutShow;
use App\Livewire\Storefront\Collections\Index as StorefrontCollectionsIndex;
use App\Livewire\Storefront\Collections\Show as StorefrontCollectionShow;
use App\Livewire\Storefront\Home as StorefrontHome;
use App\Livewire\Storefront\Pages\Show as StorefrontPageShow;
use App\Livewire\Storefront\Products\Show as StorefrontProductShow;
use App\Livewire\Storefront\Search\Index as StorefrontSearchIndex;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;

Route::middleware(['storefront'])->group(function (): void {
    Route::livewire('/', StorefrontHome::class)->name('home');
    Route::livewire('collections', StorefrontCollectionsIndex::class)->name('collections.index');
    Route::livewire('collections/{handle}', StorefrontCollectionShow::class)->name('collections.show');
    Route::livewire('products/{handle}', StorefrontProductShow::class)->name('products.show');
    Route::livewire('cart', StorefrontCartShow::class)->name('cart.show');
    Route::livewire('checkout', StorefrontCheckoutShow::class)->name('checkout.show');
    Route::livewire('checkout/confirmation/{order}', StorefrontCheckoutConfirmation::class)->name('checkout.confirmation');
    Route::livewire('search', StorefrontSearchIndex::class)->name('search.index');
    Route::livewire('pages/{handle}', StorefrontPageShow::class)->name('pages.show');
});

Route::livewire('admin/login', AdminLogin::class)
    ->middleware('guest')
    ->name('admin.login');

Route::post('admin/logout', function () {
    Auth::guard('web')->logout();

    request()->session()->invalidate();
    request()->session()->regenerateToken();

    return redirect()->route('admin.login');
})->middleware('auth')->name('admin.logout');

Route::middleware(['auth', EnsureUserEmailIsVerified::class, 'admin'])->prefix('admin')->name('admin.')->group(function (): void {
    Route::livewire('/', AdminDashboard::class)->name('dashboard');
    Route::livewire('analytics', AdminAnalyticsIndex::class)->name('analytics.index');
    Route::livewire('apps', AdminAppsIndex::class)->name('apps.index');
    Route::livewire('apps/{installation}', AdminAppShow::class)->name('apps.show');
    Route::livewire('developers', AdminDevelopersIndex::class)->name('developers.index');
    Route::livewire('products', AdminProductsIndex::class)->name('products.index');
    Route::livewire('products/create', AdminProductForm::class)->name('products.create');
    Route::livewire('products/{product}/edit', AdminProductForm::class)->name('products.edit');
    Route::livewire('inventory', AdminInventoryIndex::class)->name('inventory.index');
    Route::livewire('orders', AdminOrdersIndex::class)->name('orders.index');
    Route::livewire('orders/{order}', AdminOrderShow::class)->name('orders.show');
    Route::livewire('customers', AdminCustomersIndex::class)->name('customers.index');
    Route::livewire('customers/{customer}', AdminCustomerShow::class)->name('customers.show');
    Route::livewire('discounts', AdminDiscountsIndex::class)->name('discounts.index');
    Route::livewire('discounts/create', AdminDiscountForm::class)->name('discounts.create');
    Route::livewire('discounts/{discount}/edit', AdminDiscountForm::class)->name('discounts.edit');
    Route::livewire('pages', AdminPagesIndex::class)->name('pages.index');
    Route::livewire('pages/create', AdminPageForm::class)->name('pages.create');
    Route::livewire('pages/{page}/edit', AdminPageForm::class)->name('pages.edit');
    Route::livewire('navigation', AdminNavigationIndex::class)->name('navigation.index');
    Route::livewire('themes', AdminThemesIndex::class)->name('themes.index');
    Route::livewire('themes/{theme}/editor', AdminThemeEditor::class)->name('themes.editor');
    Route::livewire('settings', AdminSettingsIndex::class)->name('settings.index');
    Route::livewire('settings/shipping', AdminSettingsShipping::class)->name('settings.shipping');
    Route::livewire('settings/taxes', AdminSettingsTaxes::class)->name('settings.taxes');
    Route::livewire('search/settings', AdminSearchSettings::class)->name('search.settings');
    Route::livewire('collections', AdminCollectionsIndex::class)->name('collections.index');
    Route::livewire('collections/create', AdminCollectionForm::class)->name('collections.create');
    Route::livewire('collections/{collection}/edit', AdminCollectionForm::class)->name('collections.edit');
});

Route::middleware(['storefront'])->group(function (): void {
    Route::livewire('account/login', CustomerLogin::class)
        ->middleware('guest:customer')
        ->name('account.login');

    Route::livewire('account/register', CustomerRegister::class)
        ->middleware('guest:customer')
        ->name('account.register');

    Route::livewire('account/forgot-password', CustomerForgotPassword::class)
        ->middleware('guest:customer')
        ->name('account.password.request');

    Route::livewire('account/reset-password/{token}', CustomerResetPassword::class)
        ->middleware('guest:customer')
        ->name('account.password.reset');

    Route::livewire('account', CustomerOrdersIndex::class)
        ->middleware('auth:customer')
        ->name('account.dashboard');

    Route::livewire('account/orders/{order}', CustomerOrderShow::class)
        ->middleware('auth:customer')
        ->name('account.orders.show');
});

Route::redirect('dashboard', 'admin')
    ->middleware(['auth', 'verified'])
    ->name('dashboard');

require __DIR__.'/settings.php';


sed -n '1,240p' resources/views/components/admin/sidebar.blade.php && sed -n '1,240p' tests/Feature/Admin/SettingsManagementTest.php

SettingsManagementTest.php

sed: resources/views/components/admin/sidebar.blade.php: No such file or directory


Output:
Chunk ID: ac473d
Wall time: 0.0000 seconds
Process exited with code 1
Original token count: 21
Output:
sed: resources/views/components/admin/sidebar.blade.php: No such file or directory


rg --files resources/views | rg 'sidebar|navigation|layout|app'


sed -n '1,260p' tests/Feature/Admin/SettingsManagementTest.php


rg -n "admin.settings|Settings|sidebar|navigation" resources/views app/Livewire | head -200


sed -n '1,260p' tests/Feature/Admin/SettingsManagementTest.php

<?php

use App\Enums\ShippingRateType;
use App\Enums\StoreUserRole;
use App\Enums\TaxMode;
use App\Livewire\Admin\Settings\Index as AdminSettingsIndex;
use App\Livewire\Admin\Settings\Shipping as AdminSettingsShipping;
use App\Livewire\Admin\Settings\Taxes as AdminSettingsTaxes;
use App\Models\ShippingRate;
use App\Models\ShippingZone;
use App\Models\Store;
use App\Models\StoreDomain;
use App\Models\StoreSettings;
use App\Models\TaxSettings;
use App\Models\User;
use Database\Seeders\DatabaseSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;

uses(RefreshDatabase::class);

beforeEach(function (): void {
    $this->withoutVite();
    $this->seed(DatabaseSeeder::class);
});

function adminSettingsStore(): Store
{
    $store = Store::query()->where('handle', 'acme-fashion')->firstOrFail();
    app()->instance('current_store', $store);

    return $store;
}

function adminSettingsUser(): User
{
    return User::query()->where('email', 'admin@acme.test')->firstOrFail();
}

function adminSettingsUserWithRole(Store $store, StoreUserRole $role): User
{
    $user = User::factory()->create();
    $user->stores()->attach($store->getKey(), [
        'role' => $role->value,
        'created_at' => now(),
    ]);

    return $user;
}

test('settings routes render for owners and reject staff', function (): void {
    $store = adminSettingsStore();
    $owner = adminSettingsUser();
    $staff = adminSettingsUserWithRole($store, StoreUserRole::Staff);

    foreach (['/admin/settings', '/admin/settings/shipping', '/admin/settings/taxes'] as $path) {
        $this->actingAs($owner)
            ->withSession(['current_store_id' => $store->getKey()])
            ->get($path)
            ->assertSuccessful();

        $this->actingAs($staff)
            ->withSession(['current_store_id' => $store->getKey()])
            ->get($path)
            ->assertForbidden();
    }
});

test('general settings update store defaults and domains', function (): void {
    $store = adminSettingsStore();
    $user = adminSettingsUser();

    Livewire::actingAs($user)
        ->test(AdminSettingsIndex::class)
        ->set('storeName', 'Acme Atelier')
        ->set('defaultCurrency', 'GBP')
        ->set('defaultLocale', 'de')
        ->set('timezone', 'Europe/Berlin')
        ->set('announcementEnabled', true)
        ->set('announcementText', 'Spring edits now live')
        ->set('guestCheckoutEnabled', false)
        ->call('save')
        ->assertHasNoErrors()
        ->set('newHostname', 'atelier.test')
        ->set('newType', 'storefront')
        ->call('addDomain')
        ->assertHasNoErrors();

    $settings = StoreSettings::query()->whereKey($store->getKey())->firstOrFail();

    expect($store->refresh()->name)->toBe('Acme Atelier')
        ->and($store->default_currency)->toBe('GBP')
        ->and($store->default_locale)->toBe('de')
        ->and($settings->settings_json['announcement']['text'])->toBe('Spring edits now live')
        ->and($settings->settings_json['checkout']['guest_checkout_enabled'])->toBeFalse()
        ->and(StoreDomain::query()->where('hostname', 'atelier.test')->where('store_id', $store->getKey())->exists())->toBeTrue();
});

test('shipping settings manage zones rates and address tests', function (): void {
    $store = adminSettingsStore();
    $user = adminSettingsUser();

    Livewire::actingAs($user)
        ->test(AdminSettingsShipping::class)
        ->set('zoneName', 'Nordics')
        ->set('zoneCountries', 'SE, NO')
        ->call('saveZone')
        ->assertHasNoErrors();

    $zone = ShippingZone::withoutGlobalScopes()
        ->where('store_id', $store->getKey())
        ->where('name', 'Nordics')
        ->firstOrFail();

    Livewire::actingAs($user)
        ->test(AdminSettingsShipping::class)
        ->call('addRate', $zone->getKey())
        ->set('rateName', 'Nordic Standard')
        ->set('rateType', ShippingRateType::Flat->value)
        ->set('rateAmount', '12.50')
        ->call('saveRate')
        ->assertHasNoErrors()
        ->set('testCountry', 'SE')
        ->call('testShippingAddress')
        ->assertSet('testResult.zone', 'Nordics');

    $rate = ShippingRate::withoutGlobalScopes()
        ->where('zone_id', $zone->getKey())
        ->where('name', 'Nordic Standard')
        ->firstOrFail();

    expect($zone->countries_json)->toBe(['SE', 'NO'])
        ->and($rate->type)->toBe(ShippingRateType::Flat)
        ->and($rate->config_json['amount'])->toBe(1250);
});

test('tax settings save manual and provider configuration', function (): void {
    $store = adminSettingsStore();
    $user = adminSettingsUser();

    Livewire::actingAs($user)
        ->test(AdminSettingsTaxes::class)
        ->set('manualRates', [
            ['country' => 'DE', 'name' => 'VAT', 'rate_percentage' => '19.00'],
            ['country' => 'FR', 'name' => 'TVA', 'rate_percentage' => '20.00'],
        ])
        ->set('pricesIncludeTax', true)
        ->call('save')
        ->assertHasNoErrors();

    $manual = TaxSettings::withoutGlobalScopes()->whereKey($store->getKey())->firstOrFail();

    expect($manual->mode)->toBe(TaxMode::Manual)
        ->and($manual->prices_include_tax)->toBeTrue()
        ->and($manual->config_json['rates'][1]['country'])->toBe('FR')
        ->and($manual->config_json['rates'][1]['rate_bps'])->toBe(2000);

    Livewire::actingAs($user)
        ->test(AdminSettingsTaxes::class)
        ->set('mode', TaxMode::Provider->value)
        ->set('provider', 'stripe_tax')
        ->set('providerApiKey', 'sk_test_tax')
        ->call('save')
        ->assertHasNoErrors();

    $provider = TaxSettings::withoutGlobalScopes()->whereKey($store->getKey())->firstOrFail();

    expect($provider->mode)->toBe(TaxMode::Provider)
        ->and($provider->provider)->toBe('stripe_tax')
        ->and($provider->config_json['provider_api_key'])->toBe('sk_test_tax');
});


rg --files resources/views | rg 'sidebar|navigation|layout|app'

Question: sidebar|navigation|layout|app


Output:
Chunk ID: 52184e
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 191
Output:
resources/views/layouts/storefront.blade.php
resources/views/layouts/app.blade.php
resources/views/layouts/auth/split.blade.php
resources/views/layouts/auth/simple.blade.php
resources/views/layouts/auth/card.blade.php
resources/views/layouts/app/sidebar.blade.php
resources/views/layouts/app/header.blade.php
resources/views/layouts/auth.blade.php
resources/views/livewire/admin/apps/show.blade.php
resources/views/livewire/admin/apps/index.blade.php
resources/views/livewire/admin/navigation/index.blade.php
resources/views/livewire/settings/appearance.blade.php
resources/views/components/app-logo.blade.php
resources/views/components/app-logo-icon.blade.php
resources/views/flux/icon/layout-grid.blade.php
resources/views/components/settings/layout.blade.php


Output:
Chunk ID: c481ec
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1479
Output:
<?php

use App\Enums\ShippingRateType;
use App\Enums\StoreUserRole;
use App\Enums\TaxMode;
use App\Livewire\Admin\Settings\Index as AdminSettingsIndex;
use App\Livewire\Admin\Settings\Shipping as AdminSettingsShipping;
use App\Livewire\Admin\Settings\Taxes as AdminSettingsTaxes;
use App\Models\ShippingRate;
use App\Models\ShippingZone;
use App\Models\Store;
use App\Models\StoreDomain;
use App\Models\StoreSettings;
use App\Models\TaxSettings;
use App\Models\User;
use Database\Seeders\DatabaseSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;

uses(RefreshDatabase::class);

beforeEach(function (): void {
    $this->withoutVite();
    $this->seed(DatabaseSeeder::class);
});

function adminSettingsStore(): Store
{
    $store = Store::query()->where('handle', 'acme-fashion')->firstOrFail();
    app()->instance('current_store', $store);

    return $store;
}

function adminSettingsUser(): User
{
    return User::query()->where('email', 'admin@acme.test')->firstOrFail();
}

function adminSettingsUserWithRole(Store $store, StoreUserRole $role): User
{
    $user = User::factory()->create();
    $user->stores()->attach($store->getKey(), [
        'role' => $role->value,
        'created_at' => now(),
    ]);

    return $user;
}

test('settings routes render for owners and reject staff', function (): void {
    $store = adminSettingsStore();
    $owner = adminSettingsUser();
    $staff = adminSettingsUserWithRole($store, StoreUserRole::Staff);

    foreach (['/admin/settings', '/admin/settings/shipping', '/admin/settings/taxes'] as $path) {
        $this->actingAs($owner)
            ->withSession(['current_store_id' => $store->getKey()])
            ->get($path)
            ->assertSuccessful();

        $this->actingAs($staff)
            ->withSession(['current_store_id' => $store->getKey()])
            ->get($path)
            ->assertForbidden();
    }
});

test('general settings update store defaults and domains', function (): void {
    $store = adminSettingsStore();
    $user = adminSettingsUser();

    Livewire::actingAs($user)
        ->test(AdminSettingsIndex::class)
        ->set('storeName', 'Acme Atelier')
        ->set('defaultCurrency', 'GBP')
        ->set('defaultLocale', 'de')
        ->set('timezone', 'Europe/Berlin')
        ->set('announcementEnabled', true)
        ->set('announcementText', 'Spring edits now live')
        ->set('guestCheckoutEnabled', false)
        ->call('save')
        ->assertHasNoErrors()
        ->set('newHostname', 'atelier.test')
        ->set('newType', 'storefront')
        ->call('addDomain')
        ->assertHasNoErrors();

    $settings = StoreSettings::query()->whereKey($store->getKey())->firstOrFail();

    expect($store->refresh()->name)->toBe('Acme Atelier')
        ->and($store->default_currency)->toBe('GBP')
        ->and($store->default_locale)->toBe('de')
        ->and($settings->settings_json['announcement']['text'])->toBe('Spring edits now live')
        ->and($settings->settings_json['checkout']['guest_checkout_enabled'])->toBeFalse()
        ->and(StoreDomain::query()->where('hostname', 'atelier.test')->where('store_id', $store->getKey())->exists())->toBeTrue();
});

test('shipping settings manage zones rates and address tests', function (): void {
    $store = adminSettingsStore();
    $user = adminSettingsUser();

    Livewire::actingAs($user)
        ->test(AdminSettingsShipping::class)
        ->set('zoneName', 'Nordics')
        ->set('zoneCountries', 'SE, NO')
        ->call('saveZone')
        ->assertHasNoErrors();

    $zone = ShippingZone::withoutGlobalScopes()
        ->where('store_id', $store->getKey())
        ->where('name', 'Nordics')
        ->firstOrFail();

    Livewire::actingAs($user)
        ->test(AdminSettingsShipping::class)
        ->call('addRate', $zone->getKey())
        ->set('rateName', 'Nordic Standard')
        ->set('rateType', ShippingRateType::Flat->value)
        ->set('rateAmount', '12.50')
        ->call('saveRate')
        ->assertHasNoErrors()
        ->set('testCountry', 'SE')
        ->call('testShippingAddress')
        ->assertSet('testResult.zone', 'Nordics');

    $rate = ShippingRate::withoutGlobalScopes()
        ->where('zone_id', $zone->getKey())
        ->where('name', 'Nordic Standard')
        ->firstOrFail();

    expect($zone->countries_json)->toBe(['SE', 'NO'])
        ->and($rate->type)->toBe(ShippingRateType::Flat)
        ->and($rate->config_json['amount'])->toBe(1250);
});

test('tax settings save manual and provider configuration', function (): void {
    $store = adminSettingsStore();
    $user = adminSettingsUser();

    Livewire::actingAs($user)
        ->test(AdminSettingsTaxes::class)
        ->set('manualRates', [
            ['country' => 'DE', 'name' => 'VAT', 'rate_percentage' => '19.00'],
            ['country' => 'FR', 'name' => 'TVA', 'rate_percentage' => '20.00'],
        ])
        ->set('pricesIncludeTax', true)
        ->call('save')
        ->assertHasNoErrors();

    $manual = TaxSettings::withoutGlobalScopes()->whereKey($store->getKey())->firstOrFail();

    expect($manual->mode)->toBe(TaxMode::Manual)
        ->and($manual->prices_include_tax)->toBeTrue()
        ->and($manual->config_json['rates'][1]['country'])->toBe('FR')
        ->and($manual->config_json['rates'][1]['rate_bps'])->toBe(2000);

    Livewire::actingAs($user)
        ->test(AdminSettingsTaxes::class)
        ->set('mode', TaxMode::Provider->value)
        ->set('provider', 'stripe_tax')
        ->set('providerApiKey', 'sk_test_tax')
        ->call('save')
        ->assertHasNoErrors();

    $provider = TaxSettings::withoutGlobalScopes()->whereKey($store->getKey())->firstOrFail();

    expect($provider->mode)->toBe(TaxMode::Provider)
        ->and($provider->provider)->toBe('stripe_tax')
        ->and($provider->config_json['provider_api_key'])->toBe('sk_test_tax');
});


rg -n "admin.settings|Settings|sidebar|navigation" resources/views app/Livewire | head -200

rg -n 'admin.settings|Settings|sidebar|navigation' resources/views app/Livewire

Question: admin.settings|Settings|sidebar|navigation

resources/views/partials/settings-heading.blade.php:2:    <flux:heading size="xl" level="1">{{ __('Settings') }}</flux:heading>
resources/views/layouts/storefront.blade.php:8:        @php($announcement = data_get($themeSettings ?? [], 'announcement', []))
resources/views/layouts/storefront.blade.php:30:            'sticky' => data_get($themeSettings ?? [], 'header.sticky', true),
resources/views/layouts/storefront.blade.php:37:
resources/views/layouts/storefront.blade.php:65:
{{ data_get($themeSettings ?? [], 'footer.tagline') }}

app/Livewire/Admin/Themes/Editor.php:8:use App\Models\ThemeSettings;
app/Livewire/Admin/Themes/Editor.php:9:use App\Services\ThemeSettingsService;
app/Livewire/Admin/Themes/Editor.php:27:    public function mount(Theme $theme, ThemeSettingsService $themeSettings): void
app/Livewire/Admin/Themes/Editor.php:38:            $themeSettings->defaultsForStore($store),
app/Livewire/Admin/Themes/Editor.php:50:    public function save(ThemeSettingsService $settings): void
app/Livewire/Admin/Themes/Editor.php:54:        ThemeSettings::withoutGlobalScopes()->updateOrCreate(
app/Livewire/Admin/Themes/Editor.php:68:    public function publish(ThemeSettingsService $settings): void
resources/views/layouts/app.blade.php:1:<x-layouts::app.sidebar :title="$title ?? null">
resources/views/layouts/app.blade.php:5:</x-layouts::app.sidebar>
app/Livewire/Admin/Navigation/Index.php:153:    public function saveMenu(NavigationService $navigation): void
app/Livewire/Admin/Navigation/Index.php:176:        $navigation->forget($menu);
app/Livewire/Admin/Navigation/Index.php:240:        return view('livewire.admin.navigation.index', [
app/Livewire/Admin/Search/Settings.php:5:use App\Models\SearchSettings;
app/Livewire/Admin/Search/Settings.php:12:class Settings extends Component
app/Livewire/Admin/Search/Settings.php:144:    private function settings(): SearchSettings
app/Livewire/Admin/Search/Settings.php:146:        return SearchSettings::withoutGlobalScopes()->firstOrCreate([
app/Livewire/Admin/Themes/Index.php:9:use App\Models\ThemeSettings;
app/Livewire/Admin/Themes/Index.php:10:use App\Services\ThemeSettingsService;
app/Livewire/Admin/Themes/Index.php:35:    public function publishTheme(int $themeId, ThemeSettingsService $settings): void
app/Livewire/Admin/Themes/Index.php:87:            ThemeSettings::withoutGlobalScopes()->create([
app/Livewire/Admin/Pages/Form.php:60:    public function save(NavigationService $navigation): void
app/Livewire/Admin/Pages/Form.php:101:        $this->forgetNavigation($store, $navigation);
app/Livewire/Admin/Pages/Form.php:107:    public function deletePage(NavigationService $navigation): void
app/Livewire/Admin/Pages/Form.php:118:        $this->forgetNavigation($store, $navigation);
app/Livewire/Admin/Pages/Form.php:167:    private function forgetNavigation(Store $store, NavigationService $navigation): void
app/Livewire/Admin/Pages/Form.php:172:            ->each(fn (NavigationMenu $menu): mixed => $navigation->forget($menu));
resources/views/layouts/app/header.blade.php:8:            <flux:sidebar.toggle class="lg:hidden mr-2" icon="bars-2" inset="left" />
resources/views/layouts/app/header.blade.php:48:        <flux:sidebar collapsible="mobile" sticky class="lg:hidden border-e border-zinc-200 bg-zinc-50 dark:border-zinc-700 dark:bg-zinc-900">
resources/views/layouts/app/header.blade.php:49:            <flux:sidebar.header>
resources/views/layouts/app/header.blade.php:50:                <x-app-logo :sidebar="true" href="{{ route('dashboard') }}" wire:navigate />
resources/views/layouts/app/header.blade.php:51:                <flux:sidebar.collapse class="in-data-flux-sidebar-on-desktop:not-in-data-flux-sidebar-collapsed-desktop:-mr-2" />
resources/views/layouts/app/header.blade.php:52:            </flux:sidebar.header>
resources/views/layouts/app/header.blade.php:54:            <flux:sidebar.nav>
resources/views/layouts/app/header.blade.php:55:                <flux:sidebar.group :heading="__('Platform')">
resources/views/layouts/app/header.blade.php:56:                    <flux:sidebar.item icon="layout-grid" :href="route('dashboard')" :current="request()->routeIs('dashboard')" wire:navigate>
resources/views/layouts/app/header.blade.php:58:                    </flux:sidebar.item>
resources/views/layouts/app/header.blade.php:59:                </flux:sidebar.group>
resources/views/layouts/app/header.blade.php:60:            </flux:sidebar.nav>
resources/views/layouts/app/header.blade.php:64:            <flux:sidebar.nav>
resources/views/layouts/app/header.blade.php:65:                <flux:sidebar.item icon="folder-git-2" href="https://github.com/laravel/livewire-starter-kit" target="_blank">
resources/views/layouts/app/header.blade.php:67:                </flux:sidebar.item>
resources/view…9192 chars truncated…get($this->themeSettings(), 'home.featured_collection_limit', 4))
app/Livewire/Storefront/Home.php:48:    public function themeSettings(): array
app/Livewire/Storefront/Home.php:50:        return app(ThemeSettingsService::class)->forStore($this->store());
app/Livewire/Storefront/Home.php:59:            'themeSettings' => $this->themeSettings(),
app/Livewire/Admin/Settings/Taxes.php:3:namespace App\Livewire\Admin\Settings;
app/Livewire/Admin/Settings/Taxes.php:7:use App\Models\TaxSettings;
app/Livewire/Admin/Settings/Taxes.php:40:        $this->fillFromSettings($this->taxSettings($store));
app/Livewire/Admin/Settings/Taxes.php:76:        TaxSettings::withoutGlobalScopes()->updateOrCreate(
app/Livewire/Admin/Settings/Taxes.php:105:        return view('livewire.admin.settings.taxes')
app/Livewire/Admin/Settings/Taxes.php:125:    private function taxSettings(Store $store): TaxSettings
app/Livewire/Admin/Settings/Taxes.php:127:        return TaxSettings::withoutGlobalScopes()->firstOrCreate(
app/Livewire/Admin/Settings/Taxes.php:143:    private function fillFromSettings(TaxSettings $settings): void
resources/views/livewire/storefront/home.blade.php:2:    @php($hero = data_get($themeSettings, 'home.hero', []))
resources/views/livewire/admin/navigation/index.blade.php:17:                    wire:key="navigation-menu-{{ $menu->getKey() }}"
resources/views/livewire/admin/navigation/index.blade.php:38:

app/Livewire/Settings/Appearance.php:3:namespace App\Livewire\Settings;
app/Livewire/Settings/Password.php:3:namespace App\Livewire\Settings;
app/Livewire/Settings/TwoFactor/RecoveryCodes.php:3:namespace App\Livewire\Settings\TwoFactor;
resources/views/livewire/admin/settings/shipping.blade.php:9:            <flux:button :href="route('admin.settings.index')" wire:navigate variant="filled">General</flux:button>
resources/views/livewire/admin/settings/shipping.blade.php:10:            <flux:button :href="route('admin.settings.shipping')" wire:navigate variant="primary">Shipping</flux:button>
resources/views/livewire/admin/settings/shipping.blade.php:11:            <flux:button :href="route('admin.settings.taxes')" wire:navigate variant="filled">Taxes</flux:button>
resources/views/livewire/admin/settings/taxes.blade.php:9:            <flux:button :href="route('admin.settings.index')" wire:navigate variant="filled">General</flux:button>
resources/views/livewire/admin/settings/taxes.blade.php:10:            <flux:button :href="route('admin.settings.shipping')" wire:navigate variant="filled">Shipping</flux:button>
resources/views/livewire/admin/settings/taxes.blade.php:11:            <flux:button :href="route('admin.settings.taxes')" wire:navigate variant="primary">Taxes</flux:button>
app/Livewire/Settings/TwoFactor.php:3:namespace App\Livewire\Settings;
resources/views/livewire/admin/settings/index.blade.php:4:            <flux:heading size="xl">Settings</flux:heading>
resources/views/livewire/admin/settings/index.blade.php:9:            <flux:button :href="route('admin.settings.index')" wire:navigate variant="primary">General</flux:button>
resources/views/livewire/admin/settings/index.blade.php:10:            <flux:button :href="route('admin.settings.shipping')" wire:navigate variant="filled">Shipping</flux:button>
resources/views/livewire/admin/settings/index.blade.php:11:            <flux:button :href="route('admin.settings.taxes')" wire:navigate variant="filled">Taxes</flux:button>
app/Livewire/Settings/Profile.php:3:namespace App\Livewire\Settings;
app/Livewire/Settings/DeleteUserForm.php:3:namespace App\Livewire\Settings;
resources/views/components/app-logo.blade.php:2:    'sidebar' => false,
resources/views/components/app-logo.blade.php:5:@if($sidebar)
resources/views/components/app-logo.blade.php:6:    <flux:sidebar.brand :name="config('app.name')" {{ $attributes }}>
resources/views/components/app-logo.blade.php:10:    </flux:sidebar.brand>
resources/views/components/desktop-user-menu.blade.php:2:    <flux:sidebar.profile
resources/views/components/desktop-user-menu.blade.php:6:        data-test="sidebar-menu-button"
resources/views/components/desktop-user-menu.blade.php:23:                {{ __('Settings') }}
resources/views/livewire/settings/appearance.blade.php:4:    <flux:heading class="sr-only">{{ __('Appearance Settings') }}</flux:heading>
resources/views/livewire/settings/password.blade.php:4:    <flux:heading class="sr-only">{{ __('Password Settings') }}</flux:heading>
resources/views/livewire/settings/profile.blade.php:4:    <flux:heading class="sr-only">{{ __('Profile Settings') }}</flux:heading>
resources/views/components/settings/layout.blade.php:3:        <flux:navlist aria-label="{{ __('Settings') }}">
resources/views/livewire/settings/two-factor.blade.php:4:    <flux:heading class="sr-only">{{ __('Two-Factor Authentication Settings') }}</flux:heading>


Output:
Chunk ID: a82366
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 4798
Output:
resources/views/partials/settings-heading.blade.php:2:    <flux:heading size="xl" level="1">{{ __('Settings') }}</flux:heading>
resources/views/layouts/storefront.blade.php:8:        @php($announcement = data_get($themeSettings ?? [], 'announcement', []))
resources/views/layouts/storefront.blade.php:30:            'sticky' => data_get($themeSettings ?? [], 'header.sticky', true),
resources/views/layouts/storefront.blade.php:37:
resources/views/layouts/storefront.blade.php:65:
{{ data_get($themeSettings ?? [], 'footer.tagline') }}

app/Livewire/Admin/Themes/Editor.php:8:use App\Models\ThemeSettings;
app/Livewire/Admin/Themes/Editor.php:9:use App\Services\ThemeSettingsService;
app/Livewire/Admin/Themes/Editor.php:27:    public function mount(Theme $theme, ThemeSettingsService $themeSettings): void
app/Livewire/Admin/Themes/Editor.php:38:            $themeSettings->defaultsForStore($store),
app/Livewire/Admin/Themes/Editor.php:50:    public function save(ThemeSettingsService $settings): void
app/Livewire/Admin/Themes/Editor.php:54:        ThemeSettings::withoutGlobalScopes()->updateOrCreate(
app/Livewire/Admin/Themes/Editor.php:68:    public function publish(ThemeSettingsService $settings): void
resources/views/layouts/app.blade.php:1:<x-layouts::app.sidebar :title="$title ?? null">
resources/views/layouts/app.blade.php:5:</x-layouts::app.sidebar>
app/Livewire/Admin/Navigation/Index.php:153:    public function saveMenu(NavigationService $navigation): void
app/Livewire/Admin/Navigation/Index.php:176:        $navigation->forget($menu);
app/Livewire/Admin/Navigation/Index.php:240:        return view('livewire.admin.navigation.index', [
app/Livewire/Admin/Search/Settings.php:5:use App\Models\SearchSettings;
app/Livewire/Admin/Search/Settings.php:12:class Settings extends Component
app/Livewire/Admin/Search/Settings.php:144:    private function settings(): SearchSettings
app/Livewire/Admin/Search/Settings.php:146:        return SearchSettings::withoutGlobalScopes()->firstOrCreate([
app/Livewire/Admin/Themes/Index.php:9:use App\Models\ThemeSettings;
app/Livewire/Admin/Themes/Index.php:10:use App\Services\ThemeSettingsService;
app/Livewire/Admin/Themes/Index.php:35:    public function publishTheme(int $themeId, ThemeSettingsService $settings): void
app/Livewire/Admin/Themes/Index.php:87:            ThemeSettings::withoutGlobalScopes()->create([
app/Livewire/Admin/Pages/Form.php:60:    public function save(NavigationService $navigation): void
app/Livewire/Admin/Pages/Form.php:101:        $this->forgetNavigation($store, $navigation);
app/Livewire/Admin/Pages/Form.php:107:    public function deletePage(NavigationService $navigation): void
app/Livewire/Admin/Pages/Form.php:118:        $this->forgetNavigation($store, $navigation);
app/Livewire/Admin/Pages/Form.php:167:    private function forgetNavigation(Store $store, NavigationService $navigation): void
app/Livewire/Admin/Pages/Form.php:172:            ->each(fn (NavigationMenu $menu): mixed => $navigation->forget($menu));
resources/views/layouts/app/header.blade.php:8:            <flux:sidebar.toggle class="lg:hidden mr-2" icon="bars-2" inset="left" />
resources/views/layouts/app/header.blade.php:48:        <flux:sidebar collapsible="mobile" sticky class="lg:hidden border-e border-zinc-200 bg-zinc-50 dark:border-zinc-700 dark:bg-zinc-900">
resources/views/layouts/app/header.blade.php:49:            <flux:sidebar.header>
resources/views/layouts/app/header.blade.php:50:                <x-app-logo :sidebar="true" href="{{ route('dashboard') }}" wire:navigate />
resources/views/layouts/app/header.blade.php:51:                <flux:sidebar.collapse class="in-data-flux-sidebar-on-desktop:not-in-data-flux-sidebar-collapsed-desktop:-mr-2" />
resources/views/layouts/app/header.blade.php:52:            </flux:sidebar.header>
resources/views/layouts/app/header.blade.php:54:            <flux:sidebar.nav>
resources/views/layouts/app/header.blade.php:55:                <flux:sidebar.group :heading="__('Platform')">
resources/views/layouts/app/header.blade.php:56:                    <flux:sidebar.item icon="layout-grid" :href="route('dashboard')" :current="request()->routeIs('dashboard')" wire:navigate>
resources/views/layouts/app/header.blade.php:58:                    </flux:sidebar.item>
resources/views/layouts/app/header.blade.php:59:                </flux:sidebar.group>
resources/views/layouts/app/header.blade.php:60:            </flux:sidebar.nav>
resources/views/layouts/app/header.blade.php:64:            <flux:sidebar.nav>
resources/views/layouts/app/header.blade.php:65:                <flux:sidebar.item icon="folder-git-2" href="https://github.com/laravel/livewire-starter-kit" target="_blank">
resources/views/layouts/app/header.blade.php:67:                </flux:sidebar.item>
resources/views/layouts/app/header.blade.php:68:                <flux:sidebar.item icon="book-open-text" href="https://laravel.com/docs/starter-kits#livewire" target="_blank">
resources/views/layouts/app/header.blade.php:70:                </flux:sidebar.item>
resources/views/layouts/app/header.blade.php:71:            </flux:sidebar.nav>
resources/views/layouts/app/header.blade.php:72:        </flux:sidebar>
app/Livewire/Admin/Settings/Shipping.php:3:namespace App\Livewire\Admin\Settings;
app/Livewire/Admin/Settings/Shipping.php:267:        return view('livewire.admin.settings.shipping', [
resources/views/layouts/app/sidebar.blade.php:7:        <flux:sidebar sticky collapsible="mobile" class="border-e border-zinc-200 bg-zinc-50 dark:border-zinc-700 dark:bg-zinc-900">
resources/views/layouts/app/sidebar.blade.php:8:            <flux:sidebar.header>
resources/views/layouts/app/sidebar.blade.php:9:                <x-app-logo :sidebar="true" href="{{ route('admin.dashboard') }}" wire:navigate />
resources/views/layouts/app/sidebar.blade.php:10:                <flux:sidebar.collapse class="lg:hidden" />
resources/views/layouts/app/sidebar.blade.php:11:            </flux:sidebar.header>
resources/views/layouts/app/sidebar.blade.php:13:            <flux:sidebar.nav>
resources/views/layouts/app/sidebar.blade.php:14:                <flux:sidebar.group :heading="__('Platform')" class="grid">
resources/views/layouts/app/sidebar.blade.php:15:                    <flux:sidebar.item icon="home" :href="route('admin.dashboard')" :current="request()->routeIs('admin.dashboard')" wire:navigate>
resources/views/layouts/app/sidebar.blade.php:17:                    </flux:sidebar.item>
resources/views/layouts/app/sidebar.blade.php:19:                    <flux:sidebar.item icon="chart-bar" :href="route('admin.analytics.index')" :current="request()->routeIs('admin.analytics.*')" wire:navigate>
resources/views/layouts/app/sidebar.blade.php:21:                    </flux:sidebar.item>
resources/views/layouts/app/sidebar.blade.php:23:                    <flux:sidebar.item icon="squares-2x2" :href="route('admin.apps.index')" :current="request()->routeIs('admin.apps.*')" wire:navigate>
resources/views/layouts/app/sidebar.blade.php:25:                    </flux:sidebar.item>
resources/views/layouts/app/sidebar.blade.php:27:                    <flux:sidebar.item icon="code-bracket" :href="route('admin.developers.index')" :current="request()->routeIs('admin.developers.*')" wire:navigate>
resources/views/layouts/app/sidebar.blade.php:29:                    </flux:sidebar.item>
resources/views/layouts/app/sidebar.blade.php:30:                </flux:sidebar.group>
resources/views/layouts/app/sidebar.blade.php:32:                <flux:sidebar.group :heading="__('Products')" class="grid">
resources/views/layouts/app/sidebar.blade.php:33:                    <flux:sidebar.item icon="cube" :href="route('admin.products.index')" :current="request()->routeIs('admin.products.*')" wire:navigate>
resources/views/layouts/app/sidebar.blade.php:35:                    </flux:sidebar.item>
resources/views/layouts/app/sidebar.blade.php:37:                    <flux:sidebar.item icon="rectangle-stack" :href="route('admin.collections.index')" :current="request()->routeIs('admin.collections.*')" wire:navigate>
resources/views/layouts/app/sidebar.blade.php:39:                    </flux:sidebar.item>
resources/views/layouts/app/sidebar.blade.php:41:                    <flux:sidebar.item icon="archive-box" :href="route('admin.inventory.index')" :current="request()->routeIs('admin.inventory.*')" wire:navigate>
resources/views/layouts/app/sidebar.blade.php:43:                    </flux:sidebar.item>
resources/views/layouts/app/sidebar.blade.php:44:                </flux:sidebar.group>
resources/views/layouts/app/sidebar.blade.php:46:                <flux:sidebar.group :heading="__('Operations')" class="grid">
resources/views/layouts/app/sidebar.blade.php:47:                    <flux:sidebar.item icon="shopping-bag" :href="route('admin.orders.index')" :current="request()->routeIs('admin.orders.*')" wire:navigate>
resources/views/layouts/app/sidebar.blade.php:49:                    </flux:sidebar.item>
resources/views/layouts/app/sidebar.blade.php:51:                    <flux:sidebar.item icon="users" :href="route('admin.customers.index')" :current="request()->routeIs('admin.customers.*')" wire:navigate>
resources/views/layouts/app/sidebar.blade.php:53:                    </flux:sidebar.item>
resources/views/layouts/app/sidebar.blade.php:55:                    <flux:sidebar.item icon="tag" :href="route('admin.discounts.index')" :current="request()->routeIs('admin.discounts.*')" wire:navigate>
resources/views/layouts/app/sidebar.blade.php:57:                    </flux:sidebar.item>
resources/views/layouts/app/sidebar.blade.php:58:                </flux:sidebar.group>
resources/views/layouts/app/sidebar.blade.php:60:                <flux:sidebar.group :heading="__('Storefront')" class="grid">
resources/views/layouts/app/sidebar.blade.php:61:                    <flux:sidebar.item icon="document-text" :href="route('admin.pages.index')" :current="request()->routeIs('admin.pages.*')" wire:navigate>
resources/views/layouts/app/sidebar.blade.php:63:                    </flux:sidebar.item>
resources/views/layouts/app/sidebar.blade.php:65:                    <flux:sidebar.item icon="bars-3" :href="route('admin.navigation.index')" :current="request()->routeIs('admin.navigation.*')" wire:navigate>
resources/views/layouts/app/sidebar.blade.php:67:                    </flux:sidebar.item>
resources/views/layouts/app/sidebar.blade.php:69:                    <flux:sidebar.item icon="paint-brush" :href="route('admin.themes.index')" :current="request()->routeIs('admin.themes.*')" wire:navigate>
resources/views/layouts/app/sidebar.blade.php:71:                    </flux:sidebar.item>
resources/views/layouts/app/sidebar.blade.php:72:                </flux:sidebar.group>
resources/views/layouts/app/sidebar.blade.php:74:                <flux:sidebar.group :heading="__('Configuration')" class="grid">
resources/views/layouts/app/sidebar.blade.php:75:                    <flux:sidebar.item icon="cog-6-tooth" :href="route('admin.settings.index')" :current="request()->routeIs('admin.settings.*')" wire:navigate>
resources/views/layouts/app/sidebar.blade.php:76:                        {{ __('Settings') }}
resources/views/layouts/app/sidebar.blade.php:77:                    </flux:sidebar.item>
resources/views/layouts/app/sidebar.blade.php:79:                    <flux:sidebar.item icon="magnifying-glass" :href="route('admin.search.settings')" :current="request()->routeIs('admin.search.*')" wire:navigate>
resources/views/layouts/app/sidebar.blade.php:81:                    </flux:sidebar.item>
resources/views/layouts/app/sidebar.blade.php:82:                </flux:sidebar.group>
resources/views/layouts/app/sidebar.blade.php:83:            </flux:sidebar.nav>
resources/views/layouts/app/sidebar.blade.php:87:            <flux:sidebar.nav>
resources/views/layouts/app/sidebar.blade.php:88:                <flux:sidebar.item icon="folder-git-2" href="https://github.com/laravel/livewire-starter-kit" target="_blank">
resources/views/layouts/app/sidebar.blade.php:90:                </flux:sidebar.item>
resources/views/layouts/app/sidebar.blade.php:92:                <flux:sidebar.item icon="book-open-text" href="https://laravel.com/docs/starter-kits#livewire" target="_blank">
resources/views/layouts/app/sidebar.blade.php:94:                </flux:sidebar.item>
resources/views/layouts/app/sidebar.blade.php:95:            </flux:sidebar.nav>
resources/views/layouts/app/sidebar.blade.php:98:        </flux:sidebar>
resources/views/layouts/app/sidebar.blade.php:102:            <flux:sidebar.toggle class="lg:hidden" icon="bars-2" inset="left" />
resources/views/layouts/app/sidebar.blade.php:133:                            {{ __('Settings') }}
app/Livewire/Admin/Settings/Index.php:3:namespace App\Livewire\Admin\Settings;
app/Livewire/Admin/Settings/Index.php:8:use App\Models\StoreSettings;
app/Livewire/Admin/Settings/Index.php:48:        $settings = $this->storeSettings($store)->settings_json ?? [];
app/Livewire/Admin/Settings/Index.php:84:        $settings = $this->storeSettings($store);
app/Livewire/Admin/Settings/Index.php:98:        session()->flash('status', 'Settings saved');
app/Livewire/Admin/Settings/Index.php:99:        $this->dispatch('toast', type: 'success', message: __('Settings saved'));
app/Livewire/Admin/Settings/Index.php:221:        return view('livewire.admin.settings.index', [
app/Livewire/Admin/Settings/Index.php:227:            'title' => __('Settings'),
app/Livewire/Admin/Settings/Index.php:245:    private function storeSettings(Store $store): StoreSettings
app/Livewire/Admin/Settings/Index.php:247:        return StoreSettings::query()->firstOrCreate(
app/Livewire/Storefront/Home.php:8:use App\Services\ThemeSettingsService;
app/Livewire/Storefront/Home.php:31:            ->limit((int) data_get($this->themeSettings(), 'home.featured_product_limit', 8))
app/Livewire/Storefront/Home.php:41:            ->limit((int) data_get($this->themeSettings(), 'home.featured_collection_limit', 4))
app/Livewire/Storefront/Home.php:48:    public function themeSettings(): array
app/Livewire/Storefront/Home.php:50:        return app(ThemeSettingsService::class)->forStore($this->store());
app/Livewire/Storefront/Home.php:59:            'themeSettings' => $this->themeSettings(),
app/Livewire/Admin/Settings/Taxes.php:3:namespace App\Livewire\Admin\Settings;
app/Livewire/Admin/Settings/Taxes.php:7:use App\Models\TaxSettings;
app/Livewire/Admin/Settings/Taxes.php:40:        $this->fillFromSettings($this->taxSettings($store));
app/Livewire/Admin/Settings/Taxes.php:76:        TaxSettings::withoutGlobalScopes()->updateOrCreate(
app/Livewire/Admin/Settings/Taxes.php:105:        return view('livewire.admin.settings.taxes')
app/Livewire/Admin/Settings/Taxes.php:125:    private function taxSettings(Store $store): TaxSettings
app/Livewire/Admin/Settings/Taxes.php:127:        return TaxSettings::withoutGlobalScopes()->firstOrCreate(
app/Livewire/Admin/Settings/Taxes.php:143:    private function fillFromSettings(TaxSettings $settings): void
resources/views/livewire/storefront/home.blade.php:2:    @php($hero = data_get($themeSettings, 'home.hero', []))
resources/views/livewire/admin/navigation/index.blade.php:17:                    wire:key="navigation-menu-{{ $menu->getKey() }}"
resources/views/livewire/admin/navigation/index.blade.php:38:

app/Livewire/Settings/Appearance.php:3:namespace App\Livewire\Settings;
app/Livewire/Settings/Password.php:3:namespace App\Livewire\Settings;
app/Livewire/Settings/TwoFactor/RecoveryCodes.php:3:namespace App\Livewire\Settings\TwoFactor;
resources/views/livewire/admin/settings/shipping.blade.php:9:            <flux:button :href="route('admin.settings.index')" wire:navigate variant="filled">General</flux:button>
resources/views/livewire/admin/settings/shipping.blade.php:10:            <flux:button :href="route('admin.settings.shipping')" wire:navigate variant="primary">Shipping</flux:button>
resources/views/livewire/admin/settings/shipping.blade.php:11:            <flux:button :href="route('admin.settings.taxes')" wire:navigate variant="filled">Taxes</flux:button>
resources/views/livewire/admin/settings/taxes.blade.php:9:            <flux:button :href="route('admin.settings.index')" wire:navigate variant="filled">General</flux:button>
resources/views/livewire/admin/settings/taxes.blade.php:10:            <flux:button :href="route('admin.settings.shipping')" wire:navigate variant="filled">Shipping</flux:button>
resources/views/livewire/admin/settings/taxes.blade.php:11:            <flux:button :href="route('admin.settings.taxes')" wire:navigate variant="primary">Taxes</flux:button>
app/Livewire/Settings/TwoFactor.php:3:namespace App\Livewire\Settings;
resources/views/livewire/admin/settings/index.blade.php:4:            <flux:heading size="xl">Settings</flux:heading>
resources/views/livewire/admin/settings/index.blade.php:9:            <flux:button :href="route('admin.settings.index')" wire:navigate variant="primary">General</flux:button>
resources/views/livewire/admin/settings/index.blade.php:10:            <flux:button :href="route('admin.settings.shipping')" wire:navigate variant="filled">Shipping</flux:button>
resources/views/livewire/admin/settings/index.blade.php:11:            <flux:button :href="route('admin.settings.taxes')" wire:navigate variant="filled">Taxes</flux:button>
app/Livewire/Settings/Profile.php:3:namespace App\Livewire\Settings;
app/Livewire/Settings/DeleteUserForm.php:3:namespace App\Livewire\Settings;
resources/views/components/app-logo.blade.php:2:    'sidebar' => false,
resources/views/components/app-logo.blade.php:5:@if($sidebar)
resources/views/components/app-logo.blade.php:6:    <flux:sidebar.brand :name="config('app.name')" {{ $attributes }}>
resources/views/components/app-logo.blade.php:10:    </flux:sidebar.brand>
resources/views/components/desktop-user-menu.blade.php:2:    <flux:sidebar.profile
resources/views/components/desktop-user-menu.blade.php:6:        data-test="sidebar-menu-button"
resources/views/components/desktop-user-menu.blade.php:23:                {{ __('Settings') }}
resources/views/livewire/settings/appearance.blade.php:4:    <flux:heading class="sr-only">{{ __('Appearance Settings') }}</flux:heading>
resources/views/livewire/settings/password.blade.php:4:    <flux:heading class="sr-only">{{ __('Password Settings') }}</flux:heading>
resources/views/livewire/settings/profile.blade.php:4:    <flux:heading class="sr-only">{{ __('Profile Settings') }}</flux:heading>
resources/views/components/settings/layout.blade.php:3:        <flux:navlist aria-label="{{ __('Settings') }}">
resources/views/livewire/settings/two-factor.blade.php:4:    <flux:heading class="sr-only">{{ __('Two-Factor Authentication Settings') }}</flux:heading>


rg -n "11\.5|Checkout Settings|Notification|Notifications|checkout" specs/03-ADMIN-UI.md | head -120


rg -n "11\.5|Checkout Settings|Notification|Notifications|checkout" specs/03-ADMIN-UI.md | head -120

rg -n "11\\.5|Checkout Settings|Notification|Notifications|checkout" specs/03-ADMIN-UI.md

Question: 11\.5|Checkout Settings|Notification|Notifications|checkout

128:| `unreadNotificationCount` | `int` | Count of unread notifications |
156:- Notification bell shows an unread count badge (positioned absolutely over the icon) when `unreadNotificationCount > 0`.
165:| Notification bell | `button` (icon: bell, variant: ghost) |
166:| Notification count | `badge` |
179:### 1.5 Toast Notifications
227:| `funnelData` | `array` | Funnel steps: `{visits, add_to_cart, checkout_started, checkout_completed}` |
1312:|  ( ) Discount code - Customers enter a code at checkout          |
1313:|  (o) Automatic discount - Applied automatically at checkout      |
1353:**Type section:** Two radio buttons - "Discount code" (description: "Customers enter a code at checkout") and "Automatic discount" (description: "Applied automatically at checkout"). Selecting type is live-bound.
1423:Domains is a tab within the Settings page (`/admin/settings`), not a separate route. The Settings page has tabs: General, Domains, Shipping, Taxes, Checkout, Notifications.
2116:- Event type select with options: order.created, order.updated, order.cancelled, product.created, product.updated, product.deleted, customer.created, checkout.completed, fulfillment.created, refund.created
2326:### 19.4 Toast Notifications