@php $editorMode = $editorMode ?? request()->query('editor') === 'fullscreen'; if ($editorMode) { $pageConfigs = ['myLayout' => 'blank']; } @endphp @extends('layouts/layoutMaster') @section('title', 'Editar anuncio') @section('vendor-style') @vite(['resources/assets/vendor/libs/bs-stepper/bs-stepper.scss']) @endsection @section('page-style') @endsection @section('vendor-script') @vite(['resources/assets/vendor/libs/bs-stepper/bs-stepper.js']) @endsection @section('page-script') @include('partials.epayco-inline-checkout') @vite(['resources/assets/js/mariachi-listing-wizard.js']) @if($editorMode) @vite(['resources/assets/js/mariachi-listing-editor-shell.js']) @endif @endsection @section('content') @php $selectedEventTypeIds = $listing->eventTypes->pluck('id')->all(); $selectedServiceTypeIds = $listing->serviceTypes->pluck('id')->all(); $selectedGroupSizeIds = $listing->groupSizeOptions->pluck('id')->all(); $selectedBudgetIds = $listing->budgetRanges->pluck('id')->all(); $selectedZoneIds = $listing->serviceAreas->pluck('marketplace_zone_id')->filter()->map(fn ($id) => (int) $id)->all(); $selectedCityId = (int) old('marketplace_city_id', $listing->marketplace_city_id); $primaryZoneId = (int) old('primary_marketplace_zone_id', $selectedZoneIds[0] ?? 0); $formSelectedZoneIds = collect(old('zone_ids', $selectedZoneIds)) ->map(fn ($id) => (int) $id) ->filter(fn ($id) => $id > 0 && $id !== $primaryZoneId) ->values() ->all(); $displayCityName = old('city_name', $listing->city_name); $displayZoneName = old('zone_name', $listing->zone_name ?: ($listing->serviceAreas->first()?->city_name ?? '')); $pendingCityApproval = old('city_name', $pendingCityApproval ? $pendingCityLabel : null) && ! $selectedCityId; $pendingCityLabel = old('city_name', $pendingCityLabel); $googlePayload = old('google_location_payload', $listing->google_location_payload ? json_encode($listing->google_location_payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) : ''); $decodedGooglePayload = is_string($googlePayload) && $googlePayload !== '' ? json_decode($googlePayload, true) : []; $decodedGooglePayload = is_array($decodedGooglePayload) ? $decodedGooglePayload : []; $extractPayloadComponent = function (array $payload, array $candidateTypes): string { $components = $payload['address_components'] ?? null; if (! is_array($components)) { return ''; } foreach ($candidateTypes as $candidateType) { foreach ($components as $component) { if (! is_array($component)) { continue; } $types = $component['types'] ?? []; if (is_array($types) && in_array($candidateType, $types, true)) { return trim((string) ($component['long_name'] ?? '')); } } } return ''; }; $displayNeighborhood = $extractPayloadComponent($decodedGooglePayload, ['neighborhood']) ?: $extractPayloadComponent($decodedGooglePayload, ['sublocality_level_2']) ?: $extractPayloadComponent($decodedGooglePayload, ['administrative_area_level_5']); $pendingLocalityName = old('suggest_zone', ($selectedCityId > 0 && $displayZoneName !== '' && ! $primaryZoneId ? $displayZoneName : '')); $faqAi = is_array($faqAi ?? null) ? $faqAi : []; $persistedSystemFaqRows = $listing->systemFaqRows()->values(); $oldSystemFaqQuestions = old('system_faq_question'); $oldSystemFaqAnswers = old('system_faq_answer'); $systemFaqRows = collect(range(0, 2))->map(function ($index) use ($persistedSystemFaqRows, $oldSystemFaqQuestions, $oldSystemFaqAnswers) { $fallback = $persistedSystemFaqRows->get($index) ?? ['question' => '', 'answer' => '']; return [ 'question' => is_array($oldSystemFaqQuestions) ? ($oldSystemFaqQuestions[$index] ?? $fallback['question']) : $fallback['question'], 'answer' => is_array($oldSystemFaqAnswers) ? ($oldSystemFaqAnswers[$index] ?? $fallback['answer']) : $fallback['answer'], ]; }); $faqRows = is_array(old('faq_question')) ? collect(old('faq_question'))->map(function ($question, $index) { return ['question' => $question, 'answer' => old('faq_answer')[$index] ?? '']; }) : $listing->customFaqRows(true)->map(fn ($faq) => ['question' => $faq['question'], 'answer' => $faq['answer']]); if ($faqRows->isEmpty()) { $faqRows = collect([['question' => '', 'answer' => '']]); } $systemFaqGenerationEligible = (bool) ($faqAi['can_generate_system'] ?? false); $listingHasPersistedSystemFaqs = (bool) ($faqAi['has_persisted_system'] ?? false); $hasOldSystemFaqInput = is_array($oldSystemFaqQuestions); $shouldAutoGenerateSystemFaqs = ! $hasOldSystemFaqInput && ! $listingHasPersistedSystemFaqs; $systemFaqGenerateUrl = $faqAi['system_generate_url'] ?? route('mariachi.listings.faqs.ai.generate-system', ['listing' => $listing->id]); $singleFaqGenerateUrl = $faqAi['single_generate_url'] ?? route('mariachi.listings.faqs.ai.generate-one', ['listing' => $listing->id]); $basePriceValue = old('base_price', $listing->base_price); $basePriceValue = filled($basePriceValue) ? (int) round((float) $basePriceValue) : null; $editorDescription = app(\App\Support\ListingDescriptionSanitizer::class)->sanitize( old('description', $editorDescription ?? $listing->description) ) ?? ''; $reviewMap = [ \App\Models\MariachiListing::REVIEW_DRAFT => ['label' => 'Borrador de revision', 'class' => 'secondary'], \App\Models\MariachiListing::REVIEW_PENDING => ['label' => 'En revision', 'class' => 'warning'], \App\Models\MariachiListing::REVIEW_APPROVED => ['label' => 'Aprobado', 'class' => 'success'], \App\Models\MariachiListing::REVIEW_REJECTED => ['label' => 'Rechazado', 'class' => 'danger'], ]; $paymentMap = [ \App\Models\MariachiListing::PAYMENT_NONE => ['label' => 'Sin pago', 'class' => 'secondary'], \App\Models\MariachiListing::PAYMENT_PENDING => ['label' => 'Pago pendiente', 'class' => 'warning'], \App\Models\MariachiListing::PAYMENT_APPROVED => ['label' => 'Pago aprobado', 'class' => 'success'], \App\Models\MariachiListing::PAYMENT_REJECTED => ['label' => 'Pago rechazado', 'class' => 'danger'], ]; $reviewMeta = $reviewMap[$listing->review_status] ?? ['label' => $listing->reviewStatusLabel(), 'class' => 'secondary']; $paymentMeta = $paymentMap[$listing->payment_status] ?? ['label' => $listing->paymentStatusLabel(), 'class' => 'secondary']; $selectedPlan = $listing->selected_plan_code ? ($plans[$listing->selected_plan_code] ?? null) : null; $defaultPlan = $selectedPlan ?: (count($plans) ? reset($plans) : null); $planDurationOptions = $defaultPlan ? array_values($defaultPlan['terms'] ?? []) : []; $selectedTermMonths = (int) old('term_months', $listing->plan_duration_months ?: ($defaultPlan['default_term_months'] ?? ($planDurationOptions[0]['months'] ?? 1))); $defaultPlanTerm = $defaultPlan && isset($defaultPlan['terms'][$selectedTermMonths]) ? $defaultPlan['terms'][$selectedTermMonths] : ($defaultPlan ? reset($defaultPlan['terms']) : null); $latestPayment = $listing->latestPayment; $canSubmitForReview = $listing->canBeSubmittedForReview(); $submitForReviewLabel = $listing->review_status === \App\Models\MariachiListing::REVIEW_REJECTED ? 'Reenviar a revisión' : 'Enviar a revisión'; $maxPhotos = (int) ($capabilities['max_photos_per_listing'] ?? 0); $maxVideos = (int) ($capabilities['max_videos_per_listing'] ?? 0); $maxZones = (int) ($capabilities['max_zones_covered'] ?? 0); $maxEventTypes = (int) ($capabilities['max_event_types'] ?? 0); $maxServiceTypes = (int) ($capabilities['max_service_types'] ?? 0); $maxGroupSizes = (int) ($capabilities['max_group_sizes'] ?? 0); $maxBudgetRanges = (int) ($capabilities['max_budget_ranges'] ?? 0); $photoCount = $listing->photos->count(); $videoCount = $listing->videos->count(); $canAddMorePhotos = $photoCount < $maxPhotos; $canAddMoreVideos = $videoCount < $maxVideos; $canAddCoverageExtras = $maxZones > 1; $canPauseListing = $listing->canOwnerPause(); $canResumeListing = $listing->canOwnerResume(); $showReviewCta = $canSubmitForReview && $listingIssues === [] && $planIssues === []; $usesDraftPlaceholders = trim((string) $listing->title) === 'Nuevo anuncio' || trim((string) $listing->short_description) === 'Completa la informacion del anuncio' || $basePriceValue === null; $forcedInitialStep = session('force_listing_step'); $requestedInitialStep = request()->query('step'); $initialWizardStep = is_string($forcedInitialStep) && $forcedInitialStep !== '' ? $forcedInitialStep : (is_string($requestedInitialStep) && in_array($requestedInitialStep, ['basic', 'location', 'filters', 'contact', 'faqs', 'photos', 'videos', 'final', 'details', 'media'], true) ? $requestedInitialStep : ($listing->isPaymentPending() ? 'final' : '')); @endphp @if($editorMode)
Editor de anuncio {{ $listing->title }}
Autoguardado listo @if($listing->isApprovedForMarketplace() && $listing->slug) Ver público @endif {{ $reviewMeta['label'] }} {{ $paymentMeta['label'] }}
@endif @unless($editorMode) @if(session('status'))
{{ session('status') }}
@endif @if($errors->any())
Hay errores de validación.
    @foreach($errors->all() as $error)
  • {{ $error }}
  • @endforeach
@endif @if($listing->review_status === \App\Models\MariachiListing::REVIEW_REJECTED && $listing->rejection_reason)
El anuncio fue rechazado. Corrige lo siguiente y luego vuelve a enviarlo a revisión.
{{ $listing->rejection_reason }}
@elseif($listing->isPaymentPending())
Pago enviado. El anuncio está bloqueado mientras el equipo valida tu comprobante.
@elseif($listing->isPaymentRejected())
Pago rechazado. {{ $listing->latestPayment?->rejection_reason ?: 'Revisa el comprobante y vuelve a intentar.' }}
@elseif($listing->review_status === \App\Models\MariachiListing::REVIEW_APPROVED)
Este anuncio ya fue aprobado. Si cambias contenido, fotos, videos o filtros, saldrá de publicación y volverá a borrador de revisión.
@endif @if($planIssues !== [])
Tu plan actual requiere ajuste.
    @foreach($planIssues as $issue)
  • {{ $issue }}
  • @endforeach
@endif @if($listingIssues !== [])
Este anuncio requiere ajuste para volver a publicarse.
    @foreach($listingIssues as $issue)
  • {{ $issue }}
  • @endforeach
@endif @endunless @unless($editorMode)
{{ $listing->title }}

Estado: {{ $listing->status }} · Revisión: {{ $reviewMeta['label'] }} · Pago: {{ $paymentMeta['label'] }} · Plan seleccionado: {{ \Illuminate\Support\Str::headline($listing->selected_plan_code ?: 'basic') }} · Plan activo: {{ \Illuminate\Support\Str::headline($listing->effectivePlanCode() ?: 'basic') }}

Completitud: {{ $listing->listing_completion }}% · Fotos {{ $capabilities['max_photos_per_listing'] }} · Videos {{ $capabilities['max_videos_per_listing'] }} · Localidades {{ $capabilities['max_zones_covered'] ?? 0 }}. @if($listing->daysRemainingLabel())
{{ $listing->daysRemainingLabel() }} · vence {{ $listing->currentPlanExpiresAt()?->format('Y-m-d') }}
@endif @if($listing->submitted_for_review_at)
Último envío a revisión: {{ $listing->submitted_for_review_at->format('Y-m-d H:i') }}
@endif
Autoguardado listo @if($canPauseListing)
@csrf
@elseif($canResumeListing)
@csrf
@endif Volver @if($canPauseListing || $canResumeListing) Pausar solo oculta el anuncio; el tiempo del plan sigue corriendo. @endif
@endunless
(int) $city->id, 'name' => $city->name])->values())' data-location-zones='@json($zones->map(fn ($zone) => ['id' => (int) $zone->id, 'city_id' => (int) $zone->marketplace_city_id, 'name' => $zone->name])->values())' > @csrf @method('PATCH') @if($editorMode)
@endif
@if($usesDraftPlaceholders)
Empieza por aquí. Cambia el título, la descripción corta y define un precio base para continuar con el anuncio.
@endif
Desde
{{ $basePriceValue !== null ? '$'.number_format($basePriceValue, 0, ',', '.') : '$—' }}
COP
$0 $4.000.000
Muévelo para definir un precio base sin decimales. Luego puedes cerrar por encima según fecha, ciudad y formato.
{!! $editorDescription !!}
Usa negrita, cursiva, listas, enlaces y títulos. No se permiten imágenes ni embeds.
Escribe la dirección real del anuncio o usa el pin del mapa. El sistema detectará ciudad, localidad, barrio informativo, coordenadas y dejará el país fijo en {{ $googleMaps['default_country_name'] }}.
@if($pendingCityApproval)
Ciudad pendiente de aprobación: {{ $pendingCityLabel }}. Aún no pertenece al catálogo oficial, así que no podrás enviar el anuncio a revisión hasta ajustar la ubicación o esperar aprobación admin.
@endif @if(! $googleMaps['enabled'])
Google Maps no está configurado. Desde admin debes registrar la API key para activar el autocompletado.
@endif
Busca la dirección o usa el mapa. Aquí dejamos calle y número para una lectura más limpia; el detalle completo queda en Google Maps.
Ciudad, localidad y departamento se detectan desde Google Maps y no se editan manualmente. Las coordenadas siguen siendo internas y el país permanece fijo en {{ $googleMaps['default_country_name'] }}.
Cobertura adicional
La localidad principal se detecta automáticamente. Activa esta opción solo si también cubres otras localidades dentro de la misma ciudad.
travels_to_other_cities) ? 'checked' : '' }} @disabled(! $canAddCoverageExtras) >
No agrega otras ciudades ni cambia tu localidad principal. Solo amplía la cobertura dentro del mismo catálogo de ciudad. @unless($canAddCoverageExtras)
Tu plan no permite cobertura adicional. Si quieres sumar más localidades dentro de esta ciudad, .
@endunless
Tu plan permite hasta {{ $maxZones }} localidad(es) por anuncio, contando la localidad principal detectada. Aquí solo puedes sumar localidades adicionales de la misma ciudad.
Localidades disponibles
Solo del catálogo oficial de la ciudad principal.
Localidades seleccionadas (0 / {{ $maxZones }})
La localidad principal se detecta automáticamente y cuenta dentro del límite.
Máx {{ $maxZones }}
@foreach($formSelectedZoneIds as $zoneId) @endforeach
@error('zone_ids')
{{ $message }}
@enderror
Tipos de evento

Selecciona hasta {{ $maxEventTypes }} opciones para este anuncio.

0 / {{ $maxEventTypes }}
@foreach($eventTypes as $eventType)
id, old('event_type_ids', $selectedEventTypeIds)) ? 'checked' : '' }}>
@endforeach
@error('event_type_ids')
{{ $message }}
@enderror
Tipos de servicio

Selecciona hasta {{ $maxServiceTypes }} opciones para definir mejor el formato.

0 / {{ $maxServiceTypes }}
@foreach($serviceTypes as $serviceType)
id, old('service_type_ids', $selectedServiceTypeIds)) ? 'checked' : '' }}>
@endforeach
@error('service_type_ids')
{{ $message }}
@enderror
Tamaño del grupo

Selecciona hasta {{ $maxGroupSizes }} opciones para indicar el formato disponible.

0 / {{ $maxGroupSizes }}
@foreach($groupSizeOptions as $option)
id, old('group_size_option_ids', $selectedGroupSizeIds)) ? 'checked' : '' }}>
@endforeach
@error('group_size_option_ids')
{{ $message }}
@enderror
Presupuesto

Selecciona hasta {{ $maxBudgetRanges }} rangos para cubrir varias búsquedas del marketplace.

0 / {{ $maxBudgetRanges }}
@foreach($budgetRanges as $range)
id, old('budget_range_ids', $selectedBudgetIds)) ? 'checked' : '' }}>
@endforeach
@error('budget_range_ids')
{{ $message }}
@enderror
@php $stripColombiaDialCode = static function (mixed $value): string { $raw = trim((string) $value); if ($raw === '') { return ''; } $normalized = preg_replace('/^\+?\s*57[\s\-]*/u', '', $raw); return trim((string) ($normalized ?? $raw)); }; $listingPublicPhoneInput = $stripColombiaDialCode(old('public_phone', $listing->public_phone)); $listingPublicWhatsappInput = $stripColombiaDialCode(old('public_whatsapp', $listing->public_whatsapp)); @endphp
Este contacto es exclusivo de este anuncio. Si dejas un campo vacío, no se mostrará en la vista pública. Teléfono y WhatsApp además dependen del plan activo.
Teléfono y WhatsApp

Canales directos del anuncio. Si están vacíos, no se mostrarán.

+57 Colombia
Botón “Llamar” del anuncio público. @error('public_phone')
{{ $message }}
@enderror
+57 Colombia
Se usará para el botón de WhatsApp del anuncio. @error('public_whatsapp')
{{ $message }}
@enderror
Redes y sitio web

Puedes pegar una URL completa o un @usuario compatible. Se verán en el anuncio público.

Se mostrará en tu anuncio público. @error('website')
{{ $message }}
@enderror
@error('instagram')
{{ $message }}
@enderror
@error('facebook')
{{ $message }}
@enderror
@error('tiktok')
{{ $message }}
@enderror
@error('youtube')
{{ $message }}
@enderror
FAQs del sistema

Estas 3 preguntas siempre se muestran primero. Puedes ajustarlas manualmente o regenerarlas con IA.

Las 3 FAQs del sistema se reemplazan al regenerarlas con IA.
@foreach($systemFaqRows as $faq)

FAQ automática {{ $loop->iteration }}

Visible arriba del resto de preguntas.
Sistema
@endforeach
@error('system_faq_question')
{{ $message }}
@enderror @error('system_faq_answer')
{{ $message }}
@enderror
FAQs personalizadas

Agrega respuestas propias para tu anuncio. Puedes reordenarlas entre sí sin mover las 3 del sistema.

{{ $faqRows->count() }} / 10
@foreach($faqRows as $faq)
FAQ adicional
Visible después de las 3 automáticas.
@endforeach
Máximo 10 FAQs personalizadas. Si dejas una vacía, no se guardará. La IA solo rellena bloques vacíos.
@error('faq_question')
{{ $message }}
@enderror @error('faq_answer')
{{ $message }}
@enderror
Fotos del anuncio

Tu plan permite hasta {{ $maxPhotos }} fotos. La primera destacada se usa como portada principal del anuncio.

{{ $photoCount }} / {{ $maxPhotos }}
@error('photo')
{{ $message }}
@enderror
@csrf
@if($maxPhotos > 0 && $canAddMorePhotos) @endif @foreach($listing->photos as $photo)
foto del anuncio
@if($photo->is_featured) Destacada @else Foto {{ $loop->iteration }} @endif {{ $loop->iteration }}
@unless($photo->is_featured)
@csrf @method('PATCH')
@endunless @if($listing->photos->count() > 1)
@csrf @method('PATCH')
@csrf @method('PATCH')
@endif
@csrf @method('DELETE')
@endforeach @if($maxPhotos <= 0 || ! $canAddMorePhotos) @endif
Videos del anuncio

Agrega enlaces de YouTube o videos externos para reforzar confianza y mostrar el repertorio.

{{ $videoCount }} / {{ $maxVideos }}
@if($maxVideos <= 0)
Tu plan actual no incluye videos

Mejora tu plan para añadir videos al anuncio y aumentar la conversión.

@else
@csrf
Los videos son opcionales. Solo validamos la URL cuando presionas “Agregar video”.
@error('url')
{{ $message }}
@enderror
@endif
@forelse($listing->videos as $video)
@if($video->thumbnail_url) {{ $video->display_title }} @else
@endif
{{ $video->display_title }}
{{ $video->url }}
@csrf @method('DELETE')
@empty
Todavía no has agregado videos Cuando añadas uno, aparecerá aquí con acceso rápido para eliminarlo.
@endforelse
@if($maxVideos > 0 && ! $canAddMoreVideos) @endif
Planes disponibles

El anuncio se autoguarda. Aquí eliges plan y continúas a ePayco para completar el cobro.

Completitud {{ $listing->listing_completion }}%
@if(! $listing->listing_completed)
Aún faltan bloques para completar el anuncio. Termina datos, ubicación, filtros y fotos antes de pagar.
@endif @if(! $epayco['is_configured'])
ePayco no está configurado en este momento. No podrás continuar al checkout hasta completar las llaves en el entorno.
@endif @if($listing->isPaymentPending())
Ya existe un checkout ePayco pendiente para este anuncio. Puedes retomarlo con el plan seleccionado.
@elseif($listing->payment_status === \App\Models\MariachiListing::PAYMENT_APPROVED)
Este anuncio ya tiene un pago aprobado. Puedes dejarlo como está, renovarlo o subirlo de plan sin bajarlo del aire.
@elseif($listing->isPaymentRejected())
Pago rechazado. {{ $latestPayment?->rejection_reason ?: 'ePayco no aprobó la transacción. Revisa el cobro y vuelve a intentar.' }}
@endif @if($plans) @if($planDurationOptions)
Duración del anuncio
Elige cuánto tiempo quieres publicar este anuncio
El plazo cambia el total a pagar y aplica descuento automático en 3 y 12 meses.
@foreach($planDurationOptions as $termOption) @endforeach
@endif
@foreach($plans as $code => $plan) @php $activeTerm = $plan['terms'][$selectedTermMonths] ?? reset($plan['terms']); $isCurrentSelection = $listing->selected_plan_code === $code && (int) ($listing->plan_duration_months ?: 1) === (int) ($activeTerm['months'] ?? 1); $canRenewCurrentPlan = $listing->status === \App\Models\MariachiListing::STATUS_ACTIVE && $listing->review_status === \App\Models\MariachiListing::REVIEW_APPROVED && $listing->payment_status === \App\Models\MariachiListing::PAYMENT_APPROVED && $isCurrentSelection; $buttonLabel = 'Pagar con ePayco'; if ($canRenewCurrentPlan) { $buttonLabel = 'Renovar con ePayco'; } elseif ($listing->payment_status === \App\Models\MariachiListing::PAYMENT_APPROVED && $isCurrentSelection) { $buttonLabel = 'Plan aprobado'; } elseif ($listing->isPaymentPending()) { $buttonLabel = $isCurrentSelection ? 'Continuar pago en ePayco' : 'Pago pendiente en otro plan'; } elseif ($listing->isPaymentRejected() && $isCurrentSelection) { $buttonLabel = 'Reintentar con ePayco'; } elseif ($isCurrentSelection) { $buttonLabel = 'Continuar con este plan'; } $isDisabled = ! $listing->listing_completed || (! $isCurrentSelection && $listing->isPaymentPending()) || ! $epayco['is_configured'] || ($listing->payment_status === \App\Models\MariachiListing::PAYMENT_APPROVED && $isCurrentSelection && ! $canRenewCurrentPlan); @endphp
{{ $plan['name'] }} @if($plan['badge_text']) {{ $plan['badge_text'] }} @endif
@if($isCurrentSelection) Seleccionado @endif

{{ $plan['description'] }}

${{ number_format((int) ($activeTerm['total_price_cop'] ?? 0), 0, ',', '.') }} COP

Total {{ $activeTerm['label'] ?? '1 mes' }} ${{ number_format((int) ($activeTerm['monthly_equivalent_cop'] ?? 0), 0, ',', '.') }} / mes equivalente
{{ $activeTerm['savings_copy'] ?? 'Precio regular' }}
  • {{ $plan['max_zones_covered'] }} localidad(es) por anuncio
  • {{ $plan['max_photos_per_listing'] }} foto(s) por anuncio
  • {{ $plan['can_add_video'] ? $plan['max_videos_per_listing'].' video(s) por anuncio' : 'Sin videos incluidos' }}
  • {{ $plan['max_event_types'] }} tipo(s) de evento
  • {{ $plan['max_service_types'] }} tipo(s) de servicio
  • {{ $plan['max_group_sizes'] }} tamaño(s) de grupo
  • {{ $plan['max_budget_ranges'] }} rango(s) de presupuesto
@endforeach
@else
No hay planes configurados todavía para este anuncio.
@endif
@if($showReviewCta)
@csrf
@endif
@if($editorMode)
@endif @if($editorMode) @endif
@csrf
@if($editorMode)
@endif @endsection