8fdfc9ef85
Part (HasMedia): - Spatie media `image` single-file collection + imageUrl() helper - PartResource form: image upload section (image editor, 2 MB max) - Parts list: circular thumbnail column - Shop catalog cards: square thumbnail + 📦 placeholder - Shop part detail: 260px image alongside info, single column when no image Seasonal tire-swap reminders: - NotificationDispatcher::tireSeasonalSwap(TireSet) — Telegram first, email fallback (when set has a vehicle, via ServiceReminderMail with 'tire_swap' type and a size-aware note) - tires:remind-seasonal artisan command, self-gating to Feb 15-Mar 15 (notify winter sets stored) and Sep 15-Oct 15 (notify summer sets stored). 60-day cooldown per client via service_reminders_sent. --force / --dry-run. - Schedule: weekly Mon 09:30 Tests (6 new): - outside window no-ops; spring window notifies winter; spring ignores summer; autumn notifies summer; cooldown blocks doubles; --force overrides window Full suite: 106 passed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
84 lines
4.7 KiB
PHP
84 lines
4.7 KiB
PHP
@php
|
|
$themeColor = $tenant->settings['theme_color'] ?? '#3B82F6';
|
|
$brand = $tenant->display_name ?? $tenant->name;
|
|
$logoUrl = method_exists($tenant, 'getLogoUrl') ? $tenant->getLogoUrl() : null;
|
|
$faviconUrl = method_exists($tenant, 'getFaviconUrl') ? $tenant->getFaviconUrl() : null;
|
|
$currency = $tenant->settings['currency'] ?? 'MDL';
|
|
@endphp
|
|
<!DOCTYPE html>
|
|
<html lang="{{ app()->getLocale() }}">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<title>@yield('title', 'Magazin') — {{ $brand }}</title>
|
|
@if ($faviconUrl)<link rel="icon" href="{{ $faviconUrl }}">@endif
|
|
<style>
|
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
body { font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; color: #1f2937; background: #f3f4f6; line-height: 1.5; }
|
|
a { color: inherit; text-decoration: none; }
|
|
|
|
header { background: {{ $themeColor }}; color: #fff; }
|
|
.hd { max-width: 1100px; margin: 0 auto; padding: 14px 16px; display: flex; align-items: center; gap: 16px; }
|
|
.hd .logo { display: flex; align-items: center; gap: 10px; font-weight: 700; font-size: 18px; }
|
|
.hd .logo img { max-height: 34px; }
|
|
.hd nav { margin-left: auto; display: flex; gap: 16px; font-size: 14px; align-items: center; }
|
|
.hd .cart-badge { background: #fff; color: {{ $themeColor }}; border-radius: 999px; padding: 2px 9px; font-weight: 700; font-size: 12px; margin-left: 4px; }
|
|
|
|
.wrap { max-width: 1100px; margin: 0 auto; padding: 20px 16px 64px; }
|
|
.btn { display: inline-block; background: {{ $themeColor }}; color: #fff; border: 0; border-radius: 8px; padding: 10px 18px; font-size: 14px; font-weight: 600; cursor: pointer; }
|
|
.btn.outline { background: transparent; border: 1px solid {{ $themeColor }}; color: {{ $themeColor }}; }
|
|
.btn.block { display: block; width: 100%; text-align: center; }
|
|
.card { background: #fff; border: 1px solid #e5e7eb; border-radius: 12px; padding: 16px; }
|
|
|
|
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 14px; }
|
|
.product { background: #fff; border: 1px solid #e5e7eb; border-radius: 12px; padding: 14px; display: flex; flex-direction: column; }
|
|
.product-thumb { display: block; aspect-ratio: 1; margin-bottom: 10px; border-radius: 8px; overflow: hidden; background: #f9fafb; border: 1px solid #f3f4f6; }
|
|
.product-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
|
|
.product-thumb-empty { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; font-size: 36px; color: #cbd5e1; }
|
|
.product h3 { font-size: 14px; font-weight: 600; margin-bottom: 4px; min-height: 38px; }
|
|
.product .meta { font-size: 12px; color: #6b7280; margin-bottom: 8px; }
|
|
.product .price { font-size: 18px; font-weight: 700; color: {{ $themeColor }}; margin-top: auto; }
|
|
.product .stock { font-size: 12px; margin: 6px 0; }
|
|
.stock.in { color: #059669; } .stock.out { color: #dc2626; }
|
|
|
|
.filters { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 18px; }
|
|
.filters input, .filters select { padding: 9px 12px; border: 1px solid #d1d5db; border-radius: 8px; font-size: 14px; }
|
|
.filters input[type=text] { flex: 1; min-width: 200px; }
|
|
|
|
table.cart { width: 100%; border-collapse: collapse; }
|
|
table.cart th, table.cart td { padding: 10px; border-bottom: 1px solid #e5e7eb; font-size: 14px; text-align: left; }
|
|
table.cart td.r, table.cart th.r { text-align: right; }
|
|
.field { margin-bottom: 12px; }
|
|
.field label { display: block; font-size: 13px; color: #4b5563; margin-bottom: 4px; }
|
|
.field input, .field select, .field textarea { width: 100%; padding: 10px 12px; border: 1px solid #d1d5db; border-radius: 8px; font-size: 14px; }
|
|
|
|
.status-pill { display: inline-block; padding: 5px 12px; border-radius: 999px; font-size: 13px; font-weight: 600; background: {{ $themeColor }}; color: #fff; }
|
|
.muted { color: #6b7280; font-size: 13px; }
|
|
footer { text-align: center; padding: 24px; color: #9ca3af; font-size: 12px; }
|
|
|
|
@media (max-width: 600px) { .hd .logo span { display: none; } }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<header>
|
|
<div class="hd">
|
|
<a class="logo" href="/shop">
|
|
@if ($logoUrl)<img src="{{ $logoUrl }}" alt="">@endif
|
|
<span>{{ $brand }}</span>
|
|
</a>
|
|
<nav>
|
|
<a href="/shop">Catalog</a>
|
|
<a href="/shop/vin">Caută după VIN</a>
|
|
<a href="/shop/cart">🛒 Coș
|
|
@if (($cartCount ?? 0) > 0)<span class="cart-badge">{{ $cartCount }}</span>@endif
|
|
</a>
|
|
</nav>
|
|
</div>
|
|
</header>
|
|
<div class="wrap">
|
|
@yield('content')
|
|
</div>
|
|
<footer>{{ $brand }} · Powered by AutoCRM</footer>
|
|
</body>
|
|
</html>
|