chore: migrate AdminShuttles and old API endpoints from Axios/Render to Supabase client, remove Axios

This commit is contained in:
2026-02-26 14:51:03 -05:00
parent 30c3f092d8
commit 35a29fbb0f
9 changed files with 69 additions and 175 deletions

View File

@ -1,10 +1,7 @@
<script setup lang="ts">
import { ref } from 'vue';
import { useRouter } from 'vue-router';
import { SUPABASE_URL } from '@/supabase';
import axios from 'axios';
const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:8000';
import { supabase } from '@/supabase';
const router = useRouter();
const isLoading = ref(false);
@ -53,33 +50,39 @@ async function saveShuttle() {
showMessage.value = { text: '', type: '' };
try {
const token = localStorage.getItem('auth_token');
const formData = new FormData();
// Añadimos campos obligatorios para el backend
formData.append('route_name', `${shuttleForm.value.origin} - ${shuttleForm.value.destination}`);
formData.append('origin', shuttleForm.value.origin);
formData.append('destination', shuttleForm.value.destination);
formData.append('vehicle_type', shuttleForm.value.vehicle_type);
formData.append('company_name', shuttleForm.value.company_name);
formData.append('price_per_person', String(shuttleForm.value.price_per_person));
formData.append('price_private_trip', String(shuttleForm.value.price_private_trip));
formData.append('estimated_duration', shuttleForm.value.estimated_duration);
formData.append('departure_times', shuttleForm.value.departure_times);
formData.append('contact_whatsapp', shuttleForm.value.contact_whatsapp);
formData.append('phone_number', shuttleForm.value.phone_number);
formData.append('english_speaking', String(shuttleForm.value.english_speaking));
let image_url = '';
if (selectedFile.value) {
formData.append('image', selectedFile.value);
const ext = selectedFile.value.name.split('.').pop();
const filename = `shuttles/${Date.now()}.${ext}`;
const { error: upErr } = await supabase.storage.from('uploads').upload(filename, selectedFile.value);
if (upErr) throw upErr;
const { data: urlData } = supabase.storage.from('uploads').getPublicUrl(filename);
image_url = urlData.publicUrl;
}
await axios.post(`${API_URL}/api/shuttles`, formData, {
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'multipart/form-data'
}
});
const payload = {
route_name: `${shuttleForm.value.origin} - ${shuttleForm.value.destination}`,
origin: shuttleForm.value.origin,
destination: shuttleForm.value.destination,
vehicle_type: shuttleForm.value.vehicle_type,
company_name: shuttleForm.value.company_name,
price_per_person: shuttleForm.value.price_per_person,
price_private_trip: shuttleForm.value.price_private_trip,
estimated_duration: shuttleForm.value.estimated_duration,
departure_times: shuttleForm.value.departure_times,
contact_whatsapp: shuttleForm.value.contact_whatsapp,
phone_number: shuttleForm.value.phone_number,
english_speaking: shuttleForm.value.english_speaking,
is_active: shuttleForm.value.is_active,
image_url: image_url || shuttleForm.value.image_url
};
const { error: insertError } = await supabase.from('shuttles').insert([payload]);
if (insertError) {
throw insertError;
}
showMessage.value = { text: '¡Viaje Turístico Desplegado!', type: 'success' };
setTimeout(() => router.push('/admin'), 2000);

View File

@ -3,11 +3,9 @@ import { ref, onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { businessService } from '@/services/businessService'
import { couponsService } from '@/services/couponsService'
import { SUPABASE_URL } from '@/supabase'
import type { Business, Coupon } from '@/types'
import FavoriteButton from '@/components/FavoriteButton.vue'
const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:8000';
import { getImageUrl as utilGetImageUrl } from '@/utils/imageUrl'
const route = useRoute()
const router = useRouter()
@ -42,9 +40,7 @@ onMounted(async () => {
})
function getImageUrl(path: string | null | undefined) {
if (!path) return '/default-business.jpg'
if (path.startsWith('http')) return path
return `${API_URL}${path.startsWith('/') ? '' : '/'}${path}`
return utilGetImageUrl(path, 'business')
}
const goBack = () => router.back()

View File

@ -2,11 +2,9 @@
import { onMounted, ref, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { useCouponStore } from '@/stores/coupon'
import { SUPABASE_URL } from '@/supabase'
import type { Coupon } from '@/types'
import FavoriteButton from '@/components/FavoriteButton.vue'
const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:8000';
import { getImageUrl as utilGetImageUrl } from '@/utils/imageUrl'
const { t } = useI18n()
const couponStore = useCouponStore()
@ -33,9 +31,7 @@ const filteredCoupons = computed(() => {
})
function getImageUrl(path: string | null | undefined) {
if (!path) return '/default-coupon.png'
if (path.startsWith('http')) return path
return `${API_URL}${path.startsWith('/') ? '' : '/'}${path}`
return utilGetImageUrl(path, 'coupon')
}

View File

@ -3,9 +3,7 @@ import { ref, computed, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { useI18n } from 'vue-i18n'
import { useFavoritesStore } from '@/stores/favorites'
import { SUPABASE_URL } from '@/supabase'
const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:8000';
import { getImageUrl as utilGetImageUrl } from '@/utils/imageUrl'
const { t } = useI18n()
const router = useRouter()
@ -26,9 +24,7 @@ onMounted(async () => {
})
function getImageUrl(path?: string) {
if (!path) return `https://ui-avatars.com/api/?name=Favorito&background=fee715&color=101820&bold=true`
if (path.startsWith('http')) return path
return `${API_URL}${path.startsWith('/') ? '' : '/'}${path}`
return utilGetImageUrl(path, 'business')
}
async function removeFavorite(event: Event, itemType: string, itemId: string) {

View File

@ -5,11 +5,9 @@ import { businessService } from '@/services/businessService'
import { couponsService } from '@/services/couponsService'
import { shuttlesService } from '@/services/shuttlesService'
import { useAuthStore } from '@/stores/auth'
import { SUPABASE_URL } from '@/supabase'
import { SUPABASE_URL, supabase } from '@/supabase'
import type { Coupon, Business, Shuttle } from '@/types'
const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:8000';
const route = useRoute()
const authStore = useAuthStore()
@ -142,14 +140,13 @@ async function loadShuttles() {
// Shuttle Methods
async function toggleShuttleStatus(shuttle: Shuttle) {
try {
const token = localStorage.getItem('auth_token')
const response = await fetch(`${API_URL}/api/shuttles/${shuttle.id}/status?is_active=${!shuttle.is_active}`, {
method: 'PATCH',
headers: { 'Authorization': `Bearer ${token}` }
})
if (response.ok) {
await loadShuttles()
}
const { error } = await supabase
.from('shuttles')
.update({ is_active: !shuttle.is_active })
.eq('id', shuttle.id);
if (error) throw error;
await loadShuttles();
} catch (e) {
alert('Error al actualizar estado del shuttle')
}
@ -158,16 +155,13 @@ async function toggleShuttleStatus(shuttle: Shuttle) {
async function deleteShuttle(id: string) {
if (confirm('¿Estás seguro de eliminar este transporte turístico?')) {
try {
const token = localStorage.getItem('auth_token')
const response = await fetch(`${API_URL}/api/shuttles/${id}`, {
method: 'DELETE',
headers: { 'Authorization': `Bearer ${token}` }
})
if (response.ok) {
await loadShuttles()
} else {
alert('No se pudo eliminar el shuttle')
}
const { error } = await supabase
.from('shuttles')
.delete()
.eq('id', id);
if (error) throw error;
await loadShuttles();
} catch (e) {
alert('Error al eliminar shuttle')
}
@ -289,8 +283,7 @@ function openEditModal(coupon: Coupon) {
function getImageUrl(path: string | null | undefined) {
if (!path) return '/default-coupon.png'
if (path.startsWith('http')) return path
return `${API_URL}${path.startsWith('/') ? '' : '/'}${path}`
return path
}
async function saveCoupon() {