Files
ladill-merchant/resources/views/merchant/products/index.blade.php
T
isaaccladandClaude Opus 4.8 b19e2654a1
Deploy Ladill Merchant / deploy (push) Successful in 30s
Add Products page backed by the CRM products API + storefront catalog picker
- New Products page (merchant.products.*) with full CRUD proxied to the Ladill
  CRM products API via a new CrmClient + config/crm.php (owner-scoped, type=product).
- Sidebar gains a Products entry.
- The new storefront form loads the merchant's catalog: each shop/menu section
  gets an "Add from products…" picker that drops a CRM product in as an item
  (name, price, description). Catalog fetch is resilient — empty if CRM is down.

Wires CRM_API_URL + CRM_API_KEY_MERCHANT on the merchant env (matches CRM).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 07:32:58 +00:00

76 lines
4.8 KiB
PHP

<x-user-layout>
<x-slot name="title">Products</x-slot>
<div class="space-y-6">
<div class="flex flex-wrap items-center justify-between gap-3">
<div>
<h1 class="text-xl font-semibold text-slate-900">Products</h1>
<p class="mt-1 text-sm text-slate-500">Your product catalog, synced with Ladill CRM. Use these on any storefront.</p>
</div>
<x-btn.create :href="route('merchant.products.create')">New product</x-btn.create>
</div>
@if(session('success'))
<div class="rounded-xl border border-emerald-100 bg-emerald-50 px-4 py-3 text-sm text-emerald-700">{{ session('success') }}</div>
@endif
<form method="get" class="flex max-w-sm items-center gap-2">
<input type="search" name="search" value="{{ $search }}" placeholder="Search products…"
class="w-full rounded-xl border-slate-200 text-sm focus:border-indigo-500 focus:ring-indigo-500">
<button class="rounded-xl border border-slate-200 px-3 py-2 text-sm font-medium text-slate-600 hover:bg-slate-50">Search</button>
</form>
@if(empty($products))
<div class="rounded-2xl border border-dashed border-slate-200 bg-white px-6 py-12 text-center">
<p class="text-sm text-slate-500">{{ $search !== '' ? 'No products match your search.' : 'No products yet.' }}</p>
<a href="{{ route('merchant.products.create') }}" class="mt-3 inline-block text-sm font-semibold text-indigo-600 hover:text-indigo-800">Add your first product</a>
</div>
@else
<div class="overflow-hidden rounded-2xl border border-slate-200 bg-white">
<table class="min-w-full divide-y divide-slate-100 text-sm">
<thead class="bg-slate-50 text-left text-xs font-semibold uppercase tracking-wide text-slate-500">
<tr>
<th class="px-4 py-3">Product</th>
<th class="px-4 py-3">SKU</th>
<th class="px-4 py-3 text-right">Price</th>
<th class="px-4 py-3">Status</th>
<th class="px-4 py-3"></th>
</tr>
</thead>
<tbody class="divide-y divide-slate-100">
@foreach($products as $p)
<tr class="hover:bg-slate-50/60">
<td class="px-4 py-3">
<p class="font-medium text-slate-900">{{ $p['name'] ?? '—' }}</p>
@if(!empty($p['description']))
<p class="mt-0.5 truncate text-xs text-slate-400">{{ \Illuminate\Support\Str::limit($p['description'], 60) }}</p>
@endif
</td>
<td class="px-4 py-3 text-slate-500">{{ $p['sku'] ?: '—' }}</td>
<td class="px-4 py-3 text-right font-medium text-slate-900">
{{ strtoupper($p['currency'] ?? 'GHS') }} {{ number_format(((int) ($p['unit_price_minor'] ?? 0)) / 100, 2) }}
</td>
<td class="px-4 py-3">
<span class="inline-flex rounded-full px-2 py-0.5 text-xs font-medium {{ ($p['active'] ?? true) ? 'bg-emerald-50 text-emerald-700' : 'bg-slate-100 text-slate-500' }}">
{{ ($p['active'] ?? true) ? 'Active' : 'Inactive' }}
</span>
</td>
<td class="px-4 py-3 text-right">
<div class="flex items-center justify-end gap-3">
<a href="{{ route('merchant.products.edit', $p['id']) }}" class="text-sm font-medium text-indigo-600 hover:text-indigo-800">Edit</a>
<form method="post" action="{{ route('merchant.products.destroy', $p['id']) }}"
onsubmit="return confirm('Delete this product?');">
@csrf
@method('DELETE')
<button class="text-sm font-medium text-red-500 hover:text-red-700">Delete</button>
</form>
</div>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
@endif
</div>
</x-user-layout>