import { defineStore } from "pinia"; import { ref, computed } from "vue"; import ClientLocationService from "@/services/client_location"; import type { ClientLocation, CreateClientLocationPayload, UpdateClientLocationPayload, ClientLocationListResponse, } from "@/services/client_location"; export const useClientLocationStore = defineStore("clientLocation", () => { // State const clientLocations = ref([]); const currentClientLocation = ref(null); const loading = ref(false); const error = ref(null); const searchResults = ref([]); // Pagination state const pagination = ref({ current_page: 1, last_page: 1, per_page: 10, total: 0, }); // Getters const allClientLocations = computed(() => clientLocations.value); const defaultLocations = computed(() => clientLocations.value.filter((location) => location.is_default) ); const nonDefaultLocations = computed(() => clientLocations.value.filter((location) => !location.is_default) ); const isLoading = computed(() => loading.value); const hasError = computed(() => error.value !== null); const getError = computed(() => error.value); const getLocationById = computed(() => (id: number) => clientLocations.value.find((location) => location.id === id) ); const getDefaultLocationByClientId = computed(() => (clientId: number) => clientLocations.value.find( (location) => location.client_id === clientId && location.is_default ) ); const getPagination = computed(() => pagination.value); // Actions const setLoading = (isLoading: boolean) => { loading.value = isLoading; }; const setError = (err: string | null) => { error.value = err; }; const clearError = () => { error.value = null; }; const setClientLocations = (newLocations: ClientLocation[]) => { clientLocations.value = newLocations; }; const setCurrentClientLocation = (location: ClientLocation | null) => { currentClientLocation.value = location; }; const setSearchResults = (results: ClientLocation[]) => { searchResults.value = results; }; const setPagination = (meta: any) => { if (meta) { pagination.value = { current_page: meta.current_page || 1, last_page: meta.last_page || 1, per_page: meta.per_page || 10, total: meta.total || 0, }; } }; /** * Fetch all client locations with optional pagination and filters */ const fetchClientLocations = async (params?: { page?: number; per_page?: number; client_id?: number; is_default?: boolean; search?: string; }) => { setLoading(true); setError(null); try { const response = await ClientLocationService.getAllClientLocations( params ); setClientLocations(response.data); if (response.meta) { setPagination(response.meta); } return response; } catch (err: any) { const errorMessage = err.response?.data?.message || err.message || "Failed to fetch client locations"; setError(errorMessage); throw err; } finally { setLoading(false); } }; /** * Fetch locations for a specific client */ const fetchClientLocationsByClient = async ( clientId: number, params?: { page?: number; per_page?: number; is_default?: boolean; } ) => { setLoading(true); setError(null); try { const response = await ClientLocationService.getClientLocations(clientId); setClientLocations(response); return response; } catch (err: any) { const errorMessage = err.response?.data?.message || err.message || "Failed to fetch client locations"; setError(errorMessage); throw err; } finally { setLoading(false); } }; /** * Fetch a single client location by ID */ const fetchClientLocation = async (id: number) => { setLoading(true); setError(null); try { const response = await ClientLocationService.getClientLocation(id); setCurrentClientLocation(response.data); return response.data; } catch (err: any) { const errorMessage = err.response?.data?.message || err.message || "Failed to fetch client location"; setError(errorMessage); throw err; } finally { setLoading(false); } }; /** * Create a new client location */ const createClientLocation = async (payload: CreateClientLocationPayload) => { setLoading(true); setError(null); try { const response = await ClientLocationService.createClientLocation( payload ); const newLocation = response.data; // Add the new location to the list clientLocations.value.push(newLocation); setCurrentClientLocation(newLocation); // If this location is set as default, update other locations if (newLocation.is_default) { clientLocations.value = clientLocations.value.map((location) => location.client_id === newLocation.client_id && location.id !== newLocation.id ? { ...location, is_default: false } : location ); } return newLocation; } catch (err: any) { const errorMessage = err.response?.data?.message || err.message || "Failed to create client location"; setError(errorMessage); throw err; } finally { setLoading(false); } }; /** * Update an existing client location */ const updateClientLocation = async (payload: UpdateClientLocationPayload) => { setLoading(true); setError(null); try { const response = await ClientLocationService.updateClientLocation( payload ); const updatedLocation = response.data; // Update in the locations list const index = clientLocations.value.findIndex( (location) => location.id === updatedLocation.id ); if (index !== -1) { clientLocations.value[index] = updatedLocation; } // Update current location if it's the one being edited if ( currentClientLocation.value && currentClientLocation.value.id === updatedLocation.id ) { setCurrentClientLocation(updatedLocation); } // If this location is set as default, update other locations if (updatedLocation.is_default) { clientLocations.value = clientLocations.value.map((location) => location.client_id === updatedLocation.client_id && location.id !== updatedLocation.id ? { ...location, is_default: false } : location ); } return updatedLocation; } catch (err: any) { const errorMessage = err.response?.data?.message || err.message || "Failed to update client location"; setError(errorMessage); throw err; } finally { setLoading(false); } }; /** * Delete a client location */ const deleteClientLocation = async (id: number) => { setLoading(true); setError(null); try { const response = await ClientLocationService.deleteClientLocation(id); // Remove from the locations list clientLocations.value = clientLocations.value.filter( (location) => location.id !== id ); // Clear current location if it's the one being deleted if ( currentClientLocation.value && currentClientLocation.value.id === id ) { setCurrentClientLocation(null); } return response; } catch (err: any) { const errorMessage = err.response?.data?.message || err.message || "Failed to delete client location"; setError(errorMessage); throw err; } finally { setLoading(false); } }; /** * Set a location as default for a client */ const setAsDefaultLocation = async (id: number) => { setLoading(true); setError(null); try { const response = await ClientLocationService.setAsDefaultLocation(id); const updatedLocation = response.data; // Update all locations for this client clientLocations.value = clientLocations.value.map((location) => location.client_id === updatedLocation.client_id ? { ...location, is_default: location.id === updatedLocation.id, } : location ); // Update current location if it's the one being set as default if ( currentClientLocation.value && currentClientLocation.value.id === updatedLocation.id ) { setCurrentClientLocation(updatedLocation); } return updatedLocation; } catch (err: any) { const errorMessage = err.response?.data?.message || err.message || "Failed to set default location"; setError(errorMessage); throw err; } finally { setLoading(false); } }; /** * Get the default location for a client */ const fetchDefaultClientLocation = async (clientId: number) => { setLoading(true); setError(null); try { const response = await ClientLocationService.getDefaultClientLocation( clientId ); return response ? response.data : null; } catch (err: any) { const errorMessage = err.response?.data?.message || err.message || "Failed to fetch default location"; setError(errorMessage); throw err; } finally { setLoading(false); } }; const getClientLocations = async (clientId: number) => { setLoading(true); setError(null); try { const response = await ClientLocationService.getClientLocations(clientId); return response; } catch (err: any) { const errorMessage = err.response?.data?.message || err.message || "Failed to fetch default location"; setError(errorMessage); throw err; } finally { setLoading(false); } }; /** * Clear current client location */ const clearCurrentClientLocation = () => { setCurrentClientLocation(null); }; /** * Clear search results */ const clearSearchResults = () => { searchResults.value = []; }; /** * Clear all state */ const clearStore = () => { clientLocations.value = []; currentClientLocation.value = null; error.value = null; searchResults.value = []; pagination.value = { current_page: 1, last_page: 1, per_page: 10, total: 0, }; }; return { // State clientLocations, currentClientLocation, loading, error, searchResults, // Getters allClientLocations, defaultLocations, nonDefaultLocations, isLoading, hasError, getError, getLocationById, getDefaultLocationByClientId, getPagination, // Actions fetchClientLocations, fetchClientLocationsByClient, fetchClientLocation, createClientLocation, updateClientLocation, deleteClientLocation, setAsDefaultLocation, fetchDefaultClientLocation, clearCurrentClientLocation, clearSearchResults, clearStore, clearError, getClientLocations, }; });