"use client"; import { useState, useEffect, useCallback } from 'react'; import { serviceService, Service, ServiceListResponse, ServiceStats, ServiceSearchResponse } from '../api/serviceService'; // Hook for fetching all services export const useServices = (params?: { featured?: boolean; category?: string; min_price?: number; max_price?: number; search?: string; ordering?: string; page?: number; }) => { const [services, setServices] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [pagination, setPagination] = useState<{ count: number; next: string | null; previous: string | null; } | null>(null); const fetchServices = useCallback(async () => { try { setLoading(true); setError(null); const response = await serviceService.getServices(params); setServices(response.results); setPagination({ count: response.count, next: response.next, previous: response.previous, }); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to fetch services'); } finally { setLoading(false); } }, [params]); useEffect(() => { fetchServices(); }, [fetchServices]); return { services, loading, error, pagination, refetch: fetchServices, }; }; // Hook for fetching a single service by slug export const useService = (slug: string) => { const [service, setService] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const fetchService = useCallback(async () => { if (!slug) return; try { setLoading(true); setError(null); const response = await serviceService.getServiceBySlug(slug); setService(response); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to fetch service'); } finally { setLoading(false); } }, [slug]); useEffect(() => { fetchService(); }, [fetchService]); return { service, loading, error, refetch: fetchService, }; }; // Hook for fetching featured services export const useFeaturedServices = () => { const [services, setServices] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const fetchFeaturedServices = useCallback(async () => { try { setLoading(true); setError(null); const response = await serviceService.getFeaturedServices(); setServices(response.results); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to fetch featured services'); } finally { setLoading(false); } }, []); useEffect(() => { fetchFeaturedServices(); }, [fetchFeaturedServices]); return { services, loading, error, refetch: fetchFeaturedServices, }; }; // Hook for searching services export const useServiceSearch = (query: string) => { const [results, setResults] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [count, setCount] = useState(0); const searchServices = useCallback(async (searchQuery: string) => { if (!searchQuery.trim()) { setResults([]); setCount(0); return; } try { setLoading(true); setError(null); const response = await serviceService.searchServices(searchQuery); setResults(response.results); setCount(response.count); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to search services'); } finally { setLoading(false); } }, []); useEffect(() => { const timeoutId = setTimeout(() => { searchServices(query); }, 300); // Debounce search return () => clearTimeout(timeoutId); }, [query, searchServices]); return { results, loading, error, count, search: searchServices, }; }; // Hook for fetching service statistics export const useServiceStats = () => { const [stats, setStats] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const fetchStats = useCallback(async () => { try { setLoading(true); setError(null); const response = await serviceService.getServiceStats(); setStats(response); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to fetch service stats'); } finally { setLoading(false); } }, []); useEffect(() => { fetchStats(); }, [fetchStats]); return { stats, loading, error, refetch: fetchStats, }; }; // Hook for managing service state (for admin operations) export const useServiceManagement = () => { const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const createService = useCallback(async (serviceData: Partial) => { try { setLoading(true); setError(null); const response = await serviceService.createService(serviceData); return response; } catch (err) { setError(err instanceof Error ? err.message : 'Failed to create service'); throw err; } finally { setLoading(false); } }, []); const updateService = useCallback(async (slug: string, serviceData: Partial) => { try { setLoading(true); setError(null); const response = await serviceService.updateService(slug, serviceData); return response; } catch (err) { setError(err instanceof Error ? err.message : 'Failed to update service'); throw err; } finally { setLoading(false); } }, []); const deleteService = useCallback(async (slug: string) => { try { setLoading(true); setError(null); await serviceService.deleteService(slug); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to delete service'); throw err; } finally { setLoading(false); } }, []); const uploadServiceImage = useCallback(async (slug: string, imageFile: File) => { try { setLoading(true); setError(null); const response = await serviceService.uploadServiceImage(slug, imageFile); return response; } catch (err) { setError(err instanceof Error ? err.message : 'Failed to upload service image'); throw err; } finally { setLoading(false); } }, []); return { loading, error, createService, updateService, deleteService, uploadServiceImage, }; }; // Hook for navigation services (for header menu) export const useNavigationServices = () => { const [services, setServices] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const fetchNavigationServices = useCallback(async () => { try { setLoading(true); setError(null); // Fetch only active services, ordered by display_order const response = await serviceService.getServices({ ordering: 'display_order', page: 1 }); // Filter only active services (handle null values as active) const activeServices = response.results.filter(service => service.is_active !== false); setServices(activeServices); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to fetch navigation services'); // Set empty array on error to prevent navigation issues setServices([]); } finally { setLoading(false); } }, []); useEffect(() => { fetchNavigationServices(); }, [fetchNavigationServices]); return { services, loading, error, refetch: fetchNavigationServices, }; };