{{-- resources/views/zapatera/admin/products/form.blade.php --}} @csrf @php use App\Models\Product; // Monedas para UI de costo/precio $currencies = \App\Models\Currency::orderByDesc('is_primary')->orderBy('code')->get(); $defaultCurrency = optional($currencies->firstWhere('is_primary',true))->id; $currencyRates = $currencies->map(fn($c)=>[ 'id' => $c->id, 'code' => $c->code, 'rate' => (float)$c->rate_to_primary, 'is_primary' => (bool)$c->is_primary, ]); // AJAX upload habilitado sólo si el producto existe $canAjaxUpload = isset($product) && $product instanceof Product && $product->exists; $ajaxUploadUrl = $canAjaxUpload ? route('zapatera.admin.products.media.store.ajax', $product) : null; // Plantilla de URL para actualizar media (modal Etiquetar) $updateUrlTpl = null; if ($canAjaxUpload) { $updateUrlTpl = route('zapatera.admin.products.media.update', [ 'product' => $product->getKey(), 'media' => '___MEDIA___', ]); } @endphp
Puedes dejarlo vacío y asignarlo más tarde.
—
@foreach($attributes as $attr)
{{ $attr->name }}
@foreach($attr->values as $val) @php $checked = in_array($val->id, old('attribute_values', $selectedAttributeValues ?? [])); @endphp @endforeach
@endforeach
Un producto tiene 1 categoría principal y múltiples subcategorías.
{{-- ============================ BLOQUE DE IMÁGENES + MODAL ============================ --}} @php //use App\Models\Product; $canAjaxUpload = isset($product) && $product instanceof Product && $product->exists; $ajaxUploadUrl = $canAjaxUpload ? route('zapatera.admin.products.media.store.ajax', $product) : null; $updateUrlTpl = null; if ($canAjaxUpload) { $updateUrlTpl = route('zapatera.admin.products.media.update', [ 'product' => $product->getKey(), 'media' => '___MEDIA___', ]); } @endphp {{-- Renderizamos el contenedor Alpine SOLO si hay producto guardado --}} @if($canAjaxUpload) @include('zapatera.admin.products.partials.media_tagger_js')
Arrastra tus imágenes aquí
o
JPG, PNG, WEBP · Máx 5 MB c/u · Múltiples permitidas
0 seleccionadas
{{-- Previews locales durante la subida (se limpian automáticamente) --}}
Puedes subir varias imágenes. Luego, debajo, eliges la principal o eliminas existentes.
{{-- Panel derecho con media existente (solo visible si $media existe) --}} @isset($media)
@foreach($media as $m) @php $raw = trim($m->path ?? ''); $url = null; if ($raw !== '') { if (preg_match('~^https?://~i', $raw)) $url = $raw; elseif (str_starts_with($raw, 'storage/')) $url = asset($raw); elseif (\Storage::disk('public')->exists($raw)) $url = \Storage::url($raw); elseif (file_exists(public_path($raw))) $url = asset($raw); } $url = $url ?: asset('img/placeholder_zapato_detalle.svg'); $selectedIds = ($m->relationLoaded('attributeValues') ? $m->attributeValues->pluck('id')->all() : []); $chips = $m->attributes_cache; if (!is_array($chips)) { $chips = json_decode($chips ?? '', true) ?: []; } @endphp
imagen
is_primary)>
#{{ $m->id }}
@foreach($chips as $chip) {{ $chip['attribute'] ?? 'Attr' }}: {{ $chip['value'] ?? '—' }} @endforeach
@endforeach
@foreach($media as $m) @endforeach
Marca las imágenes a eliminar y guarda para aplicar cambios.
@endisset {{-- ===== Modal teletransportado al para evitar forms anidados ===== --}}
@else {{-- Sin producto: no mostramos uploader ni modal --}} @endif {{-- ===== Botones del formulario principal ===== --}}
Cancelar
{{-- PARTIALS --}} @include('zapatera.admin.products.partials.lightbox') @include('zapatera.admin.products.partials.scripts')