Proyectos de Subversion LeadersLinked - SPA

Rev

Rev 3664 | Autoría | Ultima modificación | Ver Log |

import React, { useEffect, useState, useMemo, useCallback } from 'react';

import {
  useModal,
  useAlert,
  useAlertModal,
  useApi,
  usePagination,
  useInterceptionObserver,
  useDebouncedSearchParam
} from '@shared/hooks';
import { useKnowledgeMetadata } from './useKnowledgeMetadata';
import { deleteKnowledge, saveKnowledge, updateKnowledge } from '@knowledges/services';

import { KnowledgeForm } from '@knowledges/components';

export function useKnowledges() {
  const [addedKnowledges, setAddedKnowledges] = useState([]);
  const [editedKnowledges, setEditedKnowledges] = useState(new Map());
  const [deletedKnowledgeUrls, setDeletedKnowledgeUrls] = useState(new Set());

  const {
    categories,
    categoriesWithEdition,
    addUrl,
    imageSize,
    loading: loadingMetadata
  } = useKnowledgeMetadata();

  const {
    inputValue: searchTerm,
    setInputValue: setSearchTerm,
    debouncedValue: debouncedSearchTerm
  } = useDebouncedSearchParam('search');
  const {
    inputValue: searchCategory,
    setInputValue: setSearchCategory,
    debouncedValue: debouncedSearchCategory
  } = useDebouncedSearchParam('category_id');

  const { data, loading, hasMore, loadMore, applyFilters } = usePagination('/knowledge-area/list');

  const { elementRef } = useInterceptionObserver({
    onIntersect: hasMore ? loadMore : undefined
  });

  const { showModal, closeModal } = useModal();
  const { showAlert, closeAlert } = useAlertModal();
  const { showSuccess, showError } = useAlert();

  const knowledges = useMemo(() => {
    const paginatedItems = data.filter((item) => !deletedKnowledgeUrls.has(item.link_delete));

    const mergedItems = paginatedItems.map((item) =>
      editedKnowledges.has(item.link_edit) ? editedKnowledges.get(item.link_edit) : item
    );

    const addedItemsSet = new Set(mergedItems.map((item) => item.link_edit));
    const uniqueAddedKnowledges = addedKnowledges.filter(
      (item) => !addedItemsSet.has(item.link_edit)
    );

    return [...uniqueAddedKnowledges, ...mergedItems];
  }, [data, addedKnowledges, editedKnowledges, deletedKnowledgeUrls]);

  const { execute: saveKnowledgeApi } = useApi(saveKnowledge, {
    onSuccess: ({ message, knowledge }) => {
      setAddedKnowledges((prev) => [knowledge, ...prev]);
      showSuccess(message);
      closeModal();
    },
    onError: (error) => {
      showError(error.message);
    }
  });

  const { execute: updateKnowledgeApi } = useApi(updateKnowledge, {
    onSuccess: ({ message, knowledge }) => {
      setEditedKnowledges((prev) => new Map(prev).set(knowledge.link_edit, knowledge));
      showSuccess(message);
      closeModal();
    },
    onError: (error) => {
      showError(error.message);
    }
  });

  const { execute: deleteKnowledgeApi } = useApi(deleteKnowledge, {
    onSuccess: (message) => {
      showSuccess(message);
      closeAlert();
    },
    onError: (error) => {
      showError(error.message);
    }
  });

  const handleAddKnowledge = useCallback(
    (url) => {
      showModal(
        'Agregar Conocimiento',
        <KnowledgeForm
          categories={categories}
          imageSize={imageSize}
          onSubmit={(knowledge) => saveKnowledgeApi(url, knowledge)}
        />
      );
    },
    [categories]
  );

  const handleEditKnowledge = useCallback(
    (url) => {
      const knowledge = knowledges.find((k) => k.link_edit === url);
      showModal(
        'Editar Conocimiento',
        <KnowledgeForm
          categories={categories}
          imageSize={imageSize}
          onSubmit={(knowledge) => updateKnowledgeApi(url, knowledge)}
          defaultValues={knowledge}
        />
      );
    },
    [knowledges, categories]
  );

  const handleDeleteKnowledge = useCallback((url) => {
    setDeletedKnowledgeUrls((prev) => new Set(prev).add(url));
    showAlert({
      title: 'Eliminar Conocimiento',
      message: '¿Está seguro que desea eliminar este conocimiento?',
      onConfirm: () => deleteKnowledgeApi(url)
    });
  }, []);

  const clearFilters = useCallback(() => {
    setSearchTerm('');
    setSearchCategory('');
  }, []);

  useEffect(() => {
    applyFilters({ search: debouncedSearchTerm, category_id: debouncedSearchCategory });
    setAddedKnowledges([]);
    setEditedKnowledges(new Map());
    setDeletedKnowledgeUrls(new Set());
  }, [debouncedSearchTerm, debouncedSearchCategory]);

  return {
    knowledges,
    loading: loadingMetadata || loading,
    addUrl,
    searchTerm,
    searchCategory,
    categoriesWithEdition,
    elementRef,
    clearFilters,
    changeCategory: setSearchCategory,
    searchKnowledge: setSearchTerm,
    deleteKnowledge: handleDeleteKnowledge,
    addKnowledge: handleAddKnowledge,
    editKnowledge: handleEditKnowledge
  };
}