Stage 12 — Online Store: public catalog + cart + orders
Schema: - online_orders (token-tracked, status workflow, delivery method/fee) - online_order_items (price snapshot, fulfilled flag) - part_cross_refs (OEM/equivalent codes for search) - parts.is_published (shop visibility) Storefront (ShopController, tenant subdomain, /shop): - Catalog with search across name/article/brand/cross-refs, category + in-stock filters, live stock, white-label themed layout - Part detail page with cross-ref codes - VIN search → VinDecoder → guided catalog search - Session cart (per-tenant key), guest checkout, order confirmation page - Respects settings.shop.enabled (404 when off); tenant-guarded Part::searchPublished matches cross-ref articles via whereHas. Order notifications (ShopOrderNotifier, best-effort): - Staff: Web Push to active users - Customer: Telegram if phone matches a linked client Filament (tenant): - OnlineOrderResource under "Magazin" nav group, status workflow, items relation, "Onorează" action issues stock via WarehouseService (FIFO) - PartResource: is_published toggle + column + bulk publish/unpublish + CrossRefsRelationManager - Settings: shop section (enable, delivery methods, fee, free-over) - Landing page: shop button when enabled Tests (6 new): - catalog 404 when disabled; lists published only; cross-ref search; order placement (token + items + total); fulfill issues stock; cross-tenant token isolation Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
@extends('shop.layout')
|
||||
@section('title', 'Coș')
|
||||
@section('content')
|
||||
@php $currency = $tenant->settings['currency'] ?? 'MDL'; @endphp
|
||||
|
||||
<h1 style="font-size:22px;margin-bottom:16px;">Coșul meu</h1>
|
||||
|
||||
@if (empty($cart))
|
||||
<div class="card" style="text-align:center;padding:40px;">
|
||||
<p class="muted">Coșul e gol.</p>
|
||||
<a class="btn" href="/shop" style="margin-top:12px;">Vezi catalogul</a>
|
||||
</div>
|
||||
@else
|
||||
<form method="POST" action="/shop/cart/update">
|
||||
@csrf
|
||||
<div class="card">
|
||||
<table class="cart">
|
||||
<thead>
|
||||
<tr><th>Piesă</th><th class="r">Preț</th><th class="r">Cant.</th><th class="r">Total</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($cart as $id => $item)
|
||||
<tr>
|
||||
<td>
|
||||
<a href="/shop/part/{{ $item['part_id'] }}">{{ $item['name'] }}</a>
|
||||
@if (!empty($item['article']))<div class="muted">{{ $item['article'] }}</div>@endif
|
||||
</td>
|
||||
<td class="r">{{ number_format($item['price'], 2) }} {{ $currency }}</td>
|
||||
<td class="r">
|
||||
<input type="number" name="qty[{{ $id }}]" value="{{ $item['qty'] }}" min="0"
|
||||
style="width:64px;padding:6px;border:1px solid #d1d5db;border-radius:6px;text-align:right;">
|
||||
</td>
|
||||
<td class="r">{{ number_format($item['price'] * $item['qty'], 2) }} {{ $currency }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div style="display:flex;justify-content:space-between;align-items:center;margin-top:16px;flex-wrap:wrap;gap:12px;">
|
||||
<button class="btn outline" type="submit">Actualizează coșul</button>
|
||||
<div style="text-align:right;">
|
||||
<div style="font-size:20px;font-weight:700;">Subtotal: {{ number_format($subtotal, 2) }} {{ $currency }}</div>
|
||||
<a class="btn" href="/shop/checkout" style="margin-top:8px;">Finalizează comanda →</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@endif
|
||||
@endsection
|
||||
@@ -0,0 +1,49 @@
|
||||
@extends('shop.layout')
|
||||
@section('title', 'Catalog piese')
|
||||
@section('content')
|
||||
@php $currency = $tenant->settings['currency'] ?? 'MDL'; @endphp
|
||||
|
||||
<form method="GET" action="/shop" class="filters">
|
||||
<input type="text" name="q" value="{{ $term }}" placeholder="Caută denumire, cod, brand, cod cross…">
|
||||
<select name="cat" onchange="this.form.submit()">
|
||||
<option value="">Toate categoriile</option>
|
||||
@foreach ($categories as $c)
|
||||
<option value="{{ $c }}" {{ $category === $c ? 'selected' : '' }}>{{ $c }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<label style="display:flex;align-items:center;gap:6px;font-size:14px;">
|
||||
<input type="checkbox" name="in_stock" value="1" {{ $inStock ? 'checked' : '' }} onchange="this.form.submit()">
|
||||
Doar în stoc
|
||||
</label>
|
||||
<button class="btn" type="submit">Caută</button>
|
||||
</form>
|
||||
|
||||
@if ($parts->isEmpty())
|
||||
<div class="card" style="text-align:center;padding:48px;">
|
||||
<p class="muted">Nicio piesă găsită{{ $term ? ' pentru „' . $term . '”' : '' }}.</p>
|
||||
</div>
|
||||
@else
|
||||
<div class="grid">
|
||||
@foreach ($parts as $p)
|
||||
@php $stock = (float) $p->qty; @endphp
|
||||
<div class="product">
|
||||
<a href="/shop/part/{{ $p->id }}">
|
||||
<h3>{{ $p->name }}</h3>
|
||||
</a>
|
||||
<div class="meta">
|
||||
{{ $p->brand ? $p->brand . ' · ' : '' }}{{ $p->article ?? '' }}
|
||||
</div>
|
||||
<div class="stock {{ $stock > 0 ? 'in' : 'out' }}">
|
||||
{{ $stock > 0 ? '● În stoc' : '○ La comandă' }}
|
||||
</div>
|
||||
<div class="price">{{ number_format((float) $p->sell_price, 2) }} {{ $currency }}</div>
|
||||
<form method="POST" action="/shop/part/{{ $p->id }}/add" style="margin-top:10px;">
|
||||
@csrf
|
||||
<button class="btn block" type="submit">Adaugă în coș</button>
|
||||
</form>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
<div style="margin-top:20px;">{{ $parts->links() }}</div>
|
||||
@endif
|
||||
@endsection
|
||||
@@ -0,0 +1,71 @@
|
||||
@extends('shop.layout')
|
||||
@section('title', 'Finalizare comandă')
|
||||
@section('content')
|
||||
@php
|
||||
$currency = $tenant->settings['currency'] ?? 'MDL';
|
||||
$labels = \App\Models\Tenant\OnlineOrder::DELIVERY;
|
||||
@endphp
|
||||
|
||||
<h1 style="font-size:22px;margin-bottom:16px;">Finalizează comanda</h1>
|
||||
|
||||
@if ($errors->any())
|
||||
<div class="card" style="border-color:#fca5a5;background:#fef2f2;margin-bottom:14px;">
|
||||
<ul style="margin:0;padding-left:18px;color:#991b1b;font-size:14px;">
|
||||
@foreach ($errors->all() as $e)<li>{{ $e }}</li>@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div style="display:grid;grid-template-columns:1fr 320px;gap:18px;align-items:start;">
|
||||
<form method="POST" action="/shop/checkout" class="card">
|
||||
@csrf
|
||||
<div class="field">
|
||||
<label>Nume complet *</label>
|
||||
<input type="text" name="customer_name" value="{{ old('customer_name') }}" required>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Telefon *</label>
|
||||
<input type="text" name="customer_phone" value="{{ old('customer_phone') }}" required placeholder="+373…">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Email</label>
|
||||
<input type="email" name="customer_email" value="{{ old('customer_email') }}">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Livrare *</label>
|
||||
<select name="delivery_method" required>
|
||||
@foreach ($deliveryOptions as $opt)
|
||||
<option value="{{ $opt }}">{{ $labels[$opt] ?? $opt }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Adresă (pentru curier/poștă)</label>
|
||||
<input type="text" name="address" value="{{ old('address') }}">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Observații</label>
|
||||
<textarea name="notes" rows="2">{{ old('notes') }}</textarea>
|
||||
</div>
|
||||
<button class="btn block" type="submit">Plasează comanda</button>
|
||||
</form>
|
||||
|
||||
<div class="card">
|
||||
<h3 style="font-size:15px;margin-bottom:10px;">Sumar</h3>
|
||||
<table class="cart">
|
||||
@foreach ($cart as $item)
|
||||
<tr>
|
||||
<td>{{ $item['name'] }} <span class="muted">×{{ $item['qty'] }}</span></td>
|
||||
<td class="r">{{ number_format($item['price'] * $item['qty'], 2) }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
<div style="margin-top:12px;font-size:18px;font-weight:700;text-align:right;">
|
||||
{{ number_format($subtotal, 2) }} {{ $currency }}
|
||||
</div>
|
||||
<p class="muted" style="margin-top:6px;">Taxa de livrare se calculează în funcție de metoda aleasă.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>@media (max-width:720px){ .wrap div[style*="grid-template-columns:1fr 320px"]{ grid-template-columns:1fr !important; } }</style>
|
||||
@endsection
|
||||
@@ -0,0 +1,80 @@
|
||||
@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 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>
|
||||
@@ -0,0 +1,60 @@
|
||||
@extends('shop.layout')
|
||||
@section('title', 'Comanda ' . $order->number)
|
||||
@section('content')
|
||||
@php
|
||||
$currency = $tenant->settings['currency'] ?? 'MDL';
|
||||
$statuses = \App\Models\Tenant\OnlineOrder::STATUSES;
|
||||
$delivery = \App\Models\Tenant\OnlineOrder::DELIVERY;
|
||||
$flow = ['new', 'confirmed', 'packed', 'shipped', 'delivered'];
|
||||
$idx = array_search($order->status, $flow, true);
|
||||
@endphp
|
||||
|
||||
<div class="card" style="text-align:center;">
|
||||
<div style="font-size:14px;color:#6b7280;">Comanda</div>
|
||||
<div style="font-size:24px;font-weight:700;margin:4px 0;">#{{ $order->number }}</div>
|
||||
<span class="status-pill">{{ $statuses[$order->status] ?? $order->status }}</span>
|
||||
</div>
|
||||
|
||||
@if ($order->status !== 'cancelled')
|
||||
<div class="card" style="margin-top:14px;">
|
||||
<h3 style="font-size:15px;margin-bottom:12px;">Status</h3>
|
||||
<div style="display:flex;justify-content:space-between;gap:4px;">
|
||||
@foreach ($flow as $i => $st)
|
||||
<div style="flex:1;text-align:center;">
|
||||
<div style="width:22px;height:22px;border-radius:50%;margin:0 auto 6px;
|
||||
background:{{ $idx !== false && $i <= $idx ? ($tenant->settings['theme_color'] ?? '#3B82F6') : '#e5e7eb' }};"></div>
|
||||
<div style="font-size:11px;color:{{ $idx !== false && $i <= $idx ? '#111827' : '#9ca3af' }};">
|
||||
{{ $statuses[$st] }}
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="card" style="margin-top:14px;">
|
||||
<h3 style="font-size:15px;margin-bottom:10px;">Produse</h3>
|
||||
<table class="cart">
|
||||
@foreach ($order->items as $it)
|
||||
<tr>
|
||||
<td>{{ $it->name }} <span class="muted">×{{ rtrim(rtrim(number_format((float)$it->qty,2),'0'),'.') }}</span></td>
|
||||
<td class="r">{{ number_format((float) $it->total, 2) }} {{ $currency }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
<tr><td class="muted">Livrare ({{ $delivery[$order->delivery_method] ?? $order->delivery_method }})</td>
|
||||
<td class="r">{{ number_format((float) $order->delivery_fee, 2) }} {{ $currency }}</td></tr>
|
||||
<tr><td style="font-weight:700;">Total</td>
|
||||
<td class="r" style="font-weight:700;font-size:18px;">{{ number_format((float) $order->total, 2) }} {{ $currency }}</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="card" style="margin-top:14px;">
|
||||
<h3 style="font-size:15px;margin-bottom:8px;">Date livrare</h3>
|
||||
<p class="muted">{{ $order->customer_name }} · {{ $order->customer_phone }}</p>
|
||||
@if ($order->address)<p class="muted">{{ $order->address }}</p>@endif
|
||||
</div>
|
||||
|
||||
<div style="margin-top:16px;text-align:center;">
|
||||
<a class="btn outline" href="/shop">← Continuă cumpărăturile</a>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -0,0 +1,49 @@
|
||||
@extends('shop.layout')
|
||||
@section('title', $part->name)
|
||||
@section('content')
|
||||
@php $currency = $tenant->settings['currency'] ?? 'MDL'; $stock = (float) $part->qty; @endphp
|
||||
|
||||
<a href="/shop" class="muted">← Înapoi la catalog</a>
|
||||
|
||||
<div class="card" style="margin-top:12px;">
|
||||
<h1 style="font-size:22px;margin-bottom:8px;">{{ $part->name }}</h1>
|
||||
<div class="muted" style="margin-bottom:14px;">
|
||||
{{ $part->brand ? 'Brand: ' . $part->brand : '' }}
|
||||
{{ $part->article ? ' · Cod: ' . $part->article : '' }}
|
||||
{{ $part->category ? ' · ' . $part->category : '' }}
|
||||
</div>
|
||||
|
||||
<div class="stock {{ $stock > 0 ? 'in' : 'out' }}" style="margin-bottom:8px;">
|
||||
{{ $stock > 0 ? '● În stoc (' . rtrim(rtrim(number_format($stock, 2), '0'), '.') . ' ' . ($part->unit ?? 'buc') . ')' : '○ La comandă' }}
|
||||
</div>
|
||||
<div style="font-size:26px;font-weight:700;color:{{ $tenant->settings['theme_color'] ?? '#3B82F6' }};margin-bottom:16px;">
|
||||
{{ number_format((float) $part->sell_price, 2) }} {{ $currency }}
|
||||
</div>
|
||||
|
||||
<form method="POST" action="/shop/part/{{ $part->id }}/add" style="display:flex;gap:8px;align-items:center;max-width:320px;">
|
||||
@csrf
|
||||
<input type="number" name="qty" value="1" min="1" style="width:80px;padding:10px;border:1px solid #d1d5db;border-radius:8px;">
|
||||
<button class="btn" type="submit">Adaugă în coș</button>
|
||||
</form>
|
||||
|
||||
@if ($part->crossRefs->isNotEmpty())
|
||||
<div style="margin-top:20px;">
|
||||
<h3 style="font-size:14px;margin-bottom:6px;">Coduri echivalente (cross)</h3>
|
||||
<div class="muted">
|
||||
@foreach ($part->crossRefs as $cr)
|
||||
<span style="display:inline-block;background:#f3f4f6;border-radius:6px;padding:3px 8px;margin:2px;">
|
||||
{{ $cr->cross_article }}{{ $cr->brand ? ' (' . $cr->brand . ')' : '' }}
|
||||
</span>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if ($part->notes)
|
||||
<div style="margin-top:20px;">
|
||||
<h3 style="font-size:14px;margin-bottom:6px;">Descriere</h3>
|
||||
<p class="muted" style="white-space:pre-wrap;">{{ $part->notes }}</p>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@endsection
|
||||
@@ -0,0 +1,39 @@
|
||||
@extends('shop.layout')
|
||||
@section('title', 'Căutare după VIN')
|
||||
@section('content')
|
||||
|
||||
<div class="card">
|
||||
<h1 style="font-size:20px;margin-bottom:6px;">Caută piese după VIN</h1>
|
||||
<p class="muted" style="margin-bottom:16px;">Introdu codul VIN (17 caractere) ca să identificăm mașina. Apoi caută piesele în catalog.</p>
|
||||
|
||||
<form method="GET" action="/shop/vin" style="display:flex;gap:8px;flex-wrap:wrap;">
|
||||
<input type="text" name="vin" value="{{ $vin }}" maxlength="17" placeholder="ex: WVWZZZ1JZXW000001"
|
||||
style="flex:1;min-width:240px;padding:10px 12px;border:1px solid #d1d5db;border-radius:8px;font-family:monospace;text-transform:uppercase;">
|
||||
<button class="btn" type="submit">Decodează</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@if ($decoded)
|
||||
<div class="card" style="margin-top:14px;">
|
||||
@if (! ($decoded['valid_length'] ?? false))
|
||||
<p class="stock out">{{ $decoded['reason'] ?? 'VIN invalid — trebuie 17 caractere.' }}</p>
|
||||
@else
|
||||
<h3 style="font-size:16px;margin-bottom:10px;">Mașină identificată</h3>
|
||||
<table class="cart">
|
||||
<tr><td>Producător</td><td class="r"><strong>{{ $decoded['manufacturer'] ?? '—' }}</strong></td></tr>
|
||||
<tr><td>An model</td><td class="r"><strong>{{ $decoded['year'] ?? '—' }}</strong></td></tr>
|
||||
<tr><td>Țară</td><td class="r">{{ $decoded['country'] ?? '—' }}</td></tr>
|
||||
<tr><td>Regiune</td><td class="r">{{ $decoded['region'] ?? '—' }}</td></tr>
|
||||
</table>
|
||||
<div style="margin-top:14px;">
|
||||
<a class="btn outline" href="/shop?q={{ urlencode($decoded['manufacturer'] ?? '') }}">
|
||||
Caută piese pentru {{ $decoded['manufacturer'] ?? 'această mașină' }} →
|
||||
</a>
|
||||
</div>
|
||||
<p class="muted" style="margin-top:12px;">
|
||||
Pentru compatibilitate exactă pe model/motorizare, contactează service-ul cu acest VIN.
|
||||
</p>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
@endsection
|
||||
@@ -58,6 +58,11 @@
|
||||
@endif
|
||||
<h1>{{ $name }}</h1>
|
||||
<p>Autoservice profesional{{ $city ? ' — ' . $city : '' }}. Diagnostic, reparații, piese, ITP.</p>
|
||||
@if (! empty($shopEnabled))
|
||||
<a href="/shop" style="display:inline-block;margin-top:20px;background:#fff;color:{{ $themeColor }};padding:12px 28px;border-radius:8px;font-weight:700;text-decoration:none;">
|
||||
🛒 Magazin piese online
|
||||
</a>
|
||||
@endif
|
||||
</header>
|
||||
|
||||
@if (! empty($services))
|
||||
|
||||
Reference in New Issue
Block a user