import { defineStore } from "pinia"; export const useModalStore = defineStore("modal", { state: () => ({ // Dynamic modal registry - can handle any number of modals modals: {}, // Stack for modal layering (optional) modalStack: [], // Component registry for dynamic modals registeredComponents: {}, // Global modal configuration globalConfig: { closeOnEscape: true, closeOnOutsideClick: true, preventBodyScroll: true } }), getters: { // Check if any modal is open hasOpenModal: (state) => { return Object.values(state.modals).some(modal => modal.isOpen); }, // Get modal by ID getModal: (state) => (modalId) => { return state.modals[modalId] || null; }, // Check if specific modal is open isModalOpen: (state) => (modalId) => { return state.modals[modalId]?.isOpen || false; }, // Get modal data getModalData: (state) => (modalId) => { return state.modals[modalId]?.data || null; }, // Get the topmost modal in stack getTopModal: (state) => { if (state.modalStack.length === 0) return null; const topModalId = state.modalStack[state.modalStack.length - 1]; return state.modals[topModalId]; } }, actions: { // Register a modal component for dynamic loading registerModalComponent(modalId, component) { this.registeredComponents[modalId] = component; }, // Initialize a modal (register it in the store) initializeModal(modalId, config = {}) { if (!this.modals[modalId]) { this.modals[modalId] = { id: modalId, isOpen: false, data: null, config: { ...this.globalConfig, ...config }, history: [] }; } }, // Open a modal with optional data openModal(modalId, data = null, config = {}) { // Initialize modal if it doesn't exist this.initializeModal(modalId, config); // Close other modals if exclusive mode (default behavior) if (config.exclusive !== false) { this.closeAllModals(); } // Set modal state this.modals[modalId].isOpen = true; this.modals[modalId].data = data; this.modals[modalId].config = { ...this.modals[modalId].config, ...config }; // Add to stack if (!this.modalStack.includes(modalId)) { this.modalStack.push(modalId); } // Track opening in history this.modals[modalId].history.push({ action: 'opened', timestamp: new Date(), data: data }); }, // Close a specific modal closeModal(modalId) { if (this.modals[modalId]) { this.modals[modalId].isOpen = false; this.modals[modalId].data = null; // Remove from stack const index = this.modalStack.indexOf(modalId); if (index > -1) { this.modalStack.splice(index, 1); } // Track closing in history this.modals[modalId].history.push({ action: 'closed', timestamp: new Date() }); } }, // Toggle a modal toggleModal(modalId, data = null, config = {}) { if (this.isModalOpen(modalId)) { this.closeModal(modalId); } else { this.openModal(modalId, data, config); } }, // Close all modals closeAllModals() { Object.keys(this.modals).forEach(modalId => { if (this.modals[modalId].isOpen) { this.closeModal(modalId); } }); this.modalStack = []; }, // Close the topmost modal closeTopModal() { if (this.modalStack.length > 0) { const topModalId = this.modalStack[this.modalStack.length - 1]; this.closeModal(topModalId); } }, // Update modal data without opening/closing updateModalData(modalId, data) { if (this.modals[modalId]) { this.modals[modalId].data = data; } }, // Update modal configuration updateModalConfig(modalId, config) { if (this.modals[modalId]) { this.modals[modalId].config = { ...this.modals[modalId].config, ...config }; } }, // Remove a modal from the store (cleanup) removeModal(modalId) { if (this.modals[modalId]) { this.closeModal(modalId); delete this.modals[modalId]; } }, // Convenience methods for common modals // Add your specific modal methods here // Example: Edit User Modal openEditUser(userData = null) { this.openModal('editUser', userData, { closeOnEscape: true, closeOnOutsideClick: false }); }, closeEditUser() { this.closeModal('editUser'); }, // Example: Confirmation Modal openConfirmation(message, onConfirm, onCancel = null) { this.openModal('confirmation', { message, onConfirm, onCancel }, { closeOnEscape: false, closeOnOutsideClick: false }); }, closeConfirmation() { this.closeModal('confirmation'); }, // Example: Image Gallery Modal openImageGallery(images, currentIndex = 0) { this.openModal('imageGallery', { images, currentIndex }, { closeOnEscape: true, exclusive: true }); }, closeImageGallery() { this.closeModal('imageGallery'); }, // Create Client Modal openCreateClient(clientData = null) { this.openModal('createClient', clientData, { closeOnEscape: true, closeOnOutsideClick: true, exclusive: true }); }, closeCreateClient() { this.closeModal('createClient'); } } });