feat(admin): new AdminBusinessEditor with live mobile preview + fix admin logout bug on file picker timeout

This commit is contained in:
2026-03-04 14:15:59 -05:00
parent 0a6a0e8f7e
commit d17955383a
4 changed files with 663 additions and 220 deletions

View File

@ -0,0 +1,641 @@
<script setup lang="ts">
import { ref, onMounted, computed } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { businessService } from '@/services/businessService';
import type { Business } from '@/types';
import { useAuthStore } from '@/stores/auth';
const router = useRouter();
const route = useRoute();
const authStore = useAuthStore();
const isLoading = ref(false);
const isEditing = ref(false);
const showMessage = ref({ text: '', type: '' });
const selectedFile = ref<File | null>(null);
const selectedFileName = ref('');
// Business state
const businessForm = ref<Partial<Business>>({
name: '',
address: '',
phone: '',
image_url: '',
social_media: '',
category: 'Restaurante',
area: 'Boquete',
description: '',
website: '',
schedule: '',
whatsapp: '',
instagram: '',
facebook: '',
gallery_images: []
});
const previewImageUrl = ref('https://images.unsplash.com/photo-1555396273-367ea4eb4db5?q=80&w=2074&auto=format&fit=crop');
onMounted(async () => {
const id = route.params.id as string;
if (id && id !== 'new') {
isEditing.value = true;
try {
isLoading.value = true;
const data = await businessService.getBusiness(id);
businessForm.value = { ...data };
if (data.image_url) {
previewImageUrl.value = data.image_url;
}
} catch (e) {
console.error(e);
showMessage.value = { text: 'Error cargando negocio', type: 'error' };
} finally {
isLoading.value = false;
}
}
});
function handleImageChange(event: Event) {
const input = event.target as HTMLInputElement;
if (input.files && input.files[0]) {
const file = input.files[0];
selectedFile.value = file;
selectedFileName.value = file.name;
// Preview logic
const reader = new FileReader();
reader.onload = (e) => {
previewImageUrl.value = e.target?.result as string;
};
reader.readAsDataURL(file);
}
}
async function saveBusiness() {
isLoading.value = true;
showMessage.value = { text: '', type: '' };
try {
const formData = new FormData();
formData.append('name', businessForm.value.name || '');
formData.append('category', businessForm.value.category || 'Restaurante');
formData.append('address', businessForm.value.address || '');
formData.append('phone', businessForm.value.phone || '');
formData.append('area', businessForm.value.area || 'Boquete');
formData.append('description', businessForm.value.description || '');
formData.append('website', businessForm.value.website || '');
formData.append('schedule', businessForm.value.schedule || '');
formData.append('whatsapp', businessForm.value.whatsapp || '');
formData.append('instagram', businessForm.value.instagram || '');
formData.append('facebook', businessForm.value.facebook || '');
if (businessForm.value.gallery_images?.length) {
formData.append('gallery_images', JSON.stringify(businessForm.value.gallery_images));
}
if (selectedFile.value) {
formData.append('image', selectedFile.value);
}
if (isEditing.value && businessForm.value.id) {
await businessService.updateBusiness(businessForm.value.id, formData);
} else {
await businessService.createBusiness(formData);
}
showMessage.value = { text: '¡Negocio Guardado Exitosamente!', type: 'success' };
setTimeout(() => {
router.push(authStore.isAdmin ? '/admin' : '/promoter');
}, 2000);
} catch (error: any) {
console.error('Error saving business:', error);
showMessage.value = { text: 'Error al guardar. Intenta de nuevo.', type: 'error' };
} finally {
isLoading.value = false;
}
}
const CATEGORY_EMOJI: Record<string, string> = {
'Restaurante': '🍽️', 'Hotel': '🏨', 'Café': '☕',
'Comercio': '🏪', 'Turismo': '🌄', 'Bebidas': '🍹',
}
const catEmoji = computed(() => CATEGORY_EMOJI[businessForm.value.category || ''] || '📍');
</script>
<template>
<div class="admin-editor-view">
<div class="nexus-admin-header">
<button class="back-btn" @click="router.back()">
<span class="material-icons">arrow_back</span>
</button>
<h1>{{ isEditing ? 'Editar Negocio' : 'Nuevo Negocio' }}</h1>
</div>
<div class="admin-grid-layout">
<!-- FORM PANEL -->
<section class="form-panel nexus-glass">
<div class="section-title">
<span class="material-icons">storefront</span>
<h2>Datos del Negocio</h2>
</div>
<div class="nexus-form">
<div class="form-group grid-row">
<div class="input-box">
<label>Nombre del Negocio *</label>
<input v-model="businessForm.name" type="text" placeholder="Ej: Restaurante La Casona" required>
</div>
<div class="input-box">
<label>Imagen de Portada</label>
<div class="file-upload-wrapper">
<input type="file" @change="handleImageChange" accept="image/*" id="file-input">
<label for="file-input" class="file-label">
<span class="material-icons">cloud_upload</span>
{{ selectedFileName || 'SELECCIONAR FOTO' }}
</label>
</div>
</div>
</div>
<div class="form-group grid-row">
<div class="input-box">
<label>Categoría</label>
<select v-model="businessForm.category" class="nexus-select">
<option value="Restaurante">Restaurante</option>
<option value="Hotel">Hotel</option>
<option value="Café">Café</option>
<option value="Bebidas">Bar / Bebidas</option>
<option value="Comercio">Comercio</option>
<option value="Turismo">Turismo</option>
</select>
</div>
<div class="input-box">
<label>Área / Región</label>
<select v-model="businessForm.area" class="nexus-select">
<option value="Boquete">Boquete</option>
<option value="Alto Boquete">Alto Boquete</option>
<option value="Dolega">Dolega</option>
<option value="David">David</option>
<option value="Caldera">Caldera</option>
<option value="Chiriquí">Chiriquí</option>
</select>
</div>
</div>
<div class="form-group">
<label>Descripción del Lugar</label>
<textarea
v-model="businessForm.description"
placeholder="Describe el ambiente, la especialidad, qué lo hace único..."
rows="3"
class="nexus-textarea"
></textarea>
</div>
<div class="form-group grid-row">
<div class="input-box">
<label>Horario de Atención</label>
<input v-model="businessForm.schedule" type="text" placeholder="Ej: Lun-Sáb 8am-10pm">
</div>
<div class="input-box">
<label>Teléfono Fijo</label>
<input v-model="businessForm.phone" type="text" placeholder="+507 720-0000">
</div>
</div>
<div class="form-group">
<label>Dirección Física</label>
<input v-model="businessForm.address" type="text" placeholder="Ej: Calle Principal #123">
</div>
<div class="form-section-label mt-4">Redes y Contacto Directo</div>
<div class="form-group grid-row">
<div class="input-box">
<label>WhatsApp (Sin +)</label>
<div class="whatsapp-input">
<span class="prefix">+</span>
<input v-model="businessForm.whatsapp" type="text" placeholder="50760000000">
</div>
</div>
<div class="input-box">
<label>Instagram / Facebook</label>
<input v-model="businessForm.instagram" type="text" placeholder="@usuario">
</div>
</div>
<div class="form-group">
<label>Página Web</label>
<input v-model="businessForm.website" type="text" placeholder="https://">
</div>
<button class="deploy-btn" :disabled="isLoading" @click="saveBusiness">
<span class="material-icons">{{ isLoading ? 'sync' : 'save' }}</span>
{{ isLoading ? 'GUARDANDO...' : 'GUARDAR NEGOCIO' }}
</button>
<p v-if="showMessage.text" :class="['message', showMessage.type]">{{ showMessage.text }}</p>
</div>
</section>
<!-- PREVIEW PANEL -->
<section class="preview-panel">
<div class="section-title white">
<span class="material-icons">visibility</span>
<h2>Visualización en App</h2>
</div>
<div class="preview-container">
<!-- MOBILE PHONE MOCKUP -->
<div class="phone-mockup">
<div class="phone-content biz-page-preview custom-scrollbar">
<section class="hero">
<img :src="previewImageUrl" class="hero-img" alt="Hero" />
<div class="hero-gradient"></div>
<div class="hero-body">
<span class="hero-cat">{{ catEmoji }} {{ businessForm.category }}</span>
<h1 class="hero-name">{{ businessForm.name || 'Nombre del Negocio' }}</h1>
</div>
<div class="hero-rule"></div>
</section>
<div class="pills-row-preview">
<div class="pill" v-if="businessForm.area"><span class="material-icons">location_on</span> {{ businessForm.area }}</div>
<div class="pill" v-if="businessForm.schedule"><span class="material-icons">schedule</span> {{ businessForm.schedule }}</div>
<div class="pill" v-if="businessForm.phone"><span class="material-icons">phone</span> {{ businessForm.phone }}</div>
</div>
<section class="biz-section">
<div class="section-header">
<span class="section-accent"></span>
<h2 class="section-title">Sobre Nosotros</h2>
</div>
<p class="biz-desc">{{ businessForm.description || 'Aquí aparecerá la descripción del negocio. Un lugar espectacular para disfrutar de lo mejor en compañía de amigos y familiares.' }}</p>
<!-- Social links -->
<div class="social-links mt-4">
<button class="social-btn social-wa" v-if="businessForm.whatsapp">
<span class="material-icons">chat</span> WhatsApp
</button>
<button class="social-btn social-ig" v-if="businessForm.instagram">
<span class="material-icons">photo_camera</span> Instagram
</button>
</div>
</section>
<!-- Sticky CTA -->
<div class="cta-bar">
<button class="cta-map"><span class="material-icons">near_me</span> Ver en el Mapa</button>
</div>
</div>
</div>
<p class="preview-hint mt-3 text-center text-sm text-gray-400">Interactúa con el scroll para ver cómo luce el perfil</p>
</div>
</section>
</div>
</div>
</template>
<style scoped>
.admin-editor-view {
min-height: 100vh;
background: #0f172a;
color: white;
padding: 40px;
font-family: 'Inter', sans-serif;
}
.nexus-admin-header {
display: flex;
align-items: center;
gap: 24px;
margin-bottom: 40px;
}
.back-btn {
background: rgba(255,255,255,0.1);
border: none;
color: white;
width: 44px;
height: 44px;
border-radius: 12px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
.nexus-admin-header h1 {
font-size: 2rem;
font-weight: 800;
margin: 0;
background: linear-gradient(135deg, #fff 0%, #94a3b8 100%);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.admin-grid-layout {
display: grid;
grid-template-columns: 1fr 400px;
gap: 40px;
}
.nexus-glass {
background: rgba(30, 41, 59, 0.5);
backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 32px;
padding: 32px;
}
.section-title {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 32px;
color: #94a3b8;
}
.section-title h2 {
font-size: 1.25rem;
margin: 0;
}
.section-title.white {
color: white;
}
.nexus-form {
display: flex;
flex-direction: column;
gap: 24px;
}
.grid-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
}
.form-group {
display: flex;
flex-direction: column;
gap: 8px;
}
.form-group label {
font-size: 0.85rem;
font-weight: 600;
color: #94a3b8;
}
.form-group input, .nexus-select, .nexus-textarea {
background: rgba(15, 23, 42, 0.5);
border: 1px solid rgba(255, 255, 255, 0.1);
padding: 14px 16px;
border-radius: 12px;
color: white;
font-size: 1rem;
outline: none;
transition: all 0.3s;
}
.nexus-select {
cursor: pointer;
appearance: none;
}
.nexus-textarea {
resize: vertical;
min-height: 100px;
}
.form-group input:focus, .nexus-select:focus, .nexus-textarea:focus {
border-color: #fee715;
box-shadow: 0 0 0 4px rgba(254, 231, 21, 0.1);
}
.file-upload-wrapper {
position: relative;
width: 100%;
}
.file-upload-wrapper input[type="file"] {
position: absolute;
width: 0.1px;
height: 0.1px;
opacity: 0;
overflow: hidden;
z-index: -1;
}
.file-label {
display: flex !important;
align-items: center;
justify-content: center;
gap: 10px;
background: rgba(254, 231, 21, 0.1) !important;
border: 1px dashed #fee715 !important;
padding: 12px !important;
border-radius: 12px;
color: #fee715 !important;
font-weight: 800;
cursor: pointer;
transition: all 0.3s;
font-size: 0.8rem;
}
.whatsapp-input {
display: flex;
background: rgba(15, 23, 42, 0.5);
border-radius: 12px;
border: 1px solid rgba(255, 255, 255, 0.1);
overflow: hidden;
}
.whatsapp-input .prefix {
padding: 14px 16px;
background: rgba(255,255,255,0.05);
color: #94a3b8;
font-weight: 700;
}
.whatsapp-input input {
flex: 1;
border: none;
background: transparent;
}
.deploy-btn {
margin-top: 20px;
background: #fee715;
color: #101820;
border: none;
padding: 20px;
border-radius: 16px;
font-weight: 800;
font-size: 1.1rem;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
gap: 12px;
transition: all 0.3s;
}
.deploy-btn:hover:not(:disabled) {
transform: translateY(-4px);
}
.deploy-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.message {
text-align: center;
font-weight: bold;
margin-top: 10px;
}
.message.success { color: #25d366; }
.message.error { color: #ef4444; }
/* ── PHONE MOCKUP FOR PREVIEW ── */
.phone-mockup {
width: 375px;
height: 750px;
background: #101820;
border: 12px solid #1e293b;
border-radius: 40px;
overflow: hidden;
box-shadow: 0 30px 60px rgba(0,0,0,0.5);
position: relative;
margin: 0 auto;
}
.phone-content {
width: 100%;
height: 100%;
overflow-y: auto;
position: relative;
}
/* ── PREVIEW BIZ PAGE STYLES ── */
.biz-page-preview {
background: #101820;
color: white;
font-family: sans-serif;
}
.hero {
position: relative;
height: 280px;
}
.hero-img {
width: 100%;
height: 100%;
object-fit: cover;
}
.hero-gradient {
position: absolute;
inset: 0;
background: linear-gradient(transparent 30%, rgba(0,0,0,0.9) 100%);
}
.hero-body {
position: absolute;
bottom: 0;
width: 100%;
text-align: center;
padding: 20px;
}
.hero-cat {
background: #fee715;
color: black;
font-size: 0.7rem;
font-weight: 800;
padding: 4px 10px;
border-radius: 20px;
display: inline-block;
margin-bottom: 8px;
}
.hero-name {
font-size: 1.6rem;
font-weight: 900;
margin: 0;
text-shadow: 0 2px 10px rgba(0,0,0,0.5);
}
.hero-rule {
position: absolute;
bottom: 0;
width: 100%;
height: 3px;
background: linear-gradient(90deg, transparent, #fee715 40%, transparent);
}
.pills-row-preview {
display: flex;
gap: 8px;
padding: 16px;
overflow-x: auto;
scrollbar-width: none;
}
.pill {
background: rgba(255,255,255,0.05);
border: 1px solid rgba(255,255,255,0.1);
padding: 6px 12px;
border-radius: 20px;
font-size: 0.75rem;
display: flex;
align-items: center;
gap: 6px;
white-space: nowrap;
}
.pill .material-icons { font-size: 14px; color: #fee715; }
.biz-section { padding: 20px 16px; border-bottom: 1px solid rgba(255,255,255,0.05); }
.section-header { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.section-accent { width: 4px; height: 18px; background: #fee715; border-radius: 4px; }
.section-title { font-size: 1rem; font-weight: 800; margin: 0; }
.biz-desc { font-size: 0.85rem; color: #a1a1aa; line-height: 1.5; }
.social-links { display: flex; gap: 8px; flex-wrap: wrap; }
.social-btn {
flex: 1;
padding: 10px;
border-radius: 12px;
border: none;
font-weight: 700;
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
}
.social-wa { background: #128c7e; color: white; }
.social-ig { background: linear-gradient(45deg, #f09433 0%, #e6683c 25%, #dc2743 50%, #cc2366 75%, #bc1888 100%); color: white; }
.cta-bar {
position: sticky;
bottom: 0px;
width: 100%;
padding: 16px;
background: rgba(16, 24, 32, 0.95);
backdrop-filter: blur(10px);
border-top: 1px solid rgba(255,255,255,0.1);
}
.cta-map {
width: 100%;
padding: 14px;
border-radius: 100px;
background: white;
color: black;
font-weight: 800;
border: none;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
}
</style>

View File

@ -24,11 +24,7 @@ const categories = ['Todas', 'Restaurante', 'Turismo', 'Bebidas', 'Comercio']
// Modals
const showModal = ref(false)
const showBusinessModal = ref(false)
const isEditing = ref(false)
const isEditingBusiness = ref(false)
const businessImageFile = ref<File | null>(null)
const businessImagePreview = ref<string | null>(null)
// Current data
@ -47,24 +43,6 @@ const currentCoupon = ref<Partial<Coupon>>({
is_active: true
})
const currentBusiness = ref<Partial<Business>>({
name: '',
address: '',
phone: '',
image_url: '',
social_media: '',
category: 'Restaurante',
area: 'Boquete',
description: '',
website: '',
// Template fields
schedule: '',
whatsapp: '',
instagram: '',
facebook: '',
gallery_images: []
})
const userName = localStorage.getItem('user_name') || 'Promotor'
onMounted(async () => {
@ -174,82 +152,15 @@ async function deleteShuttle(id: string) {
}
// Business Methods
import { useRouter } from 'vue-router'
const localRouter = useRouter()
function openCreateBusinessModal() {
isEditingBusiness.value = false
currentBusiness.value = {
name: '',
address: '',
phone: '',
image_url: '',
social_media: '',
category: 'Restaurante',
area: 'Boquete',
description: '',
website: '',
schedule: '',
whatsapp: '',
instagram: '',
facebook: '',
gallery_images: []
}
showBusinessModal.value = true
businessImageFile.value = null
businessImagePreview.value = null
}
function handleBusinessImage(event: any) {
const file = event.target.files[0]
if (file) {
businessImageFile.value = file
businessImagePreview.value = URL.createObjectURL(file)
}
localRouter.push('/admin/business-edit/new')
}
function openEditBusinessModal(biz: Business) {
isEditingBusiness.value = true
currentBusiness.value = { ...biz }
showBusinessModal.value = true
businessImageFile.value = null
businessImagePreview.value = getImageUrl(biz.image_url)
}
async function saveBusiness() {
try {
const formData = new FormData()
formData.append('name', currentBusiness.value.name || '')
formData.append('category', currentBusiness.value.category || 'Restaurante')
formData.append('address', currentBusiness.value.address || '')
formData.append('phone', currentBusiness.value.phone || '')
formData.append('social_media', currentBusiness.value.social_media || '')
formData.append('area', currentBusiness.value.area || 'Boquete')
formData.append('description', currentBusiness.value.description || '')
formData.append('website', currentBusiness.value.website || '')
// Template fields
formData.append('schedule', currentBusiness.value.schedule || '')
formData.append('whatsapp', currentBusiness.value.whatsapp || '')
formData.append('instagram', currentBusiness.value.instagram || '')
formData.append('facebook', currentBusiness.value.facebook || '')
// gallery_images handled separately via JSON
if (currentBusiness.value.gallery_images?.length) {
formData.append('gallery_images', JSON.stringify(currentBusiness.value.gallery_images))
}
if (businessImageFile.value) {
formData.append('image', businessImageFile.value)
}
if (isEditingBusiness.value && currentBusiness.value.id) {
await businessService.updateBusiness(currentBusiness.value.id, formData)
} else {
await businessService.createBusiness(formData)
}
showBusinessModal.value = false
await loadBusinesses()
} catch (e) {
console.error('Error saving business:', e)
alert('Error al guardar el negocio')
}
localRouter.push(`/admin/business-edit/${biz.id}`)
}
async function deleteBusiness(id: string) {
@ -704,125 +615,6 @@ async function toggleCouponStatus(coupon: Coupon) {
</div>
</div>
<!-- Business Modal -->
<div v-if="showBusinessModal" class="modal-overlay" @click.self="showBusinessModal = false">
<div class="modal-content">
<div class="modal-header">
<h2>{{ isEditingBusiness ? 'Editar Negocio' : 'Registrar Negocio' }}</h2>
<button class="close-btn" @click="showBusinessModal = false"><span class="material-icons">close</span></button>
</div>
<form @submit.prevent="saveBusiness" class="coupon-form">
<!-- Info básica -->
<div class="form-section-label">📋 Información Básica</div>
<div class="form-group">
<label>Nombre del Negocio *</label>
<input v-model="currentBusiness.name" type="text" required placeholder="Ej: Restaurante La Casona">
</div>
<div class="form-row">
<div class="form-group">
<label>Categoría</label>
<select v-model="currentBusiness.category">
<option value="Restaurante">Restaurante</option>
<option value="Hotel">Hotel</option>
<option value="Café">Café</option>
<option value="Bebidas">Bar / Bebidas</option>
<option value="Comercio">Comercio</option>
<option value="Turismo">Turismo</option>
</select>
</div>
<div class="form-group">
<label>Área / Región</label>
<select v-model="currentBusiness.area">
<option value="Boquete">Boquete</option>
<option value="Alto Boquete">Alto Boquete</option>
<option value="Dolega">Dolega</option>
<option value="David">David</option>
<option value="Caldera">Caldera</option>
<option value="Chiriquí">Chiriquí</option>
</select>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label>Teléfono</label>
<input v-model="currentBusiness.phone" type="text" placeholder="+507 6000-0000">
</div>
<div class="form-group">
<label>🕐 Horario de Atención</label>
<input v-model="currentBusiness.schedule" type="text" placeholder="Ej: Lun-Sáb 8am-10pm">
</div>
</div>
<div class="form-group">
<label>Dirección Física</label>
<input v-model="currentBusiness.address" type="text" placeholder="Ej: Calle Principal #123, Frente al Parque">
</div>
<!-- Imagen principal -->
<div class="form-section-label">🖼 Imagen de Portada</div>
<div class="form-group">
<label>Foto Principal (Logo o Fachada)</label>
<div class="file-upload-wrapper">
<input type="file" @change="handleBusinessImage" accept="image/*" class="file-input">
<div class="file-preview" v-if="businessImagePreview">
<img :src="businessImagePreview" alt="Vista previa">
</div>
</div>
</div>
<!-- Descripción -->
<div class="form-section-label">📝 Descripción</div>
<div class="form-group">
<label>Sobre el Negocio (Texto de marketing)</label>
<textarea v-model="currentBusiness.description" placeholder="Describe la experiencia del lugar, su especialidad y ambiente para atraer clientes..." rows="4"></textarea>
</div>
<!-- Redes Sociales y Contacto -->
<div class="form-section-label">🌐 Contacto y Redes Sociales</div>
<div class="form-row">
<div class="form-group">
<label>💬 WhatsApp</label>
<input v-model="currentBusiness.whatsapp" type="text" placeholder="50760000000 (con código de país)">
</div>
<div class="form-group">
<label>📸 Instagram</label>
<input v-model="currentBusiness.instagram" type="text" placeholder="@usuario">
</div>
</div>
<div class="form-row">
<div class="form-group">
<label>👍 Facebook</label>
<input v-model="currentBusiness.facebook" type="text" placeholder="/nombre-de-pagina">
</div>
<div class="form-group">
<label>🌐 Página Web</label>
<input v-model="currentBusiness.website" type="url" placeholder="https://www.ejemplo.com">
</div>
</div>
<!-- Galería -->
<div class="form-section-label">📸 Galería de Imágenes (Carrusel)</div>
<div class="form-group">
<label>URLs de fotos adicionales (una por línea)</label>
<textarea
:value="currentBusiness.gallery_images?.join('\n') || ''"
@input="(e: any) => currentBusiness.gallery_images = e.target.value.split('\n').map((s: string) => s.trim()).filter((s: string) => s.length > 0)"
placeholder="https://url-foto1.jpg&#10;https://url-foto2.jpg&#10;https://url-foto3.jpg"
rows="3"
></textarea>
<small class="form-hint">Agrega URLs de imágenes para el carrusel (menú, ambiente, experiencias). Una URL por línea.</small>
</div>
<div class="form-actions">
<button type="submit" class="submit-btn">
<span class="material-icons">{{ isEditingBusiness ? 'save' : 'store' }}</span>
{{ isEditingBusiness ? 'Guardar Cambios' : 'Publicar Negocio' }}
</button>
</div>
</form>
</div>
</div>
</div>
</template>