360 lines
8.6 KiB
TypeScript
360 lines
8.6 KiB
TypeScript
import { defineStore } from "pinia";
|
|
import { ref, computed } from "vue";
|
|
import ClientCategoryService from "@/services/categories_client";
|
|
|
|
import type {
|
|
ClientCategory,
|
|
CreateClientCategoryPayload,
|
|
UpdateClientCategoryPayload,
|
|
} from "@/services/categories_client";
|
|
|
|
export const useClientCategoryStore = defineStore("clientCategory", () => {
|
|
// State
|
|
const categories = ref<ClientCategory[]>([]);
|
|
const currentCategory = ref<ClientCategory | null>(null);
|
|
const loading = ref(false);
|
|
const error = ref<string | null>(null);
|
|
|
|
// Getters
|
|
const allCategories = computed(() => categories.value);
|
|
const activeCategories = computed(() =>
|
|
categories.value.filter((category) => category.is_active)
|
|
);
|
|
const isLoading = computed(() => loading.value);
|
|
const hasError = computed(() => error.value !== null);
|
|
const getError = computed(() => error.value);
|
|
const getCategoryById = computed(() => (id: number) =>
|
|
categories.value.find((category) => category.id === id)
|
|
);
|
|
const getCategoryBySlug = computed(() => (slug: string) =>
|
|
categories.value.find((category) => category.slug === slug)
|
|
);
|
|
|
|
// Actions
|
|
const setLoading = (isLoading: boolean) => {
|
|
loading.value = isLoading;
|
|
};
|
|
|
|
const setError = (err: string | null) => {
|
|
error.value = err;
|
|
};
|
|
|
|
const clearError = () => {
|
|
error.value = null;
|
|
};
|
|
|
|
const setCategories = (newCategories: ClientCategory[]) => {
|
|
categories.value = newCategories;
|
|
};
|
|
|
|
const setCurrentCategory = (category: ClientCategory | null) => {
|
|
currentCategory.value = category;
|
|
};
|
|
|
|
/**
|
|
* Fetch all client categories
|
|
*/
|
|
const fetchCategories = async () => {
|
|
setLoading(true);
|
|
setError(null);
|
|
|
|
try {
|
|
const response = await ClientCategoryService.getAllCategories({
|
|
per_page: 1000, // Get all categories without pagination
|
|
});
|
|
setCategories(response.data);
|
|
return response.data;
|
|
} catch (err: any) {
|
|
const errorMessage =
|
|
err.response?.data?.message ||
|
|
err.message ||
|
|
"Failed to fetch categories";
|
|
setError(errorMessage);
|
|
throw err;
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Fetch active client categories only
|
|
*/
|
|
const fetchActiveCategories = async () => {
|
|
setLoading(true);
|
|
setError(null);
|
|
|
|
try {
|
|
const response = await ClientCategoryService.getActiveCategories({
|
|
per_page: 1000, // Get all active categories without pagination
|
|
});
|
|
setCategories(response.data);
|
|
return response.data;
|
|
} catch (err: any) {
|
|
const errorMessage =
|
|
err.response?.data?.message ||
|
|
err.message ||
|
|
"Failed to fetch active categories";
|
|
setError(errorMessage);
|
|
throw err;
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Fetch a single category by ID
|
|
*/
|
|
const fetchCategory = async (id: number) => {
|
|
setLoading(true);
|
|
setError(null);
|
|
|
|
try {
|
|
const response = await ClientCategoryService.getCategory(id);
|
|
setCurrentCategory(response.data);
|
|
return response.data;
|
|
} catch (err: any) {
|
|
const errorMessage =
|
|
err.response?.data?.message ||
|
|
err.message ||
|
|
"Failed to fetch category";
|
|
setError(errorMessage);
|
|
throw err;
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Fetch a single category by slug
|
|
*/
|
|
const fetchCategoryBySlug = async (slug: string) => {
|
|
setLoading(true);
|
|
setError(null);
|
|
|
|
try {
|
|
const response = await ClientCategoryService.getCategoryBySlug(slug);
|
|
setCurrentCategory(response.data);
|
|
return response.data;
|
|
} catch (err: any) {
|
|
const errorMessage =
|
|
err.response?.data?.message ||
|
|
err.message ||
|
|
"Failed to fetch category by slug";
|
|
setError(errorMessage);
|
|
throw err;
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Create a new category
|
|
*/
|
|
const createCategory = async (payload: CreateClientCategoryPayload) => {
|
|
setLoading(true);
|
|
setError(null);
|
|
|
|
try {
|
|
const response = await ClientCategoryService.createCategory(payload);
|
|
// Add the new category to the list
|
|
categories.value.push(response.data);
|
|
setCurrentCategory(response.data);
|
|
return response.data;
|
|
} catch (err: any) {
|
|
const errorMessage =
|
|
err.response?.data?.message ||
|
|
err.message ||
|
|
"Failed to create category";
|
|
setError(errorMessage);
|
|
throw err;
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Update an existing category
|
|
*/
|
|
const updateCategory = async (payload: UpdateClientCategoryPayload) => {
|
|
setLoading(true);
|
|
setError(null);
|
|
|
|
try {
|
|
const response = await ClientCategoryService.updateCategory(payload);
|
|
const updatedCategory = response.data;
|
|
|
|
// Update in the categories list
|
|
const index = categories.value.findIndex(
|
|
(category) => category.id === updatedCategory.id
|
|
);
|
|
if (index !== -1) {
|
|
categories.value[index] = updatedCategory;
|
|
}
|
|
|
|
// Update current category if it's the one being edited
|
|
if (
|
|
currentCategory.value &&
|
|
currentCategory.value.id === updatedCategory.id
|
|
) {
|
|
setCurrentCategory(updatedCategory);
|
|
}
|
|
|
|
return updatedCategory;
|
|
} catch (err: any) {
|
|
const errorMessage =
|
|
err.response?.data?.message ||
|
|
err.message ||
|
|
"Failed to update category";
|
|
setError(errorMessage);
|
|
throw err;
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Delete a category
|
|
*/
|
|
const deleteCategory = async (id: number) => {
|
|
setLoading(true);
|
|
setError(null);
|
|
|
|
try {
|
|
const response = await ClientCategoryService.deleteCategory(id);
|
|
|
|
// Remove from the categories list
|
|
categories.value = categories.value.filter(
|
|
(category) => category.id !== id
|
|
);
|
|
|
|
// Clear current category if it's the one being deleted
|
|
if (currentCategory.value && currentCategory.value.id === id) {
|
|
setCurrentCategory(null);
|
|
}
|
|
|
|
return response;
|
|
} catch (err: any) {
|
|
const errorMessage =
|
|
err.response?.data?.message ||
|
|
err.message ||
|
|
"Failed to delete category";
|
|
setError(errorMessage);
|
|
throw err;
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Toggle category active status
|
|
*/
|
|
const toggleCategoryStatus = async (id: number, isActive: boolean) => {
|
|
setLoading(true);
|
|
setError(null);
|
|
|
|
try {
|
|
const response = await ClientCategoryService.toggleCategoryStatus(
|
|
id,
|
|
isActive
|
|
);
|
|
const updatedCategory = response.data;
|
|
|
|
// Update in the categories list
|
|
const index = categories.value.findIndex(
|
|
(category) => category.id === id
|
|
);
|
|
if (index !== -1) {
|
|
categories.value[index] = updatedCategory;
|
|
}
|
|
|
|
// Update current category if it's the one being toggled
|
|
if (currentCategory.value && currentCategory.value.id === id) {
|
|
setCurrentCategory(updatedCategory);
|
|
}
|
|
|
|
return updatedCategory;
|
|
} catch (err: any) {
|
|
const errorMessage =
|
|
err.response?.data?.message ||
|
|
err.message ||
|
|
"Failed to toggle category status";
|
|
setError(errorMessage);
|
|
throw err;
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Search categories by name or description
|
|
*/
|
|
const searchCategories = async (query: string) => {
|
|
setLoading(true);
|
|
setError(null);
|
|
|
|
try {
|
|
const response = await ClientCategoryService.searchCategories(query, {
|
|
per_page: 1000, // Get all search results without pagination
|
|
});
|
|
setCategories(response.data);
|
|
return response.data;
|
|
} catch (err: any) {
|
|
const errorMessage =
|
|
err.response?.data?.message ||
|
|
err.message ||
|
|
"Failed to search categories";
|
|
setError(errorMessage);
|
|
throw err;
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Clear current category
|
|
*/
|
|
const clearCurrentCategory = () => {
|
|
setCurrentCategory(null);
|
|
};
|
|
|
|
/**
|
|
* Clear all state
|
|
*/
|
|
const clearStore = () => {
|
|
categories.value = [];
|
|
currentCategory.value = null;
|
|
error.value = null;
|
|
};
|
|
|
|
return {
|
|
// State
|
|
categories,
|
|
currentCategory,
|
|
loading,
|
|
error,
|
|
|
|
// Getters
|
|
allCategories,
|
|
activeCategories,
|
|
isLoading,
|
|
hasError,
|
|
getError,
|
|
getCategoryById,
|
|
getCategoryBySlug,
|
|
|
|
// Actions
|
|
fetchCategories,
|
|
fetchActiveCategories,
|
|
fetchCategory,
|
|
fetchCategoryBySlug,
|
|
createCategory,
|
|
updateCategory,
|
|
deleteCategory,
|
|
toggleCategoryStatus,
|
|
searchCategories,
|
|
clearCurrentCategory,
|
|
clearStore,
|
|
clearError,
|
|
};
|
|
});
|