UNPKG

@replyke/core

Version:

Replyke: Build interactive apps with social features like comments, votes, feeds, user lists, notifications, and more.

195 lines 8.38 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const react_1 = require("react"); const hooks_1 = require("../../store/hooks"); const collectionsSlice_1 = require("../../store/slices/collectionsSlice"); const useCollectionsActions_1 = require("./useCollectionsActions"); const useProject_1 = __importDefault(require("../projects/useProject")); const user_1 = require("../user"); const useAxiosPrivate_1 = __importDefault(require("../../config/useAxiosPrivate")); /** * Redux-powered hook that provides the exact same interface as useCollectionsData() * This is a drop-in replacement for the Context-based hook */ function useCollections(_ = {}) { const dispatch = (0, hooks_1.useReplykeDispatch)(); const axios = (0, useAxiosPrivate_1.default)(); // Get external context const { projectId } = (0, useProject_1.default)(); const { user } = (0, user_1.useUser)(); // Get Redux state const currentCollection = (0, hooks_1.useReplykeSelector)(collectionsSlice_1.selectCurrentCollection); const subCollections = (0, hooks_1.useReplykeSelector)(collectionsSlice_1.selectSubCollections); const loading = (0, hooks_1.useReplykeSelector)(collectionsSlice_1.selectCollectionsLoading); const subCollectionsMap = (0, hooks_1.useReplykeSelector)(collectionsSlice_1.selectSubCollectionsMap); const collectionsById = (0, hooks_1.useReplykeSelector)((state) => state.replyke.collections.collectionsById); const currentProjectId = (0, hooks_1.useReplykeSelector)(collectionsSlice_1.selectCurrentProjectId); // Get actions const { openCollection, goBack, goToRoot, fetchRootCollection, fetchSubCollections, createCollection: createCollectionAction, updateCollection: updateCollectionAction, deleteCollection: deleteCollectionAction, addToCollection: addToCollectionAction, removeFromCollection: removeFromCollectionAction, } = (0, useCollectionsActions_1.useCollectionsActions)(); // Update Redux state when project changes (0, react_1.useEffect)(() => { if (projectId && projectId !== currentProjectId) { dispatch((0, collectionsSlice_1.setProjectContext)(projectId)); } }, [dispatch, projectId, currentProjectId]); // Fetch root collection when user and project are available. // Skip if a collection is already loaded for this project — otherwise mounting // useCollections() per leaf component (e.g. a BookmarkButton in every card) // hammers /collections/root and trips the rate limit. (0, react_1.useEffect)(() => { if (!user || !projectId) return; if (currentCollection && currentProjectId === projectId) return; fetchRootCollection({ projectId }); }, [fetchRootCollection, user, projectId, currentCollection, currentProjectId]); // Fetch sub-collections when current collection changes (0, react_1.useEffect)(() => { if (!user || !projectId || !currentCollection) return; // Check if sub-collections for this collection are already fetched if (subCollectionsMap[currentCollection.id] !== undefined) { return; // No need to fetch, we already have the mapping (even if empty) } fetchSubCollections({ projectId, collectionId: currentCollection.id }); }, [ fetchSubCollections, user, projectId, currentCollection, subCollectionsMap, ]); // Entity membership checker - checks if entity is in any collection (or specific collection if provided) const isEntitySaved = (0, react_1.useCallback)(async ({ entityId: selectedEntityId, collectionId }) => { if (!projectId || !selectedEntityId) { return { saved: false, inSpecificCollection: collectionId ? false : undefined, collections: [], }; } try { const response = await axios.get(`/${projectId}/entities/is-entity-saved`, { params: { entityId: selectedEntityId }, }); // If specific collection ID provided, check if entity is in that collection const inSpecificCollection = collectionId ? response.data.collections.some((col) => col.id === collectionId) : undefined; return { saved: response.data.saved, inSpecificCollection, collections: response.data.collections, }; } catch (err) { console.error("Error checking if entity is in collection:", err); return { saved: false, inSpecificCollection: collectionId ? false : undefined, collections: [], }; } }, [projectId, axios]); // Wrapped CRUD operations that match the original interface const handleCreateCollection = (0, react_1.useCallback)(async ({ collectionName }) => { if (!collectionName) { console.error("No collectionName provided."); return; } if (!currentCollection) { console.error("No current collection."); return; } if (!projectId) { console.error("No projectId available."); return; } await createCollectionAction({ projectId, parentCollectionId: currentCollection.id, collectionName, }); }, [createCollectionAction, currentCollection, projectId]); const handleUpdateCollection = (0, react_1.useCallback)(async ({ collectionId, update }) => { if (!projectId) { console.error("No projectId available."); return; } await updateCollectionAction({ projectId, collectionId, update }); }, [updateCollectionAction, projectId]); const handleDeleteCollection = (0, react_1.useCallback)(async ({ collection }) => { if (!projectId) { console.error("No projectId available."); return; } await deleteCollectionAction({ projectId, collection }); }, [deleteCollectionAction, projectId]); const handleAddToCollection = (0, react_1.useCallback)(async ({ entity }) => { if (!entity?.id) { console.error("No entity provided."); return; } if (!currentCollection) { console.error("No current collection."); return; } if (!projectId) { console.error("No projectId available."); return; } await addToCollectionAction({ projectId, collectionId: currentCollection.id, entity, }); }, [addToCollectionAction, currentCollection, projectId]); const handleRemoveFromCollection = (0, react_1.useCallback)(async ({ entityId }) => { if (!currentCollection) { console.error("No current collection."); return; } if (!projectId) { console.error("No projectId available."); return; } await removeFromCollectionAction({ projectId, collectionId: currentCollection.id, entityId, }); }, [removeFromCollectionAction, currentCollection, projectId]); // Return the same interface as the original hook return (0, react_1.useMemo)(() => ({ currentCollection, subCollections, loading, openCollection, goBack, goToRoot, isEntitySaved, createCollection: handleCreateCollection, updateCollection: handleUpdateCollection, deleteCollection: handleDeleteCollection, addToCollection: handleAddToCollection, removeFromCollection: handleRemoveFromCollection, }), [ currentCollection, subCollections, loading, openCollection, goBack, goToRoot, isEntitySaved, handleCreateCollection, handleUpdateCollection, handleDeleteCollection, handleAddToCollection, handleRemoveFromCollection, ]); } exports.default = useCollections; //# sourceMappingURL=useCollections.js.map