feat: business template/mold redesign

- Supabase: Add schedule, whatsapp, instagram, facebook, gallery_images
  columns to businesses table
- types/index.ts: Add 5 new fields to Business interface
- businessService.ts: Update all SELECT queries to include new fields,
  add _parseFormData helper, handle gallery_images as JSON array
- BusinessDetailsView.vue: Full redesign matching the approved mockup:
  * Hero 300px with centered name + yellow category badge
  * Horizontal scrollable quick-info pills (area, schedule, phone, web)
  * Image carousel (main image + gallery_images) with arrows + dots
  * About section with yellow left-accent bar
  * 2x2 social grid (WhatsApp, Instagram, Facebook, Maps) with brand colors
  * Coupon section preserved
  * Sticky CTA bar: Ver en el Mapa + Llamar buttons
- PromoterDashboard.vue: Updated business modal with grouped sections
  (Info Basica / Portada / Descripcion / Redes / Galeria) + new fields
This commit is contained in:
2026-03-03 21:31:35 -05:00
parent af7464be43
commit bdfcd55370
4 changed files with 858 additions and 497 deletions

View File

@ -2,6 +2,8 @@
import { supabase } from '@/supabase'
import type { Business } from '@/types'
const SELECT_FIELDS = 'id, name, address, phone, image_url, social_media, category, latitude, longitude, area, description, website, schedule, whatsapp, instagram, facebook, gallery_images, updated_at'
export const businessService = {
/** Helper to upload file to supabase storage */
async uploadImage(file: File): Promise<string> {
@ -18,58 +20,59 @@ export const businessService = {
/** Get all businesses */
async getAllBusinesses(): Promise<Business[]> {
const { data, error } = await supabase.from('businesses').select('id, name, address, phone, image_url, social_media, category, latitude, longitude, area, description, website, updated_at')
const { data, error } = await supabase.from('businesses').select(SELECT_FIELDS)
if (error) throw new Error(error.message)
return data as Business[]
},
/** Get a single business by ID */
async getBusiness(id: string): Promise<Business> {
const { data, error } = await supabase.from('businesses').select('id, name, address, phone, image_url, social_media, category, latitude, longitude, area, description, website, updated_at').eq('id', id).single()
const { data, error } = await supabase.from('businesses').select(SELECT_FIELDS).eq('id', id).single()
if (error) throw new Error(error.message)
return data as Business
},
/** Create a new business */
async createBusiness(businessData: FormData): Promise<Business> {
/** Parse FormData into a payload object, handling gallery_images JSON */
_parseFormData(businessData: FormData): { payload: any; fileUpload: File | null } {
const payload: any = {}
let fileUpload: File | null = null
businessData.forEach((value, key) => {
if ((key === 'file' || key === 'image') && value instanceof File) {
fileUpload = value
} else if (key === 'gallery_images' && typeof value === 'string') {
// Comes as JSON string from the form
try { payload[key] = JSON.parse(value) } catch { /* ignore */ }
} else if (value !== 'null' && value !== '' && key !== 'file' && key !== 'image') {
payload[key] = value
}
})
return { payload, fileUpload }
},
/** Create a new business */
async createBusiness(businessData: FormData): Promise<Business> {
const { payload, fileUpload } = this._parseFormData(businessData)
if (fileUpload) {
payload.image_url = await this.uploadImage(fileUpload)
}
const { data, error } = await supabase.from('businesses').insert([payload]).select().single()
const { data, error } = await supabase.from('businesses').insert([payload]).select(SELECT_FIELDS).single()
if (error) throw new Error(error.message)
return data as Business
},
/** Update an existing business */
async updateBusiness(id: string, businessData: FormData): Promise<Business> {
const payload: any = {}
let fileUpload: File | null = null
businessData.forEach((value, key) => {
if ((key === 'file' || key === 'image') && value instanceof File) {
fileUpload = value
} else if (value !== 'null' && value !== '' && key !== 'file' && key !== 'image') {
payload[key] = value
}
})
const { payload, fileUpload } = this._parseFormData(businessData)
if (fileUpload) {
payload.image_url = await this.uploadImage(fileUpload)
}
const { data, error } = await supabase.from('businesses').update(payload).eq('id', id).select().single()
const { data, error } = await supabase.from('businesses').update(payload).eq('id', id).select(SELECT_FIELDS).single()
if (error) throw new Error(error.message)
return data as Business
},