2026-02-21 09:53:31 -05:00
|
|
|
/** Service for bus stop-related API calls */
|
2026-02-25 21:01:18 -05:00
|
|
|
import { supabase } from '@/supabase'
|
2026-02-21 09:53:31 -05:00
|
|
|
import type { BusStop, Route } from '@/types'
|
|
|
|
|
|
|
|
|
|
export const busStopsService = {
|
|
|
|
|
/** Get all bus stops */
|
|
|
|
|
async getAllBusStops(): Promise<BusStop[]> {
|
2026-02-26 22:17:56 -05:00
|
|
|
const { data, error } = await supabase.from('bus_stops').select('id, name, latitude, longitude, city, address, parent_id, side, stop_type, has_shelter, has_seating, is_accessible, created_at, updated_at')
|
2026-02-25 21:01:18 -05:00
|
|
|
if (error) throw new Error(error.message)
|
|
|
|
|
return data as BusStop[]
|
2026-02-21 09:53:31 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/** Get a single bus stop by ID */
|
|
|
|
|
async getBusStopById(id: string): Promise<BusStop> {
|
2026-02-26 22:17:56 -05:00
|
|
|
const { data, error } = await supabase.from('bus_stops').select('id, name, latitude, longitude, city, address, parent_id, side, stop_type, has_shelter, has_seating, is_accessible, created_at, updated_at').eq('id', id).single()
|
2026-02-25 21:01:18 -05:00
|
|
|
if (error) throw new Error(error.message)
|
|
|
|
|
return data as BusStop
|
2026-02-21 09:53:31 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/** Get all routes passing through a bus stop */
|
|
|
|
|
async getBusStopRoutes(stopId: string): Promise<Route[]> {
|
2026-02-25 21:01:18 -05:00
|
|
|
const { data, error } = await supabase
|
|
|
|
|
.from('route_stops')
|
|
|
|
|
.select('routes(*)')
|
|
|
|
|
.eq('stop_id', stopId)
|
|
|
|
|
|
|
|
|
|
if (error) throw new Error(error.message)
|
|
|
|
|
// Extract the nested strictly typed route object automatically connected by Supabase relationships
|
|
|
|
|
return (data || []).map((row: any) => row.routes) as Route[]
|
2026-02-21 09:53:31 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/** Get estimated next bus arrivals (Mock Data) */
|
|
|
|
|
async getNextBusArrivals(_stopId: string): Promise<{ routeName: string; arrivalTime: string }[]> {
|
|
|
|
|
// Mock delay to simulate network request
|
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
|
|
|
|
|
|
|
|
// Generate some random mock arrivals
|
|
|
|
|
const mockArrivals = [
|
|
|
|
|
{ routeName: "Ruta Boquete - David", arrivalTime: "5 min" },
|
|
|
|
|
{ routeName: "Ruta David - Boquete", arrivalTime: "12 min" },
|
|
|
|
|
{ routeName: "Ruta Circular", arrivalTime: "25 min" }
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// Randomly return 1-3 arrivals
|
|
|
|
|
return mockArrivals.slice(0, Math.floor(Math.random() * 3) + 1);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/** Create a new bus stop (Admin) */
|
2026-02-25 21:01:18 -05:00
|
|
|
async createBusStop(currentData: import('@/types').BusStopCreate): Promise<BusStop> {
|
|
|
|
|
const { data, error } = await supabase
|
|
|
|
|
.from('bus_stops')
|
|
|
|
|
.insert([currentData])
|
|
|
|
|
.select()
|
|
|
|
|
.single()
|
|
|
|
|
|
|
|
|
|
if (error) throw new Error(error.message)
|
|
|
|
|
return data as BusStop
|
2026-02-21 09:53:31 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/** Update a bus stop (Admin) */
|
2026-02-25 21:01:18 -05:00
|
|
|
async updateBusStop(id: string, currentData: import('@/types').BusStopUpdate): Promise<BusStop> {
|
|
|
|
|
const { data, error } = await supabase
|
|
|
|
|
.from('bus_stops')
|
|
|
|
|
.update(currentData)
|
|
|
|
|
.eq('id', id)
|
|
|
|
|
.select()
|
|
|
|
|
.single()
|
|
|
|
|
|
|
|
|
|
if (error) throw new Error(error.message)
|
|
|
|
|
return data as BusStop
|
2026-02-21 09:53:31 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/** Delete a bus stop (Admin) */
|
|
|
|
|
async deleteBusStop(id: string): Promise<void> {
|
2026-02-25 21:01:18 -05:00
|
|
|
const { error } = await supabase.from('bus_stops').delete().eq('id', id)
|
|
|
|
|
if (error) throw new Error(error.message)
|
2026-02-21 09:53:31 -05:00
|
|
|
}
|
|
|
|
|
}
|