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([]); const currentCategory = ref(null); const loading = ref(false); const error = ref(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, }; });