Add Products page backed by the CRM products API + storefront catalog picker
Deploy Ladill Merchant / deploy (push) Successful in 30s

- 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>
This commit is contained in:
isaacclad
2026-06-24 07:32:58 +00:00
co-authored by Claude Opus 4.8
parent 08d3c99996
commit b19e2654a1
12 changed files with 435 additions and 9 deletions
+8
View File
@@ -5,6 +5,7 @@ use App\Http\Controllers\WalletBalanceController;
use App\Http\Controllers\Merchant\OrdersController;
use App\Http\Controllers\Merchant\OverviewController;
use App\Http\Controllers\Merchant\PayoutsController;
use App\Http\Controllers\Merchant\ProductController;
use App\Http\Controllers\Merchant\StorefrontController;
use App\Http\Controllers\NotificationController;
use App\Http\Controllers\Public\BookingController;
@@ -63,6 +64,13 @@ Route::middleware(['auth', 'platform.session'])->group(function () {
Route::get('/storefronts/{storefront}/preview.png', [StorefrontController::class, 'preview'])->name('merchant.storefronts.preview');
Route::get('/storefronts/{storefront}/download/{format}', [StorefrontController::class, 'download'])->name('merchant.storefronts.download')->whereIn('format', ['png', 'svg', 'pdf']);
Route::get('/products', [ProductController::class, 'index'])->name('merchant.products.index');
Route::get('/products/create', [ProductController::class, 'create'])->name('merchant.products.create');
Route::post('/products', [ProductController::class, 'store'])->name('merchant.products.store');
Route::get('/products/{product}/edit', [ProductController::class, 'edit'])->name('merchant.products.edit');
Route::put('/products/{product}', [ProductController::class, 'update'])->name('merchant.products.update');
Route::delete('/products/{product}', [ProductController::class, 'destroy'])->name('merchant.products.destroy');
Route::get('/orders', [OrdersController::class, 'index'])->name('merchant.orders.index');
Route::patch('/orders/{order}/status', [OrdersController::class, 'updateStatus'])->name('merchant.orders.update-status');
Route::patch('/bookings/{booking}/status', [OrdersController::class, 'updateBookingStatus'])->name('merchant.bookings.update-status');