452 lines
11 KiB
TypeScript
452 lines
11 KiB
TypeScript
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<ClientLocation[]>([]);
|
|
const currentClientLocation = ref<ClientLocation | null>(null);
|
|
const loading = ref(false);
|
|
const error = ref<string | null>(null);
|
|
const searchResults = ref<ClientLocation[]>([]);
|
|
|
|
// 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,
|
|
};
|
|
});
|