104 lines
2.8 KiB
TypeScript
104 lines
2.8 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
import { supabase } from '../lib/supabase';
|
|
import type { Reservation, NewReservation, Property } from '../types';
|
|
|
|
export function useReservations(property: Property) {
|
|
const [reservations, setReservations] = useState<Reservation[]>([]);
|
|
const [loading, setLoading] = useState(true);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
const fetchReservations = async () => {
|
|
try {
|
|
setLoading(true);
|
|
const { data, error } = await supabase
|
|
.from('reservations')
|
|
.select('*')
|
|
.eq('property', property)
|
|
.order('start_date', { ascending: true });
|
|
|
|
if (error) throw error;
|
|
setReservations(data || []);
|
|
} catch (err: unknown) {
|
|
setError(err instanceof Error ? err.message : 'Error desconocido');
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
fetchReservations();
|
|
|
|
// Suscripción realtime filtrada por propiedad
|
|
const channel = supabase
|
|
.channel(`reservations_${property}`)
|
|
.on(
|
|
'postgres_changes',
|
|
{
|
|
event: '*',
|
|
schema: 'natur_reservas',
|
|
table: 'reservations',
|
|
filter: `property=eq.${property}`,
|
|
},
|
|
() => {
|
|
fetchReservations();
|
|
}
|
|
)
|
|
.subscribe();
|
|
|
|
return () => {
|
|
supabase.removeChannel(channel);
|
|
};
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [property]);
|
|
|
|
const createReservation = async (reservation: NewReservation): Promise<Reservation> => {
|
|
const { data: authData } = await supabase.auth.getUser();
|
|
const payload = {
|
|
...reservation,
|
|
property,
|
|
created_by: authData.user?.id,
|
|
};
|
|
const { data, error } = await supabase
|
|
.from('reservations')
|
|
.insert([payload])
|
|
.select('id')
|
|
.single();
|
|
if (error) throw error;
|
|
const { data: created, error: fetchError } = await supabase
|
|
.from('reservations')
|
|
.select('*')
|
|
.eq('id', data.id)
|
|
.single();
|
|
if (fetchError) throw fetchError;
|
|
return created as Reservation;
|
|
};
|
|
|
|
const updateReservation = async (id: string, updates: Partial<Reservation>) => {
|
|
const { data: authData } = await supabase.auth.getUser();
|
|
const payload = {
|
|
...updates,
|
|
updated_by: authData.user?.id,
|
|
};
|
|
const { error } = await supabase
|
|
.from('reservations')
|
|
.update(payload)
|
|
.eq('id', id);
|
|
if (error) throw error;
|
|
};
|
|
|
|
const deleteReservation = async (id: string) => {
|
|
const { error } = await supabase.from('reservations').delete().eq('id', id);
|
|
if (error) throw error;
|
|
};
|
|
|
|
return {
|
|
reservations,
|
|
loading,
|
|
error,
|
|
createReservation,
|
|
updateReservation,
|
|
deleteReservation,
|
|
refreshResolver: fetchReservations,
|
|
};
|
|
}
|