feat: add auto-carousel progression and admin image uploader guidelines

This commit is contained in:
2026-03-18 12:51:27 -05:00
parent 79fe4953c7
commit e2dff3fd5e
2 changed files with 40 additions and 3 deletions

View File

@ -200,6 +200,9 @@ const catEmoji = computed(() => CATEGORY_EMOJI[businessForm.value.category || ''
{{ selectedFileName || 'SELECCIONAR FOTO' }}
</label>
</div>
<p style="font-size: 0.7rem; color: #94a3b8; margin-top: 8px;">
💡 <strong>Recomendación:</strong> Resolución de 800x600px (4:3) o similar para que encaje perfecto en las tarjetas principales. Peso máximo sugerido: 5MB.
</p>
</div>
</div>
@ -306,7 +309,10 @@ const catEmoji = computed(() => CATEGORY_EMOJI[businessForm.value.category || ''
<label for="gallery-input" class="gallery-upload-label">
<span class="material-icons" style="font-size:36px">add_photo_alternate</span>
<span>Agregar fotos a la galería</span>
<span style="font-size:0.7rem;opacity:0.6">PNG, JPG hasta 5 MB cada una</span>
<span style="font-size:0.75rem; color: #fee715; margin-top: 4px;">
💡 <strong>Mejor visual:</strong> Usa formato horizontal / apaisado (16:9) como <strong>1200x675px</strong>.
</span>
<span style="font-size:0.7rem;opacity:0.6; margin-top: 4px;">PNG, JPG hasta 5 MB cada una</span>
</label>
</div>

View File

@ -1,5 +1,5 @@
<script setup lang="ts">
import { ref, onMounted, computed } from 'vue'
import { ref, onMounted, computed, onUnmounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { businessService } from '@/services/businessService'
import { couponsService } from '@/services/couponsService'
@ -49,6 +49,7 @@ async function fetchData() {
])
business.value = bizData
coupons.value = allCoupons.filter(c => c.business_id === id)
startCarouselTimer()
analyticsService.logEvent({
event_name: 'view_details',
entity_type: 'business',
@ -110,13 +111,43 @@ function openFacebook() {
window.open(fb.startsWith('http') ? fb : `https://facebook.com/${fb}`, '_blank')
}
let carouselTimer: number | ReturnType<typeof setInterval> | null = null
function startCarouselTimer() {
stopCarouselTimer()
if (galleryImages.value.length > 1) {
carouselTimer = setInterval(() => {
carouselIndex.value = (carouselIndex.value + 1) % galleryImages.value.length
}, 4000)
}
}
function stopCarouselTimer() {
if (carouselTimer !== null) {
clearInterval(carouselTimer as any)
carouselTimer = null
}
}
function prevSlide() {
carouselIndex.value = (carouselIndex.value - 1 + galleryImages.value.length) % galleryImages.value.length
startCarouselTimer()
}
function nextSlide() {
carouselIndex.value = (carouselIndex.value + 1) % galleryImages.value.length
startCarouselTimer()
}
function setSlide(idx: number) {
carouselIndex.value = idx
startCarouselTimer()
}
onUnmounted(() => {
stopCarouselTimer()
})
// Quick info pills computed
const quickInfoPills = computed(() => {
if (!business.value) return []
@ -260,7 +291,7 @@ const hasSocials = computed(() =>
:key="dotIdx"
class="car-dot"
:class="{ 'car-dot-active': dotIdx === carouselIndex }"
@click="carouselIndex = dotIdx"
@click="setSlide(dotIdx)"
></span>
</div>
</template>